diff --git a/apps/mobile/package.json b/apps/mobile/package.json index cf30b4a..f7c78fc 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -36,7 +36,7 @@ "@react-navigation/native": "^7.1.8", "@tanstack/react-form": "^1.19.5", "@tanstack/react-query": "^5.87.1", - "expo": "54.0.6", + "expo": "54.0.7", "expo-build-properties": "~1.0.8", "expo-clipboard": "~8.0.7", "expo-constants": "~18.0.8", @@ -48,7 +48,7 @@ "expo-haptics": "~15.0.7", "expo-image": "~3.0.8", "expo-linking": "~8.0.8", - "expo-router": "6.0.3", + "expo-router": "6.0.4", "expo-secure-store": "~15.0.7", "expo-splash-screen": "~31.0.10", "expo-status-bar": "~3.0.8", diff --git a/apps/mobile/src/lib/test-uniffi-russh.ts b/apps/mobile/src/lib/test-uniffi-russh.ts index df7d8c3..3bd0c9b 100644 --- a/apps/mobile/src/lib/test-uniffi-russh.ts +++ b/apps/mobile/src/lib/test-uniffi-russh.ts @@ -1,36 +1,85 @@ import { - Calculator, - type BinaryOperator, - SafeAddition, - type ComputationResult, + generateKeyPair, + KeyType, uniffiInitAsync, } from '@fressh/react-native-uniffi-russh'; void uniffiInitAsync().then(() => { - const calculator = new Calculator(); - - const addOp = new SafeAddition(); - - class SafeMultiply implements BinaryOperator { - perform(lhs: bigint, rhs: bigint): bigint { - return lhs * rhs; - } - } - - const multOp = new SafeMultiply(); - - // bigints - const three = 3n; - const seven = 7n; - - // Perform the calculation, and to get an object - // representing the computation result. - const computation: ComputationResult = calculator - .calculate(addOp, three, three) - .calculateMore(multOp, seven) - .lastResult()!; - - // Unpack the bigint value into a string. - const result = computation.value.toString(); - console.log('AAAAAAAAAAAAAAAAAAAAAAAAAA', result); + const testKeyPair = generateKeyPair(KeyType.Ed25519); + console.log('testKeyPair', testKeyPair); }); + +// // https://jhugman.github.io/uniffi-bindgen-react-native/idioms/common-types.html +// // https://jhugman.github.io/uniffi-bindgen-react-native/idioms/callback-interfaces.html +// // https://jhugman.github.io/uniffi-bindgen-react-native/idioms/async-callbacks.html + +// const connectionDetailsSchema = z.object({ +// host: z.string().min(1), +// port: z.number().min(1), +// username: z.string().min(1), +// security: z.discriminatedUnion('type', [ +// z.object({ +// type: z.literal('password'), +// password: z.string().min(1), +// }), +// z.object({ +// type: z.literal('key'), +// keyId: z.string().min(1), +// }), +// ]), +// }); + +// The ideal interface + +// const connectionDetailsSchema = z.object({ +// host: z.string().min(1), +// port: z.number().min(1), +// username: z.string().min(1), +// // There is a section on tagged enums: https://jhugman.github.io/uniffi-bindgen-react-native/idioms/enums.html#enums-with-properties +// security: z.discriminatedUnion('type', [ +// z.object({ +// type: z.literal('password'), +// password: z.string().min(1), +// }), +// z.object({ +// type: z.literal('key'), +// keyId: z.string().min(1), +// }), +// ]), +// }); + +// type ConnectionDetails = z.infer; + +// type SSHConnectionStatus = +// | 'tcp-connecting' +// | 'tcp-connected' +// | 'tcp-disconnected' +// | 'shell-connecting' +// | 'shell-connected' +// | 'shell-disconnected'; + +// type SSHConnection = { +// connectionDetails: ConnectionDetails; +// sessionId: string; +// createdAtMs: number; +// establishedAtMs: number; +// // I am not sure this is the best way to do this within uniffi. +// addListener: (listener: (data: ArrayBuffer) => void) => void; +// removeListener: (listener: (data: ArrayBuffer) => void) => void; + +// // Also not sure if this is the best way +// sendData: (data: ArrayBuffer) => Promise; +// disconnect: () => Promise; +// }; + +// type SSHConnectParams = { +// connectionDetails: ConnectionDetails; +// onStatusChange: (status: SSHConnectionStatus) => void; +// }; + +// type RustInterface = { +// requestSshConnection: (params: SSHConnectParams) => Promise; +// generateKeyPair: ( +// type: 'rsa' | 'ecdsa' | 'ed25519' | 'ed448', +// ) => Promise; +// }; diff --git a/packages/react-native-uniffi-russh/rust/uniffi-russh/src/lib.rs b/packages/react-native-uniffi-russh/rust/uniffi-russh/src/lib.rs index 63a4a8a..121e2d9 100644 --- a/packages/react-native-uniffi-russh/rust/uniffi-russh/src/lib.rs +++ b/packages/react-native-uniffi-russh/rust/uniffi-russh/src/lib.rs @@ -1,212 +1,181 @@ -use std::sync::Arc; -// You must call this once +// lib.rs (or your crate root) + +use std::sync::{Arc, Mutex}; +use std::time::{SystemTime, UNIX_EPOCH}; +use std::fmt; + + +// You must call this once in your crate uniffi::setup_scaffolding!(); -// What follows is an intentionally ridiculous whirlwind tour of how you'd expose a complex API to UniFFI. +/// ----- Types that mirror your TS schema ----- -#[derive(Debug, PartialEq, uniffi::Enum, Default)] -pub enum ComputationState { - /// Initial state with no value computed - #[default] - Init, - Computed { - result: ComputationResult, - }, +#[derive(Debug, Clone, PartialEq, uniffi::Enum)] +pub enum Security { + Password { password: String }, + Key { key_id: String }, } -#[derive(Copy, Clone, Debug, PartialEq, uniffi::Record)] -pub struct ComputationResult { - pub value: i64, +#[derive(Debug, Clone, PartialEq, uniffi::Record)] +pub struct ConnectionDetails { + pub host: String, + pub port: u16, // maps cleanly to JS number + pub username: String, + pub security: Security, } -#[derive(Debug, PartialEq, thiserror::Error, uniffi::Error)] -pub enum ComputationError { - #[error("Division by zero is not allowed.")] - DivisionByZero, - #[error("Result overflowed the numeric type bounds.")] - Overflow, - #[error("There is no existing computation state, so you cannot perform this operation.")] - IllegalComputationWithInitState, +#[derive(Debug, Clone, Copy, PartialEq, uniffi::Enum)] +pub enum SSHConnectionStatus { + TcpConnecting, + TcpConnected, + TcpDisconnected, + ShellConnecting, + ShellConnected, + ShellDisconnected, } -/// A binary operator that performs some mathematical operation with two numbers. +#[derive(Debug, thiserror::Error, uniffi::Error)] +pub enum SshError { + #[error("The connection is not available.")] + Disconnected, + #[error("Unsupported key type.")] + UnsupportedKeyType, +} + +/// Callback for status changes: onStatusChange(status) #[uniffi::export(with_foreign)] -pub trait BinaryOperator: Send + Sync { - fn perform(&self, lhs: i64, rhs: i64) -> Result; +pub trait StatusListener: Send + Sync { + fn on_status_change(&self, status: SSHConnectionStatus); } -/// A somewhat silly demonstration of functional core/imperative shell in the form of a calculator with arbitrary operators. -/// -/// Operations return a new calculator with updated internal state reflecting the computation. -#[derive(PartialEq, Debug, Default, uniffi::Object)] -pub struct Calculator { - state: ComputationState, +/// Data listener: on_data(ArrayBuffer) +#[uniffi::export(with_foreign)] +pub trait DataListener: Send + Sync { + fn on_data(&self, data: Vec); } -#[uniffi::export] -impl Calculator { - #[uniffi::constructor] - pub fn new() -> Self { - Self::default() - } - - pub fn last_result(&self) -> Option { - match self.state { - ComputationState::Init => None, - ComputationState::Computed { result } => Some(result), - } - } - - /// Performs a calculation using the supplied binary operator and operands. - pub fn calculate( - &self, - op: Arc, - lhs: i64, - rhs: i64, - ) -> Result { - let value = op.perform(lhs, rhs)?; - - Ok(Calculator { - state: ComputationState::Computed { - result: ComputationResult { value }, - }, - }) - } - - /// Performs a calculation using the supplied binary operator, the last computation result, and the supplied operand. - /// - /// The supplied operand will be the right-hand side in the mathematical operation. - pub fn calculate_more( - &self, - op: Arc, - rhs: i64, - ) -> Result { - let ComputationState::Computed { result } = &self.state else { - return Err(ComputationError::IllegalComputationWithInitState); - }; - - let value = op.perform(result.value, rhs)?; - - Ok(Calculator { - state: ComputationState::Computed { - result: ComputationResult { value }, - }, - }) - } +/// Key types +#[derive(Debug, Clone, Copy, PartialEq, uniffi::Enum)] +pub enum KeyType { + Rsa, + Ecdsa, + Ed25519, + Ed448, } +/// ----- SSHConnection object ----- + #[derive(uniffi::Object)] -struct SafeAddition {} +pub struct SSHConnection { + connection_details: ConnectionDetails, + session_id: String, + created_at_ms: f64, + established_at_ms: f64, + listeners: Mutex>>, +} -// Makes it easy to construct from foreign code -#[uniffi::export] -impl SafeAddition { - #[uniffi::constructor] - fn new() -> Self { - SafeAddition {} +impl fmt::Debug for SSHConnection { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("SSHConnection") + .field("connection_details", &self.connection_details) + .field("session_id", &self.session_id) + .field("created_at_ms", &self.created_at_ms) + .field("established_at_ms", &self.established_at_ms) + // Don’t try to print the trait objects; just show count or omit entirely. + .field( + "listeners_len", + &self.listeners.lock().map(|v| v.len()).unwrap_or(0), + ) + .finish() } } #[uniffi::export] -impl BinaryOperator for SafeAddition { - fn perform(&self, lhs: i64, rhs: i64) -> Result { - lhs.checked_add(rhs).ok_or(ComputationError::Overflow) +impl SSHConnection { + // Read-only “properties” via getters (JS sees methods: connectionDetails(), etc.) + pub fn connection_details(&self) -> ConnectionDetails { + self.connection_details.clone() + } + + pub fn session_id(&self) -> String { + self.session_id.clone() + } + + pub fn created_at_ms(&self) -> f64 { + self.created_at_ms + } + + pub fn established_at_ms(&self) -> f64 { + self.established_at_ms + } + + /// Register a data listener (no-op storage for now; we keep it so you can emit later) + pub fn add_data_listener(&self, listener: Arc) { + let mut vec = self.listeners.lock().unwrap(); + vec.push(listener); + // If you want to prove it works, you could immediately emit a hello packet: + // if let Some(last) = vec.last() { + // last.on_data(b"hello-from-rust".to_vec()); + // } + } + + /// Send bytes to the session (dummy async) + pub async fn send_data(&self, _data: Vec) -> Result<(), SshError> { + // No real transport yet; just succeed. + Ok(()) + } + + /// Disconnect (dummy async) + pub async fn disconnect(&self) -> Result<(), SshError> { + // No real transport yet; just succeed. + Ok(()) } } -#[derive(uniffi::Object)] -struct SafeDivision {} +/// ----- Top-level API surface ----- -// Makes it easy to construct from foreign code +/// Connect and emit a few status transitions. Returns a ready SSHConnection. +/// Kept async so JS sees a Promise. #[uniffi::export] -impl SafeDivision { - #[uniffi::constructor] - fn new() -> Self { - SafeDivision {} - } +pub async fn connect( + details: ConnectionDetails, + status_listener: Arc, +) -> Result, SshError> { + // Fire a short, synchronous sequence of status updates (no sleeps needed for now) + status_listener.on_status_change(SSHConnectionStatus::TcpConnecting); + status_listener.on_status_change(SSHConnectionStatus::TcpConnected); + status_listener.on_status_change(SSHConnectionStatus::ShellConnecting); + status_listener.on_status_change(SSHConnectionStatus::ShellConnected); + + let now = now_ms(); + + let conn = Arc::new(SSHConnection { + connection_details: details, + session_id: "SESSION-STATIC-0001".to_string(), + created_at_ms: now, + established_at_ms: now, + listeners: Mutex::new(Vec::new()), + }); + + Ok(conn) } +/// Generate a key pair as a PEM string (dummy content) #[uniffi::export] -impl BinaryOperator for SafeDivision { - fn perform(&self, lhs: i64, rhs: i64) -> Result { - if rhs == 0 { - Err(ComputationError::DivisionByZero) - } else { - lhs.checked_div(rhs).ok_or(ComputationError::Overflow) - } - } +pub async fn generate_key_pair(key_type: KeyType) -> Result { + let pem = match key_type { + KeyType::Rsa => "-----BEGIN RSA PRIVATE KEY-----\n...dummy...\n-----END RSA PRIVATE KEY-----", + KeyType::Ecdsa => "-----BEGIN EC PRIVATE KEY-----\n...dummy...\n-----END EC PRIVATE KEY-----", + KeyType::Ed25519 => "-----BEGIN OPENSSH PRIVATE KEY-----\n...dummy-ed25519...\n-----END OPENSSH PRIVATE KEY-----", + KeyType::Ed448 => "-----BEGIN OPENSSH PRIVATE KEY-----\n...dummy-ed448...\n-----END OPENSSH PRIVATE KEY-----", + }; + Ok(pem.to_string()) } -// Helpers that only exist because the concrete objects above DO NOT have the requisite protocol conformances -// stated in the glue code. It's easy to extend classes in Swift, but you can't just declare a conformance in Kotlin. -// So, to keep things easy, we just do this as a compromise. - -#[uniffi::export] -fn safe_addition_operator() -> Arc { - Arc::new(SafeAddition::new()) -} - -#[uniffi::export] -fn safe_division_operator() -> Arc { - Arc::new(SafeDivision::new()) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn addition() { - let calc = Calculator::new(); - let op = Arc::new(SafeAddition {}); - - let calc = calc - .calculate(op.clone(), 2, 2) - .expect("Something went wrong"); - assert_eq!(calc.last_result().unwrap().value, 4); - - assert_eq!( - calc.calculate_more(op.clone(), i64::MAX), - Err(ComputationError::Overflow) - ); - assert_eq!( - calc.calculate_more(op, 8) - .unwrap() - .last_result() - .unwrap() - .value, - 12 - ); - } - - #[test] - fn division() { - let calc = Calculator::new(); - let op = Arc::new(SafeDivision {}); - - let calc = calc - .calculate(op.clone(), 2, 2) - .expect("Something went wrong"); - assert_eq!(calc.last_result().unwrap().value, 1); - - assert_eq!( - calc.calculate_more(op.clone(), 0), - Err(ComputationError::DivisionByZero) - ); - assert_eq!( - calc.calculate(op, i64::MIN, -1), - Err(ComputationError::Overflow) - ); - } - - #[test] - fn compute_more_from_init_state() { - let calc = Calculator::new(); - let op = Arc::new(SafeAddition {}); - - assert_eq!( - calc.calculate_more(op, 1), - Err(ComputationError::IllegalComputationWithInitState) - ); - } +/// Helper +fn now_ms() -> f64 { + let d = SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap_or_default(); + d.as_millis() as f64 } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 90cfc05..2a9843b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -45,7 +45,7 @@ importers: version: 1.5.20(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) '@expo/vector-icons': specifier: ^15.0.2 - version: 15.0.2(expo-font@14.0.8(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@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.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) '@fressh/assets': specifier: workspace:* version: link:../../packages/assets @@ -74,62 +74,62 @@ importers: specifier: ^5.87.1 version: 5.87.1(react@19.1.0) expo: - specifier: 54.0.6 - version: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + specifier: 54.0.7 + version: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) expo-build-properties: specifier: ~1.0.8 - version: 1.0.8(expo@54.0.6) + version: 1.0.8(expo@54.0.7) expo-clipboard: specifier: ~8.0.7 - version: 8.0.7(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + version: 8.0.7(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) expo-constants: specifier: ~18.0.8 - version: 18.0.8(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) + version: 18.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) expo-crypto: specifier: ~15.0.7 - version: 15.0.7(expo@54.0.6) + version: 15.0.7(expo@54.0.7) expo-dev-client: specifier: ~6.0.12 - version: 6.0.12(expo@54.0.6) + version: 6.0.12(expo@54.0.7) expo-document-picker: specifier: ~14.0.7 - version: 14.0.7(expo@54.0.6) + version: 14.0.7(expo@54.0.7) expo-file-system: specifier: ~19.0.14 - version: 19.0.14(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) + version: 19.0.14(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) expo-font: specifier: ~14.0.8 - version: 14.0.8(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + version: 14.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) expo-haptics: specifier: ~15.0.7 - version: 15.0.7(expo@54.0.6) + version: 15.0.7(expo@54.0.7) expo-image: specifier: ~3.0.8 - version: 3.0.8(expo@54.0.6)(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)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + version: 3.0.8(expo@54.0.7)(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)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) expo-linking: specifier: ~8.0.8 - version: 8.0.8(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + version: 8.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) expo-router: - specifier: 6.0.3 - version: 6.0.3(6213c2891d9a8ed69441ba48cb06d781) + specifier: 6.0.4 + version: 6.0.4(750b4158402c81723fe42a215de7942a) expo-secure-store: specifier: ~15.0.7 - version: 15.0.7(expo@54.0.6) + version: 15.0.7(expo@54.0.7) expo-splash-screen: specifier: ~31.0.10 - version: 31.0.10(expo@54.0.6) + version: 31.0.10(expo@54.0.7) expo-status-bar: specifier: ~3.0.8 version: 3.0.8(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) expo-symbols: specifier: ~1.0.7 - version: 1.0.7(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) + version: 1.0.7(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) expo-system-ui: specifier: ~6.0.7 - version: 6.0.7(expo@54.0.6)(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)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) + version: 6.0.7(expo@54.0.7)(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)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) expo-web-browser: specifier: ~15.0.7 - version: 15.0.7(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) + version: 15.0.7(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) react: specifier: 19.1.0 version: 19.1.0 @@ -1308,8 +1308,8 @@ packages: resolution: {integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@expo/cli@54.0.4': - resolution: {integrity: sha512-n3UukNRL8eG1XyN/sI6UCxvnJqhHxmtgReP2hBJnN9E1R+nPWdYxysV6hw1I/FghL0O/eZou2WTY1E8lGQ3Frw==} + '@expo/cli@54.0.5': + resolution: {integrity: sha512-8MZOZKHfHRHTBQu2/PXBi7eCKc2aF1i1JsZweL/P7aX8nivhrP6KV6An5PtO1/rrdnS9z7pmX2KwMygvvaFNhg==} hasBin: true peerDependencies: expo: '*' @@ -4792,8 +4792,8 @@ packages: react: '*' react-native: '*' - expo-router@6.0.3: - resolution: {integrity: sha512-TNBHE7qMutUB6GlXciNRZYH1H6bxXR6knzsEHQoBypSvCHdFYpq/EvUtc5BG+umHjTJaJq3WVzDFJ8Xl/WP0+w==} + expo-router@6.0.4: + resolution: {integrity: sha512-RZRHAhUCCU6QNTnVhoy0PAJxbLy7OF78F4/4fwJna3cHGTtokPvJYUwz8kOZOOub/7l8jqgxnT7eKAk1dw9uXQ==} peerDependencies: '@expo/metro-runtime': ^6.1.2 '@react-navigation/drawer': ^7.5.0 @@ -4869,8 +4869,8 @@ packages: expo: '*' react-native: '*' - expo@54.0.6: - resolution: {integrity: sha512-fzOrhdMNJiNlQyj7Gj1GvEzwIx1XaOLWRVOoTtaOkWckYJzgsTnnUQhFFGEfb8Vv0tZGeWzx6CFXqjcraxYT7g==} + expo@54.0.7: + resolution: {integrity: sha512-DftN6nMdpHYUCw5Xnh7+h7wnusjtly4JzQknvuD7MzIvqoyJL9uffQyMQrmZkXrUbgm+cKBm47vtooIz4qj0Qg==} hasBin: true peerDependencies: '@expo/dom-webview': '*' @@ -9889,7 +9889,7 @@ snapshots: '@eslint/core': 0.15.2 levn: 0.4.1 - '@expo/cli@54.0.4(expo-router@6.0.3)(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))': + '@expo/cli@54.0.5(expo-router@6.0.4)(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))': dependencies: '@0no-co/graphql.web': 1.2.0 '@expo/code-signing-certificates': 0.0.5 @@ -9900,11 +9900,11 @@ snapshots: '@expo/image-utils': 0.8.7 '@expo/json-file': 10.0.7 '@expo/metro': 0.1.1 - '@expo/metro-config': 54.0.3(expo@54.0.6) + '@expo/metro-config': 54.0.3(expo@54.0.7) '@expo/osascript': 2.3.7 '@expo/package-manager': 1.9.7 '@expo/plist': 0.4.7 - '@expo/prebuild-config': 54.0.3(expo@54.0.6) + '@expo/prebuild-config': 54.0.3(expo@54.0.7) '@expo/schema-utils': 0.1.7 '@expo/server': 0.7.4 '@expo/spawn-async': 1.7.2 @@ -9924,7 +9924,7 @@ snapshots: connect: 3.7.0 debug: 4.4.1 env-editor: 0.4.2 - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@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 @@ -9956,7 +9956,7 @@ snapshots: wrap-ansi: 7.0.0 ws: 8.18.3 optionalDependencies: - expo-router: 6.0.3(6213c2891d9a8ed69441ba48cb06d781) + expo-router: 6.0.4(750b4158402c81723fe42a215de7942a) react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) transitivePeerDependencies: - bufferutil @@ -10111,7 +10111,7 @@ snapshots: '@babel/code-frame': 7.10.4 json5: 2.2.3 - '@expo/metro-config@54.0.3(expo@54.0.6)': + '@expo/metro-config@54.0.3(expo@54.0.7)': dependencies: '@babel/code-frame': 7.27.1 '@babel/core': 7.28.3 @@ -10135,16 +10135,16 @@ snapshots: postcss: 8.4.49 resolve-from: 5.0.0 optionalDependencies: - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@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.6)(react-dom@19.1.0(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)': + '@expo/metro-runtime@6.1.1(expo@54.0.7)(react-dom@19.1.0(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)': dependencies: anser: 1.4.10 - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@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)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) @@ -10198,7 +10198,7 @@ snapshots: base64-js: 1.5.1 xmlbuilder: 15.1.1 - '@expo/prebuild-config@54.0.3(expo@54.0.6)': + '@expo/prebuild-config@54.0.3(expo@54.0.7)': dependencies: '@expo/config': 12.0.9 '@expo/config-plugins': 54.0.1 @@ -10207,7 +10207,7 @@ snapshots: '@expo/json-file': 10.0.7 '@react-native/normalize-colors': 0.81.4 debug: 4.4.1 - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@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 @@ -10231,9 +10231,9 @@ snapshots: '@expo/sudo-prompt@9.3.2': {} - '@expo/vector-icons@15.0.2(expo-font@14.0.8(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@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.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)': dependencies: - expo-font: 14.0.8(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo-font: 14.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@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)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) @@ -12697,7 +12697,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.1(@babel/core@7.28.3)(@babel/runtime@7.28.3)(expo@54.0.6)(react-refresh@0.14.2): + babel-preset-expo@54.0.1(@babel/core@7.28.3)(@babel/runtime@7.28.3)(expo@54.0.7)(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) @@ -12724,7 +12724,7 @@ snapshots: resolve-from: 5.0.0 optionalDependencies: '@babel/runtime': 7.28.3 - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) transitivePeerDependencies: - '@babel/core' - supports-color @@ -14124,93 +14124,93 @@ snapshots: jest-message-util: 29.7.0 jest-util: 29.7.0 - expo-asset@12.0.8(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): + expo-asset@12.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): dependencies: '@expo/image-utils': 0.8.7 - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-constants: 18.0.8(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo-constants: 18.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) react: 19.1.0 react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) transitivePeerDependencies: - supports-color - expo-build-properties@1.0.8(expo@54.0.6): + expo-build-properties@1.0.8(expo@54.0.7): dependencies: ajv: 8.17.1 - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) semver: 7.7.2 - expo-clipboard@8.0.7(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): + expo-clipboard@8.0.7(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): dependencies: - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@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)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) - expo-constants@18.0.8(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)): + expo-constants@18.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)): dependencies: '@expo/config': 12.0.8 '@expo/env': 2.0.7 - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) transitivePeerDependencies: - supports-color - expo-crypto@15.0.7(expo@54.0.6): + expo-crypto@15.0.7(expo@54.0.7): dependencies: base64-js: 1.5.1 - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-dev-client@6.0.12(expo@54.0.6): + expo-dev-client@6.0.12(expo@54.0.7): dependencies: - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-dev-launcher: 6.0.11(expo@54.0.6) - expo-dev-menu: 7.0.11(expo@54.0.6) - expo-dev-menu-interface: 2.0.0(expo@54.0.6) - expo-manifests: 1.0.8(expo@54.0.6) - expo-updates-interface: 2.0.0(expo@54.0.6) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo-dev-launcher: 6.0.11(expo@54.0.7) + expo-dev-menu: 7.0.11(expo@54.0.7) + expo-dev-menu-interface: 2.0.0(expo@54.0.7) + expo-manifests: 1.0.8(expo@54.0.7) + expo-updates-interface: 2.0.0(expo@54.0.7) transitivePeerDependencies: - supports-color - expo-dev-launcher@6.0.11(expo@54.0.6): + expo-dev-launcher@6.0.11(expo@54.0.7): dependencies: - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-dev-menu: 7.0.11(expo@54.0.6) - expo-manifests: 1.0.8(expo@54.0.6) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo-dev-menu: 7.0.11(expo@54.0.7) + expo-manifests: 1.0.8(expo@54.0.7) transitivePeerDependencies: - supports-color - expo-dev-menu-interface@2.0.0(expo@54.0.6): + expo-dev-menu-interface@2.0.0(expo@54.0.7): dependencies: - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-dev-menu@7.0.11(expo@54.0.6): + expo-dev-menu@7.0.11(expo@54.0.7): dependencies: - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-dev-menu-interface: 2.0.0(expo@54.0.6) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo-dev-menu-interface: 2.0.0(expo@54.0.7) - expo-document-picker@14.0.7(expo@54.0.6): + expo-document-picker@14.0.7(expo@54.0.7): dependencies: - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-file-system@19.0.14(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)): + expo-file-system@19.0.14(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)): dependencies: - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) - expo-font@14.0.8(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): + expo-font@14.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): dependencies: - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@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)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) - expo-haptics@15.0.7(expo@54.0.6): + expo-haptics@15.0.7(expo@54.0.7): dependencies: - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-image@3.0.8(expo@54.0.6)(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)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): + expo-image@3.0.8(expo@54.0.7)(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)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): dependencies: - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@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)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) optionalDependencies: @@ -14218,14 +14218,14 @@ snapshots: expo-json-utils@0.15.0: {} - expo-keep-awake@15.0.7(expo@54.0.6)(react@19.1.0): + expo-keep-awake@15.0.7(expo@54.0.7)(react@19.1.0): dependencies: - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) react: 19.1.0 - expo-linking@8.0.8(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): + expo-linking@8.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): dependencies: - expo-constants: 18.0.8(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) + expo-constants: 18.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@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)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) @@ -14233,10 +14233,10 @@ snapshots: - expo - supports-color - expo-manifests@1.0.8(expo@54.0.6): + expo-manifests@1.0.8(expo@54.0.7): dependencies: '@expo/config': 12.0.8 - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) expo-json-utils: 0.15.0 transitivePeerDependencies: - supports-color @@ -14256,9 +14256,9 @@ snapshots: react: 19.1.0 react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) - expo-router@6.0.3(6213c2891d9a8ed69441ba48cb06d781): + expo-router@6.0.4(750b4158402c81723fe42a215de7942a): dependencies: - '@expo/metro-runtime': 6.1.1(expo@54.0.6)(react-dom@19.1.0(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + '@expo/metro-runtime': 6.1.1(expo@54.0.7)(react-dom@19.1.0(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@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) @@ -14269,9 +14269,9 @@ snapshots: client-only: 0.0.1 debug: 4.4.1 escape-string-regexp: 4.0.0 - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-constants: 18.0.8(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) - expo-linking: 8.0.8(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo-constants: 18.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) + expo-linking: 8.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@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 @@ -14299,14 +14299,14 @@ snapshots: - '@types/react-dom' - supports-color - expo-secure-store@15.0.7(expo@54.0.6): + expo-secure-store@15.0.7(expo@54.0.7): dependencies: - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-splash-screen@31.0.10(expo@54.0.6): + expo-splash-screen@31.0.10(expo@54.0.7): dependencies: - '@expo/prebuild-config': 54.0.3(expo@54.0.6) - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + '@expo/prebuild-config': 54.0.3(expo@54.0.7) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) transitivePeerDependencies: - supports-color @@ -14316,50 +14316,50 @@ snapshots: react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@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)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-symbols@1.0.7(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)): + expo-symbols@1.0.7(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)): dependencies: - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) sf-symbols-typescript: 2.1.0 - expo-system-ui@6.0.7(expo@54.0.6)(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)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)): + expo-system-ui@6.0.7(expo@54.0.7)(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)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)): dependencies: '@react-native/normalize-colors': 0.81.4 debug: 4.4.1 - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@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-updates-interface@2.0.0(expo@54.0.6): + expo-updates-interface@2.0.0(expo@54.0.7): dependencies: - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-web-browser@15.0.7(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)): + expo-web-browser@15.0.7(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)): dependencies: - expo: 54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) - expo@54.0.6(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.3)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): + expo@54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.4)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): dependencies: '@babel/runtime': 7.28.3 - '@expo/cli': 54.0.4(expo-router@6.0.3)(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) + '@expo/cli': 54.0.5(expo-router@6.0.4)(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) '@expo/config': 12.0.9 '@expo/config-plugins': 54.0.1 '@expo/devtools': 0.1.7(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@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.3(expo@54.0.6) - '@expo/vector-icons': 15.0.2(expo-font@14.0.8(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + '@expo/metro-config': 54.0.3(expo@54.0.7) + '@expo/vector-icons': 15.0.2(expo-font@14.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) '@ungap/structured-clone': 1.3.0 - babel-preset-expo: 54.0.1(@babel/core@7.28.3)(@babel/runtime@7.28.3)(expo@54.0.6)(react-refresh@0.14.2) - expo-asset: 12.0.8(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-constants: 18.0.8(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) - expo-file-system: 19.0.14(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) - expo-font: 14.0.8(expo@54.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-keep-awake: 15.0.7(expo@54.0.6)(react@19.1.0) + babel-preset-expo: 54.0.1(@babel/core@7.28.3)(@babel/runtime@7.28.3)(expo@54.0.7)(react-refresh@0.14.2) + expo-asset: 12.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo-constants: 18.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) + expo-file-system: 19.0.14(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) + expo-font: 14.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo-keep-awake: 15.0.7(expo@54.0.7)(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)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) pretty-format: 29.7.0 @@ -14368,7 +14368,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.6)(react-dom@19.1.0(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + '@expo/metro-runtime': 6.1.1(expo@54.0.7)(react-dom@19.1.0(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) transitivePeerDependencies: - '@babel/core' - bufferutil