some key stuff

This commit is contained in:
EthanShoeDev
2025-09-12 01:37:17 -04:00
parent 92882e276e
commit d9879d7a87
8 changed files with 509 additions and 431 deletions

View File

@@ -1,3 +0,0 @@
https://github.com/dylankenneally/react-native-ssh-sftp
https://xtermjs.org/
https://docs.expo.dev/versions/latest/sdk/webview/

View File

@@ -33,20 +33,20 @@
"@react-navigation/native": "^7.1.8",
"@tanstack/react-form": "^1.19.5",
"@tanstack/react-query": "^5.87.1",
"expo": "54.0.1",
"expo-build-properties": "~1.0.7",
"expo": "54.0.2",
"expo-build-properties": "~1.0.8",
"expo-constants": "~18.0.8",
"expo-font": "~14.0.7",
"expo-haptics": "~15.0.6",
"expo-image": "~3.0.7",
"expo-linking": "~8.0.7",
"expo-router": "6.0.0",
"expo-secure-store": "~15.0.6",
"expo-splash-screen": "~31.0.8",
"expo-status-bar": "~3.0.7",
"expo-symbols": "~1.0.6",
"expo-font": "~14.0.8",
"expo-haptics": "~15.0.7",
"expo-image": "~3.0.8",
"expo-linking": "~8.0.8",
"expo-router": "6.0.1",
"expo-secure-store": "~15.0.7",
"expo-splash-screen": "~31.0.9",
"expo-status-bar": "~3.0.8",
"expo-symbols": "~1.0.7",
"expo-system-ui": "~6.0.7",
"expo-web-browser": "~15.0.6",
"expo-web-browser": "~15.0.7",
"react": "19.1.0",
"react-dom": "19.1.0",
"react-native": "0.81.4",

View File

@@ -1,11 +1,18 @@
import SSHClient, { PtyType } from '@dylankenneally/react-native-ssh-sftp';
import { Picker } from '@react-native-picker/picker';
// Removed inline Picker usage in favor of modal selection
import { useStore } from '@tanstack/react-form';
import { useQuery } from '@tanstack/react-query';
import { useRouter } from 'expo-router';
import React from 'react';
import { Pressable, ScrollView, StyleSheet, Text, View } from 'react-native';
import { useAppForm, withFieldGroup } from '../components/form-components';
import {
Pressable,
ScrollView,
StyleSheet,
Text,
View,
Switch,
} from 'react-native';
import { useAppForm, useFieldContext } from '../components/form-components';
import { KeyManagerModal } from '../components/key-manager-modal';
import {
type ConnectionDetails,
@@ -26,44 +33,57 @@ const defaultValues: ConnectionDetails = {
export default function Index() {
const router = useRouter();
const storedConnectionsQuery = useQuery(
secretsManager.connections.query.list,
);
// const storedConnectionsQuery = useQuery(
// secretsManager.connections.query.list,
// );
const preferredStoredConnection = storedConnectionsQuery.data?.[0];
const connectionForm = useAppForm({
// https://tanstack.com/form/latest/docs/framework/react/guides/async-initial-values
defaultValues: preferredStoredConnection
? preferredStoredConnection.value
: defaultValues,
defaultValues,
validators: {
onChange: connectionDetailsSchema,
onSubmitAsync: async ({ value }) => {
try {
console.log('Connecting to SSH server...');
const effective = await (async () => {
if (value.security.type === 'password') return value;
if (value.security.keyId) return value;
const keys =
await secretsManager.keys.utils.listEntriesWithValues();
const def = keys.find((k) => k.metadata?.isDefault);
const pick = def ?? keys[0];
if (pick) {
return {
...value,
security: { type: 'key', keyId: pick.id },
} as ConnectionDetails;
}
return value;
})();
const sshClientConnection = await (async () => {
if (value.security.type === 'password') {
if (effective.security.type === 'password') {
return await SSHClient.connectWithPassword(
value.host,
value.port,
value.username,
value.security.password,
effective.host,
effective.port,
effective.username,
effective.security.password,
);
}
const privateKey = await secretsManager.keys.utils.getPrivateKey(
value.security.keyId,
effective.security.keyId,
);
return await SSHClient.connectWithKey(
value.host,
value.port,
value.username,
effective.host,
effective.port,
effective.username,
privateKey.value,
);
})();
await secretsManager.connections.utils.upsertConnection({
id: 'default',
details: value,
details: effective,
priority: 0,
});
await sshClientConnection.startShell(PtyType.XTERM);
@@ -143,10 +163,18 @@ export default function Index() {
</connectionForm.AppField>
<connectionForm.AppField name="security.type">
{(field) => (
<field.PickerField label="Security Type">
<Picker.Item label="Password" value="password" />
<Picker.Item label="Key" value="key" />
</field.PickerField>
<View style={styles.inputGroup}>
<Text style={styles.label}>Use Private Key</Text>
<View>
{/* Map boolean switch to discriminated union */}
<Switch
value={field.state.value === 'key'}
onValueChange={(val) => {
field.handleChange(val ? 'key' : 'password');
}}
/>
</View>
</View>
)}
</connectionForm.AppField>
{securityType === 'password' ? (
@@ -161,13 +189,9 @@ export default function Index() {
)}
</connectionForm.AppField>
) : (
<KeyPairSection
form={connectionForm}
fields={{
keyId: 'security.keyId',
type: 'security.type',
}}
/>
<connectionForm.AppField name="security.keyId">
{() => <KeyIdPicker />}
</connectionForm.AppField>
)}
<View style={styles.actions}>
@@ -209,68 +233,60 @@ export default function Index() {
);
}
// Yes, HOCs are weird. Its what the docs recommend.
// https://tanstack.com/form/v1/docs/framework/react/guides/form-composition#withform-faq
const KeyPairSection = withFieldGroup({
defaultValues: {
type: 'key',
keyId: '',
},
props: {},
render: function Render({ group }) {
function KeyIdPicker() {
const field = useFieldContext<string>();
const hasInteractedRef = React.useRef(false);
const [manualVisible, setManualVisible] = React.useState(false);
const listPrivateKeysQuery = useQuery(secretsManager.keys.query.list);
const [showManager, setShowManager] = React.useState(false);
const defaultPick = React.useMemo(() => {
const keys = listPrivateKeysQuery.data ?? [];
const def = keys.find((k) => k.metadata?.isDefault);
return def ?? keys[0];
}, [listPrivateKeysQuery.data]);
const keys = listPrivateKeysQuery.data ?? [];
const computedSelectedId = field.state.value ?? defaultPick?.id;
const selected = keys.find((k) => k.id === computedSelectedId);
const display = selected ? (selected.metadata?.label ?? selected.id) : 'None';
const isEmpty = (listPrivateKeysQuery.data?.length ?? 0) === 0;
const visible = manualVisible || (!hasInteractedRef.current && isEmpty);
return (
<group.AppField name="keyId">
{(field) => {
if (listPrivateKeysQuery.isLoading) {
return <Text style={styles.mutedText}>Loading keys...</Text>;
}
if (listPrivateKeysQuery.isError) {
return (
<Text style={styles.errorText}>
Error: {listPrivateKeysQuery.error.message}
</Text>
);
}
return (
<>
<field.PickerField label="Key">
{listPrivateKeysQuery.data?.map((key) => {
const label = `${key.metadata?.label ?? key.id}${
key.metadata?.isDefault ? ' • Default' : ''
}`;
return (
<Picker.Item key={key.id} label={label} value={key.id} />
);
})}
</field.PickerField>
<View style={styles.inputGroup}>
<Text style={styles.label}>Private Key</Text>
<Pressable
style={styles.secondaryButton}
onPress={() => setShowManager(true)}
style={[styles.input, { justifyContent: 'center' }]}
onPress={() => {
hasInteractedRef.current = true;
setManualVisible(true);
}}
>
<Text style={styles.secondaryButtonText}>Manage Keys</Text>
<Text style={{ color: '#E5E7EB' }}>{display}</Text>
</Pressable>
{!selected && (
<Text style={styles.mutedText}>
Open Key Manager to add/select a key
</Text>
)}
</View>
<KeyManagerModal
visible={showManager}
visible={visible}
selectedKeyId={computedSelectedId}
onSelect={(id) => {
hasInteractedRef.current = true;
field.handleChange(id);
}}
onClose={() => {
setShowManager(false);
if (!field.state.value && listPrivateKeysQuery.data) {
const def = listPrivateKeysQuery.data.find(
(k) => k.metadata?.isDefault,
);
if (def) field.handleChange(def.id);
}
hasInteractedRef.current = true;
setManualVisible(false);
}}
/>
</>
);
}}
</group.AppField>
);
},
});
}
function PreviousConnectionsSection(props: {
onSelect: (connection: ConnectionDetails) => void;

View File

@@ -14,6 +14,8 @@ import { secretsManager } from '../lib/secrets-manager';
export function KeyManagerModal(props: {
visible: boolean;
onClose: () => void;
selectedKeyId?: string;
onSelect?: (keyId: string) => void;
}) {
const listKeysQuery = useQuery(secretsManager.keys.query.list);
@@ -96,6 +98,11 @@ export function KeyManagerModal(props: {
<KeyRow
key={k.id}
entry={k}
selected={props.selectedKeyId === k.id}
onSelect={() => {
if (props.onSelect) props.onSelect(k.id);
props.onClose();
}}
onDelete={() => handleDelete(k.id)}
onSetDefault={() => handleSetDefault(k.id)}
/>
@@ -114,6 +121,8 @@ function KeyRow(props: {
entry: Awaited<
ReturnType<typeof secretsManager.keys.utils.listEntriesWithValues>
>[number];
selected?: boolean;
onSelect?: () => void;
onDelete: () => void;
onSetDefault: () => void;
}) {
@@ -141,7 +150,7 @@ function KeyRow(props: {
}
return (
<View style={styles.row}>
<Pressable style={styles.row} onPress={props.onSelect}>
<View style={{ flex: 1, marginRight: 8 }}>
<Text style={styles.rowTitle}>
{(props.entry.metadata?.label ?? props.entry.id) +
@@ -159,6 +168,13 @@ function KeyRow(props: {
) : null}
</View>
<View style={styles.rowActions}>
{props.onSelect ? (
<View style={styles.radioWrap}>
<View
style={[styles.radio, props.selected && styles.radioSelected]}
/>
</View>
) : null}
{!isDefault ? (
<Pressable
style={styles.secondaryButton}
@@ -192,7 +208,7 @@ function KeyRow(props: {
<Text style={styles.dangerButtonText}>Delete</Text>
</Pressable>
</View>
</View>
</Pressable>
);
}
@@ -292,6 +308,23 @@ const styles = StyleSheet.create({
gap: 6,
alignItems: 'flex-end',
},
radioWrap: {
justifyContent: 'center',
alignItems: 'center',
marginRight: 6,
},
radio: {
width: 16,
height: 16,
borderRadius: 16,
borderColor: '#2A3655',
borderWidth: 2,
backgroundColor: 'transparent',
},
radioSelected: {
backgroundColor: '#2563EB',
borderColor: '#2563EB',
},
secondaryButton: {
backgroundColor: 'transparent',
borderWidth: 1,

View File

@@ -1,47 +1,64 @@
# Key Management UX & Tech Plan
Goal: Make SSH private key management clear and consistent: selecting a key, generating/importing keys, renaming, deleting, and setting a default — all with a unified, styled UI and predictable data semantics.
Goal: Make SSH private key management clear and consistent: selecting a key,
generating/importing keys, renaming, deleting, and setting a default — all with
a unified, styled UI and predictable data semantics.
## Current State (Summary)
- Security type uses a `Picker` in the main form; defaults to `password`.
- Switching to key auth shows a `Picker` for keys (awkward empty state) and a “Manage Keys” button.
- Switching to key auth shows a `Picker` for keys (awkward empty state) and a
“Manage Keys” button.
- Keys can be generated, renamed, deleted, set as default inside a modal.
- Storage uses a chunked manifest in `expo-secure-store` (works for >2KB values) with metadata (`priority`, `createdAtMs`, `label?`, `isDefault?`).
- All key mutations go through one `upsertPrivateKey` that invalidates the React Query `keys` query.
- Storage uses a chunked manifest in `expo-secure-store` (works for >2KB values)
with metadata (`priority`, `createdAtMs`, `label?`, `isDefault?`).
- All key mutations go through one `upsertPrivateKey` that invalidates the React
Query `keys` query.
## UX Objectives
- Remove the inline key `Picker`; select a key within the Key Manager modal.
- Replace the security type `Picker` with a simple toggle/switch.
- Handle the “no keys yet” case gracefully by auto-opening the modal when user chooses key auth.
- Keep visual styling consistent with text inputs (button heights, paddings, colors).
- Prepare the modal for importing private keys (paste text or select file) in a future phase.
- Handle the “no keys yet” case gracefully by auto-opening the modal when user
chooses key auth.
- Keep visual styling consistent with text inputs (button heights, paddings,
colors).
- Prepare the modal for importing private keys (paste text or select file) in a
future phase.
## Phase 1 — Selection UX + Styling
1) Replace security type `Picker` with toggle
1. Replace security type `Picker` with toggle
- Use a `SwitchField` (styled like inputs) labeled "Use Private Key".
- Value mapping: off → password; on → key.
- When toggled ON and there is no selected key and no keys exist, auto-open Key Manager.
- When toggled ON and there is no selected key and no keys exist, auto-open
Key Manager.
2) Remove inline key `Picker`
- Replace with a read-only field styled like inputs: label: "Private Key", value: current key label or "None".
2. Remove inline key `Picker`
- Replace with a read-only field styled like inputs: label: "Private Key",
value: current key label or "None".
- The field is a `Pressable` that opens the Key Manager for selection.
- Disabled state (no keys): show "None" with hint "Open Key Manager to add a key".
- Disabled state (no keys): show "None" with hint "Open Key Manager to add a
key".
3) Key Manager: add selection mode
3. Key Manager: add selection mode
- Add a radio-style control on each row to select the key for this session.
- Modal accepts an optional `selectedKeyId` and `onSelect(id)` callback.
- When user taps a row (or radio), call `onSelect(id)` and close the modal.
- Continue to support generate/rename/delete/set-default; selection should update live.
- Continue to support generate/rename/delete/set-default; selection should
update live.
4) Styling parity
- Ensure the read-only "Private Key" field height/padding matches `TextField`.
4. Styling parity
- Ensure the read-only "Private Key" field height/padding matches
`TextField`.
- Use consistent typography/colors for labels, values, and hints.
5) Empty states
5. Empty states
- If no keys: show a friendly empty state in modal with primary action
"Generate New Key" and secondary "Import Key" (Import lands in Phase 2).
Deliverables (Phase 1)
- Update `apps/mobile/src/app/index.tsx` form:
- Toggle for auth type.
- Read-only key field that opens modal.
@@ -50,53 +67,75 @@ Deliverables (Phase 1)
- Keep existing generate/rename/delete/set-default.
## Phase 2 — Import Keys
1) Import entry points in modal
- Add "Import" button/menu in the modal header or as secondary action in empty state.
1. Import entry points in modal
- Add "Import" button/menu in the modal header or as secondary action in
empty state.
- Options:
- Paste PEM text (multiline input)
- Pick a file (use `expo-document-picker`)
2) Validation + Storage
- Validate PEM or OpenSSH formats; detect supported types (rsa/ecdsa/ed25519/ed448/dsa).
- Optional passphrase field (store encrypted if supported by library; otherwise prompt each use — confirm feasibility with SSH lib).
- On success, call the single `upsertPrivateKey({ keyId, value, metadata })` and close import flow.
2. Validation + Storage
- Validate PEM or OpenSSH formats; detect supported types
(rsa/ecdsa/ed25519/ed448/dsa).
- Optional passphrase field (store encrypted if supported by library;
otherwise prompt each use — confirm feasibility with SSH lib).
- On success, call the single `upsertPrivateKey({ keyId, value, metadata })`
and close import flow.
3) UX details
3. UX details
- Show parse/validation errors inline.
- Set initial `label` from filename (file import) or "Imported Key" (paste); allow editing label on success or selection.
- Set initial `label` from filename (file import) or "Imported Key" (paste);
allow editing label on success or selection.
Deliverables (Phase 2)
- Modal import screen(s) with paste/file flows.
- PEM validation utility and error handling.
## Phase 3 — Data Model + Semantics
1) Default key semantics
- Guarantee exactly one default key at most by flipping `isDefault` on upsert when `isDefault === true`.
- Consider: separate lightweight persistent "defaultId" in manifest root to avoid iterating all keys on default change.
2) Robustness
- Add safety around manifest chunk growth: if `manifestChunkSize + newEntrySize > sizeLimit`, create a new chunk.
- Ensure `createdAtMs` is preserved across upserts (done) and add `modifiedAtMs` if useful.
1. Default key semantics
- Guarantee exactly one default key at most by flipping `isDefault` on upsert
when `isDefault === true`.
- Consider: separate lightweight persistent "defaultId" in manifest root to
avoid iterating all keys on default change.
3) Logging + Dev ergonomics
- Gate verbose logs behind a debug flag to avoid log spam in production builds.
2. Robustness
- Add safety around manifest chunk growth: if
`manifestChunkSize + newEntrySize > sizeLimit`, create a new chunk.
- Ensure `createdAtMs` is preserved across upserts (done) and add
`modifiedAtMs` if useful.
3. Logging + Dev ergonomics
- Gate verbose logs behind a debug flag to avoid log spam in production
builds.
## Phase 4 — Edge Cases & Polish
- Deleting the currently-selected key: clear selection and show hint to pick/create a new key.
- Deleting the currently-selected key: clear selection and show hint to
pick/create a new key.
- Auto-select the default key when switching to key auth and no key is selected.
- Handle failures from `SecureStore` (permissions/storage full) with user-friendly messages.
- Handle very large keys with chunking (already supported), surface an error if size exceeds safe thresholds.
- Accessibility: ensure labels/roles for controls in modal and the selection field.
- Handle failures from `SecureStore` (permissions/storage full) with
user-friendly messages.
- Handle very large keys with chunking (already supported), surface an error if
size exceeds safe thresholds.
- Accessibility: ensure labels/roles for controls in modal and the selection
field.
## Phase 5 — Testing & QA
- Unit test PEM parsing/validation (Phase 2).
- E2E flows:
- First run → toggle to key → auto-open modal → generate key → selected → connect.
- First run → toggle to key → auto-open modal → generate key → selected →
connect.
- Import key by paste/file; rename; set default; delete.
- Delete selected key; confirm the form state updates.
## Implementation Notes
- Keep a single write path for keys: `upsertPrivateKey` (invalidates the `keys` query).
- Prefer modal-based selection with a simple “field-as-button” in the form.
- For future passphrase support, confirm the SSH librarys API shape and storage expectations.
- Keep a single write path for keys: `upsertPrivateKey` (invalidates the `keys`
query).
- Prefer modal-based selection with a simple “field-as-button” in the form.
- For future passphrase support, confirm the SSH librarys API shape and storage
expectations.

View File

@@ -1,9 +1,30 @@
# Big TODOS
- real terminal emulation
- llm command suggestions
- llm output synthesis
- better keyboard management
- import private key
https://github.com/software-mansion/react-native-executorch
https://docs.expo.dev/guides/keyboard-handling/
https://kirillzyusko.github.io/react-native-keyboard-controller/
### Future reading
https://reactnativereusables.com/
#### AI Libraries
- https://github.com/software-mansion/react-native-executorch
- https://github.com/callstackincubator/ai
#### Keyboard handling
- https://docs.expo.dev/guides/keyboard-handling/
- https://kirillzyusko.github.io/react-native-keyboard-controller/
#### Styling and components
- https://reactnativereusables.com/ https://www.unistyl.es/
- https://github.com/Shopify/restyle
#### SSH Conn
- https://github.com/dylankenneally/react-native-ssh-sftp
- https://xtermjs.org/
- https://docs.expo.dev/versions/latest/sdk/webview/

386
pnpm-lock.yaml generated
View File

@@ -40,7 +40,7 @@ importers:
version: 1.5.20(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))
'@expo/vector-icons':
specifier: ^15.0.2
version: 15.0.2(expo-font@14.0.7(expo@54.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
version: 15.0.2(expo-font@14.0.8(expo@54.0.2)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
'@fressh/assets':
specifier: workspace:*
version: link:../../packages/assets
@@ -63,47 +63,47 @@ importers:
specifier: ^5.87.1
version: 5.87.1(react@19.1.0)
expo:
specifier: 54.0.1
version: 54.0.1(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.0)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
specifier: 54.0.2
version: 54.0.2(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo-build-properties:
specifier: ~1.0.7
version: 1.0.7(expo@54.0.1)
specifier: ~1.0.8
version: 1.0.8(expo@54.0.2)
expo-constants:
specifier: ~18.0.8
version: 18.0.8(expo@54.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))
version: 18.0.8(expo@54.0.2)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))
expo-font:
specifier: ~14.0.7
version: 14.0.7(expo@54.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
specifier: ~14.0.8
version: 14.0.8(expo@54.0.2)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo-haptics:
specifier: ~15.0.6
version: 15.0.6(expo@54.0.1)
specifier: ~15.0.7
version: 15.0.7(expo@54.0.2)
expo-image:
specifier: ~3.0.7
version: 3.0.7(expo@54.0.1)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
specifier: ~3.0.8
version: 3.0.8(expo@54.0.2)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo-linking:
specifier: ~8.0.7
version: 8.0.7(expo@54.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
specifier: ~8.0.8
version: 8.0.8(expo@54.0.2)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo-router:
specifier: 6.0.0
version: 6.0.0(@types/react@19.1.12)(expo-constants@18.0.8)(expo-linking@8.0.7)(expo@54.0.1)(react-dom@19.1.0(react@19.1.0))(react-native-gesture-handler@2.28.0(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native-reanimated@4.1.0(@babel/core@7.28.3)(react-native-worklets@0.5.1(@babel/core@7.28.3)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.1(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native-screens@4.16.0(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
specifier: 6.0.1
version: 6.0.1(@types/react@19.1.12)(expo-constants@18.0.8)(expo-linking@8.0.8)(expo@54.0.2)(react-dom@19.1.0(react@19.1.0))(react-native-gesture-handler@2.28.0(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native-reanimated@4.1.0(@babel/core@7.28.3)(react-native-worklets@0.5.1(@babel/core@7.28.3)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.1(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native-screens@4.16.0(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo-secure-store:
specifier: ~15.0.6
version: 15.0.6(expo@54.0.1)
specifier: ~15.0.7
version: 15.0.7(expo@54.0.2)
expo-splash-screen:
specifier: ~31.0.8
version: 31.0.8(expo@54.0.1)
specifier: ~31.0.9
version: 31.0.9(expo@54.0.2)
expo-status-bar:
specifier: ~3.0.7
version: 3.0.7(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
specifier: ~3.0.8
version: 3.0.8(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo-symbols:
specifier: ~1.0.6
version: 1.0.6(expo@54.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))
specifier: ~1.0.7
version: 1.0.7(expo@54.0.2)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))
expo-system-ui:
specifier: ~6.0.7
version: 6.0.7(expo@54.0.1)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))
version: 6.0.7(expo@54.0.2)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))
expo-web-browser:
specifier: ~15.0.6
version: 15.0.6(expo@54.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))
specifier: ~15.0.7
version: 15.0.7(expo@54.0.2)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))
react:
specifier: 19.1.0
version: 19.1.0
@@ -993,8 +993,8 @@ packages:
resolution: {integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@expo/cli@54.0.1':
resolution: {integrity: sha512-vIITqb96FCHzCt4ctlkfghAcuNolNpYDE2cqBFt4zqgiesQW19xeucZRiw+IYF0XE0fo3/8OF29H+Aj3aisELA==}
'@expo/cli@54.0.2':
resolution: {integrity: sha512-WaMwVUC1twawsicKS/jabrc9b56EYLWDa1JvF1oopEE8H15+KLsgfjqN9IWtIR2wu5d6zhOT3ikTLc2cN4S4/Q==}
hasBin: true
peerDependencies:
expo: '*'
@@ -1009,23 +1009,26 @@ packages:
'@expo/code-signing-certificates@0.0.5':
resolution: {integrity: sha512-BNhXkY1bblxKZpltzAx98G2Egj9g1Q+JRcvR7E99DOj862FTCX+ZPsAUtPTr7aHxwtrL7+fL3r0JSmM9kBm+Bw==}
'@expo/config-plugins@11.0.7':
resolution: {integrity: sha512-kak5m27fPTzwmzYPbaYL6I67OFnhdrzV0h5JcoljrEC7uM3R18V/RrnEMzv10XQk+s+qmPfMkr0aK9YYgGqR6g==}
'@expo/config-plugins@54.0.0':
resolution: {integrity: sha512-b2yFNKwaiHjDfh7K+zhMvRKA09gdaP/raqIzB112qeacVJaT66vka8m6cffYbbiXMe1srqofSJvyvr+g3H6+nA==}
'@expo/config-plugins@54.0.1':
resolution: {integrity: sha512-NyBChhiWFL6VqSgU+LzK4R1vC397tEG2XFewVt4oMr4Pnalq/mJxBANQrR+dyV1RHhSyhy06RNiJIkQyngVWeg==}
'@expo/config-types@54.0.7':
resolution: {integrity: sha512-f0UehgPd2gUqUtQ6euHAL6MqTT/A07r847Ztw2yZYWTUr0hRZr4nCP4U+lr8/pPtsHQYMKoPB1mOeAaTO25ruw==}
'@expo/config-types@54.0.8':
resolution: {integrity: sha512-lyIn/x/Yz0SgHL7IGWtgTLg6TJWC9vL7489++0hzCHZ4iGjVcfZmPTUfiragZ3HycFFj899qN0jlhl49IHa94A==}
'@expo/config@12.0.8':
resolution: {integrity: sha512-yFadXa5Cmja57EVOSyEYV1hF7kCaSbPnd1twx0MfvTr1Yj2abIbrEu2MUZqcvElNQOtgADnLRP0YJiuEdgoO5A==}
'@expo/devcert@1.2.0':
resolution: {integrity: sha512-Uilcv3xGELD5t/b0eM4cxBFEKQRIivB3v7i+VhWLV/gL98aw810unLKKJbGAxAIhY6Ipyz8ChWibFsKFXYwstA==}
'@expo/devtools@0.1.6':
resolution: {integrity: sha512-NE4TaCyUS/Cy2YxMdajt4grjfuJIsv6symUbQXk06Y96SyHy5DVzI1H0KdUca1HkPoZwwGCACFZZCN+Jvzuujw==}
'@expo/devtools@0.1.7':
resolution: {integrity: sha512-dfIa9qMyXN+0RfU6SN4rKeXZyzKWsnz6xBSDccjL4IRiE+fQ0t84zg0yxgN4t/WK2JU5v6v4fby7W7Crv9gJvA==}
peerDependencies:
react: '*'
react-native: '*'
@@ -1042,9 +1045,6 @@ packages:
resolution: {integrity: sha512-PrLA6fxScZfnLy7OHZ2GHXsDG9YbE7L5DbNhion6j/U/O+FQgz4VbxJarW5C00kMg1ll2u6EghB7ENAvL1T4qg==}
hasBin: true
'@expo/image-utils@0.8.6':
resolution: {integrity: sha512-8DMA76Sakq6dMLyJyoeWcxWpjcQUrr0V6jjsJ+Z3ZnEVKpWlxXO5SOc6mib1HOUDMtMqg4cwAhyKHZ98LmDj8Q==}
'@expo/image-utils@0.8.7':
resolution: {integrity: sha512-SXOww4Wq3RVXLyOaXiCCuQFguCDh8mmaHBv54h/R29wGl4jRY8GEyQEx8SypV/iHt1FbzsU/X3Qbcd9afm2W2w==}
@@ -1054,8 +1054,8 @@ packages:
'@expo/json-file@10.0.7':
resolution: {integrity: sha512-z2OTC0XNO6riZu98EjdNHC05l51ySeTto6GP7oSQrCvQgG9ARBwD1YvMQaVZ9wU7p/4LzSf1O7tckL3B45fPpw==}
'@expo/metro-config@54.0.1':
resolution: {integrity: sha512-yq+aA38RjmTxFUUWK2xuKWIRAVfnIDf7ephSXcc5isNVGRylwnWE+8N2scWrOQt49ikePbvwWpakTsNfLVLZbw==}
'@expo/metro-config@54.0.2':
resolution: {integrity: sha512-RYnqFlqzTwdSOd/2OcLT/8td64ybfV5Q01YKZRUhUaszuOshS3hXVHdOPBpWDYQk6h2rWew8ds9FGiJaPyRVKw==}
peerDependencies:
expo: '*'
peerDependenciesMeta:
@@ -1076,8 +1076,8 @@ packages:
'@expo/metro@0.1.1':
resolution: {integrity: sha512-zvA9BE6myFoCxeiw/q3uE/kVkIwLTy27a+fDoEl7WQ7EvKfFeiXnRVhUplDMLGZIHH8VC38Gay6RBtVhnmOm5w==}
'@expo/osascript@2.3.6':
resolution: {integrity: sha512-EMi4/YgWN/dHSkE9A4A5EJE8WrGnp71+BcVAKY80KMYtq5s6mOhLyDm8ytvHeUISUrPcPTRZ/6c8JMd6F8Ggmg==}
'@expo/osascript@2.3.7':
resolution: {integrity: sha512-IClSOXxR0YUFxIriUJVqyYki7lLMIHrrzOaP01yxAL1G8pj2DWV5eW1y5jSzIcIfSCNhtGsshGd1tU/AYup5iQ==}
engines: {node: '>=12'}
'@expo/package-manager@1.9.7':
@@ -1086,24 +1086,22 @@ packages:
'@expo/plist@0.4.6':
resolution: {integrity: sha512-6yklhtUWohs1rBSC8dGyBBpElEbosjXN0zJN/+1/B121n7pPWvd9y/UGJm+2x7b81VnW3AHmWVnbU/u0INQsqA==}
'@expo/prebuild-config@10.0.8':
resolution: {integrity: sha512-9ibcRuWngmMnoYe25XXfZEWcPCdx6LiyzqHqpojsvHBI+sMsyZPf4b/5y/zmeJy3PKjR4LSzMRonEitTfUSL/A==}
peerDependencies:
expo: '*'
'@expo/plist@0.4.7':
resolution: {integrity: sha512-dGxqHPvCZKeRKDU1sJZMmuyVtcASuSYh1LPFVaM1DuffqPL36n6FMEL0iUqq2Tx3xhWk8wCnWl34IKplUjJDdA==}
'@expo/prebuild-config@54.0.1':
resolution: {integrity: sha512-f2FFDQlIh83rc89/AOdRBtO9nwkE4BCSji0oPBSq0YmAUSXZE7q/cYKABkArZNjuuwjb6jRjD8JfSMcwV7ybTA==}
peerDependencies:
expo: '*'
'@expo/schema-utils@0.1.6':
resolution: {integrity: sha512-arKkNlPZYD0uUxGPbSwV/6v4owmZcUNrXk9Vq/o+p2Eqt1DM9jIjbXwrqlmvkTsPkjUtNLDGB0EDiosVJ4OvDg==}
'@expo/schema-utils@0.1.7':
resolution: {integrity: sha512-jWHoSuwRb5ZczjahrychMJ3GWZu54jK9ulNdh1d4OzAEq672K9E5yOlnlBsfIHWHGzUAT+0CL7Yt1INiXTz68g==}
'@expo/sdk-runtime-versions@1.0.0':
resolution: {integrity: sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ==}
'@expo/server@0.7.3':
resolution: {integrity: sha512-lmlpJrjC0PLspPIF8ZzAalpbCxqbsqLRzIpolT3gZP48H6039BOlb1hAWTVgZvXmWkpvlYbt0PYG9o9GZxkQuw==}
'@expo/server@0.7.4':
resolution: {integrity: sha512-8bfRzL7h1Qgrmf3auR71sPAcAuxnmNkRJs+8enL8vZi2+hihevLhrayDu7P0A/XGEq7wySAGvBBFfIB00Et/AA==}
engines: {node: '>=20.16.0'}
'@expo/spawn-async@1.7.2':
@@ -1771,9 +1769,6 @@ packages:
'@react-native/normalize-colors@0.74.89':
resolution: {integrity: sha512-qoMMXddVKVhZ8PA1AbUCk83trpd6N+1nF2A6k1i6LsQObyS92fELuk8kU/lQs6M7BsMHwqyLCpQJ1uFgNvIQXg==}
'@react-native/normalize-colors@0.81.1':
resolution: {integrity: sha512-TsaeZlE8OYFy3PSWc+1VBmAzI2T3kInzqxmwXoGU4w1d4XFkQFg271Ja9GmDi9cqV3CnBfqoF9VPwRxVlc/l5g==}
'@react-native/normalize-colors@0.81.4':
resolution: {integrity: sha512-9nRRHO1H+tcFqjb9gAM105Urtgcanbta2tuqCVY0NATHeFPDEAB7gPyiLxCHKMi1NbhP6TH0kxgSWXKZl1cyRg==}
@@ -3576,8 +3571,8 @@ packages:
react: '*'
react-native: '*'
expo-build-properties@1.0.7:
resolution: {integrity: sha512-HbsLEjhmVaGudNpO3qYSdZddK+B82D0ff5r9hZ1huOGqwPnb21TmajsSjHC0q7M+9MJ2P+IunC4qYib21IWSAg==}
expo-build-properties@1.0.8:
resolution: {integrity: sha512-Ram9Jcg2WkbE7bRopWacMnXIhqUP6P13cQoj4rSfXLpJVOyGGvuMiw3rs1vzMbWSHxhvvsX2NvYXXIrZatexuw==}
peerDependencies:
expo: '*'
@@ -3587,26 +3582,26 @@ packages:
expo: '*'
react-native: '*'
expo-file-system@19.0.11:
resolution: {integrity: sha512-xrtd4YobW5pKYJt4tGNbmzjb9ojg5J4H1iavUs2MDt4S/jX+IObLuJ8tWxBI7Zce5+0i9j4nU/V0gz/18AMJ8w==}
expo-file-system@19.0.12:
resolution: {integrity: sha512-gqpxpnjfhzXLcqMOi49isB5S1Af49P9410fsaFfnLZWN3X6Dwc8EplDwbaolOI/wnGwP81P+/nDn5RNmU6m7mQ==}
peerDependencies:
expo: '*'
react-native: '*'
expo-font@14.0.7:
resolution: {integrity: sha512-jW6aEHUwn+SKizE1iJsaC0nLFb7ipy2wqUrceg+k7KyVZW74DRyDVjuJYzyuJE8BJutulsiYBzvx6K0axboULA==}
expo-font@14.0.8:
resolution: {integrity: sha512-bTUHaJWRZ7ywP8dg3f+wfOwv6RwMV3mWT2CDUIhsK70GjNGlCtiWOCoHsA5Od/esPaVxqc37cCBvQGQRFStRlA==}
peerDependencies:
expo: '*'
react: '*'
react-native: '*'
expo-haptics@15.0.6:
resolution: {integrity: sha512-Unns//atxLq4UkDrgvwNpzOB2pm6hPS1nhZVL8BIfOebU/++JQlKJYPam4sRn7w/vMbRYpJ8BmC96mRs3QR0Tg==}
expo-haptics@15.0.7:
resolution: {integrity: sha512-7flWsYPrwjJxZ8x82RiJtzsnk1Xp9ahnbd9PhCy3NnsemyMApoWIEUr4waPqFr80DtiLZfhD9VMLL1CKa8AImQ==}
peerDependencies:
expo: '*'
expo-image@3.0.7:
resolution: {integrity: sha512-JlokOLUnIx9fKWgC6jlP/0C1TJd6ESNo/hKVO49a989YvHodslj1GGRy9+CR2ak4WBJiBv1X6SrYMchMXobfSg==}
expo-image@3.0.8:
resolution: {integrity: sha512-L83fTHVjvE5hACxUXPk3dpABteI/IypeqxKMeOAAcT2eB/jbqT53ddsYKEvKAP86eoByQ7+TCtw9AOUizEtaTQ==}
peerDependencies:
expo: '*'
react: '*'
@@ -3616,14 +3611,14 @@ packages:
react-native-web:
optional: true
expo-keep-awake@15.0.6:
resolution: {integrity: sha512-xO/KbQQjSdhHR87x2uZsMnIDXsDO9apa64jqxG5t0WKSBujdS3uDmvuYF7EwiJc8fKEWZ500Co51nOtO0wU1dg==}
expo-keep-awake@15.0.7:
resolution: {integrity: sha512-CgBNcWVPnrIVII5G54QDqoE125l+zmqR4HR8q+MQaCfHet+dYpS5vX5zii/RMayzGN4jPgA4XYIQ28ePKFjHoA==}
peerDependencies:
expo: '*'
react: '*'
expo-linking@8.0.7:
resolution: {integrity: sha512-DCPEDg522ryJp752kcajGR8kWgQfKMc/YbjzApb4Uzm2kJNW+0JXrIwsLPTl/mn9XxcOkGrE81B1L5EwQZKHkw==}
expo-linking@8.0.8:
resolution: {integrity: sha512-MyeMcbFDKhXh4sDD1EHwd0uxFQNAc6VCrwBkNvvvufUsTYFq3glTA9Y8a+x78CPpjNqwNAamu74yIaIz7IEJyg==}
peerDependencies:
react: '*'
react-native: '*'
@@ -3638,14 +3633,14 @@ packages:
react: '*'
react-native: '*'
expo-router@6.0.0:
resolution: {integrity: sha512-4/SI/4f4wOmbxyQ3TH2nvRdbmlggQx2/WO5mWSuSsazUUerjc8h3lo9NkKyEZRrkeq09jYcfQQhbbl8yCnW/Gg==}
expo-router@6.0.1:
resolution: {integrity: sha512-5wXkWyNMqUbjCWH0PRkOM0P6UsgLVdgchDkiLz5FY7HfU00ToBcxij965bqtlaATBgoaIo4DuLu6EgxewrKJ8Q==}
peerDependencies:
'@react-navigation/drawer': ^7.5.0
'@testing-library/react-native': '>= 12.0.0'
expo: '*'
expo-constants: ^18.0.7
expo-linking: ^8.0.7
expo-constants: ^18.0.8
expo-linking: ^8.0.8
react: '*'
react-dom: '*'
react-native: '*'
@@ -3671,24 +3666,24 @@ packages:
react-server-dom-webpack:
optional: true
expo-secure-store@15.0.6:
resolution: {integrity: sha512-jzCsjnoMJYuRFxb4oHlwQY71WFIiOFiqQlvtay3Ct6OoKugR3/qjBwkcBoDsr1LsbFBVEkOMEU2i59peBMG1Jg==}
expo-secure-store@15.0.7:
resolution: {integrity: sha512-9q7+G1Zxr5P6J5NRIlm86KulvmYwc6UnQlYPjQLDu1drDnerz6AT6l884dPu29HgtDTn4rR0heYeeGFhMKM7/Q==}
peerDependencies:
expo: '*'
expo-splash-screen@31.0.8:
resolution: {integrity: sha512-NNgNhrqkuJAt98k9CKJ9JeCInv5g/xRhe1fWbciQrqTQWPXeIGg3tn5T5HNFwfRD1aKr2uOs1Ctly8rE6i5vtQ==}
expo-splash-screen@31.0.9:
resolution: {integrity: sha512-pYLWFrEHn/c8e1a8oDzrlcyYI08oG4i37KA+VN5wwoC1DsQ0rm3kyAk0bmoydV1mBzNfXQFYbA1BGftXJl1f0w==}
peerDependencies:
expo: '*'
expo-status-bar@3.0.7:
resolution: {integrity: sha512-8AyNDAsOIR0sAh8uUuOnCNrntr2sM2Q8MW173bQJQIDRNClK7WLVnho1mQhZU3it7MrSWp3QOyUTNU0RcQrL1w==}
expo-status-bar@3.0.8:
resolution: {integrity: sha512-L248XKPhum7tvREoS1VfE0H6dPCaGtoUWzRsUv7hGKdiB4cus33Rc0sxkWkoQ77wE8stlnUlL5lvmT0oqZ3ZBw==}
peerDependencies:
react: '*'
react-native: '*'
expo-symbols@1.0.6:
resolution: {integrity: sha512-866OfsPJUjT9OhxP6ol/tnQLUY3h2LGHXGpb2SR9OLbM2M/xv+5Ko1+GBMcTbJ3wqW6uZKEgQBNLLKXUIvi/bg==}
expo-symbols@1.0.7:
resolution: {integrity: sha512-ZqFUeTXbwO6BrE00n37wTXYfJmsjFrfB446jeB9k9w7aA8a6eugNUIzNsUIUfbFWoOiY4wrGmpLSLPBwk4PH+g==}
peerDependencies:
expo: '*'
react-native: '*'
@@ -3703,14 +3698,14 @@ packages:
react-native-web:
optional: true
expo-web-browser@15.0.6:
resolution: {integrity: sha512-f3LPRwYGHQ6lM2PZX1Fz79mfa90e3s8Zs9UKv2TqSqsM85YmqTiT5pgd5tLHh55HgWjSMeISCCtahe6WKeWgCw==}
expo-web-browser@15.0.7:
resolution: {integrity: sha512-eXnfO3FQ2WthTA8uEPNJ7SDRfPaLIU/P2k082HGEYIHAFZMwh2o9Wo+SDVytO3E95TAv1qwhggUjOrczYzxteQ==}
peerDependencies:
expo: '*'
react-native: '*'
expo@54.0.1:
resolution: {integrity: sha512-BJSraR0CM8aUtrSlk8fgOXHhhsB5SeFqc+rJPsnMpdguN60PNkoGF+/ulr9dYfLaPa2w51tW5PmeVTLzESdXbA==}
expo@54.0.2:
resolution: {integrity: sha512-0YcsvMuiZlVFVZRdD4PlhwsYrTmcN1qm5b1IRSLIeLZjH6ZnQwBb3KBSnK8WRC9V6EUPSbuLGpNT5AEewrtakQ==}
hasBin: true
peerDependencies:
'@expo/dom-webview': '*'
@@ -7756,24 +7751,24 @@ snapshots:
'@eslint/core': 0.15.2
levn: 0.4.1
'@expo/cli@54.0.1(expo-router@6.0.0)(expo@54.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))':
'@expo/cli@54.0.2(expo-router@6.0.1)(expo@54.0.2)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))':
dependencies:
'@0no-co/graphql.web': 1.2.0
'@expo/code-signing-certificates': 0.0.5
'@expo/config': 12.0.8
'@expo/config-plugins': 54.0.0
'@expo/config-plugins': 54.0.1
'@expo/devcert': 1.2.0
'@expo/env': 2.0.7
'@expo/image-utils': 0.8.7
'@expo/json-file': 10.0.7
'@expo/metro': 0.1.1
'@expo/metro-config': 54.0.1(expo@54.0.1)
'@expo/osascript': 2.3.6
'@expo/metro-config': 54.0.2(expo@54.0.2)
'@expo/osascript': 2.3.7
'@expo/package-manager': 1.9.7
'@expo/plist': 0.4.6
'@expo/prebuild-config': 54.0.1(expo@54.0.1)
'@expo/schema-utils': 0.1.6
'@expo/server': 0.7.3
'@expo/plist': 0.4.7
'@expo/prebuild-config': 54.0.1(expo@54.0.2)
'@expo/schema-utils': 0.1.7
'@expo/server': 0.7.4
'@expo/spawn-async': 1.7.2
'@expo/ws-tunnel': 1.0.6
'@expo/xcpretty': 4.3.2
@@ -7791,7 +7786,7 @@ snapshots:
connect: 3.7.0
debug: 4.4.1
env-editor: 0.4.2
expo: 54.0.1(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.0)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo: 54.0.2(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
freeport-async: 2.0.0
getenv: 2.0.0
glob: 10.4.5
@@ -7823,7 +7818,7 @@ snapshots:
wrap-ansi: 7.0.0
ws: 8.18.3
optionalDependencies:
expo-router: 6.0.0(@types/react@19.1.12)(expo-constants@18.0.8)(expo-linking@8.0.7)(expo@54.0.1)(react-dom@19.1.0(react@19.1.0))(react-native-gesture-handler@2.28.0(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native-reanimated@4.1.0(@babel/core@7.28.3)(react-native-worklets@0.5.1(@babel/core@7.28.3)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.1(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native-screens@4.16.0(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo-router: 6.0.1(@types/react@19.1.12)(expo-constants@18.0.8)(expo-linking@8.0.8)(expo@54.0.2)(react-dom@19.1.0(react@19.1.0))(react-native-gesture-handler@2.28.0(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native-reanimated@4.1.0(@babel/core@7.28.3)(react-native-worklets@0.5.1(@babel/core@7.28.3)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.1(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native-screens@4.16.0(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
react-native: 0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0)
transitivePeerDependencies:
- bufferutil
@@ -7836,25 +7831,6 @@ snapshots:
node-forge: 1.3.1
nullthrows: 1.1.1
'@expo/config-plugins@11.0.7':
dependencies:
'@expo/config-types': 54.0.7
'@expo/json-file': 10.0.7
'@expo/plist': 0.4.6
'@expo/sdk-runtime-versions': 1.0.0
chalk: 4.1.2
debug: 4.4.1
getenv: 2.0.0
glob: 10.4.5
resolve-from: 5.0.0
semver: 7.7.2
slash: 3.0.0
slugify: 1.6.6
xcode: 3.0.1
xml2js: 0.6.0
transitivePeerDependencies:
- supports-color
'@expo/config-plugins@54.0.0':
dependencies:
'@expo/config-types': 54.0.7
@@ -7874,8 +7850,29 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@expo/config-plugins@54.0.1':
dependencies:
'@expo/config-types': 54.0.8
'@expo/json-file': 10.0.7
'@expo/plist': 0.4.7
'@expo/sdk-runtime-versions': 1.0.0
chalk: 4.1.2
debug: 4.4.1
getenv: 2.0.0
glob: 10.4.5
resolve-from: 5.0.0
semver: 7.7.2
slash: 3.0.0
slugify: 1.6.6
xcode: 3.0.1
xml2js: 0.6.0
transitivePeerDependencies:
- supports-color
'@expo/config-types@54.0.7': {}
'@expo/config-types@54.0.8': {}
'@expo/config@12.0.8':
dependencies:
'@babel/code-frame': 7.10.4
@@ -7902,7 +7899,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@expo/devtools@0.1.6(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)':
'@expo/devtools@0.1.7(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)':
dependencies:
chalk: 4.1.2
optionalDependencies:
@@ -7935,19 +7932,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@expo/image-utils@0.8.6':
dependencies:
'@expo/spawn-async': 1.7.2
chalk: 4.1.2
getenv: 2.0.0
jimp-compact: 0.16.1
parse-png: 2.1.0
resolve-from: 5.0.0
resolve-global: 1.0.0
semver: 7.7.2
temp-dir: 2.0.0
unique-string: 2.0.0
'@expo/image-utils@0.8.7':
dependencies:
'@expo/spawn-async': 1.7.2
@@ -7971,7 +7955,7 @@ snapshots:
'@babel/code-frame': 7.10.4
json5: 2.2.3
'@expo/metro-config@54.0.1(expo@54.0.1)':
'@expo/metro-config@54.0.2(expo@54.0.2)':
dependencies:
'@babel/code-frame': 7.27.1
'@babel/core': 7.28.3
@@ -7995,16 +7979,16 @@ snapshots:
postcss: 8.4.49
resolve-from: 5.0.0
optionalDependencies:
expo: 54.0.1(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.0)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo: 54.0.2(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
'@expo/metro-runtime@6.1.1(expo@54.0.1)(react-dom@19.1.0(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)':
'@expo/metro-runtime@6.1.1(expo@54.0.2)(react-dom@19.1.0(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)':
dependencies:
anser: 1.4.10
expo: 54.0.1(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.0)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo: 54.0.2(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
pretty-format: 29.7.0
react: 19.1.0
react-native: 0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0)
@@ -8032,7 +8016,7 @@ snapshots:
- supports-color
- utf-8-validate
'@expo/osascript@2.3.6':
'@expo/osascript@2.3.7':
dependencies:
'@expo/spawn-async': 1.7.2
exec-async: 2.2.0
@@ -8052,43 +8036,33 @@ snapshots:
base64-js: 1.5.1
xmlbuilder: 15.1.1
'@expo/prebuild-config@10.0.8(expo@54.0.1)':
'@expo/plist@0.4.7':
dependencies:
'@expo/config': 12.0.8
'@expo/config-plugins': 11.0.7
'@expo/config-types': 54.0.7
'@expo/image-utils': 0.8.6
'@expo/json-file': 10.0.6
'@react-native/normalize-colors': 0.81.1
debug: 4.4.1
expo: 54.0.1(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.0)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
resolve-from: 5.0.0
semver: 7.7.2
xml2js: 0.6.0
transitivePeerDependencies:
- supports-color
'@xmldom/xmldom': 0.8.11
base64-js: 1.5.1
xmlbuilder: 15.1.1
'@expo/prebuild-config@54.0.1(expo@54.0.1)':
'@expo/prebuild-config@54.0.1(expo@54.0.2)':
dependencies:
'@expo/config': 12.0.8
'@expo/config-plugins': 54.0.0
'@expo/config-types': 54.0.7
'@expo/config-plugins': 54.0.1
'@expo/config-types': 54.0.8
'@expo/image-utils': 0.8.7
'@expo/json-file': 10.0.7
'@react-native/normalize-colors': 0.81.4
debug: 4.4.1
expo: 54.0.1(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.0)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo: 54.0.2(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
resolve-from: 5.0.0
semver: 7.7.2
xml2js: 0.6.0
transitivePeerDependencies:
- supports-color
'@expo/schema-utils@0.1.6': {}
'@expo/schema-utils@0.1.7': {}
'@expo/sdk-runtime-versions@1.0.0': {}
'@expo/server@0.7.3':
'@expo/server@0.7.4':
dependencies:
abort-controller: 3.0.0
debug: 4.4.1
@@ -8101,9 +8075,9 @@ snapshots:
'@expo/sudo-prompt@9.3.2': {}
'@expo/vector-icons@15.0.2(expo-font@14.0.7(expo@54.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)':
'@expo/vector-icons@15.0.2(expo-font@14.0.8(expo@54.0.2)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)':
dependencies:
expo-font: 14.0.7(expo@54.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo-font: 14.0.8(expo@54.0.2)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
react: 19.1.0
react-native: 0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0)
@@ -8770,8 +8744,6 @@ snapshots:
'@react-native/normalize-colors@0.74.89': {}
'@react-native/normalize-colors@0.81.1': {}
'@react-native/normalize-colors@0.81.4': {}
'@react-native/virtualized-lists@0.81.4(@types/react@19.1.12)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)':
@@ -9827,7 +9799,7 @@ snapshots:
'@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.28.3)
'@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.28.3)
babel-preset-expo@54.0.0(@babel/core@7.28.3)(@babel/runtime@7.28.3)(expo@54.0.1)(react-refresh@0.14.2):
babel-preset-expo@54.0.0(@babel/core@7.28.3)(@babel/runtime@7.28.3)(expo@54.0.2)(react-refresh@0.14.2):
dependencies:
'@babel/helper-module-imports': 7.27.1
'@babel/plugin-proposal-decorators': 7.28.0(@babel/core@7.28.3)
@@ -9854,7 +9826,7 @@ snapshots:
resolve-from: 5.0.0
optionalDependencies:
'@babel/runtime': 7.28.3
expo: 54.0.1(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.0)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo: 54.0.2(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
transitivePeerDependencies:
- '@babel/core'
- supports-color
@@ -10902,63 +10874,63 @@ snapshots:
signal-exit: 3.0.7
strip-final-newline: 2.0.0
expo-asset@12.0.8(expo@54.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
expo-asset@12.0.8(expo@54.0.2)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
dependencies:
'@expo/image-utils': 0.8.7
expo: 54.0.1(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.0)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo-constants: 18.0.8(expo@54.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))
expo: 54.0.2(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo-constants: 18.0.8(expo@54.0.2)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))
react: 19.1.0
react-native: 0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0)
transitivePeerDependencies:
- supports-color
expo-build-properties@1.0.7(expo@54.0.1):
expo-build-properties@1.0.8(expo@54.0.2):
dependencies:
ajv: 8.17.1
expo: 54.0.1(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.0)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo: 54.0.2(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
semver: 7.7.2
expo-constants@18.0.8(expo@54.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0)):
expo-constants@18.0.8(expo@54.0.2)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0)):
dependencies:
'@expo/config': 12.0.8
'@expo/env': 2.0.7
expo: 54.0.1(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.0)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo: 54.0.2(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
react-native: 0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0)
transitivePeerDependencies:
- supports-color
expo-file-system@19.0.11(expo@54.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0)):
expo-file-system@19.0.12(expo@54.0.2)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0)):
dependencies:
expo: 54.0.1(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.0)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo: 54.0.2(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
react-native: 0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0)
expo-font@14.0.7(expo@54.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
expo-font@14.0.8(expo@54.0.2)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
dependencies:
expo: 54.0.1(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.0)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo: 54.0.2(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
fontfaceobserver: 2.3.0
react: 19.1.0
react-native: 0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0)
expo-haptics@15.0.6(expo@54.0.1):
expo-haptics@15.0.7(expo@54.0.2):
dependencies:
expo: 54.0.1(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.0)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo: 54.0.2(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo-image@3.0.7(expo@54.0.1)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
expo-image@3.0.8(expo@54.0.2)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
dependencies:
expo: 54.0.1(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.0)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo: 54.0.2(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
react: 19.1.0
react-native: 0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0)
optionalDependencies:
react-native-web: 0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
expo-keep-awake@15.0.6(expo@54.0.1)(react@19.1.0):
expo-keep-awake@15.0.7(expo@54.0.2)(react@19.1.0):
dependencies:
expo: 54.0.1(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.0)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo: 54.0.2(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
react: 19.1.0
expo-linking@8.0.7(expo@54.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
expo-linking@8.0.8(expo@54.0.2)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
dependencies:
expo-constants: 18.0.8(expo@54.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))
expo-constants: 18.0.8(expo@54.0.2)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))
invariant: 2.2.4
react: 19.1.0
react-native: 0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0)
@@ -10981,11 +10953,11 @@ snapshots:
react: 19.1.0
react-native: 0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0)
expo-router@6.0.0(@types/react@19.1.12)(expo-constants@18.0.8)(expo-linking@8.0.7)(expo@54.0.1)(react-dom@19.1.0(react@19.1.0))(react-native-gesture-handler@2.28.0(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native-reanimated@4.1.0(@babel/core@7.28.3)(react-native-worklets@0.5.1(@babel/core@7.28.3)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.1(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native-screens@4.16.0(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
expo-router@6.0.1(@types/react@19.1.12)(expo-constants@18.0.8)(expo-linking@8.0.8)(expo@54.0.2)(react-dom@19.1.0(react@19.1.0))(react-native-gesture-handler@2.28.0(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native-reanimated@4.1.0(@babel/core@7.28.3)(react-native-worklets@0.5.1(@babel/core@7.28.3)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.1(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native-screens@4.16.0(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
dependencies:
'@expo/metro-runtime': 6.1.1(expo@54.0.1)(react-dom@19.1.0(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
'@expo/schema-utils': 0.1.6
'@expo/server': 0.7.3
'@expo/metro-runtime': 6.1.1(expo@54.0.2)(react-dom@19.1.0(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
'@expo/schema-utils': 0.1.7
'@expo/server': 0.7.4
'@radix-ui/react-slot': 1.2.0(@types/react@19.1.12)(react@19.1.0)
'@radix-ui/react-tabs': 1.1.13(@types/react@19.1.12)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@react-navigation/bottom-tabs': 7.4.7(@react-navigation/native@7.1.17(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.1(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native-screens@4.16.0(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
@@ -10994,9 +10966,9 @@ snapshots:
client-only: 0.0.1
debug: 4.4.1
escape-string-regexp: 4.0.0
expo: 54.0.1(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.0)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo-constants: 18.0.8(expo@54.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))
expo-linking: 8.0.7(expo@54.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo: 54.0.2(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo-constants: 18.0.8(expo@54.0.2)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))
expo-linking: 8.0.8(expo@54.0.2)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
fast-deep-equal: 3.1.3
invariant: 2.2.4
nanoid: 3.3.11
@@ -11024,63 +10996,63 @@ snapshots:
- '@types/react-dom'
- supports-color
expo-secure-store@15.0.6(expo@54.0.1):
expo-secure-store@15.0.7(expo@54.0.2):
dependencies:
expo: 54.0.1(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.0)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo: 54.0.2(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo-splash-screen@31.0.8(expo@54.0.1):
expo-splash-screen@31.0.9(expo@54.0.2):
dependencies:
'@expo/prebuild-config': 10.0.8(expo@54.0.1)
expo: 54.0.1(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.0)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
'@expo/prebuild-config': 54.0.1(expo@54.0.2)
expo: 54.0.2(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
transitivePeerDependencies:
- supports-color
expo-status-bar@3.0.7(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
expo-status-bar@3.0.8(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
dependencies:
react: 19.1.0
react-native: 0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0)
react-native-is-edge-to-edge: 1.2.1(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo-symbols@1.0.6(expo@54.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0)):
expo-symbols@1.0.7(expo@54.0.2)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0)):
dependencies:
expo: 54.0.1(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.0)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo: 54.0.2(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
react-native: 0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0)
sf-symbols-typescript: 2.1.0
expo-system-ui@6.0.7(expo@54.0.1)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0)):
expo-system-ui@6.0.7(expo@54.0.2)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0)):
dependencies:
'@react-native/normalize-colors': 0.81.4
debug: 4.4.1
expo: 54.0.1(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.0)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo: 54.0.2(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
react-native: 0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0)
optionalDependencies:
react-native-web: 0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
transitivePeerDependencies:
- supports-color
expo-web-browser@15.0.6(expo@54.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0)):
expo-web-browser@15.0.7(expo@54.0.2)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0)):
dependencies:
expo: 54.0.1(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.0)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo: 54.0.2(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
react-native: 0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0)
expo@54.0.1(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.0)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
expo@54.0.2(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0):
dependencies:
'@babel/runtime': 7.28.3
'@expo/cli': 54.0.1(expo-router@6.0.0)(expo@54.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))
'@expo/cli': 54.0.2(expo-router@6.0.1)(expo@54.0.2)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))
'@expo/config': 12.0.8
'@expo/config-plugins': 54.0.0
'@expo/devtools': 0.1.6(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
'@expo/config-plugins': 54.0.1
'@expo/devtools': 0.1.7(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
'@expo/fingerprint': 0.15.0
'@expo/metro': 0.1.1
'@expo/metro-config': 54.0.1(expo@54.0.1)
'@expo/vector-icons': 15.0.2(expo-font@14.0.7(expo@54.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
'@expo/metro-config': 54.0.2(expo@54.0.2)
'@expo/vector-icons': 15.0.2(expo-font@14.0.8(expo@54.0.2)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
'@ungap/structured-clone': 1.3.0
babel-preset-expo: 54.0.0(@babel/core@7.28.3)(@babel/runtime@7.28.3)(expo@54.0.1)(react-refresh@0.14.2)
expo-asset: 12.0.8(expo@54.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo-constants: 18.0.8(expo@54.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))
expo-file-system: 19.0.11(expo@54.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))
expo-font: 14.0.7(expo@54.0.1)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo-keep-awake: 15.0.6(expo@54.0.1)(react@19.1.0)
babel-preset-expo: 54.0.0(@babel/core@7.28.3)(@babel/runtime@7.28.3)(expo@54.0.2)(react-refresh@0.14.2)
expo-asset: 12.0.8(expo@54.0.2)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo-constants: 18.0.8(expo@54.0.2)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))
expo-file-system: 19.0.12(expo@54.0.2)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))
expo-font: 14.0.8(expo@54.0.2)(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
expo-keep-awake: 15.0.7(expo@54.0.2)(react@19.1.0)
expo-modules-autolinking: 3.0.10
expo-modules-core: 3.0.15(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
pretty-format: 29.7.0
@@ -11089,7 +11061,7 @@ snapshots:
react-refresh: 0.14.2
whatwg-url-without-unicode: 8.0.0-3
optionalDependencies:
'@expo/metro-runtime': 6.1.1(expo@54.0.1)(react-dom@19.1.0(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
'@expo/metro-runtime': 6.1.1(expo@54.0.2)(react-dom@19.1.0(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)
transitivePeerDependencies:
- '@babel/core'
- bufferutil