diff --git a/.claude/commands/review.md b/.claude/commands/review.md new file mode 100644 index 0000000..6bc4759 --- /dev/null +++ b/.claude/commands/review.md @@ -0,0 +1,20 @@ +Review my staged and unstaged changes before committing: + +**CRITICAL: NEVER stage changes with `git add` and NEVER commit changes with `git commit`. This is a review-only command.** + +1. Run `git diff` and `git diff --staged` to see all changes +2. Read the relevant rules from `.claude/rules/` (e.g., `react.md` for .tsx files, `typescript.md` for .ts files, `rust.md` for .rs files) +3. For each changed file: + - Summarize what changed + - Check for potential issues (bugs, security, performance) + - Verify it follows the rules in `.claude/rules/` +4. Give me a brief summary: + - What's good + - Any concerns or suggestions + - Ready to commit? (yes/no with reason) +5. Suggest a commit message: + - Extract issue number from branch name (e.g., `3-focuscat-poc` → `#3`) + - Format: `# ` + - Keep it concise (50 chars or less) + +Keep the review concise and actionable. diff --git a/.claude/rules b/.claude/rules new file mode 120000 index 0000000..65505c7 --- /dev/null +++ b/.claude/rules @@ -0,0 +1 @@ +../.cursor/rules \ No newline at end of file diff --git a/.cursor/rules/comments.mdc b/.cursor/rules/comments.mdc new file mode 100644 index 0000000..eb76f22 --- /dev/null +++ b/.cursor/rules/comments.mdc @@ -0,0 +1,191 @@ +--- +description: Comment guidelines for clear, valuable code documentation +globs: ["**/*.rs", "**/*.ts", "**/*.tsx"] +alwaysApply: true +--- + +# Comment Guidelines + +The goal is balance: enough signposts to navigate, not so many that they become noise. + +## Core Principles + +- **Value-Driven** - Always ask "Does this help the next reader?" +- **Long-Term** - Comments should still be useful in weeks or months. Prefer explaining *what exists and why* (constraints, tradeoffs, environment). Avoid comments that only make sense during the current task or refactor. +- **Balanced** - Never over-comment obvious code, never under-comment complex logic. +- **Context over history** - Document the design and its reasons, not the change you just made or alternatives you rejected (unless that explains a non-obvious constraint). + +## What TO Comment + +### Section Headers +Short labels to help readers skim longer functions. + +✅ Good: +```rust +// Validate input +... + +// Process data +... + +// Save results +... +``` + +❌ Bad: +```rust +// This section validates the input by checking all required fields +... +``` + +### WHY Comments +Explain non-obvious constraints or tradeoffs. Place them next to the code they explain (e.g. above the function or block), not floating near unrelated declarations. Use "do X so that Y" (what the code does and what problem it solves), not "we chose X over Y." + +✅ Good (states the reason something is done): +```rust +// Validate here; caller may be untrusted. +let input = parse(raw)?; +``` + +✅ Good (constraint or tradeoff): +```typescript +// Process in batches so we stay under the rate limit. +for (const chunk of chunks(data, 100)) { + await submit(chunk); +} +``` + +❌ Bad (restates the operation, no why): +```rust +// Insert into database +db.insert(...).await; +``` + +### Domain Logic +Explain business rules that need context. + +✅ Good: +```rust +// Overtime = time beyond planned (base + extensions) +let overtime = actual.saturating_sub(planned + extended); +``` + +### Thresholds and Config Values +Explain what a value means, not its literal value. Document on props/parameters. + +✅ Good: +```typescript +interface TProps { + /** Minimum size (px) for element to be visible */ + minSizePx?: number; +} +``` + +❌ Bad: +```typescript +interface TProps { + minSizePx?: number; // 8 +} +``` + +### Data State Documentation +Document non-obvious data states. + +✅ Good: +```rust +/// Insert new record (ended_at is NULL until complete). +pub async fn insert(...) -> Result +``` + +❌ Bad: +```rust +/// Insert a new record into the database. +pub async fn insert(...) -> Result +``` + +## What NOT TO Comment + +### Restating Code +Never restate what the code literally does. + +✅ Good - Intent helps readers skim: +```typescript +if (current == null || current.id !== id) { + // Start new group + ... +} else { + // Extend current group + ... +} +``` + +❌ Bad - Restates mechanics: +```rust +// Get the timer +let timer = state.lock(); + +// Loop through items +for item in items { + +// Check if null or id different +if (current == null || current.id !== id) { +``` + +### Session Rationale and Bloat +Never document design choices that only matter during the current refactor or agent session. Comments that explain "what we changed," "what we didn't use," or "why we chose X over Y" (without a lasting constraint) become noise once the change is done. + +❌ Bad (documents what's NOT there): +```typescript +// We don't validate here; that's done in the parent. +``` + +❌ Bad (only relevant during this refactor/session): +```typescript +// Changed from string to enum for type safety +``` + +❌ Bad (choice without lasting reason; doesn't help in 6 months): +```typescript +// We use a queue here because we tried direct calls but had race conditions. +``` +Rewrite to state the lasting reason only. + +✅ Good (what exists and why, long-term): +```typescript +// Use a queue so events are processed in order and we avoid races. +``` + +### Em Dashes +Never use em dashes (—) in comments. Use commas, semicolons, or plain sentences instead. + +### Type Information +Never restate what types already document. + +✅ Good: +```rust +// Unix timestamp in seconds +let timestamp: i64 = row.get("created_at"); +``` + +❌ Bad: +```rust +// The ID as an integer +let id: i64 = row.get("id"); +``` + +## Before Adding a Comment + +- **Would a reader in 6 months benefit?** If the comment only explains "what we changed" or "what we considered," rewrite it to describe *what the code does and why* (constraint, tradeoff, rule), or omit it. +- **Is it next to the code it explains?** WHY and context comments belong above the block or function they describe, not on unrelated fields or earlier in the file. + +## Language Specifics + +### Rust +- `//` for inline comments +- `///` for doc comments (only when adding value) +- `// MARK: -` for IDE navigation (sparingly) + +### TypeScript +- `//` for inline comments +- `/** */` for JSDoc (only when adding value) +- `// MARK: -` for IDE navigation (sparingly) diff --git a/.cursor/rules/drizzle.mdc b/.cursor/rules/drizzle.mdc deleted file mode 100644 index 997c4f2..0000000 --- a/.cursor/rules/drizzle.mdc +++ /dev/null @@ -1,305 +0,0 @@ ---- -description: -globs: -alwaysApply: false ---- -# DrizzleORM Guidelines - -Core patterns for using Drizzle ORM with PostgreSQL. These guidelines ensure type-safe, maintainable database operations. - -## Core Principles -- **Type Safety** - Always leverage TypeScript and Drizzle's type system -- **SQL First** - Always prefer SQL-like syntax over ORM abstractions -- **Transactions** - Always use transactions for multi-table operations -- **Explicit Returns** - Always return specific columns, never `*` - -## Schema Definition -- Always use `pgTable` with explicit column types -- Always include `updatedAt` and `createdAt` timestamps -- Always use `text('id')` with UUID for primary keys -- Always define proper constraints and foreign keys - -✅ Good: -```typescript -import { pgTable, text, timestamp, primaryKey } from 'drizzle-orm/pg-core'; - -export const userTable = pgTable('user', { - id: text('id') - .primaryKey() - .$defaultFn(() => crypto.randomUUID()), - - email: text('email').unique().notNull(), - name: text('name').notNull(), - - updatedAt: timestamp('updated_at', { mode: 'date' }) - .notNull() - .$defaultFn(() => new Date()), - createdAt: timestamp('created_at', { mode: 'date' }) - .notNull() - .$defaultFn(() => new Date()) -}); - -// Composite primary key pattern -export const userRoleTable = pgTable('user_role', { - userId: text('user_id') - .notNull() - .references(() => userTable.id, { onDelete: 'cascade' }), - role: text('role').notNull(), - - updatedAt: timestamp('updated_at', { mode: 'date' }) - .notNull() - .$defaultFn(() => new Date()), - createdAt: timestamp('created_at', { mode: 'date' }) - .notNull() - .$defaultFn(() => new Date()) -}, (table) => [ - primaryKey({ columns: [table.userId, table.role] }) -]); -``` - -❌ Bad: -```typescript -// Wrong: Missing timestamps, constraints, and types -const users = pgTable('users', { - id: text('id'), - name: text('name'), - email: text('email') -}); -``` - -## Select Queries -- Always specify exact columns in select object -- Always use `and()` for multiple conditions -- Always use `.limit(1)` for single record queries -- Always check array length for existence - -✅ Good: -```typescript -// Single record select -const users = await db - .select({ - id: userTable.id, - email: userTable.email, - name: userTable.name - }) - .from(userTable) - .where(eq(userTable.email, email)) - .limit(1); - -if (!users.length) { - throw new AppError('#ERR_USER_NOT_FOUND', 404); -} - -// Multiple conditions -const activeUsers = await db - .select({ - id: userTable.id, - name: userTable.name - }) - .from(userTable) - .where( - and( - eq(userTable.active, true), - eq(userTable.role, 'admin') - ) - ); -``` - -❌ Bad: -```typescript -// Wrong: Selecting all columns, no limit, using findFirst -const user = await db.query.userTable.findFirst({ - where: { email } -}); - -const users = await db - .select() // Wrong: Selecting all columns - .from(userTable) - .where(eq(userTable.email, email)); -``` - -## Insert Operations -- Always use `.returning()` with specific columns -- Always destructure the first result with `[newRecord]` -- Always set `updatedAt` and `createdAt` explicitly -- Always validate before insertion - -✅ Good: -```typescript -// Single insert with return -const [user] = await db - .insert(userTable) - .values({ - email: 'user@example.com', - name: 'John Doe', - updatedAt: new Date(), - createdAt: new Date() - }) - .returning({ - id: userTable.id, - email: userTable.email - }); - -// Batch insert -const users = await db - .insert(userTable) - .values(validatedUsers) - .returning({ id: userTable.id }); -``` - -❌ Bad: -```typescript -// Wrong: No returning, no timestamps -await db.insert(userTable).values(userData); - -// Wrong: Multiple single inserts instead of batch -for (const user of users) { - await db.insert(userTable).values(user); -} -``` - -## Update Operations -- Always use `.where()` with explicit conditions -- Always update `updatedAt` field -- Always use `.returning()` when data is needed - -✅ Good: -```typescript -const [updated] = await db - .update(userTable) - .set({ - name: 'New Name', - updatedAt: new Date() - }) - .where(eq(userTable.id, userId)) - .returning({ - id: userTable.id, - name: userTable.name - }); -``` - -❌ Bad: -```typescript -// Wrong: Missing where clause, no updatedAt -await db.update(userTable).set(data); - -// Wrong: Not returning when needed -await db - .update(userTable) - .set(data) - .where(eq(userTable.id, id)); -``` - -## Delete Operations -- Always use `.where()` with explicit conditions -- Always use `.returning()` to confirm deletion -- Always check result length to verify deletion - -✅ Good: -```typescript -const deleted = await db - .delete(userTable) - .where(eq(userTable.id, userId)) - .returning({ id: userTable.id }); - -if (!deleted.length) { - throw new AppError('#ERR_USER_NOT_FOUND', 404); -} -``` - -❌ Bad: -```typescript -// Wrong: No where clause, no confirmation -await db.delete(userTable); - -// Wrong: Not checking if anything was deleted -await db - .delete(userTable) - .where(eq(userTable.id, userId)); -``` - -## Transactions -- Always use transactions for multi-table operations -- Always return data from transaction -- Always handle the transaction result properly - -✅ Good: -```typescript -const result = await db.transaction(async (tx) => { - // 1. Create user - const [user] = await tx - .insert(userTable) - .values({ - email: 'user@example.com', - name: 'John Doe', - updatedAt: new Date(), - createdAt: new Date() - }) - .returning({ id: userTable.id }); - - // 2. Create user role - await tx - .insert(userRoleTable) - .values({ - userId: user.id, - role: 'admin', - updatedAt: new Date(), - createdAt: new Date() - }); - - return user; -}); - -return result; -``` - -❌ Bad: -```typescript -// Wrong: No transaction for multi-table operation -const user = await db.insert(userTable).values(userData); -await db.insert(userRoleTable).values({ userId: user.id }); - -// Wrong: Not handling transaction result -await db.transaction(async (tx) => { - await tx.insert(userTable).values(userData); - await tx.insert(userRoleTable).values(roleData); -}); -``` - -## Error Handling -- Always throw `AppError` for business logic errors -- Always check array length for existence -- Always validate parsed data before use - -✅ Good: -```typescript -// Existence check with proper error -if (!users.length) { - throw new AppError('#ERR_USER_NOT_FOUND', 404, { - detail: 'User not found' - }); -} - -// Data validation -const userData = users[0]; -if (userData?.email == null) { - throw new AppError('#ERR_INVALID_USER_DATA', 500, { - detail: 'Invalid user data' - }); -} -``` - -❌ Bad: -```typescript -// Wrong: Generic error handling -if (!user) { - throw new Error('User not found'); -} - -// Wrong: Not checking for null/undefined -const email = result[0].email; -``` - -## Related Rules -- [style-guide.mdc](mdc:.cursor/rules/style-guide.mdc): Core coding standards -- [hono.mdc](mdc:.cursor/rules/hono.mdc): API route patterns diff --git a/.cursor/rules/feature-fetch.mdc b/.cursor/rules/feature-fetch.mdc deleted file mode 100644 index 8e11227..0000000 --- a/.cursor/rules/feature-fetch.mdc +++ /dev/null @@ -1,218 +0,0 @@ ---- -description: -globs: -alwaysApply: false ---- -# Feature Fetch Patterns - -Core patterns and best practices for using feature-fetch, our typesafe API client library. - -## Core Principles -- **Type Safety First** - Always use proper typing for requests and responses -- **Error Handling** - Always handle errors using the Result pattern -- **Modular Features** - Always compose clients with relevant features only -- **Clean Architecture** - Always organize API clients in a consistent way - -## Implementation Guidelines - -### Client Creation -- Always create clients in dedicated environment files -- Always specify proper type parameters -- Always configure base URL and headers appropriately -- Always use feature composition for extended functionality - -✅ Good: -```typescript -// environment/clients/api-client.ts -import { createApiFetchClient, withRetry, withOpenApi } from 'feature-fetch'; -import type { paths } from '../types/api'; - -export const apiClient = withRetry( - createOpenApiFetchClient({ - prefixUrl: config.apiUrl, - headers: { - 'Authorization': `Bearer ${config.apiToken}` - } - }), - { maxRetries: 3 } -); -``` - -❌ Bad: -```typescript -// Scattered across components -const client = createApiFetchClient(); // Wrong: No configuration -const client = new ApiClient(); // Wrong: Class-based approach -const client = fetch(url); // Wrong: Raw fetch usage -``` - -### Error Handling -- Always use the Result pattern with `.isOk()` and `.isErr()` -- Always handle specific error types appropriately -- Always provide meaningful error messages -- Always propagate errors with proper context - -#### Error Types and Classes -- **NetworkError**: For connection-level failures (timeout, DNS, offline) -- **RequestError**: For HTTP-level failures (status codes, validation) -- **FetchError**: Base class for all fetch-related errors - -✅ Good: -```typescript -if (response.isErr()) { - if (response.error instanceof NetworkError) { - logger.error('Network connectivity issue', { error: response.error }); - throw new AppError('Failed to connect', { cause: response.error }); - } - if (response.error instanceof RequestError) { - if (response.error.response?.status === 404) { - return Result.err(new NotFoundError(`User ${id} not found`)); - } - } - throw response.error; -} -``` - -### OpenAPI Integration -- Always generate types from OpenAPI schemas -- Always use strongly typed paths and responses -- Always validate schema changes -- Always keep generated types in sync - -✅ Good: -```typescript -// Generated type usage -const response = await apiClient.get('/users/{userId}', { - pathParams: { userId: '123' } -}); - -if (response.isOk()) { - const user: TUser = response.value.data; - return user; -} -``` - -❌ Bad: -```typescript -// Manual type definitions -type User = any; // Wrong: Loose typing -const response = await fetch('/users/123'); // Wrong: No type safety -const data = await response.json(); // Wrong: Untyped response -``` - -### Feature Composition -- Always compose features in a logical order -- Always document feature dependencies -- Always configure features appropriately -- Always use only necessary features - -✅ Good: -```typescript -const apiClient = withOpenApi( - withRetry( - withAuth( - createApiFetchClient({ - prefixUrl: config.apiUrl - }) - ), - { maxRetries: 3 } - ) -); -``` - -❌ Bad: -```typescript -// Wrong: Inconsistent composition -const client = withAuth(createApiFetchClient()); -const retryClient = withRetry(fetch); -const finalClient = withOpenApi(retryClient); -``` - -### GraphQL Usage -- Always use the `gql` template literal -- Always define operation types -- Always handle GraphQL errors properly -- Always organize queries in dedicated files - -✅ Good: -```typescript -// queries/user.ts -const GET_USER = gql` - query GetUser($id: ID!) { - user(id: $id) { - id - name - email - } - } -`; - -// Usage -const response = await graphqlClient.query(GET_USER, { - variables: { id: '123' } -}); -``` - -❌ Bad: -```typescript -// Wrong: String literals -const query = `query { user { id } }`; - -// Wrong: No typing -const data = await client.query(query); -``` - -## Best Practices - -### Request Configuration -- Always set appropriate timeouts -- Always include necessary headers -- Always validate request parameters -- Always use proper HTTP methods - -✅ Good: -```typescript -const response = await apiClient.post('/orders', { - headers: { - 'Idempotency-Key': generateKey() - }, - body: orderData, - timeout: 5000 -}); -``` - -❌ Bad: -```typescript -// Wrong: Missing headers and validation -const response = await fetch('/orders', { - method: 'POST', - body: JSON.stringify(data) -}); -``` - -### Response Handling -- Always check response status -- Always parse response data safely -- Always handle pagination properly -- Always respect content types - -✅ Good: -```typescript -const response = await apiClient.get('/users', { - queryParams: { page: 1, limit: 10 } -}); - -if (response.isOk()) { - const { data, pagination } = response.value.data; - return { users: data, hasMore: pagination.hasNextPage }; -} -``` - -❌ Bad: -```typescript -// Wrong: Unsafe response handling -const res = await fetch('/users'); -const data = await res.json(); -return data.users; -``` - diff --git a/.cursor/rules/hono.mdc b/.cursor/rules/hono.mdc deleted file mode 100644 index 8bad7c4..0000000 --- a/.cursor/rules/hono.mdc +++ /dev/null @@ -1,231 +0,0 @@ ---- -description: -globs: -alwaysApply: false ---- -# Hono Guidelines - -Core guidelines for building type-safe, maintainable APIs using Hono. These patterns ensure consistent, secure, and performant backend services. - -## Core Principles -- **KISS (Keep It Simple, Stupid)** - Always choose the simplest, most maintainable solution -- **TypeScript First** - Always use TypeScript with strict typing everywhere -- **Less is More** - Always avoid unnecessary complexity, the best code is no code -- **Clean Routes** - Always keep route handlers focused on request/response flow -- **Smart Separation** - Only extract code to lib/ when it adds value - -## Route Organization - -### Directory Structure -- Always structure routes using dot notation for clear API paths -- Always keep route handlers in `index.ts` -- Always keep schemas in `schema.ts` -- Always use `lib/` for complex or reused functionality - -✅ Good: -```typescript -src/app/routes/ -├── v1.user/ # User resource -│ ├── index.ts # Route handlers with direct DB ops -│ └── schema.ts # API contracts -│ -├── v1.auth/ # Auth operations -│ ├── index.ts # Route handlers -│ ├── schema.ts # API contracts -│ └── lib/ # Complex/reused logic -│ ├── verify-token.ts # Token verification -│ └── hash-password.ts # Password hashing -``` - -❌ Bad: -```typescript -src/routes/ -├── v1/ # Wrong: Nested version -│ └── users/ # Wrong: Nested resource -│ └── users.ts # Wrong: Single file for all routes -``` - -## Schema Definition -- Always use Zod with `DTO` suffix for API contracts -- Always include OpenAPI examples for all fields -- Always use descriptive parameter names (`userId`, not `id`) -- Always export TypeScript types from schemas - -✅ Good: -```typescript -// schema.ts -import { createRoute, z } from '@hono/zod-openapi'; -import { JsonSuccessResponse, BadRequestResponse } from '@repo/hono-utils'; - -const SUserDto = z - .object({ - id: z.string().uuid().openapi({ example: '123e4567-e89b-12d3' }), - email: z.email().openapi({ example: 'user@example.com' }), - name: z.string().openapi({ example: 'John Doe' }) - }) - .openapi('UserDto'); - -export type TUserDto = z.infer; - -export const CreateUserRoute = createRoute({ - method: 'post', - path: '/v1/users', - tags: ['users'], - summary: 'Create user', - operationId: 'createUser', - request: { - body: { - content: { - 'application/json': { - schema: SUserDto.omit({ id: true }) - } - } - } - }, - responses: { - 201: JsonSuccessResponse(SUserDto), - 400: BadRequestResponse - } -}); -``` - -❌ Bad: -```typescript -// Wrong: Missing DTO suffix, no examples, generic parameters -const SUser = z.object({ // Wrong: Missing Dto suffix - email: z.string(), // Wrong: No OpenAPI example - name: z.string() -}); - -export const CreateRoute = createRoute({ - path: '/users/{id}', // Wrong: Generic 'id' parameter - responses: { - 200: { description: 'OK' } // Wrong: No typed response - } -}); -``` - -## Route Implementation -- Always keep simple CRUD operations in route handlers -- Always keep request/response flow clear in route handlers -- Always extract complex business logic to lib/ -- Always validate inputs with `c.req.valid()` - -✅ Good: -```typescript -// Simple CRUD stays in index.ts -router.openapi(GetUserRoute, async (c) => { - const { id } = c.req.valid('param'); - - const [user] = await db - .select() - .from(userTable) - .where(eq(userTable.id, id)) - .limit(1); - - if (user == null) { - throw new AppError('#ERR_NOT_FOUND', 404); - } - - return c.json(user); -}); - -// Complex operations use lib functions -router.openapi(RegisterUserRoute, async (c) => { - const input = c.req.valid('json'); - - // Clear flow with complex operations in lib/ - const hashedPassword = await hashPassword(input.password); - const user = await createUser({ ...input, password: hashedPassword }); - const token = await generateAuthToken(user); - await sendWelcomeEmail(user.email); - - return c.json({ user, token }); -}); -``` - -❌ Bad: -```typescript -// Wrong: Simple CRUD operation doesn't need lib/ -// lib/get-user.ts -export async function getUser(id: string) { - return await db - .select() - .from(userTable) - .where(eq(userTable.id, id)) - .limit(1); -} - -// Wrong: Route-specific validation doesn't need lib/ -// lib/validate-create-input.ts -export function validateCreateUserInput(input: unknown) { - return SCreateUserDto.parse(input); -} - -// Wrong: Complex business logic in route handler -router.openapi(RegisterUserRoute, async (c) => { - const input = c.req.valid('json'); - - // Wrong: These operations should be in lib/ - const hashedPassword = await bcrypt.hash(input.password, 10); - const existingUser = await db - .select() - .from(userTable) - .where(eq(userTable.email, input.email)) - .limit(1); - - if (existingUser.length > 0) { - throw new AppError('#ERR_USER_EXISTS', 409); - } - - const [user] = await db - .insert(userTable) - .values({ ...input, password: hashedPassword }) - .returning(); - - const token = jwt.sign( - { id: user.id, role: user.role }, - process.env.JWT_SECRET, - { expiresIn: '24h' } - ); - - await sendWelcomeEmail(user.email); - - return c.json({ user, token }); -}); -``` - -## Error Handling -- Always use `AppError` from `@repo/hono-utils` -- Always include error codes with `#ERR_` prefix -- Always provide helpful detail messages -- Always re-throw `AppError` instances in route handlers - -✅ Good: -```typescript -if (user == null) { - throw new AppError('#ERR_USER_NOT_FOUND', 404, { - detail: 'User not found' - }); -} -``` - -❌ Bad: -```typescript -// Wrong: Generic error handling -if (!user) { - throw new Error('User not found'); // Wrong: Generic Error -} - -// Wrong: Custom error responses -try { - const user = await getUser(id); - return c.json(user); -} catch (e) { - return c.json({ error: e.message }, 500); // Wrong: Custom format -} -``` - -## Related Rules -- [style-guide.mdc](mdc:.cursor/rules/style-guide.mdc): Core coding standards -- [drizzle.mdc](mdc:.cursor/rules/drizzle.mdc): Database patterns \ No newline at end of file diff --git a/.cursor/rules/index.mdc b/.cursor/rules/index.mdc index 99a4218..dfacd99 100644 --- a/.cursor/rules/index.mdc +++ b/.cursor/rules/index.mdc @@ -14,10 +14,8 @@ This document serves as the central index for all active Cursor rules within thi ## Development Guidelines - [typescript.mdc](mdc:.cursor/rules/typescript.mdc): TypeScript coding standards and style guidelines +- [react.mdc](mdc:.cursor/rules/react.mdc): React component patterns and conventions - [rust.mdc](mdc:.cursor/rules/rust.mdc): Rust coding standards and style guidelines for Tauri applications -- [hono.mdc](mdc:.cursor/rules/hono.mdc): Backend API development with Hono -- [nextjs.mdc](mdc:.cursor/rules/nextjs.mdc): Frontend development with Next.js - [vitest.mdc](mdc:.cursor/rules/vitest.mdc): Testing patterns and best practices with Vitest -- [xml-tokenizer.mdc](mdc:.cursor/rules/xml-tokenizer.mdc): Stream-based XML/HTML parsing with xml-tokenizer Each rule file contains comprehensive guidelines for its domain. We can split these into more specific rules as the project grows and patterns emerge. \ No newline at end of file diff --git a/.cursor/rules/nextjs.mdc b/.cursor/rules/nextjs.mdc deleted file mode 100644 index 316f627..0000000 --- a/.cursor/rules/nextjs.mdc +++ /dev/null @@ -1,475 +0,0 @@ ---- -description: -globs: -alwaysApply: false ---- -# Next.js Guidelines - -Core development guidelines for Next.js applications, focusing on App Router, Server Components, and type safety. These patterns ensure maintainable, performant applications while maximizing the benefits of React Server Components and TypeScript. - -## Core Principles -- **Server-First** - Always default to Server Components unless client interactivity is required -- **Type Safety** - Always use TypeScript with strict typing everywhere -- **Minimal Client JS** - Always keep client-side code focused on necessary interactivity -- **Clean Architecture** - Always maintain clear separation between server and client concerns -- **Performance First** - Always leverage React Server Components for optimal loading - -## Project Structure -- Always organize code by feature and responsibility -- Always separate server and client code clearly -- Always maintain consistent directory naming -- Always follow clear import patterns - -✅ Good: -```typescript -// Clear separation of server and client code -src/ - app/ # Next.js App Router (routes) - layout.tsx # Root layout (server) - page.tsx # Home page (server) - error.tsx # Error boundary (client) - features/ # Feature-based organization - users/ - components/ # Feature-specific components - lib/ # Feature-specific logic - components/ # Shared components - ui/ # Pure UI components - forms/ # Form components - lib/ # Shared logic -``` - -❌ Bad: -```typescript -// Wrong: Mixed concerns and unclear boundaries -src/ - pages/ # Wrong: Old pages directory mixed with app - components/ # Wrong: No separation of client/server components - utils/ # Wrong: No clear responsibility separation - helpers/ # Wrong: Generic bucket of mixed code - api/ # Wrong: API routes mixed with pages -``` - -## Server Components - -### Component Structure -- Always use TypeScript `React.FC` types -- Always handle errors explicitly -- Always keep data fetching in Server Components -- Always process data on the server - -✅ Good: -```typescript -// Clean Server Component with proper data fetching -import { db } from '@/environment'; -import { processUserData } from '@/lib'; -import { UserList } from '@/components'; -import type { TPageProps } from '@/app/types'; - -const UsersPage: React.FC = async ({ searchParams }) => { - try { - // Server-side data fetching - const users = await db.users.findMany({ - where: { status: 'active' } - }); - - // Process data on server - const processedUsers = users.map(processUserData); - - return ( -
- -
- ); - } catch (error) { - throw new Error('Failed to load users'); - } -}; - -export default UsersPage; -``` - -❌ Bad: -```typescript -// Wrong: Server Component with client-side patterns -const BadUsersPage = () => { // Wrong: Missing type definition - // Wrong: React.useState in Server Component - const [users, setUsers] = React.useState([]); - - // Wrong: React.useEffect in Server Component - React.useEffect(() => { - fetch('/api/users').then(res => res.json()) - .then(setUsers); - }, []); - - // Wrong: Client-side data fetching - return
{users.map(user => user.name)}
; -}; -``` - -## Client Components - -### Component Structure -- Always add 'use client' directive at the top -- Always implement proper error boundaries -- Always handle loading states -- Always type props and state -- Always use React.* methods (React.useState, React.useCallback, etc.) -- Always define TProps interface after the component - -✅ Good: -```typescript -'use client'; - -import React from 'react'; -import { Button } from '@/components'; -import type { TUser } from './types'; - -export const UserProfile: React.FC = ({ user, onUpdate }) => { - const [isLoading, setIsLoading] = React.useState(false); - const [error, setError] = React.useState(); - - const handleUpdate = React.useCallback(async () => { - try { - setIsLoading(true); - setError(undefined); - await onUpdate(user); - } catch (err) { - setError(err.message); - } finally { - setIsLoading(false); - } - }, [user, onUpdate]); - - return ( -
-

{user.name}

- - {error && ( -

{error}

- )} -
- ); -}; - -interface TProps { - user: TUser; - onUpdate: (user: TUser) => Promise; -} -``` - -❌ Bad: -```typescript -// Wrong: Poorly structured Client Component -'use client'; - -interface TProps { // Wrong: TProps defined before component - user: TUser; -} - -const BadProfile = (props) => { // Wrong: Missing type definition - // Wrong: Not using React.useState - const [loading, setLoading] = useState(); - - // Wrong: Not using React.useCallback - const update = () => { - fetch('/api/user', { method: 'POST' }); // Wrong: Using fetch instead of feature-fetch - }; - - // Wrong: No loading or error states in UI - return ( -
- -
- ); -}; -``` - -## State Management - -### Feature State -- Always use feature-state for global state management -- Always use React.useState for local component state -- Always keep state as close as possible to where it's used -- Always use proper typing for state - -✅ Good: -```typescript -// lib/editor.ts -import { createState } from 'feature-state'; -import type { TEditorState } from './types'; - -export const $editor = createState({ - mode: 'edit', - content: '' -}); - -// components/Editor.tsx -'use client'; - -import React from 'react'; -import { useFeatureState } from 'feature-state-react'; -import { $editor } from '@/store/editor'; - -export const Editor: React.FC = () => { - const editorState = useFeatureState($editor); - const [localState, setLocalState] = React.useState(''); - - const handleModeToggle = React.useCallback(() => { - $editor.set({ - ...$editor.get(), - mode: editorState.mode === 'edit' ? 'preview' : 'edit' - }); - }, [editorState.mode]); - - return ( -
- -
- ); -}; -``` - -❌ Bad: -```typescript -// Wrong: Poor state management -'use client'; - -const BadEditor = () => { - // Wrong: Using global state for local concerns - const [mode, setMode] = useState('edit'); - - // Wrong: Not using React.useCallback - const toggleMode = () => { - setMode(mode === 'edit' ? 'preview' : 'edit'); - }; - - return ; -}; -``` - -## Data Fetching - -### API Client Setup -- Always use feature-fetch for API requests -- Always handle errors explicitly with Result types -- Always type request and response data -- Always use proper error handling - -✅ Good: -```typescript -// lib/api/client.ts -import { createApiFetchClient, withRetry } from 'feature-fetch'; -import type { paths } from './openapi'; - -export const apiClient = withRetry( - createOpenApiFetchClient({ - prefixUrl: process.env.NEXT_PUBLIC_API_URL - }), - { maxRetries: 3 } -); - -// features/users/lib/api.ts -import { apiClient } from '@/environment'; -import type { TUser } from './types'; - -export async function getUser(id: string) { - const response = await apiClient.get('/users/{id}', { - pathParams: { id } - }); - - if (response.isErr()) { - if (response.error instanceof NetworkError) { - throw new Error('Network error occurred'); - } - if (isStatusCode(response.error, 404)) { - return null; - } - throw response.error; - } - - return response.value.data; -} - -// components/UserProfile.tsx -'use client'; - -import React from 'react'; -import { apiClient } from '@/lib/api/client'; - -export const UserProfile: React.FC = ({ userId }) => { - const [user, setUser] = React.useState(); - const [error, setError] = React.useState(); - - const fetchUser = React.useCallback(async () => { - const response = await apiClient.get('/users/{id}', { - pathParams: { id: userId } - }); - - if (response.isOk()) { - setUser(response.value.data); - } else { - setError(response.error.message); - } - }, [userId]); - - return ( -
- {user &&

{user.name}

} - {error &&

{error}

} -
- ); -}; - -interface TProps { - userId: string; -} -``` - -❌ Bad: -```typescript -// Wrong: Poor API client implementation -const badApiClient = { - getUser: async (id: string) => { - // Wrong: Using fetch instead of feature-fetch - const res = await fetch('/api/users/' + id); - // Wrong: No proper error handling - const data = await res.json(); - return data; - } -}; - -// Wrong: Poor data fetching implementation -const BadComponent = () => { - // Wrong: Not using React.useState - const [data, setData] = useState(); - - // Wrong: Not using React.useCallback - const fetchData = () => { - // Wrong: Using fetch directly - fetch('/api/data') - .then(res => res.json()) - .then(setData); - }; - - // Wrong: No error handling - return
{data}
; -}; -``` - -## Form Handling - -### Form Implementation -- Always use feature-form for form management -- Always handle loading and error states -- Always validate on the server -- Always provide user feedback - -✅ Good: -```typescript -'use client'; - -import React from 'react'; -import { createForm } from 'feature-form'; -import { useForm } from 'feature-react/form'; -import { Input, Button } from '@/components'; -import { SUserForm } from './schema'; -import type { TUserForm } from './types'; - -const $userForm = createForm({ - fields: { - name: { - validator: zValidator(z.string().min(2)), - defaultValue: '' - }, - email: { - validator: zValidator(z.email()), - defaultValue: '' - } - }, - onValidSubmit: async (data) => { - await submitUser(data); - } -}); - -interface TProps { - defaultValues?: Partial; -} - -export const UserForm: React.FC = ({ defaultValues }) => { - const [error, setError] = React.useState(); - const { handleSubmit, register, status } = useForm($userForm); - - const onSubmit = React.useCallback(async () => { - try { - await handleSubmit(); - setError(undefined); - } catch (err) { - setError(err.message); - } - }, [handleSubmit]); - - return ( -
- - {status('name').error && ( -

{status('name').error}

- )} - - {status('email').error && ( -

{status('email').error}

- )} - - {error && ( -

{error}

- )} -
- ); -}; -``` - -❌ Bad: -```typescript -'use client'; - -// Wrong: Not using feature-form -const BadForm = () => { - // Wrong: Manual form state management - const [formData, setFormData] = React.useState({}); - - // Wrong: Untyped event handler - const handleChange = (e) => { - setFormData({ - ...formData, - [e.target.name]: e.target.value - }); - }; - - // Wrong: No validation or error handling - const onSubmit = (e) => { - e.preventDefault(); - fetch('/api/submit', { - method: 'POST', - body: JSON.stringify(formData) - }); - }; - - return ( -
- - -
- ); -}; -``` - -## Related Rules -- [style-guide.mdc](mdc:.cursor/rules/style-guide.mdc): Core coding standards diff --git a/.cursor/rules/react.mdc b/.cursor/rules/react.mdc new file mode 100644 index 0000000..dfc4912 --- /dev/null +++ b/.cursor/rules/react.mdc @@ -0,0 +1,204 @@ +--- +description: React component patterns and conventions +globs: ['**/*.tsx'] +alwaysApply: false +--- + +# React Style Guide + +React component patterns and conventions for our codebase. + +## Component Definition + +- Always use `React.FC` pattern for components +- Always destructure props at the top with `const { ... } = props` +- Always define interface at the bottom of the file with `T` prefix +- Always use `useMemo` for computed values (especially switch statements) + +✅ Good: + +```tsx +export const StartButton: React.FC = (props) => { + const { status, onStart, onPause, className } = props; + + const { label, onClick } = React.useMemo(() => { + switch (status) { + case 'idle': + return { label: 'START', onClick: onStart }; + case 'running': + return { label: 'PAUSE', onClick: onPause }; + } + }, [status, onStart, onPause]); + + return ( + + ); +}; + +interface TStartButtonProps { + status: 'idle' | 'running'; + onStart: () => void; + onPause: () => void; + className?: string; +} +``` + +❌ Bad: + +```tsx +// Wrong: function declaration, I prefix, inline ternary +function StartButton({ status, onStart }: IStartButtonProps) { + const label = status === 'idle' ? 'START' : 'PAUSE'; + return ; +} + +interface IStartButtonProps { + status: 'idle' | 'running'; +} +``` + +## Props with Defaults + +- Always prefer props with defaults over module-level constants +- Always destructure with default values in props + +✅ Good: + +```tsx +export const NumberWheel: React.FC = (props) => { + const { value, min = 1, max = 60, itemWidth = 14 } = props; + // ... +}; + +interface TNumberWheelProps { + value: number; + min?: number; + max?: number; + itemWidth?: number; +} +``` + +❌ Bad: + +```tsx +const ITEM_WIDTH = 14; // Wrong: module-level constant + +export const NumberWheel: React.FC = (props) => { + // Uses ITEM_WIDTH instead of prop +}; +``` + +## Hooks + +- Always prefix custom hooks with `use` +- Always use `React.useCallback` for event handlers passed to children +- Always use `React.useMemo` for expensive computations +- Always use `React.useRef` for mutable values that don't trigger re-renders + +✅ Good: + +```tsx +export function useTimer(): TUseTimerReturn { + const [state, setState] = React.useState(initialState); + const intervalRef = React.useRef(null); + + const start = React.useCallback(() => { + setState((prev) => ({ ...prev, status: 'running' })); + }, []); + + return { state, start }; +} + +interface TUseTimerReturn { + state: TTimerState; + start: () => void; +} +``` + +## Component Structure + +Larger components follow a consistent section order (skip MARK comments for small components): + +1. **Top** - Props destructuring, useState, useRef, useMemo +2. **`// MARK: - Actions`** - useCallback handlers +3. **`// MARK: - Effects`** - useEffect hooks +4. **`// MARK: - UI`** - return JSX + +✅ Good: + +```tsx +export const Timer: React.FC = (props) => { + const { initialTime, onComplete } = props; + + const [time, setTime] = React.useState(initialTime); + const intervalRef = React.useRef(null); + + const isRunning = React.useMemo(() => time > 0, [time]); + + // MARK: - Actions + + const start = React.useCallback(() => { + intervalRef.current = window.setInterval(() => { + setTime((prev) => prev - 1); + }, 1000); + }, []); + + const stop = React.useCallback(() => { + if (intervalRef.current != null) { + clearInterval(intervalRef.current); + } + }, []); + + // MARK: - Effects + + React.useEffect(() => { + if (time === 0) { + stop(); + onComplete?.(); + } + }, [time, stop, onComplete]); + + // MARK: - UI + + return ( +
+ {/* Time display */} + {time} + + {/* Controls */} + +
+ ); +}; +``` + +## Comments + +- Use `{/* Label */}` in JSX for layout structure (helps skimming) +- Use `// Note:` prefix for non-obvious explanations +- Never restate what code does - explain WHY if not obvious +- Keep comments concise - one line when possible + +## File Structure + +- Always organize features with `components/` and `hooks/` folders +- Always use barrel exports with `export * from` + +✅ Good: + +``` +features/ + timer/ + components/ + TimerDial.tsx + StartButton.tsx + index.ts # export * from './TimerDial'; etc. + hooks/ + use-timer.ts + index.ts # export * from './use-timer'; + TimerView.tsx + types.ts + index.ts # export * from './TimerView'; etc. +``` diff --git a/.cursor/rules/rust.mdc b/.cursor/rules/rust.mdc index b36d74b..bdd7887 100644 --- a/.cursor/rules/rust.mdc +++ b/.cursor/rules/rust.mdc @@ -128,15 +128,13 @@ pub async fn upsert(input: &UpsertInput) -> Result { ``` ### Section Dividers +- Always use `// MARK: -` style section dividers (Xcode convention) - Always use section dividers to organize large files into logical sections -- Always use consistent divider style - Always place dividers before major sections, not between every function ✅ Good: ```rust -// ============================================================================= -// App Repository -// ============================================================================= +// MARK: - App Repository pub struct AppRepository; @@ -144,9 +142,7 @@ impl AppRepository { // ... } -// ============================================================================= -// App Activity Repository -// ============================================================================= +// MARK: - App Activity Repository pub struct AppActivityRepository; ``` @@ -339,9 +335,7 @@ pub fn insert(input: &UpsertInput) -> Result, Error> { // Wrong: No ✅ Good: ```rust -// ============================================================================= -// App Repository -// ============================================================================= +// MARK: - App Repository pub struct AppRepository; diff --git a/.cursor/rules/swift.mdc b/.cursor/rules/swift.mdc new file mode 100644 index 0000000..b16ea70 --- /dev/null +++ b/.cursor/rules/swift.mdc @@ -0,0 +1,425 @@ +--- +description: Swift and SwiftUI coding standards and style guidelines +globs: ['**/*.swift'] +alwaysApply: false +--- + +# Swift Style Guide + +Swift and SwiftUI coding standards and style guidelines for our iOS codebase. These guidelines ensure consistency, maintainability, and high code quality across Swift projects. + +## Core Principles + +- **KISS (Keep It Simple, Stupid)** - Always choose the simplest, most maintainable solution +- **SwiftUI First** - Always prefer SwiftUI over UIKit when possible +- **Less is More** - Always avoid unnecessary complexity, the best code is no code +- **Self-Documenting** - Always make code obvious and clear without comments + +## Linter Errors and False Positives + +### Ignoring False Positive Errors + +**Always ignore false positive linter errors from Cursor/VS Code** when working with Swift code. The Swift language server in VS Code/Cursor cannot properly resolve Swift symbols and dependencies that are correctly configured in Xcode. + +**Common false positive errors to ignore:** + +- `Cannot find 'X' in scope` - When X is clearly defined in the codebase +- `Reference to member 'X' cannot be resolved without a contextual type` - When X is a valid SwiftUI/UIKit type +- `No such module 'X'` - When the module is correctly imported in Xcode +- `Value of type 'X' has no member 'Y'` - When Y is a valid member in Xcode +- Any reference errors for custom views, models, or utilities that compile successfully in Xcode + +**Workflow:** + +- Use Cursor for AI assistance and code generation +- Use Xcode for actual development and compilation +- Only report real compilation errors from Xcode, not linter errors from Cursor/VS Code +- Trust Xcode's build system over Cursor's language server for Swift + +## File Organization + +### Directory Structure + +- Always organize code in a predictable and scalable way +- Always keep related code close together +- Always use clear, descriptive directory names +- Always follow consistent patterns across the project +- Always use singular for categories/domains (e.g. `Feature/`, `Model/`, `View/`) +- Always use plural for collections/lists (e.g. `Features/`, `Models/`, `Views/`) + +✅ Good: + +```swift +Tapling/ + Features/ + Collectible/ + Environment/ + Models/ + CollectibleRegistry.swift + Views/ + Routes/ + Settings/ + SettingsView.swift + Views/ + ActionRowView.swift +``` + +❌ Bad: + +```swift +Tapling/ + feature/ // Wrong: Should be Features (plural) + collectible/ // Wrong: Should be Collectible (PascalCase) + model/ // Wrong: Should be Models (plural) +``` + +### File Naming + +- Always use `PascalCase` for Swift files (e.g. `SettingsView.swift`, `TaplingSettings.swift`) +- Always match the file name to the primary type/struct/class it contains +- Always use descriptive names that indicate purpose + +✅ Good: + +```swift +SettingsView.swift // Contains SettingsView struct +TaplingSettings.swift // Contains TaplingSettings class +ActionRowView.swift // Contains ActionRowView struct +``` + +❌ Bad: + +```swift +settings.swift // Wrong: Should be PascalCase +Settings.swift // Wrong: Too generic +View.swift // Wrong: Not descriptive +``` + +## SwiftUI View Structure + +### View Organization + +- Always follow the 3-layer structure: Variables → UI → Actions +- Always use `// MARK: - UI` to separate UI components from actions +- Always use `// MARK: - Actions` to separate actions from UI +- Never add more than these 2 MARKs - if you need more organization, split the view + +✅ Good: + +```swift +struct SettingsView: View { + // Variables (no MARK needed) + @State private var isEnabled = false + @QuerySingleton private var settings: Settings + + // MARK: - UI + + var body: some View { + Form { + headerSection + } + } + + private var headerSection: some View { + Section { + Toggle("Enabled", isOn: isEnabledBinding) + } + } + + // MARK: - Actions + + private func saveSettings() { + try? modelContext.save() + } +} +``` + +❌ Bad: + +```swift +struct SettingsView: View { + // MARK: - Properties // Wrong: No MARK for variables + @State private var isEnabled = false + + // MARK: - UI + var body: some View { } + + // MARK: - Search UI // Wrong: Too many MARKs + // MARK: - Filter UI // Wrong: Split into separate views instead + // MARK: - Actions +} +``` + +### View Components + +- Always use computed properties for view sections +- Always use descriptive names ending with `Section`, `View`, or `Button` (e.g. `headerSection`, `settingsForm`, `saveButton`) +- Always keep view components private unless they need to be reused elsewhere + +✅ Good: + +```swift +private var headerSection: some View { + VStack { + Text("Title") + } +} + +private var settingsForm: some View { + Form { + // ... + } +} +``` + +❌ Bad: + +```swift +var header: some View { } // Wrong: Not descriptive +public var section: some View { } // Wrong: Should be private unless reused +``` + +## Naming Conventions + +### Types and Structures + +- Always use `PascalCase` for types, structs, classes, enums, protocols +- Always use descriptive names that clearly indicate purpose +- Always prefix protocols with descriptive names (e.g. `SingletonModel`, not `Model`) + +✅ Good: + +```swift +struct SettingsView: View { } +class DataContainer { } +protocol SingletonModel { } +enum Rarity { } +``` + +❌ Bad: + +```swift +struct view: View { } // Wrong: Should be PascalCase +class container { } // Wrong: Should be PascalCase +protocol Model { } // Wrong: Too generic +``` + +### Variables and Functions + +- Always use `camelCase` for variables and functions +- Always use descriptive names that indicate purpose +- Always use verb phrases for functions that perform actions +- Always use noun phrases for computed properties + +✅ Good: + +```swift +private var isEnabled = false +private func saveSettings() { } +private func formatDate(_ date: Date) -> String { } +private var headerSection: some View { } +``` + +❌ Bad: + +```swift +var enabled = false // Wrong: Should indicate boolean +func save() { } // Wrong: Too generic +func date(_ d: Date) -> String { } // Wrong: Not a verb phrase +``` + +### Property Wrappers + +- Always use appropriate property wrappers (`@State`, `@Query`, `@QuerySingleton`, `@Environment`, etc.) +- Always make property wrapper variables `private` unless they need external access +- Always use descriptive names that indicate the property's purpose + +✅ Good: + +```swift +@State private var isEnabled = false +@QuerySingleton private var settings: TaplingSettings +@Environment(\.modelContext) private var modelContext +``` + +❌ Bad: + +```swift +@State var enabled = false // Wrong: Should be private +@Query var items: [Item] // Wrong: Should be private +``` + +## Code Style + +### Imports + +- Always import only what you need +- Always group imports logically (Foundation, SwiftUI, SwiftData, then third-party) +- Always use explicit imports when possible + +✅ Good: + +```swift +import Foundation +import SwiftData +import SwiftUI +import KeyboardKit +``` + +❌ Bad: + +```swift +import * // Wrong: Not valid Swift +import Foundation.SwiftUI // Wrong: Incorrect import syntax +``` + +### Spacing and Formatting + +- Always use consistent indentation (spaces, not tabs) +- Always add blank lines between logical sections +- Always use trailing commas in multi-line arrays/dictionaries +- Always format code consistently with Xcode's formatter + +✅ Good: + +```swift +let items = [ + "item1", + "item2", + "item3", +] +``` + +❌ Bad: + +```swift +let items = ["item1","item2","item3"] // Wrong: No spacing +``` + +### Error Handling + +- Always handle errors explicitly +- Always use `try?` when errors can be safely ignored +- Always use `do-catch` when error handling is important +- Always provide meaningful error messages + +✅ Good: + +```swift +do { + try modelContext.save() +} catch { + print("Failed to save: \(error)") +} + +// Or when error can be ignored +try? modelContext.save() +``` + +❌ Bad: + +```swift +try modelContext.save() // Wrong: Unhandled error +``` + +## SwiftData Patterns + +### Model Definitions + +- Always use `@Model` macro for SwiftData models +- Always provide default values where appropriate +- Always use `SingletonModel` protocol for singleton models + +✅ Good: + +```swift +@Model +final class TaplingSettings: SingletonModel { + var scale: Double = 1.0 + var position: HandPosition = .center + + static var `default`: TaplingSettings { + TaplingSettings() + } +} +``` + +❌ Bad: + +```swift +class TaplingSettings { // Wrong: Missing @Model + var scale: Double // Wrong: No default value +} +``` + +### Querying Data + +- Always use `@Query` for collections +- Always use `@QuerySingleton` for singleton models +- Always make query properties `private` + +✅ Good: + +```swift +@Query private var collectibles: [OwnedCollectible] +@QuerySingleton private var settings: TaplingSettings +``` + +❌ Bad: + +```swift +@Query var items: [Item] // Wrong: Should be private +``` + +## Documentation + +### Comments + +- Always use comments sparingly - code should be self-documenting +- Always use `///` for documentation comments +- Always explain "why" not "what" in comments + +✅ Good: + +```swift +/// Ensures singleton models exist in the given context. +/// Creates default instances if they don't exist. +static func ensureSingletons(in context: ModelContext) { + // ... +} +``` + +❌ Bad: + +```swift +// This function ensures singletons +// It creates default instances +static func ensureSingletons(in context: ModelContext) { + // ... +} +``` + +## Testing + +### Test Structure + +- Always organize tests to match source structure +- Always use descriptive test names that explain what is being tested +- Always use `XCTest` for unit tests + +✅ Good: + +```swift +func testSettingsDefaultValues() { + let settings = TaplingSettings.default + XCTAssertEqual(settings.scale, 1.0) +} +``` + +❌ Bad: + +```swift +func test1() { // Wrong: Not descriptive + // ... +} +``` diff --git a/.cursor/rules/typescript.mdc b/.cursor/rules/typescript.mdc index a39889e..940531f 100644 --- a/.cursor/rules/typescript.mdc +++ b/.cursor/rules/typescript.mdc @@ -1,7 +1,7 @@ --- description: TypeScript coding standards and style guidelines -globs: ["**/*.ts", "**/*.tsx"] -alwaysApply: true +globs: ['**/*.ts', '**/*.tsx'] +alwaysApply: false --- # TypeScript Style Guide @@ -18,6 +18,7 @@ TypeScript coding standards and style guidelines for our codebase. These guideli ## File Organization ### Directory Structure + - Always organize code in a predictable and scalable way - Always keep related code close together - Always use clear, descriptive directory names @@ -26,49 +27,53 @@ TypeScript coding standards and style guidelines for our codebase. These guideli - Always use plural for collections/lists (e.g. `components/`, `hooks/`, `utils/`) ✅ Good: + ```typescript src/ auth/ # Singular: domain components/ # Plural: collection hooks/ # Plural: collection lib/ # Singular: category - + user/ # Singular: domain components/ # Plural: collection hooks/ # Plural: collection lib/ # Singular: category - + lib/ # Singular: core category components/ # Plural: shared collection hooks/ # Plural: shared collection ``` ❌ Bad: + ```typescript src/ auths/ # Wrong: Category should be singular component/ # Wrong: Collection should be plural - + users/ # Wrong: Category should be singular hook/ # Wrong: Collection should be plural - + libraries/ # Wrong: Category should be singular shared-components/ # Wrong: Use simple plural ``` ### Files & Directories + - Always use consistent and predictable naming patterns - Always make names descriptive and purpose-indicating - Always follow established community conventions ✅ Good: + ```typescript // Directories (kebab-case) src/ auth/ - components/ - hooks/ - lib/ + components/ + hooks/ + lib/ // Regular Files (kebab-case) user-service.ts @@ -89,6 +94,7 @@ CacheManager.ts ``` ❌ Bad: + ```typescript // Directories (mixed case) src/ @@ -105,217 +111,396 @@ Api.Client.ts # Wrong: PascalCase with dots ``` ### Code Identifiers + - Always use clear, descriptive names that indicate purpose - Always follow TypeScript community standards - Always maintain consistent prefixing for special types ✅ Good: + ```typescript // Variables & Functions (camelCase) const currentUser = getCurrentUser(); const isValidEmail = validateEmail(email); -const calculateTotalPrice = (items: TOrderItem[]): number => { - return items.reduce((sum, item) => sum + item.price, 0); -}; +function calculateTotalPrice(items: TOrderItem[]): number { + return items.reduce((sum, item) => sum + item.price, 0); +} -// Interfaces & Types (T prefix) -type TUser = { - id: string; - email: string; - profile: TUserProfile; -}; +// Interfaces (T prefix) - Always use for object shapes +interface TUser { + id: string; + email: string; + profile: TUserProfile; +} -type TOrderItem = { - id: string; - productId: string; - quantity: number; - price: number; -}; +interface TOrderItem { + id: string; + productId: string; + quantity: number; + price: number; +} + +// Types (T prefix) - Only use when interface is not possible +type TOrderStatus = 'pending' | 'processing' | 'completed'; // Union +type TUserOrNull = TUser | null; // Union with null +type TPartialUser = Partial; // Mapped type +type TUserConfig = Required; // Utility type // Enums (E prefix) enum EOrderStatus { - Pending = 'pending', - Processing = 'processing', - Completed = 'completed', - Cancelled = 'cancelled' + Pending = 'pending', + Processing = 'processing', + Completed = 'completed', + Cancelled = 'cancelled' } enum EUserRole { - Admin = 'admin', - Customer = 'customer', - Guest = 'guest' + Admin = 'admin', + Customer = 'customer', + Guest = 'guest' } // Schemas (S prefix) const SUserProfile = z.object({ - firstName: z.string().min(2), - lastName: z.string().min(2), - dateOfBirth: z.iso.datetime().optional(), - phoneNumber: z.string().regex(/^\+?[1-9]\d{1,14}$/).optional() + firstName: z.string().min(2), + lastName: z.string().min(2), + dateOfBirth: z.iso.datetime().optional(), + phoneNumber: z + .string() + .regex(/^\+?[1-9]\d{1,14}$/) + .optional() }); const SOrderCreate = z.object({ - userId: z.string().uuid(), - items: z.array(z.object({ - productId: z.string().uuid(), - quantity: z.number().int().positive() - })) + userId: z.string().uuid(), + items: z.array( + z.object({ + productId: z.string().uuid(), + quantity: z.number().int().positive() + }) + ) }); ``` ❌ Bad: + ```typescript // Variables & Functions (inconsistent) -const CurrentUser = getCurrentUser(); # Wrong: PascalCase -const valid_email = validate_email(); # Wrong: snake_case -const CALCULATE_PRICE = () => {}; # Wrong: UPPER_CASE - -// Types & Interfaces (missing prefix) -type User = { # Wrong: Missing T prefix - ID: string; # Wrong: UPPER_CASE - Email: string; # Wrong: PascalCase +const CurrentUser = getCurrentUser(); // Wrong: PascalCase +const valid_email = validate_email(); // Wrong: snake_case +const CALCULATE_PRICE = () => {}; // Wrong: UPPER_CASE + +// Types & Interfaces (missing prefix or wrong keyword) +type User = { // Wrong: Missing T prefix + ID: string; // Wrong: UPPER_CASE + Email: string; // Wrong: PascalCase }; -interface OrderItem { # Wrong: Missing T prefix - product_id: string; # Wrong: snake_case - Quantity: number; # Wrong: PascalCase -} +type TOrderItem = { // Wrong: Use interface for objects + product_id: string; // Wrong: snake_case + Quantity: number; // Wrong: PascalCase +}; + +interface TUserStatus = 'active' | 'inactive'; // Wrong: Can't use interface for unions // Enums (inconsistent) -enum OrderStatus { # Wrong: Missing E prefix - PENDING = 'PENDING', # Wrong: All caps - Processing = 'Processing', # Wrong: PascalCase value - completed = 'completed' # Wrong: camelCase +enum OrderStatus { // Wrong: Missing E prefix + PENDING = 'PENDING', // Wrong: All caps + Processing = 'Processing', // Wrong: PascalCase value + completed = 'completed' // Wrong: camelCase } // Schemas (inconsistent) -const userSchema = z.object({ # Wrong: Missing S prefix - FirstName: z.string(), # Wrong: PascalCase - last_name: z.string(), # Wrong: snake_case - DOB: z.iso.datetime() # Wrong: Abbreviation +const userSchema = z.object({ // Wrong: Missing S prefix + FirstName: z.string(), // Wrong: PascalCase + last_name: z.string(), // Wrong: snake_case + DOB: z.iso.datetime() // Wrong: Abbreviation }); ``` ## Code Style ### Type Safety + - Always define explicit types for better maintainability - Always use TypeScript's type system to prevent runtime errors - Always make code intentions clear through typing ✅ Good: + ```typescript async function getUser(id: string): Promise { - const user = await db.users.findUnique({ where: { id } }); - if (user == null) { - throw new Error('User not found'); - } - return user; + const user = await db.users.findUnique({ where: { id } }); + if (user == null) { + throw new Error('User not found'); + } + return user; } ``` ❌ Bad: + ```typescript async function getUser(id) { - const user = await db.users.findUnique({ where: { id } }); - if (!user) throw new Error('User not found'); - return user; + const user = await db.users.findUnique({ where: { id } }); + if (!user) throw new Error('User not found'); + return user; } ``` ### Null Checks + - Always be explicit about null/undefined checks - Always handle edge cases clearly and consistently - Always prevent runtime null/undefined errors ✅ Good: + ```typescript if (user == null) { - throw new Error('User is required'); + throw new Error('User is required'); } const name = user.name ?? 'Anonymous'; ``` ❌ Bad: + ```typescript if (!user) { - throw new Error('User is required'); + throw new Error('User is required'); } const name = user.name || 'Anonymous'; ``` ### Functions + - Always keep functions focused and single-purpose - Always use function declarations for named functions - Always use arrow functions only for callbacks and inline functions ✅ Good: + ```typescript function processUser(user: TUser): void { - // Implementation + // Implementation } -users.map(user => user.name); +users.map((user) => user.name); ``` ❌ Bad: + ```typescript const processUser = (user: TUser): void => { - // Implementation -} + // Implementation +}; -users.map(function(user) { return user.name; }); +users.map(function (user) { + return user.name; +}); ``` ### Conditionals + - Always keep conditionals simple and flat -- Always use early returns to reduce nesting +- Always use early returns for guard clauses (invalid states) - Always avoid deeply nested conditions +- Always prefer single exit point for main flow when possible ✅ Good: + ```typescript -// Early return pattern +// Guard clauses for invalid states function processUser(user: TUser): void { - if (user == null) { - return; - } - - if (!user.isActive) { - return; - } - - processActiveUser(user); + if (user == null) { + return; + } + + if (!user.isActive) { + return; + } + + processActiveUser(user); +} + +// Single exit point for main flow +async function handleMessage(ctx: TBotContext): Promise { + const session = getSession(ctx); + if (session == null) { + return; + } + + await processMessage(ctx); + await sendResponse(ctx); + + const finalState = getState(ctx); + if (finalState.isComplete) { + await handleComplete(ctx); + } } // Simple boolean check function isValidUser(user: TUser): boolean { - return user != null && user.isActive; + return user != null && user.isActive; } ``` ❌ Bad: + ```typescript // Deeply nested conditions function processUser(user: TUser): void { - if (user != null) { - if (user.isActive) { - if (user.permissions != null) { - if (user.permissions.canEdit) { - processActiveUser(user); - } - } - } - } + if (user != null) { + if (user.isActive) { + if (user.permissions != null) { + if (user.permissions.canEdit) { + processActiveUser(user); + } + } + } + } } // Complex nested ternary -const userName = user - ? user.profile - ? user.profile.name - ? user.profile.name - : 'No name' - : 'No profile' - : 'No user'; +const userName = user + ? user.profile + ? user.profile.name + ? user.profile.name + : 'No name' + : 'No profile' + : 'No user'; +``` + +## Code Organization + +### Section Markers + +- Always use `// MARK: -` for section dividers (Xcode/IDE compatible) +- Always place section markers at the same indentation level as the code they describe + +✅ Good: + +```typescript +// MARK: - Main Class + +export class UserService { + // MARK: - Properties + + private readonly db: Database; + + // MARK: - Public Methods + + public getUser(id: string): TUser { + // ... + } + + // MARK: - Private Helpers + + private validateId(id: string): boolean { + // ... + } +} +``` + +❌ Bad: + +```typescript +// ============================================================================ +// Main Class +// ============================================================================ + +// === Properties === + +// --- Public Methods --- +``` + +### Conditional Clarity + +- Always use named variables for complex conditions (self-documenting) +- Always prefer variables over comments for explaining what a condition checks + +✅ Good: + +```typescript +const isLargeEnough = widthPx >= minBlockPx; +if (isLargeEnough) { + renderBlock(block); +} + +const needsClipping = startMs < boundsStart || endMs > boundsEnd; +if (needsClipping) { + return clipToBounds(block); +} +``` + +❌ Bad: + +```typescript +// Check if block is large enough to render +if (widthPx >= minBlockPx) { + renderBlock(block); +} + +// Needs clipping if outside bounds +if (startMs < boundsStart || endMs > boundsEnd) { + return clipToBounds(block); +} +``` + +### Array Length Checks + +- Always use `!array.length` for empty checks (concise, handles undefined) +- Always use `array.length > 0` for non-empty checks (explicit intent) + +✅ Good: + +```typescript +// Empty check - concise and handles undefined +if (!items.length) { + return []; +} + +// Non-empty check - explicit "has items" +if (users.length > 0) { + processUsers(users); +} +``` + +❌ Bad: + +```typescript +// Verbose empty check +if (items.length === 0) { + return []; +} + +// Relies on truthiness - less explicit +if (users.length) { + processUsers(users); +} +``` + +## Barrel Exports + +- Always use `export * from` in index files +- Always keep barrel files simple and flat + +✅ Good: + +```typescript +// index.ts +export * from './Button'; +export * from './Input'; +export * from './Modal'; +``` + +❌ Bad: + +```typescript +// index.ts +export { Button } from './Button'; +export { Input } from './Input'; +export { Modal } from './Modal'; ``` diff --git a/.cursor/rules/xml-tokenizer.mdc b/.cursor/rules/xml-tokenizer.mdc deleted file mode 100644 index 9b09548..0000000 --- a/.cursor/rules/xml-tokenizer.mdc +++ /dev/null @@ -1,600 +0,0 @@ ---- -description: -globs: -alwaysApply: false ---- -# XML Tokenizer - -Stream-based XML/HTML parsing patterns and best practices using the xml-tokenizer library. This library provides a callback-based tokenization approach for efficient XML/HTML processing. - -## Core Principles -- **Stream Processing** - Always use callback-based streaming for memory efficiency -- **Type Safety** - Always use TypeScript types for tokens and configurations -- **Early Termination** - Always terminate parsing early when target data is found -- **Error Handling** - Always handle parsing errors gracefully with meaningful messages - -## Import Patterns - -### Essential Imports -- Always import specific functions and types you need -- Always use the `htmlConfig` for HTML parsing -- Always import `TXmlToken` type for token handling - -✅ Good: -```typescript -import { tokenize, htmlConfig, type TXmlToken } from 'xml-tokenizer'; -``` - -❌ Bad: -```typescript -import * as xmlTokenizer from 'xml-tokenizer'; // Wrong: Avoid namespace imports -import { tokenize } from 'xml-tokenizer'; // Wrong: Missing config and types -``` - -## Basic Usage Patterns - -### HTML Parsing -- Always use `htmlConfig` when parsing HTML content -- Always handle different token types in the callback -- Always provide type-safe token handling - -**HTML Configuration Features:** -- `strictDocument: false` - Allows non-strict HTML structure -- `rawTextElements: ['script', 'style', 'title', 'textarea']` - Handles raw text content -- `implicitSelfClosingElements: [...]` - Recognizes HTML void elements (br, img, etc.) -- `allowDtd: true` - Allows DTD declarations - -✅ Good: -```typescript -import { htmlConfig, type TXmlToken } from 'xml-tokenizer'; - -function parseHtml(html: string): void { - tokenize( - html, - (token: TXmlToken, stream) => { - switch (token.type) { - case 'ElementStart': - // HTML config recognizes void elements automatically - console.log(`Element: ${token.local}`); - break; - case 'Attribute': - // HTML config handles attributes without values as "true" - console.log(`${token.local}="${token.value}"`); - break; - case 'ElementEnd': - if (token.end.type === 'Empty') { - console.log('Self-closing element'); - } - break; - case 'Text': - console.log(`Text: ${token.text}`); - break; - default: - break; - } - }, - htmlConfig // Essential for HTML parsing - ); -} -``` - -❌ Bad: -```typescript -function parseHtml(html: string): void { - tokenize(html, (token) => { // Wrong: Missing types and config - if (token.type === 'ElementStart') { - // Handle element - } - // Wrong: No comprehensive token handling - }); -} -``` - -### XML Parsing -- Always use `xmlConfig` for strict XML content -- Always validate XML structure when needed -- Always handle namespaces properly - -**XML Configuration Features:** -- `strictDocument: true` - Enforces strict XML structure and validation -- `allowDtd: true` - Allows DTD declarations -- `rawTextElements: null` - No raw text elements (all content is parsed) -- `implicitSelfClosingElements: null` - No implicit self-closing elements - -✅ Good: -```typescript -import { xmlConfig, type TXmlToken } from 'xml-tokenizer'; - -function parseXml(xml: string): void { - tokenize( - xml, - (token: TXmlToken, stream) => { - switch (token.type) { - case 'ElementStart': - // XML config enforces proper namespace handling - const qName = token.prefix ? `${token.prefix}:${token.local}` : token.local; - console.log(`XML Element: ${qName}`); - break; - case 'Text': - if (token.text.trim()) { - console.log(`Text: ${token.text}`); - } - break; - case 'Attribute': - // XML config requires explicit attribute values - console.log(`Attribute: ${token.local}="${token.value}"`); - break; - default: - break; - } - }, - xmlConfig // Strict XML parsing - ); -} -``` - -❌ Bad: -```typescript -function parseXml(xml: string): void { - tokenize(xml, (token) => { // Wrong: Missing types - console.log(token); // Wrong: Not handling specific token types - }, htmlConfig); // Wrong: Using HTML config for XML -} -``` - -### SVG Parsing -- Always use `svgConfig` for SVG content -- Always understand SVG-specific parsing behavior -- Always handle SVG elements and structure properly - -**SVG Configuration Features:** -- `strictDocument: false` - Allows non-strict SVG structure -- `rawTextElements: ['style']` - Handles style elements as raw text -- `implicitSelfClosingElements: []` - No implicit self-closing elements -- `allowDtd: true` - Allows DTD declarations - -✅ Good: -```typescript -import { svgConfig, type TXmlToken } from 'xml-tokenizer'; - -function parseSvg(svg: string): void { - tokenize( - svg, - (token: TXmlToken, stream) => { - switch (token.type) { - case 'ElementStart': - // SVG config handles SVG-specific elements - console.log(`SVG Element: ${token.local}`); - break; - case 'Attribute': - // Handle SVG attributes (viewBox, d, etc.) - console.log(`SVG Attribute: ${token.local}="${token.value}"`); - break; - case 'Text': - if (token.text.trim()) { - console.log(`SVG Text: ${token.text}`); - } - break; - default: - break; - } - }, - svgConfig // SVG-specific parsing - ); -} -``` - -❌ Bad: -```typescript -function parseSvg(svg: string): void { - tokenize(svg, (token) => { - // Parse logic - }); // Wrong: No config specified, may not handle SVG properly -} -``` - -## Advanced Patterns - -### Stream Control -- Always use `stream.goToEnd()` to terminate parsing early -- Always use stream control for performance optimization -- Always check stream state before continuing - -✅ Good: -```typescript -function findSpecificData(html: string): string | null { - let foundData: string | null = null; - - tokenize( - html, - (token: TXmlToken, stream) => { - if (token.type === 'Attribute' && token.local === 'data-target') { - foundData = token.value; - stream.goToEnd(); // Stop processing immediately - } - }, - htmlConfig - ); - - return foundData; -} -``` - -❌ Bad: -```typescript -function findSpecificData(html: string): string | null { - let foundData: string | null = null; - - tokenize(html, (token) => { - if (token.type === 'Attribute' && token.local === 'data-target') { - foundData = token.value; - // Wrong: Continue processing unnecessarily - } - }, htmlConfig); - - return foundData; -} -``` - -### State Management -- Always maintain parsing state outside the callback -- Always use clear state tracking for complex parsing -- Always reset state appropriately - -✅ Good: -```typescript -function parseMetaTags(html: string): Record { - const metaTags: Record = {}; - let isInMetaTag = false; - let currentAttributes: Record = {}; - - tokenize( - html, - (token: TXmlToken, stream) => { - switch (token.type) { - case 'ElementStart': - if (token.local.toLowerCase() === 'meta') { - isInMetaTag = true; - currentAttributes = {}; - } - break; - - case 'Attribute': - if (isInMetaTag) { - currentAttributes[token.local] = token.value; - } - break; - - case 'ElementEnd': - if (isInMetaTag) { - const name = currentAttributes.name; - const content = currentAttributes.content; - if (name && content) { - metaTags[name] = content; - } - isInMetaTag = false; - currentAttributes = {}; - } - break; - - default: - break; - } - }, - htmlConfig - ); - - return metaTags; -} -``` - -❌ Bad: -```typescript -function parseMetaTags(html: string): Record { - const metaTags: Record = {}; - - tokenize(html, (token) => { // Wrong: Missing types and complex state logic - if (token.type === 'ElementStart' && token.local === 'meta') { - // Wrong: No state management for attributes - } - }, htmlConfig); - - return metaTags; -} -``` - -## Error Handling - -### Parsing Errors -- Always wrap tokenization in try-catch blocks -- Always provide meaningful error messages -- Always log parsing errors for debugging - -✅ Good: -```typescript -function safeParseHtml(html: string): TParseResult { - try { - const result = extractDataFromHtml(html); - return { success: true, data: result }; - } catch (error) { - logger.error('Failed to parse HTML', { error }); - return { - success: false, - error: 'Could not parse HTML content' - }; - } -} - -function extractDataFromHtml(html: string): TExtractedData { - let data: TExtractedData | null = null; - - tokenize( - html, - (token: TXmlToken, stream) => { - // Parse logic here - }, - htmlConfig - ); - - if (data == null) { - throw new Error('Required data not found in HTML'); - } - - return data; -} -``` - -❌ Bad: -```typescript -function parseHtml(html: string): TParseResult { - let data: TExtractedData | null = null; - - tokenize(html, (token) => { // Wrong: No error handling - // Parse logic - }, htmlConfig); - - return data; // Wrong: Could return null without handling -} -``` - -## Performance Optimization - -### Memory Efficiency -- Always use streaming approach for large documents -- Always avoid storing unnecessary token data -- Always terminate parsing when target data is found - -✅ Good: -```typescript -function findFirstMatch(html: string, targetAttribute: string): string | null { - let result: string | null = null; - - tokenize( - html, - (token: TXmlToken, stream) => { - if (token.type === 'Attribute' && token.local === targetAttribute) { - result = token.value; - stream.goToEnd(); // Immediately stop processing - } - }, - htmlConfig - ); - - return result; -} -``` - -❌ Bad: -```typescript -function findAllMatches(html: string, targetAttribute: string): string[] { - const results: string[] = []; - - tokenize(html, (token) => { - if (token.type === 'Attribute' && token.local === targetAttribute) { - results.push(token.value); - // Wrong: Continue processing even if only first match needed - } - }, htmlConfig); - - return results.slice(0, 1); // Wrong: Process everything then filter -} -``` - -## Common Token Types - -### Element Tokens -- Always handle `ElementStart` for opening tags -- Always handle `ElementEnd` for closing tags and self-closing tags -- Always check `ElementEnd.end.type` for different closing patterns - -✅ Good: -```typescript -function handleElementTokens(token: TXmlToken): void { - switch (token.type) { - case 'ElementStart': - console.log(`Opening tag: <${token.local}>`); - break; - - case 'ElementEnd': - if (token.end.type === 'Empty') { - console.log('Self-closing tag'); - } else if (token.end.type === 'Close') { - console.log(`Closing tag: `); - } else if (token.end.type === 'Open') { - console.log('Tag opened for content'); - } - break; - - default: - break; - } -} -``` - -❌ Bad: -```typescript -function handleElementTokens(token: TXmlToken): void { - if (token.type === 'ElementStart') { - console.log(token.local); // Wrong: Not comprehensive handling - } - // Wrong: Missing ElementEnd handling -} -``` - -### Attribute Tokens -- Always access attribute name via `token.local` -- Always access attribute value via `token.value` -- Always handle attribute prefixes when needed - -✅ Good: -```typescript -function handleAttribute(token: TXmlToken): void { - if (token.type === 'Attribute') { - const fullName = token.prefix - ? `${token.prefix}:${token.local}` - : token.local; - console.log(`Attribute: ${fullName}="${token.value}"`); - } -} -``` - -❌ Bad: -```typescript -function handleAttribute(token: TXmlToken): void { - if (token.type === 'Attribute') { - console.log(`${token.local}=${token.value}`); // Wrong: Missing quotes and prefix handling - } -} -``` - -## Custom Configuration - -### Creating Custom Configurations -- Always create custom configurations for specific parsing needs -- Always use proper TypeScript typing with `TXmlStreamOptions` -- Always document custom configuration choices - -✅ Good: -```typescript -import { type TXmlStreamOptions, tokenize, type TXmlToken } from 'xml-tokenizer'; - -// Custom configuration for specific parsing needs -const customConfig: TXmlStreamOptions = { - strictDocument: false, - allowDtd: false, // Disable DTD for security - rawTextElements: ['script', 'style', 'pre'], - implicitSelfClosingElements: ['br', 'hr', 'img'], - contextSliceSize: 50 // Larger context for debugging -}; - -function parseWithCustomConfig(content: string): void { - tokenize( - content, - (token: TXmlToken, stream) => { - // Handle parsing with custom configuration - }, - customConfig - ); -} -``` - -❌ Bad: -```typescript -// Wrong: Hardcoded configuration without explanation -function parseContent(content: string): void { - tokenize(content, (token) => { - // Parse logic - }, { - strictDocument: false, // Wrong: No explanation of why - allowDtd: true, - rawTextElements: null, - implicitSelfClosingElements: null, - contextSliceSize: 30 - }); -} -``` - -### Configuration Selection by Content Type -- Always choose the appropriate configuration for your content type -- Always provide fallback configurations for unknown content types -- Always document configuration selection logic - -✅ Good: -```typescript -import { htmlConfig, xmlConfig, svgConfig, type TXmlStreamOptions } from 'xml-tokenizer'; - -function parseByContentType(content: string, contentType: string): void { - let config: TXmlStreamOptions; - - switch (contentType) { - case 'text/html': - config = htmlConfig; - break; - case 'application/xml': - case 'text/xml': - config = xmlConfig; - break; - case 'image/svg+xml': - config = svgConfig; - break; - default: - config = htmlConfig; // Default to HTML config - break; - } - - tokenize(content, (token: TXmlToken, stream) => { - // Handle parsing - }, config); -} -``` - -❌ Bad: -```typescript -function parseContent(content: string, contentType: string): void { - // Wrong: Always using same config regardless of content type - tokenize(content, (token) => { - // Parse logic - }, htmlConfig); -} -``` - -## Debugging - -### Debug Logging -- Always log parsing errors with context -- Always save problematic HTML/XML for debugging -- Always include relevant metadata in error logs - -✅ Good: -```typescript -function parseWithDebug(html: string): TParseResult { - try { - return parseHtml(html); - } catch (error) { - logger.error('XML parsing failed', { - error: error.message, - htmlLength: html.length, - htmlPreview: html.substring(0, 200) - }); - - // Save debug file if needed - const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); - const debugFile = `/tmp/parse-debug-${timestamp}.html`; - fs.writeFileSync(debugFile, html); - - throw new Error('Failed to parse HTML content'); - } -} -``` - -❌ Bad: -```typescript -function parseWithDebug(html: string): TParseResult { - try { - return parseHtml(html); - } catch (error) { - console.log('Error:', error); // Wrong: Minimal error info - throw error; // Wrong: Re-throw without context - } -} -``` diff --git a/.easignore b/.easignore new file mode 100644 index 0000000..870e90a --- /dev/null +++ b/.easignore @@ -0,0 +1,31 @@ +# # Learn more https://docs.expo.dev/build-reference/easignore/ + +# Copy everything from .gitignore (EAS uses this when present) +node_modules +.pnp +.pnp.js +.env +.env.dev +.env.prod +.env.local +.env.test +coverage +.turbo +.vercel +.next/ +out/ +build +dist +target +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.DS_Store +*.pem +.todo +.local +**/migrations/local + +# Monorepo: ignore all apps, allow only kairos (and packages/ + root are allowed) +/apps/* +!/apps/kairos diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..e554bff --- /dev/null +++ b/.prettierignore @@ -0,0 +1,6 @@ +# Xcode asset catalogs and app icon (Xcode owns these JSON files) +**/*.xcassets/** +**/AppIcon.icon/** + +# Deprecated apps +apps/__deprecated/ diff --git a/apps/isshin/.gitignore b/apps/__deprecated/isshin/.gitignore similarity index 100% rename from apps/isshin/.gitignore rename to apps/__deprecated/isshin/.gitignore diff --git a/apps/isshin/README.md b/apps/__deprecated/isshin/README.md similarity index 100% rename from apps/isshin/README.md rename to apps/__deprecated/isshin/README.md diff --git a/apps/isshin/creates/mado/Cargo.lock b/apps/__deprecated/isshin/creates/mado/Cargo.lock similarity index 100% rename from apps/isshin/creates/mado/Cargo.lock rename to apps/__deprecated/isshin/creates/mado/Cargo.lock diff --git a/apps/isshin/creates/mado/Cargo.toml b/apps/__deprecated/isshin/creates/mado/Cargo.toml similarity index 100% rename from apps/isshin/creates/mado/Cargo.toml rename to apps/__deprecated/isshin/creates/mado/Cargo.toml diff --git a/apps/isshin/creates/mado/README.md b/apps/__deprecated/isshin/creates/mado/README.md similarity index 100% rename from apps/isshin/creates/mado/README.md rename to apps/__deprecated/isshin/creates/mado/README.md diff --git a/apps/isshin/creates/mado/examples/listen.rs b/apps/__deprecated/isshin/creates/mado/examples/listen.rs similarity index 100% rename from apps/isshin/creates/mado/examples/listen.rs rename to apps/__deprecated/isshin/creates/mado/examples/listen.rs diff --git a/apps/isshin/creates/mado/examples/poll.rs b/apps/__deprecated/isshin/creates/mado/examples/poll.rs similarity index 100% rename from apps/isshin/creates/mado/examples/poll.rs rename to apps/__deprecated/isshin/creates/mado/examples/poll.rs diff --git a/apps/isshin/creates/mado/src/config.rs b/apps/__deprecated/isshin/creates/mado/src/config.rs similarity index 100% rename from apps/isshin/creates/mado/src/config.rs rename to apps/__deprecated/isshin/creates/mado/src/config.rs diff --git a/apps/isshin/creates/mado/src/error.rs b/apps/__deprecated/isshin/creates/mado/src/error.rs similarity index 100% rename from apps/isshin/creates/mado/src/error.rs rename to apps/__deprecated/isshin/creates/mado/src/error.rs diff --git a/apps/isshin/creates/mado/src/lib.rs b/apps/__deprecated/isshin/creates/mado/src/lib.rs similarity index 100% rename from apps/isshin/creates/mado/src/lib.rs rename to apps/__deprecated/isshin/creates/mado/src/lib.rs diff --git a/apps/isshin/creates/mado/src/listener.rs b/apps/__deprecated/isshin/creates/mado/src/listener.rs similarity index 100% rename from apps/isshin/creates/mado/src/listener.rs rename to apps/__deprecated/isshin/creates/mado/src/listener.rs diff --git a/apps/isshin/creates/mado/src/monitor.rs b/apps/__deprecated/isshin/creates/mado/src/monitor.rs similarity index 100% rename from apps/isshin/creates/mado/src/monitor.rs rename to apps/__deprecated/isshin/creates/mado/src/monitor.rs diff --git a/apps/isshin/creates/mado/src/platform/linux/mod.rs b/apps/__deprecated/isshin/creates/mado/src/platform/linux/mod.rs similarity index 100% rename from apps/isshin/creates/mado/src/platform/linux/mod.rs rename to apps/__deprecated/isshin/creates/mado/src/platform/linux/mod.rs diff --git a/apps/isshin/creates/mado/src/platform/linux/window_info.rs b/apps/__deprecated/isshin/creates/mado/src/platform/linux/window_info.rs similarity index 100% rename from apps/isshin/creates/mado/src/platform/linux/window_info.rs rename to apps/__deprecated/isshin/creates/mado/src/platform/linux/window_info.rs diff --git a/apps/isshin/creates/mado/src/platform/linux/x11_helpers.rs b/apps/__deprecated/isshin/creates/mado/src/platform/linux/x11_helpers.rs similarity index 100% rename from apps/isshin/creates/mado/src/platform/linux/x11_helpers.rs rename to apps/__deprecated/isshin/creates/mado/src/platform/linux/x11_helpers.rs diff --git a/apps/isshin/creates/mado/src/platform/linux/x11_monitor.rs b/apps/__deprecated/isshin/creates/mado/src/platform/linux/x11_monitor.rs similarity index 100% rename from apps/isshin/creates/mado/src/platform/linux/x11_monitor.rs rename to apps/__deprecated/isshin/creates/mado/src/platform/linux/x11_monitor.rs diff --git a/apps/isshin/creates/mado/src/platform/macos/accessibility.rs b/apps/__deprecated/isshin/creates/mado/src/platform/macos/accessibility.rs similarity index 100% rename from apps/isshin/creates/mado/src/platform/macos/accessibility.rs rename to apps/__deprecated/isshin/creates/mado/src/platform/macos/accessibility.rs diff --git a/apps/isshin/creates/mado/src/platform/macos/app_info.rs b/apps/__deprecated/isshin/creates/mado/src/platform/macos/app_info.rs similarity index 100% rename from apps/isshin/creates/mado/src/platform/macos/app_info.rs rename to apps/__deprecated/isshin/creates/mado/src/platform/macos/app_info.rs diff --git a/apps/isshin/creates/mado/src/platform/macos/browser.rs b/apps/__deprecated/isshin/creates/mado/src/platform/macos/browser.rs similarity index 100% rename from apps/isshin/creates/mado/src/platform/macos/browser.rs rename to apps/__deprecated/isshin/creates/mado/src/platform/macos/browser.rs diff --git a/apps/isshin/creates/mado/src/platform/macos/mod.rs b/apps/__deprecated/isshin/creates/mado/src/platform/macos/mod.rs similarity index 100% rename from apps/isshin/creates/mado/src/platform/macos/mod.rs rename to apps/__deprecated/isshin/creates/mado/src/platform/macos/mod.rs diff --git a/apps/isshin/creates/mado/src/platform/macos/window_event_handler.rs b/apps/__deprecated/isshin/creates/mado/src/platform/macos/window_event_handler.rs similarity index 100% rename from apps/isshin/creates/mado/src/platform/macos/window_event_handler.rs rename to apps/__deprecated/isshin/creates/mado/src/platform/macos/window_event_handler.rs diff --git a/apps/isshin/creates/mado/src/platform/macos/window_info.rs b/apps/__deprecated/isshin/creates/mado/src/platform/macos/window_info.rs similarity index 100% rename from apps/isshin/creates/mado/src/platform/macos/window_info.rs rename to apps/__deprecated/isshin/creates/mado/src/platform/macos/window_info.rs diff --git a/apps/isshin/creates/mado/src/platform/macos/workspace.rs b/apps/__deprecated/isshin/creates/mado/src/platform/macos/workspace.rs similarity index 100% rename from apps/isshin/creates/mado/src/platform/macos/workspace.rs rename to apps/__deprecated/isshin/creates/mado/src/platform/macos/workspace.rs diff --git a/apps/isshin/creates/mado/src/platform/mod.rs b/apps/__deprecated/isshin/creates/mado/src/platform/mod.rs similarity index 100% rename from apps/isshin/creates/mado/src/platform/mod.rs rename to apps/__deprecated/isshin/creates/mado/src/platform/mod.rs diff --git a/apps/isshin/creates/mado/src/types.rs b/apps/__deprecated/isshin/creates/mado/src/types.rs similarity index 100% rename from apps/isshin/creates/mado/src/types.rs rename to apps/__deprecated/isshin/creates/mado/src/types.rs diff --git a/apps/isshin/env.d.ts b/apps/__deprecated/isshin/env.d.ts similarity index 100% rename from apps/isshin/env.d.ts rename to apps/__deprecated/isshin/env.d.ts diff --git a/apps/isshin/eslint.config.js b/apps/__deprecated/isshin/eslint.config.js similarity index 100% rename from apps/isshin/eslint.config.js rename to apps/__deprecated/isshin/eslint.config.js diff --git a/apps/isshin/package.json b/apps/__deprecated/isshin/package.json similarity index 100% rename from apps/isshin/package.json rename to apps/__deprecated/isshin/package.json diff --git a/apps/isshin/public/tauri.svg b/apps/__deprecated/isshin/public/tauri.svg similarity index 100% rename from apps/isshin/public/tauri.svg rename to apps/__deprecated/isshin/public/tauri.svg diff --git a/apps/isshin/public/vite.svg b/apps/__deprecated/isshin/public/vite.svg similarity index 100% rename from apps/isshin/public/vite.svg rename to apps/__deprecated/isshin/public/vite.svg diff --git a/apps/isshin/react-router.config.ts b/apps/__deprecated/isshin/react-router.config.ts similarity index 100% rename from apps/isshin/react-router.config.ts rename to apps/__deprecated/isshin/react-router.config.ts diff --git a/apps/isshin/src-tauri/.gitignore b/apps/__deprecated/isshin/src-tauri/.gitignore similarity index 100% rename from apps/isshin/src-tauri/.gitignore rename to apps/__deprecated/isshin/src-tauri/.gitignore diff --git a/apps/isshin/src-tauri/Cargo.lock b/apps/__deprecated/isshin/src-tauri/Cargo.lock similarity index 100% rename from apps/isshin/src-tauri/Cargo.lock rename to apps/__deprecated/isshin/src-tauri/Cargo.lock diff --git a/apps/isshin/src-tauri/Cargo.toml b/apps/__deprecated/isshin/src-tauri/Cargo.toml similarity index 100% rename from apps/isshin/src-tauri/Cargo.toml rename to apps/__deprecated/isshin/src-tauri/Cargo.toml diff --git a/apps/isshin/src-tauri/build.rs b/apps/__deprecated/isshin/src-tauri/build.rs similarity index 100% rename from apps/isshin/src-tauri/build.rs rename to apps/__deprecated/isshin/src-tauri/build.rs diff --git a/apps/isshin/src-tauri/capabilities/default.json b/apps/__deprecated/isshin/src-tauri/capabilities/default.json similarity index 100% rename from apps/isshin/src-tauri/capabilities/default.json rename to apps/__deprecated/isshin/src-tauri/capabilities/default.json diff --git a/apps/isshin/src-tauri/icons/128x128.png b/apps/__deprecated/isshin/src-tauri/icons/128x128.png similarity index 100% rename from apps/isshin/src-tauri/icons/128x128.png rename to apps/__deprecated/isshin/src-tauri/icons/128x128.png diff --git a/apps/isshin/src-tauri/icons/128x128@2x.png b/apps/__deprecated/isshin/src-tauri/icons/128x128@2x.png similarity index 100% rename from apps/isshin/src-tauri/icons/128x128@2x.png rename to apps/__deprecated/isshin/src-tauri/icons/128x128@2x.png diff --git a/apps/isshin/src-tauri/icons/32x32.png b/apps/__deprecated/isshin/src-tauri/icons/32x32.png similarity index 100% rename from apps/isshin/src-tauri/icons/32x32.png rename to apps/__deprecated/isshin/src-tauri/icons/32x32.png diff --git a/apps/isshin/src-tauri/icons/64x64.png b/apps/__deprecated/isshin/src-tauri/icons/64x64.png similarity index 100% rename from apps/isshin/src-tauri/icons/64x64.png rename to apps/__deprecated/isshin/src-tauri/icons/64x64.png diff --git a/apps/isshin/src-tauri/icons/Square107x107Logo.png b/apps/__deprecated/isshin/src-tauri/icons/Square107x107Logo.png similarity index 100% rename from apps/isshin/src-tauri/icons/Square107x107Logo.png rename to apps/__deprecated/isshin/src-tauri/icons/Square107x107Logo.png diff --git a/apps/isshin/src-tauri/icons/Square142x142Logo.png b/apps/__deprecated/isshin/src-tauri/icons/Square142x142Logo.png similarity index 100% rename from apps/isshin/src-tauri/icons/Square142x142Logo.png rename to apps/__deprecated/isshin/src-tauri/icons/Square142x142Logo.png diff --git a/apps/isshin/src-tauri/icons/Square150x150Logo.png b/apps/__deprecated/isshin/src-tauri/icons/Square150x150Logo.png similarity index 100% rename from apps/isshin/src-tauri/icons/Square150x150Logo.png rename to apps/__deprecated/isshin/src-tauri/icons/Square150x150Logo.png diff --git a/apps/isshin/src-tauri/icons/Square284x284Logo.png b/apps/__deprecated/isshin/src-tauri/icons/Square284x284Logo.png similarity index 100% rename from apps/isshin/src-tauri/icons/Square284x284Logo.png rename to apps/__deprecated/isshin/src-tauri/icons/Square284x284Logo.png diff --git a/apps/isshin/src-tauri/icons/Square30x30Logo.png b/apps/__deprecated/isshin/src-tauri/icons/Square30x30Logo.png similarity index 100% rename from apps/isshin/src-tauri/icons/Square30x30Logo.png rename to apps/__deprecated/isshin/src-tauri/icons/Square30x30Logo.png diff --git a/apps/isshin/src-tauri/icons/Square310x310Logo.png b/apps/__deprecated/isshin/src-tauri/icons/Square310x310Logo.png similarity index 100% rename from apps/isshin/src-tauri/icons/Square310x310Logo.png rename to apps/__deprecated/isshin/src-tauri/icons/Square310x310Logo.png diff --git a/apps/isshin/src-tauri/icons/Square44x44Logo.png b/apps/__deprecated/isshin/src-tauri/icons/Square44x44Logo.png similarity index 100% rename from apps/isshin/src-tauri/icons/Square44x44Logo.png rename to apps/__deprecated/isshin/src-tauri/icons/Square44x44Logo.png diff --git a/apps/isshin/src-tauri/icons/Square71x71Logo.png b/apps/__deprecated/isshin/src-tauri/icons/Square71x71Logo.png similarity index 100% rename from apps/isshin/src-tauri/icons/Square71x71Logo.png rename to apps/__deprecated/isshin/src-tauri/icons/Square71x71Logo.png diff --git a/apps/isshin/src-tauri/icons/Square89x89Logo.png b/apps/__deprecated/isshin/src-tauri/icons/Square89x89Logo.png similarity index 100% rename from apps/isshin/src-tauri/icons/Square89x89Logo.png rename to apps/__deprecated/isshin/src-tauri/icons/Square89x89Logo.png diff --git a/apps/isshin/src-tauri/icons/StoreLogo.png b/apps/__deprecated/isshin/src-tauri/icons/StoreLogo.png similarity index 100% rename from apps/isshin/src-tauri/icons/StoreLogo.png rename to apps/__deprecated/isshin/src-tauri/icons/StoreLogo.png diff --git a/apps/isshin/src-tauri/icons/android/mipmap-anydpi-v26/ic_launcher.xml b/apps/__deprecated/isshin/src-tauri/icons/android/mipmap-anydpi-v26/ic_launcher.xml similarity index 100% rename from apps/isshin/src-tauri/icons/android/mipmap-anydpi-v26/ic_launcher.xml rename to apps/__deprecated/isshin/src-tauri/icons/android/mipmap-anydpi-v26/ic_launcher.xml diff --git a/apps/isshin/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png b/apps/__deprecated/isshin/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png similarity index 100% rename from apps/isshin/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png rename to apps/__deprecated/isshin/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png diff --git a/apps/isshin/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png b/apps/__deprecated/isshin/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png similarity index 100% rename from apps/isshin/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png rename to apps/__deprecated/isshin/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png diff --git a/apps/isshin/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png b/apps/__deprecated/isshin/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png similarity index 100% rename from apps/isshin/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png rename to apps/__deprecated/isshin/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png diff --git a/apps/isshin/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png b/apps/__deprecated/isshin/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png similarity index 100% rename from apps/isshin/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png rename to apps/__deprecated/isshin/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png diff --git a/apps/isshin/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png b/apps/__deprecated/isshin/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png similarity index 100% rename from apps/isshin/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png rename to apps/__deprecated/isshin/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png diff --git a/apps/isshin/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png b/apps/__deprecated/isshin/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png similarity index 100% rename from apps/isshin/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png rename to apps/__deprecated/isshin/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png diff --git a/apps/isshin/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png b/apps/__deprecated/isshin/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from apps/isshin/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png rename to apps/__deprecated/isshin/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png diff --git a/apps/isshin/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png b/apps/__deprecated/isshin/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png similarity index 100% rename from apps/isshin/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png rename to apps/__deprecated/isshin/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png diff --git a/apps/isshin/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png b/apps/__deprecated/isshin/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png similarity index 100% rename from apps/isshin/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png rename to apps/__deprecated/isshin/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png diff --git a/apps/isshin/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png b/apps/__deprecated/isshin/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from apps/isshin/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png rename to apps/__deprecated/isshin/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png diff --git a/apps/isshin/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png b/apps/__deprecated/isshin/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png similarity index 100% rename from apps/isshin/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png rename to apps/__deprecated/isshin/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png diff --git a/apps/isshin/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png b/apps/__deprecated/isshin/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png similarity index 100% rename from apps/isshin/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png rename to apps/__deprecated/isshin/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png diff --git a/apps/isshin/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png b/apps/__deprecated/isshin/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from apps/isshin/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png rename to apps/__deprecated/isshin/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png diff --git a/apps/isshin/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png b/apps/__deprecated/isshin/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png similarity index 100% rename from apps/isshin/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png rename to apps/__deprecated/isshin/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png diff --git a/apps/isshin/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png b/apps/__deprecated/isshin/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png similarity index 100% rename from apps/isshin/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png rename to apps/__deprecated/isshin/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png diff --git a/apps/isshin/src-tauri/icons/android/values/ic_launcher_background.xml b/apps/__deprecated/isshin/src-tauri/icons/android/values/ic_launcher_background.xml similarity index 100% rename from apps/isshin/src-tauri/icons/android/values/ic_launcher_background.xml rename to apps/__deprecated/isshin/src-tauri/icons/android/values/ic_launcher_background.xml diff --git a/apps/isshin/src-tauri/icons/icon.icns b/apps/__deprecated/isshin/src-tauri/icons/icon.icns similarity index 100% rename from apps/isshin/src-tauri/icons/icon.icns rename to apps/__deprecated/isshin/src-tauri/icons/icon.icns diff --git a/apps/isshin/src-tauri/icons/icon.ico b/apps/__deprecated/isshin/src-tauri/icons/icon.ico similarity index 100% rename from apps/isshin/src-tauri/icons/icon.ico rename to apps/__deprecated/isshin/src-tauri/icons/icon.ico diff --git a/apps/isshin/src-tauri/icons/icon.png b/apps/__deprecated/isshin/src-tauri/icons/icon.png similarity index 100% rename from apps/isshin/src-tauri/icons/icon.png rename to apps/__deprecated/isshin/src-tauri/icons/icon.png diff --git a/apps/isshin/src-tauri/icons/ios/AppIcon-20x20@1x.png b/apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-20x20@1x.png similarity index 100% rename from apps/isshin/src-tauri/icons/ios/AppIcon-20x20@1x.png rename to apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-20x20@1x.png diff --git a/apps/isshin/src-tauri/icons/ios/AppIcon-20x20@2x-1.png b/apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-20x20@2x-1.png similarity index 100% rename from apps/isshin/src-tauri/icons/ios/AppIcon-20x20@2x-1.png rename to apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-20x20@2x-1.png diff --git a/apps/isshin/src-tauri/icons/ios/AppIcon-20x20@2x.png b/apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-20x20@2x.png similarity index 100% rename from apps/isshin/src-tauri/icons/ios/AppIcon-20x20@2x.png rename to apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-20x20@2x.png diff --git a/apps/isshin/src-tauri/icons/ios/AppIcon-20x20@3x.png b/apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-20x20@3x.png similarity index 100% rename from apps/isshin/src-tauri/icons/ios/AppIcon-20x20@3x.png rename to apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-20x20@3x.png diff --git a/apps/isshin/src-tauri/icons/ios/AppIcon-29x29@1x.png b/apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-29x29@1x.png similarity index 100% rename from apps/isshin/src-tauri/icons/ios/AppIcon-29x29@1x.png rename to apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-29x29@1x.png diff --git a/apps/isshin/src-tauri/icons/ios/AppIcon-29x29@2x-1.png b/apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-29x29@2x-1.png similarity index 100% rename from apps/isshin/src-tauri/icons/ios/AppIcon-29x29@2x-1.png rename to apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-29x29@2x-1.png diff --git a/apps/isshin/src-tauri/icons/ios/AppIcon-29x29@2x.png b/apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-29x29@2x.png similarity index 100% rename from apps/isshin/src-tauri/icons/ios/AppIcon-29x29@2x.png rename to apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-29x29@2x.png diff --git a/apps/isshin/src-tauri/icons/ios/AppIcon-29x29@3x.png b/apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-29x29@3x.png similarity index 100% rename from apps/isshin/src-tauri/icons/ios/AppIcon-29x29@3x.png rename to apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-29x29@3x.png diff --git a/apps/isshin/src-tauri/icons/ios/AppIcon-40x40@1x.png b/apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-40x40@1x.png similarity index 100% rename from apps/isshin/src-tauri/icons/ios/AppIcon-40x40@1x.png rename to apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-40x40@1x.png diff --git a/apps/isshin/src-tauri/icons/ios/AppIcon-40x40@2x-1.png b/apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-40x40@2x-1.png similarity index 100% rename from apps/isshin/src-tauri/icons/ios/AppIcon-40x40@2x-1.png rename to apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-40x40@2x-1.png diff --git a/apps/isshin/src-tauri/icons/ios/AppIcon-40x40@2x.png b/apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-40x40@2x.png similarity index 100% rename from apps/isshin/src-tauri/icons/ios/AppIcon-40x40@2x.png rename to apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-40x40@2x.png diff --git a/apps/isshin/src-tauri/icons/ios/AppIcon-40x40@3x.png b/apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-40x40@3x.png similarity index 100% rename from apps/isshin/src-tauri/icons/ios/AppIcon-40x40@3x.png rename to apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-40x40@3x.png diff --git a/apps/isshin/src-tauri/icons/ios/AppIcon-512@2x.png b/apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-512@2x.png similarity index 100% rename from apps/isshin/src-tauri/icons/ios/AppIcon-512@2x.png rename to apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-512@2x.png diff --git a/apps/isshin/src-tauri/icons/ios/AppIcon-60x60@2x.png b/apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-60x60@2x.png similarity index 100% rename from apps/isshin/src-tauri/icons/ios/AppIcon-60x60@2x.png rename to apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-60x60@2x.png diff --git a/apps/isshin/src-tauri/icons/ios/AppIcon-60x60@3x.png b/apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-60x60@3x.png similarity index 100% rename from apps/isshin/src-tauri/icons/ios/AppIcon-60x60@3x.png rename to apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-60x60@3x.png diff --git a/apps/isshin/src-tauri/icons/ios/AppIcon-76x76@1x.png b/apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-76x76@1x.png similarity index 100% rename from apps/isshin/src-tauri/icons/ios/AppIcon-76x76@1x.png rename to apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-76x76@1x.png diff --git a/apps/isshin/src-tauri/icons/ios/AppIcon-76x76@2x.png b/apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-76x76@2x.png similarity index 100% rename from apps/isshin/src-tauri/icons/ios/AppIcon-76x76@2x.png rename to apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-76x76@2x.png diff --git a/apps/isshin/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png b/apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png similarity index 100% rename from apps/isshin/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png rename to apps/__deprecated/isshin/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png diff --git a/apps/isshin/src-tauri/icons/tray-default-icon-dev.png b/apps/__deprecated/isshin/src-tauri/icons/tray-default-icon-dev.png similarity index 100% rename from apps/isshin/src-tauri/icons/tray-default-icon-dev.png rename to apps/__deprecated/isshin/src-tauri/icons/tray-default-icon-dev.png diff --git a/apps/isshin/src-tauri/icons/tray-default-icon.png b/apps/__deprecated/isshin/src-tauri/icons/tray-default-icon.png similarity index 100% rename from apps/isshin/src-tauri/icons/tray-default-icon.png rename to apps/__deprecated/isshin/src-tauri/icons/tray-default-icon.png diff --git a/apps/isshin/src-tauri/migrations/0001_init.sql b/apps/__deprecated/isshin/src-tauri/migrations/0001_init.sql similarity index 100% rename from apps/isshin/src-tauri/migrations/0001_init.sql rename to apps/__deprecated/isshin/src-tauri/migrations/0001_init.sql diff --git a/apps/isshin/src-tauri/src/app/mod.rs b/apps/__deprecated/isshin/src-tauri/src/app/mod.rs similarity index 100% rename from apps/isshin/src-tauri/src/app/mod.rs rename to apps/__deprecated/isshin/src-tauri/src/app/mod.rs diff --git a/apps/isshin/src-tauri/src/app/tray.rs b/apps/__deprecated/isshin/src-tauri/src/app/tray.rs similarity index 100% rename from apps/isshin/src-tauri/src/app/tray.rs rename to apps/__deprecated/isshin/src-tauri/src/app/tray.rs diff --git a/apps/isshin/src-tauri/src/app/window.rs b/apps/__deprecated/isshin/src-tauri/src/app/window.rs similarity index 100% rename from apps/isshin/src-tauri/src/app/window.rs rename to apps/__deprecated/isshin/src-tauri/src/app/window.rs diff --git a/apps/isshin/src-tauri/src/common/db.rs b/apps/__deprecated/isshin/src-tauri/src/common/db.rs similarity index 100% rename from apps/isshin/src-tauri/src/common/db.rs rename to apps/__deprecated/isshin/src-tauri/src/common/db.rs diff --git a/apps/isshin/src-tauri/src/common/mod.rs b/apps/__deprecated/isshin/src-tauri/src/common/mod.rs similarity index 100% rename from apps/isshin/src-tauri/src/common/mod.rs rename to apps/__deprecated/isshin/src-tauri/src/common/mod.rs diff --git a/apps/isshin/src-tauri/src/common/path.rs b/apps/__deprecated/isshin/src-tauri/src/common/path.rs similarity index 100% rename from apps/isshin/src-tauri/src/common/path.rs rename to apps/__deprecated/isshin/src-tauri/src/common/path.rs diff --git a/apps/isshin/src-tauri/src/common/time.rs b/apps/__deprecated/isshin/src-tauri/src/common/time.rs similarity index 100% rename from apps/isshin/src-tauri/src/common/time.rs rename to apps/__deprecated/isshin/src-tauri/src/common/time.rs diff --git a/apps/isshin/src-tauri/src/environment/configs/app.rs b/apps/__deprecated/isshin/src-tauri/src/environment/configs/app.rs similarity index 100% rename from apps/isshin/src-tauri/src/environment/configs/app.rs rename to apps/__deprecated/isshin/src-tauri/src/environment/configs/app.rs diff --git a/apps/isshin/src-tauri/src/environment/configs/db.rs b/apps/__deprecated/isshin/src-tauri/src/environment/configs/db.rs similarity index 100% rename from apps/isshin/src-tauri/src/environment/configs/db.rs rename to apps/__deprecated/isshin/src-tauri/src/environment/configs/db.rs diff --git a/apps/isshin/src-tauri/src/environment/configs/logger.rs b/apps/__deprecated/isshin/src-tauri/src/environment/configs/logger.rs similarity index 100% rename from apps/isshin/src-tauri/src/environment/configs/logger.rs rename to apps/__deprecated/isshin/src-tauri/src/environment/configs/logger.rs diff --git a/apps/isshin/src-tauri/src/environment/configs/mod.rs b/apps/__deprecated/isshin/src-tauri/src/environment/configs/mod.rs similarity index 100% rename from apps/isshin/src-tauri/src/environment/configs/mod.rs rename to apps/__deprecated/isshin/src-tauri/src/environment/configs/mod.rs diff --git a/apps/isshin/src-tauri/src/environment/configs/settings.rs b/apps/__deprecated/isshin/src-tauri/src/environment/configs/settings.rs similarity index 100% rename from apps/isshin/src-tauri/src/environment/configs/settings.rs rename to apps/__deprecated/isshin/src-tauri/src/environment/configs/settings.rs diff --git a/apps/isshin/src-tauri/src/environment/logger.rs b/apps/__deprecated/isshin/src-tauri/src/environment/logger.rs similarity index 100% rename from apps/isshin/src-tauri/src/environment/logger.rs rename to apps/__deprecated/isshin/src-tauri/src/environment/logger.rs diff --git a/apps/isshin/src-tauri/src/environment/mod.rs b/apps/__deprecated/isshin/src-tauri/src/environment/mod.rs similarity index 100% rename from apps/isshin/src-tauri/src/environment/mod.rs rename to apps/__deprecated/isshin/src-tauri/src/environment/mod.rs diff --git a/apps/isshin/src-tauri/src/environment/states/app.rs b/apps/__deprecated/isshin/src-tauri/src/environment/states/app.rs similarity index 100% rename from apps/isshin/src-tauri/src/environment/states/app.rs rename to apps/__deprecated/isshin/src-tauri/src/environment/states/app.rs diff --git a/apps/isshin/src-tauri/src/environment/states/blocking.rs b/apps/__deprecated/isshin/src-tauri/src/environment/states/blocking.rs similarity index 100% rename from apps/isshin/src-tauri/src/environment/states/blocking.rs rename to apps/__deprecated/isshin/src-tauri/src/environment/states/blocking.rs diff --git a/apps/isshin/src-tauri/src/environment/states/db.rs b/apps/__deprecated/isshin/src-tauri/src/environment/states/db.rs similarity index 100% rename from apps/isshin/src-tauri/src/environment/states/db.rs rename to apps/__deprecated/isshin/src-tauri/src/environment/states/db.rs diff --git a/apps/isshin/src-tauri/src/environment/states/mod.rs b/apps/__deprecated/isshin/src-tauri/src/environment/states/mod.rs similarity index 100% rename from apps/isshin/src-tauri/src/environment/states/mod.rs rename to apps/__deprecated/isshin/src-tauri/src/environment/states/mod.rs diff --git a/apps/isshin/src-tauri/src/environment/states/settings.rs b/apps/__deprecated/isshin/src-tauri/src/environment/states/settings.rs similarity index 100% rename from apps/isshin/src-tauri/src/environment/states/settings.rs rename to apps/__deprecated/isshin/src-tauri/src/environment/states/settings.rs diff --git a/apps/isshin/src-tauri/src/features/activity/mod.rs b/apps/__deprecated/isshin/src-tauri/src/features/activity/mod.rs similarity index 100% rename from apps/isshin/src-tauri/src/features/activity/mod.rs rename to apps/__deprecated/isshin/src-tauri/src/features/activity/mod.rs diff --git a/apps/isshin/src-tauri/src/features/activity_afk/mod.rs b/apps/__deprecated/isshin/src-tauri/src/features/activity_afk/mod.rs similarity index 100% rename from apps/isshin/src-tauri/src/features/activity_afk/mod.rs rename to apps/__deprecated/isshin/src-tauri/src/features/activity_afk/mod.rs diff --git a/apps/isshin/src-tauri/src/features/activity_input/mod.rs b/apps/__deprecated/isshin/src-tauri/src/features/activity_input/mod.rs similarity index 100% rename from apps/isshin/src-tauri/src/features/activity_input/mod.rs rename to apps/__deprecated/isshin/src-tauri/src/features/activity_input/mod.rs diff --git a/apps/isshin/src-tauri/src/features/activity_window/commands.rs b/apps/__deprecated/isshin/src-tauri/src/features/activity_window/commands.rs similarity index 100% rename from apps/isshin/src-tauri/src/features/activity_window/commands.rs rename to apps/__deprecated/isshin/src-tauri/src/features/activity_window/commands.rs diff --git a/apps/isshin/src-tauri/src/features/activity_window/mod.rs b/apps/__deprecated/isshin/src-tauri/src/features/activity_window/mod.rs similarity index 100% rename from apps/isshin/src-tauri/src/features/activity_window/mod.rs rename to apps/__deprecated/isshin/src-tauri/src/features/activity_window/mod.rs diff --git a/apps/isshin/src-tauri/src/features/activity_window/monitor.rs b/apps/__deprecated/isshin/src-tauri/src/features/activity_window/monitor.rs similarity index 100% rename from apps/isshin/src-tauri/src/features/activity_window/monitor.rs rename to apps/__deprecated/isshin/src-tauri/src/features/activity_window/monitor.rs diff --git a/apps/isshin/src-tauri/src/features/activity_window/repository.rs b/apps/__deprecated/isshin/src-tauri/src/features/activity_window/repository.rs similarity index 100% rename from apps/isshin/src-tauri/src/features/activity_window/repository.rs rename to apps/__deprecated/isshin/src-tauri/src/features/activity_window/repository.rs diff --git a/apps/isshin/src-tauri/src/features/activity_window/types.rs b/apps/__deprecated/isshin/src-tauri/src/features/activity_window/types.rs similarity index 100% rename from apps/isshin/src-tauri/src/features/activity_window/types.rs rename to apps/__deprecated/isshin/src-tauri/src/features/activity_window/types.rs diff --git a/apps/isshin/src-tauri/src/features/blocking/blocker.rs b/apps/__deprecated/isshin/src-tauri/src/features/blocking/blocker.rs similarity index 100% rename from apps/isshin/src-tauri/src/features/blocking/blocker.rs rename to apps/__deprecated/isshin/src-tauri/src/features/blocking/blocker.rs diff --git a/apps/isshin/src-tauri/src/features/blocking/commands.rs b/apps/__deprecated/isshin/src-tauri/src/features/blocking/commands.rs similarity index 100% rename from apps/isshin/src-tauri/src/features/blocking/commands.rs rename to apps/__deprecated/isshin/src-tauri/src/features/blocking/commands.rs diff --git a/apps/isshin/src-tauri/src/features/blocking/mod.rs b/apps/__deprecated/isshin/src-tauri/src/features/blocking/mod.rs similarity index 100% rename from apps/isshin/src-tauri/src/features/blocking/mod.rs rename to apps/__deprecated/isshin/src-tauri/src/features/blocking/mod.rs diff --git a/apps/isshin/src-tauri/src/features/blocking/types.rs b/apps/__deprecated/isshin/src-tauri/src/features/blocking/types.rs similarity index 100% rename from apps/isshin/src-tauri/src/features/blocking/types.rs rename to apps/__deprecated/isshin/src-tauri/src/features/blocking/types.rs diff --git a/apps/isshin/src-tauri/src/features/mod.rs b/apps/__deprecated/isshin/src-tauri/src/features/mod.rs similarity index 100% rename from apps/isshin/src-tauri/src/features/mod.rs rename to apps/__deprecated/isshin/src-tauri/src/features/mod.rs diff --git a/apps/isshin/src-tauri/src/features/settings/commands.rs b/apps/__deprecated/isshin/src-tauri/src/features/settings/commands.rs similarity index 100% rename from apps/isshin/src-tauri/src/features/settings/commands.rs rename to apps/__deprecated/isshin/src-tauri/src/features/settings/commands.rs diff --git a/apps/isshin/src-tauri/src/features/settings/mod.rs b/apps/__deprecated/isshin/src-tauri/src/features/settings/mod.rs similarity index 100% rename from apps/isshin/src-tauri/src/features/settings/mod.rs rename to apps/__deprecated/isshin/src-tauri/src/features/settings/mod.rs diff --git a/apps/isshin/src-tauri/src/features/settings/persistence.rs b/apps/__deprecated/isshin/src-tauri/src/features/settings/persistence.rs similarity index 100% rename from apps/isshin/src-tauri/src/features/settings/persistence.rs rename to apps/__deprecated/isshin/src-tauri/src/features/settings/persistence.rs diff --git a/apps/isshin/src-tauri/src/features/settings/types.rs b/apps/__deprecated/isshin/src-tauri/src/features/settings/types.rs similarity index 100% rename from apps/isshin/src-tauri/src/features/settings/types.rs rename to apps/__deprecated/isshin/src-tauri/src/features/settings/types.rs diff --git a/apps/isshin/src-tauri/src/lib.rs b/apps/__deprecated/isshin/src-tauri/src/lib.rs similarity index 100% rename from apps/isshin/src-tauri/src/lib.rs rename to apps/__deprecated/isshin/src-tauri/src/lib.rs diff --git a/apps/isshin/src-tauri/src/main.rs b/apps/__deprecated/isshin/src-tauri/src/main.rs similarity index 100% rename from apps/isshin/src-tauri/src/main.rs rename to apps/__deprecated/isshin/src-tauri/src/main.rs diff --git a/apps/isshin/src-tauri/tauri.conf.json b/apps/__deprecated/isshin/src-tauri/tauri.conf.json similarity index 100% rename from apps/isshin/src-tauri/tauri.conf.json rename to apps/__deprecated/isshin/src-tauri/tauri.conf.json diff --git a/apps/isshin/src/environment/index.ts b/apps/__deprecated/isshin/src/environment/index.ts similarity index 100% rename from apps/isshin/src/environment/index.ts rename to apps/__deprecated/isshin/src/environment/index.ts diff --git a/apps/isshin/src/environment/specta/bindings.ts b/apps/__deprecated/isshin/src/environment/specta/bindings.ts similarity index 100% rename from apps/isshin/src/environment/specta/bindings.ts rename to apps/__deprecated/isshin/src/environment/specta/bindings.ts diff --git a/apps/isshin/src/environment/specta/index.ts b/apps/__deprecated/isshin/src/environment/specta/index.ts similarity index 100% rename from apps/isshin/src/environment/specta/index.ts rename to apps/__deprecated/isshin/src/environment/specta/index.ts diff --git a/apps/isshin/src/lib/index.ts b/apps/__deprecated/isshin/src/lib/index.ts similarity index 100% rename from apps/isshin/src/lib/index.ts rename to apps/__deprecated/isshin/src/lib/index.ts diff --git a/apps/isshin/src/lib/specta.ts b/apps/__deprecated/isshin/src/lib/specta.ts similarity index 100% rename from apps/isshin/src/lib/specta.ts rename to apps/__deprecated/isshin/src/lib/specta.ts diff --git a/apps/isshin/src/lib/ui/format.ts b/apps/__deprecated/isshin/src/lib/ui/format.ts similarity index 100% rename from apps/isshin/src/lib/ui/format.ts rename to apps/__deprecated/isshin/src/lib/ui/format.ts diff --git a/apps/isshin/src/lib/ui/index.ts b/apps/__deprecated/isshin/src/lib/ui/index.ts similarity index 100% rename from apps/isshin/src/lib/ui/index.ts rename to apps/__deprecated/isshin/src/lib/ui/index.ts diff --git a/apps/isshin/src/lib/ui/with-result-loader.tsx b/apps/__deprecated/isshin/src/lib/ui/with-result-loader.tsx similarity index 100% rename from apps/isshin/src/lib/ui/with-result-loader.tsx rename to apps/__deprecated/isshin/src/lib/ui/with-result-loader.tsx diff --git a/apps/isshin/src/root.tsx b/apps/__deprecated/isshin/src/root.tsx similarity index 100% rename from apps/isshin/src/root.tsx rename to apps/__deprecated/isshin/src/root.tsx diff --git a/apps/isshin/src/routes.ts b/apps/__deprecated/isshin/src/routes.ts similarity index 100% rename from apps/isshin/src/routes.ts rename to apps/__deprecated/isshin/src/routes.ts diff --git a/apps/isshin/src/routes/_index/route.tsx b/apps/__deprecated/isshin/src/routes/_index/route.tsx similarity index 100% rename from apps/isshin/src/routes/_index/route.tsx rename to apps/__deprecated/isshin/src/routes/_index/route.tsx diff --git a/apps/isshin/src/routes/blocked/route.tsx b/apps/__deprecated/isshin/src/routes/blocked/route.tsx similarity index 100% rename from apps/isshin/src/routes/blocked/route.tsx rename to apps/__deprecated/isshin/src/routes/blocked/route.tsx diff --git a/apps/isshin/src/routes/settings/route.tsx b/apps/__deprecated/isshin/src/routes/settings/route.tsx similarity index 100% rename from apps/isshin/src/routes/settings/route.tsx rename to apps/__deprecated/isshin/src/routes/settings/route.tsx diff --git a/apps/isshin/src/styles.css b/apps/__deprecated/isshin/src/styles.css similarity index 100% rename from apps/isshin/src/styles.css rename to apps/__deprecated/isshin/src/styles.css diff --git a/apps/isshin/src/types.ts b/apps/__deprecated/isshin/src/types.ts similarity index 100% rename from apps/isshin/src/types.ts rename to apps/__deprecated/isshin/src/types.ts diff --git a/apps/isshin/src/vite-env.d.ts b/apps/__deprecated/isshin/src/vite-env.d.ts similarity index 100% rename from apps/isshin/src/vite-env.d.ts rename to apps/__deprecated/isshin/src/vite-env.d.ts diff --git a/apps/isshin/tailwind.config.ts b/apps/__deprecated/isshin/tailwind.config.ts similarity index 100% rename from apps/isshin/tailwind.config.ts rename to apps/__deprecated/isshin/tailwind.config.ts diff --git a/apps/isshin/tsconfig.json b/apps/__deprecated/isshin/tsconfig.json similarity index 100% rename from apps/isshin/tsconfig.json rename to apps/__deprecated/isshin/tsconfig.json diff --git a/apps/isshin/vite.config.ts b/apps/__deprecated/isshin/vite.config.ts similarity index 100% rename from apps/isshin/vite.config.ts rename to apps/__deprecated/isshin/vite.config.ts diff --git a/apps/__deprecated/kairos_expo-54/.gitignore b/apps/__deprecated/kairos_expo-54/.gitignore new file mode 100644 index 0000000..f8c6c2e --- /dev/null +++ b/apps/__deprecated/kairos_expo-54/.gitignore @@ -0,0 +1,43 @@ +# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files + +# dependencies +node_modules/ + +# Expo +.expo/ +dist/ +web-build/ +expo-env.d.ts + +# Native +.kotlin/ +*.orig.* +*.jks +*.p8 +*.p12 +*.key +*.mobileprovision + +# Metro +.metro-health-check* + +# debug +npm-debug.* +yarn-debug.* +yarn-error.* + +# macOS +.DS_Store +*.pem + +# local env files +.env*.local + +# typescript +*.tsbuildinfo + +app-example + +# generated native folders +/ios +/android diff --git a/apps/__deprecated/kairos_expo-54/README.md b/apps/__deprecated/kairos_expo-54/README.md new file mode 100644 index 0000000..48dd63f --- /dev/null +++ b/apps/__deprecated/kairos_expo-54/README.md @@ -0,0 +1,50 @@ +# Welcome to your Expo app 👋 + +This is an [Expo](https://expo.dev) project created with [`create-expo-app`](https://www.npmjs.com/package/create-expo-app). + +## Get started + +1. Install dependencies + + ```bash + npm install + ``` + +2. Start the app + + ```bash + npx expo start + ``` + +In the output, you'll find options to open the app in a + +- [development build](https://docs.expo.dev/develop/development-builds/introduction/) +- [Android emulator](https://docs.expo.dev/workflow/android-studio-emulator/) +- [iOS simulator](https://docs.expo.dev/workflow/ios-simulator/) +- [Expo Go](https://expo.dev/go), a limited sandbox for trying out app development with Expo + +You can start developing by editing the files inside the **app** directory. This project uses [file-based routing](https://docs.expo.dev/router/introduction). + +## Get a fresh project + +When you're ready, run: + +```bash +npm run reset-project +``` + +This command will move the starter code to the **app-example** directory and create a blank **app** directory where you can start developing. + +## Learn more + +To learn more about developing your project with Expo, look at the following resources: + +- [Expo documentation](https://docs.expo.dev/): Learn fundamentals, or go into advanced topics with our [guides](https://docs.expo.dev/guides). +- [Learn Expo tutorial](https://docs.expo.dev/tutorial/introduction/): Follow a step-by-step tutorial where you'll create a project that runs on Android, iOS, and the web. + +## Join the community + +Join our community of developers creating universal apps. + +- [Expo on GitHub](https://github.com/expo/expo): View our open source platform and contribute. +- [Discord community](https://chat.expo.dev): Chat with Expo users and ask questions. diff --git a/apps/__deprecated/kairos_expo-54/app.json b/apps/__deprecated/kairos_expo-54/app.json new file mode 100644 index 0000000..36a83ff --- /dev/null +++ b/apps/__deprecated/kairos_expo-54/app.json @@ -0,0 +1,48 @@ +{ + "expo": { + "name": "kairos", + "slug": "kairos", + "version": "0.0.1", + "orientation": "portrait", + "icon": "./assets/images/icon.png", + "scheme": "kairos", + "userInterfaceStyle": "automatic", + "newArchEnabled": true, + "ios": { + "supportsTablet": true + }, + "android": { + "adaptiveIcon": { + "backgroundColor": "#E6F4FE", + "foregroundImage": "./assets/images/android-icon-foreground.png", + "backgroundImage": "./assets/images/android-icon-background.png", + "monochromeImage": "./assets/images/android-icon-monochrome.png" + }, + "edgeToEdgeEnabled": true, + "predictiveBackGestureEnabled": false + }, + "web": { + "output": "static", + "favicon": "./assets/images/favicon.png" + }, + "plugins": [ + "expo-router", + [ + "expo-splash-screen", + { + "image": "./assets/images/splash-icon.png", + "imageWidth": 200, + "resizeMode": "contain", + "backgroundColor": "#ffffff", + "dark": { + "backgroundColor": "#000000" + } + } + ] + ], + "experiments": { + "typedRoutes": true, + "reactCompiler": true + } + } +} diff --git a/apps/__deprecated/kairos_expo-54/assets/images/android-icon-background.png b/apps/__deprecated/kairos_expo-54/assets/images/android-icon-background.png new file mode 100644 index 0000000..5ffefc5 Binary files /dev/null and b/apps/__deprecated/kairos_expo-54/assets/images/android-icon-background.png differ diff --git a/apps/__deprecated/kairos_expo-54/assets/images/android-icon-foreground.png b/apps/__deprecated/kairos_expo-54/assets/images/android-icon-foreground.png new file mode 100644 index 0000000..3a9e501 Binary files /dev/null and b/apps/__deprecated/kairos_expo-54/assets/images/android-icon-foreground.png differ diff --git a/apps/__deprecated/kairos_expo-54/assets/images/android-icon-monochrome.png b/apps/__deprecated/kairos_expo-54/assets/images/android-icon-monochrome.png new file mode 100644 index 0000000..77484eb Binary files /dev/null and b/apps/__deprecated/kairos_expo-54/assets/images/android-icon-monochrome.png differ diff --git a/apps/__deprecated/kairos_expo-54/assets/images/favicon.png b/apps/__deprecated/kairos_expo-54/assets/images/favicon.png new file mode 100644 index 0000000..408bd74 Binary files /dev/null and b/apps/__deprecated/kairos_expo-54/assets/images/favicon.png differ diff --git a/apps/__deprecated/kairos_expo-54/assets/images/icon.png b/apps/__deprecated/kairos_expo-54/assets/images/icon.png new file mode 100644 index 0000000..7165a53 Binary files /dev/null and b/apps/__deprecated/kairos_expo-54/assets/images/icon.png differ diff --git a/apps/__deprecated/kairos_expo-54/assets/images/partial-react-logo.png b/apps/__deprecated/kairos_expo-54/assets/images/partial-react-logo.png new file mode 100644 index 0000000..66fd957 Binary files /dev/null and b/apps/__deprecated/kairos_expo-54/assets/images/partial-react-logo.png differ diff --git a/apps/__deprecated/kairos_expo-54/assets/images/react-logo.png b/apps/__deprecated/kairos_expo-54/assets/images/react-logo.png new file mode 100644 index 0000000..9d72a9f Binary files /dev/null and b/apps/__deprecated/kairos_expo-54/assets/images/react-logo.png differ diff --git a/apps/__deprecated/kairos_expo-54/assets/images/react-logo@2x.png b/apps/__deprecated/kairos_expo-54/assets/images/react-logo@2x.png new file mode 100644 index 0000000..2229b13 Binary files /dev/null and b/apps/__deprecated/kairos_expo-54/assets/images/react-logo@2x.png differ diff --git a/apps/__deprecated/kairos_expo-54/assets/images/react-logo@3x.png b/apps/__deprecated/kairos_expo-54/assets/images/react-logo@3x.png new file mode 100644 index 0000000..a99b203 Binary files /dev/null and b/apps/__deprecated/kairos_expo-54/assets/images/react-logo@3x.png differ diff --git a/apps/__deprecated/kairos_expo-54/assets/images/splash-icon.png b/apps/__deprecated/kairos_expo-54/assets/images/splash-icon.png new file mode 100644 index 0000000..03d6f6b Binary files /dev/null and b/apps/__deprecated/kairos_expo-54/assets/images/splash-icon.png differ diff --git a/apps/__deprecated/kairos_expo-54/eslint.config.js b/apps/__deprecated/kairos_expo-54/eslint.config.js new file mode 100644 index 0000000..5025da6 --- /dev/null +++ b/apps/__deprecated/kairos_expo-54/eslint.config.js @@ -0,0 +1,10 @@ +// https://docs.expo.dev/guides/using-eslint/ +const { defineConfig } = require('eslint/config'); +const expoConfig = require('eslint-config-expo/flat'); + +module.exports = defineConfig([ + expoConfig, + { + ignores: ['dist/*'], + }, +]); diff --git a/apps/__deprecated/kairos_expo-54/metro.config.js b/apps/__deprecated/kairos_expo-54/metro.config.js new file mode 100644 index 0000000..07c9fce --- /dev/null +++ b/apps/__deprecated/kairos_expo-54/metro.config.js @@ -0,0 +1,7 @@ +// Learn more https://docs.expo.io/guides/customizing-metro +const { getDefaultConfig } = require('expo/metro-config'); + +/** @type {import('expo/metro-config').MetroConfig} */ +const config = getDefaultConfig(__dirname); + +module.exports = config; diff --git a/apps/__deprecated/kairos_expo-54/package.json b/apps/__deprecated/kairos_expo-54/package.json new file mode 100644 index 0000000..02363ca --- /dev/null +++ b/apps/__deprecated/kairos_expo-54/package.json @@ -0,0 +1,61 @@ +{ + "name": "@repo/kairos", + "version": "0.0.1", + "private": true, + "description": "", + "keywords": [], + "bugs": { + "url": "https://github.com/builder-group/lab/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/builder-group/lab.git" + }, + "license": "AGPL-3.0-or-later", + "author": "@bennobuilder", + "main": "expo-router/entry", + "scripts": { + "clean": "shx rm -rf build && shx rm -rf .turbo && shx rm -rf .expo && shx rm -rf node_modules", + "format": "prettier --write \"**/*.{ts,tsx,md,json,js,jsx}\"", + "install:clean": "pnpm run clean && pnpm install", + "lint": "expo lint", + "start:android": "expo start --android", + "start:dev": "expo start", + "start:ios": "expo start --ios", + "start:web": "expo start --web", + "test": "echo \"🧪 No tests defined yet.\"", + "typecheck": "tsc --noEmit", + "update:latest": "pnpm update --latest" + }, + "dependencies": { + "@expo/vector-icons": "^15.0.3", + "@react-navigation/bottom-tabs": "^7.4.0", + "@react-navigation/elements": "^2.6.3", + "@react-navigation/native": "^7.1.8", + "expo": "~54.0.33", + "expo-constants": "~18.0.13", + "expo-font": "~14.0.11", + "expo-haptics": "~15.0.8", + "expo-image": "~3.0.11", + "expo-linking": "~8.0.11", + "expo-router": "~6.0.23", + "expo-splash-screen": "~31.0.13", + "expo-status-bar": "~3.0.9", + "expo-symbols": "~1.0.8", + "expo-system-ui": "~6.0.9", + "expo-web-browser": "~15.0.10", + "react": "19.1.0", + "react-dom": "19.1.0", + "react-native": "0.81.5", + "react-native-gesture-handler": "~2.28.0", + "react-native-reanimated": "~4.1.1", + "react-native-safe-area-context": "~5.6.0", + "react-native-screens": "~4.16.0", + "react-native-web": "~0.21.0", + "react-native-worklets": "0.5.1" + }, + "devDependencies": { + "@types/react": "~19.1.0", + "eslint-config-expo": "~10.0.0" + } +} diff --git a/apps/__deprecated/kairos_expo-54/src/app/(tabs)/_layout.tsx b/apps/__deprecated/kairos_expo-54/src/app/(tabs)/_layout.tsx new file mode 100644 index 0000000..28149ea --- /dev/null +++ b/apps/__deprecated/kairos_expo-54/src/app/(tabs)/_layout.tsx @@ -0,0 +1,27 @@ +import { Tabs } from 'expo-router'; +import React from 'react'; +import { HapticTab, IconSymbol } from '@/components'; +import { Colors } from '@/environment'; +import { useColorScheme } from '@/hooks'; + +export default function TabLayout() { + const colorScheme = useColorScheme(); + + return ( + + + }} + /> + + ); +} diff --git a/apps/__deprecated/kairos_expo-54/src/app/(tabs)/index.tsx b/apps/__deprecated/kairos_expo-54/src/app/(tabs)/index.tsx new file mode 100644 index 0000000..fc61205 --- /dev/null +++ b/apps/__deprecated/kairos_expo-54/src/app/(tabs)/index.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { StyleSheet } from 'react-native'; +import { ThemedText, ThemedView } from '@/components'; + +export default function HomeScreen() { + return ( + + {/* Greeting */} + Hello World + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: 'center', + justifyContent: 'center' + } +}); diff --git a/apps/__deprecated/kairos_expo-54/src/app/_layout.tsx b/apps/__deprecated/kairos_expo-54/src/app/_layout.tsx new file mode 100644 index 0000000..23a850d --- /dev/null +++ b/apps/__deprecated/kairos_expo-54/src/app/_layout.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native'; +import { Stack } from 'expo-router'; +import { StatusBar } from 'expo-status-bar'; +import { useColorScheme } from '@/hooks'; + +export const unstable_settings = { + anchor: '(tabs)' +}; + +export default function RootLayout() { + const colorScheme = useColorScheme(); + + return ( + + + + + + + ); +} diff --git a/apps/__deprecated/kairos_expo-54/src/components/HapticTab.tsx b/apps/__deprecated/kairos_expo-54/src/components/HapticTab.tsx new file mode 100644 index 0000000..2d1b8cf --- /dev/null +++ b/apps/__deprecated/kairos_expo-54/src/components/HapticTab.tsx @@ -0,0 +1,20 @@ +import { type BottomTabBarButtonProps } from '@react-navigation/bottom-tabs'; +import { PlatformPressable } from '@react-navigation/elements'; +import * as Haptics from 'expo-haptics'; +import React from 'react'; + +export const HapticTab: React.FC = (props) => { + const { onPressIn, ...rest } = props; + + return ( + { + if (process.env.EXPO_OS === 'ios') { + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); + } + onPressIn?.(ev); + }} + /> + ); +}; diff --git a/apps/__deprecated/kairos_expo-54/src/components/IconSymbol.ios.tsx b/apps/__deprecated/kairos_expo-54/src/components/IconSymbol.ios.tsx new file mode 100644 index 0000000..5610977 --- /dev/null +++ b/apps/__deprecated/kairos_expo-54/src/components/IconSymbol.ios.tsx @@ -0,0 +1,25 @@ +import { SymbolView, type SymbolViewProps, type SymbolWeight } from 'expo-symbols'; +import React from 'react'; +import { type StyleProp, type ViewStyle } from 'react-native'; + +export const IconSymbol: React.FC = (props) => { + const { name, size = 24, color, style, weight = 'regular' } = props; + + return ( + + ); +}; + +interface TIconSymbolProps { + name: SymbolViewProps['name']; + size?: number; + color: string; + style?: StyleProp; + weight?: SymbolWeight; +} diff --git a/apps/__deprecated/kairos_expo-54/src/components/IconSymbol.tsx b/apps/__deprecated/kairos_expo-54/src/components/IconSymbol.tsx new file mode 100644 index 0000000..619ad3a --- /dev/null +++ b/apps/__deprecated/kairos_expo-54/src/components/IconSymbol.tsx @@ -0,0 +1,34 @@ +// Fallback for using MaterialIcons on Android and web. + +import MaterialIcons from '@expo/vector-icons/MaterialIcons'; +import { type SymbolViewProps, type SymbolWeight } from 'expo-symbols'; +import React, { type ComponentProps } from 'react'; +import { type OpaqueColorValue, type StyleProp, type TextStyle } from 'react-native'; + +/** + * Add your SF Symbols to Material Icons mappings here. + * - see Material Icons in the [Icons Directory](https://icons.expo.fyi). + * - see SF Symbols in the [SF Symbols](https://developer.apple.com/sf-symbols/) app. + */ +const MAPPING = { + 'house.fill': 'home', + 'paperplane.fill': 'send', + 'chevron.left.forwardslash.chevron.right': 'code', + 'chevron.right': 'chevron-right' +} as TIconMapping; + +export const IconSymbol: React.FC = (props) => { + const { name, size = 24, color, style } = props; + return ; +}; + +interface TIconSymbolProps { + name: TIconSymbolName; + size?: number; + color: string | OpaqueColorValue; + style?: StyleProp; + weight?: SymbolWeight; +} + +type TIconMapping = Record['name']>; +type TIconSymbolName = keyof typeof MAPPING; diff --git a/apps/__deprecated/kairos_expo-54/src/components/ThemedText.tsx b/apps/__deprecated/kairos_expo-54/src/components/ThemedText.tsx new file mode 100644 index 0000000..bb644ab --- /dev/null +++ b/apps/__deprecated/kairos_expo-54/src/components/ThemedText.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { StyleSheet, Text, type TextProps } from 'react-native'; +import { useThemeColor } from '@/hooks'; + +export const ThemedText: React.FC = (props) => { + const { style, lightColor, darkColor, type = 'default', ...rest } = props; + const color = useThemeColor({ light: lightColor, dark: darkColor }, 'text'); + + return ( + + ); +}; + +const styles = StyleSheet.create({ + default: { fontSize: 16, lineHeight: 24 }, + defaultSemiBold: { fontSize: 16, lineHeight: 24, fontWeight: '600' }, + title: { fontSize: 32, fontWeight: 'bold', lineHeight: 32 }, + subtitle: { fontSize: 20, fontWeight: 'bold' }, + link: { lineHeight: 30, fontSize: 16, color: '#0a7ea4' } +}); + +interface TThemedTextProps extends TextProps { + lightColor?: string; + darkColor?: string; + type?: 'default' | 'title' | 'defaultSemiBold' | 'subtitle' | 'link'; +} diff --git a/apps/__deprecated/kairos_expo-54/src/components/ThemedView.tsx b/apps/__deprecated/kairos_expo-54/src/components/ThemedView.tsx new file mode 100644 index 0000000..e29b324 --- /dev/null +++ b/apps/__deprecated/kairos_expo-54/src/components/ThemedView.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import { View, type ViewProps } from 'react-native'; +import { useThemeColor } from '@/hooks'; + +export const ThemedView: React.FC = (props) => { + const { style, lightColor, darkColor, ...rest } = props; + const backgroundColor = useThemeColor({ light: lightColor, dark: darkColor }, 'background'); + + return ; +}; + +interface TThemedViewProps extends ViewProps { + lightColor?: string; + darkColor?: string; +} diff --git a/apps/__deprecated/kairos_expo-54/src/components/index.ts b/apps/__deprecated/kairos_expo-54/src/components/index.ts new file mode 100644 index 0000000..d634045 --- /dev/null +++ b/apps/__deprecated/kairos_expo-54/src/components/index.ts @@ -0,0 +1,4 @@ +export * from './HapticTab'; +export * from './IconSymbol'; +export * from './ThemedText'; +export * from './ThemedView'; diff --git a/apps/__deprecated/kairos_expo-54/src/environment/index.ts b/apps/__deprecated/kairos_expo-54/src/environment/index.ts new file mode 100644 index 0000000..7b1f54e --- /dev/null +++ b/apps/__deprecated/kairos_expo-54/src/environment/index.ts @@ -0,0 +1 @@ +export * from './theme'; diff --git a/apps/__deprecated/kairos_expo-54/src/environment/theme.ts b/apps/__deprecated/kairos_expo-54/src/environment/theme.ts new file mode 100644 index 0000000..0f3ad17 --- /dev/null +++ b/apps/__deprecated/kairos_expo-54/src/environment/theme.ts @@ -0,0 +1,48 @@ +import { Platform } from 'react-native'; + +const tintColorLight = '#0a7ea4'; +const tintColorDark = '#fff'; + +export const Colors = { + light: { + text: '#11181C', + background: '#fff', + tint: tintColorLight, + icon: '#687076', + tabIconDefault: '#687076', + tabIconSelected: tintColorLight + }, + dark: { + text: '#ECEDEE', + background: '#151718', + tint: tintColorDark, + icon: '#9BA1A6', + tabIconDefault: '#9BA1A6', + tabIconSelected: tintColorDark + } +}; + +export const Fonts = Platform.select({ + ios: { + /** iOS `UIFontDescriptorSystemDesignDefault` */ + sans: 'system-ui', + /** iOS `UIFontDescriptorSystemDesignSerif` */ + serif: 'ui-serif', + /** iOS `UIFontDescriptorSystemDesignRounded` */ + rounded: 'ui-rounded', + /** iOS `UIFontDescriptorSystemDesignMonospaced` */ + mono: 'ui-monospace' + }, + default: { + sans: 'normal', + serif: 'serif', + rounded: 'normal', + mono: 'monospace' + }, + web: { + sans: "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif", + serif: "Georgia, 'Times New Roman', serif", + rounded: "'SF Pro Rounded', 'Hiragino Maru Gothic ProN', Meiryo, 'MS PGothic', sans-serif", + mono: "SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace" + } +}); diff --git a/apps/__deprecated/kairos_expo-54/src/features/.gitkeep b/apps/__deprecated/kairos_expo-54/src/features/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/apps/__deprecated/kairos_expo-54/src/hooks/index.ts b/apps/__deprecated/kairos_expo-54/src/hooks/index.ts new file mode 100644 index 0000000..95459bc --- /dev/null +++ b/apps/__deprecated/kairos_expo-54/src/hooks/index.ts @@ -0,0 +1,2 @@ +export * from './use-color-scheme'; +export * from './use-theme-color'; diff --git a/apps/__deprecated/kairos_expo-54/src/hooks/use-color-scheme.ts b/apps/__deprecated/kairos_expo-54/src/hooks/use-color-scheme.ts new file mode 100644 index 0000000..17e3c63 --- /dev/null +++ b/apps/__deprecated/kairos_expo-54/src/hooks/use-color-scheme.ts @@ -0,0 +1 @@ +export { useColorScheme } from 'react-native'; diff --git a/apps/__deprecated/kairos_expo-54/src/hooks/use-color-scheme.web.ts b/apps/__deprecated/kairos_expo-54/src/hooks/use-color-scheme.web.ts new file mode 100644 index 0000000..c72d824 --- /dev/null +++ b/apps/__deprecated/kairos_expo-54/src/hooks/use-color-scheme.web.ts @@ -0,0 +1,21 @@ +import { useEffect, useState } from 'react'; +import { useColorScheme as useRNColorScheme } from 'react-native'; + +/** + * To support static rendering, this value needs to be re-calculated on the client side for web + */ +export function useColorScheme() { + const [hasHydrated, setHasHydrated] = useState(false); + + useEffect(() => { + setHasHydrated(true); + }, []); + + const colorScheme = useRNColorScheme(); + + if (hasHydrated) { + return colorScheme; + } + + return 'light'; +} diff --git a/apps/__deprecated/kairos_expo-54/src/hooks/use-theme-color.ts b/apps/__deprecated/kairos_expo-54/src/hooks/use-theme-color.ts new file mode 100644 index 0000000..d2bfbae --- /dev/null +++ b/apps/__deprecated/kairos_expo-54/src/hooks/use-theme-color.ts @@ -0,0 +1,16 @@ +import { Colors } from '@/environment'; +import { useColorScheme } from './use-color-scheme'; + +export function useThemeColor( + props: { light?: string; dark?: string }, + colorName: keyof typeof Colors.light & keyof typeof Colors.dark +): string { + const theme = useColorScheme() ?? 'light'; + const colorFromProps = props[theme as keyof typeof props]; + + if (colorFromProps != null) { + return colorFromProps; + } + + return Colors[theme as keyof typeof Colors][colorName]; +} diff --git a/apps/__deprecated/kairos_expo-54/tsconfig.json b/apps/__deprecated/kairos_expo-54/tsconfig.json new file mode 100644 index 0000000..38f3374 --- /dev/null +++ b/apps/__deprecated/kairos_expo-54/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "expo/tsconfig.base", + "compilerOptions": { + "strict": true, + "paths": { + "@/*": [ + "./src/*" + ] + } + }, + "include": [ + "**/*.ts", + "**/*.tsx", + ".expo/types/**/*.ts", + "expo-env.d.ts" + ] +} diff --git a/apps/tabbytap/.gitignore b/apps/__deprecated/tabbytap/.gitignore similarity index 100% rename from apps/tabbytap/.gitignore rename to apps/__deprecated/tabbytap/.gitignore diff --git a/apps/tabbytap/Keyboard/Info.plist b/apps/__deprecated/tabbytap/Keyboard/Info.plist similarity index 100% rename from apps/tabbytap/Keyboard/Info.plist rename to apps/__deprecated/tabbytap/Keyboard/Info.plist diff --git a/apps/tabbytap/Keyboard/Keyboard.entitlements b/apps/__deprecated/tabbytap/Keyboard/Keyboard.entitlements similarity index 100% rename from apps/tabbytap/Keyboard/Keyboard.entitlements rename to apps/__deprecated/tabbytap/Keyboard/Keyboard.entitlements diff --git a/apps/tabbytap/Keyboard/KeyboardDebug.entitlements b/apps/__deprecated/tabbytap/Keyboard/KeyboardDebug.entitlements similarity index 100% rename from apps/tabbytap/Keyboard/KeyboardDebug.entitlements rename to apps/__deprecated/tabbytap/Keyboard/KeyboardDebug.entitlements diff --git a/apps/tabbytap/Keyboard/KeyboardViewController.swift b/apps/__deprecated/tabbytap/Keyboard/KeyboardViewController.swift similarity index 100% rename from apps/tabbytap/Keyboard/KeyboardViewController.swift rename to apps/__deprecated/tabbytap/Keyboard/KeyboardViewController.swift diff --git a/apps/tabbytap/Keyboard/MascotState.swift b/apps/__deprecated/tabbytap/Keyboard/MascotState.swift similarity index 100% rename from apps/tabbytap/Keyboard/MascotState.swift rename to apps/__deprecated/tabbytap/Keyboard/MascotState.swift diff --git a/apps/tabbytap/Keyboard/MascotView.swift b/apps/__deprecated/tabbytap/Keyboard/MascotView.swift similarity index 100% rename from apps/tabbytap/Keyboard/MascotView.swift rename to apps/__deprecated/tabbytap/Keyboard/MascotView.swift diff --git a/apps/tabbytap/Keyboard/Media.xcassets/Contents.json b/apps/__deprecated/tabbytap/Keyboard/Media.xcassets/Contents.json similarity index 100% rename from apps/tabbytap/Keyboard/Media.xcassets/Contents.json rename to apps/__deprecated/tabbytap/Keyboard/Media.xcassets/Contents.json diff --git a/apps/tabbytap/Keyboard/Media.xcassets/base.imageset/Contents.json b/apps/__deprecated/tabbytap/Keyboard/Media.xcassets/base.imageset/Contents.json similarity index 100% rename from apps/tabbytap/Keyboard/Media.xcassets/base.imageset/Contents.json rename to apps/__deprecated/tabbytap/Keyboard/Media.xcassets/base.imageset/Contents.json diff --git a/apps/tabbytap/Keyboard/Media.xcassets/base.imageset/base.png b/apps/__deprecated/tabbytap/Keyboard/Media.xcassets/base.imageset/base.png similarity index 100% rename from apps/tabbytap/Keyboard/Media.xcassets/base.imageset/base.png rename to apps/__deprecated/tabbytap/Keyboard/Media.xcassets/base.imageset/base.png diff --git a/apps/tabbytap/Keyboard/Media.xcassets/left-down.imageset/Contents.json b/apps/__deprecated/tabbytap/Keyboard/Media.xcassets/left-down.imageset/Contents.json similarity index 100% rename from apps/tabbytap/Keyboard/Media.xcassets/left-down.imageset/Contents.json rename to apps/__deprecated/tabbytap/Keyboard/Media.xcassets/left-down.imageset/Contents.json diff --git a/apps/tabbytap/Keyboard/Media.xcassets/left-down.imageset/left-down.png b/apps/__deprecated/tabbytap/Keyboard/Media.xcassets/left-down.imageset/left-down.png similarity index 100% rename from apps/tabbytap/Keyboard/Media.xcassets/left-down.imageset/left-down.png rename to apps/__deprecated/tabbytap/Keyboard/Media.xcassets/left-down.imageset/left-down.png diff --git a/apps/tabbytap/Keyboard/Media.xcassets/left-up.imageset/Contents.json b/apps/__deprecated/tabbytap/Keyboard/Media.xcassets/left-up.imageset/Contents.json similarity index 100% rename from apps/tabbytap/Keyboard/Media.xcassets/left-up.imageset/Contents.json rename to apps/__deprecated/tabbytap/Keyboard/Media.xcassets/left-up.imageset/Contents.json diff --git a/apps/tabbytap/Keyboard/Media.xcassets/left-up.imageset/left-up.png b/apps/__deprecated/tabbytap/Keyboard/Media.xcassets/left-up.imageset/left-up.png similarity index 100% rename from apps/tabbytap/Keyboard/Media.xcassets/left-up.imageset/left-up.png rename to apps/__deprecated/tabbytap/Keyboard/Media.xcassets/left-up.imageset/left-up.png diff --git a/apps/tabbytap/Keyboard/Media.xcassets/right-down.imageset/Contents.json b/apps/__deprecated/tabbytap/Keyboard/Media.xcassets/right-down.imageset/Contents.json similarity index 100% rename from apps/tabbytap/Keyboard/Media.xcassets/right-down.imageset/Contents.json rename to apps/__deprecated/tabbytap/Keyboard/Media.xcassets/right-down.imageset/Contents.json diff --git a/apps/tabbytap/Keyboard/Media.xcassets/right-down.imageset/right-down.png b/apps/__deprecated/tabbytap/Keyboard/Media.xcassets/right-down.imageset/right-down.png similarity index 100% rename from apps/tabbytap/Keyboard/Media.xcassets/right-down.imageset/right-down.png rename to apps/__deprecated/tabbytap/Keyboard/Media.xcassets/right-down.imageset/right-down.png diff --git a/apps/tabbytap/Keyboard/Media.xcassets/right-up.imageset/Contents.json b/apps/__deprecated/tabbytap/Keyboard/Media.xcassets/right-up.imageset/Contents.json similarity index 100% rename from apps/tabbytap/Keyboard/Media.xcassets/right-up.imageset/Contents.json rename to apps/__deprecated/tabbytap/Keyboard/Media.xcassets/right-up.imageset/Contents.json diff --git a/apps/tabbytap/Keyboard/Media.xcassets/right-up.imageset/right-up.png b/apps/__deprecated/tabbytap/Keyboard/Media.xcassets/right-up.imageset/right-up.png similarity index 100% rename from apps/tabbytap/Keyboard/Media.xcassets/right-up.imageset/right-up.png rename to apps/__deprecated/tabbytap/Keyboard/Media.xcassets/right-up.imageset/right-up.png diff --git a/apps/tabbytap/Keyboard/MeowActionHandler.swift b/apps/__deprecated/tabbytap/Keyboard/MeowActionHandler.swift similarity index 100% rename from apps/tabbytap/Keyboard/MeowActionHandler.swift rename to apps/__deprecated/tabbytap/Keyboard/MeowActionHandler.swift diff --git a/apps/tabbytap/Keyboard/MeowSoundPlayer.swift b/apps/__deprecated/tabbytap/Keyboard/MeowSoundPlayer.swift similarity index 100% rename from apps/tabbytap/Keyboard/MeowSoundPlayer.swift rename to apps/__deprecated/tabbytap/Keyboard/MeowSoundPlayer.swift diff --git a/apps/tabbytap/Keyboard/meow.mp3 b/apps/__deprecated/tabbytap/Keyboard/meow.mp3 similarity index 100% rename from apps/tabbytap/Keyboard/meow.mp3 rename to apps/__deprecated/tabbytap/Keyboard/meow.mp3 diff --git a/apps/tabbytap/README.md b/apps/__deprecated/tabbytap/README.md similarity index 100% rename from apps/tabbytap/README.md rename to apps/__deprecated/tabbytap/README.md diff --git a/apps/tabbytap/TabbyTap.xcodeproj/project.pbxproj b/apps/__deprecated/tabbytap/TabbyTap.xcodeproj/project.pbxproj similarity index 100% rename from apps/tabbytap/TabbyTap.xcodeproj/project.pbxproj rename to apps/__deprecated/tabbytap/TabbyTap.xcodeproj/project.pbxproj diff --git a/apps/tabbytap/TabbyTap.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/apps/__deprecated/tabbytap/TabbyTap.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from apps/tabbytap/TabbyTap.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to apps/__deprecated/tabbytap/TabbyTap.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/apps/tabbytap/TabbyTap.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/apps/__deprecated/tabbytap/TabbyTap.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved similarity index 100% rename from apps/tabbytap/TabbyTap.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved rename to apps/__deprecated/tabbytap/TabbyTap.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/apps/tabbytap/TabbyTap/Assets.xcassets/AccentColor.colorset/Contents.json b/apps/__deprecated/tabbytap/TabbyTap/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from apps/tabbytap/TabbyTap/Assets.xcassets/AccentColor.colorset/Contents.json rename to apps/__deprecated/tabbytap/TabbyTap/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/apps/tabbytap/TabbyTap/Assets.xcassets/AppIcon.appiconset/Contents.json b/apps/__deprecated/tabbytap/TabbyTap/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from apps/tabbytap/TabbyTap/Assets.xcassets/AppIcon.appiconset/Contents.json rename to apps/__deprecated/tabbytap/TabbyTap/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/apps/tabbytap/TabbyTap/Assets.xcassets/Contents.json b/apps/__deprecated/tabbytap/TabbyTap/Assets.xcassets/Contents.json similarity index 100% rename from apps/tabbytap/TabbyTap/Assets.xcassets/Contents.json rename to apps/__deprecated/tabbytap/TabbyTap/Assets.xcassets/Contents.json diff --git a/apps/tabbytap/TabbyTap/ContentView.swift b/apps/__deprecated/tabbytap/TabbyTap/ContentView.swift similarity index 100% rename from apps/tabbytap/TabbyTap/ContentView.swift rename to apps/__deprecated/tabbytap/TabbyTap/ContentView.swift diff --git a/apps/tabbytap/TabbyTap/KeyboardApp+Extension.swift b/apps/__deprecated/tabbytap/TabbyTap/KeyboardApp+Extension.swift similarity index 100% rename from apps/tabbytap/TabbyTap/KeyboardApp+Extension.swift rename to apps/__deprecated/tabbytap/TabbyTap/KeyboardApp+Extension.swift diff --git a/apps/tabbytap/TabbyTap/SharedStorage.swift b/apps/__deprecated/tabbytap/TabbyTap/SharedStorage.swift similarity index 100% rename from apps/tabbytap/TabbyTap/SharedStorage.swift rename to apps/__deprecated/tabbytap/TabbyTap/SharedStorage.swift diff --git a/apps/tabbytap/TabbyTap/TabbyTap.entitlements b/apps/__deprecated/tabbytap/TabbyTap/TabbyTap.entitlements similarity index 100% rename from apps/tabbytap/TabbyTap/TabbyTap.entitlements rename to apps/__deprecated/tabbytap/TabbyTap/TabbyTap.entitlements diff --git a/apps/tabbytap/TabbyTap/TabbyTapApp.swift b/apps/__deprecated/tabbytap/TabbyTap/TabbyTapApp.swift similarity index 100% rename from apps/tabbytap/TabbyTap/TabbyTapApp.swift rename to apps/__deprecated/tabbytap/TabbyTap/TabbyTapApp.swift diff --git a/apps/tabbytap/TabbyTap/TabbyTapDebug.entitlements b/apps/__deprecated/tabbytap/TabbyTap/TabbyTapDebug.entitlements similarity index 100% rename from apps/tabbytap/TabbyTap/TabbyTapDebug.entitlements rename to apps/__deprecated/tabbytap/TabbyTap/TabbyTapDebug.entitlements diff --git a/apps/derive/.gitignore b/apps/derive/.gitignore new file mode 100644 index 0000000..f5b322f --- /dev/null +++ b/apps/derive/.gitignore @@ -0,0 +1,95 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## User-specific files +xcuserdata/ + +## Xcode 8 and earlier +*.xcscmblueprint +*.xccheckout + +## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) +*.xcscmblueprint +*.xccheckout + +## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) +build/ +DerivedData/ +*.moved-aside +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 + +## Obj-C/Swift specific +*.hmap + +## App packaging +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +# Package.pins +# Package.resolved +# *.xcodeproj +# +# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata +# hence it is not needed unless you have added a package configuration file to your project +# .swiftpm + +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# Pods/ +# +# Add this line if you want to avoid checking in source code from the Xcode workspace +# *.xcworkspace + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build/ + +# Accio dependency management +Dependencies/ +.accio/ + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. +# Instead, use fastlane to re-generate the screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/#source-control + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots/**/*.png +fastlane/test_output + +# Code Injection +# +# After new code Injection tools there's a generated folder /iOSInjectionProject +# https://github.com/johnno1962/injectionforxcode + +iOSInjectionProject/ + diff --git a/apps/derive/Derive.xcodeproj/project.pbxproj b/apps/derive/Derive.xcodeproj/project.pbxproj new file mode 100644 index 0000000..6a951aa --- /dev/null +++ b/apps/derive/Derive.xcodeproj/project.pbxproj @@ -0,0 +1,370 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 77; + objects = { + +/* Begin PBXFileReference section */ + D3ACCE852F0CE7D6004E01DE /* Derive.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Derive.app; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ + D3ACD0D12F0D39EF004E01DE /* Exceptions for "Derive" folder in "Derive" target */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + Info.plist, + ); + target = D3ACCE842F0CE7D6004E01DE /* Derive */; + }; +/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + D3ACCE872F0CE7D6004E01DE /* Derive */ = { + isa = PBXFileSystemSynchronizedRootGroup; + exceptions = ( + D3ACD0D12F0D39EF004E01DE /* Exceptions for "Derive" folder in "Derive" target */, + ); + path = Derive; + sourceTree = ""; + }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + D3ACCE822F0CE7D6004E01DE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + D3ACCE7C2F0CE7D6004E01DE = { + isa = PBXGroup; + children = ( + D3ACCE872F0CE7D6004E01DE /* Derive */, + D3ACCE862F0CE7D6004E01DE /* Products */, + ); + sourceTree = ""; + }; + D3ACCE862F0CE7D6004E01DE /* Products */ = { + isa = PBXGroup; + children = ( + D3ACCE852F0CE7D6004E01DE /* Derive.app */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + D3ACCE842F0CE7D6004E01DE /* Derive */ = { + isa = PBXNativeTarget; + buildConfigurationList = D3ACCE902F0CE7D7004E01DE /* Build configuration list for PBXNativeTarget "Derive" */; + buildPhases = ( + D3ACCE812F0CE7D6004E01DE /* Sources */, + D3ACCE822F0CE7D6004E01DE /* Frameworks */, + D3ACCE832F0CE7D6004E01DE /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + D3ACCE872F0CE7D6004E01DE /* Derive */, + ); + name = Derive; + packageProductDependencies = ( + ); + productName = Derive; + productReference = D3ACCE852F0CE7D6004E01DE /* Derive.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + D3ACCE7D2F0CE7D6004E01DE /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 2610; + LastUpgradeCheck = 2610; + TargetAttributes = { + D3ACCE842F0CE7D6004E01DE = { + CreatedOnToolsVersion = 26.1.1; + }; + }; + }; + buildConfigurationList = D3ACCE802F0CE7D6004E01DE /* Build configuration list for PBXProject "Derive" */; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = D3ACCE7C2F0CE7D6004E01DE; + minimizedProjectReferenceProxies = 1; + preferredProjectObjectVersion = 77; + productRefGroup = D3ACCE862F0CE7D6004E01DE /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D3ACCE842F0CE7D6004E01DE /* Derive */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + D3ACCE832F0CE7D6004E01DE /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + D3ACCE812F0CE7D6004E01DE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + D3ACCE8E2F0CE7D7004E01DE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = 9RQRHCCMVL; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 26.1; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + D3ACCE8F2F0CE7D7004E01DE /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = 9RQRHCCMVL; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 26.1; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + D3ACCE912F0CE7D7004E01DE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 3; + DEVELOPMENT_TEAM = 9RQRHCCMVL; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = Derive/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = Derive; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.lifestyle"; + INFOPLIST_KEY_NSCameraUsageDescription = "Derive needs camera access to take photos for your grid."; + INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "Derive needs access to save your completed grid to your photo library."; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + IPHONEOS_DEPLOYMENT_TARGET = 18.6; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 0.0.2; + PRODUCT_BUNDLE_IDENTIFIER = com.buildergroup.Derive; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Debug; + }; + D3ACCE922F0CE7D7004E01DE /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 3; + DEVELOPMENT_TEAM = 9RQRHCCMVL; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = Derive/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = Derive; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.lifestyle"; + INFOPLIST_KEY_NSCameraUsageDescription = "Derive needs camera access to take photos for your grid."; + INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "Derive needs access to save your completed grid to your photo library."; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + IPHONEOS_DEPLOYMENT_TARGET = 18.6; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 0.0.2; + PRODUCT_BUNDLE_IDENTIFIER = com.buildergroup.Derive; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + D3ACCE802F0CE7D6004E01DE /* Build configuration list for PBXProject "Derive" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D3ACCE8E2F0CE7D7004E01DE /* Debug */, + D3ACCE8F2F0CE7D7004E01DE /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D3ACCE902F0CE7D7004E01DE /* Build configuration list for PBXNativeTarget "Derive" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D3ACCE912F0CE7D7004E01DE /* Debug */, + D3ACCE922F0CE7D7004E01DE /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = D3ACCE7D2F0CE7D6004E01DE /* Project object */; +} diff --git a/apps/derive/Derive.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/apps/derive/Derive.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/apps/derive/Derive.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/apps/derive/Derive/AppIcon.icon/Assets/1-layer.svg b/apps/derive/Derive/AppIcon.icon/Assets/1-layer.svg new file mode 100644 index 0000000..026b268 --- /dev/null +++ b/apps/derive/Derive/AppIcon.icon/Assets/1-layer.svg @@ -0,0 +1,3 @@ + + + diff --git a/apps/derive/Derive/AppIcon.icon/icon.json b/apps/derive/Derive/AppIcon.icon/icon.json new file mode 100644 index 0000000..41b3779 --- /dev/null +++ b/apps/derive/Derive/AppIcon.icon/icon.json @@ -0,0 +1,34 @@ +{ + "fill" : { + "solid" : "display-p3:0.95045,0.93751,0.91953,1.00000" + }, + "groups" : [ + { + "hidden" : false, + "layers" : [ + { + "blend-mode" : "normal", + "glass" : true, + "hidden" : false, + "image-name" : "1-layer.svg", + "name" : "1-layer" + } + ], + "shadow" : { + "kind" : "neutral", + "opacity" : 0.5 + }, + "specular" : true, + "translucency" : { + "enabled" : true, + "value" : 0.5 + } + } + ], + "supported-platforms" : { + "circles" : [ + "watchOS" + ], + "squares" : "shared" + } +} \ No newline at end of file diff --git a/apps/derive/Derive/Assets.xcassets/AccentColor.colorset/Contents.json b/apps/derive/Derive/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/apps/derive/Derive/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apps/derive/Derive/Assets.xcassets/AppIcon.appiconset/Contents.json b/apps/derive/Derive/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..2305880 --- /dev/null +++ b/apps/derive/Derive/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,35 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apps/derive/Derive/Assets.xcassets/Contents.json b/apps/derive/Derive/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/apps/derive/Derive/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apps/derive/Derive/Assets.xcassets/colors/Contents.json b/apps/derive/Derive/Assets.xcassets/colors/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/apps/derive/Derive/Assets.xcassets/colors/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apps/derive/Derive/Assets.xcassets/colors/background.colorset/Contents.json b/apps/derive/Derive/Assets.xcassets/colors/background.colorset/Contents.json new file mode 100644 index 0000000..94d22bb --- /dev/null +++ b/apps/derive/Derive/Assets.xcassets/colors/background.colorset/Contents.json @@ -0,0 +1,56 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xEA", + "green" : "0xEF", + "red" : "0xF3" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "light" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xEA", + "green" : "0xEF", + "red" : "0xF3" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x00", + "green" : "0x00", + "red" : "0x00" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apps/derive/Derive/Assets.xcassets/colors/card.colorset/Contents.json b/apps/derive/Derive/Assets.xcassets/colors/card.colorset/Contents.json new file mode 100644 index 0000000..8492b0c --- /dev/null +++ b/apps/derive/Derive/Assets.xcassets/colors/card.colorset/Contents.json @@ -0,0 +1,56 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "1.000", + "green" : "1.000", + "red" : "1.000" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "light" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "1.000", + "green" : "1.000", + "red" : "1.000" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.118", + "green" : "0.110", + "red" : "0.110" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apps/derive/Derive/Assets.xcassets/colors/cta.colorset/Contents.json b/apps/derive/Derive/Assets.xcassets/colors/cta.colorset/Contents.json new file mode 100644 index 0000000..9903aec --- /dev/null +++ b/apps/derive/Derive/Assets.xcassets/colors/cta.colorset/Contents.json @@ -0,0 +1,56 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.000", + "green" : "0.000", + "red" : "0.000" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "light" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.000", + "green" : "0.000", + "red" : "0.000" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "1.000", + "green" : "1.000", + "red" : "1.000" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apps/derive/Derive/Assets.xcassets/colors/ctaContent.colorset/Contents.json b/apps/derive/Derive/Assets.xcassets/colors/ctaContent.colorset/Contents.json new file mode 100644 index 0000000..737e910 --- /dev/null +++ b/apps/derive/Derive/Assets.xcassets/colors/ctaContent.colorset/Contents.json @@ -0,0 +1,56 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "1.000", + "green" : "1.000", + "red" : "1.000" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "light" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "1.000", + "green" : "1.000", + "red" : "1.000" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.000", + "green" : "0.000", + "red" : "0.000" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apps/derive/Derive/Assets.xcassets/icons/Contents.json b/apps/derive/Derive/Assets.xcassets/icons/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/apps/derive/Derive/Assets.xcassets/icons/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apps/derive/Derive/Assets.xcassets/icons/github.symbolset/Contents.json b/apps/derive/Derive/Assets.xcassets/icons/github.symbolset/Contents.json new file mode 100644 index 0000000..c1e81e1 --- /dev/null +++ b/apps/derive/Derive/Assets.xcassets/icons/github.symbolset/Contents.json @@ -0,0 +1,12 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "symbols" : [ + { + "filename" : "github.svg", + "idiom" : "universal" + } + ] +} diff --git a/apps/derive/Derive/Assets.xcassets/icons/github.symbolset/github.svg b/apps/derive/Derive/Assets.xcassets/icons/github.symbolset/github.svg new file mode 100644 index 0000000..d6af429 --- /dev/null +++ b/apps/derive/Derive/Assets.xcassets/icons/github.symbolset/github.svg @@ -0,0 +1,84 @@ + + + + + + + Weight/Scale Variations + Ultralight + Thin + Light + Regular + Medium + Semibold + Bold + Heavy + Black + + + + + + + + + + + Design Variations + Symbols are supported in up to nine weights and three scales. + For optimal layout with text and other symbols, vertically align + symbols with the adjacent text. + + + + + + Margins + Leading and trailing margins on the left and right side of each symbol + can be adjusted by modifying the x-location of the margin guidelines. + Modifications are automatically applied proportionally to all + scales and weights. + + + + Exporting + Symbols should be outlined when exporting to ensure the + design is preserved when submitting to Xcode. + Template v.6.0 + Requires Xcode 16 or greater + Generated from square + Typeset at 100.0 points + Small + Medium + Large + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apps/derive/Derive/Assets.xcassets/icons/logo.symbolset/Contents.json b/apps/derive/Derive/Assets.xcassets/icons/logo.symbolset/Contents.json new file mode 100644 index 0000000..f1e059e --- /dev/null +++ b/apps/derive/Derive/Assets.xcassets/icons/logo.symbolset/Contents.json @@ -0,0 +1,12 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "symbols" : [ + { + "filename" : "logo.svg", + "idiom" : "universal" + } + ] +} diff --git a/apps/derive/Derive/Assets.xcassets/icons/logo.symbolset/logo.svg b/apps/derive/Derive/Assets.xcassets/icons/logo.symbolset/logo.svg new file mode 100644 index 0000000..c31ac0f --- /dev/null +++ b/apps/derive/Derive/Assets.xcassets/icons/logo.symbolset/logo.svg @@ -0,0 +1,94 @@ + + + + + + + + diff --git a/apps/derive/Derive/Assets.xcassets/illustrations/Contents.json b/apps/derive/Derive/Assets.xcassets/illustrations/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/apps/derive/Derive/Assets.xcassets/illustrations/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apps/derive/Derive/ContentView.swift b/apps/derive/Derive/ContentView.swift new file mode 100644 index 0000000..88d4f7a --- /dev/null +++ b/apps/derive/Derive/ContentView.swift @@ -0,0 +1,79 @@ +// +// ContentView.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import SwiftData +import SwiftUI + +enum AppTab: Hashable { + case derive, discover, settings +} + +struct ContentView: View { + @QuerySingleton private var player: Player + @State private var showSplash = true + @State private var selectedTab: AppTab = .derive + + var body: some View { + Group { + if showSplash { + SplashView() + } else if !player.hasCompletedOnboarding { + OnboardingView() + } else { + mainTabView + } + } + .onAppear { + DispatchQueue.main.asyncAfter(deadline: .now() + 1) { + showSplash = false + } + } + } + + // MARK: - UI + + private var mainTabView: some View { + TabView(selection: $selectedTab) { + Tab(value: .derive) { + NavigationStack { + HomeView(selectedTab: $selectedTab) + } + } label: { + Label("Dérive", image: "logo") + } + + Tab(value: .discover) { + NavigationStack { + BrowseView(selectedTab: $selectedTab) + } + } label: { + Label("Discover", systemImage: "sparkle.magnifyingglass") + } + + Tab(value: .settings) { + NavigationStack { + SettingsView() + } + } label: { + Label("Settings", systemImage: "gearshape") + } + } + } +} + +#Preview { + ContentView() + .previewDataContainer() +} + +#Preview("Onboarded") { + ContentView() + .previewDataContainer { context in + let player = Player.instance(with: context) + player.onboardingCompletedAt = Date() + } +} diff --git a/apps/derive/Derive/DeriveApp.swift b/apps/derive/Derive/DeriveApp.swift new file mode 100644 index 0000000..41d8e76 --- /dev/null +++ b/apps/derive/Derive/DeriveApp.swift @@ -0,0 +1,48 @@ +// +// DeriveApp.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import SwiftData +import SwiftUI + +@main +struct DeriveApp: App { + init() { + configureNavigationBarAppearance() + } + + var body: some Scene { + WindowGroup { + ContentView() + .modelContainer(DataContainer.shared.modelContainer) + } + } + + private func configureNavigationBarAppearance() { + let appearance = UINavigationBarAppearance() + appearance.configureWithDefaultBackground() + + // Variable fonts - need to use font descriptor for weight + let titleDescriptor = UIFontDescriptor(fontAttributes: [ + .family: "Erode Variable", + .traits: [UIFontDescriptor.TraitKey.weight: UIFont.Weight.bold] + ]) + let titleFont = UIFont(descriptor: titleDescriptor, size: 18) + + let largeTitleDescriptor = UIFontDescriptor(fontAttributes: [ + .family: "Erode Variable", + .traits: [UIFontDescriptor.TraitKey.weight: UIFont.Weight.bold] + ]) + let largeTitleFont = UIFont(descriptor: largeTitleDescriptor, size: 36) + + appearance.titleTextAttributes = [.font: titleFont] + appearance.largeTitleTextAttributes = [.font: largeTitleFont] + + UINavigationBar.appearance().standardAppearance = appearance + UINavigationBar.appearance().scrollEdgeAppearance = appearance + UINavigationBar.appearance().compactAppearance = appearance + } +} diff --git a/apps/derive/Derive/Environment/ChallengeRegistry.swift b/apps/derive/Derive/Environment/ChallengeRegistry.swift new file mode 100644 index 0000000..8ea5f67 --- /dev/null +++ b/apps/derive/Derive/Environment/ChallengeRegistry.swift @@ -0,0 +1,28 @@ +// +// ChallengeRegistry.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import SwiftUI + +struct ChallengeRegistry { + static let shared = ChallengeRegistry() + private init() {} + + let all: [Challenge] = [ + Challenge(id: "yellow", prompt: "find things in yellow"), + Challenge(id: "red", prompt: "find things in red"), + Challenge(id: "blue", prompt: "find things in blue"), + Challenge(id: "green", prompt: "find things in green"), + Challenge(id: "orange", prompt: "find things in orange"), + Challenge(id: "pink", prompt: "find things in pink"), + Challenge(id: "purple", prompt: "find things in purple"), + Challenge(id: "brown", prompt: "find things in brown"), + ] + + func challenge(id: String) -> Challenge? { + all.first { $0.id == id } + } +} diff --git a/apps/derive/Derive/Environment/Configs/AppConfig.swift b/apps/derive/Derive/Environment/Configs/AppConfig.swift new file mode 100644 index 0000000..d8f79b8 --- /dev/null +++ b/apps/derive/Derive/Environment/Configs/AppConfig.swift @@ -0,0 +1,70 @@ +// +// AppConfig.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import Foundation + +enum AppConfig { + // MARK: - App Information + + static var appName: String { + Bundle.main.object(forInfoDictionaryKey: "CFBundleDisplayName") + as? String + ?? Bundle.main.object(forInfoDictionaryKey: "CFBundleName") + as? String + ?? "Derive" + } + + static var bundleIdentifier: String { + Bundle.main.bundleIdentifier ?? "com.buildergroup.Derive" + } + + static var version: String { + Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "1.0" + } + + static var build: String { + Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "1" + } + + // MARK: - External Links + + static var websiteURL: URL? { + URL(string: "https://builder.group/apps/derive") + } + + static var appStoreURL: URL? { + nil // TODO: Add App Store URL after release + } + + static var privacyPolicyURL: URL? { + URL(string: "https://builder.group/apps/derive/legal/privacy") + } + + static var githubURL: URL? { + URL(string: "https://github.com/builder-group/lab") + } + + // MARK: - Feedback & Support + + static var feedbackEmail: String { + "support@builder.group" + } + + static func mailtoURL(subject: String) -> URL? { + let fullSubject = "[Dérive] \(subject)" + let encodedSubject = + fullSubject.addingPercentEncoding( + withAllowedCharacters: .urlQueryAllowed + ) ?? fullSubject + return URL(string: "mailto:\(feedbackEmail)?subject=\(encodedSubject)") + } + + // MARK: - Image Configuration + + /// Maximum image dimension when storing photos + static let maxImageDimension: CGFloat = 1000 +} diff --git a/apps/derive/Derive/Environment/DataContainer.swift b/apps/derive/Derive/Environment/DataContainer.swift new file mode 100644 index 0000000..21cd864 --- /dev/null +++ b/apps/derive/Derive/Environment/DataContainer.swift @@ -0,0 +1,85 @@ +// +// DataContainer.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import Foundation +import OSLog +import SwiftData +import SwiftUI + +@Observable +@MainActor +class DataContainer { + static let shared = DataContainer() + + let modelContainer: ModelContainer + + var modelContext: ModelContext { + modelContainer.mainContext + } + + init(isStoredInMemoryOnly: Bool = false) { + do { + modelContainer = try Self.createContainer( + isStoredInMemoryOnly: isStoredInMemoryOnly + ) + } catch { + guard !isStoredInMemoryOnly else { + fatalError("Failed to create in-memory container: \(error)") + } + Logger( + subsystem: AppConfig.bundleIdentifier, + category: "DataContainer" + ).error( + "Failed to create persistent container, using in-memory: \(error.localizedDescription)" + ) + modelContainer = try! Self.createContainer( + isStoredInMemoryOnly: true + ) + } + + DataContainer.ensureDefaults(in: modelContext) + } + + private static func createContainer( + isStoredInMemoryOnly: Bool + ) throws -> ModelContainer { + let schema = Schema(Self.schema()) + let configuration = ModelConfiguration( + "DeriveData", + schema: schema, + isStoredInMemoryOnly: isStoredInMemoryOnly, + allowsSave: true, + cloudKitDatabase: .none + ) + return try ModelContainer(for: schema, configurations: [configuration]) + } + + static func schema() -> [any PersistentModel.Type] { + [ + Player.self, + Derive.self, + ] + } + + static func ensureDefaults(in context: ModelContext) { + _ = Player.instance(with: context) + try? context.save() + } +} + +// MARK: - Preview Support + +extension View { + func previewDataContainer(seed: ((ModelContext) -> Void)? = nil) -> some View { + let container = DataContainer(isStoredInMemoryOnly: true) + if let seed = seed { + seed(container.modelContext) + try? container.modelContext.save() + } + return self.modelContainer(container.modelContainer) + } +} diff --git a/apps/derive/Derive/Extensions/Color+App.swift b/apps/derive/Derive/Extensions/Color+App.swift new file mode 100644 index 0000000..285ca16 --- /dev/null +++ b/apps/derive/Derive/Extensions/Color+App.swift @@ -0,0 +1,15 @@ +// +// Color+App.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import SwiftUI + +extension Color { + static let appBackground = Color("background") + static let appCard = Color("card") + static let appCta = Color("cta") + static let appCtaContent = Color("ctaContent") +} diff --git a/apps/derive/Derive/Features/Challenge/Models/Challenge.swift b/apps/derive/Derive/Features/Challenge/Models/Challenge.swift new file mode 100644 index 0000000..805401e --- /dev/null +++ b/apps/derive/Derive/Features/Challenge/Models/Challenge.swift @@ -0,0 +1,40 @@ +// +// Challenge.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import SwiftUI + +struct Challenge: Identifiable, Codable, Hashable { + let id: String + let type: String + let prompt: String + + init(id: String, type: String = "color", prompt: String) { + self.id = id + self.type = type + self.prompt = prompt + } + + // MARK: - Display + + var title: String { + id.capitalized + } + + var color: Color { + switch id { + case "yellow": return .yellow + case "red": return .red + case "blue": return .blue + case "green": return .green + case "orange": return .orange + case "pink": return .pink + case "purple": return .purple + case "brown": return .brown + default: return .accentColor + } + } +} diff --git a/apps/derive/Derive/Features/Derive/Models/Derive.swift b/apps/derive/Derive/Features/Derive/Models/Derive.swift new file mode 100644 index 0000000..6c0d749 --- /dev/null +++ b/apps/derive/Derive/Features/Derive/Models/Derive.swift @@ -0,0 +1,78 @@ +// +// Derive.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import Foundation +import SwiftData + +/// A player's instance of doing a challenge. +/// Created when the player joins a challenge, contains their photos and progress. +@Model +final class Derive { + var id: UUID + var challengeId: String + var startedAt: Date + var completedAt: Date? + + /// Photos stored as JSON-encoded Data for SwiftData compatibility + var photosData: Data? + + @Relationship + var player: Player? + + /// Access photos as [PhotoSlot] array + var photos: [PhotoSlot] { + get { + guard let data = photosData else { + return (0..<9).map { _ in PhotoSlot() } + } + return (try? JSONDecoder().decode([PhotoSlot].self, from: data)) + ?? (0..<9).map { _ in PhotoSlot() } + } + set { + photosData = try? JSONEncoder().encode(newValue) + } + } + + init( + id: UUID = UUID(), + challengeId: String, + player: Player + ) { + self.id = id + self.challengeId = challengeId + self.startedAt = Date() + self.photosData = try? JSONEncoder().encode((0..<9).map { _ in PhotoSlot() }) + self.player = player + } + + // MARK: - Challenge Reference + + /// The challenge template this derive is based on + var challenge: Challenge? { + ChallengeRegistry.shared.challenge(id: challengeId) + } + + var prompt: String { + challenge?.prompt ?? "Unknown challenge" + } + + // MARK: - State + + var isActive: Bool { + completedAt == nil + } + + // MARK: - Progress + + var filledCount: Int { + photos.filter { $0.isFilled }.count + } + + var isComplete: Bool { + filledCount == 9 + } +} diff --git a/apps/derive/Derive/Features/Derive/Models/PhotoSlot.swift b/apps/derive/Derive/Features/Derive/Models/PhotoSlot.swift new file mode 100644 index 0000000..34123a3 --- /dev/null +++ b/apps/derive/Derive/Features/Derive/Models/PhotoSlot.swift @@ -0,0 +1,26 @@ +// +// PhotoSlot.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import Foundation + +/// A single slot in the 3×3 photo grid. +/// Stored as Codable array in Derive model. +struct PhotoSlot: Codable, Identifiable { + let id: UUID + var imageData: Data? + var capturedAt: Date? + + init(id: UUID = UUID(), imageData: Data? = nil, capturedAt: Date? = nil) { + self.id = id + self.imageData = imageData + self.capturedAt = capturedAt + } + + var isFilled: Bool { + imageData != nil + } +} diff --git a/apps/derive/Derive/Features/Derive/Views/GridCellView.swift b/apps/derive/Derive/Features/Derive/Views/GridCellView.swift new file mode 100644 index 0000000..a9eecf4 --- /dev/null +++ b/apps/derive/Derive/Features/Derive/Views/GridCellView.swift @@ -0,0 +1,47 @@ +// +// GridCellView.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import SwiftUI + +struct GridCellView: View { + let slot: PhotoSlot + var isSelected: Bool = false + let onTap: () -> Void + + var body: some View { + Button(action: onTap) { + ZStack { + if let data = slot.imageData, let image = UIImage(data: data) { + Image(uiImage: image) + .resizable() + .scaledToFill() + } else { + Color.appCard + Image(systemName: "plus") + .font(.title3) + .foregroundStyle(.tertiary) + } + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + .clipped() + .opacity(isSelected ? 0.5 : 1) + .contentShape(Rectangle()) + } + .buttonStyle(.plain) + } +} + +#Preview { + HStack(spacing: 4) { + GridCellView(slot: PhotoSlot(), onTap: {}) + GridCellView(slot: PhotoSlot(), onTap: {}) + GridCellView(slot: PhotoSlot(), onTap: {}) + } + .frame(height: 120) + .padding() + .background(Color.appBackground) +} diff --git a/apps/derive/Derive/Features/Derive/Views/GridView.swift b/apps/derive/Derive/Features/Derive/Views/GridView.swift new file mode 100644 index 0000000..1fc448b --- /dev/null +++ b/apps/derive/Derive/Features/Derive/Views/GridView.swift @@ -0,0 +1,78 @@ +// +// GridView.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import SwiftUI + +struct GridView: View { + let photos: [PhotoSlot] + var selectedIndex: Int? + var spacing: CGFloat = 4 + let onSlotTap: (Int) -> Void + + var body: some View { + GeometryReader { geo in + let cellSize = (geo.size.width - spacing * 2) / 3 + + LazyVGrid( + columns: [ + GridItem(.fixed(cellSize), spacing: spacing), + GridItem(.fixed(cellSize), spacing: spacing), + GridItem(.fixed(cellSize), spacing: spacing), + ], + spacing: spacing + ) { + ForEach(Array(photos.enumerated()), id: \.element.id) { index, slot in + GridCellView(slot: slot, isSelected: selectedIndex == index) { + onSlotTap(index) + } + .frame(width: cellSize, height: cellSize) + } + } + } + .aspectRatio(1, contentMode: .fit) + } +} + +struct GridThumbnail: View { + let photos: [PhotoSlot] + var spacing: CGFloat = 2 + + var body: some View { + GeometryReader { geo in + let cellSize = (geo.size.width - spacing * 2) / 3 + + LazyVGrid( + columns: [ + GridItem(.fixed(cellSize), spacing: spacing), + GridItem(.fixed(cellSize), spacing: spacing), + GridItem(.fixed(cellSize), spacing: spacing), + ], + spacing: spacing + ) { + ForEach(photos) { slot in + ZStack { + if let data = slot.imageData, let image = UIImage(data: data) { + Image(uiImage: image) + .resizable() + .scaledToFill() + } else { + Color.appCard + } + } + .frame(width: cellSize, height: cellSize) + .clipped() + } + } + } + .aspectRatio(1, contentMode: .fit) + } +} + +#Preview { + GridView(photos: (0 ..< 9).map { _ in PhotoSlot() }, onSlotTap: { _ in }) + .padding() +} diff --git a/apps/derive/Derive/Features/Player/Models/Player.swift b/apps/derive/Derive/Features/Player/Models/Player.swift new file mode 100644 index 0000000..f74fa0e --- /dev/null +++ b/apps/derive/Derive/Features/Player/Models/Player.swift @@ -0,0 +1,53 @@ +// +// Player.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import Foundation +import SwiftData + +/// Singleton model representing the player. +/// Owns all derives and tracks player state. +@Model +final class Player: SingletonModel { + var createdAt: Date + var onboardingCompletedAt: Date? + + @Relationship(deleteRule: .cascade, inverse: \Derive.player) + var derives: [Derive] = [] + + init(createdAt: Date = Date()) { + self.createdAt = createdAt + } + + static var `default`: Player { + Player() + } + + // MARK: - Onboarding + + var hasCompletedOnboarding: Bool { + onboardingCompletedAt != nil + } + + // MARK: - Derives + + /// The currently active derive (not completed, not expired) + var activeDerive: Derive? { + derives.first { $0.isActive } + } + + /// All completed derives, sorted by completion date (newest first) + var completedDerives: [Derive] { + derives + .filter { $0.completedAt != nil } + .sorted { ($0.completedAt ?? .distantPast) > ($1.completedAt ?? .distantPast) } + } + + /// Whether the player currently has an active derive + var hasActiveDerive: Bool { + activeDerive != nil + } +} diff --git a/apps/derive/Derive/Fonts/Erode-Variable.ttf b/apps/derive/Derive/Fonts/Erode-Variable.ttf new file mode 100644 index 0000000..dabc6b0 Binary files /dev/null and b/apps/derive/Derive/Fonts/Erode-Variable.ttf differ diff --git a/apps/derive/Derive/Fonts/Font+Erode.swift b/apps/derive/Derive/Fonts/Font+Erode.swift new file mode 100644 index 0000000..8544429 --- /dev/null +++ b/apps/derive/Derive/Fonts/Font+Erode.swift @@ -0,0 +1,25 @@ +// +// Font+Erode.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import SwiftUI +import UIKit + +extension Font { + static func erode(_ size: CGFloat, weight: Font.Weight = .regular) -> Font { + .custom("Erode Variable", size: size).weight(weight) + } +} + +extension UIFont { + static func erode(_ size: CGFloat, weight: UIFont.Weight = .regular) -> UIFont { + let descriptor = UIFontDescriptor(fontAttributes: [ + .name: "Erode Variable", + .traits: [UIFontDescriptor.TraitKey.weight: weight] + ]) + return UIFont(descriptor: descriptor, size: size) + } +} diff --git a/apps/derive/Derive/Info.plist b/apps/derive/Derive/Info.plist new file mode 100644 index 0000000..7dbf353 --- /dev/null +++ b/apps/derive/Derive/Info.plist @@ -0,0 +1,16 @@ + + + + + UIAppFonts + + Erode-Variable.ttf + + NSCameraUsageDescription + Take photos for your dérive challenge + NSPhotoLibraryUsageDescription + Select photos for your dérive and save completed grids + NSPhotoLibraryAddUsageDescription + Save your completed dérive grid to Photos + + diff --git a/apps/derive/Derive/Lib/CameraPicker.swift b/apps/derive/Derive/Lib/CameraPicker.swift new file mode 100644 index 0000000..421b35d --- /dev/null +++ b/apps/derive/Derive/Lib/CameraPicker.swift @@ -0,0 +1,46 @@ +// +// CameraPicker.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import SwiftUI +import UIKit + +struct CameraPicker: UIViewControllerRepresentable { + let onCapture: (UIImage?) -> Void + + func makeUIViewController(context: Context) -> UIImagePickerController { + let picker = UIImagePickerController() + picker.sourceType = .camera + picker.delegate = context.coordinator + return picker + } + + func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {} + + func makeCoordinator() -> Coordinator { + Coordinator(onCapture: onCapture) + } + + class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate { + let onCapture: (UIImage?) -> Void + + init(onCapture: @escaping (UIImage?) -> Void) { + self.onCapture = onCapture + } + + func imagePickerController( + _ picker: UIImagePickerController, + didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any] + ) { + let image = info[.originalImage] as? UIImage + onCapture(image) + } + + func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { + onCapture(nil) + } + } +} diff --git a/apps/derive/Derive/Lib/QuerySingleton.swift b/apps/derive/Derive/Lib/QuerySingleton.swift new file mode 100644 index 0000000..2347975 --- /dev/null +++ b/apps/derive/Derive/Lib/QuerySingleton.swift @@ -0,0 +1,28 @@ +// +// QuerySingleton.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import SwiftData +import SwiftUI + +/// Property wrapper for querying singleton SwiftData models. +/// Returns the first instance from the store, or falls back to `Model.default` if not found. +/// +/// ```swift +/// @QuerySingleton private var player: Player +/// ``` +@propertyWrapper +struct QuerySingleton: DynamicProperty { + @Query private var queried: [Model] + + var wrappedValue: Model { + queried.first ?? Model.default + } + + init() { + _queried = Query() + } +} diff --git a/apps/derive/Derive/Lib/SingletonModel.swift b/apps/derive/Derive/Lib/SingletonModel.swift new file mode 100644 index 0000000..678d826 --- /dev/null +++ b/apps/derive/Derive/Lib/SingletonModel.swift @@ -0,0 +1,32 @@ +// +// SingletonModel.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import Foundation +import SwiftData + +/// Protocol for singleton SwiftData models that have a default instance. +protocol SingletonModel: PersistentModel { + /// Default instance used when creating new singleton instances. + static var `default`: Self { get } + + /// Fetches existing instance or creates one from `default` if not found. + static func instance(with modelContext: ModelContext) -> Self +} + +extension SingletonModel { + static func instance(with modelContext: ModelContext) -> Self { + let descriptor = FetchDescriptor() + if let result = try? modelContext.fetch(descriptor).first { + return result + } else { + let instance = Self.default + modelContext.insert(instance) + try? modelContext.save() + return instance + } + } +} diff --git a/apps/derive/Derive/Routes/Browse/BrowseView.swift b/apps/derive/Derive/Routes/Browse/BrowseView.swift new file mode 100644 index 0000000..20dd279 --- /dev/null +++ b/apps/derive/Derive/Routes/Browse/BrowseView.swift @@ -0,0 +1,93 @@ +// +// BrowseView.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import SwiftUI + +struct BrowseView: View { + @Binding var selectedTab: AppTab + @State private var selectedChallenge: Challenge? + + private let challenges = ChallengeRegistry.shared.all + + // MARK: - UI + + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 0) { + colorSection + + Spacer().frame(height: 32) + + soonSection + + Spacer().frame(height: 40) + } + .padding(.horizontal, 20) + } + .scrollIndicators(.hidden) + .background(Color.appBackground) + .navigationTitle("Discover") + .navigationDestination(item: $selectedChallenge) { challenge in + ChallengeDetailView(challenge: challenge, selectedTab: $selectedTab) + } + } + + private var colorSection: some View { + VStack(alignment: .leading, spacing: 12) { + Text("Color") + .font(.erode(24, weight: .semibold)) + + LazyVGrid( + columns: [ + GridItem(.flexible(), spacing: 12), + GridItem(.flexible(), spacing: 12), + GridItem(.flexible(), spacing: 12) + ], + spacing: 12 + ) { + ForEach(challenges) { challenge in + challengeCard(challenge) + } + } + } + } + + private func challengeCard(_ challenge: Challenge) -> some View { + Button { + selectedChallenge = challenge + } label: { + VStack(spacing: 8) { + RoundedRectangle(cornerRadius: 12) + .fill(challenge.color) + .aspectRatio(1, contentMode: .fit) + + Text(challenge.title) + .font(.caption.weight(.medium)) + .foregroundStyle(.primary) + } + } + .buttonStyle(.plain) + } + + private var soonSection: some View { + VStack(alignment: .leading, spacing: 12) { + Text("Soon") + .font(.erode(24, weight: .semibold)) + + Text("More ways to explore coming soon — textures, shapes, themes, and beyond.") + .font(.subheadline) + .foregroundStyle(.secondary) + } + } +} + +#Preview { + NavigationStack { + BrowseView(selectedTab: .constant(.discover)) + } + .previewDataContainer() +} diff --git a/apps/derive/Derive/Routes/ChallengeDetail/ChallengeDetailView.swift b/apps/derive/Derive/Routes/ChallengeDetail/ChallengeDetailView.swift new file mode 100644 index 0000000..6d7f9c0 --- /dev/null +++ b/apps/derive/Derive/Routes/ChallengeDetail/ChallengeDetailView.swift @@ -0,0 +1,152 @@ +// +// ChallengeDetailView.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import SwiftData +import SwiftUI + +struct ChallengeDetailView: View { + let challenge: Challenge + @Binding var selectedTab: AppTab + @QuerySingleton private var player: Player + @Environment(\.modelContext) private var modelContext + @Environment(\.dismiss) private var dismiss + + @State private var showAbandonConfirm = false + + // MARK: - UI + + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 0) { + colorPreview + + Spacer().frame(height: 24) + + promptLabel + + Spacer().frame(height: 32) + + infoSection + + Spacer().frame(height: 40) + } + .padding(.horizontal, 24) + } + .scrollIndicators(.hidden) + .background(Color.appBackground) + .navigationTitle(challenge.title) + .safeAreaInset(edge: .bottom) { + startButton + .padding(.horizontal, 24) + .padding(.bottom, 24) + .background(Color.appBackground) + } + } + + private var colorPreview: some View { + RoundedRectangle(cornerRadius: 16) + .fill(challenge.color) + .frame(height: 200) + } + + private var promptLabel: some View { + Text(challenge.prompt) + .font(.body) + .foregroundStyle(.secondary) + } + + private var infoSection: some View { + VStack(alignment: .leading, spacing: 16) { + infoRow(icon: "square.grid.3x3", title: "9 Photos", subtitle: "Fill a 3×3 grid") + infoRow(icon: "clock", title: "Take your time", subtitle: "No time limit") + infoRow(icon: "eye", title: "Look around", subtitle: "Find the color in your world") + } + } + + private func infoRow(icon: String, title: String, subtitle: String) -> some View { + HStack(spacing: 16) { + Image(systemName: icon) + .font(.title2) + .foregroundStyle(.secondary) + .frame(width: 32) + + VStack(alignment: .leading, spacing: 2) { + Text(title) + .font(.subheadline.weight(.medium)) + Text(subtitle) + .font(.caption) + .foregroundStyle(.secondary) + } + } + } + + private var startButton: some View { + Button { + if player.hasActiveDerive { + showAbandonConfirm = true + } else { + startDerive() + } + } label: { + Text("Start Dérive") + .font(.headline) + .foregroundStyle(Color.appCtaContent) + .frame(maxWidth: .infinity) + .padding(.vertical, 16) + .background(Color.appCta) + .clipShape(Capsule()) + } + .alert("Abandon current dérive?", isPresented: $showAbandonConfirm) { + Button("Cancel", role: .cancel) {} + Button("Abandon & Start", role: .destructive) { + abandonAndStartDerive() + } + } message: { + Text("Your current progress will be lost.") + } + } + + // MARK: - Actions + + private func startDerive() { + let derive = Derive(challengeId: challenge.id, player: player) + modelContext.insert(derive) + try? modelContext.save() + dismiss() + selectedTab = .derive + } + + private func abandonAndStartDerive() { + if let activeDerive = player.activeDerive { + modelContext.delete(activeDerive) + } + startDerive() + } +} + +#Preview { + NavigationStack { + ChallengeDetailView( + challenge: Challenge(id: "yellow", prompt: "Find 9 things in yellow"), + selectedTab: .constant(.discover) + ) + } + .previewDataContainer() +} + +#Preview("Has Active") { + NavigationStack { + ChallengeDetailView( + challenge: Challenge(id: "blue", prompt: "Find 9 things in blue"), + selectedTab: .constant(.discover) + ) + } + .previewDataContainer { ctx in + let player = Player.instance(with: ctx) + ctx.insert(Derive(challengeId: "yellow", player: player)) + } +} diff --git a/apps/derive/Derive/Routes/Completed/CompletedView.swift b/apps/derive/Derive/Routes/Completed/CompletedView.swift new file mode 100644 index 0000000..26997e6 --- /dev/null +++ b/apps/derive/Derive/Routes/Completed/CompletedView.swift @@ -0,0 +1,219 @@ +// +// CompletedView.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import Photos +import SwiftData +import SwiftUI + +struct CompletedView: View { + let derive: Derive + @Environment(\.modelContext) private var modelContext + @Environment(\.dismiss) private var dismiss + + @State private var showSaveSuccess = false + @State private var showSaveError = false + @State private var showDeleteConfirm = false + + private var durationText: String { + guard let completedAt = derive.completedAt else { return "—" } + let interval = completedAt.timeIntervalSince(derive.startedAt) + let formatter = DateComponentsFormatter() + formatter.allowedUnits = [.day, .hour, .minute] + formatter.unitsStyle = .abbreviated + formatter.maximumUnitCount = 2 + return formatter.string(from: interval) ?? "—" + } + + private var completedDateText: String { + guard let completedAt = derive.completedAt else { return "—" } + let formatter = DateFormatter() + formatter.dateStyle = .medium + return formatter.string(from: completedAt) + } + + // MARK: - UI + + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 0) { + promptLabel + + Spacer().frame(height: 24) + + GridView(photos: derive.photos, onSlotTap: { _ in }) + + Spacer().frame(height: 24) + + statsRow + + Spacer().frame(height: 40) + } + .padding(.horizontal, 24) + } + .scrollIndicators(.hidden) + .background(Color.appBackground) + .navigationBarHidden(false) + .navigationTitle(derive.challenge?.title ?? "Dérive") + .navigationBarTitleDisplayMode(.large) + .toolbar { + ToolbarItem(placement: .topBarTrailing) { + Menu { + Button { + saveToLibrary() + } label: { + Label("Save to Photos", systemImage: "square.and.arrow.down") + } + + Button(role: .destructive) { + showDeleteConfirm = true + } label: { + Label("Delete", systemImage: "trash") + } + } label: { + Image(systemName: "ellipsis.circle") + } + } + } + .alert("Saved!", isPresented: $showSaveSuccess) { + Button("OK") {} + } message: { + Text("Your dérive has been saved to Photos.") + } + .alert("Error", isPresented: $showSaveError) { + Button("OK") {} + } message: { + Text("Could not save to Photos. Please check permissions in Settings.") + } + .alert("Delete Dérive?", isPresented: $showDeleteConfirm) { + Button("Cancel", role: .cancel) {} + Button("Delete", role: .destructive) { + deleteDerive() + } + } message: { + Text("This will permanently delete this dérive and all its photos.") + } + } + + private var promptLabel: some View { + Text(derive.prompt) + .font(.body) + .foregroundStyle(.secondary) + } + + private var statsRow: some View { + HStack(spacing: 32) { + VStack(alignment: .leading, spacing: 4) { + Text("Completed") + .font(.caption) + .foregroundStyle(.secondary) + Text(completedDateText) + .font(.subheadline.weight(.medium)) + } + + VStack(alignment: .leading, spacing: 4) { + Text("Duration") + .font(.caption) + .foregroundStyle(.secondary) + Text(durationText) + .font(.subheadline.weight(.medium)) + } + + Spacer() + } + } + + // MARK: - Actions + + private func deleteDerive() { + modelContext.delete(derive) + try? modelContext.save() + dismiss() + } + + private func saveToLibrary() { + let image = createGridImage(from: derive.photos) + + PHPhotoLibrary.requestAuthorization(for: .addOnly) { status in + guard status == .authorized || status == .limited else { + DispatchQueue.main.async { showSaveError = true } + return + } + + PHPhotoLibrary.shared().performChanges { + PHAssetCreationRequest.creationRequestForAsset(from: image) + } completionHandler: { success, _ in + DispatchQueue.main.async { + if success { + showSaveSuccess = true + } else { + showSaveError = true + } + } + } + } + } + + private func createGridImage(from photos: [PhotoSlot]) -> UIImage { + let cellSize: CGFloat = 400 + let spacing: CGFloat = 4 + let gridSize = cellSize * 3 + spacing * 2 + + let renderer = UIGraphicsImageRenderer( + size: CGSize(width: gridSize, height: gridSize) + ) + + return renderer.image { ctx in + UIColor.systemBackground.setFill() + ctx.fill( + CGRect( + origin: .zero, + size: CGSize(width: gridSize, height: gridSize) + ) + ) + + for (index, slot) in photos.enumerated() { + let row = index / 3 + let col = index % 3 + let x = CGFloat(col) * (cellSize + spacing) + let y = CGFloat(row) * (cellSize + spacing) + let rect = CGRect(x: x, y: y, width: cellSize, height: cellSize) + + if let data = slot.imageData, let image = UIImage(data: data) { + image.draw(in: rect) + } else { + UIColor.secondarySystemBackground.setFill() + ctx.fill(rect) + } + } + + // Watermark + if let logo = UIImage(named: "logo") { + let maxSize: CGFloat = 48 + let padding: CGFloat = 16 + let aspectRatio = logo.size.width / logo.size.height + let watermarkWidth = aspectRatio >= 1 ? maxSize : maxSize * aspectRatio + let watermarkHeight = aspectRatio >= 1 ? maxSize / aspectRatio : maxSize + let watermarkRect = CGRect( + x: gridSize - watermarkWidth - padding, + y: gridSize - watermarkHeight - padding, + width: watermarkWidth, + height: watermarkHeight + ) + logo.withTintColor(.white.withAlphaComponent(0.5), renderingMode: .alwaysOriginal) + .draw(in: watermarkRect) + } + } + } +} + +// MARK: - Preview + +#Preview { + NavigationStack { + CompletedView(derive: Derive(challengeId: "yellow", player: Player())) + } +} diff --git a/apps/derive/Derive/Routes/Home/HomeView.swift b/apps/derive/Derive/Routes/Home/HomeView.swift new file mode 100644 index 0000000..d55f7ff --- /dev/null +++ b/apps/derive/Derive/Routes/Home/HomeView.swift @@ -0,0 +1,439 @@ +// +// HomeView.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import PhotosUI +import SwiftData +import SwiftUI + +struct HomeView: View { + @Binding var selectedTab: AppTab + @QuerySingleton private var player: Player + @Environment(\.modelContext) private var modelContext + + @State private var selectedSlotIndex: Int? + @State private var showCamera = false + @State private var selectedPhotos: [PhotosPickerItem] = [] + @State private var isProcessing = false + @State private var selectedCompletedDerive: Derive? + + private var selectedSlotIsEmpty: Bool { + guard let index = selectedSlotIndex, + let derive = player.activeDerive + else { return true } + return derive.photos[index].imageData == nil + } + + private var emptySlotCount: Int { + player.activeDerive?.photos.filter { $0.imageData == nil }.count ?? 0 + } + + private var navigationTitle: String { + player.activeDerive?.challenge?.title ?? "Dérive" + } + + // MARK: - UI + + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 0) { + Spacer().frame(height: 60) + + titleLabel + + if let derive = player.activeDerive { + Spacer().frame(height: 4) + promptLabel(derive) + Spacer().frame(height: 24) + deriveContent(derive) + } else { + emptyStateContent + } + + if !player.completedDerives.isEmpty { + historySection + } + + Spacer().frame(height: 40) + } + .padding(.horizontal, 24) + } + .scrollIndicators(.hidden) + .background(Color.appBackground) + .navigationBarHidden(true) + .navigationDestination(item: $selectedCompletedDerive) { derive in + CompletedView(derive: derive) + } + .overlay { processingOverlay } + } + + private var titleLabel: some View { + HStack(spacing: 8) { + if let color = player.activeDerive?.challenge?.color { + RoundedRectangle(cornerRadius: 4) + .fill(color) + .frame(width: 20, height: 20) + } + + Text(navigationTitle) + .font(.erode(36, weight: .bold)) + + if let derive = player.activeDerive { + Text("(\(derive.filledCount)/9)") + .font(.erode(24, weight: .medium)) + .foregroundStyle(.secondary) + } + } + } + + private func promptLabel(_ derive: Derive) -> some View { + Text(derive.prompt) + .font(.body) + .foregroundStyle(.secondary) + } + + @ViewBuilder + private func deriveContent(_ derive: Derive) -> some View { + photoGrid(derive) + .overlay { photoActionOverlay(derive) } + + Spacer().frame(height: 24) + + completeRow(derive) + .fullScreenCover(isPresented: $showCamera) { + CameraPicker { image in + if let image, let derive = player.activeDerive { + saveCameraPhoto(image, to: derive) + } + showCamera = false + } + .ignoresSafeArea() + } + .onChange(of: selectedPhotos) { _, items in + guard !items.isEmpty, let derive = player.activeDerive else { + return + } + Task { await loadSelectedPhotos(items, for: derive) } + } + } + + @ViewBuilder + private func photoActionOverlay(_ derive: Derive) -> some View { + if selectedSlotIndex != nil { + ZStack(alignment: .bottomTrailing) { + Color.black.opacity(0.01) + .onTapGesture { selectedSlotIndex = nil } + + VStack(alignment: .trailing, spacing: 8) { + if selectedSlotIsEmpty { + PhotosPicker( + selection: $selectedPhotos, + maxSelectionCount: emptySlotCount, + matching: .images + ) { + actionButton("Select Photos") + } + } else { + PhotosPicker( + selection: $selectedPhotos, + maxSelectionCount: 1, + matching: .images + ) { + actionButton("Replace Photo") + } + } + + Button { + showCamera = true + } label: { + actionButton("Camera") + } + + Button { + selectedSlotIndex = nil + } label: { + actionButtonSecondary("Cancel") + } + } + .padding(16) + .background { + Circle() + .fill(Color.appBackground) + .frame(width: 300, height: 300) + .blur(radius: 30) + .offset(x: 40, y: 40) + } + } + .clipShape(Rectangle()) + } + } + + private func actionButton(_ title: String) -> some View { + Text(title) + .font(.subheadline.weight(.semibold)) + .foregroundStyle(.primary) + .padding(.horizontal, 20) + .padding(.vertical, 10) + .background(Color.appCard) + .clipShape(Capsule()) + } + + private func actionButtonSecondary(_ title: String) -> some View { + Text(title) + .font(.subheadline) + .foregroundStyle(.secondary) + .padding(.horizontal, 20) + .padding(.vertical, 10) + } + + private func photoGrid(_ derive: Derive) -> some View { + GridView(photos: derive.photos, selectedIndex: selectedSlotIndex) { index in + selectedSlotIndex = index + } + } + + private func completeRow(_ derive: Derive) -> some View { + let canComplete = derive.filledCount > 0 + + return HStack { + Spacer() + Button { + completeDerive(derive) + } label: { + Text("Complete") + .font(.headline) + .foregroundStyle(Color.appCtaContent) + .padding(.horizontal, 32) + .padding(.vertical, 14) + .background(canComplete ? Color.appCta : Color.gray) + .clipShape(Capsule()) + } + .disabled(!canComplete) + } + } + + @ViewBuilder + private var processingOverlay: some View { + if isProcessing { + ZStack { + Color.black.opacity(0.3).ignoresSafeArea() + ProgressView() + .tint(.white) + .scaleEffect(1.5) + } + } + } + + private var emptyStateContent: some View { + VStack(spacing: 16) { + Spacer().frame(height: 100) + Image(systemName: "square.grid.3x3") + .font(.system(size: 48)) + .foregroundStyle(.secondary) + Text("No Active Dérive") + .font(.erode(24, weight: .semibold)) + Text("Pick a color and start exploring.") + .font(.body) + .foregroundStyle(.secondary) + + Spacer().frame(height: 8) + + Button { + selectedTab = .discover + } label: { + Text("Discover") + .font(.headline) + .foregroundStyle(Color.appCtaContent) + .padding(.horizontal, 32) + .padding(.vertical, 14) + .background(Color.appCta) + .clipShape(Capsule()) + } + } + .frame(maxWidth: .infinity) + .padding(.bottom, 40) + } + + private var historySection: some View { + VStack(alignment: .leading, spacing: 16) { + Spacer().frame(height: 24) + + Text("History") + .font(.erode(24, weight: .semibold)) + + LazyVGrid( + columns: [ + GridItem(.flexible(), spacing: 8), + GridItem(.flexible(), spacing: 8), + GridItem(.flexible(), spacing: 8), + ], + spacing: 8 + ) { + ForEach(player.completedDerives) { derive in + historyItem(derive) + } + } + } + } + + private func historyItem(_ derive: Derive) -> some View { + Button { + selectedCompletedDerive = derive + } label: { + GridThumbnail(photos: derive.photos) + .clipShape(RoundedRectangle(cornerRadius: 4)) + } + .buttonStyle(.plain) + } + + // MARK: - Actions + + private func saveCameraPhoto(_ image: UIImage, to derive: Derive) { + guard let index = selectedSlotIndex, + let data = processImage(image) + else { return } + + var photos = derive.photos + photos[index] = PhotoSlot( + id: photos[index].id, + imageData: data, + capturedAt: Date() + ) + derive.photos = photos + try? modelContext.save() + selectedSlotIndex = nil + } + + @MainActor + private func loadSelectedPhotos( + _ items: [PhotosPickerItem], + for derive: Derive + ) async { + isProcessing = true + defer { + isProcessing = false + selectedPhotos = [] + selectedSlotIndex = nil + } + + guard let tappedIndex = selectedSlotIndex else { return } + let tappedSlotIsEmpty = derive.photos[tappedIndex].imageData == nil + + var photos = derive.photos + + if tappedSlotIsEmpty { + // Fill empty slots starting from tapped, then others + var emptyIndices = derive.photos.enumerated() + .filter { $0.element.imageData == nil } + .map { $0.offset } + .sorted { a, b in + // Prioritize tapped index first + if a == tappedIndex { return true } + if b == tappedIndex { return false } + return a < b + } + + for item in items { + guard !emptyIndices.isEmpty else { break } + + if let data = try? await item.loadTransferable(type: Data.self), + let image = UIImage(data: data), + let processed = processImage(image) + { + let index = emptyIndices.removeFirst() + photos[index] = PhotoSlot( + id: photos[index].id, + imageData: processed, + capturedAt: Date() + ) + } + } + } else { + // Replace single photo at tapped index + if let item = items.first, + let data = try? await item.loadTransferable(type: Data.self), + let image = UIImage(data: data), + let processed = processImage(image) + { + photos[tappedIndex] = PhotoSlot( + id: photos[tappedIndex].id, + imageData: processed, + capturedAt: Date() + ) + } + } + + derive.photos = photos + try? modelContext.save() + } + + private func completeDerive(_ derive: Derive) { + derive.completedAt = Date() + try? modelContext.save() + selectedCompletedDerive = derive + } + + // MARK: - Image Processing + + private func processImage(_ image: UIImage) -> Data? { + let size = image.size + let shortSide = min(size.width, size.height) + let cropRect = CGRect( + x: (size.width - shortSide) / 2, + y: (size.height - shortSide) / 2, + width: shortSide, + height: shortSide + ) + + guard let cgImage = image.cgImage?.cropping(to: cropRect) else { + return nil + } + + let cropped = UIImage( + cgImage: cgImage, + scale: image.scale, + orientation: image.imageOrientation + ) + let maxDim = AppConfig.maxImageDimension + let finalSize = shortSide > maxDim ? maxDim : shortSide + + let renderer = UIGraphicsImageRenderer( + size: CGSize(width: finalSize, height: finalSize) + ) + let resized = renderer.image { _ in + cropped.draw( + in: CGRect( + origin: .zero, + size: CGSize(width: finalSize, height: finalSize) + ) + ) + } + + return resized.jpegData(compressionQuality: 0.8) + } +} + +// MARK: - Preview + +#Preview("Empty") { + NavigationStack { + HomeView(selectedTab: .constant(.derive)) + } + .previewDataContainer { ctx in + Player.instance(with: ctx).onboardingCompletedAt = Date() + } +} + +#Preview("Active") { + NavigationStack { + HomeView(selectedTab: .constant(.derive)) + } + .previewDataContainer { ctx in + let player = Player.instance(with: ctx) + player.onboardingCompletedAt = Date() + ctx.insert(Derive(challengeId: "yellow", player: player)) + } +} diff --git a/apps/derive/Derive/Routes/Onboarding/OnboardingView.swift b/apps/derive/Derive/Routes/Onboarding/OnboardingView.swift new file mode 100644 index 0000000..68a08e9 --- /dev/null +++ b/apps/derive/Derive/Routes/Onboarding/OnboardingView.swift @@ -0,0 +1,21 @@ +// +// OnboardingView.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import SwiftUI + +struct OnboardingView: View { + var body: some View { + NavigationStack { + OnboardingWelcomeView() + } + } +} + +#Preview { + OnboardingView() + .previewDataContainer() +} diff --git a/apps/derive/Derive/Routes/Onboarding/Views/OnboardingHowItWorksView.swift b/apps/derive/Derive/Routes/Onboarding/Views/OnboardingHowItWorksView.swift new file mode 100644 index 0000000..ee80414 --- /dev/null +++ b/apps/derive/Derive/Routes/Onboarding/Views/OnboardingHowItWorksView.swift @@ -0,0 +1,81 @@ +// +// OnboardingHowItWorksView.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import SwiftUI + +struct OnboardingHowItWorksView: View { + var body: some View { + VStack(alignment: .leading, spacing: 0) { + // Title + Text("How it works") + .font(.erode(36, weight: .bold)) + + Spacer().frame(height: 8) + + // Subtitle + Text("Three simple steps") + .font(.body) + .foregroundStyle(.secondary) + + Spacer().frame(height: 40) + + // Content + VStack(spacing: 24) { + stepRow(number: 1, title: "Pick a color", description: "Choose from yellow, red, blue, and more") + stepRow(number: 2, title: "Notice 9 things", description: "Look around and capture what you notice") + stepRow(number: 3, title: "Complete your grid", description: "Save or share your finished dérive") + } + + Spacer() + + // CTA + NavigationLink { + OnboardingPickChallengeView() + } label: { + Text("Choose a Color") + .font(.headline) + .frame(maxWidth: .infinity) + .padding(.vertical, 16) + .background(Color.appCta) + .foregroundStyle(Color.appCtaContent) + .clipShape(Capsule()) + } + } + .padding(.horizontal, 24) + .padding(.top, 60) + .padding(.bottom, 24) + .background(Color.appBackground) + .navigationBarHidden(true) + } + + private func stepRow(number: Int, title: String, description: String) -> some View { + HStack(alignment: .top, spacing: 16) { + Text("\(number)") + .font(.subheadline.weight(.semibold)) + .foregroundStyle(Color.appCtaContent) + .frame(width: 28, height: 28) + .background(Circle().fill(Color.appCta)) + + VStack(alignment: .leading, spacing: 4) { + Text(title) + .font(.subheadline.weight(.semibold)) + + Text(description) + .font(.subheadline) + .foregroundStyle(.secondary) + } + + Spacer() + } + } +} + +#Preview { + NavigationStack { + OnboardingHowItWorksView() + } +} diff --git a/apps/derive/Derive/Routes/Onboarding/Views/OnboardingPickChallengeView.swift b/apps/derive/Derive/Routes/Onboarding/Views/OnboardingPickChallengeView.swift new file mode 100644 index 0000000..cd2f193 --- /dev/null +++ b/apps/derive/Derive/Routes/Onboarding/Views/OnboardingPickChallengeView.swift @@ -0,0 +1,81 @@ +// +// OnboardingPickChallengeView.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import SwiftData +import SwiftUI + +struct OnboardingPickChallengeView: View { + @QuerySingleton private var player: Player + @Environment(\.modelContext) private var modelContext + + private let challenges = ChallengeRegistry.shared.all + + var body: some View { + VStack(alignment: .leading, spacing: 0) { + // Title + Text("Pick a color") + .font(.erode(36, weight: .bold)) + + Spacer().frame(height: 8) + + // Subtitle + Text("Start your first dérive") + .font(.body) + .foregroundStyle(.secondary) + + Spacer().frame(height: 32) + + // Content (color grid) + LazyVGrid( + columns: [ + GridItem(.flexible(), spacing: 12), + GridItem(.flexible(), spacing: 12), + GridItem(.flexible(), spacing: 12), + ], + spacing: 12 + ) { + ForEach(challenges) { challenge in + Button { + startDerive(challenge) + } label: { + VStack(spacing: 8) { + RoundedRectangle(cornerRadius: 12) + .fill(challenge.color) + .aspectRatio(1, contentMode: .fit) + + Text(challenge.title) + .font(.caption.weight(.medium)) + .foregroundStyle(.primary) + } + } + .buttonStyle(.plain) + } + } + + Spacer() + } + .padding(.horizontal, 24) + .padding(.top, 60) + .padding(.bottom, 24) + .background(Color.appBackground) + .navigationBarHidden(true) + } + + private func startDerive(_ challenge: Challenge) { + let derive = Derive(challengeId: challenge.id, player: player) + modelContext.insert(derive) + player.onboardingCompletedAt = Date() + try? modelContext.save() + } +} + +#Preview { + NavigationStack { + OnboardingPickChallengeView() + } + .previewDataContainer() +} diff --git a/apps/derive/Derive/Routes/Onboarding/Views/OnboardingWelcomeView.swift b/apps/derive/Derive/Routes/Onboarding/Views/OnboardingWelcomeView.swift new file mode 100644 index 0000000..1cf8ab1 --- /dev/null +++ b/apps/derive/Derive/Routes/Onboarding/Views/OnboardingWelcomeView.swift @@ -0,0 +1,52 @@ +// +// OnboardingWelcomeView.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import SwiftUI + +struct OnboardingWelcomeView: View { + var body: some View { + VStack(alignment: .leading, spacing: 0) { + Spacer().frame(height: 60) + + // Title + Text("Dérive") + .font(.erode(36, weight: .bold)) + + Spacer().frame(height: 8) + + // Subtitle + Text("A reason to look up from your phone") + .font(.body) + .foregroundStyle(.secondary) + + Spacer() + + // CTA + NavigationLink { + OnboardingHowItWorksView() + } label: { + Text("Get Started") + .font(.headline) + .frame(maxWidth: .infinity) + .padding(.vertical, 16) + .background(Color.appCta) + .foregroundStyle(Color.appCtaContent) + .clipShape(Capsule()) + } + } + .padding(.horizontal, 24) + .padding(.bottom, 24) + .background(Color.appBackground) + .navigationBarHidden(true) + } +} + +#Preview { + NavigationStack { + OnboardingWelcomeView() + } +} diff --git a/apps/derive/Derive/Routes/Settings/SettingsView.swift b/apps/derive/Derive/Routes/Settings/SettingsView.swift new file mode 100644 index 0000000..03977d5 --- /dev/null +++ b/apps/derive/Derive/Routes/Settings/SettingsView.swift @@ -0,0 +1,44 @@ +// +// SettingsView.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import SwiftUI + +struct SettingsView: View { + + // MARK: - UI + + var body: some View { + Form { + appSection + } + .scrollContentBackground(.hidden) + .background(Color.appBackground) + .navigationTitle("Settings") + } + + private var appSection: some View { + Section("APP") { + NavigationLink { + SettingsAboutView() + } label: { + Label("About", systemImage: "info.circle") + } + + NavigationLink { + SettingsCreditsView() + } label: { + Label("Credits", systemImage: "heart") + } + } + } +} + +#Preview { + NavigationStack { + SettingsView() + } +} diff --git a/apps/derive/Derive/Routes/SettingsAbout/AboutLogoView.swift b/apps/derive/Derive/Routes/SettingsAbout/AboutLogoView.swift new file mode 100644 index 0000000..b30da04 --- /dev/null +++ b/apps/derive/Derive/Routes/SettingsAbout/AboutLogoView.swift @@ -0,0 +1,22 @@ +// +// AboutLogoView.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import SwiftUI + +struct AboutLogoView: View { + var body: some View { + Image("logo") + .font(.system(size: 48)) + .foregroundStyle(.primary) + } +} + +#Preview { + AboutLogoView() + .padding() + .background(Color.appBackground) +} diff --git a/apps/derive/Derive/Routes/SettingsAbout/SettingsAboutView.swift b/apps/derive/Derive/Routes/SettingsAbout/SettingsAboutView.swift new file mode 100644 index 0000000..1c0f1fa --- /dev/null +++ b/apps/derive/Derive/Routes/SettingsAbout/SettingsAboutView.swift @@ -0,0 +1,278 @@ +// +// SettingsAboutView.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import SwiftUI + +struct SettingsAboutView: View { + private enum FeedbackSubject { + static let general = "Dérive Feedback" + static let feature = "Feature Request" + static let bug = "Bug Report" + } + + // MARK: - UI + + var body: some View { + ScrollView { + VStack(spacing: 24) { + headerSection + feedbackSection + linksSection + privacySection + versionSection + } + } + .background(Color.appBackground) + .navigationTitle("About") + .navigationBarTitleDisplayMode(.inline) + } + + private var headerSection: some View { + VStack(spacing: 16) { + AboutLogoView() + + VStack(spacing: 4) { + Text("A reason to look up from your phone") + .font(.subheadline) + .multilineTextAlignment(.center) + .foregroundStyle(.primary) + + Text("We'd love to hear your feedback!") + .font(.subheadline) + .multilineTextAlignment(.center) + .foregroundStyle(.secondary) + } + .padding(.horizontal) + } + .padding(.top, 8) + } + + private var feedbackSection: some View { + SectionContainerView { + ActionRowView( + icon: "envelope.fill", + iconColor: .blue, + title: "Feedback", + action: { openMail(subject: FeedbackSubject.general) } + ) + + SectionDivider() + + ActionRowView( + icon: "gift.fill", + iconColor: .pink, + title: "Request a Feature", + action: { openMail(subject: FeedbackSubject.feature) } + ) + + SectionDivider() + + ActionRowView( + icon: "ladybug.fill", + iconColor: .red, + title: "Report a Bug", + action: { openMail(subject: FeedbackSubject.bug) } + ) + } + } + + private var linksSection: some View { + SectionContainerView { + if let url = AppConfig.appStoreURL { + LinkRowView( + icon: "apple.logo", + iconColor: .primary, + title: "App Store", + url: url + ) + + SectionDivider() + } + + if let url = AppConfig.websiteURL { + LinkRowView( + icon: "safari.fill", + iconColor: .blue, + title: "Website", + url: url + ) + + SectionDivider() + } + + if let url = AppConfig.githubURL { + LinkRowView( + icon: "github", + iconColor: .primary, + title: "GitHub", + url: url, + isSystemIcon: false + ) + } + } + } + + @ViewBuilder + private var privacySection: some View { + if let privacyURL = AppConfig.privacyPolicyURL { + SectionContainerView { + LinkRowView( + icon: "hand.raised.fill", + iconColor: .blue, + title: "Privacy Policy", + url: privacyURL + ) + } + } + } + + private var versionSection: some View { + VStack(spacing: 4) { + Text("Version \(AppConfig.version) (\(AppConfig.build))") + .font(.caption) + .foregroundStyle(.secondary) + + Text("© 2025 builder.group") + .font(.caption2) + .foregroundStyle(.tertiary) + } + .padding(.top, 8) + .padding(.bottom, 24) + } + + // MARK: - Actions + + private func openMail(subject: String) { + guard let url = AppConfig.mailtoURL(subject: subject) else { return } + UIApplication.shared.open(url) + } +} + +// MARK: - Helper Views + +private struct SectionContainerView: View { + @ViewBuilder let content: Content + + var body: some View { + VStack(spacing: 0) { + content + } + .background( + RoundedRectangle(cornerRadius: 12, style: .continuous) + .fill(Color.appCard) + ) + .padding(.horizontal) + } +} + +private struct SectionDivider: View { + var body: some View { + Divider() + .padding(.leading, 56) + } +} + +private struct ActionRowView: View { + let icon: String + let iconColor: Color + let title: String + let action: () -> Void + var isSystemIcon: Bool = true + + var body: some View { + Button(action: action) { + HStack(spacing: 12) { + Group { + if isSystemIcon { + Image(systemName: icon) + .font(.title3) + .foregroundStyle(iconColor) + } else { + Image(icon) + .font(.title3) + .foregroundStyle(iconColor) + } + } + .frame(width: 32, height: 32) + + Text(title) + .font(.body) + .foregroundStyle(.primary) + + Spacer() + + Image(systemName: "chevron.right") + .font(.caption) + .foregroundStyle(.tertiary) + } + .padding(.horizontal, 16) + .padding(.vertical, 12) + .contentShape(Rectangle()) + } + .buttonStyle(.plain) + } +} + +private struct LinkRowView: View { + let icon: String + let iconColor: Color + let title: String + var subtitle: String? = nil + let url: URL + var isSystemIcon: Bool = true + + var body: some View { + Link(destination: url) { + HStack(spacing: 12) { + Group { + if isSystemIcon { + Image(systemName: icon) + .font(.title3) + .foregroundStyle(iconColor) + } else { + Image(icon) + .font(.title3) + .foregroundStyle(iconColor) + } + } + .frame(width: 32, height: 32) + + if let subtitle = subtitle { + VStack(alignment: .leading, spacing: 4) { + Text(title) + .font(.body) + .foregroundStyle(.primary) + + Text(subtitle) + .font(.subheadline) + .foregroundStyle(.secondary) + } + } else { + Text(title) + .font(.body) + .foregroundStyle(.primary) + } + + Spacer() + + Image(systemName: "arrow.up.forward") + .font(.caption) + .foregroundStyle(.tertiary) + } + .padding(.horizontal, 16) + .padding(.vertical, 12) + .contentShape(Rectangle()) + } + .buttonStyle(.plain) + } +} + +#Preview { + NavigationStack { + SettingsAboutView() + } +} diff --git a/apps/derive/Derive/Routes/SettingsCredits/SettingsCreditsView.swift b/apps/derive/Derive/Routes/SettingsCredits/SettingsCreditsView.swift new file mode 100644 index 0000000..f75c92a --- /dev/null +++ b/apps/derive/Derive/Routes/SettingsCredits/SettingsCreditsView.swift @@ -0,0 +1,139 @@ +// +// SettingsCreditsView.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import SwiftUI + +struct SettingsCreditsView: View { + var body: some View { + ScrollView { + VStack(spacing: 24) { + headerSection + creditsSection + } + } + .background(Color.appBackground) + .navigationTitle("Credits") + .navigationBarTitleDisplayMode(.inline) + } + + private var headerSection: some View { + VStack(spacing: 16) { + Image("logo") + .font(.system(size: 48)) + .foregroundStyle(.primary) + + VStack(spacing: 4) { + Text("Dérive is inspired by amazing people") + .font(.subheadline) + .multilineTextAlignment(.center) + .foregroundStyle(.primary) + + Text("We're grateful for their work") + .font(.subheadline) + .multilineTextAlignment(.center) + .foregroundStyle(.secondary) + } + .padding(.horizontal) + } + .padding(.top, 8) + } + + private var creditsSection: some View { + SectionContainerView { + if let debordURL = URL(string: "https://en.wikipedia.org/wiki/D%C3%A9rive") { + LinkRowView( + icon: "book.fill", + iconColor: .orange, + title: "Guy Debord", + subtitle: "Theory of the Dérive (1956)", + url: debordURL + ) + + SectionDivider() + } + + if let tweetURL = URL(string: "https://x.com/malisauskasLT/status/2008123520727867451") { + LinkRowView( + icon: "sparkles", + iconColor: .yellow, + title: "@malisauskasLT", + subtitle: "Color hunting inspiration", + url: tweetURL + ) + } + } + } +} + +// MARK: - Helper Views + +private struct SectionContainerView: View { + @ViewBuilder let content: Content + + var body: some View { + VStack(spacing: 0) { + content + } + .background( + RoundedRectangle(cornerRadius: 12, style: .continuous) + .fill(Color.appCard) + ) + .padding(.horizontal) + } +} + +private struct SectionDivider: View { + var body: some View { + Divider() + .padding(.leading, 56) + } +} + +private struct LinkRowView: View { + let icon: String + let iconColor: Color + let title: String + let subtitle: String + let url: URL + + var body: some View { + Link(destination: url) { + HStack(spacing: 12) { + Image(systemName: icon) + .font(.title3) + .foregroundStyle(iconColor) + .frame(width: 32, height: 32) + + VStack(alignment: .leading, spacing: 2) { + Text(title) + .font(.body) + .foregroundStyle(.primary) + + Text(subtitle) + .font(.caption) + .foregroundStyle(.secondary) + } + + Spacer() + + Image(systemName: "arrow.up.forward") + .font(.caption) + .foregroundStyle(.tertiary) + } + .padding(.horizontal, 16) + .padding(.vertical, 12) + .contentShape(Rectangle()) + } + .buttonStyle(.plain) + } +} + +#Preview { + NavigationStack { + SettingsCreditsView() + } +} diff --git a/apps/derive/Derive/Routes/Splash/SplashView.swift b/apps/derive/Derive/Routes/Splash/SplashView.swift new file mode 100644 index 0000000..0459a42 --- /dev/null +++ b/apps/derive/Derive/Routes/Splash/SplashView.swift @@ -0,0 +1,23 @@ +// +// SplashView.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import SwiftUI + +struct SplashView: View { + var body: some View { + Image("logo") + .resizable() + .scaledToFit() + .frame(width: 80, height: 80) + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background { Color.appBackground.ignoresSafeArea() } + } +} + +#Preview { + SplashView() +} diff --git a/apps/derive/Derive/Views/BannerView.swift b/apps/derive/Derive/Views/BannerView.swift new file mode 100644 index 0000000..d5b751b --- /dev/null +++ b/apps/derive/Derive/Views/BannerView.swift @@ -0,0 +1,97 @@ +// +// BannerView.swift +// Derive +// +// Created by Benno on 06.01.26. +// + +import SwiftUI + +struct BannerView: View { + let icon: String + let message: Text + let style: Style + + init(icon: String, message: String, style: Style) { + self.icon = icon + self.message = Text(message) + self.style = style + } + + init(icon: String, message: Text, style: Style) { + self.icon = icon + self.message = message + self.style = style + } + + enum Style { + case success + case warning + case info + case error + + var color: Color { + switch self { + case .success: return .green + case .warning: return .yellow + case .info: return .blue + case .error: return .red + } + } + } + + var body: some View { + HStack(alignment: .top, spacing: 10) { + Image(systemName: icon) + .font(.callout) + .foregroundStyle(style.color) + + message + .font(.footnote) + .foregroundStyle(.primary) + .fixedSize(horizontal: false, vertical: true) + + Spacer(minLength: 0) + } + .padding(.horizontal, 12) + .padding(.vertical, 10) + .background( + RoundedRectangle(cornerRadius: 8, style: .continuous) + .fill(style.color.opacity(0.12)) + ) + .overlay( + RoundedRectangle(cornerRadius: 8, style: .continuous) + .stroke(style.color.opacity(0.3), lineWidth: 1) + ) + } +} + +#Preview { + VStack(spacing: 12) { + BannerView( + icon: "checkmark.circle.fill", + message: "Operation completed successfully.", + style: .success + ) + + BannerView( + icon: "exclamationmark.triangle.fill", + message: "Complete your current dérive to start a new one.", + style: .warning + ) + + BannerView( + icon: "info.circle.fill", + message: "This is helpful information.", + style: .info + ) + + BannerView( + icon: "xmark.circle.fill", + message: "An error occurred.", + style: .error + ) + } + .padding() + .background(Color.appBackground) +} diff --git a/apps/derive/README.md b/apps/derive/README.md new file mode 100644 index 0000000..918ac12 --- /dev/null +++ b/apps/derive/README.md @@ -0,0 +1,22 @@ +# Dérive + +**Dérive** (French: [de.ʁiv], "drift") — a journey through a landscape where you drop your everyday routine and let curiosity guide you. The concept originates from Guy Debord's "Theory of the Dérive" (1956). + +Dérive is a native iOS app that gives you a reason to look up from your phone. City streets or forest trails. Your neighborhood or a new country. + +## Inspiration + +- [Berlin color hunt tweet](https://x.com/malisauskasLT/status/2008123520727867451) — organic interest in the concept + +## POC: Color Grid + +The first challenge to validate the Dérive concept — one prompt, nine photos, one grid. + +- **Pick a Color** — Yellow, red, blue, and more +- **Fill the Grid** — Capture or select photos for each cell +- **Save & Share** — Export completed grid as a single image +- **History** — View past completed grids + +## Vision + +If validated, Dérive expands into more exploration challenges — textures, shapes, sound walks, route randomizers, and beyond. diff --git a/apps/kairos/.gitignore b/apps/kairos/.gitignore new file mode 100644 index 0000000..f8c6c2e --- /dev/null +++ b/apps/kairos/.gitignore @@ -0,0 +1,43 @@ +# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files + +# dependencies +node_modules/ + +# Expo +.expo/ +dist/ +web-build/ +expo-env.d.ts + +# Native +.kotlin/ +*.orig.* +*.jks +*.p8 +*.p12 +*.key +*.mobileprovision + +# Metro +.metro-health-check* + +# debug +npm-debug.* +yarn-debug.* +yarn-error.* + +# macOS +.DS_Store +*.pem + +# local env files +.env*.local + +# typescript +*.tsbuildinfo + +app-example + +# generated native folders +/ios +/android diff --git a/apps/kairos/README.md b/apps/kairos/README.md new file mode 100644 index 0000000..90fdd5c --- /dev/null +++ b/apps/kairos/README.md @@ -0,0 +1 @@ +# `@repo/kairos` diff --git a/apps/kairos/app.json b/apps/kairos/app.json new file mode 100644 index 0000000..c58882f --- /dev/null +++ b/apps/kairos/app.json @@ -0,0 +1,41 @@ +{ + "expo": { + "name": "kairos", + "slug": "kairos", + "version": "0.0.1", + "orientation": "portrait", + "icon": "./assets/images/icon.png", + "scheme": "kairos", + "userInterfaceStyle": "automatic", + "ios": { + "icon": "./assets/ios-app-icon.icon", + "bundleIdentifier": "com.buildergroup.kairos", + "infoPlist": { + "ITSAppUsesNonExemptEncryption": false + } + }, + "plugins": [ + "expo-router", + [ + "expo-splash-screen", + { + "backgroundColor": "#4A92FF", + "android": { + "image": "./assets/images/splash-icon.png", + "imageWidth": 76 + } + } + ] + ], + "experiments": { + "typedRoutes": true, + "reactCompiler": true + }, + "extra": { + "router": {}, + "eas": { + "projectId": "2b00705a-3054-4eb0-8ada-c793d01adbc7" + } + } + } +} diff --git a/apps/kairos/assets/images/icon.png b/apps/kairos/assets/images/icon.png new file mode 100644 index 0000000..f8ef989 Binary files /dev/null and b/apps/kairos/assets/images/icon.png differ diff --git a/apps/kairos/assets/images/splash-icon.png b/apps/kairos/assets/images/splash-icon.png new file mode 100644 index 0000000..b081556 Binary files /dev/null and b/apps/kairos/assets/images/splash-icon.png differ diff --git a/apps/kairos/assets/ios-app-icon.icon/Assets/1-layer.svg b/apps/kairos/assets/ios-app-icon.icon/Assets/1-layer.svg new file mode 100644 index 0000000..8ad6b1d --- /dev/null +++ b/apps/kairos/assets/ios-app-icon.icon/Assets/1-layer.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/apps/kairos/assets/ios-app-icon.icon/Assets/grid.png b/apps/kairos/assets/ios-app-icon.icon/Assets/grid.png new file mode 100644 index 0000000..eefea24 Binary files /dev/null and b/apps/kairos/assets/ios-app-icon.icon/Assets/grid.png differ diff --git a/apps/kairos/assets/ios-app-icon.icon/icon.json b/apps/kairos/assets/ios-app-icon.icon/icon.json new file mode 100644 index 0000000..532ab08 --- /dev/null +++ b/apps/kairos/assets/ios-app-icon.icon/icon.json @@ -0,0 +1,41 @@ +{ + "fill" : { + "automatic-gradient" : "extended-srgb:0.00000,0.47843,1.00000,1.00000" + }, + "groups" : [ + { + "layers" : [ + { + "image-name" : "1-layer.svg", + "name" : "1-layer", + "position" : { + "scale" : 1, + "translation-in-points" : [ + 0, + 0 + ] + } + }, + { + "hidden" : false, + "image-name" : "grid.png", + "name" : "grid" + } + ], + "shadow" : { + "kind" : "neutral", + "opacity" : 0.5 + }, + "translucency" : { + "enabled" : true, + "value" : 0.5 + } + } + ], + "supported-platforms" : { + "circles" : [ + "watchOS" + ], + "squares" : "shared" + } +} \ No newline at end of file diff --git a/apps/kairos/eas.json b/apps/kairos/eas.json new file mode 100644 index 0000000..320c365 --- /dev/null +++ b/apps/kairos/eas.json @@ -0,0 +1,21 @@ +{ + "cli": { + "version": ">= 18.0.6", + "appVersionSource": "remote" + }, + "build": { + "development": { + "developmentClient": true, + "distribution": "internal" + }, + "preview": { + "distribution": "internal" + }, + "production": { + "autoIncrement": true + } + }, + "submit": { + "production": {} + } +} diff --git a/apps/kairos/eslint.config.js b/apps/kairos/eslint.config.js new file mode 100644 index 0000000..a72c17c --- /dev/null +++ b/apps/kairos/eslint.config.js @@ -0,0 +1,10 @@ +// https://docs.expo.dev/guides/using-eslint/ +const { defineConfig } = require('eslint/config'); +const expoConfig = require('eslint-config-expo/flat'); + +module.exports = defineConfig([ + expoConfig, + { + ignores: ['dist/*'] + } +]); diff --git a/apps/kairos/metro.config.js b/apps/kairos/metro.config.js new file mode 100644 index 0000000..9d83a19 --- /dev/null +++ b/apps/kairos/metro.config.js @@ -0,0 +1,8 @@ +// Learn more https://docs.expo.io/guides/customizing-metro +const { getDefaultConfig } = require('expo/metro-config'); +const { withNativewind } = require('nativewind/metro'); + +/** @type {import('expo/metro-config').MetroConfig} */ +const config = getDefaultConfig(__dirname); + +module.exports = withNativewind(config); diff --git a/apps/kairos/modules/audio/expo-module.config.json b/apps/kairos/modules/audio/expo-module.config.json new file mode 100644 index 0000000..464ad4b --- /dev/null +++ b/apps/kairos/modules/audio/expo-module.config.json @@ -0,0 +1,6 @@ +{ + "platforms": ["apple"], + "apple": { + "modules": ["AudioModule"] + } +} diff --git a/apps/kairos/modules/audio/index.ts b/apps/kairos/modules/audio/index.ts new file mode 100644 index 0000000..8420b10 --- /dev/null +++ b/apps/kairos/modules/audio/index.ts @@ -0,0 +1 @@ +export * from './src'; diff --git a/apps/kairos/modules/audio/ios/Audio.podspec b/apps/kairos/modules/audio/ios/Audio.podspec new file mode 100644 index 0000000..a53be5d --- /dev/null +++ b/apps/kairos/modules/audio/ios/Audio.podspec @@ -0,0 +1,22 @@ +Pod::Spec.new do |s| + s.name = 'Audio' + s.version = '1.0.0' + s.summary = 'Native iOS audio module for Expo/React Native.' + s.description = '' + s.homepage = 'https://docs.expo.dev/modules/' + s.platforms = { + :ios => '15.1', + :tvos => '15.1' + } + s.source = { git: '' } + s.static_framework = true + + s.dependency 'ExpoModulesCore' + + s.pod_target_xcconfig = { + 'DEFINES_MODULE' => 'YES', + } + + s.source_files = "**/*.{h,m,mm,swift,hpp,cpp}" + s.frameworks = 'AVFoundation' +end diff --git a/apps/kairos/modules/audio/ios/AudioModule.swift b/apps/kairos/modules/audio/ios/AudioModule.swift new file mode 100644 index 0000000..0eef218 --- /dev/null +++ b/apps/kairos/modules/audio/ios/AudioModule.swift @@ -0,0 +1,108 @@ +import AVFoundation +import ExpoModulesCore + +public class AudioModule: Module { + private var player: AVAudioPlayer? + + public func definition() -> ModuleDefinition { + Name("Audio") + + // .playback category so the alarm fires even when the device is silenced. + AsyncFunction("play") { (soundName: String) throws in + try self.configureSession() + guard let url = self.resolveURL(for: soundName) else { + throw AudioError.soundNotFound(soundName) + } + // Create and play on main thread; AVAudioPlayer is not thread-safe. + DispatchQueue.main.async { + self.player = try? AVAudioPlayer(contentsOf: url) + self.player?.numberOfLoops = -1 + self.player?.play() + } + } + + Function("stop") { + DispatchQueue.main.async { + self.player?.stop() + self.player = nil + } + } + + AsyncFunction("getSystemSounds") { () -> [String] in + return self.enumerateSystemSounds() + } + } + + // MARK: - Private + + private func configureSession() throws { + try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default) + try AVAudioSession.sharedInstance().setActive(true) + } + + private func resolveURL(for soundName: String) -> URL? { + let searchDirs = [ + "/Library/Ringtones", + "/System/Library/Audio/UISounds/Modern", + "/System/Library/Audio/UISounds", + "/System/Library/Audio/UISounds/New", + ] + let extensions = ["m4r", "caf", "aiff", "wav", "mp3"] + + for dir in searchDirs { + for ext in extensions { + for candidate in [soundName, soundName.prefix(1).uppercased() + soundName.dropFirst()] { + let path = "\(dir)/\(candidate).\(ext)" + if FileManager.default.fileExists(atPath: path) { + return URL(fileURLWithPath: path) + } + } + } + } + + // Fallback: app bundle (for bundled assets) + for ext in extensions { + if let url = Bundle.main.url(forResource: soundName, withExtension: ext) { + return url + } + } + + return nil + } + + // /Library/Ringtones has proper alarm-quality sounds (Radar, Apex, etc.); falls back to UISounds/Modern if inaccessible. + private func enumerateSystemSounds() -> [String] { + let validExtensions = Set(["m4r", "caf", "aiff", "wav", "mp3"]) + + func soundNames(in dir: String) -> [String] { + guard let files = try? FileManager.default.contentsOfDirectory(atPath: dir) else { + return [] + } + return files.compactMap { file -> String? in + let url = URL(fileURLWithPath: file) + guard validExtensions.contains(url.pathExtension.lowercased()) else { return nil } + return url.deletingPathExtension().lastPathComponent + }.sorted() + } + + let ringtones = soundNames(in: "/Library/Ringtones") + if !ringtones.isEmpty { + return ringtones + } + + return soundNames(in: "/System/Library/Audio/UISounds/Modern") + } +} + +// MARK: - Errors + +enum AudioError: LocalizedError { + case soundNotFound(String) + + var errorDescription: String? { + switch self { + case .soundNotFound(let name): + return "Sound '\(name)' not found in system paths or app bundle." + } + } +} diff --git a/apps/kairos/modules/audio/src/index.ts b/apps/kairos/modules/audio/src/index.ts new file mode 100644 index 0000000..0a16766 --- /dev/null +++ b/apps/kairos/modules/audio/src/index.ts @@ -0,0 +1,16 @@ +import { requireNativeModule } from 'expo-modules-core'; + +const AudioModule = requireNativeModule('Audio'); + +/** Play a sound by name. Searches system sound paths first, then the app bundle. */ +export async function play(soundName: string): Promise { + return AudioModule.play(soundName); +} + +export function stop(): void { + AudioModule.stop(); +} + +export async function getSystemSounds(): Promise { + return AudioModule.getSystemSounds(); +} diff --git a/apps/kairos/modules/duration-picker/expo-module.config.json b/apps/kairos/modules/duration-picker/expo-module.config.json new file mode 100644 index 0000000..f5cf4a1 --- /dev/null +++ b/apps/kairos/modules/duration-picker/expo-module.config.json @@ -0,0 +1,6 @@ +{ + "platforms": ["apple"], + "apple": { + "modules": ["DurationPickerModule"] + } +} diff --git a/apps/kairos/modules/duration-picker/index.ts b/apps/kairos/modules/duration-picker/index.ts new file mode 100644 index 0000000..8420b10 --- /dev/null +++ b/apps/kairos/modules/duration-picker/index.ts @@ -0,0 +1 @@ +export * from './src'; diff --git a/apps/kairos/modules/duration-picker/ios/DurationPicker.podspec b/apps/kairos/modules/duration-picker/ios/DurationPicker.podspec new file mode 100644 index 0000000..1a2980c --- /dev/null +++ b/apps/kairos/modules/duration-picker/ios/DurationPicker.podspec @@ -0,0 +1,22 @@ +Pod::Spec.new do |s| + s.name = 'DurationPicker' + s.version = '1.0.0' + s.summary = 'Native iOS duration picker view for Expo/React Native.' + s.description = '' + s.homepage = 'https://docs.expo.dev/modules/' + s.platforms = { + :ios => '15.1', + :tvos => '15.1' + } + s.source = { git: '' } + s.static_framework = true + + s.dependency 'ExpoModulesCore' + + # Swift/Objective-C compatibility + s.pod_target_xcconfig = { + 'DEFINES_MODULE' => 'YES', + } + + s.source_files = "**/*.{h,m,mm,swift,hpp,cpp}" +end diff --git a/apps/kairos/modules/duration-picker/ios/DurationPickerModule.swift b/apps/kairos/modules/duration-picker/ios/DurationPickerModule.swift new file mode 100644 index 0000000..9eec8dd --- /dev/null +++ b/apps/kairos/modules/duration-picker/ios/DurationPickerModule.swift @@ -0,0 +1,36 @@ +import ExpoModulesCore + +public class DurationPickerModule: Module { + public func definition() -> ModuleDefinition { + Name("DurationPicker") + + View(DurationPickerView.self) { + Events("onDurationChange") + + Prop("hours") { (view: DurationPickerView, value: Int) in + view.hours = value + } + + Prop("minutes") { (view: DurationPickerView, value: Int) in + view.minutes = value + } + + Prop("seconds") { (view: DurationPickerView, value: Int) in + view.seconds = value + } + + Prop("groupSpacing") { (view: DurationPickerView, value: Double) in + view.groupSpacing = value + } + + Prop("valueToUnitSpacing") { + (view: DurationPickerView, value: Double) in + view.valueToUnitSpacing = value + } + + Prop("colorScheme") { (view: DurationPickerView, value: String) in + view.colorScheme = value + } + } + } +} diff --git a/apps/kairos/modules/duration-picker/ios/DurationPickerView.swift b/apps/kairos/modules/duration-picker/ios/DurationPickerView.swift new file mode 100644 index 0000000..4dd6bec --- /dev/null +++ b/apps/kairos/modules/duration-picker/ios/DurationPickerView.swift @@ -0,0 +1,97 @@ +import ExpoModulesCore +import UIKit + +final class DurationPickerView: ExpoView { + + let onDurationChange = EventDispatcher() + + private let haptics = UISelectionFeedbackGenerator() + private let picker: DurationWheelView + private var h = 0, m = 0, s = 0 + + required init(appContext: AppContext? = nil) { + picker = DurationWheelView(units: [ + NSLocalizedString( + "duration_picker_unit_hours", + value: "hours", + comment: "Duration picker hours unit" + ), + NSLocalizedString( + "duration_picker_unit_min", + value: "min", + comment: "Duration picker minutes unit" + ), + NSLocalizedString( + "duration_picker_unit_sec", + value: "sec", + comment: "Duration picker seconds unit" + ), + ]) + super.init(appContext: appContext) + + picker.onChange = { [weak self] h, m, s in + guard let self else { return } + self.h = h + self.m = m + self.s = s + haptics.selectionChanged() + haptics.prepare() + onDurationChange(["hours": h, "minutes": m, "seconds": s]) + } + + picker.translatesAutoresizingMaskIntoConstraints = false + addSubview(picker) + NSLayoutConstraint.activate([ + picker.topAnchor.constraint(equalTo: topAnchor), + picker.bottomAnchor.constraint(equalTo: bottomAnchor), + picker.leadingAnchor.constraint(equalTo: leadingAnchor), + picker.trailingAnchor.constraint(equalTo: trailingAnchor), + ]) + haptics.prepare() + } + + var hours: Int { + get { h } + set { + h = newValue + picker.setSelection(hours: h, minutes: m, seconds: s) + } + } + + var minutes: Int { + get { m } + set { + m = newValue + picker.setSelection(hours: h, minutes: m, seconds: s) + } + } + + var seconds: Int { + get { s } + set { + s = newValue + picker.setSelection(hours: h, minutes: m, seconds: s) + } + } + + var groupSpacing: Double { + get { Double(picker.groupSpacing) } + set { picker.groupSpacing = CGFloat(max(0, min(newValue, 20))) } + } + + var valueToUnitSpacing: Double { + get { Double(picker.valueToUnitSpacing) } + set { picker.valueToUnitSpacing = CGFloat(max(0, min(newValue, 20))) } + } + + var colorScheme: String { + get { "" } + set { + switch newValue { + case "dark": overrideUserInterfaceStyle = .dark + case "light": overrideUserInterfaceStyle = .light + default: overrideUserInterfaceStyle = .unspecified + } + } + } +} diff --git a/apps/kairos/modules/duration-picker/ios/DurationWheelView.swift b/apps/kairos/modules/duration-picker/ios/DurationWheelView.swift new file mode 100644 index 0000000..8ff1262 --- /dev/null +++ b/apps/kairos/modules/duration-picker/ios/DurationWheelView.swift @@ -0,0 +1,280 @@ +import SwiftUI +import UIKit + +// Note: We use a custom UIPickerView implementation here +// because UIPickerView renders one continuous selection indicator across all columns, +// matching the iOS Timer app. +// SwiftUI's Picker(.wheel) draws one per column and can't be styled to span them all. + +final class DurationWheelView: UIView, UIPickerViewDataSource, + UIPickerViewDelegate +{ + + private static let maxValues: [Int] = [23, 59, 59] + private static let valueFont = UIFont.monospacedDigitSystemFont( + ofSize: 23.5, + weight: .regular + ) + private static let unitFont = UIFont.systemFont( + ofSize: 17, + weight: .semibold + ) + private static let rowHeight: CGFloat = 32 + // UIPickerView adds ~5pt between columns; value is empirically determined. + private static let columnGap: CGFloat = 5 + + var onChange: ((Int, Int, Int) -> Void)? + + // groupSpacing is mutable so ExpoView can update it via React Native props. + var groupSpacing: CGFloat { + didSet { + guard oldValue != groupSpacing else { return } + picker.reloadAllComponents() + setNeedsLayout() + } + } + + // valueToUnitSpacing is mutable so ExpoView can update it via React Native props. + var valueToUnitSpacing: CGFloat { + didSet { + guard oldValue != valueToUnitSpacing else { return } + picker.reloadAllComponents() + setNeedsLayout() + } + } + + private let picker = UIPickerView() + private let units: [String] + private let unitLabels: [UILabel] + private let numberWidth: CGFloat + private let maxUnitWidth: CGFloat + private var selection = [0, 0, 0] + private var isProgrammaticSelect = false + + // columnWidth is computed so it picks up spacing changes automatically. + private var columnWidth: CGFloat { + floor(numberWidth + valueToUnitSpacing + maxUnitWidth + groupSpacing) + } + + init( + groupSpacing: CGFloat = 12, + valueToUnitSpacing: CGFloat = 4, + units: [String] = ["hours", "min", "sec"], + onChange: ((Int, Int, Int) -> Void)? = nil + ) { + self.groupSpacing = groupSpacing + self.valueToUnitSpacing = valueToUnitSpacing + self.onChange = onChange + self.units = units + + let numW = ceil( + ("00" as NSString).size(withAttributes: [.font: Self.valueFont]) + .width + ) + let unitW = ceil( + units.map { + ($0 as NSString).size(withAttributes: [.font: Self.unitFont]) + .width + }.max() ?? 0 + ) + self.numberWidth = numW + self.maxUnitWidth = unitW + + self.unitLabels = units.map { + let label = UILabel() + label.text = $0 + label.font = Self.unitFont + label.textColor = .label + // Row views carry the accessibility info; unit labels are visual only. + label.isAccessibilityElement = false + label.sizeToFit() + return label + } + + super.init(frame: .zero) + + picker.translatesAutoresizingMaskIntoConstraints = false + picker.dataSource = self + picker.delegate = self + addSubview(picker) + unitLabels.forEach { addSubview($0) } + NSLayoutConstraint.activate([ + picker.topAnchor.constraint(equalTo: topAnchor), + picker.bottomAnchor.constraint(equalTo: bottomAnchor), + picker.leadingAnchor.constraint(equalTo: leadingAnchor), + picker.trailingAnchor.constraint(equalTo: trailingAnchor), + ]) + } + + required init?(coder: NSCoder) { fatalError("init(coder:) not supported") } + + override func layoutSubviews() { + super.layoutSubviews() + let startX = (bounds.width - 3 * columnWidth - 2 * Self.columnGap) / 2 + let midY = bounds.midY + for (i, label) in unitLabels.enumerated() { + let colX = startX + CGFloat(i) * (columnWidth + Self.columnGap) + let unitX = + colX + groupSpacing / 2 + numberWidth + valueToUnitSpacing + label.frame.origin = CGPoint( + x: (unitX * UIScreen.main.scale).rounded(.up) + / UIScreen.main.scale, + y: midY - label.frame.height / 2 + ) + } + } + + func setSelection(hours: Int, minutes: Int, seconds: Int) { + for (i, v) in [hours, minutes, seconds].enumerated() { + let clamped = max(0, min(v, Self.maxValues[i])) + guard clamped != selection[i] else { continue } + selection[i] = clamped + if picker.selectedRow(inComponent: i) != clamped { + isProgrammaticSelect = true + picker.selectRow(clamped, inComponent: i, animated: false) + isProgrammaticSelect = false + } + } + } + + // MARK: UIPickerViewDataSource + + func numberOfComponents(in pickerView: UIPickerView) -> Int { 3 } + + func pickerView( + _ pickerView: UIPickerView, + numberOfRowsInComponent component: Int + ) -> Int { + Self.maxValues[component] + 1 + } + + // MARK: UIPickerViewDelegate + + func pickerView( + _ pickerView: UIPickerView, + widthForComponent component: Int + ) -> CGFloat { columnWidth } + func pickerView( + _ pickerView: UIPickerView, + rowHeightForComponent component: Int + ) -> CGFloat { Self.rowHeight } + + func pickerView( + _ pickerView: UIPickerView, + viewForRow row: Int, + forComponent component: Int, + reusing view: UIView? + ) -> UIView { + // Full-width RowView so UIPickerView doesn't center the number label, + // keeping it aligned with the static unit label overlay. + let rowView = (view as? RowView) ?? RowView(font: Self.valueFont) + rowView.frame = CGRect( + x: 0, + y: 0, + width: columnWidth, + height: Self.rowHeight + ) + rowView.label.frame = CGRect( + x: groupSpacing / 2, + y: 0, + width: numberWidth, + height: Self.rowHeight + ) + rowView.label.text = String(row) + rowView.accessibilityLabel = "\(row) \(units[component])" + return rowView + } + + func pickerView( + _ pickerView: UIPickerView, + didSelectRow row: Int, + inComponent component: Int + ) { + guard !isProgrammaticSelect else { return } + selection[component] = row + onChange?(selection[0], selection[1], selection[2]) + } +} + +private final class RowView: UIView { + let label = UILabel() + init(font: UIFont) { + super.init(frame: .zero) + label.font = font + label.textColor = .label + label.textAlignment = .right + addSubview(label) + } + required init?(coder: NSCoder) { fatalError() } +} + +// MARK: - SwiftUI Wrapper +// +// Xcode Preview doesn't seem to work with ExpoView, +// so UI changes are developed here first using the #Preview below. +// DurationPickerView (the React Native module) wraps DurationWheelView from this file. + +struct DurationPickerSwiftUI: UIViewRepresentable { + @Binding var hours: Int + @Binding var minutes: Int + @Binding var seconds: Int + /// Spacing between the three [value unit] groups. + var groupSpacing: CGFloat = 12 + /// Spacing between the number and unit label within each group. + var valueToUnitSpacing: CGFloat = 4 + + func makeCoordinator() -> Coordinator { Coordinator(parent: self) } + + // Spacing is passed at creation and baked into the UIKit view's layout. + // updateUIView only syncs the selected values, not the spacing. + func makeUIView(context: Context) -> DurationWheelView { + DurationWheelView( + groupSpacing: groupSpacing, + valueToUnitSpacing: valueToUnitSpacing, + onChange: { [weak c = context.coordinator] h, m, s in + c?.update(h, m, s) + } + ) + } + + func updateUIView(_ uiView: DurationWheelView, context: Context) { + uiView.setSelection(hours: hours, minutes: minutes, seconds: seconds) + } + + final class Coordinator { + var parent: DurationPickerSwiftUI + init(parent: DurationPickerSwiftUI) { self.parent = parent } + func update(_ h: Int, _ m: Int, _ s: Int) { + parent.hours = h + parent.minutes = m + parent.seconds = s + } + } +} + +// MARK: - Preview + +private struct DurationPickerPreviewHost: View { + @State private var hours = 0 + @State private var minutes = 6 + @State private var seconds = 0 + + var body: some View { + VStack(spacing: 20) { + DurationPickerSwiftUI( + hours: $hours, + minutes: $minutes, + seconds: $seconds + ) + .frame(height: 220) + Text("\(hours)h \(minutes)m \(seconds)s") + .font(.headline.monospacedDigit()) + } + .padding() + .preferredColorScheme(.dark) + } +} + +#Preview("Duration Picker") { + DurationPickerPreviewHost() +} diff --git a/apps/kairos/modules/duration-picker/src/DurationPickerView.tsx b/apps/kairos/modules/duration-picker/src/DurationPickerView.tsx new file mode 100644 index 0000000..bd1f676 --- /dev/null +++ b/apps/kairos/modules/duration-picker/src/DurationPickerView.tsx @@ -0,0 +1,31 @@ +import { requireNativeViewManager } from 'expo-modules-core'; +import React from 'react'; +import { useColorScheme, type ViewProps } from 'react-native'; + +export const DurationPickerView: React.FC = (props) => { + const colorScheme = useColorScheme(); + return ; +}; + +export interface TDurationPickerViewProps extends ViewProps { + hours: number; + minutes: number; + seconds: number; + // Extra spacing between hour/min/sec groups, valid range 0...20 on iOS. + groupSpacing?: number; + // Spacing between the number and its unit label, valid range 0...20 on iOS. + valueToUnitSpacing?: number; + onDurationChange?: (event: { nativeEvent: TDurationPickerChangeEvent }) => void; +} + +export interface TDurationPickerChangeEvent { + hours: number; + minutes: number; + seconds: number; +} + +const NativeDurationPickerView = requireNativeViewManager('DurationPicker'); + +interface TNativeProps extends TDurationPickerViewProps { + colorScheme: string; +} diff --git a/apps/kairos/modules/duration-picker/src/index.ts b/apps/kairos/modules/duration-picker/src/index.ts new file mode 100644 index 0000000..31d68e9 --- /dev/null +++ b/apps/kairos/modules/duration-picker/src/index.ts @@ -0,0 +1 @@ +export * from './DurationPickerView'; diff --git a/apps/kairos/nativewind-env.d.ts b/apps/kairos/nativewind-env.d.ts new file mode 100644 index 0000000..82aac40 --- /dev/null +++ b/apps/kairos/nativewind-env.d.ts @@ -0,0 +1,3 @@ +/// + +// NOTE: This file should not be edited and should be committed with your source code. It is generated by react-native-css. If you need to move or disable this file, please see the documentation. diff --git a/apps/kairos/package.json b/apps/kairos/package.json new file mode 100644 index 0000000..e2d70e1 --- /dev/null +++ b/apps/kairos/package.json @@ -0,0 +1,78 @@ +{ + "name": "@repo/kairos", + "version": "0.0.1", + "private": true, + "description": "", + "keywords": [], + "bugs": { + "url": "https://github.com/builder-group/lab/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/builder-group/lab.git" + }, + "license": "AGPL-3.0-or-later", + "author": "@bennobuilder", + "main": "expo-router/entry", + "scripts": { + "clean": "shx rm -rf build && shx rm -rf .expo && shx rm -rf .turbo && shx rm -rf node_modules", + "format": "prettier --write \"**/*.{ts,tsx,md,json,js,jsx}\"", + "install:clean": "pnpm run clean && pnpm install", + "ios:build": "eas build --platform ios --profile production", + "ios:submit": "eas submit --platform ios --latest", + "lint": "expo lint", + "start:dev": "expo start --dev-client --lan", + "start:dev:ios": "expo start --dev-client --ios --lan", + "start:dev:ios:rebuild": "expo run:ios --device", + "test": "echo \"🧪 No tests defined yet.\"", + "typecheck": "tsc --noEmit", + "update:latest": "echo \"⚠️ Avoid updating to latest in React Native projects. Expo, React, React Native and other related packages depend strongly on each other and must be upgraded in sync.\"" + }, + "dependencies": { + "@expo/ui": "55.0.1", + "@expo/vector-icons": "^15.0.2", + "@react-native-async-storage/async-storage": "^3.0.1", + "@react-navigation/bottom-tabs": "^7.7.3", + "@react-navigation/elements": "^2.8.1", + "@react-navigation/native": "^7.1.28", + "clsx": "^2.1.1", + "expo": "~55.0.3", + "expo-constants": "~55.0.7", + "expo-dev-client": "~55.0.10", + "expo-device": "~55.0.9", + "expo-font": "~55.0.4", + "expo-glass-effect": "~55.0.7", + "expo-haptics": "~15.0.8", + "expo-image": "~55.0.5", + "expo-linking": "~55.0.7", + "expo-router": "~55.0.3", + "expo-splash-screen": "~55.0.10", + "expo-status-bar": "~55.0.4", + "expo-symbols": "~55.0.4", + "expo-system-ui": "~55.0.9", + "expo-web-browser": "~55.0.9", + "feature-react": "^0.0.67", + "feature-state": "^0.0.65", + "nativewind": "5.0.0-preview.2", + "react": "19.2.0", + "react-dom": "19.2.0", + "react-native": "0.83.2", + "react-native-css": "^3.0.4", + "react-native-gesture-handler": "~2.30.0", + "react-native-reanimated": "4.2.1", + "react-native-safe-area-context": "~5.6.2", + "react-native-screens": "~4.23.0", + "react-native-svg": "15.15.3", + "react-native-web": "~0.21.0", + "react-native-worklets": "0.7.2", + "tailwind-merge": "^3.5.0" + }, + "devDependencies": { + "@tailwindcss/postcss": "^4.2.1", + "@types/react": "~19.2.2", + "eas-cli": "^18.0.6", + "eslint-config-expo": "~55.0.0", + "postcss": "^8.5.6", + "tailwindcss": "^4.2.1" + } +} diff --git a/apps/kairos/postcss.config.mjs b/apps/kairos/postcss.config.mjs new file mode 100644 index 0000000..85b958c --- /dev/null +++ b/apps/kairos/postcss.config.mjs @@ -0,0 +1,5 @@ +export default { + plugins: { + '@tailwindcss/postcss': {} + } +}; diff --git a/apps/kairos/project-spec.md b/apps/kairos/project-spec.md index cb5f26d..7cf9258 100644 --- a/apps/kairos/project-spec.md +++ b/apps/kairos/project-spec.md @@ -97,4 +97,4 @@ The `targets/widget/` folder contains the Swift Live Activity view. `expo-apple- - 4 built-in presets (Plank, Study, Zen, Hot Potato) - Live Activity: Lock Screen + Dynamic Island compact -**Not in V1:** Loop mode + break period, user-saveable presets, expanded Dynamic Island, custom alarm sounds. \ No newline at end of file +**Not in V1:** Loop mode + break period, user-saveable presets, expanded Dynamic Island, custom alarm sounds. diff --git a/apps/kairos/src/app/_layout.tsx b/apps/kairos/src/app/_layout.tsx new file mode 100644 index 0000000..af23687 --- /dev/null +++ b/apps/kairos/src/app/_layout.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { AppTabs, ThemeProvider } from '@/components'; +import { AudioCxProvider } from '@/features/audio'; +import { SettingsCxProvider } from '@/features/settings'; +import { TimerCxProvider } from '@/features/timer'; +import '../global.css'; + +const Layout: React.FC = () => { + return ( + + + + + + + + + + ); +}; + +export default Layout; diff --git a/apps/kairos/src/app/index.tsx b/apps/kairos/src/app/index.tsx new file mode 100644 index 0000000..b55c997 --- /dev/null +++ b/apps/kairos/src/app/index.tsx @@ -0,0 +1,7 @@ +import { Redirect } from 'expo-router'; + +const Screen: React.FC = () => { + return ; +}; + +export default Screen; diff --git a/apps/kairos/src/app/settings/_layout.tsx b/apps/kairos/src/app/settings/_layout.tsx new file mode 100644 index 0000000..825aae4 --- /dev/null +++ b/apps/kairos/src/app/settings/_layout.tsx @@ -0,0 +1,32 @@ +import { Stack } from 'expo-router'; +import React from 'react'; +import { useTheme } from '@/components'; + +const Layout: React.FC = () => { + const { tokens } = useTheme(); + + return ( + + + + + ); +}; + +export default Layout; diff --git a/apps/kairos/src/app/settings/about/index.ios.tsx b/apps/kairos/src/app/settings/about/index.ios.tsx new file mode 100644 index 0000000..5e37538 --- /dev/null +++ b/apps/kairos/src/app/settings/about/index.ios.tsx @@ -0,0 +1,216 @@ +import { Button, Form, Host, HStack, Image, Section, Spacer, Text } from '@expo/ui/swift-ui'; +import { + background, + buttonStyle, + clipShape, + contentShape, + foregroundStyle, + frame, + shapes +} from '@expo/ui/swift-ui/modifiers'; +import { Image as ExpoImage } from 'expo-image'; +import React from 'react'; +import { Linking, Text as RNText, ScrollView, View } from 'react-native'; +import { useTheme } from '@/components'; +import { appConfig } from '@/environment'; + +const FeedbackSubject = { + general: 'Feedback', + feature: 'Feature Request', + bug: 'Bug Report' +} as const; + +const Screen: React.FC = () => { + const { tokens } = useTheme(); + + // MARK: - Actions + + const openExternal = React.useCallback((url: string): void => { + void Linking.openURL(url); + }, []); + + const handleFeedbackPress = React.useCallback((): void => { + openExternal(appConfig.support.mailto(FeedbackSubject.general)); + }, [openExternal]); + + const handleFeaturePress = React.useCallback((): void => { + openExternal(appConfig.support.mailto(FeedbackSubject.feature)); + }, [openExternal]); + + const handleBugPress = React.useCallback((): void => { + openExternal(appConfig.support.mailto(FeedbackSubject.bug)); + }, [openExternal]); + + const handleWebsitePress = React.useCallback((): void => { + openExternal(appConfig.links.website); + }, [openExternal]); + + const handleGithubPress = React.useCallback((): void => { + openExternal(appConfig.links.github); + }, [openExternal]); + + const handlePrivacyPress = React.useCallback((): void => { + openExternal(appConfig.links.privacyPolicy); + }, [openExternal]); + + // MARK: - UI + + return ( + + + + + {appConfig.name} + + Random Interval Timer + + We'd love to hear your feedback! + + + + +
+
+ + + + + +
+ +
+ + + +
+ +
+ +
+
+
+ + + Version {appConfig.version} + © 2025 builder.group + +
+ ); +}; + +export default Screen; diff --git a/apps/kairos/src/app/settings/about/index.tsx b/apps/kairos/src/app/settings/about/index.tsx new file mode 100644 index 0000000..36c3506 --- /dev/null +++ b/apps/kairos/src/app/settings/about/index.tsx @@ -0,0 +1,77 @@ +import React from 'react'; +import { Linking, Pressable, ScrollView, Text, View } from 'react-native'; +import { appConfig } from '@/environment'; + +function openMail(subject: string): void { + Linking.openURL(appConfig.support.mailto(subject)).catch(() => undefined); +} + +function openURL(url: string): void { + Linking.openURL(url).catch(() => undefined); +} + +const Screen: React.FC = () => { + const appStoreURL = appConfig.links.appStore; + + return ( + + + {appConfig.name} + + A reason to look up from your phone + + + +
+ openMail('Feedback')} /> + openMail('Feature Request')} /> + openMail('Bug Report')} /> +
+ +
+ {appStoreURL != null ? ( + openURL(appStoreURL)} /> + ) : null} + openURL(appConfig.links.website)} /> + openURL(appConfig.links.github)} /> + openURL(appConfig.links.privacyPolicy)} /> +
+ + + + Version {appConfig.version} + + © 2025 builder.group + +
+ ); +}; + +const Section: React.FC<{ title: string; children: React.ReactNode }> = ({ title, children }) => { + return ( + + + {title} + + {children} + + ); +}; + +const Row: React.FC<{ label: string; onPress: () => void }> = ({ label, onPress }) => { + return ( + + {label} + + + ); +}; + +export default Screen; diff --git a/apps/kairos/src/app/settings/index.ios.tsx b/apps/kairos/src/app/settings/index.ios.tsx new file mode 100644 index 0000000..b1bb784 --- /dev/null +++ b/apps/kairos/src/app/settings/index.ios.tsx @@ -0,0 +1,169 @@ +import { + Button, + Form, + Host, + HStack, + Image, + Picker, + Section, + Spacer, + Text +} from '@expo/ui/swift-ui'; +import { + background, + buttonStyle, + clipShape, + contentShape, + foregroundStyle, + frame, + pickerStyle, + shapes, + tag, + tint +} from '@expo/ui/swift-ui/modifiers'; +import { useRouter } from 'expo-router'; +import { useCompute } from 'feature-react/state'; +import React from 'react'; +import { Alert } from 'react-native'; +import { useTheme } from '@/components'; +import { useSettingsCx, type TThemePreference } from '@/features/settings'; +import { useTimerCx } from '@/features/timer'; + +const Screen: React.FC = () => { + const { tokens } = useTheme(); + const router = useRouter(); + const settingsCx = useSettingsCx(); + const timerCx = useTimerCx(); + const themePreference = useCompute(settingsCx.$settings, ({ value }) => value.appearance.theme); + + // MARK: - Actions + + const handleClearRecents = (): void => { + Alert.alert('Clear Recents', 'Remove all recent timer configurations?', [ + { text: 'Cancel', style: 'cancel' }, + { text: 'Clear', style: 'destructive', onPress: () => timerCx.clearRecents() } + ]); + }; + + const handleResetApp = (): void => { + Alert.alert( + 'Reset App', + 'This will reset all timer settings, recents, and preferences to their defaults.', + [ + { text: 'Cancel', style: 'cancel' }, + { + text: 'Reset', + style: 'destructive', + onPress: () => { + timerCx.reset(); + settingsCx.reset(); + } + } + ] + ); + }; + + // MARK: - UI + + return ( + +
+
+ +
+ +
+ + + + Theme + + + + settingsCx.update({ appearance: { theme: value as TThemePreference } }) + } + modifiers={[pickerStyle('menu'), frame({ height: 22 }), tint(tokens.base500)]} + > + System + Light + Dark + + +
+ +
+ + + +
+
+
+ ); +}; + +export default Screen; diff --git a/apps/kairos/src/app/settings/index.tsx b/apps/kairos/src/app/settings/index.tsx new file mode 100644 index 0000000..32a97db --- /dev/null +++ b/apps/kairos/src/app/settings/index.tsx @@ -0,0 +1,105 @@ +import { useRouter } from 'expo-router'; +import { useCompute } from 'feature-react/state'; +import React from 'react'; +import { Alert, Pressable, ScrollView, Text, View } from 'react-native'; +import { ThemeSelector } from '@/components'; +import { useSettingsCx } from '@/features/settings'; +import { useTimerCx } from '@/features/timer'; + +const Screen: React.FC = () => { + const router = useRouter(); + const settingsCx = useSettingsCx(); + const timerCx = useTimerCx(); + const themePreference = useCompute(settingsCx.$settings, ({ value }) => value.appearance.theme); + + const handleClearRecents = (): void => { + Alert.alert('Clear Recents', 'Remove all recent timer configurations?', [ + { text: 'Cancel', style: 'cancel' }, + { + text: 'Clear', + style: 'destructive', + onPress: () => timerCx.clearRecents() + } + ]); + }; + + const handleResetApp = (): void => { + Alert.alert( + 'Reset App', + 'This will reset all timer settings, recents, and preferences to their defaults.', + [ + { text: 'Cancel', style: 'cancel' }, + { + text: 'Reset', + style: 'destructive', + onPress: () => { + timerCx.reset(); + settingsCx.reset(); + } + } + ] + ); + }; + + return ( + +
+ router.push('/settings/about')} /> +
+ +
+ + + Theme: {themePreference} + + + +
+ +
+ + +
+
+ ); +}; + +const Section: React.FC<{ title: string; children: React.ReactNode }> = ({ title, children }) => { + return ( + + + {title} + + {children} + + ); +}; + +const Row: React.FC<{ + label: string; + onPress: () => void; + destructive?: boolean; + warning?: boolean; +}> = ({ label, onPress, destructive = false, warning = false }) => { + const tone = destructive + ? 'text-danger' + : warning + ? 'text-warning' + : 'text-base-900 dark:text-base-50'; + + return ( + + {label} + + + ); +}; + +export default Screen; diff --git a/apps/kairos/src/app/timer/_layout.tsx b/apps/kairos/src/app/timer/_layout.tsx new file mode 100644 index 0000000..1428f83 --- /dev/null +++ b/apps/kairos/src/app/timer/_layout.tsx @@ -0,0 +1,51 @@ +import { Stack } from 'expo-router'; +import { useCombinedCompute } from 'feature-react/state'; +import React from 'react'; +import { useTheme } from '@/components'; +import { formatDurationRange, useTimerCx } from '@/features/timer'; + +const Layout: React.FC = () => { + const { tokens } = useTheme(); + const cx = useTimerCx(); + + const { title, headerLargeTitle } = useCombinedCompute( + [cx.$status, cx.$config], + ([statusCx, configCx]) => { + const status = statusCx?.value ?? 'idle'; + const config = configCx?.value; + + // Keep large title only while idle. Switching to inline title when active causes a small native jump, + // but this is the most reliable cross-version behavior without brittle scroll/header animation hacks + if (status === 'idle') { + return { title: 'Timers', headerLargeTitle: true }; + } + + return { + title: config != null ? formatDurationRange(config.min, config.max) : 'Timer', + headerLargeTitle: false + }; + }, + [], + { + isEqual: (a, b) => a.title === b.title && a.headerLargeTitle === b.headerLargeTitle + } + ); + + // MARK: - UI + + return ( + + + + ); +}; + +export default Layout; diff --git a/apps/kairos/src/app/timer/index.tsx b/apps/kairos/src/app/timer/index.tsx new file mode 100644 index 0000000..3208f8c --- /dev/null +++ b/apps/kairos/src/app/timer/index.tsx @@ -0,0 +1,37 @@ +import { useCompute } from 'feature-react/state'; +import React from 'react'; +import { ScrollView } from 'react-native'; +import { + TimerConfiguration, + TimerControls, + TimerInput, + TimerProgress, + TimerRecents, + useTimerCx +} from '@/features/timer'; + +const Screen: React.FC = () => { + const cx = useTimerCx(); + const isActive = useCompute(cx.$status, ({ value }) => value !== 'idle'); + + return ( + + {isActive ? ( + <> + + + + ) : ( + + )} + + + + ); +}; + +export default Screen; diff --git a/apps/kairos/src/components/display/icons/AppIcon.tsx b/apps/kairos/src/components/display/icons/AppIcon.tsx new file mode 100644 index 0000000..46ba0ed --- /dev/null +++ b/apps/kairos/src/components/display/icons/AppIcon.tsx @@ -0,0 +1,50 @@ +import MaterialIcons from '@expo/vector-icons/MaterialIcons'; +import { SymbolView, type SymbolViewProps, type SymbolWeight } from 'expo-symbols'; +import React, { type ComponentProps } from 'react'; +import { + Platform, + View, + type OpaqueColorValue, + type StyleProp, + type ViewStyle +} from 'react-native'; + +export const AppIcon: React.FC = (props) => { + const { ios, fallback, size = 18, color, style, weight = 'regular' } = props; + + if (Platform.OS === 'ios') { + return ( + + + + ); + } + + return ( + + + + ); +}; + +export interface TAppIconProps { + ios: SymbolViewProps['name']; + fallback: ComponentProps['name']; + size?: number; + color: string | OpaqueColorValue; + style?: StyleProp; + weight?: SymbolWeight; +} + +export interface TNamedAppIconProps { + size?: number; + color: string | OpaqueColorValue; + style?: StyleProp; + weight?: SymbolWeight; +} diff --git a/apps/kairos/src/components/display/icons/app-icons.tsx b/apps/kairos/src/components/display/icons/app-icons.tsx new file mode 100644 index 0000000..96ff266 --- /dev/null +++ b/apps/kairos/src/components/display/icons/app-icons.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import { AppIcon, type TNamedAppIconProps } from './AppIcon'; + +export const BellIcon: React.FC = (props) => { + return ; +}; + +export const ClockIcon: React.FC = (props) => { + return ; +}; + +export const SmartphoneIcon: React.FC = (props) => { + return ; +}; + +export const SunIcon: React.FC = (props) => { + return ; +}; + +export const MoonIcon: React.FC = (props) => { + return ; +}; + +export const PlayIcon: React.FC = (props) => { + return ; +}; diff --git a/apps/kairos/src/components/display/icons/index.ts b/apps/kairos/src/components/display/icons/index.ts new file mode 100644 index 0000000..41b8455 --- /dev/null +++ b/apps/kairos/src/components/display/icons/index.ts @@ -0,0 +1,2 @@ +export * from './app-icons'; +export * from './AppIcon'; diff --git a/apps/kairos/src/components/display/index.ts b/apps/kairos/src/components/display/index.ts new file mode 100644 index 0000000..838008a --- /dev/null +++ b/apps/kairos/src/components/display/index.ts @@ -0,0 +1 @@ +export * from './icons'; diff --git a/apps/kairos/src/components/index.ts b/apps/kairos/src/components/index.ts new file mode 100644 index 0000000..cbedb6f --- /dev/null +++ b/apps/kairos/src/components/index.ts @@ -0,0 +1,4 @@ +export * from './display'; +export * from './input'; +export * from './layout'; +export * from './provider'; diff --git a/apps/kairos/src/components/input/DurationSelectRow/DurationSelectRow.ios.tsx b/apps/kairos/src/components/input/DurationSelectRow/DurationSelectRow.ios.tsx new file mode 100644 index 0000000..727aaa3 --- /dev/null +++ b/apps/kairos/src/components/input/DurationSelectRow/DurationSelectRow.ios.tsx @@ -0,0 +1,119 @@ +import React from 'react'; +import { Animated, Text, View } from 'react-native'; +import { cn } from '@/lib'; +import { DurationPickerView } from '../../../../modules/duration-picker'; +import { SettingsRow } from '../../layout/SettingsRow'; +import type { TDurationSelectRowProps } from './types'; + +const pad = (n: number) => n.toString().padStart(2, '0'); + +export const DurationSelectRow = (props: TDurationSelectRowProps) => { + const { + title, + subtitle, + children, + hours, + minutes, + seconds, + onDurationChange, + expanded, + onToggle, + disabled = false, + groupSpacing, + valueToUnitSpacing, + wheelHeight = 216, + className, + testID + } = props; + + const animated = React.useRef(new Animated.Value(expanded ? 1 : 0)).current; + const contentHeight = wheelHeight + 28; + const compactSegments = [pad(hours), pad(minutes), pad(seconds)]; + + // MARK: - Actions + + const handlePress = React.useCallback(() => { + if (disabled) return; + onToggle(); + }, [disabled, onToggle]); + + // MARK: - Effects + + React.useEffect(() => { + Animated.timing(animated, { + toValue: expanded ? 1 : 0, + duration: expanded ? 220 : 180, + useNativeDriver: false + }).start(); + }, [animated, expanded]); + + // MARK: - UI + + return ( + + {/* Header */} + + + {compactSegments.map((segment, index) => ( + + + + {segment} + + + {index < compactSegments.length - 1 ? ( + + : + + ) : null} + + ))} + + + } + > + {children} + + + {/* Expanded Content */} + + + + + +
+ ); +}; diff --git a/apps/kairos/src/components/input/DurationSelectRow/DurationSelectRow.tsx b/apps/kairos/src/components/input/DurationSelectRow/DurationSelectRow.tsx new file mode 100644 index 0000000..2e555c5 --- /dev/null +++ b/apps/kairos/src/components/input/DurationSelectRow/DurationSelectRow.tsx @@ -0,0 +1,64 @@ +import React from 'react'; +import { Text, View } from 'react-native'; +import { cn } from '@/lib'; +import { SettingsRow } from '../../layout/SettingsRow'; +import type { TDurationSelectRowProps } from './types'; + +const pad = (n: number) => n.toString().padStart(2, '0'); + +export const DurationSelectRow = (props: TDurationSelectRowProps) => { + const { + title, + subtitle, + children, + hours, + minutes, + seconds, + expanded, + onToggle, + disabled = false, + className, + testID + } = props; + + const compactSegments = [pad(hours), pad(minutes), pad(seconds)]; + + return ( + + + + {compactSegments.map((segment, index) => ( + + + + {segment} + + + {index < compactSegments.length - 1 ? ( + + : + + ) : null} + + ))} + + + } + > + {children} + + + {expanded ? ( + + Duration picker is currently iOS-only. + + ) : null} + + ); +}; diff --git a/apps/kairos/src/components/input/DurationSelectRow/index.ts b/apps/kairos/src/components/input/DurationSelectRow/index.ts new file mode 100644 index 0000000..e9bcd26 --- /dev/null +++ b/apps/kairos/src/components/input/DurationSelectRow/index.ts @@ -0,0 +1,2 @@ +export * from './DurationSelectRow'; +export * from './types'; diff --git a/apps/kairos/src/components/input/DurationSelectRow/types.ts b/apps/kairos/src/components/input/DurationSelectRow/types.ts new file mode 100644 index 0000000..f75c6e8 --- /dev/null +++ b/apps/kairos/src/components/input/DurationSelectRow/types.ts @@ -0,0 +1,20 @@ +import type { ReactNode } from 'react'; +import type { TDurationPickerChangeEvent } from '../../../../../modules/duration-picker'; + +export interface TDurationSelectRowProps { + title?: string; + subtitle?: string; + children?: ReactNode; + hours: number; + minutes: number; + seconds: number; + onDurationChange: (event: { nativeEvent: TDurationPickerChangeEvent }) => void; + expanded: boolean; + onToggle: () => void; + disabled?: boolean; + groupSpacing?: number; + valueToUnitSpacing?: number; + wheelHeight?: number; + className?: string; + testID?: string; +} diff --git a/apps/kairos/src/components/input/SegmentControl.tsx b/apps/kairos/src/components/input/SegmentControl.tsx new file mode 100644 index 0000000..44152ab --- /dev/null +++ b/apps/kairos/src/components/input/SegmentControl.tsx @@ -0,0 +1,105 @@ +import React from 'react'; +import { Animated, Pressable, View, type StyleProp, type ViewStyle } from 'react-native'; +import { cn } from '@/lib'; + +export const SegmentControl: React.FC = (props) => { + const { value, onValueChange, items, className, style, thumbInset = 3 } = props; + + const [width, setWidth] = React.useState(0); + + const selectedIndex = React.useMemo( + () => + Math.max( + 0, + items.findIndex((item) => item.key === value) + ), + [items, value] + ); + + const slideAnimation = React.useRef(new Animated.Value(selectedIndex)).current; + + // MARK: - Effects + + React.useEffect(() => { + Animated.spring(slideAnimation, { + toValue: selectedIndex, + useNativeDriver: true, + speed: 18, + bounciness: 0, + overshootClamping: true + }).start(); + }, [selectedIndex, slideAnimation]); + + // MARK: - UI + + if (!items.length) { + return null; + } + + const borderWidth = 1; + const contentWidth = Math.max(0, width - borderWidth * 2); // Note: `onLayout` width includes border width on both horizontal edges + const segmentWidth = contentWidth > 0 ? contentWidth / items.length : 0; + const thumbWidth = Math.max(0, segmentWidth - thumbInset * 2); + const thumbRadius = Math.max(0, 32 - thumbInset); + const maxIndex = Math.max(0, items.length - 1); + const maxTranslate = Math.max(0, contentWidth - thumbWidth - thumbInset * 2); + + const translateX = slideAnimation.interpolate({ + inputRange: [0, maxIndex === 0 ? 1 : maxIndex], + outputRange: [0, maxTranslate], + extrapolate: 'clamp' + }); + + return ( + setWidth(e.nativeEvent.layout.width)} + > + {segmentWidth > 0 ? ( + + ) : null} + + {items.map((item) => ( + onValueChange(item.key)} + > + {item.render({ isSelected: item.key === value })} + + ))} + + ); +}; + +export interface TSegmentControlProps { + value: string; + onValueChange: (value: string) => void; + items: readonly TSegmentControlItem[]; + className?: string; + style?: StyleProp; + thumbInset?: number; +} + +export interface TSegmentControlItem { + key: string; + render: (params: { isSelected: boolean }) => React.ReactNode; + disabled?: boolean; + testID?: string; +} diff --git a/apps/kairos/src/components/input/ThemeSelector.tsx b/apps/kairos/src/components/input/ThemeSelector.tsx new file mode 100644 index 0000000..2f54aa3 --- /dev/null +++ b/apps/kairos/src/components/input/ThemeSelector.tsx @@ -0,0 +1,48 @@ +import { useCompute } from 'feature-react/state'; +import React from 'react'; +import { Pressable, View } from 'react-native'; +import { + MoonIcon, + SmartphoneIcon, + SunIcon, + type TNamedAppIconProps +} from '@/components/display/icons'; +import { useSettingsCx, type TThemePreference } from '@/features/settings'; +import { cn } from '@/lib'; +import { useTheme } from '../provider'; + +export const ThemeSelector: React.FC = () => { + const settingsCx = useSettingsCx(); + const themePreference = useCompute(settingsCx.$settings, ({ value }) => value.appearance.theme); + const { tokens } = useTheme(); + + const options = React.useMemo<{ value: TThemePreference; Icon: React.FC }[]>( + () => [ + { value: 'system', Icon: SmartphoneIcon }, + { value: 'light', Icon: SunIcon }, + { value: 'dark', Icon: MoonIcon } + ], + [] + ); + + // MARK: - UI + + return ( + + {options.map(({ value, Icon }) => ( + settingsCx.update({ appearance: { theme: value } })} + accessibilityRole="radio" + accessibilityState={{ checked: themePreference === value }} + className={cn( + 'items-center justify-center rounded-full px-4 py-2', + themePreference === value && 'bg-base-0' + )} + > + + + ))} + + ); +}; diff --git a/apps/kairos/src/components/input/WheelPicker/WheelPicker.ios.tsx b/apps/kairos/src/components/input/WheelPicker/WheelPicker.ios.tsx new file mode 100644 index 0000000..3b886bc --- /dev/null +++ b/apps/kairos/src/components/input/WheelPicker/WheelPicker.ios.tsx @@ -0,0 +1,77 @@ +import { Host, Picker, Text } from '@expo/ui/swift-ui'; +import { pickerStyle, tag } from '@expo/ui/swift-ui/modifiers'; +import React from 'react'; +import { View } from 'react-native'; +import { cn } from '@/lib'; +import { useTheme } from '../../provider'; +import type { TWheelPickerItem, TWheelPickerProps, TWheelValue } from './types'; + +export const WheelPicker = (props: TWheelPickerProps) => { + const { + items, + value, + onChange, + height = 216, + disabled = false, + className, + style, + testID + } = props; + const { theme } = useTheme(); + + const itemByValue = React.useMemo(() => { + const result = new Map>(); + items.forEach((item) => { + result.set(item.value, item); + }); + return result; + }, [items]); + + const selectedValue = React.useMemo(() => { + const controlled = itemByValue.get(value); + return controlled?.value ?? items[0]?.value; + }, [value, itemByValue, items]); + + // MARK: - Actions + + const handleSelectionChange = React.useCallback( + (nextSelection: TWheelValue | null) => { + if (nextSelection == null) { + return; + } + + const selectedItem = itemByValue.get(nextSelection); + if (selectedItem == null) { + return; + } + + onChange(selectedItem.value, selectedItem); + }, + [itemByValue, onChange] + ); + + // MARK: - UI + + if (!items.length) { + return null; + } + + return ( + + + + {items.map((item) => ( + + {item.label} + + ))} + + + {disabled ? : null} + + ); +}; diff --git a/apps/kairos/src/components/input/WheelPicker/WheelPicker.tsx b/apps/kairos/src/components/input/WheelPicker/WheelPicker.tsx new file mode 100644 index 0000000..9c7cbde --- /dev/null +++ b/apps/kairos/src/components/input/WheelPicker/WheelPicker.tsx @@ -0,0 +1,18 @@ +import React from 'react'; +import { Text, View } from 'react-native'; +import { cn } from '@/lib'; +import type { TWheelPickerProps, TWheelValue } from './types'; + +export const WheelPicker = (props: TWheelPickerProps) => { + const { className, style, testID } = props; + + return ( + + Wheel picker is iOS-only. + + ); +}; diff --git a/apps/kairos/src/components/input/WheelPicker/index.ts b/apps/kairos/src/components/input/WheelPicker/index.ts new file mode 100644 index 0000000..07c21dc --- /dev/null +++ b/apps/kairos/src/components/input/WheelPicker/index.ts @@ -0,0 +1,2 @@ +export * from './types'; +export * from './WheelPicker'; diff --git a/apps/kairos/src/components/input/WheelPicker/types.ts b/apps/kairos/src/components/input/WheelPicker/types.ts new file mode 100644 index 0000000..e325af5 --- /dev/null +++ b/apps/kairos/src/components/input/WheelPicker/types.ts @@ -0,0 +1,19 @@ +import type { StyleProp, ViewStyle } from 'react-native'; + +export type TWheelValue = string | number; + +export interface TWheelPickerItem { + label: string; + value: TValue; +} + +export interface TWheelPickerProps { + items: TWheelPickerItem[]; + value: TValue; + onChange: (value: TValue, item: TWheelPickerItem) => void; + height?: number; + disabled?: boolean; + className?: string; + style?: StyleProp; + testID?: string; +} diff --git a/apps/kairos/src/components/input/WheelSelectRow/WheelSelectRow.ios.tsx b/apps/kairos/src/components/input/WheelSelectRow/WheelSelectRow.ios.tsx new file mode 100644 index 0000000..68e5793 --- /dev/null +++ b/apps/kairos/src/components/input/WheelSelectRow/WheelSelectRow.ios.tsx @@ -0,0 +1,148 @@ +import React from 'react'; +import { Animated, Text, View } from 'react-native'; +import { cn } from '@/lib'; +import { SettingsRow } from '../../layout/SettingsRow'; +import { WheelPicker } from '../WheelPicker'; +import type { TWheelSelectRowProps } from './types'; + +export const WheelSelectRow = (props: TWheelSelectRowProps) => { + const { + title, + subtitle, + children, + columns, + expanded, + onToggle, + disabled = false, + separator = ':', + compactSeparator = separator, + wheelHeight = 216, + className, + testID + } = props; + const animated = React.useRef(new Animated.Value(expanded ? 1 : 0)).current; + const columnsCount = columns.length; + const contentHeight = wheelHeight + 28; + + const compactSegments = React.useMemo( + () => + columns.map((column) => { + const selectedItem = + column.items.find((item) => item.value === column.value) ?? column.items[0]; + return selectedItem?.label ?? '—'; + }), + [columns] + ); + + // MARK: - Actions + + const handlePress = React.useCallback(() => { + if (disabled) { + return; + } + + onToggle(); + }, [disabled, onToggle]); + + // MARK: - Effects + + React.useEffect(() => { + Animated.timing(animated, { + toValue: expanded ? 1 : 0, + duration: expanded ? 220 : 180, + useNativeDriver: false + }).start(); + }, [animated, expanded]); + + // MARK: - UI + + return ( + + {/* Header */} + + + {compactSegments.map((segment, index) => ( + + + + {segment} + + + {index < compactSegments.length - 1 && compactSeparator.length > 0 ? ( + + {compactSeparator} + + ) : null} + + ))} + + + } + > + {children} + + + {/* Expanded Content */} + + + + {columns.map((column, index) => ( + + + + + {column.suffix != null ? ( + + {column.suffix} + + ) : null} + {index < columnsCount - 1 && separator.length > 0 ? ( + + {separator} + + ) : null} + + ))} + + + + + ); +}; diff --git a/apps/kairos/src/components/input/WheelSelectRow/WheelSelectRow.tsx b/apps/kairos/src/components/input/WheelSelectRow/WheelSelectRow.tsx new file mode 100644 index 0000000..d56c956 --- /dev/null +++ b/apps/kairos/src/components/input/WheelSelectRow/WheelSelectRow.tsx @@ -0,0 +1,68 @@ +import React from 'react'; +import { Text, View } from 'react-native'; +import { cn } from '@/lib'; +import { SettingsRow } from '../../layout/SettingsRow'; +import type { TWheelSelectRowProps } from './types'; + +export const WheelSelectRow = (props: TWheelSelectRowProps) => { + const { + title, + subtitle, + children, + columns, + expanded, + onToggle, + disabled = false, + compactSeparator = ':', + className, + testID + } = props; + const compactSegments = React.useMemo( + () => + columns.map((column) => { + const selectedItem = + column.items.find((item) => item.value === column.value) ?? column.items[0]; + return selectedItem?.label ?? '—'; + }), + [columns] + ); + + return ( + + + + {compactSegments.map((segment, index) => ( + + + + {segment} + + + {index < compactSegments.length - 1 && compactSeparator.length > 0 ? ( + + {compactSeparator} + + ) : null} + + ))} + + + } + > + {children} + + + {expanded ? ( + + Wheel selector is currently iOS-only. + + ) : null} + + ); +}; diff --git a/apps/kairos/src/components/input/WheelSelectRow/index.ts b/apps/kairos/src/components/input/WheelSelectRow/index.ts new file mode 100644 index 0000000..0405423 --- /dev/null +++ b/apps/kairos/src/components/input/WheelSelectRow/index.ts @@ -0,0 +1,2 @@ +export { WheelSelectRow } from './WheelSelectRow'; +export type { TWheelSelectColumn, TWheelSelectRowProps } from './types'; diff --git a/apps/kairos/src/components/input/WheelSelectRow/types.ts b/apps/kairos/src/components/input/WheelSelectRow/types.ts new file mode 100644 index 0000000..b8b419d --- /dev/null +++ b/apps/kairos/src/components/input/WheelSelectRow/types.ts @@ -0,0 +1,26 @@ +import type { ReactNode } from 'react'; +import type { TWheelPickerItem, TWheelValue } from '../WheelPicker'; + +export interface TWheelSelectColumn { + id: string; + items: TWheelPickerItem[]; + value: TWheelValue; + onChange: (value: TWheelValue, item: TWheelPickerItem) => void; + width?: number; + suffix?: string; +} + +export interface TWheelSelectRowProps { + title?: string; + subtitle?: string; + children?: ReactNode; + columns: [TWheelSelectColumn, ...TWheelSelectColumn[]]; + expanded: boolean; + onToggle: () => void; + disabled?: boolean; + separator?: string; + compactSeparator?: string; + wheelHeight?: number; + className?: string; + testID?: string; +} diff --git a/apps/kairos/src/components/input/index.ts b/apps/kairos/src/components/input/index.ts new file mode 100644 index 0000000..cf3d4c8 --- /dev/null +++ b/apps/kairos/src/components/input/index.ts @@ -0,0 +1,5 @@ +export * from './DurationSelectRow'; +export * from './SegmentControl'; +export * from './ThemeSelector'; +export * from './WheelPicker'; +export * from './WheelSelectRow'; diff --git a/apps/kairos/src/components/layout/AppTabs.tsx b/apps/kairos/src/components/layout/AppTabs.tsx new file mode 100644 index 0000000..aede8be --- /dev/null +++ b/apps/kairos/src/components/layout/AppTabs.tsx @@ -0,0 +1,49 @@ +import { NativeTabs } from 'expo-router/unstable-native-tabs'; +import React from 'react'; +import { hexToRgba } from '@/lib'; +import { useTheme } from '../provider'; + +export const AppTabs: React.FC = () => { + const { tokens } = useTheme(); + + const tabColors = React.useMemo( + () => ({ + background: hexToRgba(tokens.base0, 0.85), + indicator: tokens.primary, + iconDefault: tokens.base500, + iconSelected: tokens.base900, + labelDefault: tokens.base500, + labelSelected: tokens.base900 + }), + [tokens] + ); + + return ( + + + Timer + + + + + Settings + + + + ); +}; diff --git a/apps/kairos/src/components/layout/SettingsRow.tsx b/apps/kairos/src/components/layout/SettingsRow.tsx new file mode 100644 index 0000000..3d1a243 --- /dev/null +++ b/apps/kairos/src/components/layout/SettingsRow.tsx @@ -0,0 +1,70 @@ +import React from 'react'; +import { Pressable, Text, View } from 'react-native'; +import { cn } from '@/lib'; + +export const SettingsRow: React.FC = (props) => { + const { + title, + subtitle, + children, + rightAccessory, + onPress, + disabled = false, + className, + testID + } = props; + + const content = ( + + + {children ?? ( + <> + {title != null ? ( + + {title} + + ) : null} + {subtitle != null ? ( + + {subtitle} + + ) : null} + + )} + + {rightAccessory != null ? ( + {rightAccessory} + ) : null} + + ); + + if (onPress == null) { + return ( + + {content} + + ); + } + + return ( + + {content} + + ); +}; + +interface TSettingsRowProps { + title?: string; + subtitle?: string; + children?: React.ReactNode; + rightAccessory?: React.ReactNode; + onPress?: () => void; + disabled?: boolean; + className?: string; + testID?: string; +} diff --git a/apps/kairos/src/components/layout/index.ts b/apps/kairos/src/components/layout/index.ts new file mode 100644 index 0000000..c3d53c4 --- /dev/null +++ b/apps/kairos/src/components/layout/index.ts @@ -0,0 +1,2 @@ +export * from './AppTabs'; +export * from './SettingsRow'; diff --git a/apps/kairos/src/components/provider/ThemeProvider.tsx b/apps/kairos/src/components/provider/ThemeProvider.tsx new file mode 100644 index 0000000..c593499 --- /dev/null +++ b/apps/kairos/src/components/provider/ThemeProvider.tsx @@ -0,0 +1,63 @@ +import { StatusBar } from 'expo-status-bar'; +import { useCompute, useListener } from 'feature-react/state'; +import { VariableContextProvider } from 'nativewind'; +import React from 'react'; +import { Appearance, ColorSchemeName, useColorScheme } from 'react-native'; +import { themeTokens, toCssVariables, TThemeMode, TThemeTokens } from '@/environment'; +import { useSettingsCx } from '@/features/settings'; + +const ThemeCx = React.createContext(null); + +interface TThemeCx { + theme: TThemeMode; + tokens: TThemeTokens; +} + +export const ThemeProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + const settingsCx = useSettingsCx(); + const systemTheme = useColorScheme(); + const theme = useCompute( + settingsCx.$settings, + ({ value }) => { + const pref = value.appearance.theme; + return pref === 'system' ? resolveSystemTheme(systemTheme) : pref; + }, + [systemTheme] + ); + + const { tokens, cssVariables } = React.useMemo(() => { + const tokens = themeTokens[theme]; + return { tokens, cssVariables: toCssVariables(tokens) }; + }, [theme]); + + // MARK: - Effects + + // Sync native color scheme whenever the setting changes + useListener(settingsCx.$settings, ({ value }) => { + const pref = value.appearance.theme; + Appearance.setColorScheme((pref === 'system' ? null : pref) as ColorSchemeName); + }); + + // MARK: - UI + + return ( + ({ theme, tokens }), [theme, tokens])}> + + + {children} + + + ); +}; + +export function useTheme(): TThemeCx { + const cx = React.useContext(ThemeCx); + if (cx == null) { + throw new Error('useTheme must be used within a ThemeProvider'); + } + return cx; +} + +function resolveSystemTheme(systemTheme: ColorSchemeName): TThemeMode { + return systemTheme === 'dark' ? 'dark' : 'light'; +} diff --git a/apps/kairos/src/components/provider/index.ts b/apps/kairos/src/components/provider/index.ts new file mode 100644 index 0000000..8abd195 --- /dev/null +++ b/apps/kairos/src/components/provider/index.ts @@ -0,0 +1 @@ +export * from './ThemeProvider'; diff --git a/apps/kairos/src/environment/configs/app.config.ts b/apps/kairos/src/environment/configs/app.config.ts new file mode 100644 index 0000000..65bde87 --- /dev/null +++ b/apps/kairos/src/environment/configs/app.config.ts @@ -0,0 +1,20 @@ +import Constants from 'expo-constants'; + +export const appConfig = { + name: 'Kairos', + bundleId: 'com.buildergroup.kairos', + version: Constants.expoConfig?.version ?? '1.0', + + links: { + website: 'https://builder.group/apps/kairos', + appStore: null as string | null, // TODO: Add after release + privacyPolicy: 'https://builder.group/apps/kairos/legal/privacy', + github: 'https://github.com/builder-group/lab' + }, + + support: { + email: 'support@builder.group', + mailto: (subject: string): string => + `mailto:support@builder.group?subject=${encodeURIComponent(`[Kairos] ${subject}`)}` + } +} as const; diff --git a/apps/kairos/src/environment/configs/index.ts b/apps/kairos/src/environment/configs/index.ts new file mode 100644 index 0000000..41e7ed1 --- /dev/null +++ b/apps/kairos/src/environment/configs/index.ts @@ -0,0 +1 @@ +export * from './app.config'; diff --git a/apps/kairos/src/environment/index.ts b/apps/kairos/src/environment/index.ts new file mode 100644 index 0000000..24ca7f7 --- /dev/null +++ b/apps/kairos/src/environment/index.ts @@ -0,0 +1,2 @@ +export * from './configs'; +export * from './theme'; diff --git a/apps/kairos/src/environment/theme.ts b/apps/kairos/src/environment/theme.ts new file mode 100644 index 0000000..701b8d6 --- /dev/null +++ b/apps/kairos/src/environment/theme.ts @@ -0,0 +1,61 @@ +export const themeTokens = { + light: { + base0: '#FFFFFF', + base50: '#F2F2F7', + base100: '#EFEFF4', + base200: '#E5E5EA', + base300: '#D1D1D6', + base400: '#C7C7CC', + base500: '#8E8E93', + base600: '#636366', + base700: '#48484A', + base800: '#3A3A3C', + base900: '#1C1C1E', + base950: '#000000', + primary: '#4A92FF', + warning: '#FF9F0A', + danger: '#FF3B30' + }, + dark: { + base0: '#000000', + base50: '#1C1C1E', + base100: '#2C2C2E', + base200: '#3A3A3C', + base300: '#48484A', + base400: '#636366', + base500: '#8E8E93', + base600: '#AEAEB2', + base700: '#C7C7CC', + base800: '#D1D1D6', + base900: '#E5E5EA', + base950: '#F2F2F7', + primary: '#226FF6', + warning: '#FF9F0A', + danger: '#FF453A' + } +} as const; + +export type TThemeMode = keyof typeof themeTokens; +export type TThemeTokens = (typeof themeTokens)[TThemeMode]; + +export function toCssVariables(tokens: TThemeTokens): TCssVariables { + return { + '--base-0': tokens.base0, + '--base-50': tokens.base50, + '--base-100': tokens.base100, + '--base-200': tokens.base200, + '--base-300': tokens.base300, + '--base-400': tokens.base400, + '--base-500': tokens.base500, + '--base-600': tokens.base600, + '--base-700': tokens.base700, + '--base-800': tokens.base800, + '--base-900': tokens.base900, + '--base-950': tokens.base950, + '--primary': tokens.primary, + '--warning': tokens.warning, + '--danger': tokens.danger + }; +} + +export type TCssVariables = Record<`--${string}`, string>; diff --git a/apps/kairos/src/features/audio/AudioCx.tsx b/apps/kairos/src/features/audio/AudioCx.tsx new file mode 100644 index 0000000..70d7813 --- /dev/null +++ b/apps/kairos/src/features/audio/AudioCx.tsx @@ -0,0 +1,55 @@ +import { createState, type TState } from 'feature-state'; +import React from 'react'; +import { useMemoCleanup } from '@/hooks'; +import { getSystemSounds, play, stop } from '../../../modules/audio'; + +export class AudioCx { + public readonly $sounds: TState; + + constructor() { + this.$sounds = createState([]); + } + + public async mount(): Promise { + try { + const sounds = await getSystemSounds(); + if (sounds.length > 0) { + this.$sounds.set(sounds); + } + } catch { + // do nothing + } + } + + public play(name: string): void { + play(name).catch((e) => { + if (__DEV__) console.error('[Audio] play failed:', e); + }); + } + + public stop(): void { + stop(); + } +} + +// MARK: - React Context + +const AudioCxContext = React.createContext(null); + +export const AudioCxProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + const cx = useMemoCleanup(() => [new AudioCx(), () => {}], []); + + React.useEffect(() => { + cx.mount(); + }, [cx]); + + return {children}; +}; + +export function useAudioCx(): AudioCx { + const cx = React.useContext(AudioCxContext); + if (cx == null) { + throw new Error('useAudioCx must be used within an AudioCxProvider'); + } + return cx; +} diff --git a/apps/kairos/src/features/audio/index.ts b/apps/kairos/src/features/audio/index.ts new file mode 100644 index 0000000..d4dec06 --- /dev/null +++ b/apps/kairos/src/features/audio/index.ts @@ -0,0 +1 @@ +export * from './AudioCx'; diff --git a/apps/kairos/src/features/settings/SettingsCx.tsx b/apps/kairos/src/features/settings/SettingsCx.tsx new file mode 100644 index 0000000..082c935 --- /dev/null +++ b/apps/kairos/src/features/settings/SettingsCx.tsx @@ -0,0 +1,73 @@ +import { createState } from 'feature-state'; +import React from 'react'; +import { withAsyncStorage } from '@/lib'; + +// MARK: - Class + +export class SettingsCx { + public readonly $settings = withAsyncStorage( + createState({ + appearance: { + theme: 'system' + } + }), + 'kairos:settings' + ); + + public async mount(): Promise { + await this.$settings.persist(); + } + + public unmount(): void { + // nothing to clean up + } + + public update(updates: TSettingsUpdates): void { + this.$settings.set((current) => ({ + ...current, + ...updates, + appearance: { ...current.appearance, ...updates.appearance } + })); + } + + public reset(): void { + this.$settings.set({ appearance: { theme: 'system' } }); + } +} + +export interface TSettings { + appearance: { + theme: TThemePreference; + }; +} + +interface TSettingsUpdates { + appearance?: Partial; +} + +export type TThemePreference = 'light' | 'dark' | 'system'; + +export type TSettingsCx = SettingsCx; + +// MARK: - React Context + +const SettingsCxContext = React.createContext(null); + +export const SettingsCxProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + const [cx] = React.useState(() => new SettingsCx()); + + React.useEffect(() => { + cx.mount(); + return () => cx.unmount(); + }, [cx]); + + return {children}; +}; + +export function useSettingsCx(): SettingsCx { + const cx = React.useContext(SettingsCxContext); + if (cx == null) { + throw new Error('useSettingsCx must be used within a SettingsCxProvider'); + } + return cx; +} diff --git a/apps/kairos/src/features/settings/index.ts b/apps/kairos/src/features/settings/index.ts new file mode 100644 index 0000000..a2ffec3 --- /dev/null +++ b/apps/kairos/src/features/settings/index.ts @@ -0,0 +1 @@ +export * from './SettingsCx'; diff --git a/apps/kairos/src/features/timer/TimerCx.tsx b/apps/kairos/src/features/timer/TimerCx.tsx new file mode 100644 index 0000000..9f8f8c8 --- /dev/null +++ b/apps/kairos/src/features/timer/TimerCx.tsx @@ -0,0 +1,358 @@ +import * as Haptics from 'expo-haptics'; +import { createState, type TPersistFeature, type TState } from 'feature-state'; +import React from 'react'; +import { useMemoCleanup } from '@/hooks'; +import { withAsyncStorage } from '@/lib'; +import { AudioCx, useAudioCx } from '../audio'; +import { durationToSeconds } from './format'; +import { TDuration } from './types'; + +export class TimerCx { + private static readonly RECENTS_MAX_SIZE = 20; + + private readonly _audioCx: AudioCx; + private _interval: ReturnType | null = null; + + public readonly $config: TState; + public readonly $status: TState; + + public readonly $totalSeconds: TState; + public readonly $remainingSeconds: TState; + public readonly $overtimeSeconds: TState; + + public readonly $remainingAtStart: TState; + public readonly $startedAt: TState; + public readonly $recents: TState; + + constructor(audioCx: AudioCx) { + this._audioCx = audioCx; + this.$config = withAsyncStorage( + createState({ + min: { h: 0, m: 1, s: 0 }, + max: { h: 0, m: 5, s: 0 }, + label: '', + hideTimeDisplay: false, + sound: 'Radar', + endMode: 'overtime', + endAfterSeconds: 5 + }), + 'kairos:timer:config' + ); + + this.$status = withAsyncStorage(createState('idle'), 'kairos:timer:status'); + this.$totalSeconds = withAsyncStorage( + createState(null), + 'kairos:timer:totalSeconds' + ); + this.$startedAt = withAsyncStorage(createState(null), 'kairos:timer:startedAt'); + this.$remainingAtStart = withAsyncStorage( + createState(0), + 'kairos:timer:remainingAtStart' + ); + this.$recents = withAsyncStorage(createState([]), 'kairos:timer:recents'); + this.$remainingSeconds = createState(0); + this.$overtimeSeconds = createState(0); + } + + // MARK: - Lifecycle + + public async mount(): Promise { + await Promise.all([ + this.$config.persist(), + this.$status.persist(), + this.$totalSeconds.persist(), + this.$startedAt.persist(), + this.$remainingAtStart.persist(), + this.$recents.persist() + ]); + this.$config.set((config) => ({ + ...config, + hideTimeDisplay: + config.hideTimeDisplay ?? (config as { hideTimer?: boolean }).hideTimer ?? false + })); + + const status = this.$status.get(); + const startedAt = this.$startedAt.get(); + const remainingAtStart = this.$remainingAtStart.get(); + const now = Date.now(); + + if (status === 'running') { + if (startedAt != null) { + const elapsed = (now - startedAt) / 1000; + if (elapsed < remainingAtStart) { + this.$remainingSeconds.set(remainingAtStart - elapsed); + this._startLoop(); + } else { + this._recoverOvertime(startedAt, remainingAtStart, now); + } + } else { + this.$status.set('idle'); + } + } else if (status === 'overtime') { + if (startedAt != null) { + this._recoverOvertime(startedAt, remainingAtStart, now); + } else { + this.$status.set('idle'); + } + } else if (status === 'paused') { + this.$remainingSeconds.set(remainingAtStart); + } + } + + public unmount(): void { + this._stopLoop(); + } + + // MARK: - Actions + + public start(options: TTimerStartOptions = {}): void { + this._audioCx.stop(); + + const { config: configOverride, recordRecent = true } = options; + if (configOverride != null) { + this.$config.set(configOverride); + } + const config = configOverride ?? this.$config.get(); + + const { min, max } = config; + const lo = Math.min(durationToSeconds(min), durationToSeconds(max)); + const hi = Math.max(durationToSeconds(min), durationToSeconds(max)); + const totalSeconds = lo === hi ? lo : Math.round(lo + Math.random() * (hi - lo)); + const now = Date.now(); + + if (recordRecent) { + this._upsertRecent(config, totalSeconds); + } + + this.$totalSeconds.set(totalSeconds); + this.$startedAt.set(now); + this.$remainingAtStart.set(totalSeconds); + this.$overtimeSeconds.set(0); + this.$status.set('running'); + this.$remainingSeconds.set(totalSeconds); + this._startLoop(); + } + + public pause(): void { + if (this.$status.get() !== 'running') { + return; + } + + const startedAt = this.$startedAt.get(); + const remainingAtStart = this.$remainingAtStart.get(); + if (startedAt == null) { + return; + } + + const remaining = Math.max(0, remainingAtStart - (Date.now() - startedAt) / 1000); + + this._stopLoop(); + this.$startedAt.set(null); + this.$remainingAtStart.set(remaining); + this.$status.set('paused'); + this.$remainingSeconds.set(remaining); + } + + public resume(): void { + if (this.$status.get() !== 'paused') { + return; + } + + const now = Date.now(); + this.$startedAt.set(now); + this.$status.set('running'); + this.$remainingSeconds.set(this.$remainingAtStart.get()); + this._startLoop(); + } + + public cancel(): void { + this._audioCx.stop(); + this._stopLoop(); + this.$status.set('idle'); + this.$totalSeconds.set(null); + this.$startedAt.set(null); + this.$remainingAtStart.set(0); + this.$remainingSeconds.set(0); + this.$overtimeSeconds.set(0); + } + + public clearRecents(): void { + this.$recents.set([]); + } + + public reset(): void { + this.cancel(); + this.$config.set({ + min: { h: 0, m: 1, s: 0 }, + max: { h: 0, m: 5, s: 0 }, + label: '', + hideTimeDisplay: false, + sound: 'Radar', + endMode: 'overtime', + endAfterSeconds: 5 + }); + this.$recents.set([]); + } + + // MARK: - Tick loop + + private _startLoop(): void { + this._stopLoop(); + this._interval = setInterval(() => this._tick(), 200); + } + + private _stopLoop(): void { + if (this._interval != null) { + clearInterval(this._interval); + this._interval = null; + } + } + + private _tick(): void { + const startedAt = this.$startedAt.get(); + const remainingAtStart = this.$remainingAtStart.get(); + if (startedAt == null) { + return; + } + + const elapsed = (Date.now() - startedAt) / 1000; + const remaining = Math.max(0, remainingAtStart - elapsed); + const overtime = Math.max(0, elapsed - remainingAtStart); + const status = this.$status.get(); + + if (status === 'overtime') { + this.$overtimeSeconds.set(overtime); + const { endMode, endAfterSeconds } = this.$config.get(); + if (endMode !== 'overtime' && overtime >= endAfterSeconds) { + this._onAutoEnd(); + } + return; + } + + this.$remainingSeconds.set(remaining); + if (remaining === 0) { + this.$overtimeSeconds.set(0); + this.$status.set('overtime'); + this._audioCx.play(this.$config.get().sound); + Haptics.notificationAsync(Haptics.NotificationFeedbackType.Warning); + } + } + + private _onAutoEnd(): void { + const { endMode } = this.$config.get(); + if (endMode === 'loop') { + this.start({ recordRecent: false }); + return; + } + this.cancel(); + } + + // MARK: - Helpers + + private _upsertRecent(config: TTimerConfig, lastUsedTotalSeconds: number): void { + const hash = this._recentHash(config); + this.$recents.set((current) => { + const existing = current.find((entry) => entry.hash === hash); + const now = Date.now(); + const next: TTimerRecent = { + hash, + config, + lastUsedTotalSeconds, + createdAt: existing?.createdAt ?? now, + lastUsedAt: now + }; + const filtered = current.filter((entry) => entry.hash !== hash); + return [next, ...filtered].slice(0, TimerCx.RECENTS_MAX_SIZE); + }); + } + + private _recentHash(config: TTimerConfig): string { + const key = JSON.stringify({ + min: config.min, + max: config.max, + label: config.label.trim(), + hideTimeDisplay: config.hideTimeDisplay, + sound: config.sound, + endMode: config.endMode, + endAfterSeconds: config.endAfterSeconds + }); + + // Simple stable hash for recent dedupe/list keys. + let hash = 5381; + for (let i = 0; i < key.length; i += 1) { + hash = (hash * 33) ^ key.charCodeAt(i); + } + return `timer_${(hash >>> 0).toString(36)}`; + } + + private _recoverOvertime(startedAt: number, remainingAtStart: number, now: number): void { + const elapsed = (now - startedAt) / 1000; + const overtimeSeconds = Math.max(0, elapsed - remainingAtStart); + const { endMode, endAfterSeconds } = this.$config.get(); + + if (endMode === 'overtime' || overtimeSeconds < endAfterSeconds) { + this.$remainingSeconds.set(0); + this.$overtimeSeconds.set(overtimeSeconds); + this.$status.set('overtime'); + this._startLoop(); + } else if (endMode === 'loop') { + this.start({ recordRecent: false }); + } else { + this.cancel(); + } + } +} + +export type TTimerStatus = 'idle' | 'running' | 'paused' | 'overtime'; +export type TTimerSound = string; +export type TTimerEndMode = 'overtime' | 'stop' | 'loop'; + +export interface TTimerConfig { + min: TDuration; + max: TDuration; + label: string; + hideTimeDisplay: boolean; + sound: TTimerSound; + endMode: TTimerEndMode; + /** Seconds of overtime before auto-stop or auto-loop triggers. Ignored when endMode is 'overtime'. */ + endAfterSeconds: number; +} + +interface TTimerStartOptions { + config?: TTimerConfig; + recordRecent?: boolean; +} + +export interface TTimerRecent { + hash: string; + config: TTimerConfig; + lastUsedTotalSeconds: number; + createdAt: number; + lastUsedAt: number; +} + +// MARK: - React Context + +const TimerCxContext = React.createContext(null); + +export const TimerCxProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + const audioCx = useAudioCx(); + const cx = useMemoCleanup(() => { + const instance = new TimerCx(audioCx); + return [instance, () => instance.unmount()]; + }, [audioCx]); + + React.useEffect(() => { + cx.mount(); + }, [cx]); + + return {children}; +}; + +export function useTimerCx(): TimerCx { + const cx = React.useContext(TimerCxContext); + if (cx == null) { + throw new Error('useTimerCx must be used within a TimerCxProvider'); + } + return cx; +} diff --git a/apps/kairos/src/features/timer/components/ProgressRing.tsx b/apps/kairos/src/features/timer/components/ProgressRing.tsx new file mode 100644 index 0000000..cf4ea92 --- /dev/null +++ b/apps/kairos/src/features/timer/components/ProgressRing.tsx @@ -0,0 +1,92 @@ +import React from 'react'; +import { View } from 'react-native'; +import Animated, { + Easing, + useAnimatedProps, + useSharedValue, + withTiming +} from 'react-native-reanimated'; +import Svg, { Circle } from 'react-native-svg'; +import { useTheme } from '@/components'; +import { cn } from '@/lib'; + +const AnimatedCircle = Animated.createAnimatedComponent(Circle); + +export const ProgressRing: React.FC = (props) => { + const { tokens } = useTheme(); + const { + progress, + size = 250, + thickness = 8, + trackColor = tokens.base300, + progressColor = tokens.primary, + animationDuration = 220, + className, + children + } = props; + + const clampedProgress = React.useMemo(() => Math.min(Math.max(progress, 0), 1), [progress]); + const radius = React.useMemo(() => (size - thickness) / 2, [size, thickness]); + const center = React.useMemo(() => size / 2, [size]); + const circumference = React.useMemo(() => 2 * Math.PI * radius, [radius]); + + const strokeDashoffset = useSharedValue(circumference); + + // MARK: - Effects + + React.useEffect(() => { + strokeDashoffset.value = withTiming(circumference * (1 - clampedProgress), { + duration: animationDuration, + easing: Easing.linear + }); + }, [animationDuration, clampedProgress, circumference, strokeDashoffset]); + + // MARK: - UI + + const animatedProps = useAnimatedProps(() => ({ + strokeDashoffset: strokeDashoffset.value + })); + + return ( + + + + + + + + {children != null ? ( + {children} + ) : null} + + ); +}; + +interface TProgressRingProps { + progress: number; + size?: number; + thickness?: number; + trackColor?: string; + progressColor?: string; + animationDuration?: number; + className?: string; + children?: React.ReactNode; +} diff --git a/apps/kairos/src/features/timer/components/PulsingDashRing.tsx b/apps/kairos/src/features/timer/components/PulsingDashRing.tsx new file mode 100644 index 0000000..3d805e0 --- /dev/null +++ b/apps/kairos/src/features/timer/components/PulsingDashRing.tsx @@ -0,0 +1,127 @@ +import React from 'react'; +import { View } from 'react-native'; +import Svg, { Line } from 'react-native-svg'; +import { useTheme } from '@/components'; +import { cn } from '@/lib'; + +export const PulsingDashRing: React.FC = (props) => { + const { tokens } = useTheme(); + const { + size = 250, + dashCount = 60, + dashLength = 12, + dashThickness = 3, + trailLength = 14, + stepMs = 10, + animated = true, + activeColor = tokens.primary, + inactiveColor = tokens.base300, + children, + className + } = props; + const [headIndex, setHeadIndex] = React.useState(0); + + const center = React.useMemo(() => size / 2, [size]); + const radius = React.useMemo(() => size / 2 - 12, [size]); + + // MARK: - Effects + + React.useEffect(() => { + if (!animated) { + return; + } + + const timer = setInterval(() => { + setHeadIndex((current) => (current + 1) % dashCount); + }, stepMs); + + return () => clearInterval(timer); + }, [animated, dashCount, stepMs]); + + const dashes = React.useMemo(() => { + return Array.from({ length: dashCount }, (_, index) => { + const angle = -Math.PI / 2 + (index / dashCount) * Math.PI * 2; + const outerX = center + Math.cos(angle) * radius; + const outerY = center + Math.sin(angle) * radius; + const innerX = center + Math.cos(angle) * (radius - dashLength); + const innerY = center + Math.sin(angle) * (radius - dashLength); + const distance = (headIndex - index + dashCount) % dashCount; + const intensity = distance < trailLength ? 1 - distance / trailLength : 0; + const stroke = mixColor(inactiveColor, activeColor, intensity); + return { key: `dash-${index}`, outerX, outerY, innerX, innerY, stroke }; + }); + }, [center, activeColor, inactiveColor, dashCount, dashLength, headIndex, radius, trailLength]); + + // MARK: - UI + + return ( + + + {dashes.map((dash) => ( + + ))} + + + {children != null ? ( + {children} + ) : null} + + ); +}; + +interface TPulsingDashRingProps { + size?: number; + dashCount?: number; + dashLength?: number; + dashThickness?: number; + trailLength?: number; + stepMs?: number; + animated?: boolean; + activeColor?: string; + inactiveColor?: string; + className?: string; + children?: React.ReactNode; +} + +// MARK: - Helpers + +function mixColor(from: string, to: string, weight: number): string { + const w = Math.min(Math.max(weight, 0), 1); + const start = hexToRgb(from); + const end = hexToRgb(to); + const r = Math.round(start.r + (end.r - start.r) * w); + const g = Math.round(start.g + (end.g - start.g) * w); + const b = Math.round(start.b + (end.b - start.b) * w); + return `rgb(${r}, ${g}, ${b})`; +} + +function hexToRgb(hex: string): { r: number; g: number; b: number } { + const clean = hex.replace('#', ''); + const normalized = + clean.length === 3 + ? clean + .split('') + .map((char) => `${char}${char}`) + .join('') + : clean; + + const parsed = parseInt(normalized, 16); + if (Number.isNaN(parsed)) { + return { r: 0, g: 0, b: 0 }; + } + + return { + r: (parsed >> 16) & 255, + g: (parsed >> 8) & 255, + b: parsed & 255 + }; +} diff --git a/apps/kairos/src/features/timer/components/TimerActionButton.tsx b/apps/kairos/src/features/timer/components/TimerActionButton.tsx new file mode 100644 index 0000000..42778ec --- /dev/null +++ b/apps/kairos/src/features/timer/components/TimerActionButton.tsx @@ -0,0 +1,51 @@ +import React from 'react'; +import { Pressable, Text } from 'react-native'; +import { useTheme } from '@/components'; +import { hexToRgba } from '@/lib'; + +export const TimerActionButton: React.FC = (props) => { + const { label, tone, onPress, disabled = false } = props; + const { tokens } = useTheme(); + + const { backgroundColor, textColor } = React.useMemo(() => { + switch (tone) { + case 'positive': + return { backgroundColor: hexToRgba('#00D042', 0.14), textColor: '#00D042' }; + case 'warning': + return { backgroundColor: hexToRgba('#FF8B00', 0.14), textColor: '#FF8B00' }; + case 'neutral': + return { + backgroundColor: hexToRgba(tokens.base700, 0.1), + textColor: tokens.base800 + }; + case 'primary': + default: + return { + backgroundColor: hexToRgba(tokens.primary, 0.12), + textColor: tokens.primary + }; + } + }, [tone, tokens.base700, tokens.base800, tokens.primary]); + + return ( + + + {label} + + + ); +}; + +interface TTimerActionButtonProps { + label: string; + tone?: TTimerActionButtonTone; + onPress: () => void; + disabled?: boolean; +} + +type TTimerActionButtonTone = 'primary' | 'positive' | 'warning' | 'neutral'; diff --git a/apps/kairos/src/features/timer/components/TimerConfiguration.ios.tsx b/apps/kairos/src/features/timer/components/TimerConfiguration.ios.tsx new file mode 100644 index 0000000..157e51e --- /dev/null +++ b/apps/kairos/src/features/timer/components/TimerConfiguration.ios.tsx @@ -0,0 +1,279 @@ +import { + Divider, + Host, + HStack, + Image, + LabeledContent, + Picker, + Text, + TextField, + Toggle, + VStack, + type TextFieldRef +} from '@expo/ui/swift-ui'; +import { + background, + clipShape, + foregroundStyle, + frame, + multilineTextAlignment, + padding, + pickerStyle, + shapes, + submitLabel, + tag, + textFieldStyle, + tint +} from '@expo/ui/swift-ui/modifiers'; +import { useCompute } from 'feature-react/state'; +import React from 'react'; +import { View } from 'react-native'; +import { useTheme } from '@/components'; +import { useAudioCx } from '@/features/audio'; +import { TimerCx, type TTimerEndMode } from '../TimerCx'; + +export const TimerConfiguration: React.FC = (props) => { + const { cx } = props; + const { theme, tokens } = useTheme(); + const audioCx = useAudioCx(); + + const labelRef = React.useRef(null); + const endAfterRef = React.useRef(null); + const [isLabelFocused, setIsLabelFocused] = React.useState(false); + const [isEndAfterFocused, setIsEndAfterFocused] = React.useState(false); + + const label = useCompute(cx.$config, ({ value }) => value.label); + const sound = useCompute(cx.$config, ({ value }) => value.sound); + const hideTimeDisplay = useCompute(cx.$config, ({ value }) => value.hideTimeDisplay); + const endMode = useCompute(cx.$config, ({ value }) => value.endMode); + const endAfterSeconds = useCompute(cx.$config, ({ value }) => value.endAfterSeconds); + const availableSounds = useCompute(audioCx.$sounds, ({ value }) => value); + const canClearLabel = label.length > 0 && isLabelFocused; + + const rowHeight = frame({ minHeight: 52 }); + const baseRowPadding = padding({ leading: 16, trailing: 20 }); + const pickerRowPadding = padding({ leading: 16, trailing: 8 }); + const dividerInsets = padding({ leading: 16, trailing: 20 }); + + // MARK: - Actions + + const setLabelInputText = React.useCallback((value: string) => { + void labelRef.current?.setText(value).catch(() => undefined); + }, []); + + const setEndAfterInputText = React.useCallback((value: string) => { + void endAfterRef.current?.setText(value).catch(() => undefined); + }, []); + + const handleClearLabel = React.useCallback(() => { + cx.$config.set((c) => ({ ...c, label: '' })); + setLabelInputText(''); + }, [cx, setLabelInputText]); + + const handleLabelFocusChange = React.useCallback( + (focused: boolean) => { + setIsLabelFocused(focused); + if (!focused) { + return; + } + const cursorIndex = label.length; + requestAnimationFrame(() => { + void labelRef.current?.setSelection(cursorIndex, cursorIndex).catch(() => undefined); + }); + }, + [label.length] + ); + + const handleEndAfterChange = React.useCallback( + (value: string) => { + const digitsOnly = value.replace(/\D+/g, ''); + if (digitsOnly !== value) { + setEndAfterInputText(digitsOnly); + } + if (!digitsOnly.length) { + return; + } + const n = Number(digitsOnly); + if (!Number.isNaN(n) && n >= 0) { + cx.$config.set((c) => ({ ...c, endAfterSeconds: n })); + } + }, + [cx, setEndAfterInputText] + ); + + const handleEndAfterFocusChange = React.useCallback( + (focused: boolean) => { + setIsEndAfterFocused(focused); + if (focused) { + const cursorIndex = String(endAfterSeconds).length; + requestAnimationFrame(() => { + void endAfterRef.current?.setSelection(cursorIndex, cursorIndex).catch(() => undefined); + }); + return; + } + setEndAfterInputText(String(endAfterSeconds)); + }, + [endAfterSeconds, setEndAfterInputText] + ); + + const handleEndAfterSubmit = React.useCallback(() => { + void endAfterRef.current?.blur(); + }, []); + + // MARK: - Effects + + React.useEffect(() => { + if (!isEndAfterFocused) { + setEndAfterInputText(String(endAfterSeconds)); + } + }, [endAfterSeconds, isEndAfterFocused, setEndAfterInputText]); + + React.useEffect(() => { + if (!isLabelFocused) { + setLabelInputText(label); + } + }, [label, isLabelFocused, setLabelInputText]); + + // MARK: - UI + + return ( + + + {/* We intentionally avoid Form here. + Form is list-backed and expands/collapses based on container constraints, which makes + embedding between TimerInput and Recents brittle. We considered: + 1) fixed-height Form (works but rigid), + 2) dynamic Form sizing (not reliable with list-backed layout), + 3) custom grouped card rows (chosen: predictable sizing + form-like look). */} + + + + { + cx.$config.set((c) => ({ ...c, label: v })); + }} + onChangeFocus={handleLabelFocusChange} + onSubmit={() => { + void labelRef.current?.blur(); + }} + modifiers={[ + textFieldStyle('plain'), + submitLabel('done'), + frame({ width: canClearLabel ? 120 : 140, alignment: 'trailing' }), + multilineTextAlignment('trailing') + ]} + /> + {canClearLabel && ( + + )} + + + + + + + { + const name = v as string; + cx.$config.set((c) => ({ ...c, sound: name })); + audioCx.play(name); + }} + modifiers={[ + pickerStyle('menu'), + multilineTextAlignment('trailing'), + foregroundStyle({ type: 'hierarchical', style: 'secondary' }), + tint(tokens.base500) + ]} + > + {availableSounds.map((name) => ( + + {name} + + ))} + + + + + + + { + cx.$config.set((c) => ({ ...c, endMode: v as TTimerEndMode })); + }} + modifiers={[ + pickerStyle('menu'), + multilineTextAlignment('trailing'), + foregroundStyle({ type: 'hierarchical', style: 'secondary' }), + tint(tokens.base500) + ]} + > + Overtime + Auto Stop + Auto Repeat + + + + {(endMode === 'loop' || endMode === 'stop') && ( + <> + + + + + + )} + + + + { + cx.$config.set((c) => ({ ...c, hideTimeDisplay: v })); + }} + modifiers={[baseRowPadding, rowHeight]} + /> + + + + ); +}; + +interface TTimerConfigurationProps { + cx: TimerCx; +} diff --git a/apps/kairos/src/features/timer/components/TimerConfiguration.tsx b/apps/kairos/src/features/timer/components/TimerConfiguration.tsx new file mode 100644 index 0000000..248ef9a --- /dev/null +++ b/apps/kairos/src/features/timer/components/TimerConfiguration.tsx @@ -0,0 +1,8 @@ +import React from 'react'; +import { TimerCx } from '../TimerCx'; + +export const TimerConfiguration: React.FC = () => null; + +interface TTimerConfigurationProps { + cx: TimerCx; +} diff --git a/apps/kairos/src/features/timer/components/TimerControls.tsx b/apps/kairos/src/features/timer/components/TimerControls.tsx new file mode 100644 index 0000000..f583fc4 --- /dev/null +++ b/apps/kairos/src/features/timer/components/TimerControls.tsx @@ -0,0 +1,52 @@ +import { useCompute } from 'feature-react/state'; +import React from 'react'; +import { View } from 'react-native'; +import { TimerCx } from '../TimerCx'; +import { TimerActionButton } from './TimerActionButton'; + +export const TimerControls: React.FC = ({ cx }) => { + const status = useCompute(cx.$status, ({ value }) => value); + + const canRightAction = status === 'running' || status === 'paused' || status === 'overtime'; + const rightActionLabel = + status === 'overtime' ? 'Repeat' : status === 'paused' ? 'Resume' : 'Pause'; + const rightActionTone = status === 'running' ? 'warning' : 'positive'; + + // MARK: - Actions + + const handleCancel = React.useCallback(() => { + cx.cancel(); + }, [cx]); + + const handlePrimaryAction = React.useCallback(() => { + if (status === 'overtime') { + cx.start(); + return; + } + if (status === 'paused') { + cx.resume(); + return; + } + cx.pause(); + }, [cx, status]); + + // MARK: - UI + + return ( + + + + {canRightAction && ( + + )} + + ); +}; + +interface TTimerControlsProps { + cx: TimerCx; +} diff --git a/apps/kairos/src/features/timer/components/TimerInput.tsx b/apps/kairos/src/features/timer/components/TimerInput.tsx new file mode 100644 index 0000000..608f2b5 --- /dev/null +++ b/apps/kairos/src/features/timer/components/TimerInput.tsx @@ -0,0 +1,173 @@ +import { useCombinedCompute } from 'feature-react/state'; +import React from 'react'; +import { Text, View } from 'react-native'; +import { SegmentControl, TSegmentControlItem } from '@/components'; +import { cn } from '@/lib'; +import { + DurationPickerView, + TDurationPickerChangeEvent +} from '../../../../modules/duration-picker'; +import { durationToSeconds, formatDurationCompact, isSameDuration } from '../format'; +import { TimerCx } from '../TimerCx'; +import { TimerActionButton } from './TimerActionButton'; + +export const TimerInput: React.FC = (props) => { + const { cx } = props; + const { min, max, isInvalidRange, isFixedDuration } = useCombinedCompute( + [cx.$config], + ([{ value: config }]) => { + const min = config.min; + const max = config.max; + const minTotal = durationToSeconds(min); + const maxTotal = durationToSeconds(max); + return { + min, + max, + isInvalidRange: minTotal > maxTotal, + isFixedDuration: minTotal === maxTotal + }; + }, + [], + { + isEqual: (a, b) => + isSameDuration(a.min, b.min) && + isSameDuration(a.max, b.max) && + a.isInvalidRange === b.isInvalidRange && + a.isFixedDuration === b.isFixedDuration + } + ); + const [activeTimer, setActiveTimer] = React.useState('min'); + + const hours = activeTimer === 'min' ? min.h : max.h; + const minutes = activeTimer === 'min' ? min.m : max.m; + const seconds = activeTimer === 'min' ? min.s : max.s; + + // MARK: - Actions + + const handleDurationChange = React.useCallback( + ({ nativeEvent }: { nativeEvent: TDurationPickerChangeEvent }) => { + const next = { h: nativeEvent.hours, m: nativeEvent.minutes, s: nativeEvent.seconds }; + cx.$config.set((c) => ({ ...c, [activeTimer]: next })); + }, + [activeTimer, cx] + ); + + const handleActiveTimerChange = React.useCallback((nextValue: string) => { + if (nextValue === 'min' || nextValue === 'max') { + setActiveTimer(nextValue); + } + }, []); + + const handleStart = React.useCallback(() => { + cx.start(); + }, [cx]); + + // MARK: - UI + + const timerItems = React.useMemo( + () => [ + { + key: 'min' as const, + render: ({ isSelected }) => ( + <> + + MIN + + + {formatDurationCompact(min)} + + + ) + }, + { + key: 'max' as const, + render: ({ isSelected }) => ( + <> + + MAX + + + {formatDurationCompact(max)} + + + ) + } + ], + [isFixedDuration, isInvalidRange, max, min] + ); + + return ( + <> + + + + + + {isInvalidRange && ( + + MAX must be greater than or equal to MIN. + + )} + {!isInvalidRange && isFixedDuration && ( + + MIN and MAX are equal. Timer will always use the same duration. + + )} + + + + + + ); +}; + +interface TTimerInputProps { + cx: TimerCx; +} + +type TActiveTimer = 'min' | 'max'; diff --git a/apps/kairos/src/features/timer/components/TimerProgress.tsx b/apps/kairos/src/features/timer/components/TimerProgress.tsx new file mode 100644 index 0000000..84eb16c --- /dev/null +++ b/apps/kairos/src/features/timer/components/TimerProgress.tsx @@ -0,0 +1,148 @@ +import { useCombinedCompute, useCompute, useFeatureState } from 'feature-react/state'; +import React from 'react'; +import { Text, View } from 'react-native'; +import { BellIcon, ClockIcon, useTheme } from '@/components'; +import { cn } from '@/lib'; +import { formatClockTime, formatTimerClock, hasTimerHours } from '../format'; +import { TimerCx } from '../TimerCx'; +import { ProgressRing } from './ProgressRing'; +import { PulsingDashRing } from './PulsingDashRing'; + +export const TimerProgress: React.FC = (props) => { + const { cx, className } = props; + const { tokens } = useTheme(); + + const status = useCompute(cx.$status, ({ value }) => value); + const hideTimeDisplay = useCompute(cx.$config, ({ value }) => value.hideTimeDisplay); + const endMode = useCompute(cx.$config, ({ value }) => value.endMode); + const isOvertime = status === 'overtime'; + const progress = useCombinedCompute( + [cx.$status, cx.$totalSeconds, cx.$remainingSeconds], + ([{ value: status }, { value: totalSeconds }, { value: remainingSeconds }]) => { + if (status === 'overtime') { + return 1; + } + if (totalSeconds == null || totalSeconds <= 0) { + return 0; + } + return Math.min(Math.max(1 - Math.max(0, remainingSeconds) / totalSeconds, 0), 1); + } + ); + const activeRingColor = isOvertime && endMode === 'overtime' ? '#FF9500' : tokens.primary; + + // MARK: - UI + + return ( + + {hideTimeDisplay ? ( + + {isOvertime ? : null} + + ) : ( + + + + )} + + ); +}; + +interface TTimerProgressProps { + cx: TimerCx; + className?: string; +} + +// MARK: - TimerProgressContent + +const TimerProgressContent: React.FC = (props) => { + const { cx } = props; + const { tokens } = useTheme(); + + const status = useCompute(cx.$status, ({ value }) => value); + const endMode = useCompute(cx.$config, ({ value }) => value.endMode); + const endAfterSeconds = useCompute(cx.$config, ({ value }) => value.endAfterSeconds); + const totalSeconds = useCompute(cx.$totalSeconds, ({ value }) => value); + const remainingSeconds = useFeatureState(cx.$remainingSeconds); + const overtimeSeconds = useFeatureState(cx.$overtimeSeconds); + const endTime = useCombinedCompute( + [cx.$startedAt, cx.$remainingAtStart], + ([{ value: startedAt }, { value: remainingAtStart }]) => + startedAt != null ? startedAt + remainingAtStart * 1000 : null + ); + + const autoEndCountdown = React.useMemo(() => { + if (status === 'overtime' && endMode !== 'overtime') { + return Math.max(0, endAfterSeconds - overtimeSeconds); + } + return null; + }, [status, endMode, endAfterSeconds, overtimeSeconds]); + const timerDisplaySeconds = React.useMemo( + () => + status === 'overtime' + ? Math.max(0, (totalSeconds ?? 0) + overtimeSeconds) + : Math.max(0, remainingSeconds), + [status, totalSeconds, overtimeSeconds, remainingSeconds] + ); + + // MARK: - UI + + return ( + + {status !== 'overtime' && ( + + + + {endTime != null ? formatClockTime(endTime) : '--:--'} + + + )} + + + {formatTimerClock(timerDisplaySeconds)} + + + {status === 'overtime' && ( + + + + {autoEndCountdown != null + ? `${endMode === 'loop' ? 'Repeat' : 'Stop'} in ${formatTimerClock(autoEndCountdown)}` + : `+${formatTimerClock(Math.max(0, overtimeSeconds))}`} + + + )} + + ); +}; + +interface TTimerProgressContentProps { + cx: TimerCx; +} diff --git a/apps/kairos/src/features/timer/components/TimerRecents.tsx b/apps/kairos/src/features/timer/components/TimerRecents.tsx new file mode 100644 index 0000000..b1d2bae --- /dev/null +++ b/apps/kairos/src/features/timer/components/TimerRecents.tsx @@ -0,0 +1,92 @@ +import { useCompute } from 'feature-react/state'; +import React from 'react'; +import { Pressable, Text, View } from 'react-native'; +import { PlayIcon } from '@/components'; +import { hexToRgba } from '@/lib'; +import { formatDurationRange, formatTimerClock } from '../format'; +import { TimerCx, type TTimerRecent } from '../TimerCx'; + +export const TimerRecents: React.FC = (props) => { + const { cx } = props; + const recents = useCompute(cx.$recents, ({ value }) => value); + + // MARK: - Actions + + const handleSelectRecent = React.useCallback( + (recent: TTimerRecent) => { + cx.$config.set(recent.config); + }, + [cx] + ); + + const handleStartRecent = React.useCallback( + (recent: TTimerRecent) => { + cx.start({ config: recent.config }); + }, + [cx] + ); + + // MARK: - UI + + if (!recents.length) { + return null; + } + + return ( + + Recents + + + {recents.map((recent, index) => { + const { config } = recent; + const title = formatTimerClock(recent.lastUsedTotalSeconds); + const subtitle = + config.label.trim().length > 0 + ? config.label.trim() + : formatDurationRange(config.min, config.max); + return ( + + { + handleSelectRecent(recent); + }} + > + + + {title} + + + {subtitle} + + + + { + e.stopPropagation(); + handleStartRecent(recent); + }} + > + + + + {index < recents.length - 1 ? ( + + ) : null} + + ); + })} + + + + ); +}; + +interface TTimerRecentsProps { + cx: TimerCx; +} diff --git a/apps/kairos/src/features/timer/components/index.ts b/apps/kairos/src/features/timer/components/index.ts new file mode 100644 index 0000000..67f1f03 --- /dev/null +++ b/apps/kairos/src/features/timer/components/index.ts @@ -0,0 +1,8 @@ +export * from './ProgressRing'; +export * from './PulsingDashRing'; +export * from './TimerActionButton'; +export * from './TimerControls'; +export * from './TimerProgress'; +export * from './TimerConfiguration'; +export * from './TimerInput'; +export * from './TimerRecents'; diff --git a/apps/kairos/src/features/timer/format.ts b/apps/kairos/src/features/timer/format.ts new file mode 100644 index 0000000..47c1703 --- /dev/null +++ b/apps/kairos/src/features/timer/format.ts @@ -0,0 +1,87 @@ +import type { TDuration } from './types'; + +export function durationToSeconds(duration: TDuration): number { + return duration.h * 3600 + duration.m * 60 + duration.s; +} + +export function isSameDuration(a: TDuration, b: TDuration): boolean { + return a.h === b.h && a.m === b.m && a.s === b.s; +} + +export function formatTimerClock(seconds: number): string { + const total = Math.ceil(seconds); + const h = Math.floor(total / 3600); + const m = Math.floor((total % 3600) / 60); + const s = total % 60; + + if (h > 0) { + return `${pad2(h)}:${pad2(m)}:${pad2(s)}`; + } + return `${pad2(m)}:${pad2(s)}`; +} + +export function hasTimerHours(seconds: number): boolean { + return Math.floor(Math.ceil(seconds) / 3600) > 0; +} + +export function formatClockTime(epochMs: number): string { + const date = new Date(epochMs); + return `${pad2(date.getHours())}:${pad2(date.getMinutes())}`; +} + +export function formatDurationCompact(duration: TDuration): string { + const { h, m, s } = duration; + + if (h > 0) return `${h}h ${m}m ${s}s`; + if (m > 0 && s === 0) return `${m}m`; + if (m > 0) return `${m}m ${s}s`; + if (s > 0) return `${s}s`; + return '0s'; +} + +export function formatDurationLabel(seconds: number): string { + const total = Math.max(0, Math.ceil(seconds)); + const hours = Math.floor(total / 3600); + const minutes = Math.floor((total % 3600) / 60); + + if (hours > 0 && minutes > 0) { + return `${hours} h ${minutes} min`; + } + if (hours > 0) { + return `${hours} h`; + } + if (minutes > 0) { + return `${minutes} min`; + } + return `${total} sec`; +} + +export function formatDurationRange(min: TDuration, max: TDuration): string { + const minSeconds = durationToSeconds(min); + const maxSeconds = durationToSeconds(max); + const low = Math.min(minSeconds, maxSeconds); + const high = Math.max(minSeconds, maxSeconds); + + if (low === high) { + return formatDurationLabel(low); + } + + return `${formatDurationLabel(low)} - ${formatDurationLabel(high)}`; +} + +export function formatTimerClockRange(min: TDuration, max: TDuration): string { + const minSeconds = durationToSeconds(min); + const maxSeconds = durationToSeconds(max); + const low = Math.min(minSeconds, maxSeconds); + const high = Math.max(minSeconds, maxSeconds); + + if (low === high) { + return formatTimerClock(low); + } + + return `${formatTimerClock(low)} - ${formatTimerClock(high)}`; +} + +function pad2(value: number): string { + return value.toString().padStart(2, '0'); +} diff --git a/apps/kairos/src/features/timer/index.ts b/apps/kairos/src/features/timer/index.ts new file mode 100644 index 0000000..9d24623 --- /dev/null +++ b/apps/kairos/src/features/timer/index.ts @@ -0,0 +1,4 @@ +export * from './components'; +export * from './format'; +export * from './TimerCx'; +export * from './types'; diff --git a/apps/kairos/src/features/timer/types.ts b/apps/kairos/src/features/timer/types.ts new file mode 100644 index 0000000..111ff43 --- /dev/null +++ b/apps/kairos/src/features/timer/types.ts @@ -0,0 +1,5 @@ +export interface TDuration { + h: number; + m: number; + s: number; +} diff --git a/apps/kairos/src/global.css b/apps/kairos/src/global.css new file mode 100644 index 0000000..8c4cec0 --- /dev/null +++ b/apps/kairos/src/global.css @@ -0,0 +1,23 @@ +@import 'tailwindcss/theme.css' layer(theme); +@import 'tailwindcss/preflight.css' layer(base); +@import 'tailwindcss/utilities.css'; + +@import 'nativewind/theme'; + +@theme inline { + --color-base-0: var(--base-0); + --color-base-50: var(--base-50); + --color-base-100: var(--base-100); + --color-base-200: var(--base-200); + --color-base-300: var(--base-300); + --color-base-400: var(--base-400); + --color-base-500: var(--base-500); + --color-base-600: var(--base-600); + --color-base-700: var(--base-700); + --color-base-800: var(--base-800); + --color-base-900: var(--base-900); + --color-base-950: var(--base-950); + --color-primary: var(--primary); + --color-warning: var(--warning); + --color-danger: var(--danger); +} diff --git a/apps/kairos/src/hooks/index.ts b/apps/kairos/src/hooks/index.ts new file mode 100644 index 0000000..3b6a7d2 --- /dev/null +++ b/apps/kairos/src/hooks/index.ts @@ -0,0 +1 @@ +export * from './use-memo-cleanup'; diff --git a/apps/kairos/src/hooks/use-memo-cleanup.ts b/apps/kairos/src/hooks/use-memo-cleanup.ts new file mode 100644 index 0000000..4b235f3 --- /dev/null +++ b/apps/kairos/src/hooks/use-memo-cleanup.ts @@ -0,0 +1,36 @@ +import React from 'react'; + +/** + * A version of useMemo that runs cleanup when deps change or the component unmounts. + * + * @example + * ```ts + * const editor = useMemoCleanup(() => { + * const content = createState(initialValue); + * const unlisten = content.listen(() => {}); + * return [{ content }, unlisten]; + * }, [initialValue]); + * ``` + */ +export function useMemoCleanup( + factory: () => [T, () => void], + deps: React.DependencyList = [] +): T { + const cleanupRef = React.useRef<(() => void) | null>(null); + + const value = React.useMemo(() => { + // Clean up previous value when deps change before creating the new one + cleanupRef.current?.(); + const [returned, cleanup] = factory(); + cleanupRef.current = cleanup; + return returned; + }, deps); + + // Clean up on unmount + // Note: Not nulled so React Strict Mode's fake unmount doesn't prevent real cleanup + React.useEffect(() => { + return () => cleanupRef.current?.(); + }, []); + + return value; +} diff --git a/apps/kairos/src/lib/cn.ts b/apps/kairos/src/lib/cn.ts new file mode 100644 index 0000000..7637fb9 --- /dev/null +++ b/apps/kairos/src/lib/cn.ts @@ -0,0 +1,6 @@ +import { clsx, type ClassValue } from 'clsx'; +import { twMerge } from 'tailwind-merge'; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} diff --git a/apps/kairos/src/lib/color.ts b/apps/kairos/src/lib/color.ts new file mode 100644 index 0000000..df021d5 --- /dev/null +++ b/apps/kairos/src/lib/color.ts @@ -0,0 +1,14 @@ +export function hexToRgba(hexColor: string, alpha: number): string { + const hex = hexColor.replace('#', ''); + const hasValidHexLength = hex.length === 6; + + if (!hasValidHexLength) { + return hexColor; + } + + const red = Number.parseInt(hex.slice(0, 2), 16); + const green = Number.parseInt(hex.slice(2, 4), 16); + const blue = Number.parseInt(hex.slice(4, 6), 16); + + return `rgba(${red}, ${green}, ${blue}, ${alpha})`; +} diff --git a/apps/kairos/src/lib/index.ts b/apps/kairos/src/lib/index.ts new file mode 100644 index 0000000..11136d0 --- /dev/null +++ b/apps/kairos/src/lib/index.ts @@ -0,0 +1,3 @@ +export * from './cn'; +export * from './color'; +export * from './with-async-storage'; diff --git a/apps/kairos/src/lib/with-async-storage.ts b/apps/kairos/src/lib/with-async-storage.ts new file mode 100644 index 0000000..77bf008 --- /dev/null +++ b/apps/kairos/src/lib/with-async-storage.ts @@ -0,0 +1,47 @@ +import { type TEnforceFeatureConstraint, type TFeatureDefinition } from '@blgc/types/features'; +import AsyncStorage from '@react-native-async-storage/async-storage'; +import { + FAILED_TO_LOAD_FROM_STORAGE_IDENTIFIER, + withStorage, + type TPersistFeature, + type TState, + type TStorageInterface +} from 'feature-state'; + +export function withAsyncStorage( + baseState: TEnforceFeatureConstraint, TState, []>, + key: string +): TState { + return withStorage(baseState, new AsyncStorageInterface(), key); +} + +class AsyncStorageInterface implements TStorageInterface { + async save(key: string, value: GStorageValue): Promise { + try { + await AsyncStorage.setItem(key, JSON.stringify(value)); + return true; + } catch { + return false; + } + } + + async load(key: string): Promise { + try { + const raw = await AsyncStorage.getItem(key); + return raw != null + ? (JSON.parse(raw) as GStorageValue) + : FAILED_TO_LOAD_FROM_STORAGE_IDENTIFIER; + } catch { + return FAILED_TO_LOAD_FROM_STORAGE_IDENTIFIER; + } + } + + async delete(key: string): Promise { + try { + await AsyncStorage.removeItem(key); + return true; + } catch { + return false; + } + } +} diff --git a/apps/kairos/tsconfig.json b/apps/kairos/tsconfig.json new file mode 100644 index 0000000..16aa86f --- /dev/null +++ b/apps/kairos/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "expo/tsconfig.base", + "compilerOptions": { + "strict": true, + "paths": { + "@/*": ["./src/*"], + "@/assets/*": ["./assets/*"] + } + }, + "include": ["**/*.ts", "**/*.tsx", ".expo/types/**/*.ts", "expo-env.d.ts", "nativewind-env.d.ts"] +} diff --git a/docs/good-to-know/expo.md b/docs/good-to-know/expo.md new file mode 100644 index 0000000..0809415 --- /dev/null +++ b/docs/good-to-know/expo.md @@ -0,0 +1,43 @@ +# Expo + +## Expo UI Custom Views Must Be Wrapped in `Host` + +Expo UI components (including custom Expo UI native views) must be rendered inside ``. + +**Symptom** + +- App crashes without any error when the Expo UI view renders. + +**Fix** + +- Wrap the part of the tree using Expo UI in ``. + +Example: + +```tsx +import { Host } from '@expo/ui/swift-ui'; + +export function Screen() { + return {/* Expo UI components + custom Expo UI native views */}; +} +``` + +## Developing Local Expo Modules in Xcode + +- https://www.youtube.com/watch?v=zReFsPgUdMs + +### Workflow + +1. Open the iOS project in Xcode from app root: + - `cd apps/kairos` + - `xed ios` +2. In Xcode, open the `Pods` project in the left sidebar. +3. Expand `Development Pods`. +4. Find your local module pod (for example `WheelPickerUi`, `TimePicker`, etc.). +5. Edit native files there and build/run from Xcode or `npx expo run:ios`. + +`Development Pods` maps to your local module source, so edits there update your module files. + +After module file structure changes, run: + +- `cd apps/kairos/ios && pod install` diff --git a/package.json b/package.json index 26046a6..b3810e6 100644 --- a/package.json +++ b/package.json @@ -36,8 +36,15 @@ "vite": "^7.3.1", "vitest": "^4.0.18" }, - "packageManager": "pnpm@10.20.0", + "packageManager": "pnpm@10.30.3", "engines": { "node": ">=24" + }, + "pnpm": { + "overrides": { + "lightningcss": "1.30.1", + "react": "19.2.4", + "react-dom": "19.2.4" + } } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..365ad63 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,15899 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +overrides: + lightningcss: 1.30.1 + react: 19.2.4 + react-dom: 19.2.4 + +importers: + + .: + devDependencies: + '@blgc/config': + specifier: ^0.0.40 + version: 0.0.40(eslint@9.39.3(jiti@2.6.1))(postcss@8.5.6)(prettier@3.8.1)(turbo@2.8.11)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + eslint: + specifier: ^9.39.2 + version: 9.39.3(jiti@2.6.1) + prettier: + specifier: ^3.8.1 + version: 3.8.1 + rollup: + specifier: ^4.57.1 + version: 4.59.0 + rollup-presets: + specifier: ^0.0.26 + version: 0.0.26(esbuild@0.27.3)(rollup@4.59.0)(typescript@5.9.3) + shx: + specifier: ^0.4.0 + version: 0.4.0 + tsx: + specifier: ^4.21.0 + version: 4.21.0 + turbo: + specifier: ^2.8.3 + version: 2.8.11 + typescript: + specifier: ^5.9.3 + version: 5.9.3 + vite: + specifier: ^7.3.1 + version: 7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vitest: + specifier: ^4.0.18 + version: 4.0.18(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + + apps/gazegames: + dependencies: + '@react-router/fs-routes': + specifier: ^7.13.0 + version: 7.13.1(@react-router/dev@7.13.1(@react-router/serve@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2))(typescript@5.9.3) + '@react-router/node': + specifier: ^7.13.0 + version: 7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) + '@react-router/serve': + specifier: ^7.13.0 + version: 7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) + '@vercel/analytics': + specifier: ^1.6.1 + version: 1.6.1(react@19.2.4) + '@vercel/react-router': + specifier: ^1.2.5 + version: 1.2.5(@react-router/dev@7.13.1(@react-router/serve@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2))(@react-router/node@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(isbot@5.1.35)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + clsx: + specifier: ^2.1.1 + version: 2.1.1 + ecsify: + specifier: ^0.0.15 + version: 0.0.15 + feature-react: + specifier: ^0.0.67 + version: 0.0.67(react@19.2.4) + feature-state: + specifier: ^0.0.65 + version: 0.0.65 + hono: + specifier: ^4.11.7 + version: 4.12.3 + isbot: + specifier: ^5.1.34 + version: 5.1.35 + lucide-react: + specifier: ^0.563.0 + version: 0.563.0(react@19.2.4) + react: + specifier: 19.2.4 + version: 19.2.4 + react-dom: + specifier: 19.2.4 + version: 19.2.4(react@19.2.4) + react-router: + specifier: ^7.13.0 + version: 7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react-router-hono-server: + specifier: ^2.24.0 + version: 2.25.0(@hono/node-server@1.19.9(hono@4.12.3))(@react-router/dev@7.13.1(@react-router/serve@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2))(@types/react@19.2.14)(hono@4.12.3)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + replicate: + specifier: ^1.4.0 + version: 1.4.0 + sharp: + specifier: ^0.34.5 + version: 0.34.5 + tailwind-merge: + specifier: ^3.4.0 + version: 3.5.0 + tuple-result: + specifier: ^0.0.11 + version: 0.0.11 + zod: + specifier: ^4.3.6 + version: 4.3.6 + devDependencies: + '@mdx-js/rollup': + specifier: ^3.1.1 + version: 3.1.1(rollup@4.59.0) + '@react-router/dev': + specifier: ^7.13.0 + version: 7.13.1(@react-router/serve@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2) + '@tailwindcss/typography': + specifier: ^0.5.19 + version: 0.5.19(tailwindcss@4.2.1) + '@tailwindcss/vite': + specifier: ^4.1.18 + version: 4.2.1(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@types/mdx': + specifier: ^2.0.13 + version: 2.0.13 + '@types/node': + specifier: ^25.2.1 + version: 25.3.2 + '@types/react': + specifier: ^19.2.13 + version: 19.2.14 + '@types/react-dom': + specifier: ^19.2.3 + version: 19.2.3(@types/react@19.2.14) + daisyui: + specifier: ^5.5.18 + version: 5.5.19 + tailwindcss: + specifier: ^4.1.18 + version: 4.2.1 + vite-tsconfig-paths: + specifier: ^6.0.5 + version: 6.1.1(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + + apps/kairos: + dependencies: + '@expo/ui': + specifier: 55.0.1 + version: 55.0.1(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + '@expo/vector-icons': + specifier: ^15.0.2 + version: 15.1.1(expo-font@55.0.4)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + '@react-native-async-storage/async-storage': + specifier: ^3.0.1 + version: 3.0.1(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + '@react-navigation/bottom-tabs': + specifier: ^7.7.3 + version: 7.15.2(@react-navigation/native@7.1.31(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native-safe-area-context@5.6.2(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native-screens@4.23.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + '@react-navigation/elements': + specifier: ^2.8.1 + version: 2.9.8(@react-navigation/native@7.1.31(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native-safe-area-context@5.6.2(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + '@react-navigation/native': + specifier: ^7.1.28 + version: 7.1.31(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + clsx: + specifier: ^2.1.1 + version: 2.1.1 + expo: + specifier: ~55.0.3 + version: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + expo-constants: + specifier: ~55.0.7 + version: 55.0.7(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(typescript@5.9.3) + expo-dev-client: + specifier: ~55.0.10 + version: 55.0.10(expo@55.0.3)(typescript@5.9.3) + expo-device: + specifier: ~55.0.9 + version: 55.0.9(expo@55.0.3) + expo-font: + specifier: ~55.0.4 + version: 55.0.4(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + expo-glass-effect: + specifier: ~55.0.7 + version: 55.0.7(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + expo-haptics: + specifier: ~15.0.8 + version: 15.0.8(expo@55.0.3) + expo-image: + specifier: ~55.0.5 + version: 55.0.5(expo@55.0.3)(react-native-web@0.21.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + expo-linking: + specifier: ~55.0.7 + version: 55.0.7(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + expo-router: + specifier: ~55.0.3 + version: 55.0.3(715e0706cc640a8619e3400aac055546) + expo-splash-screen: + specifier: ~55.0.10 + version: 55.0.10(expo@55.0.3)(typescript@5.9.3) + expo-status-bar: + specifier: ~55.0.4 + version: 55.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + expo-symbols: + specifier: ~55.0.4 + version: 55.0.4(expo-font@55.0.4)(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + expo-system-ui: + specifier: ~55.0.9 + version: 55.0.9(expo@55.0.3)(react-native-web@0.21.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4)) + expo-web-browser: + specifier: ~55.0.9 + version: 55.0.9(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4)) + feature-react: + specifier: ^0.0.67 + version: 0.0.67(react@19.2.4) + feature-state: + specifier: ^0.0.65 + version: 0.0.65 + nativewind: + specifier: 5.0.0-preview.2 + version: 5.0.0-preview.2(react-native-css@3.0.4(@expo/metro-config@55.0.9(expo@55.0.3)(typescript@5.9.3))(lightningcss@1.30.1)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(tailwindcss@4.2.1) + react: + specifier: 19.2.4 + version: 19.2.4 + react-dom: + specifier: 19.2.4 + version: 19.2.4(react@19.2.4) + react-native: + specifier: 0.83.2 + version: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + react-native-css: + specifier: ^3.0.4 + version: 3.0.4(@expo/metro-config@55.0.9(expo@55.0.3)(typescript@5.9.3))(lightningcss@1.30.1)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + react-native-gesture-handler: + specifier: ~2.30.0 + version: 2.30.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + react-native-reanimated: + specifier: 4.2.1 + version: 4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + react-native-safe-area-context: + specifier: ~5.6.2 + version: 5.6.2(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + react-native-screens: + specifier: ~4.23.0 + version: 4.23.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + react-native-svg: + specifier: 15.15.3 + version: 15.15.3(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + react-native-web: + specifier: ~0.21.0 + version: 0.21.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react-native-worklets: + specifier: 0.7.2 + version: 0.7.2(@babel/core@7.29.0)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + tailwind-merge: + specifier: ^3.5.0 + version: 3.5.0 + devDependencies: + '@tailwindcss/postcss': + specifier: ^4.2.1 + version: 4.2.1 + '@types/react': + specifier: ~19.2.2 + version: 19.2.14 + eas-cli: + specifier: ^18.0.6 + version: 18.0.6(@types/node@25.3.2)(typescript@5.9.3) + eslint-config-expo: + specifier: ~55.0.0 + version: 55.0.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + postcss: + specifier: ^8.5.6 + version: 8.5.6 + tailwindcss: + specifier: ^4.2.1 + version: 4.2.1 + + apps/learnlinesfaster: + dependencies: + '@react-router/fs-routes': + specifier: ^7.13.0 + version: 7.13.1(@react-router/dev@7.13.1(@react-router/serve@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2))(typescript@5.9.3) + '@react-router/node': + specifier: ^7.13.0 + version: 7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) + '@react-router/serve': + specifier: ^7.13.0 + version: 7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) + '@vercel/analytics': + specifier: ^1.6.1 + version: 1.6.1(react@19.2.4) + '@vercel/react-router': + specifier: ^1.2.5 + version: 1.2.5(@react-router/dev@7.13.1(@react-router/serve@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2))(@react-router/node@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(isbot@5.1.35)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + clsx: + specifier: ^2.1.1 + version: 2.1.1 + feature-react: + specifier: ^0.0.67 + version: 0.0.67(react@19.2.4) + feature-state: + specifier: ^0.0.65 + version: 0.0.65 + isbot: + specifier: ^5.1.34 + version: 5.1.35 + lucide-react: + specifier: ^0.563.0 + version: 0.563.0(react@19.2.4) + react: + specifier: 19.2.4 + version: 19.2.4 + react-dom: + specifier: 19.2.4 + version: 19.2.4(react@19.2.4) + react-router: + specifier: ^7.13.0 + version: 7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + tailwind-merge: + specifier: ^3.4.0 + version: 3.5.0 + devDependencies: + '@mdx-js/rollup': + specifier: ^3.1.1 + version: 3.1.1(rollup@4.59.0) + '@react-router/dev': + specifier: ^7.13.0 + version: 7.13.1(@react-router/serve@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2) + '@tailwindcss/typography': + specifier: ^0.5.19 + version: 0.5.19(tailwindcss@4.2.1) + '@tailwindcss/vite': + specifier: ^4.1.18 + version: 4.2.1(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@types/mdx': + specifier: ^2.0.13 + version: 2.0.13 + '@types/react': + specifier: ^19.2.13 + version: 19.2.14 + '@types/react-dom': + specifier: ^19.2.3 + version: 19.2.3(@types/react@19.2.14) + daisyui: + specifier: ^5.5.18 + version: 5.5.19 + tailwindcss: + specifier: ^4.1.18 + version: 4.2.1 + vite-tsconfig-paths: + specifier: ^6.0.5 + version: 6.1.1(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + +packages: + + '@0no-co/graphql.web@1.2.0': + resolution: {integrity: sha512-/1iHy9TTr63gE1YcR5idjx8UREz1s0kFhydf3bBLCXyqjhkIc6igAzTOx3zPifCwFR87tsh/4Pa9cNts6d2otw==} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 + peerDependenciesMeta: + graphql: + optional: true + + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + + '@babel/code-frame@7.10.4': + resolution: {integrity: sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==} + + '@babel/code-frame@7.23.5': + resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} + engines: {node: '>=6.9.0'} + + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.29.0': + resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.28.6': + resolution: {integrity: sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-create-regexp-features-plugin@7.28.5': + resolution: {integrity: sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-define-polyfill-provider@0.6.6': + resolution: {integrity: sha512-mOAsxeeKkUKayvZR3HeTYD/fICpCPLJrU5ZjelT/PA6WHtNDBOE436YiaEUvHN454bRM3CebhDsIpieCc4texA==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.28.5': + resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.28.6': + resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} + engines: {node: '>=6.9.0'} + + '@babel/helper-remap-async-to-generator@7.27.1': + resolution: {integrity: sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-replace-supers@7.28.6': + resolution: {integrity: sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-wrap-function@7.28.6': + resolution: {integrity: sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.28.6': + resolution: {integrity: sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==} + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.25.9': + resolution: {integrity: sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.0': + resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-proposal-decorators@7.29.0': + resolution: {integrity: sha512-CVBVv3VY/XRMxRYq5dwr2DS7/MvqPm23cOCjbwNnVrfOqcWlnefua1uUs0sjdKOGjvPUG633o07uWzJq4oI6dA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-export-default-from@7.27.1': + resolution: {integrity: sha512-hjlsMBl1aJc5lp8MoCDEZCiYzlgdRAShOjAfRw6X+GlpLpUPU7c3XNLsKFZbQk/1cRzBlJ7CXg3xJAJMrFa1Uw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-async-generators@7.8.4': + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-bigint@7.8.3': + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-properties@7.12.13': + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-static-block@7.14.5': + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-decorators@7.28.6': + resolution: {integrity: sha512-71EYI0ONURHJBL4rSFXnITXqXrrY8q4P0q006DPfN+Rk+ASM+++IBXem/ruokgBZR8YNEWZ8R6B+rCb8VcUTqA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-dynamic-import@7.8.3': + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-export-default-from@7.28.6': + resolution: {integrity: sha512-Svlx1fjJFnNz0LZeUaybRukSxZI3KkpApUmIRzEdXC5k8ErTOz0OD0kNrICi5Vc3GlpP5ZCeRyRO+mfWTSz+iQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-flow@7.28.6': + resolution: {integrity: sha512-D+OrJumc9McXNEBI/JmFnc/0uCM2/Y3PEBG3gfV3QIYkKv5pvnpzFrl1kYCrcHJP8nOeFB/SHi1IHz29pNGuew==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.28.6': + resolution: {integrity: sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-meta@7.10.4': + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-json-strings@7.8.3': + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.28.6': + resolution: {integrity: sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4': + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-numeric-separator@7.10.4': + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-object-rest-spread@7.8.3': + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3': + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-chaining@7.8.3': + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-private-property-in-object@7.14.5': + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-top-level-await@7.14.5': + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.28.6': + resolution: {integrity: sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-arrow-functions@7.27.1': + resolution: {integrity: sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-async-generator-functions@7.29.0': + resolution: {integrity: sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-async-to-generator@7.28.6': + resolution: {integrity: sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoping@7.28.6': + resolution: {integrity: sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-class-properties@7.27.1': + resolution: {integrity: sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-class-properties@7.28.6': + resolution: {integrity: sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-class-static-block@7.28.6': + resolution: {integrity: sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + + '@babel/plugin-transform-classes@7.28.4': + resolution: {integrity: sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-classes@7.28.6': + resolution: {integrity: sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-computed-properties@7.28.6': + resolution: {integrity: sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-destructuring@7.28.5': + resolution: {integrity: sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-export-namespace-from@7.27.1': + resolution: {integrity: sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-flow-strip-types@7.27.1': + resolution: {integrity: sha512-G5eDKsu50udECw7DL2AcsysXiQyB7Nfg521t2OAJ4tbfTJ27doHLeF/vlI1NZGlLdbb/v+ibvtL1YBQqYOwJGg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-for-of@7.27.1': + resolution: {integrity: sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-function-name@7.27.1': + resolution: {integrity: sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-literals@7.27.1': + resolution: {integrity: sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-logical-assignment-operators@7.28.6': + resolution: {integrity: sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-commonjs@7.28.6': + resolution: {integrity: sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-named-capturing-groups-regex@7.29.0': + resolution: {integrity: sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-nullish-coalescing-operator@7.27.1': + resolution: {integrity: sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-nullish-coalescing-operator@7.28.6': + resolution: {integrity: sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-numeric-separator@7.28.6': + resolution: {integrity: sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-object-rest-spread@7.28.6': + resolution: {integrity: sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-optional-catch-binding@7.28.6': + resolution: {integrity: sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-optional-chaining@7.27.1': + resolution: {integrity: sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-optional-chaining@7.28.6': + resolution: {integrity: sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-parameters@7.27.7': + resolution: {integrity: sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-private-methods@7.28.6': + resolution: {integrity: sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-private-property-in-object@7.28.6': + resolution: {integrity: sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-display-name@7.28.0': + resolution: {integrity: sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-development@7.27.1': + resolution: {integrity: sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-self@7.27.1': + resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-source@7.27.1': + resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx@7.28.6': + resolution: {integrity: sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-pure-annotations@7.27.1': + resolution: {integrity: sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-regenerator@7.29.0': + resolution: {integrity: sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-runtime@7.29.0': + resolution: {integrity: sha512-jlaRT5dJtMaMCV6fAuLbsQMSwz/QkvaHOHOSXRitGGwSpR1blCY4KUKoyP2tYO8vJcqYe8cEj96cqSztv3uF9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-shorthand-properties@7.27.1': + resolution: {integrity: sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-spread@7.28.6': + resolution: {integrity: sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-sticky-regex@7.27.1': + resolution: {integrity: sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-template-literals@7.27.1': + resolution: {integrity: sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.28.6': + resolution: {integrity: sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-regex@7.27.1': + resolution: {integrity: sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-react@7.28.5': + resolution: {integrity: sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-typescript@7.27.1': + resolution: {integrity: sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-typescript@7.28.5': + resolution: {integrity: sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.28.6': + resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} + + '@blgc/config@0.0.40': + resolution: {integrity: sha512-rE7loAwEbd1gPKvQKOOfRlxQOVHDFX3jABFcxWixQ+npAHvLh6J6/AU83UAaA9Ilq87Y1/nE0xM9yzFlnw/nsw==} + + '@blgc/types@0.0.21': + resolution: {integrity: sha512-mKy5l2EYVT8+O8CqTKv9Q/cA8CLfzdSnRpeGOZYsZga355oq0WXVciIV35z2xY2Tvo4pp1YKWochHpQCbJa4Yg==} + + '@blgc/utils@0.0.61': + resolution: {integrity: sha512-bCN4W/1oQgyz2S4mYUp1ZUXJJGm9w7NYjnW3Jq/toWiM6AtM47B1ygsBrtPVNEa/v2U0B8ykMB6ohY2pp+bnwg==} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@drizzle-team/brocli@0.11.0': + resolution: {integrity: sha512-hD3pekGiPg0WPCCGAZmusBBJsDqGUR66Y452YgQsZOnkdQ7ViEPKuyP4huUGEZQefp8g34RRodXYmJ2TbCH+tg==} + + '@egjs/hammerjs@2.0.17': + resolution: {integrity: sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==} + engines: {node: '>=0.8.0'} + + '@emnapi/core@1.8.1': + resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==} + + '@emnapi/runtime@1.8.1': + resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} + + '@emnapi/wasi-threads@1.1.0': + resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} + + '@esbuild/aix-ppc64@0.27.3': + resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.27.3': + resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.27.3': + resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.27.3': + resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.27.3': + resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.3': + resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.27.3': + resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.3': + resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.27.3': + resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.27.3': + resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.27.3': + resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.27.3': + resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.27.3': + resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.27.3': + resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.3': + resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.27.3': + resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.27.3': + resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.27.3': + resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.3': + resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.27.3': + resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.3': + resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.3': + resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.27.3': + resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.27.3': + resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.27.3': + resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.27.3': + resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.21.1': + resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.4': + resolution: {integrity: sha512-4h4MVF8pmBsncB60r0wSJiIeUKTSD4m7FmTFThG8RHlsg9ajqckLm9OraguFGZE4vVdpiI1Q4+hFnisopmG6gQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.39.3': + resolution: {integrity: sha512-1B1VkCq6FuUNlQvlBYb+1jDu/gV297TIs/OeiaSR9l1H27SVW55ONE1e1Vp16NqP683+xEGzxYtv4XCiDPaQiw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@expo-google-fonts/material-symbols@0.4.24': + resolution: {integrity: sha512-1bJ63Yv2Bn8SN2MjrlbwLwUhnC8COOeejd15H88WjCtw5iNErqEPaBnpvmYyqciVYwudGo5drUIdY9C/5yPGbg==} + + '@expo/apple-utils@2.1.13': + resolution: {integrity: sha512-nt3efiJhAWTHl9ikKYrHEuv3dhqCdicsHFRE9LmvtcVsPhXl9bAsm0gbACoLPr7ClP8664H/S6SdVJOD/tw0jg==} + hasBin: true + + '@expo/bunyan@4.0.1': + resolution: {integrity: sha512-+Lla7nYSiHZirgK+U/uYzsLv/X+HaJienbD5AKX1UQZHYfWaP+9uuQluRB4GrEVWF0GZ7vEVp/jzaOT9k/SQlg==} + engines: {'0': node >=0.10.0} + + '@expo/cli@55.0.13': + resolution: {integrity: sha512-9yFC2IYCFXoTSV4FScpkh6s14F5sKMfu2BXEZj2Z8P7d4O0gvd+Ee7HR4UqL+1Sb1p5B4SbniDBBPGjp5oGDNQ==} + hasBin: true + peerDependencies: + expo: '*' + expo-router: '*' + react-native: '*' + peerDependenciesMeta: + expo-router: + optional: true + react-native: + optional: true + + '@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@55.0.6': + resolution: {integrity: sha512-cIox6FjZlFaaX40rbQ3DvP9e87S5X85H9uw+BAxJE5timkMhuByy3GAlOsj1h96EyzSiol7Q6YIGgY1Jiz4M+A==} + + '@expo/config-plugins@9.0.12': + resolution: {integrity: sha512-/Ko/NM+GzvJyRkq8PITm8ms0KY5v0wmN1OQFYRMkcJqOi3PjlhndW+G6bHpJI9mkQXBaUnHwAiGLqIC3+MQ5Wg==} + + '@expo/config-types@52.0.5': + resolution: {integrity: sha512-AMDeuDLHXXqd8W+0zSjIt7f37vUd/BP8p43k68NHpyAvQO+z8mbQZm3cNQVAMySeayK2XoPigAFB1JF2NFajaA==} + + '@expo/config-types@55.0.5': + resolution: {integrity: sha512-sCmSUZG4mZ/ySXvfyyBdhjivz8Q539X1NondwDdYG7s3SBsk+wsgPJzYsqgAG/P9+l0xWjUD2F+kQ1cAJ6NNLg==} + + '@expo/config@10.0.6': + resolution: {integrity: sha512-xXkfPElrtxznkOZxFASJ7OPa6E9IHSjcZwj5BQ6XUF2dz5M7AFa2h5sXM8AalSaDU5tEBSgoUOjTh5957TlR8g==} + + '@expo/config@55.0.8': + resolution: {integrity: sha512-D7RYYHfErCgEllGxNwdYdkgzLna7zkzUECBV3snbUpf7RvIpB5l1LpCgzuVoc5KVew5h7N1Tn4LnT/tBSUZsQg==} + + '@expo/devcert@1.2.1': + resolution: {integrity: sha512-qC4eaxmKMTmJC2ahwyui6ud8f3W60Ss7pMkpBq40Hu3zyiAaugPXnZ24145U7K36qO9UHdZUVxsCvIpz2RYYCA==} + + '@expo/devtools@55.0.2': + resolution: {integrity: sha512-4VsFn9MUriocyuhyA+ycJP3TJhUsOFHDc270l9h3LhNpXMf6wvIdGcA0QzXkZtORXmlDybWXRP2KT1k36HcQkA==} + peerDependencies: + react: 19.2.4 + react-native: '*' + peerDependenciesMeta: + react: + optional: true + react-native: + optional: true + + '@expo/dom-webview@55.0.3': + resolution: {integrity: sha512-bY4/rfcZ0f43DvOtMn8/kmPlmo01tex5hRoc5hKbwBwQjqWQuQt0ACwu7akR9IHI4j0WNG48eL6cZB6dZUFrzg==} + peerDependencies: + expo: '*' + react: 19.2.4 + react-native: '*' + + '@expo/eas-build-job@18.0.2': + resolution: {integrity: sha512-RPlsDYAiKn1fBfxvlvXNSAnwc3KbcBb4lM7tcsDntpTu9CqMIlOB5YRkmKeAH7lbiuXj0xtDM0sEZHouUCKVDA==} + + '@expo/eas-json@18.0.2': + resolution: {integrity: sha512-GOPpnjgXLwuYofDB5QmLO/+7e6UEHa8h1iBABjU/ZhgRA+8nxj/40pJgr69MpuqlvkmK7E8nuLIdgq2OuzZFkA==} + engines: {node: '>=20.0.0'} + + '@expo/env@1.0.7': + resolution: {integrity: sha512-qSTEnwvuYJ3umapO9XJtrb1fAqiPlmUUg78N0IZXXGwQRt+bkp0OBls+Y5Mxw/Owj8waAM0Z3huKKskRADR5ow==} + + '@expo/env@2.1.1': + resolution: {integrity: sha512-rVvHC4I6xlPcg+mAO09ydUi2Wjv1ZytpLmHOSzvXzBAz9mMrJggqCe4s4dubjJvi/Ino/xQCLhbaLCnTtLpikg==} + engines: {node: '>=20.12.0'} + + '@expo/fingerprint@0.16.5': + resolution: {integrity: sha512-mLrcymtgkW9IJ/G1e8MH1Xt2VIb1MOS86ePY0ePcnV3nVyJqm7gfa/AXD1Hk+eZXvf8XhioYz6QZaamBdEzR3A==} + hasBin: true + + '@expo/image-utils@0.6.5': + resolution: {integrity: sha512-RsS/1CwJYzccvlprYktD42KjyfWZECH6PPIEowvoSmXfGLfdViwcUEI4RvBfKX5Jli6P67H+6YmHvPTbGOboew==} + + '@expo/image-utils@0.8.12': + resolution: {integrity: sha512-3KguH7kyKqq7pNwLb9j6BBdD/bjmNwXZG/HPWT6GWIXbwrvAJt2JNyYTP5agWJ8jbbuys1yuCzmkX+TU6rmI7A==} + + '@expo/json-file@10.0.12': + resolution: {integrity: sha512-inbDycp1rMAelAofg7h/mMzIe+Owx6F7pur3XdQ3EPTy00tme+4P6FWgHKUcjN8dBSrnbRNpSyh5/shzHyVCyQ==} + + '@expo/json-file@8.3.3': + resolution: {integrity: sha512-eZ5dld9AD0PrVRiIWpRkm5aIoWBw3kAyd8VkuWEy92sEthBKDDDHAnK2a0dw0Eil6j7rK7lS/Qaq/Zzngv2h5A==} + + '@expo/json-file@9.0.2': + resolution: {integrity: sha512-yAznIUrybOIWp3Uax7yRflB0xsEpvIwIEqIjao9SGi2Gaa+N0OamWfe0fnXBSWF+2zzF4VvqwT4W5zwelchfgw==} + + '@expo/json-file@9.1.5': + resolution: {integrity: sha512-prWBhLUlmcQtvN6Y7BpW2k9zXGd3ySa3R6rAguMJkp1z22nunLN64KYTUWfijFlprFoxm9r2VNnGkcbndAlgKA==} + + '@expo/local-build-cache-provider@55.0.6': + resolution: {integrity: sha512-4kfdv48sKzokijMqi07fINYA9/XprshmPgSLf8i69XgzIv2YdRyBbb70SzrufB7PDneFoltz8N83icW8gOOj1g==} + + '@expo/log-box@55.0.7': + resolution: {integrity: sha512-m7V1k2vlMp4NOj3fopjOg4zl/ANXyTRF3HMTMep2GZAKsPiDzgOQ41nm8CaU50/HlDIGXlCObss07gOn20UpHQ==} + peerDependencies: + '@expo/dom-webview': ^55.0.3 + expo: '*' + react: 19.2.4 + react-native: '*' + + '@expo/logger@18.0.1': + resolution: {integrity: sha512-+EP6VDpQCO7fOxnvlFhu9ravVxpSDuEYipgL8q9XhoOIo1BAm5UZSelat46RYHT97mmYKA26kVnqHJpUB+f2eg==} + + '@expo/metro-config@55.0.9': + resolution: {integrity: sha512-ZJFEfat/+dLUhFyFFWrzMjAqAwwUaJ3RD42QNqR7jh+RVYkAf6XYLynb5qrKJTHI1EcOx4KoO1717yXYYRFDBA==} + peerDependencies: + expo: '*' + peerDependenciesMeta: + expo: + optional: true + + '@expo/metro-runtime@55.0.6': + resolution: {integrity: sha512-l8VvgKN9md+URjeQDB+DnHVmvpcWI6zFLH6yv7GTv4sfRDKyaZ5zDXYjTP1phYdgW6ea2NrRtCGNIxylWhsgtg==} + peerDependencies: + expo: '*' + react: 19.2.4 + react-dom: 19.2.4 + react-native: '*' + peerDependenciesMeta: + react-dom: + optional: true + + '@expo/metro@54.2.0': + resolution: {integrity: sha512-h68TNZPGsk6swMmLm9nRSnE2UXm48rWwgcbtAHVMikXvbxdS41NDHHeqg1rcQ9AbznDRp6SQVC2MVpDnsRKU1w==} + + '@expo/multipart-body-parser@2.0.0': + resolution: {integrity: sha512-yS/wsqlj0d8ZKETEN7ro3dZtjdMhpte8wp+xUzjUQC3jizxcE0E62xgvGquJObiYUMGoCF5qRYr2t78STPEaSw==} + + '@expo/osascript@2.1.4': + resolution: {integrity: sha512-LcPjxJ5FOFpqPORm+5MRLV0CuYWMthJYV6eerF+lQVXKlvgSn3EOqaHC3Vf3H+vmB0f6G4kdvvFtg40vG4bIhA==} + engines: {node: '>=12'} + + '@expo/osascript@2.4.2': + resolution: {integrity: sha512-/XP7PSYF2hzOZzqfjgkoWtllyeTN8dW3aM4P6YgKcmmPikKL5FdoyQhti4eh6RK5a5VrUXJTOlTNIpIHsfB5Iw==} + engines: {node: '>=12'} + + '@expo/package-manager@1.10.3': + resolution: {integrity: sha512-ZuXiK/9fCrIuLjPSe1VYmfp0Sa85kCMwd8QQpgyi5ufppYKRtLBg14QOgUqj8ZMbJTxE0xqzd0XR7kOs3vAK9A==} + + '@expo/package-manager@1.9.10': + resolution: {integrity: sha512-axJm+NOj3jVxep49va/+L3KkF3YW/dkV+RwzqUJedZrv4LeTqOG4rhrCaCPXHTvLqCTDKu6j0Xyd28N7mnxsGA==} + + '@expo/pkcs12@0.1.3': + resolution: {integrity: sha512-96MePEGppKi08vawrTPw8kMCRdsbrDbV900MlI8rrP9F57DfDl/y1P52bwIDBYCEHE3XtPMo7s1xkG0BKOLCVg==} + + '@expo/plist@0.2.0': + resolution: {integrity: sha512-F/IZJQaf8OIVnVA6XWUeMPC3OH6MV00Wxf0WC0JhTQht2QgjyHUa3U5Gs3vRtDq8tXNsZneOQRDVwpaOnd4zTQ==} + + '@expo/plist@0.5.2': + resolution: {integrity: sha512-o4xdVdBpe4aTl3sPMZ2u3fJH4iG1I768EIRk1xRZP+GaFI93MaR3JvoFibYqxeTmLQ1p1kNEVqylfUjezxx45g==} + + '@expo/plugin-help@5.1.23': + resolution: {integrity: sha512-s0uH6cPplLj73ZVie40EYUhl7X7q9kRR+8IfZWDod3wUtVGOFInxuCPX9Jpv1UwwBgbRu2cLisqr8m45LrFgxw==} + engines: {node: '>=12.0.0'} + + '@expo/plugin-warn-if-update-available@2.5.1': + resolution: {integrity: sha512-B65QSIZ+TgFHnVXsTw+1Q6djsJByWwnIjYfoG8ZV9wizOC01gbAw1cOZ/YtrJ2BrDnzFQtM8qecjlmZ7C3MPLw==} + engines: {node: '>=12.0.0'} + + '@expo/prebuild-config@55.0.8': + resolution: {integrity: sha512-VJNJiOmmZgyDnR7JMmc3B8Z0ZepZ17I8Wtw+wAH/2+UCUsFg588XU+bwgYcFGw+is28kwGjY46z43kfufpxOnA==} + peerDependencies: + expo: '*' + + '@expo/prebuild-config@8.0.17': + resolution: {integrity: sha512-HM+XpDox3fAZuXZXvy55VRcBbsZSDijGf8jI8i/pexgWvtsnt1ouelPXRuE1pXDicMX+lZO83QV+XkyLmBEXYQ==} + + '@expo/require-utils@55.0.2': + resolution: {integrity: sha512-dV5oCShQ1umKBKagMMT4B/N+SREsQe3lU4Zgmko5AO0rxKV0tynZT6xXs+e2JxuqT4Rz997atg7pki0BnZb4uw==} + peerDependencies: + typescript: ^5.0.0 || ^5.0.0-0 + peerDependenciesMeta: + typescript: + optional: true + + '@expo/results@1.0.0': + resolution: {integrity: sha512-qECzzXX5oJot3m2Gu9pfRDz50USdBieQVwYAzeAtQRUTD3PVeTK1tlRUoDcrK8PSruDLuVYdKkLebX4w/o55VA==} + engines: {node: '>=10'} + + '@expo/router-server@55.0.9': + resolution: {integrity: sha512-LcCFi+P1qfZOsw0DO4JwNKRxtWt4u2bjTYj0PUe4WVf9NVG/NfUetAXYRbBS6P+gupfM6SC+/bdzdqCWQh7j8g==} + peerDependencies: + '@expo/metro-runtime': ^55.0.6 + expo: '*' + expo-constants: ^55.0.7 + expo-font: ^55.0.4 + expo-router: '*' + expo-server: ^55.0.6 + react: 19.2.4 + react-dom: 19.2.4 + 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 + + '@expo/rudder-sdk-node@1.1.1': + resolution: {integrity: sha512-uy/hS/awclDJ1S88w9UGpc6Nm9XnNUjzOAAib1A3PVAnGQIwebg8DpFqOthFBTlZxeuV/BKbZ5jmTbtNZkp1WQ==} + engines: {node: '>=12'} + + '@expo/schema-utils@55.0.2': + resolution: {integrity: sha512-QZ5WKbJOWkCrMq0/kfhV9ry8te/OaS34YgLVpG8u9y2gix96TlpRTbxM/YATjNcUR2s4fiQmPCOxkGtog4i37g==} + + '@expo/sdk-runtime-versions@1.0.0': + resolution: {integrity: sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ==} + + '@expo/spawn-async@1.7.2': + resolution: {integrity: sha512-QdWi16+CHB9JYP7gma19OVVg0BFkvU8zNj9GjWorYI8Iv8FUxjOCcYRuAmX4s/h91e4e7BPsskc8cSrZYho9Ew==} + engines: {node: '>=12'} + + '@expo/steps@18.0.2': + resolution: {integrity: sha512-RhWJZt5z3wE+9f+vjBJMu37k6C+43/RJpAzENtDnF0SIZIzRmlm0GoCTNMB79pc2V/3qUvmEFbAzTqU0Z63G6g==} + engines: {node: '>=18'} + + '@expo/sudo-prompt@9.3.2': + resolution: {integrity: sha512-HHQigo3rQWKMDzYDLkubN5WQOYXJJE2eNqIQC2axC2iO3mHdwnIR7FgZVvHWtBwAdzBgAP0ECp8KqS8TiMKvgw==} + + '@expo/timeago.js@1.0.0': + resolution: {integrity: sha512-PD45CGlCL8kG0U3YcH1NvYxQThw5XAS7qE9bgP4L7dakm8lsMz+p8BQ1IjBFMmImawVWsV3py6JZINaEebXLnw==} + + '@expo/ui@55.0.1': + resolution: {integrity: sha512-j9UFdW2OaM4+dmk5UYzgwtwioreWJlGQUhBxPUH2/5U4ROS2JPyJo0jtwgM6bfawyYQfobKvp0utVoRQJ3Ul1A==} + peerDependencies: + expo: '*' + react: 19.2.4 + react-native: '*' + + '@expo/vector-icons@15.1.1': + resolution: {integrity: sha512-Iu2VkcoI5vygbtYngm7jb4ifxElNVXQYdDrYkT7UCEIiKLeWnQY0wf2ZhHZ+Wro6Sc5TaumpKUOqDRpLi5rkvw==} + peerDependencies: + expo-font: '>=14.0.4' + react: 19.2.4 + react-native: '*' + + '@expo/ws-tunnel@1.0.6': + resolution: {integrity: sha512-nDRbLmSrJar7abvUjp3smDwH8HcbZcoOEa5jVPUv9/9CajgmWw20JNRwTuBRzWIWIkEJDkz20GoNA+tSwUqk0Q==} + + '@expo/xcpretty@4.4.1': + resolution: {integrity: sha512-KZNxZvnGCtiM2aYYZ6Wz0Ix5r47dAvpNLApFtZWnSoERzAdOMzVBOPysBoM0JlF6FKWZ8GPqgn6qt3dV/8Zlpg==} + hasBin: true + + '@hapi/hoek@9.3.0': + resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} + + '@hapi/topo@5.1.0': + resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==} + + '@hono/node-server@1.19.9': + resolution: {integrity: sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==} + engines: {node: '>=18.14.1'} + peerDependencies: + hono: ^4 + + '@hono/node-ws@1.3.0': + resolution: {integrity: sha512-ju25YbbvLuXdqBCmLZLqnNYu1nbHIQjoyUqA8ApZOeL1k4skuiTcw5SW77/5SUYo2Xi2NVBJoVlfQurnKEp03Q==} + engines: {node: '>=18.14.1'} + peerDependencies: + '@hono/node-server': ^1.19.2 + hono: ^4.6.0 + + '@hono/vite-dev-server@0.25.0': + resolution: {integrity: sha512-4j5rs7yUTOObU2/yCEHeWbf3C8m95SD9lhdUUE6CJ462Emp9vS94yiza2dsA8+ly5pdaIQW0cd4nhNVcwYL5tA==} + engines: {node: '>=18.14.1'} + peerDependencies: + hono: '*' + miniflare: '*' + wrangler: '*' + peerDependenciesMeta: + miniflare: + optional: true + wrangler: + optional: true + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.7': + resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@ianvs/prettier-plugin-sort-imports@4.7.1': + resolution: {integrity: sha512-jmTNYGlg95tlsoG3JLCcuC4BrFELJtLirLAkQW/71lXSyOhVt/Xj7xWbbGcuVbNq1gwWgSyMrPjJc9Z30hynVw==} + peerDependencies: + '@prettier/plugin-oxc': ^0.0.4 || ^0.1.0 + '@vue/compiler-sfc': 2.7.x || 3.x + content-tag: ^4.0.0 + prettier: 2 || 3 || ^4.0.0-0 + prettier-plugin-ember-template-tag: ^2.1.0 + peerDependenciesMeta: + '@prettier/plugin-oxc': + optional: true + '@vue/compiler-sfc': + optional: true + content-tag: + optional: true + prettier-plugin-ember-template-tag: + optional: true + + '@img/colour@1.0.0': + resolution: {integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.34.5': + resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.34.5': + resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.2.4': + resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.2.4': + resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.2.4': + resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-arm@1.2.4': + resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-ppc64@1.2.4': + resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-riscv64@1.2.4': + resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-s390x@1.2.4': + resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-x64@1.2.4': + resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-linux-arm64@0.34.5': + resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-arm@0.34.5': + resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-ppc64@0.34.5': + resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-riscv64@0.34.5': + resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-s390x@0.34.5': + resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-x64@0.34.5': + resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-linuxmusl-arm64@0.34.5': + resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-linuxmusl-x64@0.34.5': + resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-wasm32@0.34.5': + resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.34.5': + resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.34.5': + resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.34.5': + resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + + '@isaacs/ttlcache@1.4.1': + resolution: {integrity: sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==} + engines: {node: '>=12'} + + '@istanbuljs/load-nyc-config@1.1.0': + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + + '@jest/create-cache-key-function@29.7.0': + resolution: {integrity: sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/environment@29.7.0': + resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/fake-timers@29.7.0': + resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/transform@29.7.0': + resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/types@29.6.3': + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/source-map@0.3.11': + resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@mdx-js/mdx@3.1.1': + resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} + + '@mdx-js/rollup@3.1.1': + resolution: {integrity: sha512-v8satFmBB+DqDzYohnm1u2JOvxx6Hl3pUvqzJvfs2Zk/ngZ1aRUhsWpXvwPkNeGN9c2NCm/38H29ZqXQUjf8dw==} + peerDependencies: + rollup: '>=2' + + '@mjackson/node-fetch-server@0.2.0': + resolution: {integrity: sha512-EMlH1e30yzmTpGLQjlFmaDAjyOeZhng1/XCd7DExR8PNAnG/G1tyruZxEoUe11ClnwGhGrtsdnyyUx1frSzjng==} + + '@napi-rs/wasm-runtime@0.2.12': + resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} + + '@next/eslint-plugin-next@16.1.6': + resolution: {integrity: sha512-/Qq3PTagA6+nYVfryAtQ7/9FEr/6YVyvOtl6rZnGsbReGLf0jZU6gkpr1FuChAQpvV46a78p4cmHOVP8mbfSMQ==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@nolyfill/is-core-module@1.0.39': + resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} + engines: {node: '>=12.4.0'} + + '@oclif/core@1.26.2': + resolution: {integrity: sha512-6jYuZgXvHfOIc9GIaS4T3CIKGTjPmfAxuMcbCbMRKJJl4aq/4xeRlEz0E8/hz8HxvxZBGvN2GwAUHlrGWQVrVw==} + engines: {node: '>=14.0.0'} + + '@oclif/core@2.16.0': + resolution: {integrity: sha512-dL6atBH0zCZl1A1IXCKJgLPrM/wR7K+Wi401E/IvqsK8m2iCHW+0TEOGrans/cuN3oTW+uxIyJFHJ8Im0k4qBw==} + engines: {node: '>=14.0.0'} + + '@oclif/linewrap@1.0.0': + resolution: {integrity: sha512-Ups2dShK52xXa8w6iBWLgcjPJWjais6KPJQq3gQ/88AY6BXoTX+MIGFPrWQO1KLMiQfoTpcLnUwloN4brrVUHw==} + + '@oclif/plugin-autocomplete@2.3.10': + resolution: {integrity: sha512-Ow1AR8WtjzlyCtiWWPgzMyT8SbcDJFr47009riLioHa+MHX2BCDtVn2DVnN/E6b9JlPV5ptQpjefoRSNWBesmg==} + engines: {node: '>=12.0.0'} + + '@oclif/screen@3.0.8': + resolution: {integrity: sha512-yx6KAqlt3TAHBduS2fMQtJDL2ufIHnDRArrJEOoTTuizxqmjLT+psGYOHpmMl3gvQpFJ11Hs76guUUktzAF9Bg==} + engines: {node: '>=12.0.0'} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@radix-ui/primitive@1.1.3': + resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==} + + '@radix-ui/react-collection@1.1.7': + resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: 19.2.4 + react-dom: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-compose-refs@1.1.2': + resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} + peerDependencies: + '@types/react': '*' + react: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-context@1.1.2': + resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} + peerDependencies: + '@types/react': '*' + react: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dialog@1.1.15': + resolution: {integrity: sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: 19.2.4 + react-dom: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-direction@1.1.1': + resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==} + peerDependencies: + '@types/react': '*' + react: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dismissable-layer@1.1.11': + resolution: {integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: 19.2.4 + react-dom: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-focus-guards@1.1.3': + resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==} + peerDependencies: + '@types/react': '*' + react: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-focus-scope@1.1.7': + resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: 19.2.4 + react-dom: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-id@1.1.1': + resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} + peerDependencies: + '@types/react': '*' + react: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-portal@1.1.9': + resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: 19.2.4 + react-dom: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-presence@1.1.5': + resolution: {integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: 19.2.4 + react-dom: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-primitive@2.1.3': + resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: 19.2.4 + react-dom: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-roving-focus@1.1.11': + resolution: {integrity: sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: 19.2.4 + react-dom: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slot@1.2.3': + resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} + peerDependencies: + '@types/react': '*' + react: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-slot@1.2.4': + resolution: {integrity: sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==} + peerDependencies: + '@types/react': '*' + react: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-tabs@1.1.13': + resolution: {integrity: sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: 19.2.4 + react-dom: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-use-callback-ref@1.1.1': + resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} + peerDependencies: + '@types/react': '*' + react: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-controllable-state@1.2.2': + resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==} + peerDependencies: + '@types/react': '*' + react: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-effect-event@0.0.2': + resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==} + peerDependencies: + '@types/react': '*' + react: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-escape-keydown@1.1.1': + resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==} + peerDependencies: + '@types/react': '*' + react: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-layout-effect@1.1.1': + resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} + peerDependencies: + '@types/react': '*' + react: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + + '@react-native-async-storage/async-storage@3.0.1': + resolution: {integrity: sha512-VHwHb19sMg4Xh3W5M6YmJ/HSm1uh8RYFa6Dozm9o/jVYTYUgz2BmDXqXF7sum3glQaR34/hlwVc94px1sSdC2A==} + peerDependencies: + react: 19.2.4 + react-native: '*' + + '@react-native/assets-registry@0.83.2': + resolution: {integrity: sha512-9I5l3pGAKnlpQ15uVkeB9Mgjvt3cZEaEc8EDtdexvdtZvLSjtwBzgourrOW4yZUijbjJr8h3YO2Y0q+THwUHTA==} + engines: {node: '>= 20.19.4'} + + '@react-native/babel-plugin-codegen@0.83.2': + resolution: {integrity: sha512-XbcN/BEa64pVlb0Hb/E/Ph2SepjVN/FcNKrJcQvtaKZA6mBSO8pW8Eircdlr61/KBH94LihHbQoQDzkQFpeaTg==} + engines: {node: '>= 20.19.4'} + + '@react-native/babel-preset@0.83.2': + resolution: {integrity: sha512-X/RAXDfe6W+om/Fw1i6htTxQXFhBJ2jgNOWx3WpI3KbjeIWbq7ib6vrpTeIAW2NUMg+K3mML1NzgD4dpZeqdjA==} + engines: {node: '>= 20.19.4'} + peerDependencies: + '@babel/core': '*' + + '@react-native/codegen@0.83.2': + resolution: {integrity: sha512-9uK6X1miCXqtL4c759l74N/XbQeneWeQVjoV7SD2CGJuW7ZefxaoYenwGPs7rMoCdtS6wuIyR3hXQ+uWEBGYXA==} + engines: {node: '>= 20.19.4'} + peerDependencies: + '@babel/core': '*' + + '@react-native/community-cli-plugin@0.83.2': + resolution: {integrity: sha512-sTEF0eiUKtmImEP07Qo5c3Khvm1LIVX1Qyb6zWUqPL6W3MqFiXutZvKBjqLz6p49Szx8cplQLoXfLHT0bcDXKg==} + engines: {node: '>= 20.19.4'} + peerDependencies: + '@react-native-community/cli': '*' + '@react-native/metro-config': '*' + peerDependenciesMeta: + '@react-native-community/cli': + optional: true + '@react-native/metro-config': + optional: true + + '@react-native/debugger-frontend@0.83.2': + resolution: {integrity: sha512-t4fYfa7xopbUF5S4+ihNEwgaq4wLZLKLY0Ms8z72lkMteVd3bOX2Foxa8E2wTfRvdhPOkSpOsTeNDmD8ON4DoQ==} + engines: {node: '>= 20.19.4'} + + '@react-native/debugger-shell@0.83.2': + resolution: {integrity: sha512-z9go6NJMsLSDJT5MW6VGugRsZHjYvUTwxtsVc3uLt4U9W6T3J6FWI2wHpXIzd2dUkXRfAiRQ3Zi8ZQQ8fRFg9A==} + engines: {node: '>= 20.19.4'} + + '@react-native/dev-middleware@0.83.2': + resolution: {integrity: sha512-Zi4EVaAm28+icD19NN07Gh8Pqg/84QQu+jn4patfWKNkcToRFP5vPEbbp0eLOGWS+BVB1d1Fn5lvMrJsBbFcOg==} + engines: {node: '>= 20.19.4'} + + '@react-native/gradle-plugin@0.83.2': + resolution: {integrity: sha512-PqN11fXRAU+uJ0inZY1HWYlwJOXHOhF4SPyeHBBxjajKpm2PGunmvFWwkmBjmmUkP/CNO0ezTUudV0oj+2wiHQ==} + engines: {node: '>= 20.19.4'} + + '@react-native/js-polyfills@0.83.2': + resolution: {integrity: sha512-dk6fIY2OrKW/2Nk2HydfYNrQau8g6LOtd7NVBrgaqa+lvuRyIML5iimShP5qPqQnx2ofHuzjFw+Ya0b5Q7nDbA==} + engines: {node: '>= 20.19.4'} + + '@react-native/normalize-colors@0.74.89': + resolution: {integrity: sha512-qoMMXddVKVhZ8PA1AbUCk83trpd6N+1nF2A6k1i6LsQObyS92fELuk8kU/lQs6M7BsMHwqyLCpQJ1uFgNvIQXg==} + + '@react-native/normalize-colors@0.76.2': + resolution: {integrity: sha512-ICoOpaTLPsFQjNLSM00NgQr6wal300cZZonHVSDXKntX+BfkLeuCHRtr/Mn+klTtW+/1v2/2FRm9dXjvyGf9Dw==} + + '@react-native/normalize-colors@0.83.2': + resolution: {integrity: sha512-gkZAb9LoVVzNuYzzOviH7DiPTXQoZPHuiTH2+O2+VWNtOkiznjgvqpwYAhg58a5zfRq5GXlbBdf5mzRj5+3Y5Q==} + + '@react-native/virtualized-lists@0.83.2': + resolution: {integrity: sha512-N7mRjHLW/+KWxMp9IHRWyE3VIkeG1m3PnZJAGEFLCN8VFb7e4VfI567o7tE/HYcdcXCylw+Eqhlciz8gDeQ71g==} + engines: {node: '>= 20.19.4'} + peerDependencies: + '@types/react': ^19.2.0 + react: 19.2.4 + react-native: '*' + peerDependenciesMeta: + '@types/react': + optional: true + + '@react-navigation/bottom-tabs@7.15.2': + resolution: {integrity: sha512-xaSumZWE97P3j33guO7bh5dJ5IqR1bWiT+i17SUjsXxoI9xnNXWDm4dkTjzGuuT0BHcUVkzei0tjjCQmNg9cIQ==} + peerDependencies: + '@react-navigation/native': ^7.1.31 + react: 19.2.4 + react-native: '*' + react-native-safe-area-context: '>= 4.0.0' + react-native-screens: '>= 4.0.0' + + '@react-navigation/core@7.15.1': + resolution: {integrity: sha512-Fqr6qxfZJIC4ewho7LtTa9zz6hcOzohX7D1lcDfrkGaYkS5xBwEZViGNxCJK/czUc74ua8NThyrObQFjB6Q/RQ==} + peerDependencies: + react: 19.2.4 + + '@react-navigation/elements@2.9.8': + resolution: {integrity: sha512-3gpwUmVnDJYvK9nFmAA/YXw0hmT/C/lZx8RkRMK+ux9l1T+32EWnQFnn34Wa1BMDX8HN2r64yrlW93DIzKI7Uw==} + peerDependencies: + '@react-native-masked-view/masked-view': '>= 0.2.0' + '@react-navigation/native': ^7.1.31 + react: 19.2.4 + react-native: '*' + react-native-safe-area-context: '>= 4.0.0' + peerDependenciesMeta: + '@react-native-masked-view/masked-view': + optional: true + + '@react-navigation/native-stack@7.14.2': + resolution: {integrity: sha512-/nKxFAFSUSGV+NSXrXXcWEcGAHdyp8RyWjoGMDzVPdBhjCLblVSgHWx5y4mm+k0de9V1pkjsftUaroP7rQckzw==} + peerDependencies: + '@react-navigation/native': ^7.1.31 + react: 19.2.4 + react-native: '*' + react-native-safe-area-context: '>= 4.0.0' + react-native-screens: '>= 4.0.0' + + '@react-navigation/native@7.1.31': + resolution: {integrity: sha512-+YCUwtfDgsux59Q0LDHc3Zid9ih93ecUCFWZOH6/+eNoUGnWx77wjS6ZfvBO/7E+EiIup11IVShDzCHR4of8hw==} + peerDependencies: + react: 19.2.4 + react-native: '*' + + '@react-navigation/routers@7.5.3': + resolution: {integrity: sha512-1tJHg4KKRJuQ1/EvJxatrMef3NZXEPzwUIUZ3n1yJ2t7Q97siwRtbynRpQG9/69ebbtiZ8W3ScOZF/OmhvM4Rg==} + + '@react-router/dev@7.13.1': + resolution: {integrity: sha512-H+kEvbbOaWGaitOyL6CgqPsHqRUh66HuVRvIEaZEqdoAY/1xChdhmmq6ZumMHzcFHgHlfOcoXgNHlz6ZO4NWcg==} + engines: {node: '>=20.0.0'} + hasBin: true + peerDependencies: + '@react-router/serve': ^7.13.1 + '@vitejs/plugin-rsc': ~0.5.7 + react-router: ^7.13.1 + react-server-dom-webpack: ^19.2.3 + typescript: ^5.1.0 + vite: ^5.1.0 || ^6.0.0 || ^7.0.0 + wrangler: ^3.28.2 || ^4.0.0 + peerDependenciesMeta: + '@react-router/serve': + optional: true + '@vitejs/plugin-rsc': + optional: true + react-server-dom-webpack: + optional: true + typescript: + optional: true + wrangler: + optional: true + + '@react-router/express@7.13.1': + resolution: {integrity: sha512-ujHom4LiEWsbnohNArwNT86QP3WRB5p+rY8AAll6s4gdrzgOXIy3FHDc3up5Lz8juUrZKh0d+B+PZa/IdDSK3A==} + engines: {node: '>=20.0.0'} + peerDependencies: + express: ^4.17.1 || ^5 + react-router: 7.13.1 + typescript: ^5.1.0 + peerDependenciesMeta: + typescript: + optional: true + + '@react-router/fs-routes@7.13.1': + resolution: {integrity: sha512-3TbBVq1xBv32iWCjr7ZxdLeXyLNIWVfkISpVO0745/VWNgIN1SL1UAXsYPdrfF2lhGhCi+jXTCQbGxGl2gTHvA==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@react-router/dev': ^7.13.1 + typescript: ^5.1.0 + peerDependenciesMeta: + typescript: + optional: true + + '@react-router/node@7.13.1': + resolution: {integrity: sha512-IWPPf+Q3nJ6q4bwyTf5leeGUfg8GAxSN1RKj5wp9SK915zKK+1u4TCOfOmr8hmC6IW1fcjKV0WChkM0HkReIiw==} + engines: {node: '>=20.0.0'} + peerDependencies: + react-router: 7.13.1 + typescript: ^5.1.0 + peerDependenciesMeta: + typescript: + optional: true + + '@react-router/serve@7.13.1': + resolution: {integrity: sha512-vh5lr41rioXLz/zNLTYo0zq4yh97AkgEkJK7bhPeXnNbLNtI36WCZ2AeBtSJ4sdx4gx5LZvcjP8zoWFfSbNupA==} + engines: {node: '>=20.0.0'} + hasBin: true + peerDependencies: + react-router: 7.13.1 + + '@remix-run/node-fetch-server@0.13.0': + resolution: {integrity: sha512-1EsNo0ZpgXu/90AWoRZf/oE3RVTUS80tiTUpt+hv5pjtAkw7icN4WskDwz/KdAw5ARbJLMhZBrO1NqThmy/McA==} + + '@rollup/plugin-commonjs@29.0.0': + resolution: {integrity: sha512-U2YHaxR2cU/yAiwKJtJRhnyLk7cifnQw0zUpISsocBDoHDJn+HTV74ABqnwr5bEgWUwFZC9oFL6wLe21lHu5eQ==} + engines: {node: '>=16.0.0 || 14 >= 14.17'} + peerDependencies: + rollup: ^2.68.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/pluginutils@5.3.0': + resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.59.0': + resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.59.0': + resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.59.0': + resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.59.0': + resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.59.0': + resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.59.0': + resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} + cpu: [arm] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-arm64-gnu@4.59.0': + resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm64-musl@4.59.0': + resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-loong64-gnu@4.59.0': + resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} + cpu: [loong64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-loong64-musl@4.59.0': + resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} + cpu: [loong64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-ppc64-gnu@4.59.0': + resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-ppc64-musl@4.59.0': + resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} + cpu: [ppc64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-riscv64-gnu@4.59.0': + resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-riscv64-musl@4.59.0': + resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-s390x-gnu@4.59.0': + resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-gnu@4.59.0': + resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-musl@4.59.0': + resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rollup/rollup-openbsd-x64@4.59.0': + resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.59.0': + resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.59.0': + resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.59.0': + resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.59.0': + resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.59.0': + resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==} + cpu: [x64] + os: [win32] + + '@rtsao/scc@1.1.0': + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + + '@sec-ant/readable-stream@0.4.1': + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + + '@segment/ajv-human-errors@2.16.0': + resolution: {integrity: sha512-cHNfZcbHrmuYOA7/Sn7HlIDHanamiRTZtngfxcAuFaKQjP7cSqsVHjLz38FI2FQ8JDLz3syGLaz10Gn2ddo7+w==} + peerDependencies: + ajv: ^8.0.0 + + '@segment/loosely-validate-event@2.0.0': + resolution: {integrity: sha512-ZMCSfztDBqwotkl848ODgVcAmN4OItEWDCkshcKz0/W6gGSQayuuCtWV/MlodFivAZD793d6UgANd6wCXUfrIw==} + + '@sideway/address@4.1.5': + resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==} + + '@sideway/formula@3.0.1': + resolution: {integrity: sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==} + + '@sideway/pinpoint@2.0.0': + resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} + + '@sinclair/typebox@0.27.10': + resolution: {integrity: sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==} + + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + + '@sinonjs/commons@3.0.1': + resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + + '@sinonjs/fake-timers@10.3.0': + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@tailwindcss/node@4.2.1': + resolution: {integrity: sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg==} + + '@tailwindcss/oxide-android-arm64@4.2.1': + resolution: {integrity: sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.2.1': + resolution: {integrity: sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.2.1': + resolution: {integrity: sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.2.1': + resolution: {integrity: sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA==} + engines: {node: '>= 20'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.1': + resolution: {integrity: sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw==} + engines: {node: '>= 20'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.2.1': + resolution: {integrity: sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@tailwindcss/oxide-linux-arm64-musl@4.2.1': + resolution: {integrity: sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@tailwindcss/oxide-linux-x64-gnu@4.2.1': + resolution: {integrity: sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@tailwindcss/oxide-linux-x64-musl@4.2.1': + resolution: {integrity: sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@tailwindcss/oxide-wasm32-wasi@4.2.1': + resolution: {integrity: sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.2.1': + resolution: {integrity: sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.2.1': + resolution: {integrity: sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ==} + engines: {node: '>= 20'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.2.1': + resolution: {integrity: sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw==} + engines: {node: '>= 20'} + + '@tailwindcss/postcss@4.2.1': + resolution: {integrity: sha512-OEwGIBnXnj7zJeonOh6ZG9woofIjGrd2BORfvE5p9USYKDCZoQmfqLcfNiRWoJlRWLdNPn2IgVZuWAOM4iTYMw==} + + '@tailwindcss/typography@0.5.19': + resolution: {integrity: sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1' + + '@tailwindcss/vite@4.2.1': + resolution: {integrity: sha512-TBf2sJjYeb28jD2U/OhwdW0bbOsxkWPwQ7SrqGf9sVcoYwZj7rkXljroBO9wKBut9XnmQLXanuDUeqQK0lGg/w==} + peerDependencies: + vite: ^5.2.0 || ^6 || ^7 + + '@ts-morph/common@0.11.1': + resolution: {integrity: sha512-7hWZS0NRpEsNV8vWJzg7FEz6V8MaLNeJOmwmghqUXTpzk16V1LLZhdo+4QvE/+zv4cVci0OviuJFnqhEfoV3+g==} + + '@tsconfig/node10@1.0.12': + resolution: {integrity: sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + + '@types/bunyan@1.8.11': + resolution: {integrity: sha512-758fRH7umIMk5qt5ELmRMff4mLDlN+xyYzC+dkPTdKwbSkJFvz6xwyScrytPU0QIBbRRwbiE8/BIg8bpajerNQ==} + + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + + '@types/cli-progress@3.11.6': + resolution: {integrity: sha512-cE3+jb9WRlu+uOSAugewNpITJDt1VF8dHOopPO4IABFc3SXYL5WE/+PTz/FCdZRRfIujiWW3n3aMbv1eIGVRWA==} + + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/graceful-fs@4.1.9': + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + + '@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==} + + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/mdx@2.0.13': + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/node@25.3.2': + resolution: {integrity: sha512-RpV6r/ij22zRRdyBPcxDeKAzH43phWVKEjL2iksqo1Vz3CuBUrgmPpPhALKiRfU7OMCmeeO9vECBMsV0hMTG8Q==} + + '@types/react-dom@19.2.3': + resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} + peerDependencies: + '@types/react': ^19.2.0 + + '@types/react@19.2.14': + resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} + + '@types/stack-utils@2.0.3': + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + '@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==} + + '@types/yargs@17.0.35': + resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} + + '@typescript-eslint/eslint-plugin@8.56.1': + resolution: {integrity: sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.56.1 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/parser@8.56.1': + resolution: {integrity: sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/project-service@8.56.1': + resolution: {integrity: sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/scope-manager@8.56.1': + resolution: {integrity: sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.56.1': + resolution: {integrity: sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/type-utils@8.56.1': + resolution: {integrity: sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/types@8.56.1': + resolution: {integrity: sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.56.1': + resolution: {integrity: sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/utils@8.56.1': + resolution: {integrity: sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/visitor-keys@8.56.1': + resolution: {integrity: sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} + cpu: [arm] + os: [android] + + '@unrs/resolver-binding-android-arm64@1.11.1': + resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} + cpu: [arm64] + os: [android] + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} + cpu: [arm64] + os: [darwin] + + '@unrs/resolver-binding-darwin-x64@1.11.1': + resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} + cpu: [x64] + os: [darwin] + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} + cpu: [x64] + os: [freebsd] + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} + cpu: [arm64] + os: [win32] + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} + cpu: [ia32] + os: [win32] + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} + cpu: [x64] + os: [win32] + + '@urql/core@4.0.11': + resolution: {integrity: sha512-FFdY97vF5xnUrElcGw9erOLvtu+KGMLfwrLNDfv4IPgdp2IBsiGe+Kb7Aypfd3kH//BETewVSLm3+y2sSzjX6A==} + + '@urql/exchange-retry@1.2.0': + resolution: {integrity: sha512-1O/biKiVhhn0EtvDF4UOvz325K4RrLupfL8rHcmqD2TBLv4qVDWQuzx4JGa1FfqjjRb+C9TNZ6w19f32Mq85Ug==} + + '@vercel/analytics@1.6.1': + resolution: {integrity: sha512-oH9He/bEM+6oKlv3chWuOOcp8Y6fo6/PSro8hEkgCW3pu9/OiCXiUpRUogDh3Fs3LH2sosDrx8CxeOLBEE+afg==} + peerDependencies: + '@remix-run/react': ^2 + '@sveltejs/kit': ^1 || ^2 + next: '>= 13' + react: 19.2.4 + svelte: '>= 4' + vue: ^3 + vue-router: ^4 + peerDependenciesMeta: + '@remix-run/react': + optional: true + '@sveltejs/kit': + optional: true + next: + optional: true + react: + optional: true + svelte: + optional: true + vue: + optional: true + vue-router: + optional: true + + '@vercel/react-router@1.2.5': + resolution: {integrity: sha512-y1GSzt+pZZkO53oUzpJzmeYkdQwgWF4nI9i5OtuM1h6ItgOppkYgtGze9SmRwon3B6m0gOQXiiRhcTB1kM7Hxg==} + peerDependencies: + '@react-router/dev': '7' + '@react-router/node': '7' + isbot: '5' + react: 19.2.4 + react-dom: 19.2.4 + + '@vercel/static-config@3.1.2': + resolution: {integrity: sha512-2d+TXr6K30w86a+WbMbGm2W91O0UzO5VeemZYBBUJbCjk/5FLLGIi8aV6RS2+WmaRvtcqNTn2pUA7nCOK3bGcQ==} + + '@vitest/expect@4.0.18': + resolution: {integrity: sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==} + + '@vitest/mocker@4.0.18': + resolution: {integrity: sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ==} + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@4.0.18': + resolution: {integrity: sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==} + + '@vitest/runner@4.0.18': + resolution: {integrity: sha512-rpk9y12PGa22Jg6g5M3UVVnTS7+zycIGk9ZNGN+m6tZHKQb7jrP7/77WfZy13Y/EUDd52NDsLRQhYKtv7XfPQw==} + + '@vitest/snapshot@4.0.18': + resolution: {integrity: sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA==} + + '@vitest/spy@4.0.18': + resolution: {integrity: sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==} + + '@vitest/utils@4.0.18': + resolution: {integrity: sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==} + + '@xmldom/xmldom@0.7.13': + resolution: {integrity: sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g==} + engines: {node: '>=10.0.0'} + deprecated: this version is no longer supported, please update to at least 0.8.* + + '@xmldom/xmldom@0.8.11': + resolution: {integrity: sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==} + engines: {node: '>=10.0.0'} + + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + + accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn-walk@8.3.5: + resolution: {integrity: sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==} + engines: {node: '>=0.4.0'} + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + + ajv-formats@2.1.1: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv@6.14.0: + resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} + + ajv@8.11.0: + resolution: {integrity: sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==} + + ajv@8.6.3: + resolution: {integrity: sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==} + + anser@1.4.10: + resolution: {integrity: sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==} + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-regex@4.1.1: + resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==} + engines: {node: '>=6'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + ansicolors@0.3.2: + resolution: {integrity: sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} + engines: {node: '>=10'} + + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + + array-includes@3.1.9: + resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} + engines: {node: '>= 0.4'} + + array-timsort@1.0.3: + resolution: {integrity: sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlastindex@1.2.6: + resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.3: + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} + engines: {node: '>= 0.4'} + + array.prototype.tosorted@1.1.4: + resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + + asap@2.0.6: + resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + + asn1@0.2.6: + resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + + astring@1.9.0: + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} + hasBin: true + + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + at-least-node@1.0.0: + resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} + engines: {node: '>= 4.0.0'} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + b4a@1.8.0: + resolution: {integrity: sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==} + peerDependencies: + react-native-b4a: '*' + peerDependenciesMeta: + react-native-b4a: + optional: true + + babel-dead-code-elimination@1.0.12: + resolution: {integrity: sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig==} + + babel-jest@29.7.0: + resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + + babel-plugin-istanbul@6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} + + babel-plugin-jest-hoist@29.6.3: + resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + babel-plugin-polyfill-corejs2@0.4.15: + resolution: {integrity: sha512-hR3GwrRwHUfYwGfrisXPIDP3JcYfBrW7wKE7+Au6wDYl7fm/ka1NEII6kORzxNU556JjfidZeBsO10kYvtV1aw==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-corejs3@0.13.0: + resolution: {integrity: sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-regenerator@0.6.6: + resolution: {integrity: sha512-hYm+XLYRMvupxiQzrvXUj7YyvFFVfv5gI0R71AJzudg1g2AI2vyCPPIFEBjk162/wFzti3inBHo7isWFuEVS/A==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-react-compiler@1.0.0: + resolution: {integrity: sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==} + + babel-plugin-react-compiler@19.1.0-rc.3: + resolution: {integrity: sha512-mjRn69WuTz4adL0bXGx8Rsyk1086zFJeKmes6aK0xPuK3aaXmDJdLHqwKKMrpm6KAI1MCoUK72d2VeqQbu8YIA==} + + babel-plugin-react-native-web@0.21.2: + resolution: {integrity: sha512-SPD0J6qjJn8231i0HZhlAGH6NORe+QvRSQM2mwQEzJ2Fb3E4ruWTiiicPlHjmeWShDXLcvoorOCXjeR7k/lyWA==} + + babel-plugin-syntax-hermes-parser@0.32.0: + resolution: {integrity: sha512-m5HthL++AbyeEA2FcdwOLfVFvWYECOBObLHNqdR8ceY4TsEdn4LdX2oTvbB2QJSSElE2AWA/b2MXZ/PF/CqLZg==} + + babel-plugin-syntax-hermes-parser@0.32.1: + resolution: {integrity: sha512-HgErPZTghW76Rkq9uqn5ESeiD97FbqpZ1V170T1RG2RDp+7pJVQV2pQJs7y5YzN0/gcT6GM5ci9apRnIwuyPdQ==} + + babel-plugin-transform-flow-enums@0.0.2: + resolution: {integrity: sha512-g4aaCrDDOsWjbm0PUUeVnkcVd6AKJsVc/MbnPhEotEpkeJQP6b8nzewohQi7+QS8UyPehOhGWn0nOwjvWpmMvQ==} + + babel-preset-current-node-syntax@1.2.0: + resolution: {integrity: sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==} + peerDependencies: + '@babel/core': ^7.0.0 || ^8.0.0-0 + + babel-preset-expo@55.0.9: + resolution: {integrity: sha512-o91XmsB4nw58oyDzC/lR+LVZSFv2NgwG+ESTW/QZC9MV4SRviSzt9+ZsMaD2SjyOBxuOb5EDabZRzFPFSavZFw==} + peerDependencies: + '@babel/runtime': ^7.20.0 + expo: '*' + expo-widgets: ^55.0.2 + react-refresh: '>=0.14.0 <1.0.0' + peerDependenciesMeta: + '@babel/runtime': + optional: true + expo: + optional: true + expo-widgets: + optional: true + + babel-preset-jest@29.6.3: + resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + bare-events@2.8.2: + resolution: {integrity: sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==} + peerDependencies: + bare-abort-controller: '*' + peerDependenciesMeta: + bare-abort-controller: + optional: true + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + baseline-browser-mapping@2.10.0: + resolution: {integrity: sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==} + engines: {node: '>=6.0.0'} + hasBin: true + + basic-auth@2.0.1: + resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==} + engines: {node: '>= 0.8'} + + better-opn@3.0.2: + resolution: {integrity: sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==} + engines: {node: '>=12.0.0'} + + big-integer@1.6.52: + resolution: {integrity: sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==} + engines: {node: '>=0.6'} + + body-parser@1.20.4: + resolution: {integrity: sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + bplist-creator@0.1.0: + resolution: {integrity: sha512-sXaHZicyEEmY86WyueLTQesbeoH/mquvarJaQNbjuOQO+7gbFcDEWqKmcWA4cOTLzFlfgvkiVxolk1k5bBIpmg==} + + bplist-parser@0.3.1: + resolution: {integrity: sha512-PyJxiNtA5T2PlLIeBot4lbp7rj4OadzjnMZD/G5zuBNt8ei/yCU7+wW0h2bag9vr8c+/WuRWmSxbqAl9hL1rBA==} + engines: {node: '>= 5.10.0'} + + bplist-parser@0.3.2: + resolution: {integrity: sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ==} + engines: {node: '>= 5.10.0'} + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + + brace-expansion@5.0.4: + resolution: {integrity: sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==} + engines: {node: 18 || 20 || >=22} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + bser@2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + bunyan@1.8.15: + resolution: {integrity: sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig==} + engines: {'0': node >=0.10.0} + hasBin: true + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + caniuse-lite@1.0.30001774: + resolution: {integrity: sha512-DDdwPGz99nmIEv216hKSgLD+D4ikHQHjBC/seF98N9CPqRX4M5mSxT9eTV6oyisnJcuzxtZy4n17yKKQYmYQOA==} + + cardinal@2.1.1: + resolution: {integrity: sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==} + hasBin: true + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} + engines: {node: '>=18'} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + + charenc@0.0.2: + resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + + chrome-launcher@0.15.2: + resolution: {integrity: sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==} + engines: {node: '>=12.13.0'} + hasBin: true + + chromium-edge-launcher@0.2.0: + resolution: {integrity: sha512-JfJjUnq25y9yg4FABRRVPmBGWPZZi+AQXT4mxupb67766/0UlhG8PAZCz6xzEMXTbW3CsSoE8PcCWA49n35mKg==} + + ci-info@2.0.0: + resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} + + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + + clean-stack@3.0.1: + resolution: {integrity: sha512-lR9wNiMRcVQjSB3a7xXGLuz4cr4wJuuXlaAEbRutGowQTmlp7R72/DOgN21e8jdwblMWl9UOJMJXarX94pzKdg==} + engines: {node: '>=10'} + + cli-cursor@2.1.0: + resolution: {integrity: sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==} + engines: {node: '>=4'} + + cli-cursor@3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + + cli-progress@3.12.0: + resolution: {integrity: sha512-tRkV3HJ1ASwm19THiiLIXLO7Im7wlTuKnvkYaTkyoAPefqjNg7W7DHKUlGRxy9vxDvbyCYQkQozvptuMkGCg8A==} + engines: {node: '>=4'} + + cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + code-block-writer@10.1.1: + resolution: {integrity: sha512-67ueh2IRGst/51p0n6FvPrnRjAGHY5F8xdjkgrYE7DDzpJe6qA07RYQ9VcoUeo5ATOjSOiWpSL3SWBRRbempMw==} + + collapse-white-space@2.1.0: + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + + colorjs.io@0.6.0-alpha.1: + resolution: {integrity: sha512-c/h/8uAmPydQcriRdX8UTAFHj6SpSHFHBA8LvMikvYWAVApPTwg/pyOXNsGmaCBd6L/EeDlRHSNhTtnIFp/qsg==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + + comment-json@4.5.1: + resolution: {integrity: sha512-taEtr3ozUmOB7it68Jll7s0Pwm+aoiHyXKrEC8SEodL4rNpdfDLqa7PfBlrgFoCNNdR8ImL+muti5IGvktJAAg==} + engines: {node: '>= 6'} + + commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + + component-type@1.2.2: + resolution: {integrity: sha512-99VUHREHiN5cLeHm3YLq312p6v+HUEcwtLCAtelvUDI6+SH5g5Cr85oNR2S1o6ywzL0ykMbuwLzM2ANocjEOIA==} + + compressible@2.0.18: + resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} + engines: {node: '>= 0.6'} + + compression@1.8.1: + resolution: {integrity: sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==} + engines: {node: '>= 0.8.0'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + confbox@0.2.4: + resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==} + + connect@3.7.0: + resolution: {integrity: sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==} + engines: {node: '>= 0.10.0'} + + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-signature@1.0.7: + resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + cookie@1.1.1: + resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} + engines: {node: '>=18'} + + core-js-compat@3.48.0: + resolution: {integrity: sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + + cross-fetch@3.2.0: + resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==} + + cross-spawn@6.0.6: + resolution: {integrity: sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==} + engines: {node: '>=4.8'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + crypt@0.0.2: + resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} + + crypto-random-string@2.0.0: + resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} + engines: {node: '>=8'} + + css-declaration-sorter@7.3.1: + resolution: {integrity: sha512-gz6x+KkgNCjxq3Var03pRYLhyNfwhkKF1g/yoLgDNtFvVu0/fOLV9C8fFEZRjACp/XQLumjAYo7JVjzH3wLbxA==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.0.9 + + css-in-js-utils@3.1.0: + resolution: {integrity: sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==} + + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + + css-tree@1.1.3: + resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==} + engines: {node: '>=8.0.0'} + + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + daisyui@5.5.19: + resolution: {integrity: sha512-pbFAkl1VCEh/MPCeclKL61I/MqRIFFhNU7yiXoDDRapXN4/qNCoMxeCCswyxEEhqL5eiTTfwHvucFtOE71C9sA==} + + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + + dateformat@4.6.3: + resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + + decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} + engines: {node: '>=0.10'} + + dedent@1.7.1: + resolution: {integrity: sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + detect-indent@7.0.2: + resolution: {integrity: sha512-y+8xyqdGLL+6sh0tVeHcfP/QDd8gUgbasolJJpY7NgeQGSZ739bDtSiaiDgtoicy+mtYB81dKLxO9xRhCyIB3A==} + engines: {node: '>=12.20'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + detect-newline@4.0.1: + resolution: {integrity: sha512-qE3Veg1YXzGHQhlA6jzebZN2qVf6NX+A7m7qlhCGG30dJixrAQhYOsJjsnBjJkCSmuOPpCk30145fr8FV0bzog==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + diff@4.0.4: + resolution: {integrity: sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==} + engines: {node: '>=0.3.1'} + + diff@7.0.0: + resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==} + engines: {node: '>=0.3.1'} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + dnssd-advertise@1.1.3: + resolution: {integrity: sha512-XENsHi3MBzWOCAXif3yZvU1Ah0l+nhJj1sjWL6TnOAYKvGiFhbTx32xHN7+wLMLUOCj7Nr0evADWG4R8JtqCDA==} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domino@2.1.6: + resolution: {integrity: sha512-3VdM/SXBZX2omc9JF9nOPCtDaYQ67BGp5CoLpIQlO2KCAPETs8TcDHacF26jXadGbvUteZzRTeos2fhID5+ucQ==} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + + dotenv-expand@11.0.7: + resolution: {integrity: sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==} + engines: {node: '>=12'} + + dotenv@16.0.3: + resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} + engines: {node: '>=12'} + + dotenv@16.3.1: + resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} + engines: {node: '>=12'} + + dotenv@16.4.7: + resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} + engines: {node: '>=12'} + + dtrace-provider@0.8.8: + resolution: {integrity: sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==} + engines: {node: '>=0.10'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + eas-cli@18.0.6: + resolution: {integrity: sha512-NNb18dDjGl3qkz9QdUtF6m/ymx3phQwEWtuFK8Wv0I569/anGUKdQQHU/h1rIwzB/Psdpty8fa6PWOFrDo3LPw==} + engines: {node: '>=20.0.0'} + hasBin: true + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + ecsify@0.0.15: + resolution: {integrity: sha512-LoHb3uumPjI4/gguGPJX8Wk+IHcdFS3JzGMcgReSWLlF7GKnCwqCkw9AHkGlVbV3MhI7xu+/NAomyX2XYJ7ntw==} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + ejs@3.1.10: + resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} + engines: {node: '>=0.10.0'} + hasBin: true + + electron-to-chromium@1.5.302: + resolution: {integrity: sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + + enhanced-resolve@5.19.0: + resolution: {integrity: sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==} + engines: {node: '>=10.13.0'} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + env-paths@2.2.0: + resolution: {integrity: sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==} + engines: {node: '>=6'} + + env-string@1.0.1: + resolution: {integrity: sha512-/DhCJDf5DSFK32joQiWRpWrT0h7p3hVQfMKxiBb7Nt8C8IF8BYyPtclDnuGGLOoj16d/8udKeiE7JbkotDmorQ==} + + envinfo@7.11.0: + resolution: {integrity: sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==} + engines: {node: '>=4'} + hasBin: true + + err-code@2.0.3: + resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} + + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + + error-stack-parser@2.1.4: + resolution: {integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==} + + es-abstract@1.24.1: + resolution: {integrity: sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-iterator-helpers@1.2.2: + resolution: {integrity: sha512-BrUQ0cPTB/IwXj23HtwHjS9n7O4h9FX94b4xc5zlTHxeLgTAdzYUDyy6KdExAl9lbN5rtfe44xpjpmj9grxs5w==} + engines: {node: '>= 0.4'} + + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.1.0: + resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + engines: {node: '>= 0.4'} + + esast-util-from-estree@2.0.0: + resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} + + esast-util-from-js@2.0.1: + resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} + + esbuild@0.27.3: + resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-config-expo@55.0.0: + resolution: {integrity: sha512-YvhaKrp1g7pR/qjdI12E5nw9y0DJZWgYr815vyW8wskGLsFvxATY3mtKL8zm3ZYzWj3Bvc37tRIS661TEkrv9A==} + peerDependencies: + eslint: '>=8.10' + + eslint-config-prettier@10.1.8: + resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-import-resolver-typescript@3.10.1: + resolution: {integrity: sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + eslint-plugin-import-x: '*' + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + + eslint-module-utils@2.12.1: + resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-expo@1.0.0: + resolution: {integrity: sha512-qLtunR+cNFtC+jwYCBia5c/PJurMjSLMOV78KrEOyQK02ohZapU4dCFFnS2hfrJuw0zxfsjVkjqg3QBqi933QA==} + engines: {node: '>=18.0.0'} + peerDependencies: + eslint: '>=8.10' + + eslint-plugin-import@2.32.0: + resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-only-warn@1.1.0: + resolution: {integrity: sha512-2tktqUAT+Q3hCAU0iSf4xAN1k9zOpjK5WO8104mB0rT/dGhOa09582HN5HlbxNbPRZ0THV7nLGvzugcNOSjzfA==} + engines: {node: '>=6'} + + eslint-plugin-react-hooks@5.2.0: + resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-plugin-react-hooks@7.0.1: + resolution: {integrity: sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==} + engines: {node: '>=18'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-plugin-react@7.37.5: + resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + + eslint-plugin-turbo@2.8.11: + resolution: {integrity: sha512-DTrc61/Ppvq5xt7tAukmmcL3o8aAKFi5SPTLZF2w5UeFpFuEM7ZptFdoTsdNZfQpOWKJ+sF7quv7usO11IP/kQ==} + peerDependencies: + eslint: '>6.6.0' + turbo: '>2.0.0' + + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@9.39.3: + resolution: {integrity: sha512-VmQ+sifHUbI/IcSopBCF/HO3YiHQx/AVd3UVyYL6weuwW+HvON9VYn5l6Zl1WZzPWXPNZrSQpxwkkZ/VuvJZzg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-util-attach-comments@3.0.0: + resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} + + estree-util-build-jsx@3.0.1: + resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} + + estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + + estree-util-scope@1.0.0: + resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==} + + estree-util-to-js@2.0.0: + resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} + + estree-util-visit@2.0.0: + resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + + events-universal@1.0.1: + resolution: {integrity: sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + exec-async@2.2.0: + resolution: {integrity: sha512-87OpwcEiMia/DeiKFzaQNBNFeN3XkkpYIh9FyOqq5mS2oKv3CBE67PXoEKcr6nodWdXNogTiQ0jE2NGuoffXPw==} + + execa@1.0.0: + resolution: {integrity: sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==} + engines: {node: '>=6'} + + execa@9.6.1: + resolution: {integrity: sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==} + engines: {node: ^18.19.0 || >=20.5.0} + + exit-hook@2.2.1: + resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} + engines: {node: '>=6'} + + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} + + expo-asset@55.0.8: + resolution: {integrity: sha512-yEz2svDX67R0yiW2skx6dJmcE0q7sj9ECpGMcxBExMCbctc+nMoZCnjUuhzPl5vhClUsO5HFFXS5vIGmf1bgHQ==} + peerDependencies: + expo: '*' + react: 19.2.4 + react-native: '*' + + expo-constants@55.0.7: + resolution: {integrity: sha512-kdcO4TsQRRqt0USvjaY5vgQMO9H52K3kBZ/ejC7F6rz70mv08GoowrZ1CYOr5O4JpPDRlIpQfZJUucaS/c+KWQ==} + peerDependencies: + expo: '*' + react-native: '*' + + expo-dev-client@55.0.10: + resolution: {integrity: sha512-qclT+uDp5VjdHDrXkMus0d8ZpNq41CzOXWJq4UmlfsuFeY4b7v/vAI0OJTtScx/FSTkSkggRzjqm+EwnmIFRCg==} + peerDependencies: + expo: '*' + + expo-dev-launcher@55.0.11: + resolution: {integrity: sha512-u/8iVwD4VU2N5R5Tr32+yqT7Llm8K7VyfYB76Fe5apK97Ocpf2PR4Oqf8RbKc9DmqcbHEWfNriMGEW8U6FsaKA==} + peerDependencies: + expo: '*' + + expo-dev-menu-interface@55.0.1: + resolution: {integrity: sha512-FkNtwq1q6NmYoy28pj+ZLuHmirJgc039pQbJ167MZJIaprLcMN1yy67qA7xBHK+FNJ8AN8kGCtMTPByg5UC72A==} + peerDependencies: + expo: '*' + + expo-dev-menu@55.0.10: + resolution: {integrity: sha512-gad31DFkRmEC6pj6sZLIv3HY14PR3X6SUwUTtilArF5eQK/Nr3dWhYFL/QHlrBkwTEDYeKKgcw3V6sZDfE6hcg==} + peerDependencies: + expo: '*' + + expo-device@55.0.9: + resolution: {integrity: sha512-BzeuL7lwg2jh/tU+HTJ5dxygB1tpfgThaguPPH86K0ujcj/4RBkC27i/i7nhSoWvL1pQIgUqL0L7WTtjcS9t/w==} + peerDependencies: + expo: '*' + + expo-file-system@55.0.10: + resolution: {integrity: sha512-ysFdVdUgtfj2ApY0Cn+pBg+yK4xp+SNwcaH8j2B91JJQ4OXJmnyCSmrNZYz7J4mdYVuv2GzxIP+N/IGlHQG3Yw==} + peerDependencies: + expo: '*' + react-native: '*' + + expo-font@55.0.4: + resolution: {integrity: sha512-ZKeGTFffPygvY5dM/9ATM2p7QDkhsaHopH7wFAWgP2lKzqUMS9B/RxCvw5CaObr9Ro7x9YptyeRKX2HmgmMfrg==} + peerDependencies: + expo: '*' + react: 19.2.4 + react-native: '*' + + expo-glass-effect@55.0.7: + resolution: {integrity: sha512-G7Q9rUaEY0YC36fGE6irDljfsfvzz/y49zagARAKvSJSyQMUSrhR25WOr5LK5Cw7gQNNBEy9U1ctlr7yCay/fQ==} + peerDependencies: + expo: '*' + react: 19.2.4 + react-native: '*' + + expo-haptics@15.0.8: + resolution: {integrity: sha512-lftutojy8Qs8zaDzzjwM3gKHFZ8bOOEZDCkmh2Ddpe95Ra6kt2izeOfOfKuP/QEh0MZ1j9TfqippyHdRd1ZM9g==} + peerDependencies: + expo: '*' + + expo-image@55.0.5: + resolution: {integrity: sha512-oejmMwy5O9EtC8po9NxkcurWHqND6p8xuJaj9FGNo8NXLt9e+w3cKWx7HuPzkH5y3qFXQ9Od+z+I/wxEci36fw==} + peerDependencies: + expo: '*' + react: 19.2.4 + react-native: '*' + react-native-web: '*' + peerDependenciesMeta: + react-native-web: + optional: true + + expo-json-utils@55.0.0: + resolution: {integrity: sha512-aupt/o5PDAb8dXDCb0JcRdkqnTLxe/F+La7jrnyd/sXlYFfRgBJLFOa1SqVFXm1E/Xam1SE/yw6eAb+DGY7Arg==} + + expo-keep-awake@55.0.4: + resolution: {integrity: sha512-vwfdMtMS5Fxaon8gC0AiE70SpxTsHJ+rjeoVJl8kdfdbxczF7OIaVmfjFJ5Gfigd/WZiLqxhfZk34VAkXF4PNg==} + peerDependencies: + expo: '*' + react: 19.2.4 + + expo-linking@55.0.7: + resolution: {integrity: sha512-MiGCedere1vzQTEi2aGrkzd7eh/rPSz4w6F3GMBuAJzYl+/0VhIuyhozpEGrueyDIXWfzaUVOcn3SfxVi+kwQQ==} + peerDependencies: + react: 19.2.4 + react-native: '*' + + expo-manifests@55.0.9: + resolution: {integrity: sha512-i82j3X4hbxYDe6kxUw4u8WfvbvTj2w+9BD9WKuL0mFRy+MjvdzdyaqAjEViWCKo/alquP/hTApDTQBb3UmWhkg==} + peerDependencies: + expo: '*' + + expo-modules-autolinking@55.0.8: + resolution: {integrity: sha512-nrWB1pkNp7bR8ECUTgYUiJ2Pyh6AvxCBXZ+lyPlfl1TzEIGhwU1Yqr+d78eJDueXaW+9zKeE0HqrTZoLS3ve4A==} + hasBin: true + + expo-modules-core@55.0.13: + resolution: {integrity: sha512-DYLQTOJAR7jD3M9S0sH9myZaPEtShdicHrPiWcupIXMeMkQxFzErx+adUI8gZPy4AU45BgeGgtaogRfT25iLfw==} + peerDependencies: + react: 19.2.4 + react-native: '*' + + expo-router@55.0.3: + resolution: {integrity: sha512-B3MQAeZq9B2SS5kgEybGqXYR0AY7QYM7fQ5E4bJwtvZLJjWPmWhDALhBpD26ovK/i1k0fi9VgW47FKJODxM5Jg==} + peerDependencies: + '@expo/log-box': 55.0.7 + '@expo/metro-runtime': ^55.0.6 + '@react-navigation/drawer': ^7.7.2 + '@testing-library/react-native': '>= 13.2.0' + expo: '*' + expo-constants: ^55.0.7 + expo-linking: ^55.0.7 + react: 19.2.4 + react-dom: 19.2.4 + react-native: '*' + react-native-gesture-handler: '*' + react-native-reanimated: '*' + react-native-safe-area-context: '>= 5.4.0' + react-native-screens: '*' + react-native-web: '*' + react-server-dom-webpack: ~19.0.4 || ~19.1.5 || ~19.2.4 + peerDependenciesMeta: + '@react-navigation/drawer': + optional: true + '@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 + + expo-server@55.0.6: + resolution: {integrity: sha512-xI72FTm469FfuuBL2R5aNtthgH+GR7ygOpsx/KcPS0K8AZaZd7VjtEExbzn9/qyyYkWW3T+3dAmCDKOMX8gdmQ==} + engines: {node: '>=20.16.0'} + + expo-splash-screen@55.0.10: + resolution: {integrity: sha512-RN5qqrxudxFlRIjLFr/Ifmt+mUCLRc0gs66PekP6flzNS/JYEuoCbwJ+NmUwwJtPA+vyy60DYiky0QmS98ydmQ==} + peerDependencies: + expo: '*' + + expo-status-bar@55.0.4: + resolution: {integrity: sha512-BPDjUXKqv1F9j2YNGLRZfkBEZXIEEpqj+t81y4c+4fdSN3Pos7goIHXgcl2ozbKQLgKRZQyNZQtbUgh5UjHYUQ==} + peerDependencies: + react: 19.2.4 + react-native: '*' + + expo-symbols@55.0.4: + resolution: {integrity: sha512-w9rxPlpta3gks0G4Tvpq/qQdiMp4R/XOeOzyjSruYUQakmsWbQBKA+Sd/fCVXs7qFJSvVTOGXiOhZm+YJRYZVg==} + peerDependencies: + expo: '*' + expo-font: '*' + react: 19.2.4 + react-native: '*' + + expo-system-ui@55.0.9: + resolution: {integrity: sha512-8ygP1B0uFAFI8s7eHY2IcGnE83GhFeZYwHBr/fQ4dSXnc7iVT9zp2PvyTyiDiibQ69dBG+fauMQ4KlPcOO51kQ==} + peerDependencies: + expo: '*' + react-native: '*' + react-native-web: '*' + peerDependenciesMeta: + react-native-web: + optional: true + + expo-updates-interface@55.1.3: + resolution: {integrity: sha512-UVVIiZqymQZJL+o/jh65kXOI97xdkbqBJJM0LMabaPMNLFnc6/WvOMOzmQs7SPyKb8+0PeBaFd7tj5DzF6JeQg==} + peerDependencies: + expo: '*' + + expo-web-browser@55.0.9: + resolution: {integrity: sha512-PvAVsG401QmZabtTsYh1cYcpPiqvBPs8oiOkSrp0jIXnneiM466HxmeNtvo+fNxqJ2nwOBz9qLPiWRO91VBfsQ==} + peerDependencies: + expo: '*' + react-native: '*' + + expo@55.0.3: + resolution: {integrity: sha512-mntOU02zNtm2LZeNjPPGEduw626n1tkG0nbCkr+GrMOaG9kfISOujBNtEBByrQ863qm1cAJf/xWFGyq/oIEI7g==} + hasBin: true + peerDependencies: + '@expo/dom-webview': '*' + '@expo/metro-runtime': '*' + react: 19.2.4 + react-native: '*' + react-native-webview: '*' + peerDependenciesMeta: + '@expo/dom-webview': + optional: true + '@expo/metro-runtime': + optional: true + react-native-webview: + optional: true + + exponential-backoff@3.1.3: + resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==} + + express@4.22.1: + resolution: {integrity: sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==} + engines: {node: '>= 0.10.0'} + + exsolve@1.0.8: + resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + + fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + engines: {node: '>=8.6.0'} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + + fb-dotslash@0.5.8: + resolution: {integrity: sha512-XHYLKk9J4BupDxi9bSEhkfss0m+Vr9ChTrjhf9l2iw3jB5C7BnY4GVPoMcqbrTutsKJso6yj2nAB6BI/F2oZaA==} + engines: {node: '>=20'} + hasBin: true + + fb-watchman@2.0.2: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + + fbjs-css-vars@1.0.2: + resolution: {integrity: sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==} + + fbjs@3.0.5: + resolution: {integrity: sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + feature-react@0.0.67: + resolution: {integrity: sha512-fePAFpDGDG9JRSZGoT6ivz+pn3WZqb0KVgCpX5JllxS7BfZORffAvymyWSwJ9i5SEIdKYIld1UK4Cmpb5V1pTg==} + peerDependencies: + react: 19.2.4 + + feature-state@0.0.65: + resolution: {integrity: sha512-pkITOuHjVOf+sKa4vqWuTr4eld0J7cipHFa5ktbBUvZ0HedtmZhvVPK69pj5Sqo7jiNt8u8EUSLL/sCqvk8DsA==} + + fetch-nodeshim@0.4.8: + resolution: {integrity: sha512-YW5vG33rabBq6JpYosLNoXoaMN69/WH26MeeX2hkDVjN6UlvRGq3Wkazl9H0kisH95aMu/HtHL64JUvv/+Nv/g==} + + fetch-retry@4.1.1: + resolution: {integrity: sha512-e6eB7zN6UBSwGVwrbWVH+gdLnkW9WwHhmq2YDK1Sh30pzx1onRVGBvogTlUeWxwTa+L86NYdo4hFkh7O8ZjSnA==} + + figures@3.2.0: + resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} + engines: {node: '>=8'} + + figures@6.1.0: + resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} + engines: {node: '>=18'} + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + filelist@1.0.6: + resolution: {integrity: sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + filter-obj@1.1.0: + resolution: {integrity: sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==} + engines: {node: '>=0.10.0'} + + finalhandler@1.1.2: + resolution: {integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==} + engines: {node: '>= 0.8'} + + finalhandler@1.3.2: + resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==} + engines: {node: '>= 0.8'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + + flow-enums-runtime@0.0.6: + resolution: {integrity: sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw==} + + fontfaceobserver@2.3.0: + resolution: {integrity: sha512-6FPvD/IVyT4ZlNe7Wcn5Fb/4ChigpucKYSvD6a+0iMoLn2inpo711eyIcKjmDtE5XNcgAkSH9uN/nfAeZzHEfg==} + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + engines: {node: '>= 6'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + + fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} + + fs-extra@9.0.0: + resolution: {integrity: sha512-pmEYSk3vYsG/bF651KPUXZ+hvjpgWYw/Gc7W9NFUe3ZVLczKKWIij3IKpOrQcdw4TILtibFslZ0UmR8Vvzig4g==} + engines: {node: '>=10'} + + fs-extra@9.1.0: + resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} + engines: {node: '>=10'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + generator-function@2.0.1: + resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} + engines: {node: '>= 0.4'} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + + get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + + get-port@5.1.1: + resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==} + engines: {node: '>=8'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-stream@4.1.0: + resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==} + engines: {node: '>=6'} + + get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} + engines: {node: '>=18'} + + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.13.6: + resolution: {integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==} + + getenv@1.0.0: + resolution: {integrity: sha512-7yetJWqbS9sbn0vIfliPsFgoXMKn/YMF+Wuiog97x+urnSRRRZ7xB+uVkwGKzRgq9CDFfMQnE9ruL5DHv9c6Xg==} + engines: {node: '>=6'} + + getenv@2.0.0: + resolution: {integrity: sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ==} + engines: {node: '>=6'} + + git-hooks-list@4.2.1: + resolution: {integrity: sha512-WNvqJjOxxs/8ZP9+DWdwWJ7cDsd60NHf39XnD82pDVrKO5q7xfPqpkK6hwEAmBa/ZSEE4IOoR75EzbbIuwGlMw==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@10.5.0: + resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + hasBin: true + + glob@13.0.6: + resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} + engines: {node: 18 || 20 || >=22} + + glob@6.0.4: + resolution: {integrity: sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@16.5.0: + resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==} + engines: {node: '>=18'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + globrex@0.1.2: + resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} + + golden-fleece@1.0.9: + resolution: {integrity: sha512-YSwLaGMOgSBx9roJlNLL12c+FRiw7VECphinc6mGucphc/ZxTHgdEz6gmJqH6NOzYEd/yr64hwjom5pZ+tJVpg==} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + gradle-to-js@2.0.1: + resolution: {integrity: sha512-is3hDn9zb8XXnjbEeAEIqxTpLHUiGBqjegLmXPuyMBfKAggpadWFku4/AP8iYAGBX6qR9/5UIUIp47V0XI3aMw==} + hasBin: true + + graphql-tag@2.12.6: + resolution: {integrity: sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==} + engines: {node: '>=10'} + peerDependencies: + graphql: ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + + graphql@16.8.1: + resolution: {integrity: sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==} + engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hast-util-to-estree@3.1.3: + resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==} + + hast-util-to-jsx-runtime@2.3.6: + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + hermes-compiler@0.14.1: + resolution: {integrity: sha512-+RPPQlayoZ9n6/KXKt5SFILWXCGJ/LV5d24L5smXrvTDrPS4L6dSctPczXauuvzFP3QEJbD1YO7Z3Ra4a+4IhA==} + + hermes-estree@0.25.1: + resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==} + + hermes-estree@0.32.0: + resolution: {integrity: sha512-KWn3BqnlDOl97Xe1Yviur6NbgIZ+IP+UVSpshlZWkq+EtoHg6/cwiDj/osP9PCEgFE15KBm1O55JRwbMEm5ejQ==} + + hermes-estree@0.32.1: + resolution: {integrity: sha512-ne5hkuDxheNBAikDjqvCZCwihnz0vVu9YsBzAEO1puiyFR4F1+PAz/SiPHSsNTuOveCYGRMX8Xbx4LOubeC0Qg==} + + hermes-estree@0.33.3: + resolution: {integrity: sha512-6kzYZHCk8Fy1Uc+t3HGYyJn3OL4aeqKLTyina4UFtWl8I0kSL7OmKThaiX+Uh2f8nGw3mo4Ifxg0M5Zk3/Oeqg==} + + hermes-parser@0.25.1: + resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==} + + hermes-parser@0.32.0: + resolution: {integrity: sha512-g4nBOWFpuiTqjR3LZdRxKUkij9iyveWeuks7INEsMX741f3r9xxrOe8TeQfUxtda0eXmiIFiMQzoeSQEno33Hw==} + + hermes-parser@0.32.1: + resolution: {integrity: sha512-175dz634X/W5AiwrpLdoMl/MOb17poLHyIqgyExlE8D9zQ1OPnoORnGMB5ltRKnpvQzBjMYvT2rN/sHeIfZW5Q==} + + hermes-parser@0.33.3: + resolution: {integrity: sha512-Yg3HgaG4CqgyowtYjX/FsnPAuZdHOqSMtnbpylbptsQ9nwwSKsy6uRWcGO5RK0EqiX12q8HvDWKgeAVajRO5DA==} + + hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + + hono@4.12.3: + resolution: {integrity: sha512-SFsVSjp8sj5UumXOOFlkZOG6XS9SJDKw0TbwFeV+AJ8xlST8kxK5Z/5EYa111UY8732lK2S/xB653ceuaoGwpg==} + engines: {node: '>=16.9.0'} + + hosted-git-info@7.0.2: + resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} + engines: {node: ^16.14.0 || >=18.0.0} + + http-call@5.3.0: + resolution: {integrity: sha512-ahwimsC23ICE4kPl9xTBjKB4inbRaeLyZeRunC/1Jy/Z6X8tv22MEAjK+KBOMSVLaqXPTTmd8638waVIKLGx2w==} + engines: {node: '>=8.0.0'} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + human-signals@8.0.1: + resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==} + engines: {node: '>=18.18.0'} + + hyperlinker@1.0.0: + resolution: {integrity: sha512-Ty8UblRWFEcfSuIaajM34LdPXIhbs1ajEX/BBPv24J+enSVaEVY63xQ6lTO9VRYS5LAoghIG0IDJ+p+IPzKUQQ==} + engines: {node: '>=4'} + + hyphenate-style-name@1.1.0: + resolution: {integrity: sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + idb@8.0.3: + resolution: {integrity: sha512-LtwtVyVYO5BqRvcsKuB2iUMnHwPVByPCXFXOpuU96IZPPoPN6xjOGxZQ74pgSVVLQWtUOYgyeL4GE98BY5D3wg==} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@5.3.0: + resolution: {integrity: sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==} + engines: {node: '>= 4'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + image-size@1.2.1: + resolution: {integrity: sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw==} + engines: {node: '>=16.x'} + hasBin: true + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + inline-style-parser@0.2.7: + resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + + inline-style-prefixer@7.0.1: + resolution: {integrity: sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw==} + + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + + interpret@1.4.0: + resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} + engines: {node: '>= 0.10'} + + invariant@2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-arrayish@0.3.4: + resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==} + + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + + is-buffer@1.1.6: + resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} + + is-bun-module@2.0.0: + resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-generator-function@1.1.2: + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + + is-interactive@1.0.0: + resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} + engines: {node: '>=8'} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-reference@1.2.1: + resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-retry-allowed@1.2.0: + resolution: {integrity: sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==} + engines: {node: '>=0.10.0'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + + is-stream@1.1.0: + resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==} + engines: {node: '>=0.10.0'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-stream@4.0.1: + resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} + engines: {node: '>=18'} + + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isbot@5.1.35: + resolution: {integrity: sha512-waFfC72ZNfwLLuJ2iLaoVaqcNo+CAaLR7xCpAn0Y5WfGzkNHv7ZN39Vbi1y+kb+Zs46XHOX3tZNExroFUPX+Kg==} + engines: {node: '>=18'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + + iterator.prototype@1.1.5: + resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} + engines: {node: '>= 0.4'} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + jake@10.9.4: + resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==} + engines: {node: '>=10'} + hasBin: true + + jest-environment-node@29.7.0: + resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-haste-map@29.7.0: + resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-message-util@29.7.0: + resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-mock@29.7.0: + resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-regex-util@29.6.3: + resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-validate@29.7.0: + resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-worker@29.7.0: + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jimp-compact@0.16.1: + resolution: {integrity: sha512-dZ6Ra7u1G8c4Letq/B5EzAxj4tLFHL+cGtdpR+PVm4yzPDj+lCk+AbivWt1eOM+ikzkowtyV7qSqX6qr3t71Ww==} + + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + + jks-js@1.1.0: + resolution: {integrity: sha512-irWi8S2V029Vic63w0/TYa8NIZwXu9oeMtHQsX51JDIVBo0lrEaOoyM8ALEEh5PVKD6TrA26FixQK6TzT7dHqA==} + + joi@17.11.0: + resolution: {integrity: sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ==} + + joi@17.13.3: + resolution: {integrity: sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==} + + join-component@1.1.0: + resolution: {integrity: sha512-bF7vcQxbODoGK1imE2P9GS9aw4zD0Sd+Hni68IMZLj7zRnquH7dXUmMw9hDI5S/Jzt7q+IyTXN0rSg2GI0IKhQ==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} + hasBin: true + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + jsc-safe-url@0.2.4: + resolution: {integrity: sha512-0wM3YBWtYePOjfyXQH5MWQ8H7sdk5EXSwZvmSLKk2RboVQ2Bu239jycHDz5J/8Blf3K0Qnoy2b6xD+z10MFB+Q==} + + jsep@1.4.0: + resolution: {integrity: sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==} + engines: {node: '>= 10.16.0'} + + jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-better-errors@1.0.2: + resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} + + json-schema-to-ts@1.6.4: + resolution: {integrity: sha512-pR4yQ9DHz6itqswtHCm26mw45FSNfQ9rEQjosaZErhn5J3J2sIViQiz8rDaezjKAhFGpmsoczYVBgGHzFw/stA==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + + jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + + keychain@1.5.0: + resolution: {integrity: sha512-liyp4r+93RI7EB2jhwaRd4MWfdgHH6shuldkaPMkELCJjMFvOOVXuTvw1pGqFfhsrgA6OqfykWWPQgBjQakVag==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + lan-network@0.2.0: + resolution: {integrity: sha512-EZgbsXMrGS+oK+Ta12mCjzBFse+SIewGdwrSTr5g+MSymnjpox2x05ceI20PQejJOFvOgzcXrfDk/SdY7dSCtw==} + hasBin: true + + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lighthouse-logger@1.4.2: + resolution: {integrity: sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==} + + lightningcss-darwin-arm64@1.30.1: + resolution: {integrity: sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.30.1: + resolution: {integrity: sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.30.1: + resolution: {integrity: sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.30.1: + resolution: {integrity: sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.30.1: + resolution: {integrity: sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.30.1: + resolution: {integrity: sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.30.1: + resolution: {integrity: sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.30.1: + resolution: {integrity: sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.30.1: + resolution: {integrity: sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.30.1: + resolution: {integrity: sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.30.1: + resolution: {integrity: sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==} + engines: {node: '>= 12.0.0'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.clonedeep@4.5.0: + resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} + + lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + + lodash.get@4.4.2: + resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} + deprecated: This package is deprecated. Use the optional chaining (?.) operator instead. + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash.throttle@4.1.1: + resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==} + + lodash@4.17.23: + resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} + + log-symbols@2.2.0: + resolution: {integrity: sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==} + engines: {node: '>=4'} + + log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@11.2.6: + resolution: {integrity: sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==} + engines: {node: 20 || >=22} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + + lucide-react@0.563.0: + resolution: {integrity: sha512-8dXPB2GI4dI8jV4MgUDGBeLdGk8ekfqVZ0BdLcrRzocGgG75ltNEmWS+gE7uokKF/0oSUuczNDT+g9hFJ23FkA==} + peerDependencies: + react: 19.2.4 + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + makeerror@1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + + markdown-extensions@2.0.0: + resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} + engines: {node: '>=16'} + + marky@1.3.0: + resolution: {integrity: sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + md5@2.3.0: + resolution: {integrity: sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==} + + mdast-util-from-markdown@2.0.3: + resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==} + + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + + mdast-util-mdx@3.0.0: + resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} + + mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-hast@13.2.1: + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + mdn-data@2.0.14: + resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} + + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + memoize-one@5.2.1: + resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==} + + memoize-one@6.0.0: + resolution: {integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==} + + merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + metro-babel-transformer@0.83.3: + resolution: {integrity: sha512-1vxlvj2yY24ES1O5RsSIvg4a4WeL7PFXgKOHvXTXiW0deLvQr28ExXj6LjwCCDZ4YZLhq6HddLpZnX4dEdSq5g==} + engines: {node: '>=20.19.4'} + + metro-babel-transformer@0.83.4: + resolution: {integrity: sha512-xfNtsYIigybqm9xVL3ygTYYNFyYTMf2lGg/Wt+znVGtwcjXoRPG80WlL5SS09ZjYVei3MoE920i7MNr7ukSULA==} + engines: {node: '>=20.19.4'} + + metro-cache-key@0.83.3: + resolution: {integrity: sha512-59ZO049jKzSmvBmG/B5bZ6/dztP0ilp0o988nc6dpaDsU05Cl1c/lRf+yx8m9WW/JVgbmfO5MziBU559XjI5Zw==} + engines: {node: '>=20.19.4'} + + metro-cache-key@0.83.4: + resolution: {integrity: sha512-Y8E6mm1alkYIRzmfkOdrwXMzJ4HKANYiZE7J2d3iYTwmnLIQG+aoIpvla+bo6LRxH1Gm3qjEiOl+LbxvPCzIug==} + engines: {node: '>=20.19.4'} + + metro-cache@0.83.3: + resolution: {integrity: sha512-3jo65X515mQJvKqK3vWRblxDEcgY55Sk3w4xa6LlfEXgQ9g1WgMh9m4qVZVwgcHoLy0a2HENTPCCX4Pk6s8c8Q==} + engines: {node: '>=20.19.4'} + + metro-cache@0.83.4: + resolution: {integrity: sha512-Pm6CiksVms0cZNDDe/nFzYr1xpXzJLOSwvOjl4b3cYtXxEFllEjD6EeBgoQK5C8yk7U54PcuRaUAFSvJ+eCKbg==} + engines: {node: '>=20.19.4'} + + metro-config@0.83.3: + resolution: {integrity: sha512-mTel7ipT0yNjKILIan04bkJkuCzUUkm2SeEaTads8VfEecCh+ltXchdq6DovXJqzQAXuR2P9cxZB47Lg4klriA==} + engines: {node: '>=20.19.4'} + + metro-config@0.83.4: + resolution: {integrity: sha512-ydOgMNI9aT8l2LOTOugt1FvC7getPKG9uJo9Vclg9/RWJxbwkBF/FMBm6w5gH8NwJokSmQrbNkojXPn7nm0kGw==} + engines: {node: '>=20.19.4'} + + metro-core@0.83.3: + resolution: {integrity: sha512-M+X59lm7oBmJZamc96usuF1kusd5YimqG/q97g4Ac7slnJ3YiGglW5CsOlicTR5EWf8MQFxxjDoB6ytTqRe8Hw==} + engines: {node: '>=20.19.4'} + + metro-core@0.83.4: + resolution: {integrity: sha512-EE+j/imryd3og/6Ly9usku9vcTLQr2o4IDax/izsr6b0HRqZK9k6f5SZkGkOPqnsACLq6csPCx+2JsgF9DkVbw==} + engines: {node: '>=20.19.4'} + + metro-file-map@0.83.3: + resolution: {integrity: sha512-jg5AcyE0Q9Xbbu/4NAwwZkmQn7doJCKGW0SLeSJmzNB9Z24jBe0AL2PHNMy4eu0JiKtNWHz9IiONGZWq7hjVTA==} + engines: {node: '>=20.19.4'} + + metro-file-map@0.83.4: + resolution: {integrity: sha512-RSZLpGQhW9topefjJ9dp77Ff7BP88b17sb/YjxLHC1/H0lJVYYC9Cgqua21Vxe4RUJK2z64hw72g+ySLGTCawA==} + engines: {node: '>=20.19.4'} + + metro-minify-terser@0.83.3: + resolution: {integrity: sha512-O2BmfWj6FSfzBLrNCXt/rr2VYZdX5i6444QJU0fFoc7Ljg+Q+iqebwE3K0eTvkI6TRjELsXk1cjU+fXwAR4OjQ==} + engines: {node: '>=20.19.4'} + + metro-minify-terser@0.83.4: + resolution: {integrity: sha512-KmZnpxfj0nPIRkbBNTc6xul5f5GPvWL5kQ1UkisB7qFkgh6+UiJG+L4ukJ2sK7St6+8Za/Cb68MUEYkUouIYcQ==} + engines: {node: '>=20.19.4'} + + metro-resolver@0.83.3: + resolution: {integrity: sha512-0js+zwI5flFxb1ktmR///bxHYg7OLpRpWZlBBruYG8OKYxeMP7SV0xQ/o/hUelrEMdK4LJzqVtHAhBm25LVfAQ==} + engines: {node: '>=20.19.4'} + + metro-resolver@0.83.4: + resolution: {integrity: sha512-drWdylyNqgdaJufz0GjU/ielv2hjcc6piegjjJwKn8l7A/72aLQpUpOHtP+GMR+kOqhSsD4MchhJ6PSANvlSEw==} + engines: {node: '>=20.19.4'} + + metro-runtime@0.83.3: + resolution: {integrity: sha512-JHCJb9ebr9rfJ+LcssFYA2x1qPYuSD/bbePupIGhpMrsla7RCwC/VL3yJ9cSU+nUhU4c9Ixxy8tBta+JbDeZWw==} + engines: {node: '>=20.19.4'} + + metro-runtime@0.83.4: + resolution: {integrity: sha512-sWj9KN311yG22Zv0kVbAp9dorB9HtTThvQKsAn6PLxrVrz+1UBsLrQSxjE/s4PtzDi1HABC648jo4K9Euz/5jw==} + engines: {node: '>=20.19.4'} + + metro-source-map@0.83.3: + resolution: {integrity: sha512-xkC3qwUBh2psVZgVavo8+r2C9Igkk3DibiOXSAht1aYRRcztEZNFtAMtfSB7sdO2iFMx2Mlyu++cBxz/fhdzQg==} + engines: {node: '>=20.19.4'} + + metro-source-map@0.83.4: + resolution: {integrity: sha512-pPbmQwS0zgU+/0u5KPkuvlsQP0V+WYQ9qNshqupIL720QRH0vS3QR25IVVtbunofEDJchI11Q4QtIbmUyhpOBw==} + engines: {node: '>=20.19.4'} + + metro-symbolicate@0.83.3: + resolution: {integrity: sha512-F/YChgKd6KbFK3eUR5HdUsfBqVsanf5lNTwFd4Ca7uuxnHgBC3kR/Hba/RGkenR3pZaGNp5Bu9ZqqP52Wyhomw==} + engines: {node: '>=20.19.4'} + hasBin: true + + metro-symbolicate@0.83.4: + resolution: {integrity: sha512-clyWAXDgkDHPwvldl95pcLTrJIqUj9GbZayL8tfeUs69ilsIUBpVym2lRd/8l3/8PIHCInxL868NvD2Y7OqKXg==} + engines: {node: '>=20.19.4'} + hasBin: true + + metro-transform-plugins@0.83.3: + resolution: {integrity: sha512-eRGoKJU6jmqOakBMH5kUB7VitEWiNrDzBHpYbkBXW7C5fUGeOd2CyqrosEzbMK5VMiZYyOcNFEphvxk3OXey2A==} + engines: {node: '>=20.19.4'} + + metro-transform-plugins@0.83.4: + resolution: {integrity: sha512-c0ROVcyvdaGPUFIg2N5nEQF4xbsqB2p1PPPhVvK1d/Y7ZhBAFiwQ75so0SJok32q+I++lc/hq7IdPCp2frPGQg==} + engines: {node: '>=20.19.4'} + + metro-transform-worker@0.83.3: + resolution: {integrity: sha512-Ztekew9t/gOIMZX1tvJOgX7KlSLL5kWykl0Iwu2cL2vKMKVALRl1hysyhUw0vjpAvLFx+Kfq9VLjnHIkW32fPA==} + engines: {node: '>=20.19.4'} + + metro-transform-worker@0.83.4: + resolution: {integrity: sha512-6I81IZLeU/0ww7OBgCPALFl0OE0FQwvIuKCtuViSiKufmislF7kVr7IHH9GYtQuZcnualQ82gYeQ11KzZQTouw==} + engines: {node: '>=20.19.4'} + + metro@0.83.3: + resolution: {integrity: sha512-+rP+/GieOzkt97hSJ0MrPOuAH/jpaS21ZDvL9DJ35QYRDlQcwzcvUlGUf79AnQxq/2NPiS/AULhhM4TKutIt8Q==} + engines: {node: '>=20.19.4'} + hasBin: true + + metro@0.83.4: + resolution: {integrity: sha512-eBkAtcob+YmvSLL+/rsFiK8dHNfDbQA2/pi0lnxg3E6LLtUpwDfdGJ9WBWXkj0PVeOhoWQyj9Rt7s/+6k/GXuA==} + engines: {node: '>=20.19.4'} + hasBin: true + + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-mdx-expression@3.0.1: + resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} + + micromark-extension-mdx-jsx@3.0.2: + resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==} + + micromark-extension-mdx-md@2.0.0: + resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} + + micromark-extension-mdxjs-esm@3.0.0: + resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} + + micromark-extension-mdxjs@3.0.0: + resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-mdx-expression@2.0.3: + resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-events-to-acorn@2.0.3: + resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + mime@3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true + + mimic-fn@1.2.0: + resolution: {integrity: sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==} + engines: {node: '>=4'} + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + minimatch@10.2.4: + resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} + engines: {node: 18 || 20 || >=22} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + minimatch@5.1.2: + resolution: {integrity: sha512-bNH9mmM9qsJ2X4r2Nat1B//1dJVcn3+iBLa3IgqJ7EbGaDNepL9QSHOxN4ng33s52VMMhhIfgCYDk3C4ZmlDAg==} + engines: {node: '>=10'} + + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@3.0.1: + resolution: {integrity: sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==} + engines: {node: '>= 18'} + + minizlib@3.1.0: + resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} + engines: {node: '>= 18'} + + mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + moment@2.30.1: + resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} + + morgan@1.10.1: + resolution: {integrity: sha512-223dMRJtI/l25dJKWpgij2cMtywuG/WiUKXdvwfbhGKBhy1puASqXwFzmWZ7+K73vUPoR7SS2Qz2cI/g9MKw0A==} + engines: {node: '>= 0.8.0'} + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + multipasta@0.2.7: + resolution: {integrity: sha512-KPA58d68KgGil15oDqXjkUBEBYc00XvbPj5/X+dyzeo/lWm9Nc25pQRlf1D+gv4OpK7NM0J1odrbu9JNNGvynA==} + + multitars@0.2.4: + resolution: {integrity: sha512-XgLbg1HHchFauMCQPRwMj6MSyDd5koPlTA1hM3rUFkeXzGpjU/I9fP3to7yrObE9jcN8ChIOQGrM0tV0kUZaKg==} + + mute-stream@0.0.8: + resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} + + mv@2.1.1: + resolution: {integrity: sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==} + engines: {node: '>=0.8.0'} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nan@2.25.0: + resolution: {integrity: sha512-0M90Ag7Xn5KMLLZ7zliPWP3rT90P6PN+IzVFS0VqmnPktBk3700xUVv8Ikm9EUaUE5SDWdp/BIxdENzVznpm1g==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanoid@3.3.8: + resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + napi-postinstall@0.3.4: + resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + hasBin: true + + nativewind@5.0.0-preview.2: + resolution: {integrity: sha512-rTNrwFIwl/n2VH7KPvsZj/NdvKf+uGHF4NYtPamr5qG2eTYGT8B8VeyCPfYf/xUskpWOLJVqVEXaFO/vuIDEdw==} + engines: {node: '>=20'} + peerDependencies: + react-native-css: ^3.0.1 + tailwindcss: '>4.1.11' + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + natural-orderby@2.0.3: + resolution: {integrity: sha512-p7KTHxU0CUrcOXe62Zfrb5Z13nLvPhSWR/so3kFulUQU0sgUll2Z0LwpsLN351eOOD+hRGu/F1g+6xDfPeD++Q==} + + ncp@2.0.0: + resolution: {integrity: sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==} + hasBin: true + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + negotiator@0.6.4: + resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} + engines: {node: '>= 0.6'} + + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + + nice-try@1.0.5: + resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} + + node-exports-info@1.6.0: + resolution: {integrity: sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==} + engines: {node: '>= 0.4'} + + node-fetch@2.6.7: + resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-forge@1.3.1: + resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} + engines: {node: '>= 6.13.0'} + + node-forge@1.3.3: + resolution: {integrity: sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==} + engines: {node: '>= 6.13.0'} + + node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + + node-releases@2.0.27: + resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + + node-rsa@1.1.1: + resolution: {integrity: sha512-Jd4cvbJMryN21r5HgxQOpMEqv+ooke/korixNNK3mGqfGJmy0M77WDDzo/05969+OkMy3XW1UuZsSmW9KQm7Fw==} + + node-stream-zip@1.15.0: + resolution: {integrity: sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw==} + engines: {node: '>=0.12.0'} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + npm-package-arg@11.0.3: + resolution: {integrity: sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw==} + engines: {node: ^16.14.0 || >=18.0.0} + + npm-run-path@2.0.2: + resolution: {integrity: sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==} + engines: {node: '>=4'} + + npm-run-path@6.0.0: + resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} + engines: {node: '>=18'} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + nullthrows@1.1.1: + resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==} + + ob1@0.83.3: + resolution: {integrity: sha512-egUxXCDwoWG06NGCS5s5AdcpnumHKJlfd3HH06P3m9TEMwwScfcY35wpQxbm9oHof+dM/lVH9Rfyu1elTVelSA==} + engines: {node: '>=20.19.4'} + + ob1@0.83.4: + resolution: {integrity: sha512-9JiflaRKCkxKzH8uuZlax72cHzZ8iFLsNIORFOAKDgZUOfvfwYWOVS0ezGLzPp/yEhVktD+PTTImC0AAehSOBw==} + engines: {node: '>=20.19.4'} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object-treeify@1.1.33: + resolution: {integrity: sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==} + engines: {node: '>= 10'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + object.entries@1.1.9: + resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + engines: {node: '>= 0.4'} + + obug@2.1.1: + resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + + on-finished@2.3.0: + resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==} + engines: {node: '>= 0.8'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + on-headers@1.1.0: + resolution: {integrity: sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@2.0.1: + resolution: {integrity: sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==} + engines: {node: '>=4'} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + open@7.4.2: + resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==} + engines: {node: '>=8'} + + open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + ora@3.4.0: + resolution: {integrity: sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==} + engines: {node: '>=6'} + + ora@5.1.0: + resolution: {integrity: sha512-9tXIMPvjZ7hPTbk8DFq1f7Kow/HU/pQYB60JbNq+QnGwcyhWVZaQ4hM9zQDEsPxw/muLpgiHSaumUZxCAmod/w==} + engines: {node: '>=10'} + + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + + p-finally@1.0.0: + resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} + engines: {node: '>=4'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-map@7.0.4: + resolution: {integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==} + engines: {node: '>=18'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + + parse-json@4.0.0: + resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} + engines: {node: '>=4'} + + parse-ms@4.0.0: + resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} + engines: {node: '>=18'} + + parse-png@2.1.0: + resolution: {integrity: sha512-Nt/a5SfCLiTnQAjx3fHlqp8hRgTL3z7kTQZzvIMS9uCAepnCyjpdEc6M/sz69WqMBdaDBw9sF1F1UaHROYzGkQ==} + engines: {node: '>=10'} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + password-prompt@1.1.3: + resolution: {integrity: sha512-HkrjG2aJlvF0t2BMH0e2LB/EHf3Lcq3fNMzy4GYHcQblAvOl+QQji1Lx7WRBMqpVK8p+KR7bCg7oqAMXtdgqyw==} + + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@2.0.1: + resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} + engines: {node: '>=4'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-scurry@2.0.2: + resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} + engines: {node: 18 || 20 || >=22} + + path-to-regexp@0.1.12: + resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + engines: {node: '>= 6'} + + pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + + pkg-types@2.3.0: + resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} + + plist@3.1.0: + resolution: {integrity: sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==} + engines: {node: '>=10.4.0'} + + pngjs@3.4.0: + resolution: {integrity: sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==} + engines: {node: '>=4.0.0'} + + pngjs@7.0.0: + resolution: {integrity: sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==} + engines: {node: '>=14.19.0'} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postcss-less@6.0.0: + resolution: {integrity: sha512-FPX16mQLyEjLzEuuJtxA8X3ejDLNGGEG503d2YGZR5Ask1SpDN8KmZUMpzCvyalWRywAn1n1VOA5dcqfCLo5rg==} + engines: {node: '>=12'} + peerDependencies: + postcss: ^8.3.5 + + postcss-scss@4.0.9: + resolution: {integrity: sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.4.29 + + postcss-selector-parser@6.0.10: + resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} + engines: {node: '>=4'} + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@8.4.49: + resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} + engines: {node: ^10 || ^12 || >=14} + + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-plugin-css-order@2.2.0: + resolution: {integrity: sha512-GCkwEgQ2roT7le+zpUFQThPDO4x5EXcZmY9Rj6rvO++I/nATTGBWdZdsooha/BlvIBbZclJzXsgJdlKWrys9+w==} + engines: {node: '>=16'} + peerDependencies: + prettier: 3.x + + prettier-plugin-packagejson@2.5.22: + resolution: {integrity: sha512-G6WalmoUssKF8ZXkni0+n4324K+gG143KPysSQNW+FrR0XyNb3BdRxchGC/Q1FE/F702p7/6KU7r4mv0WSWbzA==} + peerDependencies: + prettier: '>= 1.16.0' + peerDependenciesMeta: + prettier: + optional: true + + prettier-plugin-tailwindcss@0.7.2: + resolution: {integrity: sha512-LkphyK3Fw+q2HdMOoiEHWf93fNtYJwfamoKPl7UwtjFQdei/iIBoX11G6j706FzN3ymX9mPVi97qIY8328vdnA==} + engines: {node: '>=20.19'} + peerDependencies: + '@ianvs/prettier-plugin-sort-imports': '*' + '@prettier/plugin-hermes': '*' + '@prettier/plugin-oxc': '*' + '@prettier/plugin-pug': '*' + '@shopify/prettier-plugin-liquid': '*' + '@trivago/prettier-plugin-sort-imports': '*' + '@zackad/prettier-plugin-twig': '*' + prettier: ^3.0 + prettier-plugin-astro: '*' + prettier-plugin-css-order: '*' + prettier-plugin-jsdoc: '*' + prettier-plugin-marko: '*' + prettier-plugin-multiline-arrays: '*' + prettier-plugin-organize-attributes: '*' + prettier-plugin-organize-imports: '*' + prettier-plugin-sort-imports: '*' + prettier-plugin-svelte: '*' + peerDependenciesMeta: + '@ianvs/prettier-plugin-sort-imports': + optional: true + '@prettier/plugin-hermes': + optional: true + '@prettier/plugin-oxc': + optional: true + '@prettier/plugin-pug': + optional: true + '@shopify/prettier-plugin-liquid': + optional: true + '@trivago/prettier-plugin-sort-imports': + optional: true + '@zackad/prettier-plugin-twig': + optional: true + prettier-plugin-astro: + optional: true + prettier-plugin-css-order: + optional: true + prettier-plugin-jsdoc: + optional: true + prettier-plugin-marko: + optional: true + prettier-plugin-multiline-arrays: + optional: true + prettier-plugin-organize-attributes: + optional: true + prettier-plugin-organize-imports: + optional: true + prettier-plugin-sort-imports: + optional: true + prettier-plugin-svelte: + optional: true + + prettier@3.8.1: + resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} + engines: {node: '>=14'} + hasBin: true + + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + pretty-ms@9.3.0: + resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==} + engines: {node: '>=18'} + + proc-log@4.2.0: + resolution: {integrity: sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + + promise-limit@2.7.0: + resolution: {integrity: sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw==} + + promise-retry@2.0.1: + resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} + engines: {node: '>=10'} + + promise@7.3.1: + resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==} + + promise@8.3.0: + resolution: {integrity: sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + pump@3.0.3: + resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + qrcode-terminal@0.12.0: + resolution: {integrity: sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ==} + hasBin: true + + qs@6.14.2: + resolution: {integrity: sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==} + engines: {node: '>=0.6'} + + query-string@7.1.3: + resolution: {integrity: sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==} + engines: {node: '>=6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + queue@6.0.2: + resolution: {integrity: sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.3: + resolution: {integrity: sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==} + engines: {node: '>= 0.8'} + + react-devtools-core@6.1.5: + resolution: {integrity: sha512-ePrwPfxAnB+7hgnEr8vpKxL9cmnp7F322t8oqcPshbIQQhDKgFDW4tjhF2wjVbdXF9O/nyuy3sQWd9JGpiLPvA==} + + react-dom@19.2.4: + resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==} + peerDependencies: + react: 19.2.4 + + react-fast-compare@3.2.2: + resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} + + react-freeze@1.0.4: + resolution: {integrity: sha512-r4F0Sec0BLxWicc7HEyo2x3/2icUTrRmDjaaRyzzn+7aDyFZliszMDOgLVwSnQnYENOlL1o569Ze2HZefk8clA==} + engines: {node: '>=10'} + peerDependencies: + react: 19.2.4 + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + + react-is@19.2.4: + resolution: {integrity: sha512-W+EWGn2v0ApPKgKKCy/7s7WHXkboGcsrXE+2joLyVxkbyVQfO3MUEaUQDHoSmb8TFFrSKYa9mw64WZHNHSDzYA==} + + react-native-css@3.0.4: + resolution: {integrity: sha512-umgNS/EePf6jNttPhZjOykfVQFTKpX0H0VMiZIA5RMZNp+5n9uc45PKl3QYXNoBAWzAnalRTysCMtLGYlmHOQw==} + peerDependencies: + '@expo/metro-config': '>=54' + lightningcss: 1.30.1 + react: 19.2.4 + react-native: '>=0.81' + + react-native-gesture-handler@2.30.0: + resolution: {integrity: sha512-5YsnKHGa0X9C8lb5oCnKm0fLUPM6CRduvUUw2Bav4RIj/C3HcFh4RIUnF8wgG6JQWCL1//gRx4v+LVWgcIQdGA==} + peerDependencies: + react: 19.2.4 + react-native: '*' + + react-native-is-edge-to-edge@1.2.1: + resolution: {integrity: sha512-FLbPWl/MyYQWz+KwqOZsSyj2JmLKglHatd3xLZWskXOpRaio4LfEDEz8E/A6uD8QoTHW6Aobw1jbEwK7KMgR7Q==} + peerDependencies: + react: 19.2.4 + react-native: '*' + + react-native-reanimated@4.2.1: + resolution: {integrity: sha512-/NcHnZMyOvsD/wYXug/YqSKw90P9edN0kEPL5lP4PFf1aQ4F1V7MKe/E0tvfkXKIajy3Qocp5EiEnlcrK/+BZg==} + peerDependencies: + react: 19.2.4 + react-native: '*' + react-native-worklets: '>=0.7.0' + + react-native-safe-area-context@5.6.2: + resolution: {integrity: sha512-4XGqMNj5qjUTYywJqpdWZ9IG8jgkS3h06sfVjfw5yZQZfWnRFXczi0GnYyFyCc2EBps/qFmoCH8fez//WumdVg==} + peerDependencies: + react: 19.2.4 + react-native: '*' + + react-native-screens@4.23.0: + resolution: {integrity: sha512-XhO3aK0UeLpBn4kLecd+J+EDeRRJlI/Ro9Fze06vo1q163VeYtzfU9QS09/VyDFMWR1qxDC1iazCArTPSFFiPw==} + peerDependencies: + react: 19.2.4 + react-native: '*' + + react-native-svg@15.15.3: + resolution: {integrity: sha512-/k4KYwPBLGcx2f5d4FjE+vCScK7QOX14cl2lIASJ28u4slHHtIhL0SZKU7u9qmRBHxTCKPoPBtN6haT1NENJNA==} + peerDependencies: + react: 19.2.4 + react-native: '*' + + react-native-web@0.21.2: + resolution: {integrity: sha512-SO2t9/17zM4iEnFvlu2DA9jqNbzNhoUP+AItkoCOyFmDMOhUnBBznBDCYN92fGdfAkfQlWzPoez6+zLxFNsZEg==} + peerDependencies: + react: 19.2.4 + react-dom: 19.2.4 + + react-native-worklets@0.7.2: + resolution: {integrity: sha512-DuLu1kMV/Uyl9pQHp3hehAlThoLw7Yk2FwRTpzASOmI+cd4845FWn3m2bk9MnjUw8FBRIyhwLqYm2AJaXDXsog==} + peerDependencies: + '@babel/core': '*' + react: 19.2.4 + react-native: '*' + + react-native@0.83.2: + resolution: {integrity: sha512-ZDma3SLkRN2U2dg0/EZqxNBAx4of/oTnPjXAQi299VLq2gdnbZowGy9hzqv+O7sTA62g+lM1v+2FM5DUnJ/6hg==} + engines: {node: '>= 20.19.4'} + hasBin: true + peerDependencies: + '@types/react': ^19.1.1 + react: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + + react-refresh@0.14.2: + resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} + engines: {node: '>=0.10.0'} + + react-remove-scroll-bar@2.3.8: + resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.7.2: + resolution: {integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + + react-router-hono-server@2.25.0: + resolution: {integrity: sha512-w/qAMf7DpFGK1cywMi2b7BRR2u8Bux3JR3bOe15tOtVyJj4pDKomgTWXzC1ASMaPdGik3VvSxCn0+/9aZrWriA==} + engines: {node: '>=22.20.0'} + hasBin: true + peerDependencies: + '@cloudflare/workers-types': ^4.20250317.0 + '@hono/node-server': ^1.19.0 + '@react-router/dev': ^7.9.0 + '@types/react': ^19.0.0 + hono: ^4.11.0 + miniflare: ^3.20241205.0 + react-router: ^7.9.0 + vite: ^7.0.0 + wrangler: ^4.2.0 + peerDependenciesMeta: + '@cloudflare/workers-types': + optional: true + miniflare: + optional: true + wrangler: + optional: true + + react-router@7.13.1: + resolution: {integrity: sha512-td+xP4X2/6BJvZoX6xw++A2DdEi++YypA69bJUV5oVvqf6/9/9nNlD70YO1e9d3MyamJEBQFEzk6mbfDYbqrSA==} + engines: {node: '>=20.0.0'} + peerDependencies: + react: 19.2.4 + react-dom: 19.2.4 + peerDependenciesMeta: + react-dom: + optional: true + + react-style-singleton@2.2.3: + resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + + react@19.2.4: + resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} + engines: {node: '>=0.10.0'} + + readable-stream@4.7.0: + resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + rechoir@0.6.2: + resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} + engines: {node: '>= 0.10'} + + recma-build-jsx@1.0.0: + resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} + + recma-jsx@1.0.1: + resolution: {integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + recma-parse@1.0.0: + resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} + + recma-stringify@1.0.0: + resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} + + redeyed@2.1.1: + resolution: {integrity: sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==} + + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + + regenerate-unicode-properties@10.2.2: + resolution: {integrity: sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==} + engines: {node: '>=4'} + + regenerate@1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + + regenerator-runtime@0.13.11: + resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} + + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + + regexpu-core@6.4.0: + resolution: {integrity: sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==} + engines: {node: '>=4'} + + regjsgen@0.8.0: + resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} + + regjsparser@0.13.0: + resolution: {integrity: sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==} + hasBin: true + + rehype-recma@1.0.0: + resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + + remark-mdx@3.1.1: + resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-rehype@11.1.2: + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} + + remove-trailing-slash@0.1.1: + resolution: {integrity: sha512-o4S4Qh6L2jpnCy83ysZDau+VORNvnFw07CKSAymkd6ICNVEPisMyzlc00KlvvicsxKck94SEwhDnMNdICzO+tA==} + + replicate@1.4.0: + resolution: {integrity: sha512-1ufKejfUVz/azy+5TnzQP7U1+MHVWZ6psnQ06az8byUUnRhT+DZ/MvewzB1NQYBVMgNKR7xPDtTwlcP5nv/5+w==} + engines: {git: '>=2.11.0', node: '>=18.0.0', npm: '>=7.19.0', yarn: '>=1.7.0'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve-workspace-root@2.0.1: + resolution: {integrity: sha512-nR23LHAvaI6aHtMg6RWoaHpdR4D881Nydkzi2CixINyg9T00KgaJdJI6Vwty+Ps8WLxZHuxsS0BseWjxSA4C+w==} + + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + engines: {node: '>= 0.4'} + hasBin: true + + resolve@2.0.0-next.6: + resolution: {integrity: sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==} + engines: {node: '>= 0.4'} + hasBin: true + + restore-cursor@2.0.0: + resolution: {integrity: sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==} + engines: {node: '>=4'} + + restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + + retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rimraf@2.4.5: + resolution: {integrity: sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rimraf@5.0.10: + resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} + hasBin: true + + rollup-plugin-dts@6.3.0: + resolution: {integrity: sha512-d0UrqxYd8KyZ6i3M2Nx7WOMy708qsV/7fTHMHxCMCBOAe3V/U7OMPu5GkX8hC+cmkHhzGnfeYongl1IgiooddA==} + engines: {node: '>=16'} + peerDependencies: + rollup: ^3.29.4 || ^4 + typescript: ^4.5 || ^5.0 + + rollup-plugin-esbuild@6.2.1: + resolution: {integrity: sha512-jTNOMGoMRhs0JuueJrJqbW8tOwxumaWYq+V5i+PD+8ecSCVkuX27tGW7BXqDgoULQ55rO7IdNxPcnsWtshz3AA==} + engines: {node: '>=14.18.0'} + peerDependencies: + esbuild: '>=0.18.0' + rollup: ^1.20.0 || ^2.0.0 || ^3.0.0 || ^4.0.0 + + rollup-plugin-node-externals@8.1.2: + resolution: {integrity: sha512-EuB6/lolkMLK16gvibUjikERq5fCRVIGwD2xue/CrM8D0pz5GXD2V6N8IrgxegwbcUoKkUFI8VYCEEv8MMvgpA==} + engines: {node: '>= 21 || ^20.6.0 || ^18.19.0'} + peerDependencies: + rollup: ^4.0.0 + + rollup-presets@0.0.26: + resolution: {integrity: sha512-ZJzxk66Tl210pA1wo2XyVOcwEjNyJ1L86XV2eI3DZfJo6/9W4hxbzgzJ3cUl6uMdnhYWv52MBq74uEITjw0OcA==} + + rollup@4.59.0: + resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-array-concat@1.1.3: + resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} + engines: {node: '>=0.4'} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-json-stringify@1.2.0: + resolution: {integrity: sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==} + + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sax@1.4.4: + resolution: {integrity: sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==} + engines: {node: '>=11.0.0'} + + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.5.2: + resolution: {integrity: sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==} + engines: {node: '>=10'} + hasBin: true + + semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + + semver@7.7.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} + engines: {node: '>=10'} + hasBin: true + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + send@0.19.2: + resolution: {integrity: sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==} + engines: {node: '>= 0.8.0'} + + serialize-error@2.1.0: + resolution: {integrity: sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw==} + engines: {node: '>=0.10.0'} + + serve-static@1.16.3: + resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==} + engines: {node: '>= 0.8.0'} + + server-only@0.0.1: + resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==} + + set-cookie-parser@2.7.2: + resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-interval-async@3.0.3: + resolution: {integrity: sha512-o4DyBv6mko+A9cH3QKek4SAAT5UyJRkfdTi6JHii6ZCKUYFun8SwgBmQrOXd158JOwBQzA+BnO8BvT64xuCaSw==} + engines: {node: '>= 14.0.0'} + + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + + setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + sf-symbols-typescript@2.2.0: + resolution: {integrity: sha512-TPbeg0b7ylrswdGCji8FRGFAKuqbpQlLbL8SOle3j1iHSs5Ob5mhvMAxWN2UItOjgALAB5Zp3fmMfj8mbWvXKw==} + engines: {node: '>=10'} + + shallowequal@1.1.0: + resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==} + + sharp@0.34.5: + resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + + shebang-command@1.2.0: + resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} + engines: {node: '>=0.10.0'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@1.0.0: + resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} + engines: {node: '>=0.10.0'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shell-quote@1.8.3: + resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} + engines: {node: '>= 0.4'} + + shelljs@0.9.2: + resolution: {integrity: sha512-S3I64fEiKgTZzKCC46zT/Ib9meqofLrQVbpSswtjFfAVDW+AZ54WTnAM/3/yENoxz/V1Cy6u3kiiEbQ4DNphvw==} + engines: {node: '>=18'} + hasBin: true + + shx@0.4.0: + resolution: {integrity: sha512-Z0KixSIlGPpijKgcH6oCMCbltPImvaKy0sGH8AkLRXw1KyzpKtaCTizP2xen+hNDqVF4xxgvA0KXSb9o4Q6hnA==} + engines: {node: '>=18'} + hasBin: true + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + simple-plist@1.3.1: + resolution: {integrity: sha512-iMSw5i0XseMnrhtIzRb7XpQEXepa9xhWxGUojHBL43SIpQuDQkh3Wpy67ZbDzZVr6EKxvwVChnVpdl8hEVLDiw==} + + simple-swizzle@0.2.4: + resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slice-ansi@4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + + slugify@1.6.6: + resolution: {integrity: sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==} + engines: {node: '>=8.0.0'} + + sort-object-keys@2.1.0: + resolution: {integrity: sha512-SOiEnthkJKPv2L6ec6HMwhUcN0/lppkeYuN1x63PbyPRrgSPIuBJCiYxYyvWRTtjMlOi14vQUCGUJqS6PLVm8g==} + + sort-package-json@3.6.0: + resolution: {integrity: sha512-fyJsPLhWvY7u2KsKPZn1PixbXp+1m7V8NWqU8CvgFRbMEX41Ffw1kD8n0CfJiGoaSfoAvbrqRRl/DcHO8omQOQ==} + engines: {node: '>=20'} + hasBin: true + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.5.7: + resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} + engines: {node: '>=0.10.0'} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + split-on-first@1.1.0: + resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==} + engines: {node: '>=6'} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + stable-hash@0.0.5: + resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==} + + stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + stackframe@1.3.4: + resolution: {integrity: sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==} + + stacktrace-parser@0.1.11: + resolution: {integrity: sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg==} + engines: {node: '>=6'} + + statuses@1.5.0: + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} + engines: {node: '>= 0.6'} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + + stop-iteration-iterator@1.1.0: + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} + engines: {node: '>= 0.4'} + + stream-buffers@2.2.0: + resolution: {integrity: sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg==} + engines: {node: '>= 0.10.0'} + + streamx@2.23.0: + resolution: {integrity: sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==} + + strict-uri-encode@2.0.0: + resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==} + engines: {node: '>=4'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string.prototype.matchall@4.0.12: + resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} + engines: {node: '>= 0.4'} + + string.prototype.repeat@1.0.0: + resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} + + string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + strip-ansi@5.2.0: + resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} + engines: {node: '>=6'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-eof@1.0.0: + resolution: {integrity: sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==} + engines: {node: '>=0.10.0'} + + strip-final-newline@4.0.0: + resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} + engines: {node: '>=18'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + structured-headers@0.4.1: + resolution: {integrity: sha512-0MP/Cxx5SzeeZ10p/bZI0S6MpgD+yxAhi1BOQ34jgnMXsCq3j1t6tQnZu+KdlL7dvJTLT3g9xN8tl10TqgFMcg==} + + style-to-js@1.1.21: + resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} + + style-to-object@1.0.14: + resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} + + styleq@0.1.3: + resolution: {integrity: sha512-3ZUifmCDCQanjeej1f6kyl/BeP/Vae5EYkQ9iJfUm/QwZvlgnZzyflqAsAWYURdtea8Vkvswu2GrC57h3qffcA==} + + sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-hyperlinks@2.3.0: + resolution: {integrity: sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + tailwind-merge@3.5.0: + resolution: {integrity: sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==} + + tailwindcss-safe-area@1.3.0: + resolution: {integrity: sha512-RoxnW1zAjBWC3XK+row7Qj5toRMRlKNN/p3FLXb6fTGKxDGWT6JP/mcNX1yf09xRficQ308hbwiedgniepSp1Q==} + engines: {node: '>=20'} + peerDependencies: + tailwindcss: ^4.0.0 + + tailwindcss@4.2.1: + resolution: {integrity: sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==} + + tapable@2.3.0: + resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} + engines: {node: '>=6'} + + tar-stream@3.1.7: + resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} + + tar@7.5.7: + resolution: {integrity: sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==} + engines: {node: '>=18'} + deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + + temp-dir@2.0.0: + resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} + engines: {node: '>=8'} + + terminal-link@2.1.1: + resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==} + engines: {node: '>=8'} + + terser@5.46.0: + resolution: {integrity: sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==} + engines: {node: '>=10'} + hasBin: true + + test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + + text-decoder@1.2.7: + resolution: {integrity: sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==} + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + throat@5.0.0: + resolution: {integrity: sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@1.0.2: + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} + engines: {node: '>=18'} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + tinyrainbow@3.0.3: + resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} + engines: {node: '>=14.0.0'} + + tmpl@1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + toqr@0.1.1: + resolution: {integrity: sha512-FWAPzCIHZHnrE/5/w9MPk0kK25hSQSH2IKhYh9PyjS3SG/+IEMvlwIHbhz+oF7xl54I+ueZlVnMjyzdSwLmAwA==} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + + ts-api-utils@2.4.0: + resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + ts-deepmerge@6.2.0: + resolution: {integrity: sha512-2qxI/FZVDPbzh63GwWIZYE7daWKtwXZYuyc8YNq0iTmMUwn4mL0jRLsp6hfFlgbdRSR4x2ppe+E86FnvEpN7Nw==} + engines: {node: '>=14.13.1'} + + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + ts-morph@12.0.0: + resolution: {integrity: sha512-VHC8XgU2fFW7yO1f/b3mxKDje1vmyzFXHWzOYmKEkCEwcLjDtbdLgBQviqj4ZwP4MJkQtRo6Ha2I29lq/B+VxA==} + + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + + ts-toolbelt@6.15.5: + resolution: {integrity: sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==} + + tsconfck@3.1.6: + resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==} + engines: {node: ^18 || >=20} + hasBin: true + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tslib@2.4.1: + resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} + + tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tsx@4.21.0: + resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} + engines: {node: '>=18.0.0'} + hasBin: true + + tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + + tuple-result@0.0.11: + resolution: {integrity: sha512-h4T8ut4Aon/biceYKifPwhjUtmC+O7gXVBLOeeD9vHdBb2kBttAiEhiMBaBhl4YR122AGk5BYB0IaDVNib6Sig==} + + turbo-darwin-64@2.8.11: + resolution: {integrity: sha512-XKaCWaz4OCt77oYYvGCIRpvYD4c/aNaKjRkUpv+e8rN3RZb+5Xsyew4yRO+gaHdMIUhQznXNXfHlhs+/p7lIhA==} + cpu: [x64] + os: [darwin] + + turbo-darwin-arm64@2.8.11: + resolution: {integrity: sha512-VvynLHGUNvQ9k7GZjRPSsRcK4VkioTfFb7O7liAk4nHKjEcMdls7GqxzjVWgJiKz3hWmQGaP9hRa9UUnhVWCxA==} + cpu: [arm64] + os: [darwin] + + turbo-linux-64@2.8.11: + resolution: {integrity: sha512-cbSn37dcm+EmkQ7DD0euy7xV7o2el4GAOr1XujvkAyKjjNvQ+6QIUeDgQcwAx3D17zPpDvfDMJY2dLQadWnkmQ==} + cpu: [x64] + os: [linux] + + turbo-linux-arm64@2.8.11: + resolution: {integrity: sha512-+trymp2s2aBrhS04l6qFxcExzZ8ffndevuUB9c5RCeqsVpZeiWuGQlWNm5XjOmzoMayxRARZ5ma7yiWbGMiLqQ==} + cpu: [arm64] + os: [linux] + + turbo-windows-64@2.8.11: + resolution: {integrity: sha512-3kJjFSM4yw1n9Uzmi+XkAUgCae19l/bH6RJ442xo7mnZm0tpOjo33F+FYHoSVpIWVMd0HG0LDccyafPSdylQbA==} + cpu: [x64] + os: [win32] + + turbo-windows-arm64@2.8.11: + resolution: {integrity: sha512-JOM4uF2vuLsJUvibdR6X9QqdZr6BhC6Nhlrw4LKFPsXZZI/9HHLoqAiYRpE4MuzIwldCH/jVySnWXrI1SKto0g==} + cpu: [arm64] + os: [win32] + + turbo@2.8.11: + resolution: {integrity: sha512-H+rwSHHPLoyPOSoHdmI1zY0zy0GGj1Dmr7SeJW+nZiWLz2nex8EJ+fkdVabxXFMNEux+aywI4Sae8EqhmnOv4A==} + hasBin: true + + turndown@7.1.2: + resolution: {integrity: sha512-ntI9R7fcUKjqBP6QU8rBK2Ehyt8LAzt3UBT9JR9tgo6GtuKvyUzpayWmeMKJw1DPdXzktvtIT8m2mVXz+bL/Qg==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + type-fest@0.7.1: + resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==} + engines: {node: '>=8'} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + engines: {node: '>= 0.4'} + + typescript-eslint@8.56.1: + resolution: {integrity: sha512-U4lM6pjmBX7J5wk4szltF7I1cGBHXZopnAXCMXb3+fZ3B/0Z3hq3wS/CCUB2NZBNAExK92mCU2tEohWuwVMsDQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.0.0' + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + ua-parser-js@0.7.41: + resolution: {integrity: sha512-O3oYyCMPYgNNHuO7Jjk3uacJWZF8loBgwrfd/5LE/HyZ3lUIOdniQ7DNXJcIgZbwioZxk0fLfI4EVnetdiX5jg==} + hasBin: true + + ua-parser-js@1.0.41: + resolution: {integrity: sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug==} + hasBin: true + + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + + undici-types@7.18.2: + resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} + + unicode-canonical-property-names-ecmascript@2.0.1: + resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==} + engines: {node: '>=4'} + + unicode-match-property-ecmascript@2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + + unicode-match-property-value-ecmascript@2.2.1: + resolution: {integrity: sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==} + engines: {node: '>=4'} + + unicode-property-aliases-ecmascript@2.2.0: + resolution: {integrity: sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==} + engines: {node: '>=4'} + + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unique-string@2.0.0: + resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} + engines: {node: '>=8'} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-position-from-estree@2.0.0: + resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.1.0: + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + + universalify@1.0.0: + resolution: {integrity: sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==} + engines: {node: '>= 10.0.0'} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + unplugin-utils@0.2.5: + resolution: {integrity: sha512-gwXJnPRewT4rT7sBi/IvxKTjsms7jX7QIDLOClApuZwR49SXbrB1z2NLUZ+vDHyqCj/n58OzRRqaW+B8OZi8vg==} + engines: {node: '>=18.12.0'} + + unrs-resolver@1.11.1: + resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} + + untildify@4.0.0: + resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} + engines: {node: '>=8'} + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + use-callback-ref@1.3.3: + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + + use-latest-callback@0.2.6: + resolution: {integrity: sha512-FvRG9i1HSo0wagmX63Vrm8SnlUU3LMM3WyZkQ76RnslpBrX694AdG4A0zQBx2B3ZifFA0yv/BaEHGBnEax5rZg==} + peerDependencies: + react: 19.2.4 + + use-sidecar@1.1.3: + resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: 19.2.4 + peerDependenciesMeta: + '@types/react': + optional: true + + use-sync-external-store@1.6.0: + resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + peerDependencies: + react: 19.2.4 + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + uuid@7.0.3: + resolution: {integrity: sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==} + hasBin: true + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + + valibot@1.2.0: + resolution: {integrity: sha512-mm1rxUsmOxzrwnX5arGS+U4T25RdvpPjPN4yR0u9pUBov9+zGVtO84tif1eY4r6zWxVxu3KzIyknJy3rxfRZZg==} + peerDependencies: + typescript: '>=5' + peerDependenciesMeta: + typescript: + optional: true + + validate-npm-package-name@5.0.1: + resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + vaul@1.1.2: + resolution: {integrity: sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA==} + peerDependencies: + react: 19.2.4 + react-dom: 19.2.4 + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + vite-node@3.2.4: + resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + + vite-tsconfig-paths@6.1.1: + resolution: {integrity: sha512-2cihq7zliibCCZ8P9cKJrQBkfgdvcFkOOc3Y02o3GWUDLgqjWsZudaoiuOwO/gzTzy17cS5F7ZPo4bsnS4DGkg==} + peerDependencies: + vite: '*' + + vite@7.3.1: + resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: 1.30.1 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitest@4.0.18: + resolution: {integrity: sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.0.18 + '@vitest/browser-preview': 4.0.18 + '@vitest/browser-webdriverio': 4.0.18 + '@vitest/ui': 4.0.18 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@opentelemetry/api': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + vlq@1.0.1: + resolution: {integrity: sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==} + + walker@1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + + warn-once@0.1.1: + resolution: {integrity: sha512-VkQZJbO8zVImzYFteBXvBOZEl1qL175WH8VmZcxF2fZAoudNhNDvHi+doCaAEdU2l2vtcIwa2zn0QK5+I1HQ3Q==} + + wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + whatwg-fetch@3.6.20: + resolution: {integrity: sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==} + + whatwg-url-minimum@0.1.1: + resolution: {integrity: sha512-u2FNVjFVFZhdjb502KzXy1gKn1mEisQRJssmSJT8CPhZdZa0AP6VCbWlXERKyGu0l09t0k50FiDiralpGhBxgA==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.20: + resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} + engines: {node: '>= 0.4'} + + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + widest-line@3.1.0: + resolution: {integrity: sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==} + engines: {node: '>=8'} + + wonka@6.3.5: + resolution: {integrity: sha512-SSil+ecw6B4/Dm7Pf2sAshKQ5hWFvfyGlfPbEd6A14dOH6VDjrmbY86u6nZvy9omGwwIPFR8V41+of1EezgoUw==} + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + write-file-atomic@2.4.3: + resolution: {integrity: sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==} + + write-file-atomic@4.0.2: + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + ws@7.5.10: + resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.19.0: + resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xcode@3.0.1: + resolution: {integrity: sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA==} + engines: {node: '>=10.0.0'} + + xml2js@0.6.0: + resolution: {integrity: sha512-eLTh0kA8uHceqesPqSE+VvO1CDDJWMwlQfB6LuN6T8w6MaDJ8Txm8P7s5cHD0miF0V+GGTZrDQfxPZQVsur33w==} + engines: {node: '>=4.0.0'} + + xmlbuilder@11.0.1: + resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} + engines: {node: '>=4.0'} + + xmlbuilder@14.0.0: + resolution: {integrity: sha512-ts+B2rSe4fIckR6iquDjsKbQFK2NlUk6iG5nf14mDEyldgoc2nEKZ3jZWMPTxGQwVgToSjt6VGIho1H8/fNFTg==} + engines: {node: '>=8.0'} + + xmlbuilder@15.1.1: + resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==} + engines: {node: '>=8.0'} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + + yaml@2.6.0: + resolution: {integrity: sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==} + engines: {node: '>= 14'} + hasBin: true + + 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'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + yoctocolors@2.1.2: + resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} + engines: {node: '>=18'} + + zod-validation-error@4.0.2: + resolution: {integrity: sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + + zod@4.3.6: + resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@0no-co/graphql.web@1.2.0(graphql@16.8.1)': + optionalDependencies: + graphql: 16.8.1 + + '@alloc/quick-lru@5.2.0': {} + + '@babel/code-frame@7.10.4': + dependencies: + '@babel/highlight': 7.25.9 + + '@babel/code-frame@7.23.5': + dependencies: + '@babel/highlight': 7.25.9 + chalk: 2.4.2 + + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.0': {} + + '@babel/core@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.28.6 + '@babel/parser': 7.29.0 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3(supports-color@8.1.1) + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.0.2 + + '@babel/helper-annotate-as-pure@7.27.3': + dependencies: + '@babel/types': 7.29.0 + + '@babel/helper-compilation-targets@7.28.6': + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.1 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.29.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + regexpu-core: 6.4.0 + semver: 6.3.1 + + '@babel/helper-define-polyfill-provider@0.6.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + debug: 4.4.3(supports-color@8.1.1) + lodash.debounce: 4.0.8 + resolve: 1.22.11 + transitivePeerDependencies: + - supports-color + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-member-expression-to-functions@7.28.5': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.28.6': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.29.0 + + '@babel/helper-plugin-utils@7.28.6': {} + + '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-wrap-function': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-replace-supers@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helper-wrap-function@7.28.6': + dependencies: + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helpers@7.28.6': + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + + '@babel/highlight@7.25.9': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/parser@7.29.0': + dependencies: + '@babel/types': 7.29.0 + + '@babel/plugin-proposal-decorators@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-decorators': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-export-default-from@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-decorators@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-export-default-from@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-flow@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-import-attributes@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-async-generator-functions@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-async-to-generator@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-block-scoping@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-class-properties@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-class-static-block@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-classes@7.28.4(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-globals': 7.28.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-classes@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-globals': 7.28.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-computed-properties@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/template': 7.28.6 + + '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-flow-strip-types@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-flow': 7.28.6(@babel/core@7.29.0) + + '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-literals@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-logical-assignment-operators@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-nullish-coalescing-operator@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-nullish-coalescing-operator@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-numeric-separator@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-object-rest-spread@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-optional-catch-binding@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-optional-chaining@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-optional-chaining@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-private-methods@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-private-property-in-object@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-react-display-name@7.28.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-react-pure-annotations@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-regenerator@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-runtime@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + babel-plugin-polyfill-corejs2: 0.4.15(@babel/core@7.29.0) + babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.29.0) + babel-plugin-polyfill-regenerator: 0.6.6(@babel/core@7.29.0) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-spread@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-typescript@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/preset-react@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-transform-react-display-name': 7.28.0(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-pure-annotations': 7.27.1(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/preset-typescript@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/preset-typescript@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/runtime@7.28.6': {} + + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + + '@babel/traverse@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.0 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@blgc/config@0.0.40(eslint@9.39.3(jiti@2.6.1))(postcss@8.5.6)(prettier@3.8.1)(turbo@2.8.11)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + dependencies: + '@ianvs/prettier-plugin-sort-imports': 4.7.1(prettier@3.8.1) + '@next/eslint-plugin-next': 16.1.6 + '@typescript-eslint/eslint-plugin': 8.56.1(@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + eslint-config-prettier: 10.1.8(eslint@9.39.3(jiti@2.6.1)) + eslint-plugin-only-warn: 1.1.0 + eslint-plugin-react: 7.37.5(eslint@9.39.3(jiti@2.6.1)) + eslint-plugin-react-hooks: 7.0.1(eslint@9.39.3(jiti@2.6.1)) + eslint-plugin-turbo: 2.8.11(eslint@9.39.3(jiti@2.6.1))(turbo@2.8.11) + prettier-plugin-css-order: 2.2.0(postcss@8.5.6)(prettier@3.8.1) + prettier-plugin-packagejson: 2.5.22(prettier@3.8.1) + prettier-plugin-tailwindcss: 0.7.2(@ianvs/prettier-plugin-sort-imports@4.7.1(prettier@3.8.1))(prettier-plugin-css-order@2.2.0(postcss@8.5.6)(prettier@3.8.1))(prettier@3.8.1) + typescript-eslint: 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + vite-tsconfig-paths: 6.1.1(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + transitivePeerDependencies: + - '@prettier/plugin-hermes' + - '@prettier/plugin-oxc' + - '@prettier/plugin-pug' + - '@shopify/prettier-plugin-liquid' + - '@trivago/prettier-plugin-sort-imports' + - '@vue/compiler-sfc' + - '@zackad/prettier-plugin-twig' + - content-tag + - eslint + - postcss + - prettier + - prettier-plugin-astro + - prettier-plugin-ember-template-tag + - prettier-plugin-jsdoc + - prettier-plugin-marko + - prettier-plugin-multiline-arrays + - prettier-plugin-organize-attributes + - prettier-plugin-organize-imports + - prettier-plugin-sort-imports + - prettier-plugin-svelte + - supports-color + - turbo + - typescript + - vite + + '@blgc/types@0.0.21': {} + + '@blgc/utils@0.0.61': {} + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@drizzle-team/brocli@0.11.0': {} + + '@egjs/hammerjs@2.0.17': + dependencies: + '@types/hammerjs': 2.0.46 + + '@emnapi/core@1.8.1': + dependencies: + '@emnapi/wasi-threads': 1.1.0 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.8.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.1.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@esbuild/aix-ppc64@0.27.3': + optional: true + + '@esbuild/android-arm64@0.27.3': + optional: true + + '@esbuild/android-arm@0.27.3': + optional: true + + '@esbuild/android-x64@0.27.3': + optional: true + + '@esbuild/darwin-arm64@0.27.3': + optional: true + + '@esbuild/darwin-x64@0.27.3': + optional: true + + '@esbuild/freebsd-arm64@0.27.3': + optional: true + + '@esbuild/freebsd-x64@0.27.3': + optional: true + + '@esbuild/linux-arm64@0.27.3': + optional: true + + '@esbuild/linux-arm@0.27.3': + optional: true + + '@esbuild/linux-ia32@0.27.3': + optional: true + + '@esbuild/linux-loong64@0.27.3': + optional: true + + '@esbuild/linux-mips64el@0.27.3': + optional: true + + '@esbuild/linux-ppc64@0.27.3': + optional: true + + '@esbuild/linux-riscv64@0.27.3': + optional: true + + '@esbuild/linux-s390x@0.27.3': + optional: true + + '@esbuild/linux-x64@0.27.3': + optional: true + + '@esbuild/netbsd-arm64@0.27.3': + optional: true + + '@esbuild/netbsd-x64@0.27.3': + optional: true + + '@esbuild/openbsd-arm64@0.27.3': + optional: true + + '@esbuild/openbsd-x64@0.27.3': + optional: true + + '@esbuild/openharmony-arm64@0.27.3': + optional: true + + '@esbuild/sunos-x64@0.27.3': + optional: true + + '@esbuild/win32-arm64@0.27.3': + optional: true + + '@esbuild/win32-ia32@0.27.3': + optional: true + + '@esbuild/win32-x64@0.27.3': + optional: true + + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.3(jiti@2.6.1))': + dependencies: + eslint: 9.39.3(jiti@2.6.1) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.21.1': + dependencies: + '@eslint/object-schema': 2.1.7 + debug: 4.4.3(supports-color@8.1.1) + minimatch: 3.1.5 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 + + '@eslint/core@0.17.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.4': + dependencies: + ajv: 6.14.0 + debug: 4.4.3(supports-color@8.1.1) + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + minimatch: 3.1.5 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.39.3': {} + + '@eslint/object-schema@2.1.7': {} + + '@eslint/plugin-kit@0.4.1': + dependencies: + '@eslint/core': 0.17.0 + levn: 0.4.1 + + '@expo-google-fonts/material-symbols@0.4.24': {} + + '@expo/apple-utils@2.1.13': {} + + '@expo/bunyan@4.0.1': + dependencies: + uuid: 8.3.2 + + '@expo/cli@55.0.13(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-constants@55.0.7)(expo-font@55.0.4)(expo-router@55.0.3)(expo@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)': + dependencies: + '@expo/code-signing-certificates': 0.0.6 + '@expo/config': 55.0.8(typescript@5.9.3) + '@expo/config-plugins': 55.0.6 + '@expo/devcert': 1.2.1 + '@expo/env': 2.1.1 + '@expo/image-utils': 0.8.12 + '@expo/json-file': 10.0.12 + '@expo/log-box': 55.0.7(@expo/dom-webview@55.0.3)(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + '@expo/metro': 54.2.0 + '@expo/metro-config': 55.0.9(expo@55.0.3)(typescript@5.9.3) + '@expo/osascript': 2.4.2 + '@expo/package-manager': 1.10.3 + '@expo/plist': 0.5.2 + '@expo/prebuild-config': 55.0.8(expo@55.0.3)(typescript@5.9.3) + '@expo/require-utils': 55.0.2(typescript@5.9.3) + '@expo/router-server': 55.0.9(@expo/metro-runtime@55.0.6)(expo-constants@55.0.7)(expo-font@55.0.4)(expo-router@55.0.3)(expo-server@55.0.6)(expo@55.0.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@expo/schema-utils': 55.0.2 + '@expo/spawn-async': 1.7.2 + '@expo/ws-tunnel': 1.0.6 + '@expo/xcpretty': 4.4.1 + '@react-native/dev-middleware': 0.83.2 + accepts: 1.3.8 + arg: 5.0.2 + better-opn: 3.0.2 + bplist-creator: 0.1.0 + bplist-parser: 0.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + compression: 1.8.1 + connect: 3.7.0 + debug: 4.4.3(supports-color@8.1.1) + dnssd-advertise: 1.1.3 + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + expo-server: 55.0.6 + fetch-nodeshim: 0.4.8 + getenv: 2.0.0 + glob: 13.0.6 + lan-network: 0.2.0 + multitars: 0.2.4 + node-forge: 1.3.3 + npm-package-arg: 11.0.3 + ora: 3.4.0 + picomatch: 4.0.3 + pretty-format: 29.7.0 + progress: 2.0.3 + prompts: 2.4.2 + resolve-from: 5.0.0 + semver: 7.7.4 + send: 0.19.2 + slugify: 1.6.6 + source-map-support: 0.5.21 + stacktrace-parser: 0.1.11 + structured-headers: 0.4.1 + terminal-link: 2.1.1 + toqr: 0.1.1 + wrap-ansi: 7.0.0 + ws: 8.19.0 + zod: 3.25.76 + optionalDependencies: + expo-router: 55.0.3(715e0706cc640a8619e3400aac055546) + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + transitivePeerDependencies: + - '@expo/dom-webview' + - '@expo/metro-runtime' + - bufferutil + - expo-constants + - expo-font + - react + - react-dom + - react-server-dom-webpack + - supports-color + - typescript + - utf-8-validate + + '@expo/code-signing-certificates@0.0.5': + dependencies: + 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@55.0.6': + dependencies: + '@expo/config-types': 55.0.5 + '@expo/json-file': 10.0.12 + '@expo/plist': 0.5.2 + '@expo/sdk-runtime-versions': 1.0.0 + chalk: 4.1.2 + debug: 4.4.3(supports-color@8.1.1) + getenv: 2.0.0 + glob: 13.0.6 + resolve-from: 5.0.0 + semver: 7.7.4 + slugify: 1.6.6 + xcode: 3.0.1 + xml2js: 0.6.0 + transitivePeerDependencies: + - supports-color + + '@expo/config-plugins@9.0.12': + dependencies: + '@expo/config-types': 52.0.5 + '@expo/json-file': 9.0.2 + '@expo/plist': 0.2.0 + '@expo/sdk-runtime-versions': 1.0.0 + chalk: 4.1.2 + debug: 4.4.3(supports-color@8.1.1) + getenv: 1.0.0 + glob: 10.5.0 + resolve-from: 5.0.0 + semver: 7.7.4 + slash: 3.0.0 + slugify: 1.6.6 + xcode: 3.0.1 + xml2js: 0.6.0 + transitivePeerDependencies: + - supports-color + + '@expo/config-types@52.0.5': {} + + '@expo/config-types@55.0.5': {} + + '@expo/config@10.0.6': + dependencies: + '@babel/code-frame': 7.10.4 + '@expo/config-plugins': 9.0.12 + '@expo/config-types': 52.0.5 + '@expo/json-file': 9.1.5 + deepmerge: 4.3.1 + getenv: 1.0.0 + glob: 10.5.0 + require-from-string: 2.0.2 + resolve-from: 5.0.0 + resolve-workspace-root: 2.0.1 + semver: 7.7.4 + slugify: 1.6.6 + sucrase: 3.35.0 + transitivePeerDependencies: + - supports-color + + '@expo/config@55.0.8(typescript@5.9.3)': + dependencies: + '@expo/config-plugins': 55.0.6 + '@expo/config-types': 55.0.5 + '@expo/json-file': 10.0.12 + '@expo/require-utils': 55.0.2(typescript@5.9.3) + deepmerge: 4.3.1 + getenv: 2.0.0 + glob: 13.0.6 + resolve-from: 5.0.0 + resolve-workspace-root: 2.0.1 + semver: 7.7.4 + slugify: 1.6.6 + transitivePeerDependencies: + - supports-color + - typescript + + '@expo/devcert@1.2.1': + dependencies: + '@expo/sudo-prompt': 9.3.2 + debug: 3.2.7 + transitivePeerDependencies: + - supports-color + + '@expo/devtools@55.0.2(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)': + dependencies: + chalk: 4.1.2 + optionalDependencies: + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + + '@expo/dom-webview@55.0.3(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)': + dependencies: + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + + '@expo/eas-build-job@18.0.2': + dependencies: + '@expo/logger': 18.0.1 + joi: 17.13.3 + semver: 7.7.4 + zod: 4.3.6 + + '@expo/eas-json@18.0.2': + dependencies: + '@babel/code-frame': 7.23.5 + '@expo/eas-build-job': 18.0.2 + chalk: 4.1.2 + env-string: 1.0.1 + fs-extra: 11.2.0 + golden-fleece: 1.0.9 + joi: 17.11.0 + log-symbols: 4.1.0 + semver: 7.5.2 + terminal-link: 2.1.1 + tslib: 2.4.1 + + '@expo/env@1.0.7': + dependencies: + chalk: 4.1.2 + debug: 4.4.3(supports-color@8.1.1) + dotenv: 16.4.7 + dotenv-expand: 11.0.7 + getenv: 2.0.0 + transitivePeerDependencies: + - supports-color + + '@expo/env@2.1.1': + dependencies: + chalk: 4.1.2 + debug: 4.4.3(supports-color@8.1.1) + getenv: 2.0.0 + transitivePeerDependencies: + - supports-color + + '@expo/fingerprint@0.16.5': + dependencies: + '@expo/env': 2.1.1 + '@expo/spawn-async': 1.7.2 + arg: 5.0.2 + chalk: 4.1.2 + debug: 4.4.3(supports-color@8.1.1) + getenv: 2.0.0 + glob: 13.0.6 + ignore: 5.3.2 + minimatch: 10.2.4 + resolve-from: 5.0.0 + semver: 7.7.4 + transitivePeerDependencies: + - supports-color + + '@expo/image-utils@0.6.5': + dependencies: + '@expo/spawn-async': 1.7.2 + chalk: 4.1.2 + fs-extra: 9.0.0 + getenv: 1.0.0 + jimp-compact: 0.16.1 + parse-png: 2.1.0 + resolve-from: 5.0.0 + semver: 7.7.4 + temp-dir: 2.0.0 + unique-string: 2.0.0 + + '@expo/image-utils@0.8.12': + dependencies: + '@expo/spawn-async': 1.7.2 + chalk: 4.1.2 + getenv: 2.0.0 + jimp-compact: 0.16.1 + parse-png: 2.1.0 + resolve-from: 5.0.0 + semver: 7.7.4 + + '@expo/json-file@10.0.12': + dependencies: + '@babel/code-frame': 7.29.0 + json5: 2.2.3 + + '@expo/json-file@8.3.3': + dependencies: + '@babel/code-frame': 7.10.4 + json5: 2.2.3 + write-file-atomic: 2.4.3 + + '@expo/json-file@9.0.2': + dependencies: + '@babel/code-frame': 7.10.4 + json5: 2.2.3 + write-file-atomic: 2.4.3 + + '@expo/json-file@9.1.5': + dependencies: + '@babel/code-frame': 7.10.4 + json5: 2.2.3 + + '@expo/local-build-cache-provider@55.0.6(typescript@5.9.3)': + dependencies: + '@expo/config': 55.0.8(typescript@5.9.3) + chalk: 4.1.2 + transitivePeerDependencies: + - supports-color + - typescript + + '@expo/log-box@55.0.7(@expo/dom-webview@55.0.3)(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)': + dependencies: + '@expo/dom-webview': 55.0.3(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + anser: 1.4.10 + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + stacktrace-parser: 0.1.11 + + '@expo/logger@18.0.1': + dependencies: + '@types/bunyan': 1.8.11 + bunyan: 1.8.15 + + '@expo/metro-config@55.0.9(expo@55.0.3)(typescript@5.9.3)': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@expo/config': 55.0.8(typescript@5.9.3) + '@expo/env': 2.1.1 + '@expo/json-file': 10.0.12 + '@expo/metro': 54.2.0 + '@expo/spawn-async': 1.7.2 + browserslist: 4.28.1 + chalk: 4.1.2 + debug: 4.4.3(supports-color@8.1.1) + getenv: 2.0.0 + glob: 13.0.6 + hermes-parser: 0.32.1 + jsc-safe-url: 0.2.4 + lightningcss: 1.30.1 + picomatch: 4.0.3 + postcss: 8.4.49 + resolve-from: 5.0.0 + optionalDependencies: + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + transitivePeerDependencies: + - bufferutil + - supports-color + - typescript + - utf-8-validate + + '@expo/metro-runtime@55.0.6(@expo/dom-webview@55.0.3)(expo@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)': + dependencies: + '@expo/log-box': 55.0.7(@expo/dom-webview@55.0.3)(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + anser: 1.4.10 + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + pretty-format: 29.7.0 + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + stacktrace-parser: 0.1.11 + whatwg-fetch: 3.6.20 + optionalDependencies: + react-dom: 19.2.4(react@19.2.4) + transitivePeerDependencies: + - '@expo/dom-webview' + + '@expo/metro@54.2.0': + dependencies: + metro: 0.83.3 + metro-babel-transformer: 0.83.3 + metro-cache: 0.83.3 + metro-cache-key: 0.83.3 + metro-config: 0.83.3 + metro-core: 0.83.3 + metro-file-map: 0.83.3 + metro-minify-terser: 0.83.3 + metro-resolver: 0.83.3 + metro-runtime: 0.83.3 + metro-source-map: 0.83.3 + metro-symbolicate: 0.83.3 + metro-transform-plugins: 0.83.3 + metro-transform-worker: 0.83.3 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@expo/multipart-body-parser@2.0.0': + dependencies: + multipasta: 0.2.7 + + '@expo/osascript@2.1.4': + dependencies: + '@expo/spawn-async': 1.7.2 + exec-async: 2.2.0 + + '@expo/osascript@2.4.2': + dependencies: + '@expo/spawn-async': 1.7.2 + + '@expo/package-manager@1.10.3': + dependencies: + '@expo/json-file': 10.0.12 + '@expo/spawn-async': 1.7.2 + chalk: 4.1.2 + npm-package-arg: 11.0.3 + ora: 3.4.0 + resolve-workspace-root: 2.0.1 + + '@expo/package-manager@1.9.10': + dependencies: + '@expo/json-file': 10.0.12 + '@expo/spawn-async': 1.7.2 + chalk: 4.1.2 + npm-package-arg: 11.0.3 + ora: 3.4.0 + resolve-workspace-root: 2.0.1 + + '@expo/pkcs12@0.1.3': + dependencies: + node-forge: 1.3.3 + + '@expo/plist@0.2.0': + dependencies: + '@xmldom/xmldom': 0.7.13 + base64-js: 1.5.1 + xmlbuilder: 14.0.0 + + '@expo/plist@0.5.2': + dependencies: + '@xmldom/xmldom': 0.8.11 + base64-js: 1.5.1 + xmlbuilder: 15.1.1 + + '@expo/plugin-help@5.1.23(@types/node@25.3.2)(typescript@5.9.3)': + dependencies: + '@oclif/core': 2.16.0(@types/node@25.3.2)(typescript@5.9.3) + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + - '@types/node' + - typescript + + '@expo/plugin-warn-if-update-available@2.5.1(@types/node@25.3.2)(typescript@5.9.3)': + dependencies: + '@oclif/core': 2.16.0(@types/node@25.3.2)(typescript@5.9.3) + chalk: 4.1.2 + debug: 4.4.3(supports-color@8.1.1) + ejs: 3.1.10 + fs-extra: 10.1.0 + http-call: 5.3.0 + semver: 7.7.4 + tslib: 2.8.1 + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + - '@types/node' + - supports-color + - typescript + + '@expo/prebuild-config@55.0.8(expo@55.0.3)(typescript@5.9.3)': + dependencies: + '@expo/config': 55.0.8(typescript@5.9.3) + '@expo/config-plugins': 55.0.6 + '@expo/config-types': 55.0.5 + '@expo/image-utils': 0.8.12 + '@expo/json-file': 10.0.12 + '@react-native/normalize-colors': 0.83.2 + debug: 4.4.3(supports-color@8.1.1) + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + resolve-from: 5.0.0 + semver: 7.7.4 + xml2js: 0.6.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@expo/prebuild-config@8.0.17': + dependencies: + '@expo/config': 10.0.6 + '@expo/config-plugins': 9.0.12 + '@expo/config-types': 52.0.5 + '@expo/image-utils': 0.6.5 + '@expo/json-file': 9.1.5 + '@react-native/normalize-colors': 0.76.2 + debug: 4.4.3(supports-color@8.1.1) + fs-extra: 9.1.0 + resolve-from: 5.0.0 + semver: 7.7.4 + xml2js: 0.6.0 + transitivePeerDependencies: + - supports-color + + '@expo/require-utils@55.0.2(typescript@5.9.3)': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/core': 7.29.0 + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@expo/results@1.0.0': {} + + '@expo/router-server@55.0.9(@expo/metro-runtime@55.0.6)(expo-constants@55.0.7)(expo-font@55.0.4)(expo-router@55.0.3)(expo-server@55.0.6)(expo@55.0.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + debug: 4.4.3(supports-color@8.1.1) + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + expo-constants: 55.0.7(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(typescript@5.9.3) + expo-font: 55.0.4(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + expo-server: 55.0.6 + react: 19.2.4 + optionalDependencies: + '@expo/metro-runtime': 55.0.6(@expo/dom-webview@55.0.3)(expo@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + expo-router: 55.0.3(715e0706cc640a8619e3400aac055546) + react-dom: 19.2.4(react@19.2.4) + transitivePeerDependencies: + - supports-color + + '@expo/rudder-sdk-node@1.1.1': + dependencies: + '@expo/bunyan': 4.0.1 + '@segment/loosely-validate-event': 2.0.0 + fetch-retry: 4.1.1 + md5: 2.3.0 + node-fetch: 2.7.0 + remove-trailing-slash: 0.1.1 + uuid: 8.3.2 + transitivePeerDependencies: + - encoding + + '@expo/schema-utils@55.0.2': {} + + '@expo/sdk-runtime-versions@1.0.0': {} + + '@expo/spawn-async@1.7.2': + dependencies: + cross-spawn: 7.0.6 + + '@expo/steps@18.0.2': + dependencies: + '@expo/eas-build-job': 18.0.2 + '@expo/logger': 18.0.1 + '@expo/spawn-async': 1.7.2 + arg: 5.0.2 + fs-extra: 11.2.0 + joi: 17.13.3 + jsep: 1.4.0 + lodash.clonedeep: 4.5.0 + lodash.get: 4.4.2 + uuid: 9.0.1 + yaml: 2.8.2 + + '@expo/sudo-prompt@9.3.2': {} + + '@expo/timeago.js@1.0.0': {} + + '@expo/ui@55.0.1(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)': + dependencies: + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + sf-symbols-typescript: 2.2.0 + + '@expo/vector-icons@15.1.1(expo-font@55.0.4)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)': + dependencies: + expo-font: 55.0.4(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + + '@expo/ws-tunnel@1.0.6': {} + + '@expo/xcpretty@4.4.1': + dependencies: + '@babel/code-frame': 7.29.0 + chalk: 4.1.2 + js-yaml: 4.1.1 + + '@hapi/hoek@9.3.0': {} + + '@hapi/topo@5.1.0': + dependencies: + '@hapi/hoek': 9.3.0 + + '@hono/node-server@1.19.9(hono@4.12.3)': + dependencies: + hono: 4.12.3 + + '@hono/node-ws@1.3.0(@hono/node-server@1.19.9(hono@4.12.3))(hono@4.12.3)': + dependencies: + '@hono/node-server': 1.19.9(hono@4.12.3) + hono: 4.12.3 + ws: 8.19.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@hono/vite-dev-server@0.25.0(hono@4.12.3)': + dependencies: + '@hono/node-server': 1.19.9(hono@4.12.3) + hono: 4.12.3 + minimatch: 9.0.9 + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.7': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.4.3 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@ianvs/prettier-plugin-sort-imports@4.7.1(prettier@3.8.1)': + dependencies: + '@babel/generator': 7.29.1 + '@babel/parser': 7.29.0 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + prettier: 3.8.1 + semver: 7.7.4 + transitivePeerDependencies: + - supports-color + + '@img/colour@1.0.0': {} + + '@img/sharp-darwin-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.2.4 + optional: true + + '@img/sharp-darwin-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.2.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.2.4': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-riscv64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-s390x@1.2.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + optional: true + + '@img/sharp-linux-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.2.4 + optional: true + + '@img/sharp-linux-arm@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.2.4 + optional: true + + '@img/sharp-linux-ppc64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.2.4 + optional: true + + '@img/sharp-linux-riscv64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.2.4 + optional: true + + '@img/sharp-linux-s390x@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.2.4 + optional: true + + '@img/sharp-linux-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + optional: true + + '@img/sharp-wasm32@0.34.5': + dependencies: + '@emnapi/runtime': 1.8.1 + optional: true + + '@img/sharp-win32-arm64@0.34.5': + optional: true + + '@img/sharp-win32-ia32@0.34.5': + optional: true + + '@img/sharp-win32-x64@0.34.5': + optional: true + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.2.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.3 + + '@isaacs/ttlcache@1.4.1': {} + + '@istanbuljs/load-nyc-config@1.1.0': + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.2 + resolve-from: 5.0.0 + + '@istanbuljs/schema@0.1.3': {} + + '@jest/create-cache-key-function@29.7.0': + dependencies: + '@jest/types': 29.6.3 + + '@jest/environment@29.7.0': + dependencies: + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 25.3.2 + jest-mock: 29.7.0 + + '@jest/fake-timers@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@sinonjs/fake-timers': 10.3.0 + '@types/node': 25.3.2 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.10 + + '@jest/transform@29.7.0': + dependencies: + '@babel/core': 7.29.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.31 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + micromatch: 4.0.8 + pirates: 4.0.7 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + + '@jest/types@29.6.3': + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 25.3.2 + '@types/yargs': 17.0.35 + chalk: 4.1.2 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/source-map@0.3.11': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@mdx-js/mdx@3.1.1': + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdx': 2.0.13 + acorn: 8.16.0 + collapse-white-space: 2.1.0 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-util-scope: 1.0.0 + estree-walker: 3.0.3 + hast-util-to-jsx-runtime: 2.3.6 + markdown-extensions: 2.0.0 + recma-build-jsx: 1.0.0 + recma-jsx: 1.0.1(acorn@8.16.0) + recma-stringify: 1.0.0 + rehype-recma: 1.0.0 + remark-mdx: 3.1.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + source-map: 0.7.6 + unified: 11.0.5 + unist-util-position-from-estree: 2.0.0 + unist-util-stringify-position: 4.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@mdx-js/rollup@3.1.1(rollup@4.59.0)': + dependencies: + '@mdx-js/mdx': 3.1.1 + '@rollup/pluginutils': 5.3.0(rollup@4.59.0) + rollup: 4.59.0 + source-map: 0.7.6 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@mjackson/node-fetch-server@0.2.0': {} + + '@napi-rs/wasm-runtime@0.2.12': + dependencies: + '@emnapi/core': 1.8.1 + '@emnapi/runtime': 1.8.1 + '@tybys/wasm-util': 0.10.1 + optional: true + + '@next/eslint-plugin-next@16.1.6': + dependencies: + fast-glob: 3.3.1 + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@nolyfill/is-core-module@1.0.39': {} + + '@oclif/core@1.26.2': + dependencies: + '@oclif/linewrap': 1.0.0 + '@oclif/screen': 3.0.8 + ansi-escapes: 4.3.2 + ansi-styles: 4.3.0 + cardinal: 2.1.1 + chalk: 4.1.2 + clean-stack: 3.0.1 + cli-progress: 3.12.0 + debug: 4.4.3(supports-color@8.1.1) + ejs: 3.1.10 + fs-extra: 9.1.0 + get-package-type: 0.1.0 + globby: 11.1.0 + hyperlinker: 1.0.0 + indent-string: 4.0.0 + is-wsl: 2.2.0 + js-yaml: 3.14.2 + natural-orderby: 2.0.3 + object-treeify: 1.1.33 + password-prompt: 1.1.3 + semver: 7.7.4 + string-width: 4.2.3 + strip-ansi: 6.0.1 + supports-color: 8.1.1 + supports-hyperlinks: 2.3.0 + tslib: 2.8.1 + widest-line: 3.1.0 + wrap-ansi: 7.0.0 + + '@oclif/core@2.16.0(@types/node@25.3.2)(typescript@5.9.3)': + dependencies: + '@types/cli-progress': 3.11.6 + ansi-escapes: 4.3.2 + ansi-styles: 4.3.0 + cardinal: 2.1.1 + chalk: 4.1.2 + clean-stack: 3.0.1 + cli-progress: 3.12.0 + debug: 4.4.3(supports-color@8.1.1) + ejs: 3.1.10 + get-package-type: 0.1.0 + globby: 11.1.0 + hyperlinker: 1.0.0 + indent-string: 4.0.0 + is-wsl: 2.2.0 + js-yaml: 3.14.2 + natural-orderby: 2.0.3 + object-treeify: 1.1.33 + password-prompt: 1.1.3 + slice-ansi: 4.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + supports-color: 8.1.1 + supports-hyperlinks: 2.3.0 + ts-node: 10.9.2(@types/node@25.3.2)(typescript@5.9.3) + tslib: 2.8.1 + widest-line: 3.1.0 + wordwrap: 1.0.0 + wrap-ansi: 7.0.0 + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + - '@types/node' + - typescript + + '@oclif/linewrap@1.0.0': {} + + '@oclif/plugin-autocomplete@2.3.10(@types/node@25.3.2)(typescript@5.9.3)': + dependencies: + '@oclif/core': 2.16.0(@types/node@25.3.2)(typescript@5.9.3) + chalk: 4.1.2 + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + - '@types/node' + - supports-color + - typescript + + '@oclif/screen@3.0.8': {} + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@radix-ui/primitive@1.1.3': {} + + '@radix-ui/react-collection@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.14)(react@19.2.4)': + dependencies: + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-context@1.1.2(@types/react@19.2.14)(react@19.2.4)': + dependencies: + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + aria-hidden: 1.2.6 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-direction@1.1.1(@types/react@19.2.14)(react@19.2.4)': + dependencies: + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-focus-guards@1.1.3(@types/react@19.2.14)(react@19.2.4)': + dependencies: + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-id@1.1.1(@types/react@19.2.14)(react@19.2.4)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-portal@1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-presence@1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-slot@1.2.3(@types/react@19.2.14)(react@19.2.4)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-slot@1.2.4(@types/react@19.2.14)(react@19.2.4)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-tabs@1.1.13(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.2.14)(react@19.2.4)': + dependencies: + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.14)(react@19.2.4)': + dependencies: + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.2.14)(react@19.2.4)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.2.14)(react@19.2.4)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.14)(react@19.2.4)': + dependencies: + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@react-native-async-storage/async-storage@3.0.1(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)': + dependencies: + idb: 8.0.3 + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + + '@react-native/assets-registry@0.83.2': {} + + '@react-native/babel-plugin-codegen@0.83.2(@babel/core@7.29.0)': + dependencies: + '@babel/traverse': 7.29.0 + '@react-native/codegen': 0.83.2(@babel/core@7.29.0) + transitivePeerDependencies: + - '@babel/core' + - supports-color + + '@react-native/babel-preset@0.83.2(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-proposal-export-default-from': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-export-default-from': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-async-generator-functions': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-async-to-generator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-block-scoping': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-class-properties': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-classes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-computed-properties': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-flow-strip-types': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-logical-assignment-operators': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-nullish-coalescing-operator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-numeric-separator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-object-rest-spread': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-optional-catch-binding': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/plugin-transform-private-methods': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-private-property-in-object': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-react-display-name': 7.28.0(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-regenerator': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-runtime': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-spread': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.29.0) + '@babel/template': 7.28.6 + '@react-native/babel-plugin-codegen': 0.83.2(@babel/core@7.29.0) + babel-plugin-syntax-hermes-parser: 0.32.0 + babel-plugin-transform-flow-enums: 0.0.2(@babel/core@7.29.0) + react-refresh: 0.14.2 + transitivePeerDependencies: + - supports-color + + '@react-native/codegen@0.83.2(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/parser': 7.29.0 + glob: 7.2.3 + hermes-parser: 0.32.0 + invariant: 2.2.4 + nullthrows: 1.1.1 + yargs: 17.7.2 + + '@react-native/community-cli-plugin@0.83.2': + dependencies: + '@react-native/dev-middleware': 0.83.2 + debug: 4.4.3(supports-color@8.1.1) + invariant: 2.2.4 + metro: 0.83.4 + metro-config: 0.83.4 + metro-core: 0.83.4 + semver: 7.7.4 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@react-native/debugger-frontend@0.83.2': {} + + '@react-native/debugger-shell@0.83.2': + dependencies: + cross-spawn: 7.0.6 + fb-dotslash: 0.5.8 + + '@react-native/dev-middleware@0.83.2': + dependencies: + '@isaacs/ttlcache': 1.4.1 + '@react-native/debugger-frontend': 0.83.2 + '@react-native/debugger-shell': 0.83.2 + chrome-launcher: 0.15.2 + chromium-edge-launcher: 0.2.0 + connect: 3.7.0 + debug: 4.4.3(supports-color@8.1.1) + invariant: 2.2.4 + nullthrows: 1.1.1 + open: 7.4.2 + serve-static: 1.16.3 + ws: 7.5.10 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@react-native/gradle-plugin@0.83.2': {} + + '@react-native/js-polyfills@0.83.2': {} + + '@react-native/normalize-colors@0.74.89': {} + + '@react-native/normalize-colors@0.76.2': {} + + '@react-native/normalize-colors@0.83.2': {} + + '@react-native/virtualized-lists@0.83.2(@types/react@19.2.14)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)': + dependencies: + invariant: 2.2.4 + nullthrows: 1.1.1 + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + + '@react-navigation/bottom-tabs@7.15.2(@react-navigation/native@7.1.31(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native-safe-area-context@5.6.2(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native-screens@4.23.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-navigation/elements': 2.9.8(@react-navigation/native@7.1.31(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native-safe-area-context@5.6.2(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + '@react-navigation/native': 7.1.31(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + color: 4.2.3 + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + react-native-safe-area-context: 5.6.2(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + react-native-screens: 4.23.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + sf-symbols-typescript: 2.2.0 + transitivePeerDependencies: + - '@react-native-masked-view/masked-view' + + '@react-navigation/core@7.15.1(react@19.2.4)': + dependencies: + '@react-navigation/routers': 7.5.3 + escape-string-regexp: 4.0.0 + fast-deep-equal: 3.1.3 + nanoid: 3.3.11 + query-string: 7.1.3 + react: 19.2.4 + react-is: 19.2.4 + use-latest-callback: 0.2.6(react@19.2.4) + use-sync-external-store: 1.6.0(react@19.2.4) + + '@react-navigation/elements@2.9.8(@react-navigation/native@7.1.31(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native-safe-area-context@5.6.2(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-navigation/native': 7.1.31(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + color: 4.2.3 + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + react-native-safe-area-context: 5.6.2(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + use-latest-callback: 0.2.6(react@19.2.4) + use-sync-external-store: 1.6.0(react@19.2.4) + + '@react-navigation/native-stack@7.14.2(@react-navigation/native@7.1.31(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native-safe-area-context@5.6.2(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native-screens@4.23.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-navigation/elements': 2.9.8(@react-navigation/native@7.1.31(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native-safe-area-context@5.6.2(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + '@react-navigation/native': 7.1.31(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + color: 4.2.3 + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + react-native-safe-area-context: 5.6.2(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + react-native-screens: 4.23.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + sf-symbols-typescript: 2.2.0 + warn-once: 0.1.1 + transitivePeerDependencies: + - '@react-native-masked-view/masked-view' + + '@react-navigation/native@7.1.31(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-navigation/core': 7.15.1(react@19.2.4) + escape-string-regexp: 4.0.0 + fast-deep-equal: 3.1.3 + nanoid: 3.3.11 + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + use-latest-callback: 0.2.6(react@19.2.4) + + '@react-navigation/routers@7.5.3': + dependencies: + nanoid: 3.3.11 + + '@react-router/dev@7.13.1(@react-router/serve@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2)': + dependencies: + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/parser': 7.29.0 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@react-router/node': 7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) + '@remix-run/node-fetch-server': 0.13.0 + arg: 5.0.2 + babel-dead-code-elimination: 1.0.12 + chokidar: 4.0.3 + dedent: 1.7.1 + es-module-lexer: 1.7.0 + exit-hook: 2.2.1 + isbot: 5.1.35 + jsesc: 3.0.2 + lodash: 4.17.23 + p-map: 7.0.4 + pathe: 1.1.2 + picocolors: 1.1.1 + pkg-types: 2.3.0 + prettier: 3.8.1 + react-refresh: 0.14.2 + react-router: 7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + semver: 7.7.4 + tinyglobby: 0.2.15 + valibot: 1.2.0(typescript@5.9.3) + vite: 7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite-node: 3.2.4(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + optionalDependencies: + '@react-router/serve': 7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + '@react-router/express@7.13.1(express@4.22.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)': + dependencies: + '@react-router/node': 7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) + express: 4.22.1 + react-router: 7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + optionalDependencies: + typescript: 5.9.3 + + '@react-router/fs-routes@7.13.1(@react-router/dev@7.13.1(@react-router/serve@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2))(typescript@5.9.3)': + dependencies: + '@react-router/dev': 7.13.1(@react-router/serve@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2) + minimatch: 9.0.9 + optionalDependencies: + typescript: 5.9.3 + + '@react-router/node@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)': + dependencies: + '@mjackson/node-fetch-server': 0.2.0 + react-router: 7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + optionalDependencies: + typescript: 5.9.3 + + '@react-router/serve@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)': + dependencies: + '@mjackson/node-fetch-server': 0.2.0 + '@react-router/express': 7.13.1(express@4.22.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) + '@react-router/node': 7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) + compression: 1.8.1 + express: 4.22.1 + get-port: 5.1.1 + morgan: 1.10.1 + react-router: 7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + source-map-support: 0.5.21 + transitivePeerDependencies: + - supports-color + - typescript + + '@remix-run/node-fetch-server@0.13.0': {} + + '@rollup/plugin-commonjs@29.0.0(rollup@4.59.0)': + dependencies: + '@rollup/pluginutils': 5.3.0(rollup@4.59.0) + commondir: 1.0.1 + estree-walker: 2.0.2 + fdir: 6.5.0(picomatch@4.0.3) + is-reference: 1.2.1 + magic-string: 0.30.21 + picomatch: 4.0.3 + optionalDependencies: + rollup: 4.59.0 + + '@rollup/pluginutils@5.3.0(rollup@4.59.0)': + dependencies: + '@types/estree': 1.0.8 + estree-walker: 2.0.2 + picomatch: 4.0.3 + optionalDependencies: + rollup: 4.59.0 + + '@rollup/rollup-android-arm-eabi@4.59.0': + optional: true + + '@rollup/rollup-android-arm64@4.59.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.59.0': + optional: true + + '@rollup/rollup-darwin-x64@4.59.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.59.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.59.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.59.0': + optional: true + + '@rollup/rollup-openbsd-x64@4.59.0': + optional: true + + '@rollup/rollup-openharmony-arm64@4.59.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.59.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.59.0': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.59.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.59.0': + optional: true + + '@rtsao/scc@1.1.0': {} + + '@sec-ant/readable-stream@0.4.1': {} + + '@segment/ajv-human-errors@2.16.0(ajv@8.11.0)': + dependencies: + ajv: 8.11.0 + + '@segment/loosely-validate-event@2.0.0': + dependencies: + component-type: 1.2.2 + join-component: 1.1.0 + + '@sideway/address@4.1.5': + dependencies: + '@hapi/hoek': 9.3.0 + + '@sideway/formula@3.0.1': {} + + '@sideway/pinpoint@2.0.0': {} + + '@sinclair/typebox@0.27.10': {} + + '@sindresorhus/merge-streams@4.0.0': {} + + '@sinonjs/commons@3.0.1': + dependencies: + type-detect: 4.0.8 + + '@sinonjs/fake-timers@10.3.0': + dependencies: + '@sinonjs/commons': 3.0.1 + + '@standard-schema/spec@1.1.0': {} + + '@tailwindcss/node@4.2.1': + dependencies: + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.19.0 + jiti: 2.6.1 + lightningcss: 1.30.1 + magic-string: 0.30.21 + source-map-js: 1.2.1 + tailwindcss: 4.2.1 + + '@tailwindcss/oxide-android-arm64@4.2.1': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.2.1': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.2.1': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.2.1': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.1': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.2.1': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.2.1': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.2.1': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.2.1': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.2.1': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.2.1': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.2.1': + optional: true + + '@tailwindcss/oxide@4.2.1': + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.2.1 + '@tailwindcss/oxide-darwin-arm64': 4.2.1 + '@tailwindcss/oxide-darwin-x64': 4.2.1 + '@tailwindcss/oxide-freebsd-x64': 4.2.1 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.1 + '@tailwindcss/oxide-linux-arm64-gnu': 4.2.1 + '@tailwindcss/oxide-linux-arm64-musl': 4.2.1 + '@tailwindcss/oxide-linux-x64-gnu': 4.2.1 + '@tailwindcss/oxide-linux-x64-musl': 4.2.1 + '@tailwindcss/oxide-wasm32-wasi': 4.2.1 + '@tailwindcss/oxide-win32-arm64-msvc': 4.2.1 + '@tailwindcss/oxide-win32-x64-msvc': 4.2.1 + + '@tailwindcss/postcss@4.2.1': + dependencies: + '@alloc/quick-lru': 5.2.0 + '@tailwindcss/node': 4.2.1 + '@tailwindcss/oxide': 4.2.1 + postcss: 8.5.6 + tailwindcss: 4.2.1 + + '@tailwindcss/typography@0.5.19(tailwindcss@4.2.1)': + dependencies: + postcss-selector-parser: 6.0.10 + tailwindcss: 4.2.1 + + '@tailwindcss/vite@4.2.1(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + dependencies: + '@tailwindcss/node': 4.2.1 + '@tailwindcss/oxide': 4.2.1 + tailwindcss: 4.2.1 + vite: 7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + + '@ts-morph/common@0.11.1': + dependencies: + fast-glob: 3.3.3 + minimatch: 3.1.5 + mkdirp: 1.0.4 + path-browserify: 1.0.1 + + '@tsconfig/node10@1.0.12': {} + + '@tsconfig/node12@1.0.11': {} + + '@tsconfig/node14@1.0.3': {} + + '@tsconfig/node16@1.0.4': {} + + '@tybys/wasm-util@0.10.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.28.0 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.29.0 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + + '@types/babel__traverse@7.28.0': + dependencies: + '@babel/types': 7.29.0 + + '@types/bunyan@1.8.11': + dependencies: + '@types/node': 25.3.2 + + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + + '@types/cli-progress@3.11.6': + dependencies: + '@types/node': 25.3.2 + + '@types/debug@4.1.12': + dependencies: + '@types/ms': 2.1.0 + + '@types/deep-eql@4.0.2': {} + + '@types/estree-jsx@1.0.5': + dependencies: + '@types/estree': 1.0.8 + + '@types/estree@1.0.8': {} + + '@types/graceful-fs@4.1.9': + dependencies: + '@types/node': 25.3.2 + + '@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': + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + + '@types/istanbul-reports@3.0.4': + dependencies: + '@types/istanbul-lib-report': 3.0.3 + + '@types/json-schema@7.0.15': {} + + '@types/json5@0.0.29': {} + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mdx@2.0.13': {} + + '@types/ms@2.1.0': {} + + '@types/node@25.3.2': + dependencies: + undici-types: 7.18.2 + + '@types/react-dom@19.2.3(@types/react@19.2.14)': + dependencies: + '@types/react': 19.2.14 + + '@types/react@19.2.14': + dependencies: + csstype: 3.2.3 + + '@types/stack-utils@2.0.3': {} + + '@types/unist@2.0.11': {} + + '@types/unist@3.0.3': {} + + '@types/yargs-parser@21.0.3': {} + + '@types/yargs@17.0.35': + dependencies: + '@types/yargs-parser': 21.0.3 + + '@typescript-eslint/eslint-plugin@8.56.1(@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.56.1 + '@typescript-eslint/type-utils': 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.56.1 + eslint: 9.39.3(jiti@2.6.1) + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.4.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.56.1 + '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.56.1 + debug: 4.4.3(supports-color@8.1.1) + eslint: 9.39.3(jiti@2.6.1) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.56.1(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.56.1(typescript@5.9.3) + '@typescript-eslint/types': 8.56.1 + debug: 4.4.3(supports-color@8.1.1) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.56.1': + dependencies: + '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/visitor-keys': 8.56.1 + + '@typescript-eslint/tsconfig-utils@8.56.1(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@typescript-eslint/type-utils@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + debug: 4.4.3(supports-color@8.1.1) + eslint: 9.39.3(jiti@2.6.1) + ts-api-utils: 2.4.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.56.1': {} + + '@typescript-eslint/typescript-estree@8.56.1(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.56.1(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.56.1(typescript@5.9.3) + '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/visitor-keys': 8.56.1 + debug: 4.4.3(supports-color@8.1.1) + minimatch: 10.2.4 + semver: 7.7.4 + tinyglobby: 0.2.15 + ts-api-utils: 2.4.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.3(jiti@2.6.1)) + '@typescript-eslint/scope-manager': 8.56.1 + '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) + eslint: 9.39.3(jiti@2.6.1) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.56.1': + dependencies: + '@typescript-eslint/types': 8.56.1 + eslint-visitor-keys: 5.0.1 + + '@ungap/structured-clone@1.3.0': {} + + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + optional: true + + '@unrs/resolver-binding-android-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + dependencies: + '@napi-rs/wasm-runtime': 0.2.12 + optional: true + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + optional: true + + '@urql/core@4.0.11(graphql@16.8.1)': + dependencies: + '@0no-co/graphql.web': 1.2.0(graphql@16.8.1) + wonka: 6.3.5 + transitivePeerDependencies: + - graphql + + '@urql/exchange-retry@1.2.0(graphql@16.8.1)': + dependencies: + '@urql/core': 4.0.11(graphql@16.8.1) + wonka: 6.3.5 + transitivePeerDependencies: + - graphql + + '@vercel/analytics@1.6.1(react@19.2.4)': + optionalDependencies: + react: 19.2.4 + + '@vercel/react-router@1.2.5(@react-router/dev@7.13.1(@react-router/serve@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2))(@react-router/node@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(isbot@5.1.35)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@react-router/dev': 7.13.1(@react-router/serve@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2) + '@react-router/node': 7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) + '@vercel/static-config': 3.1.2 + isbot: 5.1.35 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + ts-morph: 12.0.0 + + '@vercel/static-config@3.1.2': + dependencies: + ajv: 8.6.3 + json-schema-to-ts: 1.6.4 + ts-morph: 12.0.0 + + '@vitest/expect@4.0.18': + dependencies: + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.0.18 + '@vitest/utils': 4.0.18 + chai: 6.2.2 + tinyrainbow: 3.0.3 + + '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + dependencies: + '@vitest/spy': 4.0.18 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + + '@vitest/pretty-format@4.0.18': + dependencies: + tinyrainbow: 3.0.3 + + '@vitest/runner@4.0.18': + dependencies: + '@vitest/utils': 4.0.18 + pathe: 2.0.3 + + '@vitest/snapshot@4.0.18': + dependencies: + '@vitest/pretty-format': 4.0.18 + magic-string: 0.30.21 + pathe: 2.0.3 + + '@vitest/spy@4.0.18': {} + + '@vitest/utils@4.0.18': + dependencies: + '@vitest/pretty-format': 4.0.18 + tinyrainbow: 3.0.3 + + '@xmldom/xmldom@0.7.13': {} + + '@xmldom/xmldom@0.8.11': {} + + abort-controller@3.0.0: + dependencies: + event-target-shim: 5.0.1 + + accepts@1.3.8: + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + accepts@2.0.0: + dependencies: + mime-types: 3.0.2 + negotiator: 1.0.0 + + acorn-jsx@5.3.2(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + + acorn-walk@8.3.5: + dependencies: + acorn: 8.16.0 + + acorn@8.16.0: {} + + agent-base@6.0.2: + dependencies: + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + agent-base@7.1.4: {} + + ajv-formats@2.1.1(ajv@8.11.0): + optionalDependencies: + ajv: 8.11.0 + + ajv@6.14.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ajv@8.11.0: + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + + ajv@8.6.3: + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + + anser@1.4.10: {} + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-regex@4.1.1: {} + + ansi-regex@5.0.1: {} + + ansi-regex@6.2.2: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + ansi-styles@6.2.3: {} + + ansicolors@0.3.2: {} + + any-promise@1.3.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + arg@4.1.3: {} + + arg@5.0.2: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + aria-hidden@1.2.6: + dependencies: + tslib: 2.8.1 + + array-buffer-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + is-array-buffer: 3.0.5 + + array-flatten@1.1.1: {} + + array-includes@3.1.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + is-string: 1.1.1 + math-intrinsics: 1.1.0 + + array-timsort@1.0.3: {} + + array-union@2.1.0: {} + + array.prototype.findlast@1.2.5: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + + array.prototype.findlastindex@1.2.6: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + + array.prototype.flat@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-shim-unscopables: 1.1.0 + + array.prototype.flatmap@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-shim-unscopables: 1.1.0 + + array.prototype.tosorted@1.1.4: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-errors: 1.3.0 + es-shim-unscopables: 1.1.0 + + arraybuffer.prototype.slice@1.0.4: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 + + asap@2.0.6: {} + + asn1@0.2.6: + dependencies: + safer-buffer: 2.1.2 + + assertion-error@2.0.1: {} + + astral-regex@2.0.0: {} + + astring@1.9.0: {} + + async-function@1.0.0: {} + + async@3.2.6: {} + + asynckit@0.4.0: {} + + at-least-node@1.0.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + b4a@1.8.0: {} + + babel-dead-code-elimination@1.0.12: + dependencies: + '@babel/core': 7.29.0 + '@babel/parser': 7.29.0 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + babel-jest@29.7.0(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@jest/transform': 29.7.0 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.6.3(@babel/core@7.29.0) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-istanbul@6.1.1: + dependencies: + '@babel/helper-plugin-utils': 7.28.6 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 5.2.1 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-jest-hoist@29.6.3: + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.28.0 + + babel-plugin-polyfill-corejs2@0.4.15(@babel/core@7.29.0): + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0) + core-js-compat: 3.48.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-regenerator@0.6.6(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + babel-plugin-react-compiler@1.0.0: + dependencies: + '@babel/types': 7.29.0 + + babel-plugin-react-compiler@19.1.0-rc.3: + dependencies: + '@babel/types': 7.29.0 + + babel-plugin-react-native-web@0.21.2: {} + + babel-plugin-syntax-hermes-parser@0.32.0: + dependencies: + hermes-parser: 0.32.0 + + babel-plugin-syntax-hermes-parser@0.32.1: + dependencies: + hermes-parser: 0.32.1 + + babel-plugin-transform-flow-enums@0.0.2(@babel/core@7.29.0): + dependencies: + '@babel/plugin-syntax-flow': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - '@babel/core' + + babel-preset-current-node-syntax@1.2.0(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.29.0) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.29.0) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.29.0) + '@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.29.0) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.29.0) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.29.0) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.29.0) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.29.0) + + babel-preset-expo@55.0.9(@babel/core@7.29.0)(@babel/runtime@7.28.6)(expo@55.0.3)(react-refresh@0.14.2): + dependencies: + '@babel/generator': 7.29.1 + '@babel/helper-module-imports': 7.28.6 + '@babel/plugin-proposal-decorators': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-proposal-export-default-from': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-syntax-export-default-from': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-class-static-block': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-flow-strip-types': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-object-rest-spread': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/plugin-transform-private-methods': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-private-property-in-object': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-runtime': 7.29.0(@babel/core@7.29.0) + '@babel/preset-react': 7.28.5(@babel/core@7.29.0) + '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) + '@react-native/babel-preset': 0.83.2(@babel/core@7.29.0) + babel-plugin-react-compiler: 1.0.0 + babel-plugin-react-native-web: 0.21.2 + babel-plugin-syntax-hermes-parser: 0.32.1 + babel-plugin-transform-flow-enums: 0.0.2(@babel/core@7.29.0) + debug: 4.4.3(supports-color@8.1.1) + react-refresh: 0.14.2 + resolve-from: 5.0.0 + optionalDependencies: + '@babel/runtime': 7.28.6 + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + transitivePeerDependencies: + - '@babel/core' + - supports-color + + babel-preset-jest@29.6.3(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + babel-plugin-jest-hoist: 29.6.3 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.29.0) + + bail@2.0.2: {} + + balanced-match@1.0.2: {} + + balanced-match@4.0.4: {} + + bare-events@2.8.2: {} + + base64-js@1.5.1: {} + + baseline-browser-mapping@2.10.0: {} + + basic-auth@2.0.1: + dependencies: + safe-buffer: 5.1.2 + + better-opn@3.0.2: + dependencies: + open: 8.4.2 + + big-integer@1.6.52: {} + + body-parser@1.20.4: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.1 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.14.2 + raw-body: 2.5.3 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + boolbase@1.0.0: {} + + bplist-creator@0.1.0: + dependencies: + stream-buffers: 2.2.0 + + bplist-parser@0.3.1: + dependencies: + big-integer: 1.6.52 + + bplist-parser@0.3.2: + dependencies: + big-integer: 1.6.52 + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.2: + dependencies: + balanced-match: 1.0.2 + + brace-expansion@5.0.4: + dependencies: + balanced-match: 4.0.4 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.28.1: + dependencies: + baseline-browser-mapping: 2.10.0 + caniuse-lite: 1.0.30001774 + electron-to-chromium: 1.5.302 + node-releases: 2.0.27 + update-browserslist-db: 1.2.3(browserslist@4.28.1) + + bser@2.1.1: + dependencies: + node-int64: 0.4.0 + + buffer-from@1.1.2: {} + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + optional: true + + bunyan@1.8.15: + optionalDependencies: + dtrace-provider: 0.8.8 + moment: 2.30.1 + mv: 2.1.1 + safe-json-stringify: 1.2.0 + + bytes@3.1.2: {} + + cac@6.7.14: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + callsites@3.1.0: {} + + camelcase@5.3.1: {} + + camelcase@6.3.0: {} + + caniuse-lite@1.0.30001774: {} + + cardinal@2.1.1: + dependencies: + ansicolors: 0.3.2 + redeyed: 2.1.1 + + ccount@2.0.1: {} + + chai@6.2.2: {} + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + + character-reference-invalid@2.0.1: {} + + charenc@0.0.2: {} + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + chownr@3.0.0: {} + + chrome-launcher@0.15.2: + dependencies: + '@types/node': 25.3.2 + escape-string-regexp: 4.0.0 + is-wsl: 2.2.0 + lighthouse-logger: 1.4.2 + transitivePeerDependencies: + - supports-color + + chromium-edge-launcher@0.2.0: + dependencies: + '@types/node': 25.3.2 + escape-string-regexp: 4.0.0 + is-wsl: 2.2.0 + lighthouse-logger: 1.4.2 + mkdirp: 1.0.4 + rimraf: 3.0.2 + transitivePeerDependencies: + - supports-color + + ci-info@2.0.0: {} + + ci-info@3.9.0: {} + + clean-stack@3.0.1: + dependencies: + escape-string-regexp: 4.0.0 + + cli-cursor@2.1.0: + dependencies: + restore-cursor: 2.0.0 + + cli-cursor@3.1.0: + dependencies: + restore-cursor: 3.1.0 + + cli-progress@3.12.0: + dependencies: + string-width: 4.2.3 + + cli-spinners@2.9.2: {} + + client-only@0.0.1: {} + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clone@1.0.4: {} + + clsx@2.1.1: {} + + code-block-writer@10.1.1: {} + + collapse-white-space@2.1.0: {} + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.4 + + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + + colorjs.io@0.6.0-alpha.1: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + comma-separated-tokens@2.0.3: {} + + commander@12.1.0: {} + + commander@2.20.3: {} + + commander@4.1.1: {} + + commander@7.2.0: {} + + comment-json@4.5.1: + dependencies: + array-timsort: 1.0.3 + core-util-is: 1.0.3 + esprima: 4.0.1 + + commondir@1.0.1: {} + + component-type@1.2.2: {} + + compressible@2.0.18: + dependencies: + mime-db: 1.54.0 + + compression@1.8.1: + dependencies: + bytes: 3.1.2 + compressible: 2.0.18 + debug: 2.6.9 + negotiator: 0.6.4 + on-headers: 1.1.0 + safe-buffer: 5.2.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + concat-map@0.0.1: {} + + confbox@0.2.4: {} + + connect@3.7.0: + dependencies: + debug: 2.6.9 + finalhandler: 1.1.2 + parseurl: 1.3.3 + utils-merge: 1.0.1 + transitivePeerDependencies: + - supports-color + + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + + convert-source-map@2.0.0: {} + + cookie-signature@1.0.7: {} + + cookie@0.7.2: {} + + cookie@1.1.1: {} + + core-js-compat@3.48.0: + dependencies: + browserslist: 4.28.1 + + core-util-is@1.0.3: {} + + create-require@1.1.1: {} + + cross-fetch@3.2.0: + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + + cross-spawn@6.0.6: + dependencies: + nice-try: 1.0.5 + path-key: 2.0.1 + semver: 5.7.2 + shebang-command: 1.2.0 + which: 1.3.1 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + crypt@0.0.2: {} + + crypto-random-string@2.0.0: {} + + css-declaration-sorter@7.3.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + css-in-js-utils@3.1.0: + dependencies: + hyphenate-style-name: 1.1.0 + + css-select@5.2.2: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-tree@1.1.3: + dependencies: + mdn-data: 2.0.14 + source-map: 0.6.1 + + css-what@6.2.2: {} + + cssesc@3.0.0: {} + + csstype@3.2.3: {} + + daisyui@5.5.19: {} + + data-view-buffer@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-offset@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + dateformat@4.6.3: {} + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.4.3(supports-color@8.1.1): + dependencies: + ms: 2.1.3 + optionalDependencies: + supports-color: 8.1.1 + + decode-named-character-reference@1.3.0: + dependencies: + character-entities: 2.0.2 + + decode-uri-component@0.2.2: {} + + dedent@1.7.1: {} + + deep-is@0.1.4: {} + + deepmerge@4.3.1: {} + + defaults@1.0.4: + dependencies: + clone: 1.0.4 + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-lazy-prop@2.0.0: {} + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + delayed-stream@1.0.0: {} + + depd@2.0.0: {} + + dequal@2.0.3: {} + + destroy@1.2.0: {} + + detect-indent@7.0.2: {} + + detect-libc@2.1.2: {} + + detect-newline@4.0.1: {} + + detect-node-es@1.1.0: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + diff@4.0.4: {} + + diff@7.0.0: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + dnssd-advertise@1.1.3: {} + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domino@2.1.6: {} + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dotenv-expand@11.0.7: + dependencies: + dotenv: 16.4.7 + + dotenv@16.0.3: {} + + dotenv@16.3.1: {} + + dotenv@16.4.7: {} + + dtrace-provider@0.8.8: + dependencies: + nan: 2.25.0 + optional: true + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + eas-cli@18.0.6(@types/node@25.3.2)(typescript@5.9.3): + dependencies: + '@expo/apple-utils': 2.1.13 + '@expo/code-signing-certificates': 0.0.5 + '@expo/config': 10.0.6 + '@expo/config-plugins': 9.0.12 + '@expo/eas-build-job': 18.0.2 + '@expo/eas-json': 18.0.2 + '@expo/env': 1.0.7 + '@expo/json-file': 8.3.3 + '@expo/logger': 18.0.1 + '@expo/multipart-body-parser': 2.0.0 + '@expo/osascript': 2.1.4 + '@expo/package-manager': 1.9.10 + '@expo/pkcs12': 0.1.3 + '@expo/plist': 0.2.0 + '@expo/plugin-help': 5.1.23(@types/node@25.3.2)(typescript@5.9.3) + '@expo/plugin-warn-if-update-available': 2.5.1(@types/node@25.3.2)(typescript@5.9.3) + '@expo/prebuild-config': 8.0.17 + '@expo/results': 1.0.0 + '@expo/rudder-sdk-node': 1.1.1 + '@expo/spawn-async': 1.7.2 + '@expo/steps': 18.0.2 + '@expo/timeago.js': 1.0.0 + '@oclif/core': 1.26.2 + '@oclif/plugin-autocomplete': 2.3.10(@types/node@25.3.2)(typescript@5.9.3) + '@segment/ajv-human-errors': 2.16.0(ajv@8.11.0) + '@urql/core': 4.0.11(graphql@16.8.1) + '@urql/exchange-retry': 1.2.0(graphql@16.8.1) + ajv: 8.11.0 + ajv-formats: 2.1.1(ajv@8.11.0) + better-opn: 3.0.2 + bplist-parser: 0.3.2 + chalk: 4.1.2 + cli-progress: 3.12.0 + dateformat: 4.6.3 + diff: 7.0.0 + dotenv: 16.3.1 + env-paths: 2.2.0 + envinfo: 7.11.0 + fast-deep-equal: 3.1.3 + fast-glob: 3.3.2 + figures: 3.2.0 + form-data: 4.0.5 + fs-extra: 11.2.0 + getenv: 1.0.0 + gradle-to-js: 2.0.1 + graphql: 16.8.1 + graphql-tag: 2.12.6(graphql@16.8.1) + https-proxy-agent: 5.0.1 + ignore: 5.3.0 + indent-string: 4.0.0 + invariant: 2.2.4 + jks-js: 1.1.0 + joi: 17.11.0 + keychain: 1.5.0 + log-symbols: 4.1.0 + mime: 3.0.0 + minimatch: 5.1.2 + minizlib: 3.0.1 + nanoid: 3.3.8 + node-fetch: 2.6.7 + node-forge: 1.3.1 + node-stream-zip: 1.15.0 + nullthrows: 1.1.1 + ora: 5.1.0 + pkg-dir: 4.2.0 + pngjs: 7.0.0 + promise-limit: 2.7.0 + promise-retry: 2.0.1 + prompts: 2.4.2 + qrcode-terminal: 0.12.0 + resolve-from: 5.0.0 + semver: 7.5.4 + set-interval-async: 3.0.3 + slash: 3.0.0 + tar: 7.5.7 + tar-stream: 3.1.7 + terminal-link: 2.1.1 + ts-deepmerge: 6.2.0 + tslib: 2.6.2 + turndown: 7.1.2 + untildify: 4.0.0 + uuid: 9.0.1 + wrap-ansi: 7.0.0 + yaml: 2.6.0 + zod: 4.3.6 + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + - '@types/node' + - bare-abort-controller + - encoding + - react-native-b4a + - supports-color + - typescript + + eastasianwidth@0.2.0: {} + + ecsify@0.0.15: + dependencies: + '@blgc/utils': 0.0.61 + + ee-first@1.1.1: {} + + ejs@3.1.10: + dependencies: + jake: 10.9.4 + + electron-to-chromium@1.5.302: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + encodeurl@1.0.2: {} + + encodeurl@2.0.0: {} + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + + enhanced-resolve@5.19.0: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.0 + + entities@4.5.0: {} + + env-paths@2.2.0: {} + + env-string@1.0.1: {} + + envinfo@7.11.0: {} + + err-code@2.0.3: {} + + error-ex@1.3.4: + dependencies: + is-arrayish: 0.2.1 + + error-stack-parser@2.1.4: + dependencies: + stackframe: 1.3.4 + + es-abstract@1.24.1: + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-negative-zero: 2.0.3 + is-regex: 1.2.1 + is-set: 2.0.3 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.3 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + stop-iteration-iterator: 1.1.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.20 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-iterator-helpers@1.2.2: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-errors: 1.3.0 + es-set-tostringtag: 2.1.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + iterator.prototype: 1.1.5 + safe-array-concat: 1.1.3 + + es-module-lexer@1.7.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-shim-unscopables@1.1.0: + dependencies: + hasown: 2.0.2 + + es-to-primitive@1.3.0: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + + esast-util-from-estree@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + unist-util-position-from-estree: 2.0.0 + + esast-util-from-js@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + acorn: 8.16.0 + esast-util-from-estree: 2.0.0 + vfile-message: 4.0.3 + + esbuild@0.27.3: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.3 + '@esbuild/android-arm': 0.27.3 + '@esbuild/android-arm64': 0.27.3 + '@esbuild/android-x64': 0.27.3 + '@esbuild/darwin-arm64': 0.27.3 + '@esbuild/darwin-x64': 0.27.3 + '@esbuild/freebsd-arm64': 0.27.3 + '@esbuild/freebsd-x64': 0.27.3 + '@esbuild/linux-arm': 0.27.3 + '@esbuild/linux-arm64': 0.27.3 + '@esbuild/linux-ia32': 0.27.3 + '@esbuild/linux-loong64': 0.27.3 + '@esbuild/linux-mips64el': 0.27.3 + '@esbuild/linux-ppc64': 0.27.3 + '@esbuild/linux-riscv64': 0.27.3 + '@esbuild/linux-s390x': 0.27.3 + '@esbuild/linux-x64': 0.27.3 + '@esbuild/netbsd-arm64': 0.27.3 + '@esbuild/netbsd-x64': 0.27.3 + '@esbuild/openbsd-arm64': 0.27.3 + '@esbuild/openbsd-x64': 0.27.3 + '@esbuild/openharmony-arm64': 0.27.3 + '@esbuild/sunos-x64': 0.27.3 + '@esbuild/win32-arm64': 0.27.3 + '@esbuild/win32-ia32': 0.27.3 + '@esbuild/win32-x64': 0.27.3 + + escalade@3.2.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@2.0.0: {} + + escape-string-regexp@4.0.0: {} + + eslint-config-expo@55.0.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.56.1(@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.3(jiti@2.6.1) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.3(jiti@2.6.1)) + eslint-plugin-expo: 1.0.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.3(jiti@2.6.1)) + eslint-plugin-react: 7.37.5(eslint@9.39.3(jiti@2.6.1)) + eslint-plugin-react-hooks: 5.2.0(eslint@9.39.3(jiti@2.6.1)) + globals: 16.5.0 + transitivePeerDependencies: + - eslint-import-resolver-webpack + - eslint-plugin-import-x + - supports-color + - typescript + + eslint-config-prettier@10.1.8(eslint@9.39.3(jiti@2.6.1)): + dependencies: + eslint: 9.39.3(jiti@2.6.1) + + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: 2.16.1 + resolve: 1.22.11 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.3(jiti@2.6.1)): + dependencies: + '@nolyfill/is-core-module': 1.0.39 + debug: 4.4.3(supports-color@8.1.1) + eslint: 9.39.3(jiti@2.6.1) + get-tsconfig: 4.13.6 + is-bun-module: 2.0.0 + stable-hash: 0.0.5 + tinyglobby: 0.2.15 + unrs-resolver: 1.11.1 + optionalDependencies: + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.3(jiti@2.6.1)) + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.3(jiti@2.6.1)): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.3(jiti@2.6.1) + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.3(jiti@2.6.1)) + transitivePeerDependencies: + - supports-color + + eslint-plugin-expo@1.0.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3): + dependencies: + '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/utils': 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.3(jiti@2.6.1) + transitivePeerDependencies: + - supports-color + - typescript + + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.3(jiti@2.6.1)): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.9 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.39.3(jiti@2.6.1) + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.3(jiti@2.6.1)) + hasown: 2.0.2 + is-core-module: 2.16.1 + is-glob: 4.0.3 + minimatch: 3.1.5 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-only-warn@1.1.0: {} + + eslint-plugin-react-hooks@5.2.0(eslint@9.39.3(jiti@2.6.1)): + dependencies: + eslint: 9.39.3(jiti@2.6.1) + + eslint-plugin-react-hooks@7.0.1(eslint@9.39.3(jiti@2.6.1)): + dependencies: + '@babel/core': 7.29.0 + '@babel/parser': 7.29.0 + eslint: 9.39.3(jiti@2.6.1) + hermes-parser: 0.25.1 + zod: 4.3.6 + zod-validation-error: 4.0.2(zod@4.3.6) + transitivePeerDependencies: + - supports-color + + eslint-plugin-react@7.37.5(eslint@9.39.3(jiti@2.6.1)): + dependencies: + array-includes: 3.1.9 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.3 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.0 + es-iterator-helpers: 1.2.2 + eslint: 9.39.3(jiti@2.6.1) + estraverse: 5.3.0 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.5 + object.entries: 1.1.9 + object.fromentries: 2.0.8 + object.values: 1.2.1 + prop-types: 15.8.1 + resolve: 2.0.0-next.6 + semver: 6.3.1 + string.prototype.matchall: 4.0.12 + string.prototype.repeat: 1.0.0 + + eslint-plugin-turbo@2.8.11(eslint@9.39.3(jiti@2.6.1))(turbo@2.8.11): + dependencies: + dotenv: 16.0.3 + eslint: 9.39.3(jiti@2.6.1) + turbo: 2.8.11 + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint-visitor-keys@5.0.1: {} + + eslint@9.39.3(jiti@2.6.1): + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.3(jiti@2.6.1)) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.1 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.4 + '@eslint/js': 9.39.3 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.7 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.8 + ajv: 6.14.0 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3(supports-color@8.1.1) + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.6.1 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + eslint-visitor-keys: 4.2.1 + + esprima@4.0.1: {} + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-util-attach-comments@3.0.0: + dependencies: + '@types/estree': 1.0.8 + + estree-util-build-jsx@3.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-walker: 3.0.3 + + estree-util-is-identifier-name@3.0.0: {} + + estree-util-scope@1.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + + estree-util-to-js@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + astring: 1.9.0 + source-map: 0.7.6 + + estree-util-visit@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/unist': 3.0.3 + + estree-walker@2.0.2: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + esutils@2.0.3: {} + + etag@1.8.1: {} + + event-target-shim@5.0.1: {} + + events-universal@1.0.1: + dependencies: + bare-events: 2.8.2 + transitivePeerDependencies: + - bare-abort-controller + + events@3.3.0: + optional: true + + exec-async@2.2.0: {} + + execa@1.0.0: + dependencies: + cross-spawn: 6.0.6 + get-stream: 4.1.0 + is-stream: 1.1.0 + npm-run-path: 2.0.2 + p-finally: 1.0.0 + signal-exit: 3.0.7 + strip-eof: 1.0.0 + + execa@9.6.1: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + cross-spawn: 7.0.6 + figures: 6.1.0 + get-stream: 9.0.1 + human-signals: 8.0.1 + is-plain-obj: 4.1.0 + is-stream: 4.0.1 + npm-run-path: 6.0.0 + pretty-ms: 9.3.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.1.2 + + exit-hook@2.2.1: {} + + expect-type@1.3.0: {} + + expo-asset@55.0.8(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3): + dependencies: + '@expo/image-utils': 0.8.12 + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + expo-constants: 55.0.7(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(typescript@5.9.3) + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + transitivePeerDependencies: + - supports-color + - typescript + + expo-constants@55.0.7(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(typescript@5.9.3): + dependencies: + '@expo/config': 55.0.8(typescript@5.9.3) + '@expo/env': 2.1.1 + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + transitivePeerDependencies: + - supports-color + - typescript + + expo-dev-client@55.0.10(expo@55.0.3)(typescript@5.9.3): + dependencies: + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + expo-dev-launcher: 55.0.11(expo@55.0.3)(typescript@5.9.3) + expo-dev-menu: 55.0.10(expo@55.0.3) + expo-dev-menu-interface: 55.0.1(expo@55.0.3) + expo-manifests: 55.0.9(expo@55.0.3)(typescript@5.9.3) + expo-updates-interface: 55.1.3(expo@55.0.3) + transitivePeerDependencies: + - supports-color + - typescript + + expo-dev-launcher@55.0.11(expo@55.0.3)(typescript@5.9.3): + dependencies: + '@expo/schema-utils': 55.0.2 + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + expo-dev-menu: 55.0.10(expo@55.0.3) + expo-manifests: 55.0.9(expo@55.0.3)(typescript@5.9.3) + transitivePeerDependencies: + - supports-color + - typescript + + expo-dev-menu-interface@55.0.1(expo@55.0.3): + dependencies: + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + + expo-dev-menu@55.0.10(expo@55.0.3): + dependencies: + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + expo-dev-menu-interface: 55.0.1(expo@55.0.3) + + expo-device@55.0.9(expo@55.0.3): + dependencies: + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + ua-parser-js: 0.7.41 + + expo-file-system@55.0.10(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4)): + dependencies: + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + + expo-font@55.0.4(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4): + dependencies: + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + fontfaceobserver: 2.3.0 + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + + expo-glass-effect@55.0.7(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4): + dependencies: + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + + expo-haptics@15.0.8(expo@55.0.3): + dependencies: + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + + expo-image@55.0.5(expo@55.0.3)(react-native-web@0.21.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4): + dependencies: + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + sf-symbols-typescript: 2.2.0 + optionalDependencies: + react-native-web: 0.21.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + + expo-json-utils@55.0.0: {} + + expo-keep-awake@55.0.4(expo@55.0.3)(react@19.2.4): + dependencies: + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + react: 19.2.4 + + expo-linking@55.0.7(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3): + dependencies: + expo-constants: 55.0.7(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(typescript@5.9.3) + invariant: 2.2.4 + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + transitivePeerDependencies: + - expo + - supports-color + - typescript + + expo-manifests@55.0.9(expo@55.0.3)(typescript@5.9.3): + dependencies: + '@expo/config': 55.0.8(typescript@5.9.3) + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + expo-json-utils: 55.0.0 + transitivePeerDependencies: + - supports-color + - typescript + + expo-modules-autolinking@55.0.8(typescript@5.9.3): + dependencies: + '@expo/require-utils': 55.0.2(typescript@5.9.3) + '@expo/spawn-async': 1.7.2 + chalk: 4.1.2 + commander: 7.2.0 + transitivePeerDependencies: + - supports-color + - typescript + + expo-modules-core@55.0.13(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4): + dependencies: + invariant: 2.2.4 + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + + expo-router@55.0.3(715e0706cc640a8619e3400aac055546): + dependencies: + '@expo/log-box': 55.0.7(@expo/dom-webview@55.0.3)(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + '@expo/metro-runtime': 55.0.6(@expo/dom-webview@55.0.3)(expo@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + '@expo/schema-utils': 55.0.2 + '@radix-ui/react-slot': 1.2.4(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-navigation/bottom-tabs': 7.15.2(@react-navigation/native@7.1.31(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native-safe-area-context@5.6.2(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native-screens@4.23.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + '@react-navigation/native': 7.1.31(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + '@react-navigation/native-stack': 7.14.2(@react-navigation/native@7.1.31(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native-safe-area-context@5.6.2(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native-screens@4.23.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + client-only: 0.0.1 + debug: 4.4.3(supports-color@8.1.1) + escape-string-regexp: 4.0.0 + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + expo-constants: 55.0.7(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(typescript@5.9.3) + expo-glass-effect: 55.0.7(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + expo-image: 55.0.5(expo@55.0.3)(react-native-web@0.21.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + expo-linking: 55.0.7(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + expo-server: 55.0.6 + expo-symbols: 55.0.4(expo-font@55.0.4)(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + fast-deep-equal: 3.1.3 + invariant: 2.2.4 + nanoid: 3.3.11 + query-string: 7.1.3 + react: 19.2.4 + react-fast-compare: 3.2.2 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + react-native-is-edge-to-edge: 1.2.1(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + react-native-safe-area-context: 5.6.2(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + react-native-screens: 4.23.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + semver: 7.6.3 + server-only: 0.0.1 + sf-symbols-typescript: 2.2.0 + shallowequal: 1.1.0 + use-latest-callback: 0.2.6(react@19.2.4) + vaul: 1.1.2(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + optionalDependencies: + react-dom: 19.2.4(react@19.2.4) + react-native-gesture-handler: 2.30.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + react-native-reanimated: 4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + react-native-web: 0.21.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + transitivePeerDependencies: + - '@react-native-masked-view/masked-view' + - '@types/react' + - '@types/react-dom' + - expo-font + - supports-color + + expo-server@55.0.6: {} + + expo-splash-screen@55.0.10(expo@55.0.3)(typescript@5.9.3): + dependencies: + '@expo/prebuild-config': 55.0.8(expo@55.0.3)(typescript@5.9.3) + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + transitivePeerDependencies: + - supports-color + - typescript + + expo-status-bar@55.0.4(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4): + dependencies: + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + react-native-is-edge-to-edge: 1.2.1(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + + expo-symbols@55.0.4(expo-font@55.0.4)(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4): + dependencies: + '@expo-google-fonts/material-symbols': 0.4.24 + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + expo-font: 55.0.4(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + sf-symbols-typescript: 2.2.0 + + expo-system-ui@55.0.9(expo@55.0.3)(react-native-web@0.21.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4)): + dependencies: + '@react-native/normalize-colors': 0.83.2 + debug: 4.4.3(supports-color@8.1.1) + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + optionalDependencies: + react-native-web: 0.21.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + transitivePeerDependencies: + - supports-color + + expo-updates-interface@55.1.3(expo@55.0.3): + dependencies: + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + + expo-web-browser@55.0.9(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4)): + dependencies: + expo: 55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + + expo@55.0.3(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-router@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3): + dependencies: + '@babel/runtime': 7.28.6 + '@expo/cli': 55.0.13(@expo/dom-webview@55.0.3)(@expo/metro-runtime@55.0.6)(expo-constants@55.0.7)(expo-font@55.0.4)(expo-router@55.0.3)(expo@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + '@expo/config': 55.0.8(typescript@5.9.3) + '@expo/config-plugins': 55.0.6 + '@expo/devtools': 55.0.2(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + '@expo/fingerprint': 0.16.5 + '@expo/local-build-cache-provider': 55.0.6(typescript@5.9.3) + '@expo/log-box': 55.0.7(@expo/dom-webview@55.0.3)(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + '@expo/metro': 54.2.0 + '@expo/metro-config': 55.0.9(expo@55.0.3)(typescript@5.9.3) + '@expo/vector-icons': 15.1.1(expo-font@55.0.4)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + '@ungap/structured-clone': 1.3.0 + babel-preset-expo: 55.0.9(@babel/core@7.29.0)(@babel/runtime@7.28.6)(expo@55.0.3)(react-refresh@0.14.2) + expo-asset: 55.0.8(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + expo-constants: 55.0.7(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(typescript@5.9.3) + expo-file-system: 55.0.10(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4)) + expo-font: 55.0.4(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + expo-keep-awake: 55.0.4(expo@55.0.3)(react@19.2.4) + expo-modules-autolinking: 55.0.8(typescript@5.9.3) + expo-modules-core: 55.0.13(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + pretty-format: 29.7.0 + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + react-refresh: 0.14.2 + whatwg-url-minimum: 0.1.1 + optionalDependencies: + '@expo/dom-webview': 55.0.3(expo@55.0.3)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + '@expo/metro-runtime': 55.0.6(@expo/dom-webview@55.0.3)(expo@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + transitivePeerDependencies: + - '@babel/core' + - bufferutil + - expo-router + - expo-widgets + - react-dom + - react-server-dom-webpack + - supports-color + - typescript + - utf-8-validate + + exponential-backoff@3.1.3: {} + + express@4.22.1: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.4 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.0.7 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.3.2 + fresh: 0.5.2 + http-errors: 2.0.1 + merge-descriptors: 1.0.3 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.12 + proxy-addr: 2.0.7 + qs: 6.14.2 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.19.2 + serve-static: 1.16.3 + setprototypeof: 1.2.0 + statuses: 2.0.2 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + exsolve@1.0.8: {} + + extend@3.0.2: {} + + fast-deep-equal@3.1.3: {} + + fast-fifo@1.3.2: {} + + fast-glob@3.3.1: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + fb-dotslash@0.5.8: {} + + fb-watchman@2.0.2: + dependencies: + bser: 2.1.1 + + fbjs-css-vars@1.0.2: {} + + fbjs@3.0.5: + dependencies: + cross-fetch: 3.2.0 + fbjs-css-vars: 1.0.2 + loose-envify: 1.4.0 + object-assign: 4.1.1 + promise: 7.3.1 + setimmediate: 1.0.5 + ua-parser-js: 1.0.41 + transitivePeerDependencies: + - encoding + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + feature-react@0.0.67(react@19.2.4): + dependencies: + '@blgc/types': 0.0.21 + '@blgc/utils': 0.0.61 + react: 19.2.4 + + feature-state@0.0.65: + dependencies: + '@blgc/types': 0.0.21 + '@blgc/utils': 0.0.61 + + fetch-nodeshim@0.4.8: {} + + fetch-retry@4.1.1: {} + + figures@3.2.0: + dependencies: + escape-string-regexp: 1.0.5 + + figures@6.1.0: + dependencies: + is-unicode-supported: 2.1.0 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + filelist@1.0.6: + dependencies: + minimatch: 5.1.2 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + filter-obj@1.1.0: {} + + finalhandler@1.1.2: + dependencies: + debug: 2.6.9 + encodeurl: 1.0.2 + escape-html: 1.0.3 + on-finished: 2.3.0 + parseurl: 1.3.3 + statuses: 1.5.0 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + finalhandler@1.3.2: + dependencies: + debug: 2.6.9 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + + flatted@3.3.3: {} + + flow-enums-runtime@0.0.6: {} + + fontfaceobserver@2.3.0: {} + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + form-data@4.0.5: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + + forwarded@0.2.0: {} + + fresh@0.5.2: {} + + fs-extra@10.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 + + fs-extra@11.2.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 + + fs-extra@9.0.0: + dependencies: + at-least-node: 1.0.0 + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 1.0.0 + + fs-extra@9.1.0: + dependencies: + at-least-node: 1.0.0 + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + function.prototype.name@1.1.8: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + hasown: 2.0.2 + is-callable: 1.2.7 + + functions-have-names@1.2.3: {} + + generator-function@2.0.1: {} + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-nonce@1.0.1: {} + + get-package-type@0.1.0: {} + + get-port@5.1.1: {} + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-stream@4.1.0: + dependencies: + pump: 3.0.3 + + get-stream@9.0.1: + dependencies: + '@sec-ant/readable-stream': 0.4.1 + is-stream: 4.0.1 + + get-symbol-description@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + + get-tsconfig@4.13.6: + dependencies: + resolve-pkg-maps: 1.0.0 + + getenv@1.0.0: {} + + getenv@2.0.0: {} + + git-hooks-list@4.2.1: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@10.5.0: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.9 + minipass: 7.1.3 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + glob@13.0.6: + dependencies: + minimatch: 10.2.4 + minipass: 7.1.3 + path-scurry: 2.0.2 + + glob@6.0.4: + dependencies: + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.5 + once: 1.4.0 + path-is-absolute: 1.0.1 + optional: true + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.5 + once: 1.4.0 + path-is-absolute: 1.0.1 + + globals@14.0.0: {} + + globals@16.5.0: {} + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + globrex@0.1.2: {} + + golden-fleece@1.0.9: {} + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + gradle-to-js@2.0.1: + dependencies: + lodash.merge: 4.6.2 + + graphql-tag@2.12.6(graphql@16.8.1): + dependencies: + graphql: 16.8.1 + tslib: 2.8.1 + + graphql@16.8.1: {} + + has-bigints@1.1.0: {} + + has-flag@3.0.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-proto@1.2.0: + dependencies: + dunder-proto: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + hast-util-to-estree@3.1.3: + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-attach-comments: 3.0.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + zwitch: 2.0.4 + transitivePeerDependencies: + - supports-color + + hast-util-to-jsx-runtime@2.3.6: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hermes-compiler@0.14.1: {} + + hermes-estree@0.25.1: {} + + hermes-estree@0.32.0: {} + + hermes-estree@0.32.1: {} + + hermes-estree@0.33.3: {} + + hermes-parser@0.25.1: + dependencies: + hermes-estree: 0.25.1 + + hermes-parser@0.32.0: + dependencies: + hermes-estree: 0.32.0 + + hermes-parser@0.32.1: + dependencies: + hermes-estree: 0.32.1 + + hermes-parser@0.33.3: + dependencies: + hermes-estree: 0.33.3 + + hoist-non-react-statics@3.3.2: + dependencies: + react-is: 16.13.1 + + hono@4.12.3: {} + + hosted-git-info@7.0.2: + dependencies: + lru-cache: 10.4.3 + + http-call@5.3.0: + dependencies: + content-type: 1.0.5 + debug: 4.4.3(supports-color@8.1.1) + is-retry-allowed: 1.2.0 + is-stream: 2.0.1 + parse-json: 4.0.0 + tunnel-agent: 0.6.0 + transitivePeerDependencies: + - supports-color + + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + human-signals@8.0.1: {} + + hyperlinker@1.0.0: {} + + hyphenate-style-name@1.1.0: {} + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + idb@8.0.3: {} + + ieee754@1.2.1: + optional: true + + ignore@5.3.0: {} + + ignore@5.3.2: {} + + ignore@7.0.5: {} + + image-size@1.2.1: + dependencies: + queue: 6.0.2 + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + indent-string@4.0.0: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + inline-style-parser@0.2.7: {} + + inline-style-prefixer@7.0.1: + dependencies: + css-in-js-utils: 3.1.0 + + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.1.0 + + interpret@1.4.0: {} + + invariant@2.2.4: + dependencies: + loose-envify: 1.4.0 + + ipaddr.js@1.9.1: {} + + is-alphabetical@2.0.1: {} + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-arrayish@0.2.1: {} + + is-arrayish@0.3.4: {} + + is-async-function@2.1.1: + dependencies: + async-function: 1.0.0 + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-bigint@1.1.0: + dependencies: + has-bigints: 1.1.0 + + is-boolean-object@1.2.2: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-buffer@1.1.6: {} + + is-bun-module@2.0.0: + dependencies: + semver: 7.7.4 + + is-callable@1.2.7: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-data-view@1.0.2: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-decimal@2.0.1: {} + + is-docker@2.2.1: {} + + is-extglob@2.1.1: {} + + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-fullwidth-code-point@3.0.0: {} + + is-generator-function@1.1.2: + dependencies: + call-bound: 1.0.4 + generator-function: 2.0.1 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-hexadecimal@2.0.1: {} + + is-interactive@1.0.0: {} + + is-map@2.0.3: {} + + is-negative-zero@2.0.3: {} + + is-number-object@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-number@7.0.0: {} + + is-plain-obj@4.1.0: {} + + is-reference@1.2.1: + dependencies: + '@types/estree': 1.0.8 + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + is-retry-allowed@1.2.0: {} + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: + dependencies: + call-bound: 1.0.4 + + is-stream@1.1.0: {} + + is-stream@2.0.1: {} + + is-stream@4.0.1: {} + + is-string@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.20 + + is-unicode-supported@0.1.0: {} + + is-unicode-supported@2.1.0: {} + + is-weakmap@2.0.2: {} + + is-weakref@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + + isarray@2.0.5: {} + + isbot@5.1.35: {} + + isexe@2.0.0: {} + + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-instrument@5.2.1: + dependencies: + '@babel/core': 7.29.0 + '@babel/parser': 7.29.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + iterator.prototype@1.1.5: + dependencies: + define-data-property: 1.1.4 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + has-symbols: 1.1.0 + set-function-name: 2.0.2 + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jake@10.9.4: + dependencies: + async: 3.2.6 + filelist: 1.0.6 + picocolors: 1.1.1 + + jest-environment-node@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 25.3.2 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + jest-get-type@29.6.3: {} + + jest-haste-map@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/graceful-fs': 4.1.9 + '@types/node': 25.3.2 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + jest-worker: 29.7.0 + micromatch: 4.0.8 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + + jest-message-util@29.7.0: + dependencies: + '@babel/code-frame': 7.29.0 + '@jest/types': 29.6.3 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + stack-utils: 2.0.6 + + jest-mock@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 25.3.2 + jest-util: 29.7.0 + + jest-regex-util@29.6.3: {} + + jest-util@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 25.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.1 + + jest-validate@29.7.0: + dependencies: + '@jest/types': 29.6.3 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 29.6.3 + leven: 3.1.0 + pretty-format: 29.7.0 + + jest-worker@29.7.0: + dependencies: + '@types/node': 25.3.2 + jest-util: 29.7.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jimp-compact@0.16.1: {} + + jiti@2.6.1: {} + + jks-js@1.1.0: + dependencies: + node-forge: 1.3.3 + node-int64: 0.4.0 + node-rsa: 1.1.1 + + joi@17.11.0: + dependencies: + '@hapi/hoek': 9.3.0 + '@hapi/topo': 5.1.0 + '@sideway/address': 4.1.5 + '@sideway/formula': 3.0.1 + '@sideway/pinpoint': 2.0.0 + + joi@17.13.3: + dependencies: + '@hapi/hoek': 9.3.0 + '@hapi/topo': 5.1.0 + '@sideway/address': 4.1.5 + '@sideway/formula': 3.0.1 + '@sideway/pinpoint': 2.0.0 + + join-component@1.1.0: {} + + js-tokens@4.0.0: {} + + js-yaml@3.14.2: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + jsc-safe-url@0.2.4: {} + + jsep@1.4.0: {} + + jsesc@3.0.2: {} + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-parse-better-errors@1.0.2: {} + + json-schema-to-ts@1.6.4: + dependencies: + '@types/json-schema': 7.0.15 + ts-toolbelt: 6.15.5 + + json-schema-traverse@0.4.1: {} + + json-schema-traverse@1.0.0: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + json5@2.2.3: {} + + jsonfile@6.2.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + jsx-ast-utils@3.3.5: + dependencies: + array-includes: 3.1.9 + array.prototype.flat: 1.3.3 + object.assign: 4.1.7 + object.values: 1.2.1 + + keychain@1.5.0: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kleur@3.0.3: {} + + lan-network@0.2.0: {} + + leven@3.1.0: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lighthouse-logger@1.4.2: + dependencies: + debug: 2.6.9 + marky: 1.3.0 + transitivePeerDependencies: + - supports-color + + lightningcss-darwin-arm64@1.30.1: + optional: true + + lightningcss-darwin-x64@1.30.1: + optional: true + + lightningcss-freebsd-x64@1.30.1: + optional: true + + lightningcss-linux-arm-gnueabihf@1.30.1: + optional: true + + lightningcss-linux-arm64-gnu@1.30.1: + optional: true + + lightningcss-linux-arm64-musl@1.30.1: + optional: true + + lightningcss-linux-x64-gnu@1.30.1: + optional: true + + lightningcss-linux-x64-musl@1.30.1: + optional: true + + lightningcss-win32-arm64-msvc@1.30.1: + optional: true + + lightningcss-win32-x64-msvc@1.30.1: + optional: true + + lightningcss@1.30.1: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-darwin-arm64: 1.30.1 + lightningcss-darwin-x64: 1.30.1 + lightningcss-freebsd-x64: 1.30.1 + lightningcss-linux-arm-gnueabihf: 1.30.1 + lightningcss-linux-arm64-gnu: 1.30.1 + lightningcss-linux-arm64-musl: 1.30.1 + lightningcss-linux-x64-gnu: 1.30.1 + lightningcss-linux-x64-musl: 1.30.1 + lightningcss-win32-arm64-msvc: 1.30.1 + lightningcss-win32-x64-msvc: 1.30.1 + + lines-and-columns@1.2.4: {} + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.clonedeep@4.5.0: {} + + lodash.debounce@4.0.8: {} + + lodash.get@4.4.2: {} + + lodash.merge@4.6.2: {} + + lodash.throttle@4.1.1: {} + + lodash@4.17.23: {} + + log-symbols@2.2.0: + dependencies: + chalk: 2.4.2 + + log-symbols@4.1.0: + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + + longest-streak@3.1.0: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lru-cache@10.4.3: {} + + lru-cache@11.2.6: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lru-cache@6.0.0: + dependencies: + yallist: 4.0.0 + + lucide-react@0.563.0(react@19.2.4): + dependencies: + react: 19.2.4 + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + make-error@1.3.6: {} + + makeerror@1.0.12: + dependencies: + tmpl: 1.0.5 + + markdown-extensions@2.0.0: {} + + marky@1.3.0: {} + + math-intrinsics@1.1.0: {} + + md5@2.3.0: + dependencies: + charenc: 0.0.2 + crypt: 0.0.2 + is-buffer: 1.1.6 + + mdast-util-from-markdown@2.0.3: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-expression@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-jsx@3.2.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx@3.0.0: + dependencies: + mdast-util-from-markdown: 2.0.3 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdxjs-esm@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.1 + + mdast-util-to-hast@13.2.1: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.1.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + mdn-data@2.0.14: {} + + media-typer@0.3.0: {} + + memoize-one@5.2.1: {} + + memoize-one@6.0.0: {} + + merge-descriptors@1.0.3: {} + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + methods@1.1.2: {} + + metro-babel-transformer@0.83.3: + dependencies: + '@babel/core': 7.29.0 + flow-enums-runtime: 0.0.6 + hermes-parser: 0.32.0 + nullthrows: 1.1.1 + transitivePeerDependencies: + - supports-color + + metro-babel-transformer@0.83.4: + dependencies: + '@babel/core': 7.29.0 + flow-enums-runtime: 0.0.6 + hermes-parser: 0.33.3 + nullthrows: 1.1.1 + transitivePeerDependencies: + - supports-color + + metro-cache-key@0.83.3: + dependencies: + flow-enums-runtime: 0.0.6 + + metro-cache-key@0.83.4: + dependencies: + flow-enums-runtime: 0.0.6 + + metro-cache@0.83.3: + dependencies: + exponential-backoff: 3.1.3 + flow-enums-runtime: 0.0.6 + https-proxy-agent: 7.0.6 + metro-core: 0.83.3 + transitivePeerDependencies: + - supports-color + + metro-cache@0.83.4: + dependencies: + exponential-backoff: 3.1.3 + flow-enums-runtime: 0.0.6 + https-proxy-agent: 7.0.6 + metro-core: 0.83.4 + transitivePeerDependencies: + - supports-color + + metro-config@0.83.3: + dependencies: + connect: 3.7.0 + flow-enums-runtime: 0.0.6 + jest-validate: 29.7.0 + metro: 0.83.3 + metro-cache: 0.83.3 + metro-core: 0.83.3 + metro-runtime: 0.83.3 + yaml: 2.8.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + metro-config@0.83.4: + dependencies: + connect: 3.7.0 + flow-enums-runtime: 0.0.6 + jest-validate: 29.7.0 + metro: 0.83.4 + metro-cache: 0.83.4 + metro-core: 0.83.4 + metro-runtime: 0.83.4 + yaml: 2.8.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + metro-core@0.83.3: + dependencies: + flow-enums-runtime: 0.0.6 + lodash.throttle: 4.1.1 + metro-resolver: 0.83.3 + + metro-core@0.83.4: + dependencies: + flow-enums-runtime: 0.0.6 + lodash.throttle: 4.1.1 + metro-resolver: 0.83.4 + + metro-file-map@0.83.3: + dependencies: + debug: 4.4.3(supports-color@8.1.1) + fb-watchman: 2.0.2 + flow-enums-runtime: 0.0.6 + graceful-fs: 4.2.11 + invariant: 2.2.4 + jest-worker: 29.7.0 + micromatch: 4.0.8 + nullthrows: 1.1.1 + walker: 1.0.8 + transitivePeerDependencies: + - supports-color + + metro-file-map@0.83.4: + dependencies: + debug: 4.4.3(supports-color@8.1.1) + fb-watchman: 2.0.2 + flow-enums-runtime: 0.0.6 + graceful-fs: 4.2.11 + invariant: 2.2.4 + jest-worker: 29.7.0 + micromatch: 4.0.8 + nullthrows: 1.1.1 + walker: 1.0.8 + transitivePeerDependencies: + - supports-color + + metro-minify-terser@0.83.3: + dependencies: + flow-enums-runtime: 0.0.6 + terser: 5.46.0 + + metro-minify-terser@0.83.4: + dependencies: + flow-enums-runtime: 0.0.6 + terser: 5.46.0 + + metro-resolver@0.83.3: + dependencies: + flow-enums-runtime: 0.0.6 + + metro-resolver@0.83.4: + dependencies: + flow-enums-runtime: 0.0.6 + + metro-runtime@0.83.3: + dependencies: + '@babel/runtime': 7.28.6 + flow-enums-runtime: 0.0.6 + + metro-runtime@0.83.4: + dependencies: + '@babel/runtime': 7.28.6 + flow-enums-runtime: 0.0.6 + + metro-source-map@0.83.3: + dependencies: + '@babel/traverse': 7.29.0 + '@babel/traverse--for-generate-function-map': '@babel/traverse@7.29.0' + '@babel/types': 7.29.0 + flow-enums-runtime: 0.0.6 + invariant: 2.2.4 + metro-symbolicate: 0.83.3 + nullthrows: 1.1.1 + ob1: 0.83.3 + source-map: 0.5.7 + vlq: 1.0.1 + transitivePeerDependencies: + - supports-color + + metro-source-map@0.83.4: + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + flow-enums-runtime: 0.0.6 + invariant: 2.2.4 + metro-symbolicate: 0.83.4 + nullthrows: 1.1.1 + ob1: 0.83.4 + source-map: 0.5.7 + vlq: 1.0.1 + transitivePeerDependencies: + - supports-color + + metro-symbolicate@0.83.3: + dependencies: + flow-enums-runtime: 0.0.6 + invariant: 2.2.4 + metro-source-map: 0.83.3 + nullthrows: 1.1.1 + source-map: 0.5.7 + vlq: 1.0.1 + transitivePeerDependencies: + - supports-color + + metro-symbolicate@0.83.4: + dependencies: + flow-enums-runtime: 0.0.6 + invariant: 2.2.4 + metro-source-map: 0.83.4 + nullthrows: 1.1.1 + source-map: 0.5.7 + vlq: 1.0.1 + transitivePeerDependencies: + - supports-color + + metro-transform-plugins@0.83.3: + dependencies: + '@babel/core': 7.29.0 + '@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 + transitivePeerDependencies: + - supports-color + + metro-transform-plugins@0.83.4: + dependencies: + '@babel/core': 7.29.0 + '@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 + transitivePeerDependencies: + - supports-color + + metro-transform-worker@0.83.3: + dependencies: + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + flow-enums-runtime: 0.0.6 + metro: 0.83.3 + metro-babel-transformer: 0.83.3 + metro-cache: 0.83.3 + metro-cache-key: 0.83.3 + metro-minify-terser: 0.83.3 + metro-source-map: 0.83.3 + metro-transform-plugins: 0.83.3 + nullthrows: 1.1.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + metro-transform-worker@0.83.4: + dependencies: + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + flow-enums-runtime: 0.0.6 + metro: 0.83.4 + metro-babel-transformer: 0.83.4 + metro-cache: 0.83.4 + metro-cache-key: 0.83.4 + metro-minify-terser: 0.83.4 + metro-source-map: 0.83.4 + metro-transform-plugins: 0.83.4 + nullthrows: 1.1.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + metro@0.83.3: + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/core': 7.29.0 + '@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: 1.3.8 + chalk: 4.1.2 + ci-info: 2.0.0 + connect: 3.7.0 + debug: 4.4.3(supports-color@8.1.1) + error-stack-parser: 2.1.4 + flow-enums-runtime: 0.0.6 + graceful-fs: 4.2.11 + hermes-parser: 0.32.0 + image-size: 1.2.1 + invariant: 2.2.4 + jest-worker: 29.7.0 + jsc-safe-url: 0.2.4 + lodash.throttle: 4.1.1 + metro-babel-transformer: 0.83.3 + metro-cache: 0.83.3 + metro-cache-key: 0.83.3 + metro-config: 0.83.3 + metro-core: 0.83.3 + metro-file-map: 0.83.3 + metro-resolver: 0.83.3 + metro-runtime: 0.83.3 + metro-source-map: 0.83.3 + metro-symbolicate: 0.83.3 + metro-transform-plugins: 0.83.3 + metro-transform-worker: 0.83.3 + mime-types: 2.1.35 + nullthrows: 1.1.1 + serialize-error: 2.1.0 + source-map: 0.5.7 + throat: 5.0.0 + ws: 7.5.10 + yargs: 17.7.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + metro@0.83.4: + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/core': 7.29.0 + '@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 + chalk: 4.1.2 + ci-info: 2.0.0 + connect: 3.7.0 + debug: 4.4.3(supports-color@8.1.1) + error-stack-parser: 2.1.4 + flow-enums-runtime: 0.0.6 + graceful-fs: 4.2.11 + hermes-parser: 0.33.3 + image-size: 1.2.1 + invariant: 2.2.4 + jest-worker: 29.7.0 + jsc-safe-url: 0.2.4 + lodash.throttle: 4.1.1 + metro-babel-transformer: 0.83.4 + metro-cache: 0.83.4 + metro-cache-key: 0.83.4 + metro-config: 0.83.4 + metro-core: 0.83.4 + metro-file-map: 0.83.4 + metro-resolver: 0.83.4 + metro-runtime: 0.83.4 + metro-source-map: 0.83.4 + metro-symbolicate: 0.83.4 + metro-transform-plugins: 0.83.4 + metro-transform-worker: 0.83.4 + mime-types: 3.0.2 + nullthrows: 1.1.1 + serialize-error: 2.1.0 + source-map: 0.5.7 + throat: 5.0.0 + ws: 7.5.10 + yargs: 17.7.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-expression@3.0.1: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-jsx@3.0.2: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + + micromark-extension-mdx-md@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-mdxjs-esm@3.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + + micromark-extension-mdxjs@3.0.0: + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + micromark-extension-mdx-expression: 3.0.1 + micromark-extension-mdx-jsx: 3.0.2 + micromark-extension-mdx-md: 2.0.0 + micromark-extension-mdxjs-esm: 3.0.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-mdx-expression@2.0.3: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.3.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-events-to-acorn@2.0.3: + dependencies: + '@types/estree': 1.0.8 + '@types/unist': 3.0.3 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.12 + debug: 4.4.3(supports-color@8.1.1) + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-db@1.54.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime-types@3.0.2: + dependencies: + mime-db: 1.54.0 + + mime@1.6.0: {} + + mime@3.0.0: {} + + mimic-fn@1.2.0: {} + + mimic-fn@2.1.0: {} + + minimatch@10.2.4: + dependencies: + brace-expansion: 5.0.4 + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.12 + + minimatch@5.1.2: + dependencies: + brace-expansion: 2.0.2 + + minimatch@9.0.9: + dependencies: + brace-expansion: 2.0.2 + + minimist@1.2.8: {} + + minipass@7.1.3: {} + + minizlib@3.0.1: + dependencies: + minipass: 7.1.3 + rimraf: 5.0.10 + + minizlib@3.1.0: + dependencies: + minipass: 7.1.3 + + mkdirp@0.5.6: + dependencies: + minimist: 1.2.8 + optional: true + + mkdirp@1.0.4: {} + + moment@2.30.1: + optional: true + + morgan@1.10.1: + dependencies: + basic-auth: 2.0.1 + debug: 2.6.9 + depd: 2.0.0 + on-finished: 2.3.0 + on-headers: 1.1.0 + transitivePeerDependencies: + - supports-color + + ms@2.0.0: {} + + ms@2.1.3: {} + + multipasta@0.2.7: {} + + multitars@0.2.4: {} + + mute-stream@0.0.8: {} + + mv@2.1.1: + dependencies: + mkdirp: 0.5.6 + ncp: 2.0.0 + rimraf: 2.4.5 + optional: true + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nan@2.25.0: + optional: true + + nanoid@3.3.11: {} + + nanoid@3.3.8: {} + + napi-postinstall@0.3.4: {} + + nativewind@5.0.0-preview.2(react-native-css@3.0.4(@expo/metro-config@55.0.9(expo@55.0.3)(typescript@5.9.3))(lightningcss@1.30.1)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(tailwindcss@4.2.1): + dependencies: + react-native-css: 3.0.4(@expo/metro-config@55.0.9(expo@55.0.3)(typescript@5.9.3))(lightningcss@1.30.1)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + tailwindcss: 4.2.1 + tailwindcss-safe-area: 1.3.0(tailwindcss@4.2.1) + + natural-compare@1.4.0: {} + + natural-orderby@2.0.3: {} + + ncp@2.0.0: + optional: true + + negotiator@0.6.3: {} + + negotiator@0.6.4: {} + + negotiator@1.0.0: {} + + nice-try@1.0.5: {} + + node-exports-info@1.6.0: + dependencies: + array.prototype.flatmap: 1.3.3 + es-errors: 1.3.0 + object.entries: 1.1.9 + semver: 6.3.1 + + node-fetch@2.6.7: + dependencies: + whatwg-url: 5.0.0 + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + node-forge@1.3.1: {} + + node-forge@1.3.3: {} + + node-int64@0.4.0: {} + + node-releases@2.0.27: {} + + node-rsa@1.1.1: + dependencies: + asn1: 0.2.6 + + node-stream-zip@1.15.0: {} + + normalize-path@3.0.0: {} + + npm-package-arg@11.0.3: + dependencies: + hosted-git-info: 7.0.2 + proc-log: 4.2.0 + semver: 7.7.4 + validate-npm-package-name: 5.0.1 + + npm-run-path@2.0.2: + dependencies: + path-key: 2.0.1 + + npm-run-path@6.0.0: + dependencies: + path-key: 4.0.0 + unicorn-magic: 0.3.0 + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + nullthrows@1.1.1: {} + + ob1@0.83.3: + dependencies: + flow-enums-runtime: 0.0.6 + + ob1@0.83.4: + dependencies: + flow-enums-runtime: 0.0.6 + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + object-keys@1.1.1: {} + + object-treeify@1.1.33: {} + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + object.entries@1.1.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-object-atoms: 1.1.1 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + + object.values@1.2.1: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + obug@2.1.1: {} + + on-finished@2.3.0: + dependencies: + ee-first: 1.1.1 + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + on-headers@1.1.0: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@2.0.1: + dependencies: + mimic-fn: 1.2.0 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + open@7.4.2: + dependencies: + is-docker: 2.2.1 + is-wsl: 2.2.0 + + open@8.4.2: + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + ora@3.4.0: + dependencies: + chalk: 2.4.2 + cli-cursor: 2.1.0 + cli-spinners: 2.9.2 + log-symbols: 2.2.0 + strip-ansi: 5.2.0 + wcwidth: 1.0.1 + + ora@5.1.0: + dependencies: + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.9.2 + is-interactive: 1.0.0 + log-symbols: 4.1.0 + mute-stream: 0.0.8 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + + p-finally@1.0.0: {} + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-map@7.0.4: {} + + p-try@2.2.0: {} + + package-json-from-dist@1.0.1: {} + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.3.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + + parse-json@4.0.0: + dependencies: + error-ex: 1.3.4 + json-parse-better-errors: 1.0.2 + + parse-ms@4.0.0: {} + + parse-png@2.1.0: + dependencies: + pngjs: 3.4.0 + + parseurl@1.3.3: {} + + password-prompt@1.1.3: + dependencies: + ansi-escapes: 4.3.2 + cross-spawn: 7.0.6 + + path-browserify@1.0.1: {} + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@2.0.1: {} + + path-key@3.1.1: {} + + path-key@4.0.0: {} + + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.3 + + path-scurry@2.0.2: + dependencies: + lru-cache: 11.2.6 + minipass: 7.1.3 + + path-to-regexp@0.1.12: {} + + path-type@4.0.0: {} + + pathe@1.1.2: {} + + pathe@2.0.3: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.3: {} + + pirates@4.0.7: {} + + pkg-dir@4.2.0: + dependencies: + find-up: 4.1.0 + + pkg-types@2.3.0: + dependencies: + confbox: 0.2.4 + exsolve: 1.0.8 + pathe: 2.0.3 + + plist@3.1.0: + dependencies: + '@xmldom/xmldom': 0.8.11 + base64-js: 1.5.1 + xmlbuilder: 15.1.1 + + pngjs@3.4.0: {} + + pngjs@7.0.0: {} + + possible-typed-array-names@1.1.0: {} + + postcss-less@6.0.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + postcss-scss@4.0.9(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + postcss-selector-parser@6.0.10: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-value-parser@4.2.0: {} + + postcss@8.4.49: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + prettier-plugin-css-order@2.2.0(postcss@8.5.6)(prettier@3.8.1): + dependencies: + css-declaration-sorter: 7.3.1(postcss@8.5.6) + postcss-less: 6.0.0(postcss@8.5.6) + postcss-scss: 4.0.9(postcss@8.5.6) + prettier: 3.8.1 + transitivePeerDependencies: + - postcss + + prettier-plugin-packagejson@2.5.22(prettier@3.8.1): + dependencies: + sort-package-json: 3.6.0 + optionalDependencies: + prettier: 3.8.1 + + prettier-plugin-tailwindcss@0.7.2(@ianvs/prettier-plugin-sort-imports@4.7.1(prettier@3.8.1))(prettier-plugin-css-order@2.2.0(postcss@8.5.6)(prettier@3.8.1))(prettier@3.8.1): + dependencies: + prettier: 3.8.1 + optionalDependencies: + '@ianvs/prettier-plugin-sort-imports': 4.7.1(prettier@3.8.1) + prettier-plugin-css-order: 2.2.0(postcss@8.5.6)(prettier@3.8.1) + + prettier@3.8.1: {} + + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + + pretty-ms@9.3.0: + dependencies: + parse-ms: 4.0.0 + + proc-log@4.2.0: {} + + process@0.11.10: + optional: true + + progress@2.0.3: {} + + promise-limit@2.7.0: {} + + promise-retry@2.0.1: + dependencies: + err-code: 2.0.3 + retry: 0.12.0 + + promise@7.3.1: + dependencies: + asap: 2.0.6 + + promise@8.3.0: + dependencies: + asap: 2.0.6 + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + property-information@7.1.0: {} + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + pump@3.0.3: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + + punycode@2.3.1: {} + + qrcode-terminal@0.12.0: {} + + qs@6.14.2: + dependencies: + side-channel: 1.1.0 + + query-string@7.1.3: + dependencies: + decode-uri-component: 0.2.2 + filter-obj: 1.1.0 + split-on-first: 1.1.0 + strict-uri-encode: 2.0.0 + + queue-microtask@1.2.3: {} + + queue@6.0.2: + dependencies: + inherits: 2.0.4 + + range-parser@1.2.1: {} + + raw-body@2.5.3: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + react-devtools-core@6.1.5: + dependencies: + shell-quote: 1.8.3 + ws: 7.5.10 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + react-dom@19.2.4(react@19.2.4): + dependencies: + react: 19.2.4 + scheduler: 0.27.0 + + react-fast-compare@3.2.2: {} + + react-freeze@1.0.4(react@19.2.4): + dependencies: + react: 19.2.4 + + react-is@16.13.1: {} + + react-is@18.3.1: {} + + react-is@19.2.4: {} + + react-native-css@3.0.4(@expo/metro-config@55.0.9(expo@55.0.3)(typescript@5.9.3))(lightningcss@1.30.1)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4): + dependencies: + '@expo/metro-config': 55.0.9(expo@55.0.3)(typescript@5.9.3) + babel-plugin-react-compiler: 19.1.0-rc.3 + colorjs.io: 0.6.0-alpha.1 + comment-json: 4.5.1 + debug: 4.4.3(supports-color@8.1.1) + lightningcss: 1.30.1 + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + transitivePeerDependencies: + - supports-color + + react-native-gesture-handler@2.30.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4): + dependencies: + '@egjs/hammerjs': 2.0.17 + hoist-non-react-statics: 3.3.2 + invariant: 2.2.4 + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + + react-native-is-edge-to-edge@1.2.1(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4): + dependencies: + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + + react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4): + dependencies: + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + react-native-is-edge-to-edge: 1.2.1(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + react-native-worklets: 0.7.2(@babel/core@7.29.0)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + semver: 7.7.3 + + react-native-safe-area-context@5.6.2(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4): + dependencies: + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + + react-native-screens@4.23.0(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4): + dependencies: + react: 19.2.4 + react-freeze: 1.0.4(react@19.2.4) + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + warn-once: 0.1.1 + + react-native-svg@15.15.3(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4): + dependencies: + css-select: 5.2.2 + css-tree: 1.1.3 + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + warn-once: 0.1.1 + + react-native-web@0.21.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + '@babel/runtime': 7.28.6 + '@react-native/normalize-colors': 0.74.89 + fbjs: 3.0.5 + inline-style-prefixer: 7.0.1 + memoize-one: 6.0.0 + nullthrows: 1.1.1 + postcss-value-parser: 4.2.0 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + styleq: 0.1.3 + transitivePeerDependencies: + - encoding + + react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4): + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-classes': 7.28.4(@babel/core@7.29.0) + '@babel/plugin-transform-nullish-coalescing-operator': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-optional-chaining': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.29.0) + '@babel/preset-typescript': 7.27.1(@babel/core@7.29.0) + convert-source-map: 2.0.0 + react: 19.2.4 + react-native: 0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4) + semver: 7.7.3 + transitivePeerDependencies: + - supports-color + + react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4): + dependencies: + '@jest/create-cache-key-function': 29.7.0 + '@react-native/assets-registry': 0.83.2 + '@react-native/codegen': 0.83.2(@babel/core@7.29.0) + '@react-native/community-cli-plugin': 0.83.2 + '@react-native/gradle-plugin': 0.83.2 + '@react-native/js-polyfills': 0.83.2 + '@react-native/normalize-colors': 0.83.2 + '@react-native/virtualized-lists': 0.83.2(@types/react@19.2.14)(react-native@0.83.2(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4) + abort-controller: 3.0.0 + anser: 1.4.10 + ansi-regex: 5.0.1 + babel-jest: 29.7.0(@babel/core@7.29.0) + babel-plugin-syntax-hermes-parser: 0.32.0 + base64-js: 1.5.1 + commander: 12.1.0 + flow-enums-runtime: 0.0.6 + glob: 7.2.3 + hermes-compiler: 0.14.1 + invariant: 2.2.4 + jest-environment-node: 29.7.0 + memoize-one: 5.2.1 + metro-runtime: 0.83.4 + metro-source-map: 0.83.4 + nullthrows: 1.1.1 + pretty-format: 29.7.0 + promise: 8.3.0 + react: 19.2.4 + react-devtools-core: 6.1.5 + react-refresh: 0.14.2 + regenerator-runtime: 0.13.11 + scheduler: 0.27.0 + semver: 7.7.4 + stacktrace-parser: 0.1.11 + whatwg-fetch: 3.6.20 + ws: 7.5.10 + yargs: 17.7.2 + optionalDependencies: + '@types/react': 19.2.14 + transitivePeerDependencies: + - '@babel/core' + - '@react-native-community/cli' + - '@react-native/metro-config' + - bufferutil + - supports-color + - utf-8-validate + + react-refresh@0.14.2: {} + + react-remove-scroll-bar@2.3.8(@types/react@19.2.14)(react@19.2.4): + dependencies: + react: 19.2.4 + react-style-singleton: 2.2.3(@types/react@19.2.14)(react@19.2.4) + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.14 + + react-remove-scroll@2.7.2(@types/react@19.2.14)(react@19.2.4): + dependencies: + react: 19.2.4 + react-remove-scroll-bar: 2.3.8(@types/react@19.2.14)(react@19.2.4) + react-style-singleton: 2.2.3(@types/react@19.2.14)(react@19.2.4) + tslib: 2.8.1 + use-callback-ref: 1.3.3(@types/react@19.2.14)(react@19.2.4) + use-sidecar: 1.1.3(@types/react@19.2.14)(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + + react-router-hono-server@2.25.0(@hono/node-server@1.19.9(hono@4.12.3))(@react-router/dev@7.13.1(@react-router/serve@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2))(@types/react@19.2.14)(hono@4.12.3)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): + dependencies: + '@drizzle-team/brocli': 0.11.0 + '@hono/node-server': 1.19.9(hono@4.12.3) + '@hono/node-ws': 1.3.0(@hono/node-server@1.19.9(hono@4.12.3))(hono@4.12.3) + '@hono/vite-dev-server': 0.25.0(hono@4.12.3) + '@react-router/dev': 7.13.1(@react-router/serve@7.13.1(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3))(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2) + '@types/react': 19.2.14 + hono: 4.12.3 + react-router: 7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + vite: 7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + react-router@7.13.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + cookie: 1.1.1 + react: 19.2.4 + set-cookie-parser: 2.7.2 + optionalDependencies: + react-dom: 19.2.4(react@19.2.4) + + react-style-singleton@2.2.3(@types/react@19.2.14)(react@19.2.4): + dependencies: + get-nonce: 1.0.1 + react: 19.2.4 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.14 + + react@19.2.4: {} + + readable-stream@4.7.0: + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + optional: true + + readdirp@4.1.2: {} + + rechoir@0.6.2: + dependencies: + resolve: 1.22.11 + + recma-build-jsx@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-build-jsx: 3.0.1 + vfile: 6.0.3 + + recma-jsx@1.0.1(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + estree-util-to-js: 2.0.0 + recma-parse: 1.0.0 + recma-stringify: 1.0.0 + unified: 11.0.5 + + recma-parse@1.0.0: + dependencies: + '@types/estree': 1.0.8 + esast-util-from-js: 2.0.1 + unified: 11.0.5 + vfile: 6.0.3 + + recma-stringify@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-to-js: 2.0.0 + unified: 11.0.5 + vfile: 6.0.3 + + redeyed@2.1.1: + dependencies: + esprima: 4.0.1 + + reflect.getprototypeof@1.0.10: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + + regenerate-unicode-properties@10.2.2: + dependencies: + regenerate: 1.4.2 + + regenerate@1.4.2: {} + + regenerator-runtime@0.13.11: {} + + regexp.prototype.flags@1.5.4: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 + set-function-name: 2.0.2 + + regexpu-core@6.4.0: + 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 + + regjsgen@0.8.0: {} + + regjsparser@0.13.0: + dependencies: + jsesc: 3.1.0 + + rehype-recma@1.0.0: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + hast-util-to-estree: 3.1.3 + transitivePeerDependencies: + - supports-color + + remark-mdx@3.1.1: + dependencies: + mdast-util-mdx: 3.0.0 + micromark-extension-mdxjs: 3.0.0 + transitivePeerDependencies: + - supports-color + + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.3 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-rehype@11.1.2: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + mdast-util-to-hast: 13.2.1 + unified: 11.0.5 + vfile: 6.0.3 + + remove-trailing-slash@0.1.1: {} + + replicate@1.4.0: + optionalDependencies: + readable-stream: 4.7.0 + + require-directory@2.1.1: {} + + require-from-string@2.0.2: {} + + resolve-from@4.0.0: {} + + resolve-from@5.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve-workspace-root@2.0.1: {} + + resolve@1.22.11: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + resolve@2.0.0-next.6: + dependencies: + es-errors: 1.3.0 + is-core-module: 2.16.1 + node-exports-info: 1.6.0 + object-keys: 1.1.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + restore-cursor@2.0.0: + dependencies: + onetime: 2.0.1 + signal-exit: 3.0.7 + + restore-cursor@3.1.0: + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + + retry@0.12.0: {} + + reusify@1.1.0: {} + + rimraf@2.4.5: + dependencies: + glob: 6.0.4 + optional: true + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + rimraf@5.0.10: + dependencies: + glob: 10.5.0 + + rollup-plugin-dts@6.3.0(rollup@4.59.0)(typescript@5.9.3): + dependencies: + magic-string: 0.30.21 + rollup: 4.59.0 + typescript: 5.9.3 + optionalDependencies: + '@babel/code-frame': 7.29.0 + + rollup-plugin-esbuild@6.2.1(esbuild@0.27.3)(rollup@4.59.0): + dependencies: + debug: 4.4.3(supports-color@8.1.1) + es-module-lexer: 1.7.0 + esbuild: 0.27.3 + get-tsconfig: 4.13.6 + rollup: 4.59.0 + unplugin-utils: 0.2.5 + transitivePeerDependencies: + - supports-color + + rollup-plugin-node-externals@8.1.2(rollup@4.59.0): + dependencies: + rollup: 4.59.0 + + rollup-presets@0.0.26(esbuild@0.27.3)(rollup@4.59.0)(typescript@5.9.3): + dependencies: + '@rollup/plugin-commonjs': 29.0.0(rollup@4.59.0) + execa: 9.6.1 + picocolors: 1.1.1 + rollup-plugin-dts: 6.3.0(rollup@4.59.0)(typescript@5.9.3) + rollup-plugin-esbuild: 6.2.1(esbuild@0.27.3)(rollup@4.59.0) + rollup-plugin-node-externals: 8.1.2(rollup@4.59.0) + transitivePeerDependencies: + - esbuild + - rollup + - supports-color + - typescript + + rollup@4.59.0: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.59.0 + '@rollup/rollup-android-arm64': 4.59.0 + '@rollup/rollup-darwin-arm64': 4.59.0 + '@rollup/rollup-darwin-x64': 4.59.0 + '@rollup/rollup-freebsd-arm64': 4.59.0 + '@rollup/rollup-freebsd-x64': 4.59.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.59.0 + '@rollup/rollup-linux-arm-musleabihf': 4.59.0 + '@rollup/rollup-linux-arm64-gnu': 4.59.0 + '@rollup/rollup-linux-arm64-musl': 4.59.0 + '@rollup/rollup-linux-loong64-gnu': 4.59.0 + '@rollup/rollup-linux-loong64-musl': 4.59.0 + '@rollup/rollup-linux-ppc64-gnu': 4.59.0 + '@rollup/rollup-linux-ppc64-musl': 4.59.0 + '@rollup/rollup-linux-riscv64-gnu': 4.59.0 + '@rollup/rollup-linux-riscv64-musl': 4.59.0 + '@rollup/rollup-linux-s390x-gnu': 4.59.0 + '@rollup/rollup-linux-x64-gnu': 4.59.0 + '@rollup/rollup-linux-x64-musl': 4.59.0 + '@rollup/rollup-openbsd-x64': 4.59.0 + '@rollup/rollup-openharmony-arm64': 4.59.0 + '@rollup/rollup-win32-arm64-msvc': 4.59.0 + '@rollup/rollup-win32-ia32-msvc': 4.59.0 + '@rollup/rollup-win32-x64-gnu': 4.59.0 + '@rollup/rollup-win32-x64-msvc': 4.59.0 + fsevents: 2.3.3 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-array-concat@1.1.3: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + isarray: 2.0.5 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safe-json-stringify@1.2.0: + optional: true + + safe-push-apply@1.0.0: + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + safer-buffer@2.1.2: {} + + sax@1.4.4: {} + + scheduler@0.27.0: {} + + semver@5.7.2: {} + + semver@6.3.1: {} + + semver@7.5.2: + dependencies: + lru-cache: 6.0.0 + + semver@7.5.4: + dependencies: + lru-cache: 6.0.0 + + semver@7.6.3: {} + + semver@7.7.3: {} + + semver@7.7.4: {} + + send@0.19.2: + 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 + transitivePeerDependencies: + - supports-color + + serialize-error@2.1.0: {} + + serve-static@1.16.3: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.19.2 + transitivePeerDependencies: + - supports-color + + server-only@0.0.1: {} + + set-cookie-parser@2.7.2: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-interval-async@3.0.3: {} + + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + + setimmediate@1.0.5: {} + + setprototypeof@1.2.0: {} + + sf-symbols-typescript@2.2.0: {} + + shallowequal@1.1.0: {} + + sharp@0.34.5: + dependencies: + '@img/colour': 1.0.0 + detect-libc: 2.1.2 + semver: 7.7.4 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.34.5 + '@img/sharp-darwin-x64': 0.34.5 + '@img/sharp-libvips-darwin-arm64': 1.2.4 + '@img/sharp-libvips-darwin-x64': 1.2.4 + '@img/sharp-libvips-linux-arm': 1.2.4 + '@img/sharp-libvips-linux-arm64': 1.2.4 + '@img/sharp-libvips-linux-ppc64': 1.2.4 + '@img/sharp-libvips-linux-riscv64': 1.2.4 + '@img/sharp-libvips-linux-s390x': 1.2.4 + '@img/sharp-libvips-linux-x64': 1.2.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + '@img/sharp-linux-arm': 0.34.5 + '@img/sharp-linux-arm64': 0.34.5 + '@img/sharp-linux-ppc64': 0.34.5 + '@img/sharp-linux-riscv64': 0.34.5 + '@img/sharp-linux-s390x': 0.34.5 + '@img/sharp-linux-x64': 0.34.5 + '@img/sharp-linuxmusl-arm64': 0.34.5 + '@img/sharp-linuxmusl-x64': 0.34.5 + '@img/sharp-wasm32': 0.34.5 + '@img/sharp-win32-arm64': 0.34.5 + '@img/sharp-win32-ia32': 0.34.5 + '@img/sharp-win32-x64': 0.34.5 + + shebang-command@1.2.0: + dependencies: + shebang-regex: 1.0.0 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@1.0.0: {} + + shebang-regex@3.0.0: {} + + shell-quote@1.8.3: {} + + shelljs@0.9.2: + dependencies: + execa: 1.0.0 + fast-glob: 3.3.3 + interpret: 1.4.0 + rechoir: 0.6.2 + + shx@0.4.0: + dependencies: + minimist: 1.2.8 + shelljs: 0.9.2 + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + siginfo@2.0.0: {} + + signal-exit@3.0.7: {} + + signal-exit@4.1.0: {} + + simple-plist@1.3.1: + dependencies: + bplist-creator: 0.1.0 + bplist-parser: 0.3.1 + plist: 3.1.0 + + simple-swizzle@0.2.4: + dependencies: + is-arrayish: 0.3.4 + + sisteransi@1.0.5: {} + + slash@3.0.0: {} + + slice-ansi@4.0.0: + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + + slugify@1.6.6: {} + + sort-object-keys@2.1.0: {} + + sort-package-json@3.6.0: + dependencies: + detect-indent: 7.0.2 + detect-newline: 4.0.1 + git-hooks-list: 4.2.1 + is-plain-obj: 4.1.0 + semver: 7.7.4 + sort-object-keys: 2.1.0 + tinyglobby: 0.2.15 + + source-map-js@1.2.1: {} + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.5.7: {} + + source-map@0.6.1: {} + + source-map@0.7.6: {} + + space-separated-tokens@2.0.2: {} + + split-on-first@1.1.0: {} + + sprintf-js@1.0.3: {} + + stable-hash@0.0.5: {} + + stack-utils@2.0.6: + dependencies: + escape-string-regexp: 2.0.0 + + stackback@0.0.2: {} + + stackframe@1.3.4: {} + + stacktrace-parser@0.1.11: + dependencies: + type-fest: 0.7.1 + + statuses@1.5.0: {} + + statuses@2.0.2: {} + + std-env@3.10.0: {} + + stop-iteration-iterator@1.1.0: + dependencies: + es-errors: 1.3.0 + internal-slot: 1.1.0 + + stream-buffers@2.2.0: {} + + streamx@2.23.0: + dependencies: + events-universal: 1.0.1 + fast-fifo: 1.3.2 + text-decoder: 1.2.7 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + + strict-uri-encode@2.0.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.2.0 + + string.prototype.matchall@4.0.12: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + regexp.prototype.flags: 1.5.4 + set-function-name: 2.0.2 + side-channel: 1.1.0 + + string.prototype.repeat@1.0.0: + dependencies: + define-properties: 1.2.1 + es-abstract: 1.24.1 + + string.prototype.trim@1.2.10: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-object-atoms: 1.1.1 + has-property-descriptors: 1.0.2 + + string.prototype.trimend@1.0.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + optional: true + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + + strip-ansi@5.2.0: + dependencies: + ansi-regex: 4.1.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.2.2 + + strip-bom@3.0.0: {} + + strip-eof@1.0.0: {} + + strip-final-newline@4.0.0: {} + + strip-json-comments@3.1.1: {} + + structured-headers@0.4.1: {} + + style-to-js@1.1.21: + dependencies: + style-to-object: 1.0.14 + + style-to-object@1.0.14: + dependencies: + inline-style-parser: 0.2.7 + + styleq@0.1.3: {} + + sucrase@3.35.0: + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + commander: 4.1.1 + glob: 10.5.0 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.7 + ts-interface-checker: 0.1.13 + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + supports-hyperlinks@2.3.0: + dependencies: + has-flag: 4.0.0 + supports-color: 7.2.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + tailwind-merge@3.5.0: {} + + tailwindcss-safe-area@1.3.0(tailwindcss@4.2.1): + dependencies: + tailwindcss: 4.2.1 + + tailwindcss@4.2.1: {} + + tapable@2.3.0: {} + + tar-stream@3.1.7: + dependencies: + b4a: 1.8.0 + fast-fifo: 1.3.2 + streamx: 2.23.0 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + + tar@7.5.7: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.3 + minizlib: 3.1.0 + yallist: 5.0.0 + + temp-dir@2.0.0: {} + + terminal-link@2.1.1: + dependencies: + ansi-escapes: 4.3.2 + supports-hyperlinks: 2.3.0 + + terser@5.46.0: + dependencies: + '@jridgewell/source-map': 0.3.11 + acorn: 8.16.0 + commander: 2.20.3 + source-map-support: 0.5.21 + + test-exclude@6.0.0: + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.5 + + text-decoder@1.2.7: + dependencies: + b4a: 1.8.0 + transitivePeerDependencies: + - react-native-b4a + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + throat@5.0.0: {} + + tinybench@2.9.0: {} + + tinyexec@1.0.2: {} + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + tinyrainbow@3.0.3: {} + + tmpl@1.0.5: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toidentifier@1.0.1: {} + + toqr@0.1.1: {} + + tr46@0.0.3: {} + + trim-lines@3.0.1: {} + + trough@2.2.0: {} + + ts-api-utils@2.4.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + + ts-deepmerge@6.2.0: {} + + ts-interface-checker@0.1.13: {} + + ts-morph@12.0.0: + dependencies: + '@ts-morph/common': 0.11.1 + code-block-writer: 10.1.1 + + ts-node@10.9.2(@types/node@25.3.2)(typescript@5.9.3): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.12 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 25.3.2 + acorn: 8.16.0 + acorn-walk: 8.3.5 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.4 + make-error: 1.3.6 + typescript: 5.9.3 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + + ts-toolbelt@6.15.5: {} + + tsconfck@3.1.6(typescript@5.9.3): + optionalDependencies: + typescript: 5.9.3 + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@2.4.1: {} + + tslib@2.6.2: {} + + tslib@2.8.1: {} + + tsx@4.21.0: + dependencies: + esbuild: 0.27.3 + get-tsconfig: 4.13.6 + optionalDependencies: + fsevents: 2.3.3 + + tunnel-agent@0.6.0: + dependencies: + safe-buffer: 5.2.1 + + tuple-result@0.0.11: {} + + turbo-darwin-64@2.8.11: + optional: true + + turbo-darwin-arm64@2.8.11: + optional: true + + turbo-linux-64@2.8.11: + optional: true + + turbo-linux-arm64@2.8.11: + optional: true + + turbo-windows-64@2.8.11: + optional: true + + turbo-windows-arm64@2.8.11: + optional: true + + turbo@2.8.11: + optionalDependencies: + turbo-darwin-64: 2.8.11 + turbo-darwin-arm64: 2.8.11 + turbo-linux-64: 2.8.11 + turbo-linux-arm64: 2.8.11 + turbo-windows-64: 2.8.11 + turbo-windows-arm64: 2.8.11 + + turndown@7.1.2: + dependencies: + domino: 2.1.6 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-detect@4.0.8: {} + + type-fest@0.21.3: {} + + type-fest@0.7.1: {} + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typed-array-byte-length@1.0.3: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + + typed-array-byte-offset@1.0.4: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + + typed-array-length@1.0.7: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 + + typescript-eslint@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.56.1(@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.3(jiti@2.6.1) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + typescript@5.9.3: {} + + ua-parser-js@0.7.41: {} + + ua-parser-js@1.0.41: {} + + unbox-primitive@1.1.0: + dependencies: + call-bound: 1.0.4 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 + + undici-types@7.18.2: {} + + unicode-canonical-property-names-ecmascript@2.0.1: {} + + unicode-match-property-ecmascript@2.0.0: + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.1 + unicode-property-aliases-ecmascript: 2.2.0 + + unicode-match-property-value-ecmascript@2.2.1: {} + + unicode-property-aliases-ecmascript@2.2.0: {} + + unicorn-magic@0.3.0: {} + + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unique-string@2.0.0: + dependencies: + crypto-random-string: 2.0.0 + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position-from-estree@2.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.1.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + universalify@1.0.0: {} + + universalify@2.0.1: {} + + unpipe@1.0.0: {} + + unplugin-utils@0.2.5: + dependencies: + pathe: 2.0.3 + picomatch: 4.0.3 + + unrs-resolver@1.11.1: + dependencies: + napi-postinstall: 0.3.4 + optionalDependencies: + '@unrs/resolver-binding-android-arm-eabi': 1.11.1 + '@unrs/resolver-binding-android-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-x64': 1.11.1 + '@unrs/resolver-binding-freebsd-x64': 1.11.1 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-arm64-musl': 1.11.1 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-musl': 1.11.1 + '@unrs/resolver-binding-linux-s390x-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-musl': 1.11.1 + '@unrs/resolver-binding-wasm32-wasi': 1.11.1 + '@unrs/resolver-binding-win32-arm64-msvc': 1.11.1 + '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 + '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 + + untildify@4.0.0: {} + + update-browserslist-db@1.2.3(browserslist@4.28.1): + dependencies: + browserslist: 4.28.1 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + use-callback-ref@1.3.3(@types/react@19.2.14)(react@19.2.4): + dependencies: + react: 19.2.4 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.14 + + use-latest-callback@0.2.6(react@19.2.4): + dependencies: + react: 19.2.4 + + use-sidecar@1.1.3(@types/react@19.2.14)(react@19.2.4): + dependencies: + detect-node-es: 1.1.0 + react: 19.2.4 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.14 + + use-sync-external-store@1.6.0(react@19.2.4): + dependencies: + react: 19.2.4 + + util-deprecate@1.0.2: {} + + utils-merge@1.0.1: {} + + uuid@7.0.3: {} + + uuid@8.3.2: {} + + uuid@9.0.1: {} + + v8-compile-cache-lib@3.0.1: {} + + valibot@1.2.0(typescript@5.9.3): + optionalDependencies: + typescript: 5.9.3 + + validate-npm-package-name@5.0.1: {} + + vary@1.1.2: {} + + vaul@1.1.2(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + + vite-node@3.2.4(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + dependencies: + cac: 6.7.14 + debug: 4.4.3(supports-color@8.1.1) + es-module-lexer: 1.7.0 + pathe: 2.0.3 + vite: 7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + vite-tsconfig-paths@6.1.1(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): + dependencies: + debug: 4.4.3(supports-color@8.1.1) + globrex: 0.1.2 + tsconfck: 3.1.6(typescript@5.9.3) + vite: 7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - supports-color + - typescript + + vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + dependencies: + esbuild: 0.27.3 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.59.0 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 25.3.2 + fsevents: 2.3.3 + jiti: 2.6.1 + lightningcss: 1.30.1 + terser: 5.46.0 + tsx: 4.21.0 + yaml: 2.8.2 + + vitest@4.0.18(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + dependencies: + '@vitest/expect': 4.0.18 + '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/pretty-format': 4.0.18 + '@vitest/runner': 4.0.18 + '@vitest/snapshot': 4.0.18 + '@vitest/spy': 4.0.18 + '@vitest/utils': 4.0.18 + es-module-lexer: 1.7.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.1 + pathe: 2.0.3 + picomatch: 4.0.3 + std-env: 3.10.0 + tinybench: 2.9.0 + tinyexec: 1.0.2 + tinyglobby: 0.2.15 + tinyrainbow: 3.0.3 + vite: 7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 25.3.2 + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - terser + - tsx + - yaml + + vlq@1.0.1: {} + + walker@1.0.8: + dependencies: + makeerror: 1.0.12 + + warn-once@0.1.1: {} + + wcwidth@1.0.1: + dependencies: + defaults: 1.0.4 + + webidl-conversions@3.0.1: {} + + whatwg-fetch@3.6.20: {} + + whatwg-url-minimum@0.1.1: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which-boxed-primitive@1.1.1: + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + + which-builtin-type@1.2.1: + dependencies: + call-bound: 1.0.4 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.2 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.20 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + + which-typed-array@1.1.20: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@1.3.1: + dependencies: + isexe: 2.0.0 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + widest-line@3.1.0: + dependencies: + string-width: 4.2.3 + + wonka@6.3.5: {} + + word-wrap@1.2.5: {} + + wordwrap@1.0.0: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.2.0 + + wrappy@1.0.2: {} + + write-file-atomic@2.4.3: + dependencies: + graceful-fs: 4.2.11 + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + + write-file-atomic@4.0.2: + dependencies: + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + + ws@7.5.10: {} + + ws@8.19.0: {} + + xcode@3.0.1: + dependencies: + simple-plist: 1.3.1 + uuid: 7.0.3 + + xml2js@0.6.0: + dependencies: + sax: 1.4.4 + xmlbuilder: 11.0.1 + + xmlbuilder@11.0.1: {} + + xmlbuilder@14.0.0: {} + + xmlbuilder@15.1.1: {} + + y18n@5.0.8: {} + + yallist@3.1.1: {} + + yallist@4.0.0: {} + + yallist@5.0.0: {} + + yaml@2.6.0: {} + + yaml@2.8.2: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yn@3.1.1: {} + + yocto-queue@0.1.0: {} + + yoctocolors@2.1.2: {} + + zod-validation-error@4.0.2(zod@4.3.6): + dependencies: + zod: 4.3.6 + + zod@3.25.76: {} + + zod@4.3.6: {} + + zwitch@2.0.4: {}