diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 21f282c..f2e30a4 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -20,10 +20,22 @@ updates: update-types: ["version-update:semver-major"] - dependency-name: "@types/node" update-types: ["version-update:semver-major"] - # react-native is pinned by the Expo SDK — upgrade it via an Expo - # SDK bump, not on its own. Community react-native-* libraries are - # intentionally NOT ignored here; they can be bumped independently. + # These packages are version-pinned by the Expo SDK (see + # expo/bundledNativeModules.json) — upgrade them via an Expo SDK + # bump / `npx expo install --fix`, never on their own. Dependabot + # bumping them past the SDK's expected version broke the native + # build (expo-modules-core macro mismatch, June 2026) because CI + # never compiles native code. `react` stays unignored: the web + # apps own its version via the workspace catalog, and apps/mobile + # excludes it from expo version checks. - dependency-name: "react-native" + - dependency-name: "react-native-gesture-handler" + - dependency-name: "react-native-reanimated" + - dependency-name: "react-native-safe-area-context" + - dependency-name: "react-native-screens" + - dependency-name: "react-native-worklets" + - dependency-name: "@sentry/react-native" + - dependency-name: "jest-expo" - package-ecosystem: "github-actions" directory: "/" diff --git a/apps/journal/app/lib/activities.server.ts b/apps/journal/app/lib/activities.server.ts index 6e99d15..cfc77b0 100644 --- a/apps/journal/app/lib/activities.server.ts +++ b/apps/journal/app/lib/activities.server.ts @@ -4,8 +4,8 @@ import { unionAll } from "drizzle-orm/pg-core"; import { getDb } from "./db.ts"; import { activities, routes, syncImports, users, follows, remoteActors } from "@trails-cool/db/schema/journal"; import type { Visibility } from "@trails-cool/db/schema/journal"; -import { validateGpx, writeGeom } from "./gpx-save.server.ts"; -import type { GpxData } from "./gpx-save.server.ts"; +import { processGpx, writeGeom } from "./gpx-save.server.ts"; +import type { ProcessedGpx } from "./gpx-save.server.ts"; import { enqueueOptional } from "./boss.server.ts"; import type { OwnedRef } from "./ownership.server.ts"; import { @@ -70,7 +70,7 @@ export async function createActivity(ownerId: string, input: ActivityInput) { const db = getDb(); const id = randomUUID(); - let parsed: GpxData | null = null; + let processed: ProcessedGpx | null = null; let distance: number | null = input.distance ?? null; let elevationGain: number | null = null; let elevationLoss: number | null = null; @@ -78,13 +78,12 @@ export async function createActivity(ownerId: string, input: ActivityInput) { const duration: number | null = input.duration ?? null; if (input.gpx) { - parsed = await validateGpx(input.gpx); - distance = parsed.distance || distance; - elevationGain = parsed.elevation.gain; - elevationLoss = parsed.elevation.loss; - if (!startedAt && parsed.tracks[0]?.[0]?.time) { - startedAt = new Date(parsed.tracks[0][0].time); - } + processed = await processGpx(input.gpx); + // GPX-derived distance wins unless it is zero; caller input is the fallback + distance = processed.stats.distance || distance; + elevationGain = processed.stats.elevationGain; + elevationLoss = processed.stats.elevationLoss; + startedAt = startedAt ?? processed.stats.startTime; } await db.transaction(async (tx) => { @@ -104,9 +103,8 @@ export async function createActivity(ownerId: string, input: ActivityInput) { ...(input.synthetic ? { synthetic: true } : {}), }); - if (input.gpx && parsed) { - const coords = parsed.tracks.flat().map((p) => [p.lon, p.lat] as [number, number]); - await writeGeom(tx, id, "activities", coords); + if (input.gpx && processed) { + await writeGeom(tx, id, "activities", processed.coords); } }); @@ -332,8 +330,7 @@ export async function createRouteFromActivity(ownedActivity: OwnedRef): Promise< .where(and(eq(activities.id, activityId), eq(activities.ownerId, ownerId))); if (!activity?.gpx) return null; - const parsed = await validateGpx(activity.gpx); - const coords = parsed.tracks.flat().map((p) => [p.lon, p.lat] as [number, number]); + const { coords } = await processGpx(activity.gpx); const routeId = randomUUID(); await db.transaction(async (tx) => { diff --git a/apps/journal/app/lib/api-guard.server.ts b/apps/journal/app/lib/api-guard.server.ts index 18c6be9..7ac8466 100644 --- a/apps/journal/app/lib/api-guard.server.ts +++ b/apps/journal/app/lib/api-guard.server.ts @@ -1,3 +1,4 @@ +import type { z } from "zod"; import { getAuthenticatedUser } from "./oauth.server.ts"; import { TERMS_VERSION } from "./legal.ts"; import { ERROR_CODES } from "@trails-cool/api"; @@ -36,3 +37,19 @@ export async function requireApiUser(request: Request) { export function apiError(status: number, code: string, message: string, fields?: Array<{ field: string; message: string }>) { return Response.json({ error: message, code, fields }, { status }); } + +/** + * Respond with a payload validated against its @trails-cool/api + * contract. The schema is enforced, not advisory: a handler whose + * payload drifts from the contract fails its unit tests / e2e run with + * a ZodError instead of silently shipping a different wire shape. + * Parsing also strips unknown keys, so the response is exactly the + * contract — nothing extra leaks. + */ +export function apiJson( + schema: S, + payload: z.input, + init?: ResponseInit, +): Response { + return Response.json(schema.parse(payload), init); +} diff --git a/apps/journal/app/lib/connected-services/oauth-flow.server.test.ts b/apps/journal/app/lib/connected-services/oauth-flow.server.test.ts new file mode 100644 index 0000000..f627ebb --- /dev/null +++ b/apps/journal/app/lib/connected-services/oauth-flow.server.test.ts @@ -0,0 +1,162 @@ +import { describe, it, expect, vi, beforeEach } from "vitest"; +import { createHash } from "node:crypto"; + +const link = vi.fn(); +vi.mock("./manager.ts", () => ({ + link: (...args: unknown[]) => link(...args), +})); +vi.mock("../config.server.ts", () => ({ + getOrigin: () => "https://journal.test", +})); + +import { initiateOAuthFlow, completeOAuthFlow } from "./oauth-flow.server.ts"; +import { decodeOAuthState } from "./oauth-state.server.ts"; +import type { ProviderManifest } from "./registry.ts"; + +function fakeManifest(overrides: Partial = {}): ProviderManifest { + return { + id: "fakeprov", + displayName: "Fake Provider", + credentialKind: "oauth", + credentialAdapter: { isExpired: () => false, refresh: vi.fn() }, + buildAuthUrl: vi.fn( + (redirectUri: string, state: string, extras?: { codeChallenge?: string }) => + `https://provider.test/authorize?redirect_uri=${encodeURIComponent(redirectUri)}&state=${state}` + + (extras?.codeChallenge ? `&code_challenge=${extras.codeChallenge}` : ""), + ), + exchangeCode: vi.fn(), + ...overrides, + } as unknown as ProviderManifest; +} + +function callbackRequest(params: Record, cookie?: string): Request { + const url = new URL("https://journal.test/api/sync/callback/fakeprov"); + for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v); + return new Request(url, { headers: cookie ? { Cookie: cookie } : {} }); +} + +beforeEach(() => vi.clearAllMocks()); + +describe("initiateOAuthFlow", () => { + it("redirects to the provider with the intent in the state, no cookie for non-PKCE", () => { + const manifest = fakeManifest(); + const resp = initiateOAuthFlow(manifest, { returnTo: "/settings/connections" }); + + expect(resp.status).toBe(302); + const location = new URL(resp.headers.get("Location")!); + expect(location.origin).toBe("https://provider.test"); + expect(location.searchParams.get("redirect_uri")).toBe( + "https://journal.test/api/sync/callback/fakeprov", + ); + expect(decodeOAuthState(location.searchParams.get("state"))).toEqual({ + returnTo: "/settings/connections", + }); + expect(resp.headers.get("Set-Cookie")).toBeNull(); + }); + + it("PKCE: sets the verifier cookie and sends its S256 challenge", () => { + const manifest = fakeManifest({ pkce: true }); + const resp = initiateOAuthFlow(manifest, { pushAfter: { routeId: "r-1" }, returnTo: "/r" }); + + const cookie = resp.headers.get("Set-Cookie")!; + expect(cookie).toContain("__oauth_pkce="); + expect(cookie).toContain("HttpOnly"); + const verifier = cookie.match(/__oauth_pkce=([^;]+)/)![1]!; + + const location = new URL(resp.headers.get("Location")!); + const expectedChallenge = createHash("sha256").update(verifier).digest("base64url"); + expect(location.searchParams.get("code_challenge")).toBe(expectedChallenge); + // push intent rides the state even on the PKCE path + expect(decodeOAuthState(location.searchParams.get("state"))).toEqual({ + pushAfter: { routeId: "r-1" }, + returnTo: "/r", + }); + }); +}); + +describe("completeOAuthFlow", () => { + it("maps access_denied to denied with decoded state", async () => { + const manifest = fakeManifest(); + const state = new URL( + initiateOAuthFlow(manifest, { returnTo: "/x" }).headers.get("Location")!, + ).searchParams.get("state")!; + + const result = await completeOAuthFlow( + manifest, + callbackRequest({ error: "access_denied", state }), + "user-1", + ); + expect(result).toEqual({ status: "denied", state: { returnTo: "/x" } }); + expect(link).not.toHaveBeenCalled(); + }); + + it("returns missing_code when no code param", async () => { + const result = await completeOAuthFlow(fakeManifest(), callbackRequest({}), "user-1"); + expect(result.status).toBe("missing_code"); + }); + + it("PKCE: returns missing_verifier when the cookie is gone", async () => { + const result = await completeOAuthFlow( + fakeManifest({ pkce: true }), + callbackRequest({ code: "abc" }), + "user-1", + ); + expect(result.status).toBe("missing_verifier"); + }); + + it("exchanges the code and links the connection", async () => { + const manifest = fakeManifest(); + (manifest.exchangeCode as ReturnType).mockResolvedValue({ + credentials: { accessToken: "t" }, + providerUserId: "prov-9", + grantedScopes: ["routes_write"], + }); + + const result = await completeOAuthFlow(manifest, callbackRequest({ code: "abc" }), "user-1"); + + expect(result.status).toBe("linked"); + expect(manifest.exchangeCode).toHaveBeenCalledWith( + "abc", + "https://journal.test/api/sync/callback/fakeprov", + undefined, + ); + expect(link).toHaveBeenCalledWith({ + userId: "user-1", + provider: "fakeprov", + credentialKind: "oauth", + credentials: { accessToken: "t" }, + providerUserId: "prov-9", + grantedScopes: ["routes_write"], + }); + }); + + it("PKCE: passes the cookie verifier to exchangeCode", async () => { + const manifest = fakeManifest({ pkce: true }); + (manifest.exchangeCode as ReturnType).mockResolvedValue({ + credentials: {}, + providerUserId: "p", + grantedScopes: [], + }); + + await completeOAuthFlow( + manifest, + callbackRequest({ code: "abc" }, "__oauth_pkce=my-verifier"), + "user-1", + ); + expect(manifest.exchangeCode).toHaveBeenCalledWith( + "abc", + expect.any(String), + { codeVerifier: "my-verifier" }, + ); + }); + + it("maps exchange failures to error with the provider code", async () => { + const manifest = fakeManifest(); + (manifest.exchangeCode as ReturnType).mockRejectedValue( + Object.assign(new Error("nope"), { code: "rate_limited" }), + ); + + const result = await completeOAuthFlow(manifest, callbackRequest({ code: "x" }), "user-1"); + expect(result).toMatchObject({ status: "error", code: "rate_limited" }); + }); +}); diff --git a/apps/journal/app/lib/connected-services/oauth-flow.server.ts b/apps/journal/app/lib/connected-services/oauth-flow.server.ts new file mode 100644 index 0000000..b530b12 --- /dev/null +++ b/apps/journal/app/lib/connected-services/oauth-flow.server.ts @@ -0,0 +1,122 @@ +// The OAuth connect → callback lifecycle as one module. Routes stay +// thin adapters: they look up the manifest, call initiate/complete, +// and map the result to redirects. Everything protocol-shaped — +// state encoding, PKCE pair generation, the verifier cookie's +// lifecycle, redirect-URI construction, code exchange, linking the +// connection — lives here, so the next OAuth provider (Coros, Strava) +// reuses the flow instead of the pattern. + +import { redirect } from "react-router"; +import { getOrigin } from "../config.server.ts"; +import { link } from "./manager.ts"; +import type { ProviderManifest } from "./registry.ts"; +import { + clearPkceCookieHeader, + decodeOAuthState, + encodeOAuthState, + generatePkcePair, + pkceCookieHeader, + readPkceVerifier, + type PushOAuthState, +} from "./oauth-state.server.ts"; + +function callbackUri(manifest: ProviderManifest): string { + return `${getOrigin()}/api/sync/callback/${manifest.id}`; +} + +/** + * Build the provider authorization redirect. Encodes post-callback + * intent into the state param and, for PKCE providers, sets the + * httpOnly verifier cookie — including when the flow is initiated + * from a push-resume (the old inline code only handled PKCE on the + * plain connect path). + * + * Caller must have verified `manifest.buildAuthUrl` exists. + */ +export function initiateOAuthFlow( + manifest: ProviderManifest, + intent: PushOAuthState, +): Response { + if (!manifest.buildAuthUrl) { + throw new Error(`Provider ${manifest.id} has no buildAuthUrl`); + } + const state = encodeOAuthState(intent); + const redirectUri = callbackUri(manifest); + + if (manifest.pkce) { + const { verifier, challenge } = generatePkcePair(); + return redirect(manifest.buildAuthUrl(redirectUri, state, { codeChallenge: challenge }), { + headers: { "Set-Cookie": pkceCookieHeader(verifier) }, + }); + } + return redirect(manifest.buildAuthUrl(redirectUri, state)); +} + +export type OAuthCompletion = + /** Provider sent the user back with access_denied. */ + | { status: "denied"; state: PushOAuthState } + /** No authorization code in the callback URL. */ + | { status: "missing_code"; state: PushOAuthState } + /** PKCE provider but the verifier cookie is gone (expired / cleared). */ + | { status: "missing_verifier"; state: PushOAuthState } + /** Code exchange or linking failed; `code` is provider-specific or "sync_failed". */ + | { status: "error"; code: string; state: PushOAuthState } + /** Connection linked. */ + | { status: "linked"; state: PushOAuthState }; + +/** + * Consume the provider callback: decode state, recover the PKCE + * verifier, exchange the code, and link the connection. Never throws — + * every outcome is a variant the route maps to a redirect. The spent + * verifier cookie should be cleared on whatever response the route + * returns (`clearPkceCookieHeader`). + */ +export async function completeOAuthFlow( + manifest: ProviderManifest, + request: Request, + userId: string, +): Promise { + if (!manifest.exchangeCode) { + throw new Error(`Provider ${manifest.id} has no exchangeCode`); + } + const url = new URL(request.url); + const state = decodeOAuthState(url.searchParams.get("state")); + + if (url.searchParams.get("error") === "access_denied") { + return { status: "denied", state }; + } + + const code = url.searchParams.get("code"); + if (!code) return { status: "missing_code", state }; + + const codeVerifier = manifest.pkce ? readPkceVerifier(request) : null; + if (manifest.pkce && !codeVerifier) { + return { status: "missing_verifier", state }; + } + + try { + const exchange = await manifest.exchangeCode( + code, + callbackUri(manifest), + codeVerifier ? { codeVerifier } : undefined, + ); + await link({ + userId, + provider: manifest.id, + credentialKind: manifest.credentialKind, + credentials: exchange.credentials as Record, + providerUserId: exchange.providerUserId, + grantedScopes: exchange.grantedScopes, + }); + return { status: "linked", state }; + } catch (e) { + console.error(`OAuth callback failed for ${manifest.id}:`, e); + const code = + typeof (e as { code?: string }).code === "string" + ? (e as { code: string }).code + : "sync_failed"; + return { status: "error", code, state }; + } +} + +export { clearPkceCookieHeader }; diff --git a/apps/journal/app/lib/demo-bot.server.ts b/apps/journal/app/lib/demo-bot.server.ts index 8ee5fd5..7917524 100644 --- a/apps/journal/app/lib/demo-bot.server.ts +++ b/apps/journal/app/lib/demo-bot.server.ts @@ -6,7 +6,7 @@ import { getDb } from "./db.ts"; import { activities, routes, users } from "@trails-cool/db/schema/journal"; import { createRoute } from "./routes.server.ts"; import { createActivity } from "./activities.server.ts"; -import { validateGpx } from "./gpx-save.server.ts"; +import { processGpx } from "./gpx-save.server.ts"; import { TERMS_VERSION } from "./legal.ts"; import { logger } from "./logger.server.ts"; import { @@ -649,10 +649,8 @@ export async function generateOneWalk( const name = templateName(now, locale, persona); const description = templateDescription(now, locale, persona); - const parsed = await validateGpx(result.gpx); - const distance = parsed.distance; - const elevationGain = parsed.elevation.gain; - const elevationLoss = parsed.elevation.loss; + const { stats } = await processGpx(result.gpx); + const { distance, elevationGain, elevationLoss } = stats; if (!distance || distance < 500) return null; diff --git a/apps/journal/app/lib/gpx-save.server.test.ts b/apps/journal/app/lib/gpx-save.server.test.ts index b1455c2..3113406 100644 --- a/apps/journal/app/lib/gpx-save.server.test.ts +++ b/apps/journal/app/lib/gpx-save.server.test.ts @@ -1,5 +1,6 @@ import { describe, it, expect } from "vitest"; -import { validateGpx, GpxValidationError } from "./gpx-save.server.ts"; +import { generateGpx } from "@trails-cool/gpx"; +import { processGpx, validateGpx, GpxValidationError } from "./gpx-save.server.ts"; const VALID_GPX = ` @@ -84,3 +85,68 @@ describe("validateGpx", () => { expect(err.name).toBe("GpxValidationError"); }); }); + +const TIMED_GPX = ` + + An alpine loop + + + 500 + 520 + + +`; + +describe("processGpx", () => { + it("extracts coords in [lon, lat] PostGIS axis order", async () => { + const { coords } = await processGpx(VALID_GPX); + expect(coords).toEqual([ + [8.0, 47.0], + [8.1, 47.1], + [8.2, 47.2], + ]); + }); + + it("derives distance, elevation, description, and start time", async () => { + const { stats } = await processGpx(TIMED_GPX); + expect(stats.distance).toBeGreaterThan(0); + expect(stats.elevationGain).not.toBeNull(); + expect(stats.elevationLoss).not.toBeNull(); + expect(stats.description).toBe("An alpine loop"); + expect(stats.startTime).toEqual(new Date("2026-06-01T08:00:00Z")); + }); + + it("returns null startTime and empty dayBreaks when absent", async () => { + const { stats } = await processGpx(VALID_GPX); + expect(stats.startTime).toBeNull(); + expect(stats.dayBreaks).toEqual([]); + }); + + it("derives dayBreaks from day-break waypoints (round-trip via generateGpx)", async () => { + const gpx = generateGpx({ + name: "Multi-day", + waypoints: [ + { lat: 47.0, lon: 8.0, name: "Start" }, + { lat: 47.1, lon: 8.1, name: "Hut", isDayBreak: true }, + { lat: 47.2, lon: 8.2, name: "End" }, + ], + tracks: [[ + { lat: 47.0, lon: 8.0 }, + { lat: 47.1, lon: 8.1 }, + { lat: 47.2, lon: 8.2 }, + ]], + }); + + const { stats } = await processGpx(gpx); + expect(stats.dayBreaks).toEqual([1]); + }); + + it("propagates GpxValidationError from validation", async () => { + await expect(processGpx(ONE_POINT_GPX)).rejects.toThrow(GpxValidationError); + }); + + it("returns the parsed GpxData so callers never re-parse", async () => { + const { parsed } = await processGpx(VALID_GPX); + expect(parsed.tracks.flat()).toHaveLength(3); + }); +}); diff --git a/apps/journal/app/lib/gpx-save.server.ts b/apps/journal/app/lib/gpx-save.server.ts index b1411e9..7431a39 100644 --- a/apps/journal/app/lib/gpx-save.server.ts +++ b/apps/journal/app/lib/gpx-save.server.ts @@ -45,6 +45,51 @@ export async function validateGpx(gpx: string): Promise { return parsed; } +export interface GpxStats { + distance: number | null; + elevationGain: number | null; + elevationLoss: number | null; + /** Indices of waypoints flagged as day breaks. */ + dayBreaks: number[]; + /** GPX-level description, when present. */ + description?: string; + /** Timestamp of the first track point, when present. */ + startTime: Date | null; +} + +export interface ProcessedGpx { + parsed: GpxData; + /** [lon, lat] pairs in PostGIS axis order, ready for writeGeom. */ + coords: Array<[number, number]>; + stats: GpxStats; +} + +/** + * The validate-and-derive step every GPX save starts with: parse + + * validate (throws GpxValidationError), extract the geometry + * coordinates, and derive the stats rows store. Callers own the + * precedence between these derived stats and caller-supplied ones — + * routes let explicit input win wholesale, activities prefer the GPX + * distance unless it is zero. + */ +export async function processGpx(gpx: string): Promise { + const parsed = await validateGpx(gpx); + return { + parsed, + coords: parsed.tracks.flat().map((p) => [p.lon, p.lat] as [number, number]), + stats: { + distance: parsed.distance ?? null, + elevationGain: parsed.elevation.gain ?? null, + elevationLoss: parsed.elevation.loss ?? null, + dayBreaks: parsed.waypoints + .map((w, i) => (w.isDayBreak ? i : -1)) + .filter((i) => i >= 0), + description: parsed.description, + startTime: parsed.tracks[0]?.[0]?.time ? new Date(parsed.tracks[0][0].time) : null, + }, + }; +} + type Tx = Parameters[0]>[0]; /** diff --git a/apps/journal/app/lib/routes.server.ts b/apps/journal/app/lib/routes.server.ts index 664fe9a..91ed3f3 100644 --- a/apps/journal/app/lib/routes.server.ts +++ b/apps/journal/app/lib/routes.server.ts @@ -4,8 +4,8 @@ import { getDb } from "./db.ts"; import { routes, routeVersions } from "@trails-cool/db/schema/journal"; import type { Visibility } from "@trails-cool/db/schema/journal"; import { sql } from "drizzle-orm"; -import { validateGpx, writeGeom } from "./gpx-save.server.ts"; -import type { GpxData } from "./gpx-save.server.ts"; +import { processGpx, writeGeom } from "./gpx-save.server.ts"; +import type { ProcessedGpx } from "./gpx-save.server.ts"; import type { OwnedRef } from "./ownership.server.ts"; export interface RouteInput { @@ -26,21 +26,17 @@ export async function createRoute(ownerId: string, input: RouteInput) { const db = getDb(); const id = randomUUID(); - let parsed: GpxData | null = null; + let processed: ProcessedGpx | null = null; let distance: number | null = input.distance ?? null; let elevationGain: number | null = input.elevationGain ?? null; let elevationLoss: number | null = input.elevationLoss ?? null; let dayBreaks: number[] = input.dayBreaks ?? []; if (input.gpx) { - parsed = await validateGpx(input.gpx); - // Only compute stats from GPX if not pre-supplied by caller + processed = await processGpx(input.gpx); + // Only use GPX-derived stats if not pre-supplied by caller if (input.distance === undefined) { - const stats = computeRouteStats(parsed); - distance = stats.distance; - elevationGain = stats.elevationGain; - elevationLoss = stats.elevationLoss; - dayBreaks = stats.dayBreaks; + ({ distance, elevationGain, elevationLoss, dayBreaks } = processed.stats); } } @@ -60,9 +56,8 @@ export async function createRoute(ownerId: string, input: RouteInput) { ...(input.synthetic ? { synthetic: true } : {}), }); - if (input.gpx && parsed) { - const coords = parsed.tracks.flat().map((p) => [p.lon, p.lat] as [number, number]); - await writeGeom(tx, id, "routes", coords); + if (input.gpx && processed) { + await writeGeom(tx, id, "routes", processed.coords); await tx.insert(routeVersions).values({ id: randomUUID(), @@ -135,9 +130,9 @@ export async function updateRoute(route: OwnedRef, input: Partial) { const { id, ownerId } = route; const db = getDb(); - let parsed: GpxData | null = null; + let processed: ProcessedGpx | null = null; if (input.gpx) { - parsed = await validateGpx(input.gpx); + processed = await processGpx(input.gpx); } const updateData: Record = { updatedAt: new Date() }; @@ -145,8 +140,8 @@ export async function updateRoute(route: OwnedRef, input: Partial) { if (input.description !== undefined) updateData.description = input.description; if (input.visibility !== undefined) updateData.visibility = input.visibility; - if (input.gpx && parsed) { - const stats = computeRouteStats(parsed); + if (input.gpx && processed) { + const { stats } = processed; updateData.gpx = input.gpx; updateData.distance = stats.distance; updateData.elevationGain = stats.elevationGain; @@ -163,9 +158,8 @@ export async function updateRoute(route: OwnedRef, input: Partial) { .set(updateData) .where(and(eq(routes.id, id), eq(routes.ownerId, ownerId))); - if (input.gpx && parsed) { - const coords = parsed.tracks.flat().map((p) => [p.lon, p.lat] as [number, number]); - await writeGeom(tx, id, "routes", coords); + if (input.gpx && processed) { + await writeGeom(tx, id, "routes", processed.coords); const existingVersions = await tx .select() @@ -197,19 +191,6 @@ export async function deleteRoute(route: OwnedRef) { return result.length > 0; } -function computeRouteStats(gpxData: GpxData) { - const dayBreaks = gpxData.waypoints - .map((w, i) => (w.isDayBreak ? i : -1)) - .filter((i) => i >= 0); - return { - distance: gpxData.distance, - elevationGain: gpxData.elevation.gain, - elevationLoss: gpxData.elevation.loss, - dayBreaks, - description: gpxData.description, - }; -} - async function getGeojson(table: "routes" | "activities", id: string): Promise { try { const db = getDb(); diff --git a/apps/journal/app/routes/api.sync.callback.$provider.ts b/apps/journal/app/routes/api.sync.callback.$provider.ts index e9c0db0..f935ced 100644 --- a/apps/journal/app/routes/api.sync.callback.$provider.ts +++ b/apps/journal/app/routes/api.sync.callback.$provider.ts @@ -1,13 +1,11 @@ import { redirect, data } from "react-router"; -import { getOrigin } from "~/lib/config.server"; import type { Route } from "./+types/api.sync.callback.$provider"; import { requireSessionUser } from "~/lib/auth/session.server"; -import { getManifest, link } from "~/lib/connected-services"; +import { getManifest } from "~/lib/connected-services"; import { - decodeOAuthState, - readPkceVerifier, + completeOAuthFlow, clearPkceCookieHeader, -} from "~/lib/connected-services/oauth-state.server"; +} from "~/lib/connected-services/oauth-flow.server"; import { pushRouteToProvider } from "~/lib/connected-services/push-action.server"; export async function loader({ params, request }: Route.LoaderArgs) { @@ -18,51 +16,28 @@ export async function loader({ params, request }: Route.LoaderArgs) { return data({ error: "Unknown provider" }, { status: 404 }); } - const url = new URL(request.url); - const state = decodeOAuthState(url.searchParams.get("state")); + const result = await completeOAuthFlow(manifest, request, user.id); + const state = result.state; const fallbackReturn = state.returnTo ?? "/settings"; + // Spent (or irrelevant) verifier — clear it on every outcome. + const headers = { "Set-Cookie": clearPkceCookieHeader() }; - // User denied the new scope at Wahoo. Send them back to the originating - // page with a notice instead of looping them through OAuth again. - if (url.searchParams.get("error") === "access_denied") { - return redirect(`${fallbackReturn}?push=needs_permission`); - } - - const code = url.searchParams.get("code"); - if (!code) return data({ error: "Missing authorization code" }, { status: 400 }); - - const origin = getOrigin(); - const redirectUri = `${origin}/api/sync/callback/${params.provider}`; - - // PKCE providers: recover the verifier from the connect-time cookie. - const codeVerifier = manifest.pkce ? readPkceVerifier(request) : null; - if (manifest.pkce && !codeVerifier) { - return redirect(`${fallbackReturn}?error=sync_failed`); - } - - try { - const exchange = await manifest.exchangeCode( - code, - redirectUri, - codeVerifier ? { codeVerifier } : undefined, - ); - await link({ - userId: user.id, - provider: manifest.id, - credentialKind: manifest.credentialKind, - credentials: exchange.credentials as Record, - providerUserId: exchange.providerUserId, - grantedScopes: exchange.grantedScopes, - }); - } catch (e) { - console.error(`OAuth callback failed for ${params.provider}:`, e); - const errCode = - typeof (e as { code?: string }).code === "string" - ? (e as { code: string }).code - : "sync_failed"; - return redirect(`${fallbackReturn}?error=${errCode}`); + switch (result.status) { + case "denied": + // User declined at the provider. Back to the originating page + // with a notice instead of looping them through OAuth again. + return redirect(`${fallbackReturn}?push=needs_permission`, { headers }); + case "missing_code": + return data({ error: "Missing authorization code" }, { status: 400 }); + case "missing_verifier": + return redirect(`${fallbackReturn}?error=sync_failed`, { headers }); + case "error": + return redirect(`${fallbackReturn}?error=${result.code}`, { headers }); + case "linked": + break; } + // Resume an interrupted push now that the connection has the scope. if (state.pushAfter?.routeId) { const outcome = await pushRouteToProvider({ userId: user.id, @@ -70,16 +45,12 @@ export async function loader({ params, request }: Route.LoaderArgs) { routeId: state.pushAfter.routeId, }); const target = state.returnTo ?? `/routes/${state.pushAfter.routeId}`; - if (outcome.status === "success") return redirect(`${target}?push=success`); - if (outcome.status === "scope_missing") return redirect(`${target}?push=needs_permission`); - if (outcome.status === "needs_relink") return redirect(`${target}?push=needs_permission`); - if (outcome.status === "error") return redirect(`${target}?push=error&code=${outcome.code}`); - return redirect(`${target}?push=${outcome.status}`); + if (outcome.status === "success") return redirect(`${target}?push=success`, { headers }); + if (outcome.status === "scope_missing") return redirect(`${target}?push=needs_permission`, { headers }); + if (outcome.status === "needs_relink") return redirect(`${target}?push=needs_permission`, { headers }); + if (outcome.status === "error") return redirect(`${target}?push=error&code=${outcome.code}`, { headers }); + return redirect(`${target}?push=${outcome.status}`, { headers }); } - return redirect(state.returnTo ?? "/settings", { - // Spent verifier — clear it regardless of which provider this was - // (harmless no-op for non-PKCE providers without the cookie). - headers: { "Set-Cookie": clearPkceCookieHeader() }, - }); + return redirect(state.returnTo ?? "/settings", { headers }); } diff --git a/apps/journal/app/routes/api.sync.connect.$provider.ts b/apps/journal/app/routes/api.sync.connect.$provider.ts index 6e27d09..8118f96 100644 --- a/apps/journal/app/routes/api.sync.connect.$provider.ts +++ b/apps/journal/app/routes/api.sync.connect.$provider.ts @@ -1,13 +1,8 @@ -import { redirect, data } from "react-router"; -import { getOrigin } from "~/lib/config.server"; +import { data } from "react-router"; import type { Route } from "./+types/api.sync.connect.$provider"; import { requireSessionUser } from "~/lib/auth/session.server"; import { getManifest } from "~/lib/connected-services"; -import { - encodeOAuthState, - generatePkcePair, - pkceCookieHeader, -} from "~/lib/connected-services/oauth-state.server"; +import { initiateOAuthFlow } from "~/lib/connected-services/oauth-flow.server"; export async function loader({ params, request }: Route.LoaderArgs) { await requireSessionUser(request); @@ -17,19 +12,5 @@ export async function loader({ params, request }: Route.LoaderArgs) { return data({ error: "Unknown provider" }, { status: 404 }); } - const origin = getOrigin(); - const redirectUri = `${origin}/api/sync/callback/${params.provider}`; - const state = encodeOAuthState({ returnTo: "/settings/connections" }); - - // PKCE providers (Garmin): the verifier crosses the redirect in an - // httpOnly cookie; only the S256 challenge goes to the provider. - if (manifest.pkce) { - const { verifier, challenge } = generatePkcePair(); - return redirect( - manifest.buildAuthUrl(redirectUri, state, { codeChallenge: challenge }), - { headers: { "Set-Cookie": pkceCookieHeader(verifier) } }, - ); - } - - return redirect(manifest.buildAuthUrl(redirectUri, state)); + return initiateOAuthFlow(manifest, { returnTo: "/settings/connections" }); } diff --git a/apps/journal/app/routes/api.sync.push.$provider.$routeId.ts b/apps/journal/app/routes/api.sync.push.$provider.$routeId.ts index bb4d7e3..9bb93ea 100644 --- a/apps/journal/app/routes/api.sync.push.$provider.$routeId.ts +++ b/apps/journal/app/routes/api.sync.push.$provider.$routeId.ts @@ -1,10 +1,9 @@ import { redirect, data } from "react-router"; -import { getOrigin } from "~/lib/config.server"; import type { Route } from "./+types/api.sync.push.$provider.$routeId"; import { requireSessionUser } from "~/lib/auth/session.server"; import { getManifest } from "~/lib/connected-services"; import { pushRouteToProvider } from "~/lib/connected-services/push-action.server"; -import { encodeOAuthState } from "~/lib/connected-services/oauth-state.server"; +import { initiateOAuthFlow } from "~/lib/connected-services/oauth-flow.server"; export async function action({ params, request }: Route.ActionArgs) { const user = await requireSessionUser(request); @@ -26,13 +25,12 @@ export async function action({ params, request }: Route.ActionArgs) { if (!manifest.buildAuthUrl) { return redirect(`${returnTo}?push=needs_permission`); } - const origin = getOrigin(); - const redirectUri = `${origin}/api/sync/callback/${manifest.id}`; - const state = encodeOAuthState({ + // Re-authorize with the push intent in the state; the callback + // resumes the push once the scope is granted. + return initiateOAuthFlow(manifest, { pushAfter: { routeId: params.routeId }, returnTo, }); - return redirect(manifest.buildAuthUrl(redirectUri, state)); } case "needs_relink": return redirect(`${returnTo}?push=needs_permission`); diff --git a/apps/journal/app/routes/api.v1.activities.$id.ts b/apps/journal/app/routes/api.v1.activities.$id.ts index 41c36c1..c0c16d5 100644 --- a/apps/journal/app/routes/api.v1.activities.$id.ts +++ b/apps/journal/app/routes/api.v1.activities.$id.ts @@ -1,8 +1,8 @@ import type { Route } from "./+types/api.v1.activities.$id"; -import { requireApiUser, apiError } from "~/lib/api-guard.server"; +import { requireApiUser, apiError, apiJson } from "~/lib/api-guard.server"; import { getActivity, deleteActivity } from "~/lib/activities.server"; import { loadOwnedActivity } from "~/lib/ownership.server"; -import { ERROR_CODES } from "@trails-cool/api"; +import { ERROR_CODES, ActivityDetailSchema } from "@trails-cool/api"; /** GET /api/v1/activities/:id — full activity detail */ export async function loader({ request, params }: Route.LoaderArgs) { @@ -13,11 +13,14 @@ export async function loader({ request, params }: Route.LoaderArgs) { return apiError(404, ERROR_CODES.NOT_FOUND, "Activity not found"); } - return Response.json({ + return apiJson(ActivityDetailSchema, { id: activity.id, name: activity.name, - description: activity.description, + description: activity.description ?? "", routeId: activity.routeId, + routeName: null, // TODO: join route name (matches the list endpoint) + photos: [], // no photos on this surface yet; contract field + distance: activity.distance, duration: activity.duration, elevationGain: activity.elevationGain, diff --git a/apps/journal/app/routes/api.v1.activities._index.ts b/apps/journal/app/routes/api.v1.activities._index.ts index a323e88..13810e6 100644 --- a/apps/journal/app/routes/api.v1.activities._index.ts +++ b/apps/journal/app/routes/api.v1.activities._index.ts @@ -1,11 +1,13 @@ import type { Route } from "./+types/api.v1.activities._index"; -import { requireApiUser, apiError } from "~/lib/api-guard.server"; +import { requireApiUser, apiError, apiJson } from "~/lib/api-guard.server"; import { listActivities, createActivity } from "~/lib/activities.server"; import { PaginationQuerySchema, CreateActivityRequestSchema, ERROR_CODES, zodIssuesToFieldErrors, + ActivityListResponseSchema, + CreateActivityResponseSchema, } from "@trails-cool/api"; /** GET /api/v1/activities — paginated activity list */ @@ -32,11 +34,11 @@ export async function loader({ request }: Route.LoaderArgs) { const page = allActivities.slice(startIdx, startIdx + limit); const nextCursor = startIdx + limit < allActivities.length ? page[page.length - 1]?.id ?? null : null; - return Response.json({ + return apiJson(ActivityListResponseSchema, { activities: page.map((a) => ({ id: a.id, name: a.name, - description: a.description, + description: a.description ?? "", routeId: a.routeId, routeName: null, // TODO: join route name distance: a.distance, @@ -67,5 +69,5 @@ export async function action({ request }: Route.ActionArgs) { ...parsed.data, startedAt: parsed.data.startedAt ? new Date(parsed.data.startedAt) : null, }); - return Response.json({ id }, { status: 201 }); + return apiJson(CreateActivityResponseSchema, { id }, { status: 201 }); } diff --git a/apps/journal/app/routes/api.v1.routes.$id.ts b/apps/journal/app/routes/api.v1.routes.$id.ts index c2c41a1..74a3ef3 100644 --- a/apps/journal/app/routes/api.v1.routes.$id.ts +++ b/apps/journal/app/routes/api.v1.routes.$id.ts @@ -1,8 +1,8 @@ import type { Route } from "./+types/api.v1.routes.$id"; -import { requireApiUser, apiError } from "~/lib/api-guard.server"; +import { requireApiUser, apiError, apiJson } from "~/lib/api-guard.server"; import { getRouteWithVersions, updateRoute, deleteRoute } from "~/lib/routes.server"; import { loadOwnedRoute } from "~/lib/ownership.server"; -import { UpdateRouteRequestSchema, ERROR_CODES, zodIssuesToFieldErrors } from "@trails-cool/api"; +import { UpdateRouteRequestSchema, ERROR_CODES, zodIssuesToFieldErrors, RouteDetailSchema } from "@trails-cool/api"; /** GET /api/v1/routes/:id — full route detail */ export async function loader({ request, params }: Route.LoaderArgs) { @@ -13,10 +13,10 @@ export async function loader({ request, params }: Route.LoaderArgs) { return apiError(404, ERROR_CODES.NOT_FOUND, "Route not found"); } - return Response.json({ + return apiJson(RouteDetailSchema, { id: route.id, name: route.name, - description: route.description, + description: route.description ?? "", distance: route.distance, elevationGain: route.elevationGain, elevationLoss: route.elevationLoss, diff --git a/apps/journal/app/routes/api.v1.routes._index.ts b/apps/journal/app/routes/api.v1.routes._index.ts index 5f72767..817dae8 100644 --- a/apps/journal/app/routes/api.v1.routes._index.ts +++ b/apps/journal/app/routes/api.v1.routes._index.ts @@ -1,11 +1,13 @@ import type { Route } from "./+types/api.v1.routes._index"; -import { requireApiUser, apiError } from "~/lib/api-guard.server"; +import { requireApiUser, apiError, apiJson } from "~/lib/api-guard.server"; import { listRoutes, createRoute } from "~/lib/routes.server"; import { PaginationQuerySchema, CreateRouteRequestSchema, ERROR_CODES, zodIssuesToFieldErrors, + RouteListResponseSchema, + CreateRouteResponseSchema, } from "@trails-cool/api"; /** GET /api/v1/routes — paginated route list */ @@ -32,11 +34,11 @@ export async function loader({ request }: Route.LoaderArgs) { const page = allRoutes.slice(startIdx, startIdx + limit); const nextCursor = startIdx + limit < allRoutes.length ? page[page.length - 1]?.id ?? null : null; - return Response.json({ + return apiJson(RouteListResponseSchema, { routes: page.map((r) => ({ id: r.id, name: r.name, - description: r.description, + description: r.description ?? "", distance: r.distance, elevationGain: r.elevationGain, elevationLoss: r.elevationLoss, @@ -63,5 +65,5 @@ export async function action({ request }: Route.ActionArgs) { } const id = await createRoute(user.id, parsed.data); - return Response.json({ id }, { status: 201 }); + return apiJson(CreateRouteResponseSchema, { id }, { status: 201 }); } diff --git a/apps/journal/app/routes/api.v1.routes.test.ts b/apps/journal/app/routes/api.v1.routes.test.ts index 88f88ac..9304ac7 100644 --- a/apps/journal/app/routes/api.v1.routes.test.ts +++ b/apps/journal/app/routes/api.v1.routes.test.ts @@ -3,6 +3,9 @@ import { describe, it, expect, vi, beforeEach } from "vitest"; import { TERMS_VERSION } from "~/lib/legal"; const mockUser = { id: "user-1", email: "test@test.com", username: "test", domain: "localhost", displayName: null, bio: null, createdAt: new Date(), termsVersion: TERMS_VERSION }; +const ROUTE_ID = "11111111-1111-4111-8111-111111111111"; +const VERSION_ID = "22222222-2222-4222-8222-222222222222"; +const NEW_ID = "33333333-3333-4333-8333-333333333333"; const mockGetAuthenticatedUser = vi.fn(); const mockListRoutes = vi.fn(); const mockCreateRoute = vi.fn(); @@ -51,7 +54,7 @@ describe("GET /api/v1/routes", () => { const now = new Date(); mockListRoutes.mockResolvedValue([ { - id: "r1", name: "Tour", description: "", distance: 42000, + id: ROUTE_ID, name: "Tour", description: "", distance: 42000, elevationGain: 340, elevationLoss: 320, routingProfile: "fastbike", dayBreaks: [], geojson: null, ownerId: "user-1", gpx: null, tags: null, plannerState: null, createdAt: now, updatedAt: now, @@ -63,7 +66,7 @@ describe("GET /api/v1/routes", () => { const data = await resp.json(); expect(data.routes).toHaveLength(1); - expect(data.routes[0].id).toBe("r1"); + expect(data.routes[0].id).toBe(ROUTE_ID); expect(data.nextCursor).toBeNull(); }); @@ -83,7 +86,7 @@ describe("GET /api/v1/routes", () => { describe("POST /api/v1/routes", () => { it("creates a route with valid body", async () => { - mockCreateRoute.mockResolvedValue("new-id"); + mockCreateRoute.mockResolvedValue(NEW_ID); const { action } = await import("./api.v1.routes._index.ts"); const resp = await action(routeArgs( @@ -95,7 +98,7 @@ describe("POST /api/v1/routes", () => { expect(resp.status).toBe(201); const data = await resp.json(); - expect(data.id).toBe("new-id"); + expect(data.id).toBe(NEW_ID); }); it("returns 400 on validation error", async () => { @@ -117,20 +120,20 @@ describe("GET /api/v1/routes/:id", () => { it("returns route detail", async () => { const now = new Date(); mockGetRouteWithVersions.mockResolvedValue({ - id: "r1", name: "Tour", description: "", distance: 42000, + id: ROUTE_ID, name: "Tour", description: "", distance: 42000, elevationGain: 340, elevationLoss: 320, routingProfile: "fastbike", dayBreaks: [], gpx: "", ownerId: "user-1", tags: null, plannerState: null, createdAt: now, updatedAt: now, - versions: [{ id: "v1", routeId: "r1", version: 1, gpx: "", createdBy: "user-1", changeDescription: null, createdAt: now }], + versions: [{ id: VERSION_ID, routeId: ROUTE_ID, version: 1, gpx: "", createdBy: "user-1", changeDescription: null, createdAt: now }], }); const { loader } = await import("./api.v1.routes.$id.ts"); const resp = await loader(routeArgs( - authRequest("/api/v1/routes/r1"), { id: "r1" }, "api/v1/routes/:id", + authRequest(`/api/v1/routes/${ROUTE_ID}`), { id: ROUTE_ID }, "api/v1/routes/:id", )) as Response; const data = await resp.json(); - expect(data.id).toBe("r1"); + expect(data.id).toBe(ROUTE_ID); expect(data.gpx).toBe(""); expect(data.versions).toHaveLength(1); }); diff --git a/apps/mobile/app/__tests__/smoke.test.tsx b/apps/mobile/app/__tests__/smoke.test.tsx index 907e02a..f7922d9 100644 --- a/apps/mobile/app/__tests__/smoke.test.tsx +++ b/apps/mobile/app/__tests__/smoke.test.tsx @@ -3,8 +3,10 @@ import { render, screen } from "@testing-library/react-native"; import { Text } from "react-native"; describe("Jest + React Native Testing Library", () => { - it("renders a component", () => { - render(Hello); + it("renders a component", async () => { + // await is a no-op on RNTL v13 but required on v14, where render() + // returns a Promise + await render(Hello); expect(screen.getByTestId("hello")).toBeTruthy(); expect(screen.getByText("Hello")).toBeTruthy(); }); diff --git a/apps/mobile/package.json b/apps/mobile/package.json index e526096..8156525 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -41,7 +41,7 @@ "@trails-cool/map-core": "workspace:*", "@trails-cool/sentry-config": "workspace:*", "@trails-cool/types": "workspace:*", - "expo": "~56.0.4", + "expo": "~56.0.9", "expo-constants": "~56.0.17", "expo-crypto": "~56.0.4", "expo-dev-client": "~56.0.19", @@ -62,10 +62,10 @@ "react": "catalog:", "react-native": "0.85.3", "react-native-gesture-handler": "^2.31.2", - "react-native-reanimated": "^4.4.1", - "react-native-safe-area-context": "~5.8.0", + "react-native-reanimated": "^4.3.1", + "react-native-safe-area-context": "~5.7.0", "react-native-screens": "~4.25.2", - "react-native-worklets": "0.9.1", + "react-native-worklets": "0.8.3", "use-latest-callback": "^0.3.4", "zod": "^4.4.3" }, diff --git a/e2e/auth.test.ts b/e2e/auth.test.ts index 8cda6a3..81043e2 100644 --- a/e2e/auth.test.ts +++ b/e2e/auth.test.ts @@ -1,50 +1,5 @@ import { test, expect, waitForHydration, type CDPSession, type Page } from "./fixtures/test"; - -// Virtual authenticator helpers -async function setupVirtualAuthenticator(cdp: CDPSession) { - await cdp.send("WebAuthn.enable"); - const { authenticatorId } = await cdp.send("WebAuthn.addVirtualAuthenticator", { - options: { - protocol: "ctap2", - transport: "internal", - hasResidentKey: true, - hasUserVerification: true, - isUserVerified: true, - }, - }); - return authenticatorId; -} - -async function removeVirtualAuthenticator(cdp: CDPSession, authenticatorId: string) { - await cdp.send("WebAuthn.removeVirtualAuthenticator", { authenticatorId }); - await cdp.send("WebAuthn.disable"); -} - -async function registerUser(page: Page, email: string, username: string) { - await page.goto("/auth/register"); - await expect(page.getByRole("heading", { name: "Register" })).toBeVisible(); - await waitForHydration(page); - await page.getByLabel("Email").click(); - await page.getByLabel("Email").fill(email); - await page.getByLabel("Username").click(); - await page.getByLabel("Username").fill(username); - // Verify both fields retained values before submitting - await expect(page.getByLabel("Email")).toHaveValue(email); - await expect(page.getByLabel("Username")).toHaveValue(username); - // Accept the Terms of Service (required) - await page.getByRole("checkbox").check(); - await page.getByRole("button", { name: /Register with Passkey/ }).click(); -} - -async function logout(page: Page, accountLabel: string) { - // The account cluster lives inside an avatar dropdown now. Click the - // avatar (its aria-label is displayName || username), then click the - // Log Out menuitem inside the popup. - await waitForHydration(page); - await page.getByRole("navigation").getByRole("button", { name: accountLabel }).click(); - await page.getByRole("menuitem", { name: "Log Out" }).click(); - await expect(page.getByRole("navigation").getByRole("link", { name: "Sign In" })).toBeVisible({ timeout: 5000 }); -} +import { setupVirtualAuthenticator, removeVirtualAuthenticator, submitRegistration, logout } from "./helpers/auth"; test.describe("Passkey Authentication", () => { test("register with passkey and sign in", async ({ page }) => { @@ -55,7 +10,7 @@ test.describe("Passkey Authentication", () => { const username = `testuser${Date.now()}`; // Register - await registerUser(page, email, username); + await submitRegistration(page, email, username); await expect(page).toHaveURL("/", { timeout: 10000 }); // The avatar button's aria-label is the displayName or username; // for a freshly-registered user with no displayName set, that's @@ -95,12 +50,12 @@ test.describe("Passkey Authentication", () => { const firstUsername = `first${Date.now()}`; // Register first user - await registerUser(page, email, firstUsername); + await submitRegistration(page, email, firstUsername); await expect(page).toHaveURL("/", { timeout: 10000 }); await logout(page, firstUsername); // Try to register with same email - await registerUser(page, email, `second${Date.now()}`); + await submitRegistration(page, email, `second${Date.now()}`); await expect(page.getByText(/already in use/i)).toBeVisible({ timeout: 10000 }); await removeVirtualAuthenticator(cdp, authenticatorId); @@ -113,12 +68,12 @@ test.describe("Passkey Authentication", () => { const username = `uniq${Date.now()}`; // Register first user - await registerUser(page, `first-${Date.now()}@example.com`, username); + await submitRegistration(page, `first-${Date.now()}@example.com`, username); await expect(page).toHaveURL("/", { timeout: 10000 }); await logout(page, username); // Try to register with same username - await registerUser(page, `second-${Date.now()}@example.com`, username); + await submitRegistration(page, `second-${Date.now()}@example.com`, username); await expect(page.getByText(/already taken/i)).toBeVisible({ timeout: 10000 }); await removeVirtualAuthenticator(cdp, authenticatorId); diff --git a/e2e/explore.test.ts b/e2e/explore.test.ts index defa731..532f37b 100644 --- a/e2e/explore.test.ts +++ b/e2e/explore.test.ts @@ -1,29 +1,5 @@ import { test, expect, waitForHydration, type CDPSession, type Page } from "./fixtures/test"; - -async function setupVirtualAuthenticator(cdp: CDPSession) { - await cdp.send("WebAuthn.enable"); - const { authenticatorId } = await cdp.send("WebAuthn.addVirtualAuthenticator", { - options: { - protocol: "ctap2", - transport: "internal", - hasResidentKey: true, - hasUserVerification: true, - isUserVerified: true, - }, - }); - return authenticatorId; -} - -async function registerUser(page: Page, email: string, username: string) { - await page.goto("/auth/register"); - await expect(page.getByRole("heading", { name: "Register" })).toBeVisible(); - await waitForHydration(page); - await page.getByLabel("Email").fill(email); - await page.getByLabel("Username").fill(username); - await page.getByRole("checkbox").check(); - await page.getByRole("button", { name: /Register with Passkey/ }).click(); - await expect(page).toHaveURL("/", { timeout: 10000 }); -} +import { setupVirtualAuthenticator, registerUser } from "./helpers/auth"; async function setProfileVisibility(page: Page, value: "public" | "private") { await page.goto("/settings"); diff --git a/e2e/helpers/auth.ts b/e2e/helpers/auth.ts new file mode 100644 index 0000000..5d7c1e4 --- /dev/null +++ b/e2e/helpers/auth.ts @@ -0,0 +1,84 @@ +// Shared auth helpers for journal specs. These were previously +// copy-pasted per spec file and had already drifted (the auth spec's +// registerUser lost the final URL assertion the other copies had, and +// the settings spec's variant skipped hydration and the Terms +// checkbox). One canonical copy lives here. + +import { expect, waitForHydration, type CDPSession, type Page } from "../fixtures/test"; + +export async function setupVirtualAuthenticator(cdp: CDPSession): Promise { + await cdp.send("WebAuthn.enable"); + const { authenticatorId } = await cdp.send("WebAuthn.addVirtualAuthenticator", { + options: { + protocol: "ctap2", + transport: "internal", + hasResidentKey: true, + hasUserVerification: true, + isUserVerified: true, + }, + }); + return authenticatorId; +} + +export async function removeVirtualAuthenticator( + cdp: CDPSession, + authenticatorId: string, +): Promise { + await cdp.send("WebAuthn.removeVirtualAuthenticator", { authenticatorId }); + await cdp.send("WebAuthn.disable"); +} + +/** + * Fill and submit the registration form (passkey + Terms acceptance). + * Makes no assertion about the outcome — use this directly for + * expected-failure attempts (duplicate email/username), and + * registerUser for the success path. + */ +export async function submitRegistration( + page: Page, + email: string, + username: string, +): Promise { + await page.goto("/auth/register"); + await expect(page.getByRole("heading", { name: "Register" })).toBeVisible(); + await waitForHydration(page); + await page.getByLabel("Email").click(); + await page.getByLabel("Email").fill(email); + await page.getByLabel("Username").click(); + await page.getByLabel("Username").fill(username); + // Verify both fields retained values before submitting + await expect(page.getByLabel("Email")).toHaveValue(email); + await expect(page.getByLabel("Username")).toHaveValue(username); + // Accept the Terms of Service (required) + await page.getByRole("checkbox").check(); + await page.getByRole("button", { name: /Register with Passkey/ }).click(); +} + +/** Register a user with a passkey and wait for the signed-in redirect. */ +export async function registerUser(page: Page, email: string, username: string): Promise { + await submitRegistration(page, email, username); + await expect(page).toHaveURL("/", { timeout: 10000 }); +} + +/** Register a throwaway user with unique credentials derived from `prefix`. */ +export async function registerFreshUser( + page: Page, + prefix: string, +): Promise<{ email: string; username: string }> { + const email = `${prefix}-${Date.now()}@example.com`; + const username = `${prefix}${Date.now()}`; + await registerUser(page, email, username); + return { email, username }; +} + +export async function logout(page: Page, accountLabel: string): Promise { + // The account cluster lives inside an avatar dropdown. Click the + // avatar (its aria-label is displayName || username), then click the + // Log Out menuitem inside the popup. + await waitForHydration(page); + await page.getByRole("navigation").getByRole("button", { name: accountLabel }).click(); + await page.getByRole("menuitem", { name: "Log Out" }).click(); + await expect( + page.getByRole("navigation").getByRole("link", { name: "Sign In" }), + ).toBeVisible({ timeout: 5000 }); +} diff --git a/e2e/helpers/journal.ts b/e2e/helpers/journal.ts new file mode 100644 index 0000000..8e0745f --- /dev/null +++ b/e2e/helpers/journal.ts @@ -0,0 +1,39 @@ +// Shared journal-side constants and seed helpers. The /api/e2e/* +// endpoints only exist when the journal runs with E2E=true. + +import type { APIRequestContext } from "@playwright/test"; +import { expect } from "../fixtures/test"; + +export const JOURNAL = "http://localhost:3000"; +export const PLANNER = "http://localhost:3001"; + +/** Mint a route + single-use callback JWT via /api/e2e/seed. */ +export async function seedRoute( + request: APIRequestContext, +): Promise<{ routeId: string; token: string }> { + const resp = await request.post(`${JOURNAL}/api/e2e/seed`); + expect(resp.ok(), "POST /api/e2e/seed failed — is the journal running with E2E=true?").toBeTruthy(); + return (await resp.json()) as { routeId: string; token: string }; +} + +/** Whether the route has PostGIS geometry stored (via /api/e2e/route/:id). */ +export async function routeHasGeom( + request: APIRequestContext, + routeId: string, +): Promise { + const resp = await request.get(`${JOURNAL}/api/e2e/route/${routeId}`); + expect(resp.ok()).toBeTruthy(); + const { hasGeom } = (await resp.json()) as { hasGeom: boolean }; + return hasGeom; +} + +/** Seeds a Komoot connection for the e2e test user; returns the session cookie. */ +export async function seedKomootConnection( + request: APIRequestContext, + mode: "public" | "authenticated" = "public", +): Promise<{ cookie: string }> { + const resp = await request.post(`${JOURNAL}/api/e2e/komoot`, { data: { mode } }); + if (!resp.ok()) throw new Error(`komoot seed failed: ${resp.status()}`); + const cookie = resp.headers()["set-cookie"]; + return { cookie }; +} diff --git a/e2e/integration.test.ts b/e2e/integration.test.ts index 4fdb784..50c6811 100644 --- a/e2e/integration.test.ts +++ b/e2e/integration.test.ts @@ -1,4 +1,5 @@ import { test, expect } from "./fixtures/test"; +import { JOURNAL, PLANNER, seedRoute, routeHasGeom } from "./helpers/journal"; /** * Integration tests that require the full dev stack: @@ -9,8 +10,6 @@ import { test, expect } from "./fixtures/test"; * Locally, run `pnpm dev:full` first (with E2E=true for the callback tests). */ -const JOURNAL = "http://localhost:3000"; -const PLANNER = "http://localhost:3001"; const VALID_GPX = ` @@ -30,9 +29,7 @@ const ONE_POINT_GPX = ` test.describe("Integration: Planner callback → geometry stored", () => { test("valid GPX stores geometry atomically", async ({ request }) => { - const seedResp = await request.post(`${JOURNAL}/api/e2e/seed`); - expect(seedResp.ok()).toBeTruthy(); - const { routeId, token } = await seedResp.json() as { routeId: string; token: string }; + const { routeId, token } = await seedRoute(request); const callbackResp = await request.post(`${JOURNAL}/api/routes/${routeId}/callback`, { headers: { Authorization: `Bearer ${token}` }, @@ -40,14 +37,11 @@ test.describe("Integration: Planner callback → geometry stored", () => { }); expect(callbackResp.status()).toBe(200); - const geomResp = await request.get(`${JOURNAL}/api/e2e/route/${routeId}`); - const { hasGeom } = await geomResp.json() as { hasGeom: boolean }; - expect(hasGeom).toBe(true); + expect(await routeHasGeom(request, routeId)).toBe(true); }); test("invalid GPX returns 400 and does not store geometry", async ({ request }) => { - const seedResp = await request.post(`${JOURNAL}/api/e2e/seed`); - const { routeId, token } = await seedResp.json() as { routeId: string; token: string }; + const { routeId, token } = await seedRoute(request); const callbackResp = await request.post(`${JOURNAL}/api/routes/${routeId}/callback`, { headers: { Authorization: `Bearer ${token}` }, @@ -57,14 +51,11 @@ test.describe("Integration: Planner callback → geometry stored", () => { const body = await callbackResp.json() as { error: string }; expect(body.error).toMatch(/at least 2 track points/); - const geomResp = await request.get(`${JOURNAL}/api/e2e/route/${routeId}`); - const { hasGeom } = await geomResp.json() as { hasGeom: boolean }; - expect(hasGeom).toBe(false); + expect(await routeHasGeom(request, routeId)).toBe(false); }); test("missing token returns 401", async ({ request }) => { - const seedResp = await request.post(`${JOURNAL}/api/e2e/seed`); - const { routeId } = await seedResp.json() as { routeId: string }; + const { routeId } = await seedRoute(request); const resp = await request.post(`${JOURNAL}/api/routes/${routeId}/callback`, { data: { gpx: VALID_GPX }, @@ -73,8 +64,7 @@ test.describe("Integration: Planner callback → geometry stored", () => { }); test("token is single-use — second submit is rejected (Phase B replay guard)", async ({ request }) => { - const seedResp = await request.post(`${JOURNAL}/api/e2e/seed`); - const { routeId, token } = await seedResp.json() as { routeId: string; token: string }; + const { routeId, token } = await seedRoute(request); // First save succeeds. const first = await request.post(`${JOURNAL}/api/routes/${routeId}/callback`, { @@ -163,9 +153,7 @@ test.describe("Integration: POI metadata roundtrip", () => { `; - const seedResp = await request.post(`${JOURNAL}/api/e2e/seed`); - expect(seedResp.ok()).toBeTruthy(); - const { routeId, token } = await seedResp.json() as { routeId: string; token: string }; + const { routeId, token } = await seedRoute(request); const callbackResp = await request.post(`${JOURNAL}/api/routes/${routeId}/callback`, { headers: { Authorization: `Bearer ${token}` }, @@ -182,8 +170,7 @@ test.describe("Integration: POI metadata roundtrip", () => { }); test("GPX without POI extensions shows no waypoints section", async ({ page, request }) => { - const seedResp = await request.post(`${JOURNAL}/api/e2e/seed`); - const { routeId, token } = await seedResp.json() as { routeId: string; token: string }; + const { routeId, token } = await seedRoute(request); await request.post(`${JOURNAL}/api/routes/${routeId}/callback`, { headers: { Authorization: `Bearer ${token}` }, data: { gpx: VALID_GPX }, diff --git a/e2e/journal-planner-save.test.ts b/e2e/journal-planner-save.test.ts index 96f1a20..db0b445 100644 --- a/e2e/journal-planner-save.test.ts +++ b/e2e/journal-planner-save.test.ts @@ -17,10 +17,9 @@ // computes a route and the Save button has GPX to ship. import { test, expect } from "./fixtures/test"; +import { JOURNAL, PLANNER, seedRoute, routeHasGeom } from "./helpers/journal"; import { mockBRouter } from "./fixtures/brouter-mock"; -const JOURNAL = "http://localhost:3000"; -const PLANNER = "http://localhost:3001"; // Mock BRouter so the in-browser route compute is deterministic and // fast — same approach as `planner-coloring.test.ts`. Without this the @@ -35,9 +34,7 @@ const WAYPOINTS = encodeURIComponent(JSON.stringify([ ])); async function seedRouteAndPlannerSession(request: import("@playwright/test").APIRequestContext) { - const seedResp = await request.post(`${JOURNAL}/api/e2e/seed`); - expect(seedResp.ok()).toBeTruthy(); - const { routeId, token } = (await seedResp.json()) as { routeId: string; token: string }; + const { routeId, token } = await seedRoute(request); // Create a planner session with the journal callback wired up — no // GPX seeded into the session itself. We pass waypoints via URL @@ -85,9 +82,7 @@ test.describe("Journal ↔ Planner save handoff (Phase A + B)", () => { expect(observed.some((s) => s.includes(token))).toBe(false); // Sanity: the journal's route now has geometry. - const geomResp = await request.get(`${JOURNAL}/api/e2e/route/${routeId}`); - const { hasGeom } = (await geomResp.json()) as { hasGeom: boolean }; - expect(hasGeom).toBe(true); + expect(await routeHasGeom(request, routeId)).toBe(true); }); test("token is single-use — second save through the planner UI fails", async ({ page, request }) => { diff --git a/e2e/komoot-import.test.ts b/e2e/komoot-import.test.ts index d58ca37..4d8620a 100644 --- a/e2e/komoot-import.test.ts +++ b/e2e/komoot-import.test.ts @@ -1,8 +1,8 @@ import { test, expect } from "./fixtures/test"; +import { JOURNAL, seedKomootConnection, seedRoute } from "./helpers/journal"; // Fixed test data — the e2e seed endpoint creates a stable user + Komoot connection const KOMOOT_USER_ID = "99999999999"; -const JOURNAL = "http://localhost:3000"; const SAMPLE_GPX = ` @@ -34,19 +34,6 @@ const MOCK_TOURS_RESPONSE = { page: { totalPages: 1, number: 0 }, }; -// Seeds a Komoot connection for the e2e test user and returns a session cookie. -async function seedKomootConnection( - request: import("@playwright/test").APIRequestContext, - mode: "public" | "authenticated" = "public", -) { - const resp = await request.post(`${JOURNAL}/api/e2e/komoot`, { - data: { mode }, - }); - if (!resp.ok()) throw new Error(`komoot seed failed: ${resp.status()}`); - const cookie = resp.headers()["set-cookie"]; - return { cookie }; -} - test.describe("Komoot connection page", () => { test("unauthenticated user is redirected to login", async ({ page }) => { await page.goto("/settings/connections/komoot"); @@ -105,10 +92,8 @@ test.describe("Komoot import page", () => { test.setTimeout(60000); test("redirects to connect page when not connected", async ({ page, request }) => { - // Seed user without Komoot connection (use seed endpoint to just get a session) - const seedResp = await request.post(`${JOURNAL}/api/e2e/seed`); - const data = await seedResp.json() as { routeId: string; token: string }; // We only need the session — navigate to import page unauthenticated redirects to login + await seedRoute(request); await page.goto("/sync/import/komoot"); await expect(page).toHaveURL(/\/auth\/login|\/settings\/connections\/komoot/, { timeout: 5000 }); }); diff --git a/e2e/notifications.test.ts b/e2e/notifications.test.ts index e7549a9..b53a800 100644 --- a/e2e/notifications.test.ts +++ b/e2e/notifications.test.ts @@ -1,29 +1,5 @@ import { test, expect, waitForHydration, type CDPSession, type Page } from "./fixtures/test"; - -async function setupVirtualAuthenticator(cdp: CDPSession) { - await cdp.send("WebAuthn.enable"); - const { authenticatorId } = await cdp.send("WebAuthn.addVirtualAuthenticator", { - options: { - protocol: "ctap2", - transport: "internal", - hasResidentKey: true, - hasUserVerification: true, - isUserVerified: true, - }, - }); - return authenticatorId; -} - -async function registerUser(page: Page, email: string, username: string) { - await page.goto("/auth/register"); - await expect(page.getByRole("heading", { name: "Register" })).toBeVisible(); - await waitForHydration(page); - await page.getByLabel("Email").fill(email); - await page.getByLabel("Username").fill(username); - await page.getByRole("checkbox").check(); - await page.getByRole("button", { name: /Register with Passkey/ }).click(); - await expect(page).toHaveURL("/", { timeout: 10000 }); -} +import { setupVirtualAuthenticator, registerUser } from "./helpers/auth"; async function setProfileVisibility(page: Page, value: "public" | "private") { await page.goto("/settings"); diff --git a/e2e/public-content.test.ts b/e2e/public-content.test.ts index 449633b..88c8106 100644 --- a/e2e/public-content.test.ts +++ b/e2e/public-content.test.ts @@ -1,31 +1,5 @@ import { test, expect, waitForHydration, type CDPSession, type Page } from "./fixtures/test"; - -// Reuses the virtual-authenticator + register helpers from auth.test.ts. -// Inlined rather than factored out to keep this file independently runnable. -async function setupVirtualAuthenticator(cdp: CDPSession) { - await cdp.send("WebAuthn.enable"); - const { authenticatorId } = await cdp.send("WebAuthn.addVirtualAuthenticator", { - options: { - protocol: "ctap2", - transport: "internal", - hasResidentKey: true, - hasUserVerification: true, - isUserVerified: true, - }, - }); - return authenticatorId; -} - -async function registerUser(page: Page, email: string, username: string) { - await page.goto("/auth/register"); - await expect(page.getByRole("heading", { name: "Register" })).toBeVisible(); - await waitForHydration(page); - await page.getByLabel("Email").fill(email); - await page.getByLabel("Username").fill(username); - await page.getByRole("checkbox").check(); - await page.getByRole("button", { name: /Register with Passkey/ }).click(); - await expect(page).toHaveURL("/", { timeout: 10000 }); -} +import { setupVirtualAuthenticator, registerUser } from "./helpers/auth"; async function createRoute(page: Page, name: string): Promise { await page.goto("/routes/new"); diff --git a/e2e/settings.test.ts b/e2e/settings.test.ts index fe7aac0..921be62 100644 --- a/e2e/settings.test.ts +++ b/e2e/settings.test.ts @@ -1,36 +1,5 @@ import { test, expect, type CDPSession, type Page } from "./fixtures/test"; - -async function setupVirtualAuthenticator(cdp: CDPSession) { - await cdp.send("WebAuthn.enable"); - const { authenticatorId } = await cdp.send("WebAuthn.addVirtualAuthenticator", { - options: { - protocol: "ctap2", - transport: "internal", - hasResidentKey: true, - hasUserVerification: true, - isUserVerified: true, - }, - }); - return authenticatorId; -} - -async function removeVirtualAuthenticator(cdp: CDPSession, authenticatorId: string) { - await cdp.send("WebAuthn.removeVirtualAuthenticator", { authenticatorId }); - await cdp.send("WebAuthn.disable"); -} - -async function registerAndLogin(page: Page, cdp: CDPSession) { - const email = `settings-${Date.now()}@example.com`; - const username = `settingsuser${Date.now()}`; - - await page.goto("/auth/register"); - await page.getByLabel("Email").fill(email); - await page.getByLabel("Username").fill(username); - await page.getByRole("button", { name: /Register with Passkey/ }).click(); - await expect(page).toHaveURL("/", { timeout: 10000 }); - - return { email, username }; -} +import { setupVirtualAuthenticator, removeVirtualAuthenticator, registerFreshUser } from "./helpers/auth"; test.describe("Account Settings", () => { test("unauthenticated user is redirected to login", async ({ page }) => { @@ -41,7 +10,7 @@ test.describe("Account Settings", () => { test("settings page loads for authenticated user", async ({ page }) => { const cdp = await page.context().newCDPSession(page); const authenticatorId = await setupVirtualAuthenticator(cdp); - await registerAndLogin(page, cdp); + await registerFreshUser(page, "settings"); await page.goto("/settings"); await expect(page.getByRole("heading", { name: "Settings" })).toBeVisible(); @@ -55,7 +24,7 @@ test.describe("Account Settings", () => { test("update display name and bio", async ({ page }) => { const cdp = await page.context().newCDPSession(page); const authenticatorId = await setupVirtualAuthenticator(cdp); - const { username } = await registerAndLogin(page, cdp); + const { username } = await registerFreshUser(page, "settings"); await page.goto("/settings"); @@ -79,7 +48,7 @@ test.describe("Account Settings", () => { test("passkey list shows registered passkey", async ({ page }) => { const cdp = await page.context().newCDPSession(page); const authenticatorId = await setupVirtualAuthenticator(cdp); - await registerAndLogin(page, cdp); + await registerFreshUser(page, "settings"); await page.goto("/settings"); // Should show the passkey registered during registration @@ -92,7 +61,7 @@ test.describe("Account Settings", () => { test("add and delete passkey from settings", async ({ page }) => { const cdp = await page.context().newCDPSession(page); const authenticatorId = await setupVirtualAuthenticator(cdp); - await registerAndLogin(page, cdp); + await registerFreshUser(page, "settings"); await page.goto("/settings"); @@ -119,7 +88,7 @@ test.describe("Account Settings", () => { test("delete last passkey shows warning", async ({ page }) => { const cdp = await page.context().newCDPSession(page); const authenticatorId = await setupVirtualAuthenticator(cdp); - await registerAndLogin(page, cdp); + await registerFreshUser(page, "settings"); await page.goto("/settings"); @@ -142,7 +111,7 @@ test.describe("Account Settings", () => { test("settings link reachable from nav when logged in", async ({ page }) => { const cdp = await page.context().newCDPSession(page); const authenticatorId = await setupVirtualAuthenticator(cdp); - const { username } = await registerAndLogin(page, cdp); + const { username } = await registerFreshUser(page, "settings"); // Settings now lives inside the avatar dropdown; opening the // dropdown reveals the menuitem. @@ -161,7 +130,7 @@ test.describe("Account Settings", () => { test("account deletion requires correct username", async ({ page }) => { const cdp = await page.context().newCDPSession(page); const authenticatorId = await setupVirtualAuthenticator(cdp); - const { username } = await registerAndLogin(page, cdp); + const { username } = await registerFreshUser(page, "settings"); await page.goto("/settings"); diff --git a/e2e/social.test.ts b/e2e/social.test.ts index 210afd9..ab4006f 100644 --- a/e2e/social.test.ts +++ b/e2e/social.test.ts @@ -1,31 +1,5 @@ import { test, expect, waitForHydration, type CDPSession, type Page } from "./fixtures/test"; - -// Inline virtual-authenticator + register helpers, mirroring the pattern -// in auth.test.ts / public-content.test.ts so this file runs standalone. -async function setupVirtualAuthenticator(cdp: CDPSession) { - await cdp.send("WebAuthn.enable"); - const { authenticatorId } = await cdp.send("WebAuthn.addVirtualAuthenticator", { - options: { - protocol: "ctap2", - transport: "internal", - hasResidentKey: true, - hasUserVerification: true, - isUserVerified: true, - }, - }); - return authenticatorId; -} - -async function registerUser(page: Page, email: string, username: string) { - await page.goto("/auth/register"); - await expect(page.getByRole("heading", { name: "Register" })).toBeVisible(); - await waitForHydration(page); - await page.getByLabel("Email").fill(email); - await page.getByLabel("Username").fill(username); - await page.getByRole("checkbox").check(); - await page.getByRole("button", { name: /Register with Passkey/ }).click(); - await expect(page).toHaveURL("/", { timeout: 10000 }); -} +import { setupVirtualAuthenticator, registerUser } from "./helpers/auth"; async function setProfileVisibility(page: Page, value: "public" | "private") { await page.goto("/settings"); diff --git a/packages/api/src/activities.ts b/packages/api/src/activities.ts index e4f2420..8da6e39 100644 --- a/packages/api/src/activities.ts +++ b/packages/api/src/activities.ts @@ -39,7 +39,11 @@ export const CreateActivityRequestSchema = z.object({ distance: z.number().optional(), }); +/** Response to POST /api/v1/activities */ +export const CreateActivityResponseSchema = z.object({ id: z.uuid() }); + export type ActivitySummary = z.infer; +export type CreateActivityResponse = z.infer; export type ActivityDetail = z.infer; export type ActivityListResponse = z.infer; export type CreateActivityRequest = z.infer; diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts index a6e14a6..3d50b31 100644 --- a/packages/api/src/index.ts +++ b/packages/api/src/index.ts @@ -33,10 +33,12 @@ export { RouteSummarySchema, RouteDetailSchema, RouteVersionSchema, RouteListResponseSchema, CreateRouteRequestSchema, UpdateRouteRequestSchema, + CreateRouteResponseSchema, ComputeRouteRequestSchema, type RouteSummary, type RouteDetail, type RouteVersion, type RouteListResponse, type CreateRouteRequest, type UpdateRouteRequest, + type CreateRouteResponse, type ComputeRouteRequest, } from "./routes.ts"; @@ -44,10 +46,10 @@ export { export { ActivitySummarySchema, ActivityDetailSchema, ActivityListResponseSchema, - CreateActivityRequestSchema, + CreateActivityRequestSchema, CreateActivityResponseSchema, type ActivitySummary, type ActivityDetail, type ActivityListResponse, - type CreateActivityRequest, + type CreateActivityRequest, type CreateActivityResponse, } from "./activities.ts"; // Uploads diff --git a/packages/api/src/routes.ts b/packages/api/src/routes.ts index dc83071..a64140e 100644 --- a/packages/api/src/routes.ts +++ b/packages/api/src/routes.ts @@ -17,7 +17,9 @@ export const RouteSummarySchema = z.object({ /** Route version info */ export const RouteVersionSchema = z.object({ + id: z.uuid(), version: z.number(), + createdBy: z.string().nullable(), changeDescription: z.string().nullable(), createdAt: z.iso.datetime(), }); @@ -64,7 +66,11 @@ export const ComputeRouteRequestSchema = z.object({ })).optional(), }); +/** Response to POST /api/v1/routes */ +export const CreateRouteResponseSchema = z.object({ id: z.uuid() }); + export type RouteSummary = z.infer; +export type CreateRouteResponse = z.infer; export type RouteVersion = z.infer; export type RouteDetail = z.infer; export type RouteListResponse = z.infer; diff --git a/packages/db/src/schema/journal.ts b/packages/db/src/schema/journal.ts index 7167368..e4b7b68 100644 --- a/packages/db/src/schema/journal.ts +++ b/packages/db/src/schema/journal.ts @@ -463,3 +463,13 @@ export const consumedJwtJti = journalSchema.table("consumed_jwt_jti", { // Sweep runs `DELETE WHERE expires_at < now()` on a daily schedule. expiresAtIdx: index("consumed_jwt_jti_expires_at_idx").on(t.expiresAt), })); + +// --------------------------------------------------------------------------- +// Canonical row types — derive from the schema, never re-declare by hand. +// API wire shapes live in @trails-cool/api; these are the database truth. +// --------------------------------------------------------------------------- + +export type RouteRow = typeof routes.$inferSelect; +export type RouteVersionRow = typeof routeVersions.$inferSelect; +export type ActivityRow = typeof activities.$inferSelect; +export type UserRow = typeof users.$inferSelect; diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index a48d332..c647a2e 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -1,7 +1,13 @@ /** - * Shared TypeScript types for trails.cool + * Shared TypeScript types for trails.cool — the Waypoint wire format + * used by both the Planner and Journal apps (Yjs document, GPX + * extensions, handoff payloads). * - * These types are used by both the Planner and Journal apps. + * Not here on purpose: database row types are derived from the Drizzle + * schema (@trails-cool/db, e.g. RouteRow), and API response shapes are + * the Zod contracts in @trails-cool/api. Earlier hand-written Route / + * Activity interfaces in this file drifted from both and had zero + * importers when they were removed. */ export interface WaypointPoiTags { @@ -26,48 +32,3 @@ export interface Waypoint { osmId?: number; poiTags?: WaypointPoiTags; } - -export interface RouteMetadata { - created: Date; - updated: Date; - owner: string; - contributors: string[]; - routingProfile: string; - dayBreaks: number[]; - distance: number; - elevation: { - gain: number; - loss: number; - }; - tags: string[]; -} - -export interface Route { - id: string; - name: string; - description: string; - gpx: string; - metadata: RouteMetadata; - plannerState?: Uint8Array; - versions: RouteVersion[]; -} - -export interface RouteVersion { - version: number; - gpx: string; - createdAt: Date; - createdBy: string; - changeDescription?: string; -} - -export interface Activity { - id: string; - routeId?: string; - name: string; - description: string; - gpx: string; - startedAt: Date; - duration: number; - photos: string[]; - participants: string[]; -} diff --git a/playwright.config.ts b/playwright.config.ts index 9b86a42..c3c16f6 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -14,6 +14,9 @@ export default defineConfig({ trace: "on-first-retry", screenshot: "only-on-failure", }, + // NOTE: specs only run if a project below matches them — a new + // e2e/*.test.ts file MUST be registered here or it silently never + // executes (settings/explore/social sat unregistered for months). projects: [ { name: "journal", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e89d44d..231be36 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -120,7 +120,7 @@ importers: version: 0.31.10 drizzle-orm: specifier: 'catalog:' - version: 0.45.2(@opentelemetry/api@1.9.1)(@types/pg@8.15.6)(expo-sqlite@56.0.4(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(pg@8.20.0)(postgres@3.4.9) + version: 0.45.2(@opentelemetry/api@1.9.1)(@types/pg@8.15.6)(expo-sqlite@56.0.4(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(pg@8.20.0)(postgres@3.4.9) drizzle-postgis: specifier: 'catalog:' version: 1.1.1 @@ -249,7 +249,7 @@ importers: version: link:../../packages/types drizzle-orm: specifier: 'catalog:' - version: 0.45.2(@opentelemetry/api@1.9.1)(@types/pg@8.15.6)(expo-sqlite@56.0.4(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(pg@8.20.0)(postgres@3.4.9) + version: 0.45.2(@opentelemetry/api@1.9.1)(@types/pg@8.15.6)(expo-sqlite@56.0.4(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(pg@8.20.0)(postgres@3.4.9) isbot: specifier: ^5.1.41 version: 5.1.41 @@ -316,19 +316,19 @@ importers: dependencies: '@expo/metro-runtime': specifier: ^56.0.14 - version: 56.0.14(@expo/log-box@56.0.12)(expo@56.0.4)(react-dom@19.2.7(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + version: 56.0.14(@expo/log-box@56.0.12)(expo@56.0.9)(react-dom@19.2.7(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) '@gorhom/bottom-sheet': specifier: ^5.2.14 - version: 5.2.14(254b00b7b51da9287b313b0a3d5005b8) + version: 5.2.14(c11bc00cccf3a49a304f3223517f7240) '@maplibre/maplibre-react-native': specifier: ^11.3.3 - version: 11.3.3(@types/geojson@7946.0.16)(@types/react@19.2.17)(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + version: 11.3.3(@types/geojson@7946.0.16)(@types/react@19.2.17)(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) '@sentry/cli': specifier: ^3.5.0 version: 3.5.0 '@sentry/react-native': specifier: ~8.13.0 - version: 8.13.0(@expo/env@2.3.0)(dotenv@16.6.1)(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + version: 8.13.0(@expo/env@2.3.0)(dotenv@16.6.1)(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) '@trails-cool/api': specifier: workspace:* version: link:../../packages/api @@ -348,59 +348,59 @@ importers: specifier: workspace:* version: link:../../packages/types expo: - specifier: ~56.0.4 - version: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + specifier: ~56.0.9 + version: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) expo-constants: specifier: ~56.0.17 - version: 56.0.17(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) + version: 56.0.17(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) expo-crypto: specifier: ~56.0.4 - version: 56.0.4(expo@56.0.4) + version: 56.0.4(expo@56.0.9) expo-dev-client: specifier: ~56.0.19 - version: 56.0.19(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) + version: 56.0.19(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) expo-device: specifier: ~56.0.4 - version: 56.0.4(expo@56.0.4) + version: 56.0.4(expo@56.0.9) expo-file-system: specifier: ~56.0.7 - version: 56.0.7(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) + version: 56.0.7(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) expo-linking: specifier: ~56.0.13 - version: 56.0.13(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + version: 56.0.13(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) expo-localization: specifier: ~56.0.6 - version: 56.0.6(expo@56.0.4)(react@19.2.7) + version: 56.0.6(expo@56.0.9)(react@19.2.7) expo-location: specifier: ~56.0.16 - version: 56.0.16(expo@56.0.4)(typescript@6.0.3) + version: 56.0.16(expo@56.0.9)(typescript@6.0.3) expo-navigation-bar: specifier: ~56.0.3 - version: 56.0.3(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + version: 56.0.3(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) expo-notifications: specifier: ~56.0.16 - version: 56.0.16(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + version: 56.0.16(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) expo-router: specifier: ~56.2.9 - version: 56.2.9(75ef990c65ada50e5bf425090b62c9b1) + version: 56.2.9(0eba4098a5195e5629f2d05bdadf3fed) expo-secure-store: specifier: ~56.0.4 - version: 56.0.4(expo@56.0.4) + version: 56.0.4(expo@56.0.9) expo-splash-screen: specifier: ~56.0.10 - version: 56.0.10(expo@56.0.4)(typescript@6.0.3) + version: 56.0.10(expo@56.0.9)(typescript@6.0.3) expo-sqlite: specifier: ~56.0.4 - version: 56.0.4(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + version: 56.0.4(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) expo-status-bar: specifier: ~56.0.4 - version: 56.0.4(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + version: 56.0.4(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) expo-system-ui: specifier: ^56.0.5 - version: 56.0.5(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) + version: 56.0.5(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) expo-web-browser: specifier: ~56.0.5 - version: 56.0.5(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) + version: 56.0.5(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) react: specifier: ^19.2.5 version: 19.2.7 @@ -411,17 +411,17 @@ importers: specifier: ^2.31.2 version: 2.31.2(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) react-native-reanimated: - specifier: ^4.4.1 - version: 4.4.1(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + specifier: ^4.3.1 + version: 4.3.1(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) react-native-safe-area-context: - specifier: ~5.8.0 - version: 5.8.0(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + specifier: ~5.7.0 + version: 5.7.0(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) react-native-screens: specifier: ~4.25.2 version: 4.25.2(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) react-native-worklets: - specifier: 0.9.1 - version: 0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + specifier: 0.8.3 + version: 0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) use-latest-callback: specifier: ^0.3.4 version: 0.3.4(react@19.2.7) @@ -440,7 +440,7 @@ importers: version: 19.2.17 jest-expo: specifier: ^56.0.4 - version: 56.0.4(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(canvas@3.2.3)(expo@56.0.4)(jest@29.7.0(@types/node@25.9.2))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + version: 56.0.4(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(canvas@3.2.3)(expo@56.0.9)(jest@29.7.0(@types/node@25.9.2))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) react-test-renderer: specifier: ^19.2.7 version: 19.2.7(react@19.2.7) @@ -503,7 +503,7 @@ importers: version: 6.0.2 drizzle-orm: specifier: 'catalog:' - version: 0.45.2(@opentelemetry/api@1.9.1)(@types/pg@8.15.6)(expo-sqlite@56.0.4(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(pg@8.20.0)(postgres@3.4.9) + version: 0.45.2(@opentelemetry/api@1.9.1)(@types/pg@8.15.6)(expo-sqlite@56.0.4(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(pg@8.20.0)(postgres@3.4.9) isbot: specifier: ^5.1.41 version: 5.1.41 @@ -591,7 +591,7 @@ importers: dependencies: drizzle-orm: specifier: 'catalog:' - version: 0.45.2(@opentelemetry/api@1.9.1)(@types/pg@8.15.6)(expo-sqlite@56.0.4(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(pg@8.20.0)(postgres@3.4.9) + version: 0.45.2(@opentelemetry/api@1.9.1)(@types/pg@8.15.6)(expo-sqlite@56.0.4(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(pg@8.20.0)(postgres@3.4.9) postgres: specifier: 'catalog:' version: 3.4.9 @@ -1734,8 +1734,8 @@ packages: '@expo-google-fonts/material-symbols@0.4.38': resolution: {integrity: sha512-IJkBtN1o8u9BW5fvSii1MyHPQ7Q0HxbWcVBvOrOzgMLpVtZw7R2w94wBTVR7kZwv3w1JNTESMmLA5Sqn1+Z36A==} - '@expo/cli@56.1.11': - resolution: {integrity: sha512-agoVjJ+cygAAjWSjk278a+UVcHDVZMKkBROkzWxpSzMK0tmRuQvtRZvAgFN/wvGZchxzs+zGur7j3txojVMVZw==} + '@expo/cli@56.1.14': + resolution: {integrity: sha512-rSH3ygjEPipEYG6dgiJ116J8KqCQ/BYKcwQDipStSh4IFWJ10RZaYP4u5B74jxfeIWjWrOeqvwB6NZfQBjaQ4Q==} hasBin: true peerDependencies: expo: '*' @@ -1794,14 +1794,14 @@ packages: '@expo/image-utils@0.10.1': resolution: {integrity: sha512-YDeefvmYdihS7Wp3ESDUVnOgOSWmj2Cczm9lVNDdm4MqQLdAKm/LPYg83HtFQPfefRlAxyHrQR/O9kIXN9C1Wg==} - '@expo/inline-modules@0.0.9': - resolution: {integrity: sha512-otMUXI4mOjytbe9OQ3i5X4SV0LP1GpzqLdr9+rdxUc1b0FjdvbTM/GkcbrwY4pU0fGSK0qFqX+jgSieyi+XbUA==} + '@expo/inline-modules@0.0.11': + resolution: {integrity: sha512-ZlIfKL61DPnW8YUTdMEjMA31xrDDV6p7Xi8rWYyhd5qXBV8MwGwjuJ7vKeaVaMjRqxJk1N9lv7zlfyvQpRCNNw==} '@expo/json-file@10.2.0': resolution: {integrity: sha512-S6XzKe3R9GQeHiUPXc3xJjOv2VJhOEwFYf7xdC2z2cUqt3kZJ9mSO877sNQloVdnW/SUCtPY3bexlM7nwq+CAQ==} - '@expo/local-build-cache-provider@56.0.7': - resolution: {integrity: sha512-GedmHPUQeLKbRZNzxZ4ZiN7NKQw65MSOMMnIqJnbXySZYYeBWg5TMuCzafE0Pt0Tsd2vmp2F7OPpsgAFGFoaBw==} + '@expo/local-build-cache-provider@56.0.8': + resolution: {integrity: sha512-UsuXwpNi57MNhzZ3be4XThc8xW6nzk3Wu37s1+2qcfZGeJcMLKDFfwO6n8YXeIiGlCsOi0Ee1rsTdgjrKt/YJQ==} '@expo/log-box@56.0.12': resolution: {integrity: sha512-budE6AGmJbpOJfGSOz+JVP3+FevElT82IEIg+ukQ4gZpW/dGO7QX1unFjanKdSaYgudBwJ4FCFGMwWhW/1tXVQ==} @@ -1811,8 +1811,8 @@ packages: react: ^19.2.5 react-native: '*' - '@expo/metro-config@56.0.12': - resolution: {integrity: sha512-L9q423WwY6eUu4A3N8OaBDECuoUNukUQKomb0/LinwzG+QkU8cBvpELXwEngP7eTt1s6LB3tXcnPp/aMvLsojw==} + '@expo/metro-config@56.0.13': + resolution: {integrity: sha512-OPyNYiex/6Ms8zT2POdIZsLhcAZYk7O+yJvpz5uG/4QRA7aiESfCy1I+0YHewMlR4P1YQeyxIrfTurs6m9xfZA==} peerDependencies: expo: '*' peerDependenciesMeta: @@ -1841,14 +1841,14 @@ packages: resolution: {integrity: sha512-QvqDBlJXa8CS2vRORJ4wEflY1m0vVI07uSJdIRgBrLxRPBcsrXxrtU7+wXRXMqfq9zLwNP9XbvRsXF2omoDylg==} engines: {node: '>=12'} - '@expo/package-manager@1.12.0': - resolution: {integrity: sha512-SWr6093nwBjn94cvElsYZNUnhvs+XtUatUz3h0vAn0IbaWG0B6l/V5ZfOBptX/xq6rMpFG5ibIf/eckLSXw8Gg==} + '@expo/package-manager@1.12.1': + resolution: {integrity: sha512-fQLiFAcFRWF53mtuLK32SUJQ1ahhrTcBZPZPedYTiUT5ha5FF+UO6bPtCc0Y/hgj0/m3HCGBAuSHjbg2kI9oPQ==} '@expo/plist@0.7.0': resolution: {integrity: sha512-vrpryU1GoqSIRNqRB2D3IjXDmzNYfiQpEF6AH/xknlD7eiYmEDt3mb26V7cLcedcPG8PY/1xWHdBXVQJfEAh6Q==} - '@expo/prebuild-config@56.0.12': - resolution: {integrity: sha512-cMI1EwpVhVaZQ92VtkRGpyvBV/iC06NMBwi+p69mwvoQTJKqswgCwYK7txFH5KaavKMmYMUaZ1twiC7jd/jDRQ==} + '@expo/prebuild-config@56.0.15': + resolution: {integrity: sha512-6GC+QjdCkzp/5wjsqgfu/B2+2yf5MyZMtzf9szIPrLt9uKhzV2PdyM0vU0kvbj1YT8weHCtO7bsrzimman0sjA==} '@expo/require-utils@56.1.3': resolution: {integrity: sha512-KyLeOn/zzQSvuPpV5YhB/FPKnpQytno4luN918bGdPDssLBoS3N/0UbC3W0rJAn9kSFu+XpfR81eABRVsSdfgQ==} @@ -1858,15 +1858,15 @@ packages: typescript: optional: true - '@expo/router-server@56.0.11': - resolution: {integrity: sha512-cyROEK3gibypiyz2QR7zm1+LMHUQEj7KQopwZ/Fip75MYrQ/SYOMRFSTvchZXEipwMRjwYecE4jsnqNKyYWFZg==} + '@expo/router-server@56.0.13': + resolution: {integrity: sha512-M2H2zHlRBKIPENCWV8Gqo3/9WANCS9vvOMCcdWfS9wD8XXMnDASFniS0bBoGwwS1qq1LIpYzX8m8wdv7Awy88g==} peerDependencies: - '@expo/metro-runtime': ^56.0.11 + '@expo/metro-runtime': ^56.0.14 expo: '*' - expo-constants: ^56.0.14 + expo-constants: ^56.0.17 expo-font: ^56.0.5 expo-router: '*' - expo-server: ^56.0.4 + expo-server: ^56.0.5 react: ^19.2.5 react-dom: ^19.2.7 react-server-dom-webpack: ~19.0.1 || ~19.1.2 || ~19.2.1 @@ -4134,12 +4134,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0 || ^8.0.0-0 - babel-preset-expo@56.0.12: - resolution: {integrity: sha512-8sOIpdzMXgx81CcCF4wwAQC8xo9akFgy32pciVjHo/4tphLOXez7wfqv5p9StgyMLQPEF4qhXG2Rkbz1QAgu2A==} + babel-preset-expo@56.0.14: + resolution: {integrity: sha512-+JKVMYf3HajO3tPRA9DlKd/VhZOPTHyTzUo2yZajfMAoQ3l5VEdGVxm2MzX4DXMNKXwsC8GOeTRx7CrO/5dBDA==} peerDependencies: '@babel/runtime': ^7.20.0 expo: '*' - expo-widgets: ^56.0.14 + expo-widgets: ^56.0.16 react-refresh: '>=0.14.0 <1.0.0' peerDependenciesMeta: '@babel/runtime': @@ -4979,8 +4979,8 @@ packages: peerDependencies: expo: '*' - expo-asset@56.0.14: - resolution: {integrity: sha512-3rN/VGt4jhNOXbAz3gdSJzC/dSmX5ozHgtG/HQTCOzuRGBd1q2lzWoZewX8aU1fiWchQg9LasiLiAJi+u8oBbQ==} + expo-asset@56.0.16: + resolution: {integrity: sha512-iIxPo6C6+/d8JxGV74ZKZbIcCz2s8//dVl7oBAj124NcPMFhzdwycFBpMqq5LUxin+lVy5cCoEjv2LD8ulnkiQ==} peerDependencies: expo: '*' react: ^19.2.5 @@ -5075,12 +5075,12 @@ packages: peerDependencies: expo: '*' - expo-modules-autolinking@56.0.12: - resolution: {integrity: sha512-Sn/LiLSL4as/YOGoatsuRQYS7rxAQHK2oYbFMT/I3iIXHLSeb0DQeuAIytVQ9ypWWck9s2krH2T6NeztyftnaA==} + expo-modules-autolinking@56.0.15: + resolution: {integrity: sha512-WqpBFwLzn7DsrUkWltIjVmAjwuI1VdQ2jRMlvk1nh2kVadwdJBkSjUBQWRifsEePNhiMT/rFOovBolUU/ARt5w==} hasBin: true - expo-modules-core@56.0.12: - resolution: {integrity: sha512-2Rf+FBU2EXe27km3m066xHu4kuUSpNT35nzk98fFxIV8B2Ah+FHub2rvAznEcGAUlDArVA2S/6+pMlHWijbicQ==} + expo-modules-core@56.0.15: + resolution: {integrity: sha512-XOXuWjtUA/xF8VjMHoRTRxuAmrAeUv8QyASX3h/CpTNS58fOt3stV8EYW7BinJPJyqwV7BZoYV83iN0p2FzyZw==} peerDependencies: react: ^19.2.5 react-native: '*' @@ -5089,8 +5089,8 @@ packages: react-native-worklets: optional: true - expo-modules-jsi@56.0.7: - resolution: {integrity: sha512-iBAj4Xeh/8HT201VVxFlmf+VBfmtQV1ZUoJdLQQENm0+j9gnD2QswZLJyNo3CmNNXl46esJeLR5lpGpYZts/zA==} + expo-modules-jsi@56.0.8: + resolution: {integrity: sha512-tXqFU1MHrf7Ctq+Pw0qOeIPDFl1W51p9nRRZy9vVUn4GNuAk1Av0vrj0SGLvcxJvDf3aGwSzr8o8dgUsX5sG0g==} peerDependencies: react-native: '*' @@ -5197,8 +5197,8 @@ packages: expo: '*' react-native: '*' - expo@56.0.4: - resolution: {integrity: sha512-ZwoOkOTwITJrFQRRO5tUsBp6NlddvjWSs3ADb+zOu1UIQWBCk9dmwmSrdFxu0P+hYnU2hk5k/Y6xq6DPLNSKzg==} + expo@56.0.9: + resolution: {integrity: sha512-Zd/fhhyC600PO4cA14r+K+DlhhUZLNaDNF6dYg+hgne2kLvg9HMnkZ902sTPZYLkW56JOXLJ5dk7hsIoH26N2A==} hasBin: true peerDependencies: '@expo/dom-webview': '*' @@ -6844,15 +6844,15 @@ packages: react: ^19.2.5 react-native: '*' - react-native-reanimated@4.4.1: - resolution: {integrity: sha512-WCVBfhLE+AYI2l4inL6PC1vcfNOfmVYRSVSBkPiD12N3jvzByipnygwVpmunyhaNqbiSEDrFYcl7cOJnbHKykw==} + react-native-reanimated@4.3.1: + resolution: {integrity: sha512-KhGsS0YkCA+gusgyzlf9hnqzVPIR398KTpqXyqq/+yYJJPAvyEEPKcxlB0xtOOXSMrR2A9uRKVARVQhZwrOh+Q==} peerDependencies: react: ^19.2.5 - react-native: 0.83 - 0.86 - react-native-worklets: 0.9.x + react-native: 0.81 - 0.85 + react-native-worklets: 0.8.x - react-native-safe-area-context@5.8.0: - resolution: {integrity: sha512-t+ZsAVzY/wWzzx34vqGbo3/as9EEESJdbyZNL7Yg5EYX+toYMtMqFoDDCvqZUi35eeGVsXc6pAaEk4edMwbuCQ==} + react-native-safe-area-context@5.7.0: + resolution: {integrity: sha512-/9/MtQz8ODphjsLdZ+GZAIcC/RtoqW9EeShf7Uvnfgm/pzYrJ75y3PV/J1wuAV1T5Dye5ygq4EAW20RoBq0ABQ==} peerDependencies: react: ^19.2.5 react-native: '*' @@ -6871,14 +6871,6 @@ packages: react: ^19.2.5 react-native: 0.81 - 0.85 - react-native-worklets@0.9.1: - resolution: {integrity: sha512-kb6lGtBI5Ap41tvBPM09Np472r2GXuJ+jRApIFy1eXBk699eChG3U+lyqRC2/wz/VDpaJAy6i5XPcceNOoH3mA==} - peerDependencies: - '@babel/core': '*' - '@react-native/metro-config': '*' - react: ^19.2.5 - react-native: 0.83 - 0.86 - react-native@0.85.3: resolution: {integrity: sha512-HN/fGC+3nZVcDNcw7gfbM/DuqZAvI9Mz+/SxuhODaua4JY0BPzhfTzWXRyTR4mRgMHmShTPpH2PYMTxvZrsdZA==} engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} @@ -8986,7 +8978,7 @@ snapshots: '@expo-google-fonts/material-symbols@0.4.38': {} - '@expo/cli@56.1.11(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-constants@56.0.17)(expo-font@56.0.5)(expo-router@56.2.9)(expo@56.0.4)(react-dom@19.2.7(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3)': + '@expo/cli@56.1.14(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-constants@56.0.17)(expo-font@56.0.5)(expo-router@56.2.9)(expo@56.0.9)(react-dom@19.2.7(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3)': dependencies: '@expo/code-signing-certificates': 0.0.6 '@expo/config': 56.0.9(typescript@6.0.3) @@ -8994,18 +8986,18 @@ snapshots: '@expo/devcert': 1.2.1 '@expo/env': 2.3.0 '@expo/image-utils': 0.10.1(typescript@6.0.3) - '@expo/inline-modules': 0.0.9(typescript@6.0.3) + '@expo/inline-modules': 0.0.11(typescript@6.0.3) '@expo/json-file': 10.2.0 - '@expo/log-box': 56.0.12(@expo/dom-webview@55.0.5)(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + '@expo/log-box': 56.0.12(@expo/dom-webview@55.0.5)(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) '@expo/metro': 56.0.0 - '@expo/metro-config': 56.0.12(expo@56.0.4)(typescript@6.0.3) + '@expo/metro-config': 56.0.13(expo@56.0.9)(typescript@6.0.3) '@expo/metro-file-map': 56.0.3 '@expo/osascript': 2.6.0 - '@expo/package-manager': 1.12.0 + '@expo/package-manager': 1.12.1 '@expo/plist': 0.7.0 - '@expo/prebuild-config': 56.0.12(typescript@6.0.3) + '@expo/prebuild-config': 56.0.15(typescript@6.0.3) '@expo/require-utils': 56.1.3(typescript@6.0.3) - '@expo/router-server': 56.0.11(@expo/metro-runtime@56.0.14)(expo-constants@56.0.17)(expo-font@56.0.5)(expo-router@56.2.9)(expo-server@56.0.5)(expo@56.0.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@expo/router-server': 56.0.13(@expo/metro-runtime@56.0.14)(expo-constants@56.0.17)(expo-font@56.0.5)(expo-router@56.2.9)(expo-server@56.0.5)(expo@56.0.9)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@expo/schema-utils': 56.0.1 '@expo/spawn-async': 1.8.0 '@expo/ws-tunnel': 1.0.6 @@ -9021,7 +9013,7 @@ snapshots: connect: 3.7.0 debug: 4.4.3 dnssd-advertise: 1.1.4 - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) expo-server: 56.0.5 fetch-nodeshim: 0.4.10 getenv: 2.0.0 @@ -9047,7 +9039,7 @@ snapshots: ws: 8.21.0 zod: 3.25.76 optionalDependencies: - expo-router: 56.2.9(02c23f4c2ab2fbb61769467c7b10daf0) + expo-router: 56.2.9(0eba4098a5195e5629f2d05bdadf3fed) react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) transitivePeerDependencies: - '@expo/dom-webview' @@ -9117,9 +9109,9 @@ snapshots: react: 19.2.7 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) - '@expo/dom-webview@55.0.5(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)': + '@expo/dom-webview@55.0.5(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)': dependencies: - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) react: 19.2.7 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) @@ -9162,7 +9154,7 @@ snapshots: - supports-color - typescript - '@expo/inline-modules@0.0.9(typescript@6.0.3)': + '@expo/inline-modules@0.0.11(typescript@6.0.3)': dependencies: '@expo/config-plugins': 56.0.8(typescript@6.0.3) transitivePeerDependencies: @@ -9174,7 +9166,7 @@ snapshots: '@babel/code-frame': 7.29.7 json5: 2.2.3 - '@expo/local-build-cache-provider@56.0.7(typescript@6.0.3)': + '@expo/local-build-cache-provider@56.0.8(typescript@6.0.3)': dependencies: '@expo/config': 56.0.9(typescript@6.0.3) chalk: 4.1.2 @@ -9182,16 +9174,16 @@ snapshots: - supports-color - typescript - '@expo/log-box@56.0.12(@expo/dom-webview@55.0.5)(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)': + '@expo/log-box@56.0.12(@expo/dom-webview@55.0.5)(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)': dependencies: - '@expo/dom-webview': 55.0.5(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + '@expo/dom-webview': 55.0.5(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) anser: 1.4.10 - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) react: 19.2.7 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) stacktrace-parser: 0.1.11 - '@expo/metro-config@56.0.12(expo@56.0.4)(typescript@6.0.3)': + '@expo/metro-config@56.0.13(expo@56.0.9)(typescript@6.0.3)': dependencies: '@babel/code-frame': 7.29.7 '@babel/core': 7.29.7 @@ -9218,7 +9210,7 @@ snapshots: postcss: 8.5.15 resolve-from: 5.0.0 optionalDependencies: - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) transitivePeerDependencies: - bufferutil - supports-color @@ -9236,11 +9228,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@expo/metro-runtime@56.0.14(@expo/log-box@56.0.12)(expo@56.0.4)(react-dom@19.2.7(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)': + '@expo/metro-runtime@56.0.14(@expo/log-box@56.0.12)(expo@56.0.9)(react-dom@19.2.7(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)': dependencies: - '@expo/log-box': 56.0.12(@expo/dom-webview@55.0.5)(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + '@expo/log-box': 56.0.12(@expo/dom-webview@55.0.5)(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) anser: 1.4.10 - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) pretty-format: 29.7.0 react: 19.2.7 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) @@ -9274,7 +9266,7 @@ snapshots: dependencies: '@expo/spawn-async': 1.8.0 - '@expo/package-manager@1.12.0': + '@expo/package-manager@1.12.1': dependencies: '@expo/json-file': 10.2.0 '@expo/spawn-async': 1.8.0 @@ -9289,7 +9281,7 @@ snapshots: base64-js: 1.5.1 xmlbuilder: 15.1.1 - '@expo/prebuild-config@56.0.12(typescript@6.0.3)': + '@expo/prebuild-config@56.0.15(typescript@6.0.3)': dependencies: '@expo/config': 56.0.9(typescript@6.0.3) '@expo/config-plugins': 56.0.8(typescript@6.0.3) @@ -9298,7 +9290,7 @@ snapshots: '@expo/json-file': 10.2.0 '@react-native/normalize-colors': 0.85.3 debug: 4.4.3 - expo-modules-autolinking: 56.0.12(typescript@6.0.3) + expo-modules-autolinking: 56.0.15(typescript@6.0.3) resolve-from: 5.0.0 semver: 7.8.2 transitivePeerDependencies: @@ -9315,17 +9307,17 @@ snapshots: transitivePeerDependencies: - supports-color - '@expo/router-server@56.0.11(@expo/metro-runtime@56.0.14)(expo-constants@56.0.17)(expo-font@56.0.5)(expo-router@56.2.9)(expo-server@56.0.5)(expo@56.0.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + '@expo/router-server@56.0.13(@expo/metro-runtime@56.0.14)(expo-constants@56.0.17)(expo-font@56.0.5)(expo-router@56.2.9)(expo-server@56.0.5)(expo@56.0.9)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: debug: 4.4.3 - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) - expo-constants: 56.0.17(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) - expo-font: 56.0.5(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo-constants: 56.0.17(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) + expo-font: 56.0.5(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) expo-server: 56.0.5 react: 19.2.7 optionalDependencies: - '@expo/metro-runtime': 56.0.14(@expo/log-box@56.0.12)(expo@56.0.4)(react-dom@19.2.7(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - expo-router: 56.2.9(02c23f4c2ab2fbb61769467c7b10daf0) + '@expo/metro-runtime': 56.0.14(@expo/log-box@56.0.12)(expo@56.0.9)(react-dom@19.2.7(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + expo-router: 56.2.9(0eba4098a5195e5629f2d05bdadf3fed) react-dom: 19.2.7(react@19.2.7) transitivePeerDependencies: - supports-color @@ -9340,9 +9332,9 @@ snapshots: '@expo/sudo-prompt@9.3.2': {} - '@expo/ui@56.0.16(9fc637273ccb566a27ff9249f8427a0a)': + '@expo/ui@56.0.16(bc055f6bd56958180c26ba54e7abf6ad)': dependencies: - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) react: 19.2.7 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) sf-symbols-typescript: 2.2.0 @@ -9350,28 +9342,11 @@ snapshots: optionalDependencies: '@babel/core': 7.29.7 react-dom: 19.2.7(react@19.2.7) - react-native-reanimated: 4.4.1(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + react-native-reanimated: 4.3.1(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) react-native-worklets: 0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) transitivePeerDependencies: - '@types/react' - '@types/react-dom' - optional: true - - '@expo/ui@56.0.16(af4fcb5d3fdc0be287b8224859a9474a)': - dependencies: - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) - react: 19.2.7 - react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) - sf-symbols-typescript: 2.2.0 - vaul: 1.1.2(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) - optionalDependencies: - '@babel/core': 7.29.7 - react-dom: 19.2.7(react@19.2.7) - react-native-reanimated: 4.4.1(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - react-native-worklets: 0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - transitivePeerDependencies: - - '@types/react' - - '@types/react-dom' '@expo/ws-tunnel@1.0.6': {} @@ -9468,14 +9443,14 @@ snapshots: lodash: 4.18.1 polyclip-ts: 0.16.8 - '@gorhom/bottom-sheet@5.2.14(254b00b7b51da9287b313b0a3d5005b8)': + '@gorhom/bottom-sheet@5.2.14(c11bc00cccf3a49a304f3223517f7240)': dependencies: '@gorhom/portal': 1.0.14(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) invariant: 2.2.4 react: 19.2.7 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) react-native-gesture-handler: 2.31.2(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - react-native-reanimated: 4.4.1(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + react-native-reanimated: 4.3.1(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) optionalDependencies: '@types/react': 19.2.17 @@ -9869,7 +9844,7 @@ snapshots: quickselect: 3.0.0 tinyqueue: 3.0.0 - '@maplibre/maplibre-react-native@11.3.3(@types/geojson@7946.0.16)(@types/react@19.2.17)(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)': + '@maplibre/maplibre-react-native@11.3.3(@types/geojson@7946.0.16)(@types/react@19.2.17)(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)': dependencies: '@maplibre/maplibre-gl-style-spec': 24.8.5 '@turf/distance': 7.3.5 @@ -9881,7 +9856,7 @@ snapshots: optionalDependencies: '@types/geojson': 7946.0.16 '@types/react': 19.2.17 - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) '@marijn/find-cluster-break@1.0.2': {} @@ -10884,7 +10859,7 @@ snapshots: '@opentelemetry/semantic-conventions': 1.40.0 '@sentry/core': 10.56.0 - '@sentry/react-native@8.13.0(@expo/env@2.3.0)(dotenv@16.6.1)(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)': + '@sentry/react-native@8.13.0(@expo/env@2.3.0)(dotenv@16.6.1)(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)': dependencies: '@sentry/babel-plugin-component-annotate': 5.3.0 '@sentry/browser': 10.53.1 @@ -10895,7 +10870,7 @@ snapshots: react: 19.2.7 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) optionalDependencies: - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) transitivePeerDependencies: - '@expo/env' - dotenv @@ -11830,7 +11805,7 @@ snapshots: '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.29.7) '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.29.7) - babel-preset-expo@56.0.12(@babel/core@7.29.7)(@babel/runtime@7.29.7)(expo@56.0.4)(react-refresh@0.14.2): + babel-preset-expo@56.0.14(@babel/core@7.29.7)(@babel/runtime@7.29.7)(expo@56.0.9)(react-refresh@0.14.2): dependencies: '@babel/generator': 7.29.7 '@babel/helper-module-imports': 7.29.7 @@ -11877,7 +11852,7 @@ snapshots: react-refresh: 0.14.2 optionalDependencies: '@babel/runtime': 7.29.7 - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) transitivePeerDependencies: - '@babel/core' - supports-color @@ -12359,11 +12334,11 @@ snapshots: esbuild: 0.25.12 tsx: 4.21.0 - drizzle-orm@0.45.2(@opentelemetry/api@1.9.1)(@types/pg@8.15.6)(expo-sqlite@56.0.4(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(pg@8.20.0)(postgres@3.4.9): + drizzle-orm@0.45.2(@opentelemetry/api@1.9.1)(@types/pg@8.15.6)(expo-sqlite@56.0.4(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(pg@8.20.0)(postgres@3.4.9): optionalDependencies: '@opentelemetry/api': 1.9.1 '@types/pg': 8.15.6 - expo-sqlite: 56.0.4(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + expo-sqlite: 56.0.4(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) pg: 8.20.0 postgres: 3.4.9 @@ -12672,95 +12647,95 @@ snapshots: jest-message-util: 29.7.0 jest-util: 29.7.0 - expo-application@56.0.3(expo@56.0.4): + expo-application@56.0.3(expo@56.0.9): dependencies: - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) - expo-asset@56.0.14(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3): + expo-asset@56.0.16(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3): dependencies: '@expo/image-utils': 0.10.1(typescript@6.0.3) - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) - expo-constants: 56.0.17(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo-constants: 56.0.17(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) react: 19.2.7 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) transitivePeerDependencies: - supports-color - typescript - expo-constants@56.0.17(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)): + expo-constants@56.0.17(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)): dependencies: '@expo/env': 2.3.0 - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) transitivePeerDependencies: - supports-color - expo-crypto@56.0.4(expo@56.0.4): + expo-crypto@56.0.4(expo@56.0.9): dependencies: - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) - expo-dev-client@56.0.19(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)): + expo-dev-client@56.0.19(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)): dependencies: - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) - expo-dev-launcher: 56.0.19(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) - expo-dev-menu: 56.0.16(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) - expo-dev-menu-interface: 56.0.1(expo@56.0.4) - expo-manifests: 56.0.4(expo@56.0.4) - expo-updates-interface: 56.0.2(expo@56.0.4) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo-dev-launcher: 56.0.19(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) + expo-dev-menu: 56.0.16(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) + expo-dev-menu-interface: 56.0.1(expo@56.0.9) + expo-manifests: 56.0.4(expo@56.0.9) + expo-updates-interface: 56.0.2(expo@56.0.9) transitivePeerDependencies: - react-native - expo-dev-launcher@56.0.19(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)): + expo-dev-launcher@56.0.19(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)): dependencies: '@expo/schema-utils': 56.0.1 - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) - expo-dev-menu: 56.0.16(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) - expo-manifests: 56.0.4(expo@56.0.4) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo-dev-menu: 56.0.16(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) + expo-manifests: 56.0.4(expo@56.0.9) react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) - expo-dev-menu-interface@56.0.1(expo@56.0.4): + expo-dev-menu-interface@56.0.1(expo@56.0.9): dependencies: - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) - expo-dev-menu@56.0.16(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)): + expo-dev-menu@56.0.16(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)): dependencies: - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) - expo-dev-menu-interface: 56.0.1(expo@56.0.4) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo-dev-menu-interface: 56.0.1(expo@56.0.9) react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) - expo-device@56.0.4(expo@56.0.4): + expo-device@56.0.4(expo@56.0.9): dependencies: - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) ua-parser-js: 0.7.41 - expo-file-system@56.0.7(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)): + expo-file-system@56.0.7(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)): dependencies: - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) - expo-font@56.0.5(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7): + expo-font@56.0.5(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7): dependencies: - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) fontfaceobserver: 2.3.0 react: 19.2.7 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) - expo-glass-effect@56.0.4(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7): + expo-glass-effect@56.0.4(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7): dependencies: - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) react: 19.2.7 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) expo-json-utils@56.0.0: {} - expo-keep-awake@56.0.3(expo@56.0.4)(react@19.2.7): + expo-keep-awake@56.0.3(expo@56.0.9)(react@19.2.7): dependencies: - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) react: 19.2.7 - expo-linking@56.0.13(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7): + expo-linking@56.0.13(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7): dependencies: - expo-constants: 56.0.17(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) + expo-constants: 56.0.17(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) invariant: 2.2.4 react: 19.2.7 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) @@ -12768,26 +12743,26 @@ snapshots: - expo - supports-color - expo-localization@56.0.6(expo@56.0.4)(react@19.2.7): + expo-localization@56.0.6(expo@56.0.9)(react@19.2.7): dependencies: - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) react: 19.2.7 rtl-detect: 1.1.2 - expo-location@56.0.16(expo@56.0.4)(typescript@6.0.3): + expo-location@56.0.16(expo@56.0.9)(typescript@6.0.3): dependencies: '@expo/image-utils': 0.10.1(typescript@6.0.3) - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) transitivePeerDependencies: - supports-color - typescript - expo-manifests@56.0.4(expo@56.0.4): + expo-manifests@56.0.4(expo@56.0.9): dependencies: - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) expo-json-utils: 56.0.0 - expo-modules-autolinking@56.0.12(typescript@6.0.3): + expo-modules-autolinking@56.0.15(typescript@6.0.3): dependencies: '@expo/require-utils': 56.1.3(typescript@6.0.3) '@expo/spawn-async': 1.8.0 @@ -12797,59 +12772,49 @@ snapshots: - supports-color - typescript - expo-modules-core@56.0.12(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7): + expo-modules-core@56.0.15(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7): dependencies: '@expo/expo-modules-macros-plugin': 0.0.9 - expo-modules-jsi: 56.0.7(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) + expo-modules-jsi: 56.0.8(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) invariant: 2.2.4 react: 19.2.7 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) optionalDependencies: react-native-worklets: 0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - expo-modules-core@56.0.12(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7): - dependencies: - '@expo/expo-modules-macros-plugin': 0.0.9 - expo-modules-jsi: 56.0.7(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) - invariant: 2.2.4 - react: 19.2.7 - react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) - optionalDependencies: - react-native-worklets: 0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - - expo-modules-jsi@56.0.7(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)): + expo-modules-jsi@56.0.8(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)): dependencies: react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) - expo-navigation-bar@56.0.3(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7): + expo-navigation-bar@56.0.3(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7): dependencies: debug: 4.4.3 - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) react: 19.2.7 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) transitivePeerDependencies: - supports-color - expo-notifications@56.0.16(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3): + expo-notifications@56.0.16(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3): dependencies: '@expo/image-utils': 0.10.1(typescript@6.0.3) abort-controller: 3.0.0 badgin: 1.2.3 - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) - expo-application: 56.0.3(expo@56.0.4) - expo-constants: 56.0.17(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo-application: 56.0.3(expo@56.0.9) + expo-constants: 56.0.17(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) react: 19.2.7 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) transitivePeerDependencies: - supports-color - typescript - expo-router@56.2.9(02c23f4c2ab2fbb61769467c7b10daf0): + expo-router@56.2.9(0eba4098a5195e5629f2d05bdadf3fed): dependencies: - '@expo/log-box': 56.0.12(@expo/dom-webview@55.0.5)(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - '@expo/metro-runtime': 56.0.14(@expo/log-box@56.0.12)(expo@56.0.4)(react-dom@19.2.7(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + '@expo/log-box': 56.0.12(@expo/dom-webview@55.0.5)(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + '@expo/metro-runtime': 56.0.14(@expo/log-box@56.0.12)(expo@56.0.9)(react-dom@19.2.7(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) '@expo/schema-utils': 56.0.1 - '@expo/ui': 56.0.16(9fc637273ccb566a27ff9249f8427a0a) + '@expo/ui': 56.0.16(bc055f6bd56958180c26ba54e7abf6ad) '@radix-ui/react-slot': 1.2.5(@types/react@19.2.17)(react@19.2.7) '@radix-ui/react-tabs': 1.1.14(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@react-native-masked-view/masked-view': 0.3.2(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) @@ -12859,12 +12824,12 @@ snapshots: color: 4.2.3 debug: 4.4.3 escape-string-regexp: 4.0.0 - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) - expo-constants: 56.0.17(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) - expo-glass-effect: 56.0.4(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - expo-linking: 56.0.13(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo-constants: 56.0.17(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) + expo-glass-effect: 56.0.4(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + expo-linking: 56.0.13(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) expo-server: 56.0.5 - expo-symbols: 56.0.6(expo-font@56.0.5)(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + expo-symbols: 56.0.6(expo-font@56.0.5)(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) fast-deep-equal: 3.1.3 invariant: 2.2.4 nanoid: 3.3.12 @@ -12873,8 +12838,8 @@ snapshots: react-fast-compare: 3.2.2 react-is: 19.2.7 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) - react-native-drawer-layout: 4.2.4(7521adc8cc95790b0992d7df2840e960) - react-native-safe-area-context: 5.8.0(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + react-native-drawer-layout: 4.2.4(bd529857cac974b7a9d1ae45506ef437) + react-native-safe-area-context: 5.7.0(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) react-native-screens: 4.25.2(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) server-only: 0.0.1 sf-symbols-typescript: 2.2.0 @@ -12884,58 +12849,7 @@ snapshots: '@testing-library/react-native': 13.3.3(jest@29.7.0(@types/node@25.9.2))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react-test-renderer@19.2.7(react@19.2.7))(react@19.2.7) react-dom: 19.2.7(react@19.2.7) react-native-gesture-handler: 2.31.2(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - react-native-reanimated: 4.4.1(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - transitivePeerDependencies: - - '@babel/core' - - '@testing-library/dom' - - '@types/react' - - '@types/react-dom' - - expo-font - - react-native-worklets - - supports-color - optional: true - - expo-router@56.2.9(75ef990c65ada50e5bf425090b62c9b1): - dependencies: - '@expo/log-box': 56.0.12(@expo/dom-webview@55.0.5)(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - '@expo/metro-runtime': 56.0.14(@expo/log-box@56.0.12)(expo@56.0.4)(react-dom@19.2.7(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - '@expo/schema-utils': 56.0.1 - '@expo/ui': 56.0.16(af4fcb5d3fdc0be287b8224859a9474a) - '@radix-ui/react-slot': 1.2.5(@types/react@19.2.17)(react@19.2.7) - '@radix-ui/react-tabs': 1.1.14(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) - '@react-native-masked-view/masked-view': 0.3.2(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - '@testing-library/jest-dom': 6.9.1 - '@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.1) - client-only: 0.0.1 - color: 4.2.3 - debug: 4.4.3 - escape-string-regexp: 4.0.0 - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) - expo-constants: 56.0.17(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) - expo-glass-effect: 56.0.4(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - expo-linking: 56.0.13(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - expo-server: 56.0.5 - expo-symbols: 56.0.6(expo-font@56.0.5)(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - fast-deep-equal: 3.1.3 - invariant: 2.2.4 - nanoid: 3.3.12 - query-string: 7.1.3 - react: 19.2.7 - react-fast-compare: 3.2.2 - react-is: 19.2.7 - react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) - react-native-drawer-layout: 4.2.4(e0aaa35bca91a465bf77aa4cb387bae6) - react-native-safe-area-context: 5.8.0(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - react-native-screens: 4.25.2(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - server-only: 0.0.1 - sf-symbols-typescript: 2.2.0 - shallowequal: 1.1.0 - vaul: 1.1.2(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) - optionalDependencies: - '@testing-library/react-native': 13.3.3(jest@29.7.0(@types/node@25.9.2))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react-test-renderer@19.2.7(react@19.2.7))(react@19.2.7) - react-dom: 19.2.7(react@19.2.7) - react-native-gesture-handler: 2.31.2(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - react-native-reanimated: 4.4.1(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + react-native-reanimated: 4.3.1(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) transitivePeerDependencies: - '@babel/core' - '@testing-library/dom' @@ -12945,132 +12859,91 @@ snapshots: - react-native-worklets - supports-color - expo-secure-store@56.0.4(expo@56.0.4): + expo-secure-store@56.0.4(expo@56.0.9): dependencies: - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) expo-server@56.0.5: {} - expo-splash-screen@56.0.10(expo@56.0.4)(typescript@6.0.3): + expo-splash-screen@56.0.10(expo@56.0.9)(typescript@6.0.3): dependencies: '@expo/config-plugins': 56.0.8(typescript@6.0.3) '@expo/image-utils': 0.10.1(typescript@6.0.3) - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) xml2js: 0.6.0 transitivePeerDependencies: - supports-color - typescript - expo-sqlite@56.0.4(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7): + expo-sqlite@56.0.4(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7): dependencies: await-lock: 2.2.2 - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) react: 19.2.7 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) - expo-status-bar@56.0.4(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7): + expo-status-bar@56.0.4(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7): dependencies: - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) react: 19.2.7 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) - expo-symbols@56.0.6(expo-font@56.0.5)(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7): + expo-symbols@56.0.6(expo-font@56.0.5)(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7): dependencies: '@expo-google-fonts/material-symbols': 0.4.38 - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) - expo-font: 56.0.5(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo-font: 56.0.5(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) react: 19.2.7 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) sf-symbols-typescript: 2.2.0 - expo-system-ui@56.0.5(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)): + expo-system-ui@56.0.5(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)): dependencies: '@react-native/normalize-colors': 0.85.3 debug: 4.4.3 - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) transitivePeerDependencies: - supports-color - expo-updates-interface@56.0.2(expo@56.0.4): + expo-updates-interface@56.0.2(expo@56.0.9): dependencies: - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) - expo-web-browser@56.0.5(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)): + expo-web-browser@56.0.5(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)): dependencies: - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) - expo@56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3): + expo@56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3): dependencies: '@babel/runtime': 7.29.7 - '@expo/cli': 56.1.11(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-constants@56.0.17)(expo-font@56.0.5)(expo-router@56.2.9)(expo@56.0.4)(react-dom@19.2.7(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + '@expo/cli': 56.1.14(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-constants@56.0.17)(expo-font@56.0.5)(expo-router@56.2.9)(expo@56.0.9)(react-dom@19.2.7(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) '@expo/config': 56.0.9(typescript@6.0.3) '@expo/config-plugins': 56.0.8(typescript@6.0.3) '@expo/devtools': 56.0.2(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) '@expo/fingerprint': 0.19.4 - '@expo/local-build-cache-provider': 56.0.7(typescript@6.0.3) - '@expo/log-box': 56.0.12(@expo/dom-webview@55.0.5)(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + '@expo/local-build-cache-provider': 56.0.8(typescript@6.0.3) + '@expo/log-box': 56.0.12(@expo/dom-webview@55.0.5)(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) '@expo/metro': 56.0.0 - '@expo/metro-config': 56.0.12(expo@56.0.4)(typescript@6.0.3) + '@expo/metro-config': 56.0.13(expo@56.0.9)(typescript@6.0.3) '@ungap/structured-clone': 1.3.1 - babel-preset-expo: 56.0.12(@babel/core@7.29.7)(@babel/runtime@7.29.7)(expo@56.0.4)(react-refresh@0.14.2) - expo-asset: 56.0.14(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) - expo-constants: 56.0.17(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) - expo-file-system: 56.0.7(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) - expo-font: 56.0.5(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - expo-keep-awake: 56.0.3(expo@56.0.4)(react@19.2.7) - expo-modules-autolinking: 56.0.12(typescript@6.0.3) - expo-modules-core: 56.0.12(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + babel-preset-expo: 56.0.14(@babel/core@7.29.7)(@babel/runtime@7.29.7)(expo@56.0.9)(react-refresh@0.14.2) + expo-asset: 56.0.16(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo-constants: 56.0.17(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) + expo-file-system: 56.0.7(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) + expo-font: 56.0.5(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + expo-keep-awake: 56.0.3(expo@56.0.9)(react@19.2.7) + expo-modules-autolinking: 56.0.15(typescript@6.0.3) + expo-modules-core: 56.0.15(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) pretty-format: 29.7.0 react: 19.2.7 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) react-refresh: 0.14.2 whatwg-url-minimum: 0.1.2 optionalDependencies: - '@expo/dom-webview': 55.0.5(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - '@expo/metro-runtime': 56.0.14(@expo/log-box@56.0.12)(expo@56.0.4)(react-dom@19.2.7(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - react-dom: 19.2.7(react@19.2.7) - transitivePeerDependencies: - - '@babel/core' - - bufferutil - - expo-router - - expo-widgets - - react-native-worklets - - react-server-dom-webpack - - supports-color - - typescript - - utf-8-validate - - expo@56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3): - dependencies: - '@babel/runtime': 7.29.7 - '@expo/cli': 56.1.11(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-constants@56.0.17)(expo-font@56.0.5)(expo-router@56.2.9)(expo@56.0.4)(react-dom@19.2.7(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) - '@expo/config': 56.0.9(typescript@6.0.3) - '@expo/config-plugins': 56.0.8(typescript@6.0.3) - '@expo/devtools': 56.0.2(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - '@expo/fingerprint': 0.19.4 - '@expo/local-build-cache-provider': 56.0.7(typescript@6.0.3) - '@expo/log-box': 56.0.12(@expo/dom-webview@55.0.5)(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - '@expo/metro': 56.0.0 - '@expo/metro-config': 56.0.12(expo@56.0.4)(typescript@6.0.3) - '@ungap/structured-clone': 1.3.1 - babel-preset-expo: 56.0.12(@babel/core@7.29.7)(@babel/runtime@7.29.7)(expo@56.0.4)(react-refresh@0.14.2) - expo-asset: 56.0.14(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) - expo-constants: 56.0.17(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) - expo-file-system: 56.0.7(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7)) - expo-font: 56.0.5(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - expo-keep-awake: 56.0.3(expo@56.0.4)(react@19.2.7) - expo-modules-autolinking: 56.0.12(typescript@6.0.3) - expo-modules-core: 56.0.12(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - pretty-format: 29.7.0 - react: 19.2.7 - react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) - react-refresh: 0.14.2 - whatwg-url-minimum: 0.1.2 - optionalDependencies: - '@expo/dom-webview': 55.0.5(expo@56.0.4)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - '@expo/metro-runtime': 56.0.14(@expo/log-box@56.0.12)(expo@56.0.4)(react-dom@19.2.7(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + '@expo/dom-webview': 55.0.5(expo@56.0.9)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + '@expo/metro-runtime': 56.0.14(@expo/log-box@56.0.12)(expo@56.0.9)(react-dom@19.2.7(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) react-dom: 19.2.7(react@19.2.7) transitivePeerDependencies: - '@babel/core' @@ -13682,7 +13555,7 @@ snapshots: jest-mock: 29.7.0 jest-util: 29.7.0 - jest-expo@56.0.4(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(canvas@3.2.3)(expo@56.0.4)(jest@29.7.0(@types/node@25.9.2))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7): + jest-expo@56.0.4(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(canvas@3.2.3)(expo@56.0.9)(jest@29.7.0(@types/node@25.9.2))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7): dependencies: '@jest/create-cache-key-function': 29.7.0 '@jest/globals': 29.7.0 @@ -13699,7 +13572,7 @@ snapshots: server-only: 0.0.1 stacktrace-js: 2.0.2 optionalDependencies: - expo: 56.0.4(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + expo: 56.0.9(@babel/core@7.29.7)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@56.0.14)(expo-router@56.2.9)(react-dom@19.2.7(react@19.2.7))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)(typescript@6.0.3) transitivePeerDependencies: - '@babel/core' - bufferutil @@ -14999,23 +14872,13 @@ snapshots: react: 19.2.7 react-dom: 19.2.7(react@19.2.7) - react-native-drawer-layout@4.2.4(7521adc8cc95790b0992d7df2840e960): + react-native-drawer-layout@4.2.4(bd529857cac974b7a9d1ae45506ef437): dependencies: color: 4.2.3 react: 19.2.7 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) react-native-gesture-handler: 2.31.2(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - react-native-reanimated: 4.4.1(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - use-latest-callback: 0.2.6(react@19.2.7) - optional: true - - react-native-drawer-layout@4.2.4(e0aaa35bca91a465bf77aa4cb387bae6): - dependencies: - color: 4.2.3 - react: 19.2.7 - react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) - react-native-gesture-handler: 2.31.2(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - react-native-reanimated: 4.4.1(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + react-native-reanimated: 4.3.1(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) use-latest-callback: 0.2.6(react@19.2.7) react-native-gesture-handler@2.31.2(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7): @@ -15032,24 +14895,15 @@ snapshots: react: 19.2.7 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) - react-native-reanimated@4.4.1(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7): + react-native-reanimated@4.3.1(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7): dependencies: react: 19.2.7 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) react-native-is-edge-to-edge: 1.3.1(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) react-native-worklets: 0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) semver: 7.8.2 - optional: true - react-native-reanimated@4.4.1(react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7): - dependencies: - react: 19.2.7 - react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) - react-native-is-edge-to-edge: 1.3.1(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - react-native-worklets: 0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) - semver: 7.8.2 - - react-native-safe-area-context@5.8.0(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7): + react-native-safe-area-context@5.7.0(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7): dependencies: react: 19.2.7 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) @@ -15080,27 +14934,6 @@ snapshots: semver: 7.8.2 transitivePeerDependencies: - supports-color - optional: true - - react-native-worklets@0.9.1(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7): - dependencies: - '@babel/core': 7.29.7 - '@babel/plugin-transform-arrow-functions': 7.29.7(@babel/core@7.29.7) - '@babel/plugin-transform-class-properties': 7.29.7(@babel/core@7.29.7) - '@babel/plugin-transform-classes': 7.29.7(@babel/core@7.29.7) - '@babel/plugin-transform-nullish-coalescing-operator': 7.29.7(@babel/core@7.29.7) - '@babel/plugin-transform-optional-chaining': 7.29.7(@babel/core@7.29.7) - '@babel/plugin-transform-shorthand-properties': 7.29.7(@babel/core@7.29.7) - '@babel/plugin-transform-template-literals': 7.29.7(@babel/core@7.29.7) - '@babel/plugin-transform-unicode-regex': 7.29.7(@babel/core@7.29.7) - '@babel/preset-typescript': 7.29.7(@babel/core@7.29.7) - '@react-native/metro-config': 0.85.3(@babel/core@7.29.7) - convert-source-map: 2.0.0 - react: 19.2.7 - react-native: 0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7) - semver: 7.8.2 - transitivePeerDependencies: - - supports-color react-native@0.85.3(@babel/core@7.29.7)(@react-native/jest-preset@0.85.3(@babel/core@7.29.7)(react@19.2.7))(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.7): dependencies: