diff --git a/mobile/.gitignore b/mobile/.gitignore
index 954fc662..8f88897e 100644
--- a/mobile/.gitignore
+++ b/mobile/.gitignore
@@ -1,37 +1,8 @@
-# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files
-
-# dependencies
node_modules/
-
-# Expo
.expo/
dist/
-web-build/
-expo-env.d.ts
-
-# Native
-.kotlin/
-*.orig.*
-*.jks
-*.p8
-*.p12
-*.key
-*.mobileprovision
-
-# Metro
-.metro-health-check*
-
-# debug
-npm-debug.*
-yarn-debug.*
-yarn-error.*
-
-# macOS
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+# MacOS
.DS_Store
-*.pem
-
-# local env files
-.env*.local
-
-# typescript
-*.tsbuildinfo
diff --git a/mobile/App.js b/mobile/App.js
deleted file mode 100644
index f5496adf..00000000
--- a/mobile/App.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import React from 'react';
-import AppNavigator from './navigation/AppNavigator';
-import { PaperProvider } from 'react-native-paper';
-import { AuthProvider } from './context/AuthContext';
-
-export default function App() {
- return (
-
-
-
-
-
- );
-}
diff --git a/mobile/api/auth.js b/mobile/api/auth.js
deleted file mode 100644
index 46e0426b..00000000
--- a/mobile/api/auth.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import { apiClient } from "./client";
-
-export const login = (email, password) => {
- return apiClient.post("/auth/login/email", { email, password });
-};
-
-export const signup = (name, email, password) => {
- return apiClient.post("/auth/signup/email", { name, email, password });
-};
-
-export const updateUser = (userData) => apiClient.patch("/users/me", userData);
-
-export const refresh = (refresh_token) => {
- return apiClient.post("/auth/refresh", { refresh_token });
-};
diff --git a/mobile/api/client.js b/mobile/api/client.js
deleted file mode 100644
index 958a06b9..00000000
--- a/mobile/api/client.js
+++ /dev/null
@@ -1,117 +0,0 @@
-import axios from "axios";
-
-const API_URL = "https://splitwiser-production.up.railway.app";
-
-let accessToken = null;
-let refreshToken = null;
-let isRefreshing = false;
-let refreshPromise = null;
-let tokenUpdateListener = null; // function({ accessToken, refreshToken })
-
-export const setTokenUpdateListener = (fn) => {
- tokenUpdateListener = fn;
-};
-
-export const setAuthTokens = async ({ newAccessToken, newRefreshToken }) => {
- if (newAccessToken) accessToken = newAccessToken;
- if (newRefreshToken) refreshToken = newRefreshToken;
-};
-
-export const clearAuthTokens = async () => {
- accessToken = null;
- refreshToken = null;
-};
-
-export const getAccessToken = () => accessToken;
-export const getRefreshToken = () => refreshToken;
-
-export const apiClient = axios.create({
- baseURL: API_URL,
- headers: { "Content-Type": "application/json" },
-});
-
-// Basic retry configuration
-const MAX_RETRIES = 3;
-const BASE_DELAY_MS = 300; // base backoff
-
-function sleep(ms) {
- return new Promise((res) => setTimeout(res, ms));
-}
-
-// Attach Authorization header
-apiClient.interceptors.request.use((config) => {
- if (accessToken && !config.headers?.Authorization) {
- config.headers = config.headers || {};
- config.headers.Authorization = `Bearer ${accessToken}`;
- }
- return config;
-});
-
-async function performRefresh() {
- // Avoid multiple refresh calls
- if (isRefreshing && refreshPromise) return refreshPromise;
- isRefreshing = true;
- refreshPromise = (async () => {
- try {
- if (!refreshToken) throw new Error("No refresh token");
- const resp = await axios.post(
- `${API_URL}/auth/refresh`,
- { refresh_token: refreshToken },
- { headers: { "Content-Type": "application/json" } }
- );
- const { access_token, refresh_token } = resp.data || {};
- accessToken = access_token || accessToken;
- refreshToken = refresh_token || refreshToken;
- // Notify listener (AuthContext) so it can persist & update state
- if (tokenUpdateListener) {
- tokenUpdateListener({ accessToken, refreshToken });
- }
- return accessToken;
- } finally {
- isRefreshing = false;
- // allow GC of the completed promise
- refreshPromise = null;
- }
- })();
- return refreshPromise;
-}
-
-// Retry logic on 401
-apiClient.interceptors.response.use(
- (response) => response,
- async (error) => {
- const originalRequest = error.config || {};
- const status = error.response?.status;
-
- // Avoid refresh loop
- const isAuthRefreshCall = originalRequest.url?.includes("/auth/refresh");
-
- // 1. Handle 401 with refresh
- if (status === 401 && !originalRequest._retry && !isAuthRefreshCall) {
- originalRequest._retry = true;
- try {
- await performRefresh();
- originalRequest.headers = originalRequest.headers || {};
- if (accessToken)
- originalRequest.headers.Authorization = `Bearer ${accessToken}`;
- return apiClient(originalRequest);
- } catch (e) {
- return Promise.reject(error);
- }
- }
-
- // 2. Retry on network errors or 5xx (all methods; caller should ensure idempotency where needed)
- const transientError = !status || (status >= 500 && status < 600);
- if (transientError) {
- originalRequest._retryCount = originalRequest._retryCount || 0;
- if (originalRequest._retryCount < MAX_RETRIES) {
- originalRequest._retryCount += 1;
- const delay = BASE_DELAY_MS * 2 ** (originalRequest._retryCount - 1);
- await sleep(delay + Math.random() * 100); // jitter
- return apiClient(originalRequest);
- }
- }
-
- return Promise.reject(error);
- }
-);
diff --git a/mobile/api/groups.js b/mobile/api/groups.js
deleted file mode 100644
index 8cf9cdba..00000000
--- a/mobile/api/groups.js
+++ /dev/null
@@ -1,47 +0,0 @@
-import { apiClient } from "./client";
-
-export const getGroups = () => apiClient.get("/groups");
-
-export const getOptimizedSettlements = (groupId) =>
- apiClient.post(`/groups/${groupId}/settlements/optimize`, {});
-
-export const createExpense = (groupId, expenseData) =>
- apiClient.post(`/groups/${groupId}/expenses`, expenseData);
-
-export const getGroupDetails = (groupId) => {
- return Promise.all([getGroupMembers(groupId), getGroupExpenses(groupId)]);
-};
-
-export const getGroupMembers = (groupId) =>
- apiClient.get(`/groups/${groupId}/members`);
-
-export const getGroupExpenses = (groupId) =>
- apiClient.get(`/groups/${groupId}/expenses`);
-
-export const createGroup = (name) => apiClient.post("/groups", { name });
-
-export const joinGroup = (joinCode) =>
- apiClient.post("/groups/join", { joinCode });
-
-export const getUserBalanceSummary = () =>
- apiClient.get("/users/me/balance-summary");
-
-export const getFriendsBalance = () =>
- apiClient.get("/users/me/friends-balance");
-
-// New APIs for Group Settings
-export const getGroupById = (groupId) => apiClient.get(`/groups/${groupId}`);
-
-export const updateGroup = (groupId, updates) =>
- apiClient.patch(`/groups/${groupId}`, updates);
-
-export const deleteGroup = (groupId) => apiClient.delete(`/groups/${groupId}`);
-
-export const leaveGroup = (groupId) =>
- apiClient.post(`/groups/${groupId}/leave`, {});
-
-export const updateMemberRole = (groupId, memberId, role) =>
- apiClient.patch(`/groups/${groupId}/members/${memberId}`, { role });
-
-export const removeMember = (groupId, memberId) =>
- apiClient.delete(`/groups/${groupId}/members/${memberId}`);
diff --git a/mobile/app.json b/mobile/app.json
index db409293..8c2ae583 100644
--- a/mobile/app.json
+++ b/mobile/app.json
@@ -1,35 +1,51 @@
{
"expo": {
- "name": "frontend",
- "slug": "frontend",
- "platforms": ["ios", "android", "web"],
+ "name": "Splitwiser Mobile",
+ "slug": "splitwiser-mobile",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/icon.png",
"userInterfaceStyle": "light",
- "newArchEnabled": true,
"splash": {
- "image": "./assets/splash-icon.png",
+ "image": "./assets/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
+ "assetBundlePatterns": [
+ "**/*"
+ ],
"ios": {
"supportsTablet": true,
- "infoPlist": {
- "NSPhotoLibraryUsageDescription": "Allow Splitwiser to select a group icon from your photo library."
- }
+ "bundleIdentifier": "com.splitwiser.mobile"
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#ffffff"
},
- "edgeToEdgeEnabled": true,
- "permissions": ["READ_MEDIA_IMAGES"]
+ "package": "com.splitwiser.mobile"
},
"web": {
- "favicon": "./assets/favicon.png"
+ "favicon": "./assets/favicon.png",
+ "bundler": "metro"
},
+ "plugins": [
+ "expo-router",
+ "expo-font",
+ [
+ "expo-build-properties",
+ {
+ "android": {
+ "newArchEnabled": true
+ },
+ "ios": {
+ "newArchEnabled": true
+ }
+ }
+ ]
+ ],
+ "scheme": "splitwiser",
+ "newArchEnabled": true,
"extra": {
"eas": {
"projectId": "afe97159-52c4-425a-9ce3-c56d4f2cb568"
diff --git a/mobile/app/_layout.tsx b/mobile/app/_layout.tsx
new file mode 100644
index 00000000..db8898b9
--- /dev/null
+++ b/mobile/app/_layout.tsx
@@ -0,0 +1,40 @@
+import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';
+import { useFonts } from 'expo-font';
+import { Stack } from 'expo-router';
+import * as SplashScreen from 'expo-splash-screen';
+import { useEffect } from 'react';
+import { Inter_400Regular, Inter_700Bold } from '@expo-google-fonts/inter';
+import { SpaceGrotesk_400Regular, SpaceGrotesk_700Bold } from '@expo-google-fonts/space-grotesk';
+import "../global.css";
+import { StatusBar } from 'expo-status-bar';
+
+// Prevent the splash screen from auto-hiding before asset loading is complete.
+SplashScreen.preventAutoHideAsync();
+
+export default function RootLayout() {
+ const [loaded] = useFonts({
+ Inter_400Regular,
+ Inter_700Bold,
+ SpaceGrotesk_400Regular,
+ SpaceGrotesk_700Bold,
+ });
+
+ useEffect(() => {
+ if (loaded) {
+ SplashScreen.hideAsync();
+ }
+ }, [loaded]);
+
+ if (!loaded) {
+ return null;
+ }
+
+ return (
+
+
+
+
+
+
+ );
+}
diff --git a/mobile/app/index.tsx b/mobile/app/index.tsx
new file mode 100644
index 00000000..03f7c841
--- /dev/null
+++ b/mobile/app/index.tsx
@@ -0,0 +1,100 @@
+import { View, ScrollView } from 'react-native';
+import { ThemedText, ThemedButton, ThemedView } from '../components/Themed';
+import { NeoCard } from '../components/NeoCard';
+import { SafeAreaView } from 'react-native-safe-area-context';
+import { Wallet, PieChart, TrendingUp, ArrowRight } from 'lucide-react-native';
+
+export default function HomeScreen() {
+ return (
+
+
+
+
+ {/* Header */}
+
+ Hello, Jules!
+ Welcome back to Splitwiser.
+
+
+ {/* Balance Card */}
+
+
+ TOTAL BALANCE
+
+
+ $1,234.56
+
+
+ +2.4% this month
+
+
+
+
+ {/* Quick Actions */}
+
+ console.log('Add Expense')}
+ />
+ console.log('Settle Up')}
+ />
+
+
+ {/* Recent Activity */}
+
+ Recent Activity
+ View All
+
+
+
+
+
+
+
+
+
+ Grocery Run
+ Yesterday
+
+
+ -$45.00
+
+
+
+
+
+
+
+
+ Movie Night
+ 2 days ago
+
+
+ +$12.50
+
+
+
+
+
+
+
+
+ Rent Payment
+ Oct 1
+
+
+ -$800.00
+
+
+
+
+
+
+ );
+}
diff --git a/mobile/assets/adaptive-icon.png b/mobile/assets/adaptive-icon.png
deleted file mode 100644
index adc6e21d..00000000
Binary files a/mobile/assets/adaptive-icon.png and /dev/null differ
diff --git a/mobile/assets/adaptive-icon/background.png b/mobile/assets/adaptive-icon/background.png
deleted file mode 100644
index 0a4332a6..00000000
Binary files a/mobile/assets/adaptive-icon/background.png and /dev/null differ
diff --git a/mobile/assets/adaptive-icon/foreground.png b/mobile/assets/adaptive-icon/foreground.png
deleted file mode 100644
index b56ddd29..00000000
Binary files a/mobile/assets/adaptive-icon/foreground.png and /dev/null differ
diff --git a/mobile/assets/favicon.png b/mobile/assets/favicon.png
deleted file mode 100644
index ffd2b4ae..00000000
Binary files a/mobile/assets/favicon.png and /dev/null differ
diff --git a/mobile/assets/icon.png b/mobile/assets/icon.png
deleted file mode 100644
index adc6e21d..00000000
Binary files a/mobile/assets/icon.png and /dev/null differ
diff --git a/mobile/assets/pwa/chrome-icon/chrome-icon-144.png b/mobile/assets/pwa/chrome-icon/chrome-icon-144.png
deleted file mode 100644
index 8afeeeaa..00000000
Binary files a/mobile/assets/pwa/chrome-icon/chrome-icon-144.png and /dev/null differ
diff --git a/mobile/assets/pwa/chrome-icon/chrome-icon-192.png b/mobile/assets/pwa/chrome-icon/chrome-icon-192.png
deleted file mode 100644
index 77bb31f9..00000000
Binary files a/mobile/assets/pwa/chrome-icon/chrome-icon-192.png and /dev/null differ
diff --git a/mobile/assets/pwa/chrome-icon/chrome-icon-512.png b/mobile/assets/pwa/chrome-icon/chrome-icon-512.png
deleted file mode 100644
index 3ef334e5..00000000
Binary files a/mobile/assets/pwa/chrome-icon/chrome-icon-512.png and /dev/null differ
diff --git a/mobile/assets/splash-icon.png b/mobile/assets/splash-icon.png
deleted file mode 100644
index 03d6f6b6..00000000
Binary files a/mobile/assets/splash-icon.png and /dev/null differ
diff --git a/mobile/assets/splash.png b/mobile/assets/splash.png
deleted file mode 100644
index 26c97a31..00000000
Binary files a/mobile/assets/splash.png and /dev/null differ
diff --git a/mobile/babel.config.js b/mobile/babel.config.js
new file mode 100644
index 00000000..4b84a6b2
--- /dev/null
+++ b/mobile/babel.config.js
@@ -0,0 +1,12 @@
+module.exports = function (api) {
+ api.cache(true);
+ return {
+ presets: [
+ ["babel-preset-expo", { jsxImportSource: "nativewind" }],
+ "nativewind/babel",
+ ],
+ plugins: [
+ "react-native-reanimated/plugin",
+ ],
+ };
+};
diff --git a/mobile/components/NeoCard.tsx b/mobile/components/NeoCard.tsx
new file mode 100644
index 00000000..c5cb3fa8
--- /dev/null
+++ b/mobile/components/NeoCard.tsx
@@ -0,0 +1,15 @@
+import { View } from 'react-native';
+import { cn } from '../lib/utils';
+
+interface CardProps {
+ className?: string;
+ children: React.ReactNode;
+}
+
+export function NeoCard({ className, children }: CardProps) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/mobile/components/Themed.tsx b/mobile/components/Themed.tsx
new file mode 100644
index 00000000..50213ddf
--- /dev/null
+++ b/mobile/components/Themed.tsx
@@ -0,0 +1,45 @@
+import { View, Text, ViewProps, TouchableOpacity, TextProps } from 'react-native';
+import { cn } from '../lib/utils';
+
+export function ThemedView({ style, className, ...otherProps }: ViewProps & { className?: string }) {
+ return ;
+}
+
+export function ThemedText({ style, className, type = 'default', ...otherProps }: TextProps & { className?: string, type?: 'title' | 'subtitle' | 'default' | 'defaultSemiBold' | 'link' }) {
+ const getStyles = () => {
+ switch (type) {
+ case 'title': return "text-4xl font-mono-bold text-neo-dark";
+ case 'subtitle': return "text-2xl font-mono-bold text-neo-dark";
+ case 'defaultSemiBold': return "text-base font-sans-bold text-neo-dark";
+ case 'link': return "text-base font-sans text-neo-main underline";
+ default: return "text-base font-sans text-neo-dark";
+ }
+ };
+
+ return ;
+}
+
+export function ThemedButton({ title, onPress, variant = 'primary', className, ...otherProps }: { title: string, onPress?: () => void, variant?: 'primary' | 'secondary' | 'accent', className?: string }) {
+ const getBgColor = () => {
+ switch(variant) {
+ case 'secondary': return "bg-neo-second";
+ case 'accent': return "bg-neo-accent";
+ default: return "bg-neo-main";
+ }
+ }
+
+ return (
+
+ {title}
+
+ );
+}
diff --git a/mobile/constants/colors.ts b/mobile/constants/colors.ts
new file mode 100644
index 00000000..97de42c6
--- /dev/null
+++ b/mobile/constants/colors.ts
@@ -0,0 +1,10 @@
+export const COLORS = {
+ neo: {
+ main: '#8855ff',
+ second: '#ff9900',
+ accent: '#00cc88',
+ bg: '#f0f0f0',
+ dark: '#1a1a1a',
+ white: '#ffffff',
+ }
+};
diff --git a/mobile/context/AuthContext.js b/mobile/context/AuthContext.js
deleted file mode 100644
index 1caf5326..00000000
--- a/mobile/context/AuthContext.js
+++ /dev/null
@@ -1,190 +0,0 @@
-import AsyncStorage from "@react-native-async-storage/async-storage";
-import { createContext, useEffect, useState } from "react";
-import * as authApi from "../api/auth";
-import {
- clearAuthTokens,
- setAuthTokens,
- setTokenUpdateListener,
-} from "../api/client";
-
-export const AuthContext = createContext();
-
-export const AuthProvider = ({ children }) => {
- const [user, setUser] = useState(null);
- const [token, setToken] = useState(null);
- const [refresh, setRefresh] = useState(null);
- const [isLoading, setIsLoading] = useState(true);
-
- // Load token and user data from AsyncStorage on app start
- useEffect(() => {
- const loadStoredAuth = async () => {
- try {
- const storedToken = await AsyncStorage.getItem("auth_token");
- const storedRefresh = await AsyncStorage.getItem("refresh_token");
- const storedUser = await AsyncStorage.getItem("user_data");
-
- if (storedToken && storedUser) {
- setToken(storedToken);
- setRefresh(storedRefresh);
- await setAuthTokens({
- newAccessToken: storedToken,
- newRefreshToken: storedRefresh,
- });
- // Normalize user id shape: ensure `_id` exists even if API stored `id`
- const parsed = JSON.parse(storedUser);
- const normalized = parsed?._id
- ? parsed
- : parsed?.id
- ? { ...parsed, _id: parsed.id }
- : parsed;
- setUser(normalized);
- }
- } catch (error) {
- console.error("Failed to load stored authentication:", error);
- } finally {
- setIsLoading(false);
- }
- };
-
- loadStoredAuth();
- }, []);
-
- // Subscribe to token updates from the api client (refresh flow)
- useEffect(() => {
- setTokenUpdateListener(async ({ accessToken, refreshToken }) => {
- if (accessToken && accessToken !== token) setToken(accessToken);
- if (refreshToken && refreshToken !== refresh) setRefresh(refreshToken);
- });
- }, [token, refresh]);
-
- // Save tokens to AsyncStorage whenever they change
- useEffect(() => {
- const saveToken = async () => {
- try {
- if (token) {
- await AsyncStorage.setItem("auth_token", token);
- } else {
- await AsyncStorage.removeItem("auth_token");
- }
- } catch (error) {
- console.error("Failed to save token to storage:", error);
- }
- };
-
- saveToken();
- }, [token]);
-
- useEffect(() => {
- const saveRefresh = async () => {
- try {
- if (refresh) {
- await AsyncStorage.setItem("refresh_token", refresh);
- } else {
- await AsyncStorage.removeItem("refresh_token");
- }
- } catch (error) {
- console.error("Failed to save refresh token to storage:", error);
- }
- };
- saveRefresh();
- }, [refresh]);
-
- // Save user data to AsyncStorage whenever it changes
- useEffect(() => {
- const saveUser = async () => {
- try {
- if (user) {
- await AsyncStorage.setItem("user_data", JSON.stringify(user));
- } else {
- await AsyncStorage.removeItem("user_data");
- }
- } catch (error) {
- console.error("Failed to save user data to storage:", error);
- }
- };
-
- saveUser();
- }, [user]);
-
- const login = async (email, password) => {
- try {
- const response = await authApi.login(email, password);
- const { access_token, refresh_token, user: userData } = response.data;
- setToken(access_token);
- setRefresh(refresh_token);
- await setAuthTokens({
- newAccessToken: access_token,
- newRefreshToken: refresh_token,
- });
- // Normalize user id shape: ensure `_id` exists even if backend returns `id`
- const normalizedUser = userData?._id
- ? userData
- : userData?.id
- ? { ...userData, _id: userData.id }
- : userData;
- setUser(normalizedUser);
- return true;
- } catch (error) {
- console.error(
- "Login failed:",
- error.response?.data?.detail || error.message
- );
- return false;
- }
- };
-
- const signup = async (name, email, password) => {
- try {
- await authApi.signup(name, email, password);
- return true;
- } catch (error) {
- console.error(
- "Signup failed:",
- error.response?.data?.detail || error.message
- );
- return false;
- }
- };
-
- const logout = async () => {
- try {
- // Clear stored authentication data
- await AsyncStorage.removeItem("auth_token");
- await AsyncStorage.removeItem("refresh_token");
- await AsyncStorage.removeItem("user_data");
- } catch (error) {
- console.error("Failed to clear stored authentication:", error);
- }
-
- setToken(null);
- setRefresh(null);
- setUser(null);
- await clearAuthTokens();
- };
-
- const updateUserInContext = (updatedUser) => {
- // Normalize on updates too
- const normalizedUser = updatedUser?._id
- ? updatedUser
- : updatedUser?.id
- ? { ...updatedUser, _id: updatedUser.id }
- : updatedUser;
- setUser(normalizedUser);
- };
-
- return (
-
- {children}
-
- );
-};
diff --git a/mobile/global.css b/mobile/global.css
new file mode 100644
index 00000000..b5c61c95
--- /dev/null
+++ b/mobile/global.css
@@ -0,0 +1,3 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
diff --git a/mobile/index.js b/mobile/index.js
deleted file mode 100644
index 1d6e981e..00000000
--- a/mobile/index.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import { registerRootComponent } from 'expo';
-
-import App from './App';
-
-// registerRootComponent calls AppRegistry.registerComponent('main', () => App);
-// It also ensures that whether you load the app in Expo Go or in a native build,
-// the environment is set up appropriately
-registerRootComponent(App);
diff --git a/mobile/lib/utils.ts b/mobile/lib/utils.ts
new file mode 100644
index 00000000..365058ce
--- /dev/null
+++ b/mobile/lib/utils.ts
@@ -0,0 +1,6 @@
+import { type ClassValue, clsx } from "clsx";
+import { twMerge } from "tailwind-merge";
+
+export function cn(...inputs: ClassValue[]) {
+ return twMerge(clsx(inputs));
+}
diff --git a/mobile/metro.config.js b/mobile/metro.config.js
new file mode 100644
index 00000000..b0963fe7
--- /dev/null
+++ b/mobile/metro.config.js
@@ -0,0 +1,6 @@
+const { getDefaultConfig } = require("expo/metro-config");
+const { withNativeWind } = require("nativewind/metro");
+
+const config = getDefaultConfig(__dirname);
+
+module.exports = withNativeWind(config, { input: "./global.css" });
diff --git a/mobile/nativewind-env.d.ts b/mobile/nativewind-env.d.ts
new file mode 100644
index 00000000..a13e3136
--- /dev/null
+++ b/mobile/nativewind-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/mobile/navigation/AccountStackNavigator.js b/mobile/navigation/AccountStackNavigator.js
deleted file mode 100644
index 4a5b21d8..00000000
--- a/mobile/navigation/AccountStackNavigator.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import React from 'react';
-import { createNativeStackNavigator } from '@react-navigation/native-stack';
-import AccountScreen from '../screens/AccountScreen';
-import EditProfileScreen from '../screens/EditProfileScreen';
-
-const Stack = createNativeStackNavigator();
-
-const AccountStackNavigator = () => {
- return (
-
-
-
-
- );
-};
-
-export default AccountStackNavigator;
diff --git a/mobile/navigation/AppNavigator.js b/mobile/navigation/AppNavigator.js
deleted file mode 100644
index f24c3354..00000000
--- a/mobile/navigation/AppNavigator.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import React, { useContext } from 'react';
-import { NavigationContainer } from '@react-navigation/native';
-import { View, ActivityIndicator, StyleSheet } from 'react-native';
-import { AuthContext } from '../context/AuthContext';
-import AuthNavigator from './AuthNavigator';
-import MainNavigator from './MainNavigator';
-
-const AppNavigator = () => {
- const { token, isLoading } = useContext(AuthContext);
-
- if (isLoading) {
- return (
-
-
-
- );
- }
-
- return (
-
- {token ? : }
-
- );
-};
-
-const styles = StyleSheet.create({
- loaderContainer: {
- flex: 1,
- justifyContent: 'center',
- alignItems: 'center',
- }
-})
-
-export default AppNavigator;
diff --git a/mobile/navigation/AuthNavigator.js b/mobile/navigation/AuthNavigator.js
deleted file mode 100644
index 55837d79..00000000
--- a/mobile/navigation/AuthNavigator.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import React from 'react';
-import { createNativeStackNavigator } from '@react-navigation/native-stack';
-import LoginScreen from '../screens/LoginScreen';
-import SignupScreen from '../screens/SignupScreen';
-
-const Stack = createNativeStackNavigator();
-
-const AuthNavigator = () => {
- return (
-
-
-
-
- );
-};
-
-export default AuthNavigator;
diff --git a/mobile/navigation/GroupsStackNavigator.js b/mobile/navigation/GroupsStackNavigator.js
deleted file mode 100644
index 5ede954d..00000000
--- a/mobile/navigation/GroupsStackNavigator.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import { createNativeStackNavigator } from '@react-navigation/native-stack';
-import AddExpenseScreen from '../screens/AddExpenseScreen';
-import GroupDetailsScreen from '../screens/GroupDetailsScreen';
-import GroupSettingsScreen from '../screens/GroupSettingsScreen';
-import HomeScreen from '../screens/HomeScreen';
-import JoinGroupScreen from '../screens/JoinGroupScreen';
-
-const Stack = createNativeStackNavigator();
-
-const GroupsStackNavigator = () => {
- return (
-
-
-
-
-
-
-
- );
-};
-
-export default GroupsStackNavigator;
diff --git a/mobile/navigation/MainNavigator.js b/mobile/navigation/MainNavigator.js
deleted file mode 100644
index dc9d32a2..00000000
--- a/mobile/navigation/MainNavigator.js
+++ /dev/null
@@ -1,44 +0,0 @@
-import React from 'react';
-import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
-import { MaterialCommunityIcons } from '@expo/vector-icons';
-import GroupsStackNavigator from './GroupsStackNavigator';
-import FriendsScreen from '../screens/FriendsScreen';
-import AccountStackNavigator from './AccountStackNavigator';
-
-const Tab = createBottomTabNavigator();
-
-const MainNavigator = () => {
- return (
-
- (
-
- ),
- }}
- />
- (
-
- ),
- }}
- />
- (
-
- ),
- }}
- />
-
- );
-};
-
-export default MainNavigator;
diff --git a/mobile/package-lock.json b/mobile/package-lock.json
index 329f6465..298f6917 100644
--- a/mobile/package-lock.json
+++ b/mobile/package-lock.json
@@ -8,25 +8,36 @@
"name": "mobile",
"version": "1.0.0",
"dependencies": {
- "@expo/metro-runtime": "~6.1.2",
- "@react-native-async-storage/async-storage": "^2.1.2",
- "@react-navigation/bottom-tabs": "^7.4.4",
- "@react-navigation/native": "^7.1.16",
- "@react-navigation/native-stack": "^7.3.23",
- "axios": "^1.11.0",
- "expo": "^54.0.25",
- "expo-image-picker": "~17.0.8",
+ "@expo-google-fonts/inter": "^0.2.3",
+ "@expo-google-fonts/space-grotesk": "^0.2.3",
+ "clsx": "^2.1.1",
+ "expo": "~54.0.25",
+ "expo-build-properties": "^1.0.9",
+ "expo-constants": "~18.0.10",
+ "expo-linking": "~8.0.9",
+ "expo-router": "~6.0.15",
+ "expo-splash-screen": "^31.0.11",
"expo-status-bar": "~3.0.8",
+ "expo-system-ui": "~6.0.8",
+ "lucide-react-native": "^0.475.0",
+ "nativewind": "^4.1.23",
"react": "19.1.0",
"react-dom": "19.1.0",
"react-native": "0.81.5",
- "react-native-paper": "^5.14.5",
- "react-native-safe-area-context": "^5.4.0",
- "react-native-screens": "^4.11.1",
- "react-native-web": "^0.21.0"
+ "react-native-css-interop": "^0.1.22",
+ "react-native-reanimated": "~4.1.1",
+ "react-native-safe-area-context": "~5.6.0",
+ "react-native-screens": "~4.16.0",
+ "react-native-svg": "15.12.1",
+ "react-native-web": "~0.21.0",
+ "react-native-worklets": "^0.6.1",
+ "tailwind-merge": "^2.5.2",
+ "tailwindcss": "^3.4.17"
},
"devDependencies": {
- "@babel/core": "^7.20.0"
+ "@babel/core": "^7.20.0",
+ "@types/react": "~19.1.10",
+ "typescript": "^5.1.3"
}
},
"node_modules/@0no-co/graphql.web": {
@@ -43,17 +54,16 @@
}
}
},
- "node_modules/@ampproject/remapping": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
- "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
- "license": "Apache-2.0",
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.24"
- },
+ "node_modules/@alloc/quick-lru": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
+ "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
+ "license": "MIT",
"engines": {
- "node": ">=6.0.0"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@babel/code-frame": {
@@ -71,31 +81,31 @@
}
},
"node_modules/@babel/compat-data": {
- "version": "7.28.0",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz",
- "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==",
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz",
+ "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/core": {
- "version": "7.28.0",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.0.tgz",
- "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==",
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz",
+ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
"license": "MIT",
"peer": true,
"dependencies": {
- "@ampproject/remapping": "^2.2.0",
"@babel/code-frame": "^7.27.1",
- "@babel/generator": "^7.28.0",
+ "@babel/generator": "^7.28.5",
"@babel/helper-compilation-targets": "^7.27.2",
- "@babel/helper-module-transforms": "^7.27.3",
- "@babel/helpers": "^7.27.6",
- "@babel/parser": "^7.28.0",
+ "@babel/helper-module-transforms": "^7.28.3",
+ "@babel/helpers": "^7.28.4",
+ "@babel/parser": "^7.28.5",
"@babel/template": "^7.27.2",
- "@babel/traverse": "^7.28.0",
- "@babel/types": "^7.28.0",
+ "@babel/traverse": "^7.28.5",
+ "@babel/types": "^7.28.5",
+ "@jridgewell/remapping": "^2.3.5",
"convert-source-map": "^2.0.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@@ -244,14 +254,14 @@
}
},
"node_modules/@babel/helper-module-transforms": {
- "version": "7.27.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz",
- "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==",
+ "version": "7.28.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz",
+ "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==",
"license": "MIT",
"dependencies": {
"@babel/helper-module-imports": "^7.27.1",
"@babel/helper-validator-identifier": "^7.27.1",
- "@babel/traverse": "^7.27.3"
+ "@babel/traverse": "^7.28.3"
},
"engines": {
"node": ">=6.9.0"
@@ -370,13 +380,13 @@
}
},
"node_modules/@babel/helpers": {
- "version": "7.28.2",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.2.tgz",
- "integrity": "sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw==",
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz",
+ "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==",
"license": "MIT",
"dependencies": {
"@babel/template": "^7.27.2",
- "@babel/types": "^7.28.2"
+ "@babel/types": "^7.28.4"
},
"engines": {
"node": ">=6.9.0"
@@ -1372,6 +1382,21 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/plugin-transform-template-literals": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz",
+ "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
"node_modules/@babel/plugin-transform-typescript": {
"version": "7.28.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.5.tgz",
@@ -1447,10 +1472,11 @@
}
},
"node_modules/@babel/runtime": {
- "version": "7.28.2",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.2.tgz",
- "integrity": "sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==",
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz",
+ "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=6.9.0"
}
@@ -1519,26 +1545,116 @@
"node": ">=6.9.0"
}
},
- "node_modules/@callstack/react-theme-provider": {
- "version": "3.0.9",
- "resolved": "https://registry.npmjs.org/@callstack/react-theme-provider/-/react-theme-provider-3.0.9.tgz",
- "integrity": "sha512-tTQ0uDSCL0ypeMa8T/E9wAZRGKWj8kXP7+6RYgPTfOPs9N07C9xM8P02GJ3feETap4Ux5S69D9nteq9mEj86NA==",
+ "node_modules/@expo-google-fonts/inter": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@expo-google-fonts/inter/-/inter-0.2.3.tgz",
+ "integrity": "sha512-iHK9FI+dnE45X5c2Z5hSFwNH4zUWethizpbv3XUn0FIGw5jwvzriENz0a6wCdkI4/d+1QkurnHo5XHti7TbNJA==",
+ "license": "MIT"
+ },
+ "node_modules/@expo-google-fonts/space-grotesk": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@expo-google-fonts/space-grotesk/-/space-grotesk-0.2.3.tgz",
+ "integrity": "sha512-UYEMIrzegR02pauH7gVMI7j6cUroTtJug6dH/aQFjMNz0UwZe6GUcrEtJDmsUHJjEZdxbYgHhaiIwswWVo0CMA==",
+ "license": "MIT"
+ },
+ "node_modules/@expo/cli": {
+ "version": "54.0.16",
+ "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-54.0.16.tgz",
+ "integrity": "sha512-hY/OdRaJMs5WsVPuVSZ+RLH3VObJmL/pv5CGCHEZHN2PxZjSZSdctyKV8UcFBXTF0yIKNAJ9XLs1dlNYXHh4Cw==",
"license": "MIT",
"dependencies": {
- "deepmerge": "^3.2.0",
- "hoist-non-react-statics": "^3.3.0"
+ "@0no-co/graphql.web": "^1.0.8",
+ "@expo/code-signing-certificates": "^0.0.5",
+ "@expo/config": "~12.0.10",
+ "@expo/config-plugins": "~54.0.2",
+ "@expo/devcert": "^1.1.2",
+ "@expo/env": "~2.0.7",
+ "@expo/image-utils": "^0.8.7",
+ "@expo/json-file": "^10.0.7",
+ "@expo/mcp-tunnel": "~0.1.0",
+ "@expo/metro": "~54.1.0",
+ "@expo/metro-config": "~54.0.9",
+ "@expo/osascript": "^2.3.7",
+ "@expo/package-manager": "^1.9.8",
+ "@expo/plist": "^0.4.7",
+ "@expo/prebuild-config": "^54.0.6",
+ "@expo/schema-utils": "^0.1.7",
+ "@expo/spawn-async": "^1.7.2",
+ "@expo/ws-tunnel": "^1.0.1",
+ "@expo/xcpretty": "^4.3.0",
+ "@react-native/dev-middleware": "0.81.5",
+ "@urql/core": "^5.0.6",
+ "@urql/exchange-retry": "^1.3.0",
+ "accepts": "^1.3.8",
+ "arg": "^5.0.2",
+ "better-opn": "~3.0.2",
+ "bplist-creator": "0.1.0",
+ "bplist-parser": "^0.3.1",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.3.0",
+ "compression": "^1.7.4",
+ "connect": "^3.7.0",
+ "debug": "^4.3.4",
+ "env-editor": "^0.4.1",
+ "expo-server": "^1.0.4",
+ "freeport-async": "^2.0.0",
+ "getenv": "^2.0.0",
+ "glob": "^10.4.2",
+ "lan-network": "^0.1.6",
+ "minimatch": "^9.0.0",
+ "node-forge": "^1.3.1",
+ "npm-package-arg": "^11.0.0",
+ "ora": "^3.4.0",
+ "picomatch": "^3.0.1",
+ "pretty-bytes": "^5.6.0",
+ "pretty-format": "^29.7.0",
+ "progress": "^2.0.3",
+ "prompts": "^2.3.2",
+ "qrcode-terminal": "0.11.0",
+ "require-from-string": "^2.0.2",
+ "requireg": "^0.2.2",
+ "resolve": "^1.22.2",
+ "resolve-from": "^5.0.0",
+ "resolve.exports": "^2.0.3",
+ "semver": "^7.6.0",
+ "send": "^0.19.0",
+ "slugify": "^1.3.4",
+ "source-map-support": "~0.5.21",
+ "stacktrace-parser": "^0.1.10",
+ "structured-headers": "^0.4.1",
+ "tar": "^7.4.3",
+ "terminal-link": "^2.1.1",
+ "undici": "^6.18.2",
+ "wrap-ansi": "^7.0.0",
+ "ws": "^8.12.1"
+ },
+ "bin": {
+ "expo-internal": "build/bin/cli"
},
"peerDependencies": {
- "react": ">=16.3.0"
+ "expo": "*",
+ "expo-router": "*",
+ "react-native": "*"
+ },
+ "peerDependenciesMeta": {
+ "expo-router": {
+ "optional": true
+ },
+ "react-native": {
+ "optional": true
+ }
}
},
- "node_modules/@callstack/react-theme-provider/node_modules/deepmerge": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz",
- "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==",
- "license": "MIT",
+ "node_modules/@expo/cli/node_modules/semver": {
+ "version": "7.7.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
+ "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
"engines": {
- "node": ">=0.10.0"
+ "node": ">=10"
}
},
"node_modules/@expo/code-signing-certificates": {
@@ -1789,27 +1905,6 @@
}
}
},
- "node_modules/@expo/mcp-tunnel/node_modules/ws": {
- "version": "8.18.3",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
- "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
- "license": "MIT",
- "engines": {
- "node": ">=10.0.0"
- },
- "peerDependencies": {
- "bufferutil": "^4.0.1",
- "utf-8-validate": ">=5.0.2"
- },
- "peerDependenciesMeta": {
- "bufferutil": {
- "optional": true
- },
- "utf-8-validate": {
- "optional": true
- }
- }
- },
"node_modules/@expo/metro": {
"version": "54.1.0",
"resolved": "https://registry.npmjs.org/@expo/metro/-/metro-54.1.0.tgz",
@@ -1872,7 +1967,6 @@
"resolved": "https://registry.npmjs.org/@expo/metro-runtime/-/metro-runtime-6.1.2.tgz",
"integrity": "sha512-nvM+Qv45QH7pmYvP8JB1G8JpScrWND3KrMA6ZKe62cwwNiX/BjHU28Ear0v/4bQWXlOY0mv6B8CDIm8JxXde9g==",
"license": "MIT",
- "peer": true,
"dependencies": {
"anser": "^1.4.9",
"pretty-format": "^29.7.0",
@@ -1891,344 +1985,42 @@
}
}
},
- "node_modules/@expo/metro/node_modules/ci-info": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
- "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
- "license": "MIT"
- },
- "node_modules/@expo/metro/node_modules/hermes-estree": {
- "version": "0.32.0",
- "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.32.0.tgz",
- "integrity": "sha512-KWn3BqnlDOl97Xe1Yviur6NbgIZ+IP+UVSpshlZWkq+EtoHg6/cwiDj/osP9PCEgFE15KBm1O55JRwbMEm5ejQ==",
- "license": "MIT"
- },
- "node_modules/@expo/metro/node_modules/hermes-parser": {
- "version": "0.32.0",
- "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.32.0.tgz",
- "integrity": "sha512-g4nBOWFpuiTqjR3LZdRxKUkij9iyveWeuks7INEsMX741f3r9xxrOe8TeQfUxtda0eXmiIFiMQzoeSQEno33Hw==",
+ "node_modules/@expo/osascript": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.3.7.tgz",
+ "integrity": "sha512-IClSOXxR0YUFxIriUJVqyYki7lLMIHrrzOaP01yxAL1G8pj2DWV5eW1y5jSzIcIfSCNhtGsshGd1tU/AYup5iQ==",
"license": "MIT",
"dependencies": {
- "hermes-estree": "0.32.0"
+ "@expo/spawn-async": "^1.7.2",
+ "exec-async": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=12"
}
},
- "node_modules/@expo/metro/node_modules/metro": {
- "version": "0.83.2",
- "resolved": "https://registry.npmjs.org/metro/-/metro-0.83.2.tgz",
- "integrity": "sha512-HQgs9H1FyVbRptNSMy/ImchTTE5vS2MSqLoOo7hbDoBq6hPPZokwJvBMwrYSxdjQZmLXz2JFZtdvS+ZfgTc9yw==",
+ "node_modules/@expo/package-manager": {
+ "version": "1.9.8",
+ "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.9.8.tgz",
+ "integrity": "sha512-4/I6OWquKXYnzo38pkISHCOCOXxfeEmu4uDoERq1Ei/9Ur/s9y3kLbAamEkitUkDC7gHk1INxRWEfFNzGbmOrA==",
"license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.24.7",
- "@babel/core": "^7.25.2",
- "@babel/generator": "^7.25.0",
- "@babel/parser": "^7.25.3",
- "@babel/template": "^7.25.0",
- "@babel/traverse": "^7.25.3",
- "@babel/types": "^7.25.2",
- "accepts": "^1.3.7",
+ "@expo/json-file": "^10.0.7",
+ "@expo/spawn-async": "^1.7.2",
"chalk": "^4.0.0",
- "ci-info": "^2.0.0",
- "connect": "^3.6.5",
- "debug": "^4.4.0",
- "error-stack-parser": "^2.0.6",
- "flow-enums-runtime": "^0.0.6",
- "graceful-fs": "^4.2.4",
- "hermes-parser": "0.32.0",
- "image-size": "^1.0.2",
- "invariant": "^2.2.4",
- "jest-worker": "^29.7.0",
- "jsc-safe-url": "^0.2.2",
- "lodash.throttle": "^4.1.1",
- "metro-babel-transformer": "0.83.2",
- "metro-cache": "0.83.2",
- "metro-cache-key": "0.83.2",
- "metro-config": "0.83.2",
- "metro-core": "0.83.2",
- "metro-file-map": "0.83.2",
- "metro-resolver": "0.83.2",
- "metro-runtime": "0.83.2",
- "metro-source-map": "0.83.2",
- "metro-symbolicate": "0.83.2",
- "metro-transform-plugins": "0.83.2",
- "metro-transform-worker": "0.83.2",
- "mime-types": "^2.1.27",
- "nullthrows": "^1.1.1",
- "serialize-error": "^2.1.0",
- "source-map": "^0.5.6",
- "throat": "^5.0.0",
- "ws": "^7.5.10",
- "yargs": "^17.6.2"
- },
- "bin": {
- "metro": "src/cli.js"
- },
- "engines": {
- "node": ">=20.19.4"
+ "npm-package-arg": "^11.0.0",
+ "ora": "^3.4.0",
+ "resolve-workspace-root": "^2.0.0"
}
},
- "node_modules/@expo/metro/node_modules/metro-babel-transformer": {
- "version": "0.83.2",
- "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.83.2.tgz",
- "integrity": "sha512-rirY1QMFlA1uxH3ZiNauBninwTioOgwChnRdDcbB4tgRZ+bGX9DiXoh9QdpppiaVKXdJsII932OwWXGGV4+Nlw==",
+ "node_modules/@expo/plist": {
+ "version": "0.4.7",
+ "resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.4.7.tgz",
+ "integrity": "sha512-dGxqHPvCZKeRKDU1sJZMmuyVtcASuSYh1LPFVaM1DuffqPL36n6FMEL0iUqq2Tx3xhWk8wCnWl34IKplUjJDdA==",
"license": "MIT",
"dependencies": {
- "@babel/core": "^7.25.2",
- "flow-enums-runtime": "^0.0.6",
- "hermes-parser": "0.32.0",
- "nullthrows": "^1.1.1"
- },
- "engines": {
- "node": ">=20.19.4"
- }
- },
- "node_modules/@expo/metro/node_modules/metro-cache": {
- "version": "0.83.2",
- "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.83.2.tgz",
- "integrity": "sha512-Z43IodutUZeIS7OTH+yQFjc59QlFJ6s5OvM8p2AP9alr0+F8UKr8ADzFzoGKoHefZSKGa4bJx7MZJLF6GwPDHQ==",
- "license": "MIT",
- "dependencies": {
- "exponential-backoff": "^3.1.1",
- "flow-enums-runtime": "^0.0.6",
- "https-proxy-agent": "^7.0.5",
- "metro-core": "0.83.2"
- },
- "engines": {
- "node": ">=20.19.4"
- }
- },
- "node_modules/@expo/metro/node_modules/metro-cache-key": {
- "version": "0.83.2",
- "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.83.2.tgz",
- "integrity": "sha512-3EMG/GkGKYoTaf5RqguGLSWRqGTwO7NQ0qXKmNBjr0y6qD9s3VBXYlwB+MszGtmOKsqE9q3FPrE5Nd9Ipv7rZw==",
- "license": "MIT",
- "dependencies": {
- "flow-enums-runtime": "^0.0.6"
- },
- "engines": {
- "node": ">=20.19.4"
- }
- },
- "node_modules/@expo/metro/node_modules/metro-config": {
- "version": "0.83.2",
- "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.83.2.tgz",
- "integrity": "sha512-1FjCcdBe3e3D08gSSiU9u3Vtxd7alGH3x/DNFqWDFf5NouX4kLgbVloDDClr1UrLz62c0fHh2Vfr9ecmrOZp+g==",
- "license": "MIT",
- "dependencies": {
- "connect": "^3.6.5",
- "flow-enums-runtime": "^0.0.6",
- "jest-validate": "^29.7.0",
- "metro": "0.83.2",
- "metro-cache": "0.83.2",
- "metro-core": "0.83.2",
- "metro-runtime": "0.83.2",
- "yaml": "^2.6.1"
- },
- "engines": {
- "node": ">=20.19.4"
- }
- },
- "node_modules/@expo/metro/node_modules/metro-core": {
- "version": "0.83.2",
- "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.83.2.tgz",
- "integrity": "sha512-8DRb0O82Br0IW77cNgKMLYWUkx48lWxUkvNUxVISyMkcNwE/9ywf1MYQUE88HaKwSrqne6kFgCSA/UWZoUT0Iw==",
- "license": "MIT",
- "dependencies": {
- "flow-enums-runtime": "^0.0.6",
- "lodash.throttle": "^4.1.1",
- "metro-resolver": "0.83.2"
- },
- "engines": {
- "node": ">=20.19.4"
- }
- },
- "node_modules/@expo/metro/node_modules/metro-file-map": {
- "version": "0.83.2",
- "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.83.2.tgz",
- "integrity": "sha512-cMSWnEqZrp/dzZIEd7DEDdk72PXz6w5NOKriJoDN9p1TDQ5nAYrY2lHi8d6mwbcGLoSlWmpPyny9HZYFfPWcGQ==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.4.0",
- "fb-watchman": "^2.0.0",
- "flow-enums-runtime": "^0.0.6",
- "graceful-fs": "^4.2.4",
- "invariant": "^2.2.4",
- "jest-worker": "^29.7.0",
- "micromatch": "^4.0.4",
- "nullthrows": "^1.1.1",
- "walker": "^1.0.7"
- },
- "engines": {
- "node": ">=20.19.4"
- }
- },
- "node_modules/@expo/metro/node_modules/metro-minify-terser": {
- "version": "0.83.2",
- "resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.83.2.tgz",
- "integrity": "sha512-zvIxnh7U0JQ7vT4quasKsijId3dOAWgq+ip2jF/8TMrPUqQabGrs04L2dd0haQJ+PA+d4VvK/bPOY8X/vL2PWw==",
- "license": "MIT",
- "dependencies": {
- "flow-enums-runtime": "^0.0.6",
- "terser": "^5.15.0"
- },
- "engines": {
- "node": ">=20.19.4"
- }
- },
- "node_modules/@expo/metro/node_modules/metro-resolver": {
- "version": "0.83.2",
- "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.83.2.tgz",
- "integrity": "sha512-Yf5mjyuiRE/Y+KvqfsZxrbHDA15NZxyfg8pIk0qg47LfAJhpMVEX+36e6ZRBq7KVBqy6VDX5Sq55iHGM4xSm7Q==",
- "license": "MIT",
- "dependencies": {
- "flow-enums-runtime": "^0.0.6"
- },
- "engines": {
- "node": ">=20.19.4"
- }
- },
- "node_modules/@expo/metro/node_modules/metro-runtime": {
- "version": "0.83.2",
- "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.83.2.tgz",
- "integrity": "sha512-nnsPtgRvFbNKwemqs0FuyFDzXLl+ezuFsUXDbX8o0SXOfsOPijqiQrf3kuafO1Zx1aUWf4NOrKJMAQP5EEHg9A==",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.25.0",
- "flow-enums-runtime": "^0.0.6"
- },
- "engines": {
- "node": ">=20.19.4"
- }
- },
- "node_modules/@expo/metro/node_modules/metro-source-map": {
- "version": "0.83.2",
- "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.83.2.tgz",
- "integrity": "sha512-5FL/6BSQvshIKjXOennt9upFngq2lFvDakZn5LfauIVq8+L4sxXewIlSTcxAtzbtjAIaXeOSVMtCJ5DdfCt9AA==",
- "license": "MIT",
- "dependencies": {
- "@babel/traverse": "^7.25.3",
- "@babel/traverse--for-generate-function-map": "npm:@babel/traverse@^7.25.3",
- "@babel/types": "^7.25.2",
- "flow-enums-runtime": "^0.0.6",
- "invariant": "^2.2.4",
- "metro-symbolicate": "0.83.2",
- "nullthrows": "^1.1.1",
- "ob1": "0.83.2",
- "source-map": "^0.5.6",
- "vlq": "^1.0.0"
- },
- "engines": {
- "node": ">=20.19.4"
- }
- },
- "node_modules/@expo/metro/node_modules/metro-symbolicate": {
- "version": "0.83.2",
- "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.83.2.tgz",
- "integrity": "sha512-KoU9BLwxxED6n33KYuQQuc5bXkIxF3fSwlc3ouxrrdLWwhu64muYZNQrukkWzhVKRNFIXW7X2iM8JXpi2heIPw==",
- "license": "MIT",
- "dependencies": {
- "flow-enums-runtime": "^0.0.6",
- "invariant": "^2.2.4",
- "metro-source-map": "0.83.2",
- "nullthrows": "^1.1.1",
- "source-map": "^0.5.6",
- "vlq": "^1.0.0"
- },
- "bin": {
- "metro-symbolicate": "src/index.js"
- },
- "engines": {
- "node": ">=20.19.4"
- }
- },
- "node_modules/@expo/metro/node_modules/metro-transform-plugins": {
- "version": "0.83.2",
- "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.83.2.tgz",
- "integrity": "sha512-5WlW25WKPkiJk2yA9d8bMuZrgW7vfA4f4MBb9ZeHbTB3eIAoNN8vS8NENgG/X/90vpTB06X66OBvxhT3nHwP6A==",
- "license": "MIT",
- "dependencies": {
- "@babel/core": "^7.25.2",
- "@babel/generator": "^7.25.0",
- "@babel/template": "^7.25.0",
- "@babel/traverse": "^7.25.3",
- "flow-enums-runtime": "^0.0.6",
- "nullthrows": "^1.1.1"
- },
- "engines": {
- "node": ">=20.19.4"
- }
- },
- "node_modules/@expo/metro/node_modules/metro-transform-worker": {
- "version": "0.83.2",
- "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.83.2.tgz",
- "integrity": "sha512-G5DsIg+cMZ2KNfrdLnWMvtppb3+Rp1GMyj7Bvd9GgYc/8gRmvq1XVEF9XuO87Shhb03kFhGqMTgZerz3hZ1v4Q==",
- "license": "MIT",
- "dependencies": {
- "@babel/core": "^7.25.2",
- "@babel/generator": "^7.25.0",
- "@babel/parser": "^7.25.3",
- "@babel/types": "^7.25.2",
- "flow-enums-runtime": "^0.0.6",
- "metro": "0.83.2",
- "metro-babel-transformer": "0.83.2",
- "metro-cache": "0.83.2",
- "metro-cache-key": "0.83.2",
- "metro-minify-terser": "0.83.2",
- "metro-source-map": "0.83.2",
- "metro-transform-plugins": "0.83.2",
- "nullthrows": "^1.1.1"
- },
- "engines": {
- "node": ">=20.19.4"
- }
- },
- "node_modules/@expo/metro/node_modules/ob1": {
- "version": "0.83.2",
- "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.83.2.tgz",
- "integrity": "sha512-XlK3w4M+dwd1g1gvHzVbxiXEbUllRONEgcF2uEO0zm4nxa0eKlh41c6N65q1xbiDOeKKda1tvNOAD33fNjyvCg==",
- "license": "MIT",
- "dependencies": {
- "flow-enums-runtime": "^0.0.6"
- },
- "engines": {
- "node": ">=20.19.4"
- }
- },
- "node_modules/@expo/osascript": {
- "version": "2.3.7",
- "resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.3.7.tgz",
- "integrity": "sha512-IClSOXxR0YUFxIriUJVqyYki7lLMIHrrzOaP01yxAL1G8pj2DWV5eW1y5jSzIcIfSCNhtGsshGd1tU/AYup5iQ==",
- "license": "MIT",
- "dependencies": {
- "@expo/spawn-async": "^1.7.2",
- "exec-async": "^2.2.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@expo/package-manager": {
- "version": "1.9.8",
- "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.9.8.tgz",
- "integrity": "sha512-4/I6OWquKXYnzo38pkISHCOCOXxfeEmu4uDoERq1Ei/9Ur/s9y3kLbAamEkitUkDC7gHk1INxRWEfFNzGbmOrA==",
- "license": "MIT",
- "dependencies": {
- "@expo/json-file": "^10.0.7",
- "@expo/spawn-async": "^1.7.2",
- "chalk": "^4.0.0",
- "npm-package-arg": "^11.0.0",
- "ora": "^3.4.0",
- "resolve-workspace-root": "^2.0.0"
- }
- },
- "node_modules/@expo/plist": {
- "version": "0.4.7",
- "resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.4.7.tgz",
- "integrity": "sha512-dGxqHPvCZKeRKDU1sJZMmuyVtcASuSYh1LPFVaM1DuffqPL36n6FMEL0iUqq2Tx3xhWk8wCnWl34IKplUjJDdA==",
- "license": "MIT",
- "dependencies": {
- "@xmldom/xmldom": "^0.8.8",
- "base64-js": "^1.2.3",
- "xmlbuilder": "^15.1.1"
+ "@xmldom/xmldom": "^0.8.8",
+ "base64-js": "^1.2.3",
+ "xmlbuilder": "^15.1.1"
}
},
"node_modules/@expo/prebuild-config": {
@@ -2427,6 +2219,15 @@
"sprintf-js": "~1.0.2"
}
},
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
@@ -2441,9 +2242,9 @@
}
},
"node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": {
- "version": "3.14.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
- "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "version": "3.14.2",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
+ "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
"license": "MIT",
"dependencies": {
"argparse": "^1.0.7",
@@ -2601,15 +2402,25 @@
}
},
"node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.12",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz",
- "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==",
+ "version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.0",
"@jridgewell/trace-mapping": "^0.3.24"
}
},
+ "node_modules/@jridgewell/remapping": {
+ "version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
@@ -2630,41 +2441,551 @@
}
},
"node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.4",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz",
- "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==",
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.29",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz",
- "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==",
+ "version": "0.3.31",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
"license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
- "node_modules/@pkgjs/parseargs": {
- "version": "0.11.0",
- "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
- "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
"license": "MIT",
- "optional": true,
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "license": "MIT",
+ "optional": true,
"engines": {
"node": ">=14"
}
},
- "node_modules/@react-native-async-storage/async-storage": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-2.2.0.tgz",
- "integrity": "sha512-gvRvjR5JAaUZF8tv2Kcq/Gbt3JHwbKFYfmb445rhOj6NUMx3qPLixmDx5pZAyb9at1bYvJ4/eTUipU5aki45xw==",
+ "node_modules/@radix-ui/primitive": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz",
+ "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==",
+ "license": "MIT"
+ },
+ "node_modules/@radix-ui/react-collection": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz",
+ "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-slot": "1.2.3"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-slot": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
+ "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-compose-refs": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
+ "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-context": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz",
+ "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-dialog": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz",
+ "integrity": "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-dismissable-layer": "1.1.11",
+ "@radix-ui/react-focus-guards": "1.1.3",
+ "@radix-ui/react-focus-scope": "1.1.7",
+ "@radix-ui/react-id": "1.1.1",
+ "@radix-ui/react-portal": "1.1.9",
+ "@radix-ui/react-presence": "1.1.5",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-slot": "1.2.3",
+ "@radix-ui/react-use-controllable-state": "1.2.2",
+ "aria-hidden": "^1.2.4",
+ "react-remove-scroll": "^2.6.3"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-slot": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
+ "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-direction": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz",
+ "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-dismissable-layer": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz",
+ "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-callback-ref": "1.1.1",
+ "@radix-ui/react-use-escape-keydown": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-focus-guards": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz",
+ "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-focus-scope": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz",
+ "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-callback-ref": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-id": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz",
+ "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-portal": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz",
+ "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-presence": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz",
+ "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-primitive": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
+ "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-slot": "1.2.3"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-primitive/node_modules/@radix-ui/react-slot": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
+ "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-roving-focus": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz",
+ "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-collection": "1.1.7",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-direction": "1.1.1",
+ "@radix-ui/react-id": "1.1.1",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-callback-ref": "1.1.1",
+ "@radix-ui/react-use-controllable-state": "1.2.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-slot": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.0.tgz",
+ "integrity": "sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-tabs": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.13.tgz",
+ "integrity": "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-direction": "1.1.1",
+ "@radix-ui/react-id": "1.1.1",
+ "@radix-ui/react-presence": "1.1.5",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-roving-focus": "1.1.11",
+ "@radix-ui/react-use-controllable-state": "1.2.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-callback-ref": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz",
+ "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-controllable-state": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz",
+ "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-effect-event": "0.0.2",
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-effect-event": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz",
+ "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-escape-keydown": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz",
+ "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==",
"license": "MIT",
"dependencies": {
- "merge-options": "^3.0.4"
+ "@radix-ui/react-use-callback-ref": "1.1.1"
},
"peerDependencies": {
- "react-native": "^0.0.0-0 || >=0.65 <1.0"
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-layout-effect": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz",
+ "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
}
},
"node_modules/@react-native/assets-registry": {
@@ -2918,17 +3239,41 @@
"integrity": "sha512-0HuJ8YtqlTVRXGZuGeBejLE04wSQsibpTI+RGOyVqxZvgtlLLC/Ssw0UmbHhT4lYMp2fhdtvKZSs5emWB1zR/g==",
"license": "MIT"
},
+ "node_modules/@react-native/virtualized-lists": {
+ "version": "0.81.5",
+ "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.81.5.tgz",
+ "integrity": "sha512-UVXgV/db25OPIvwZySeToXD/9sKKhOdkcWmmf4Jh8iBZuyfML+/5CasaZ1E7Lqg6g3uqVQq75NqIwkYmORJMPw==",
+ "license": "MIT",
+ "dependencies": {
+ "invariant": "^2.2.4",
+ "nullthrows": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 20.19.4"
+ },
+ "peerDependencies": {
+ "@types/react": "^19.1.0",
+ "react": "*",
+ "react-native": "*"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@react-navigation/bottom-tabs": {
- "version": "7.4.4",
- "resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-7.4.4.tgz",
- "integrity": "sha512-/YEBu/cZUgYAaNoSfUnqoRjpbt8NOsb5YvDiKVyTcOOAF1GTbUw6kRi+AGW1Sm16CqzabO/TF2RvN1RmPS9VHg==",
+ "version": "7.8.7",
+ "resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-7.8.7.tgz",
+ "integrity": "sha512-OKdUCJ/nA6CPOO3ruxZTKphH8U9b3zr21ibrsiqM3Sr72tJ5fAPNbI+3zh2mENVRnRxQbUNHh016ruJ65nl0JQ==",
"license": "MIT",
"dependencies": {
- "@react-navigation/elements": "^2.6.1",
- "color": "^4.2.3"
+ "@react-navigation/elements": "^2.8.4",
+ "color": "^4.2.3",
+ "sf-symbols-typescript": "^2.1.0"
},
"peerDependencies": {
- "@react-navigation/native": "^7.1.16",
+ "@react-navigation/native": "^7.1.22",
"react": ">= 18.2.0",
"react-native": "*",
"react-native-safe-area-context": ">= 4.0.0",
@@ -2954,12 +3299,6 @@
"react": ">= 18.2.0"
}
},
- "node_modules/@react-navigation/core/node_modules/react-is": {
- "version": "19.2.0",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.0.tgz",
- "integrity": "sha512-x3Ax3kNSMIIkyVYhWPyO09bu0uttcAIoecO/um/rKGQ4EltYWVYtyiGkS/3xMynrbVQdS69Jhlv8FXUEZehlzA==",
- "license": "MIT"
- },
"node_modules/@react-navigation/elements": {
"version": "2.8.4",
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-2.8.4.tgz",
@@ -3002,16 +3341,18 @@
}
},
"node_modules/@react-navigation/native-stack": {
- "version": "7.3.23",
- "resolved": "https://registry.npmjs.org/@react-navigation/native-stack/-/native-stack-7.3.23.tgz",
- "integrity": "sha512-WQBBnPrlM0vXj5YAFnJTyrkiCyANl2KnBV8ZmUG61HkqXFwuBbnHij6eoggXH1VZkEVRxW8k0E3qqfPtEZfUjQ==",
+ "version": "7.8.1",
+ "resolved": "https://registry.npmjs.org/@react-navigation/native-stack/-/native-stack-7.8.1.tgz",
+ "integrity": "sha512-76dqsWJiDzw+H6ZZJXNS32j9hYjm+J+bkV+vtribaWv5Ky0VUX1K0jGT7Z4EKiHqS7dVsqGHTnUXwwqA/xj1gg==",
"license": "MIT",
"dependencies": {
- "@react-navigation/elements": "^2.6.1",
+ "@react-navigation/elements": "^2.8.4",
+ "color": "^4.2.3",
+ "sf-symbols-typescript": "^2.1.0",
"warn-once": "^0.1.1"
},
"peerDependencies": {
- "@react-navigation/native": "^7.1.16",
+ "@react-navigation/native": "^7.1.22",
"react": ">= 18.2.0",
"react-native": "*",
"react-native-safe-area-context": ">= 4.0.0",
@@ -3084,12 +3425,12 @@
}
},
"node_modules/@types/babel__traverse": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz",
- "integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==",
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",
+ "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.20.7"
+ "@babel/types": "^7.28.2"
}
},
"node_modules/@types/graceful-fs": {
@@ -3126,12 +3467,23 @@
}
},
"node_modules/@types/node": {
- "version": "24.1.0",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-24.1.0.tgz",
- "integrity": "sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w==",
+ "version": "24.10.1",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz",
+ "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==",
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~7.16.0"
+ }
+ },
+ "node_modules/@types/react": {
+ "version": "19.1.17",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.17.tgz",
+ "integrity": "sha512-Qec1E3mhALmaspIrhWt9jkQMNdw6bReVu64mjvhbhq2NFPftLPVr+l1SZgmw/66WwBNpDh7ao5AT6gF5v41PFA==",
+ "devOptional": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
- "undici-types": "~7.8.0"
+ "csstype": "^3.0.2"
}
},
"node_modules/@types/stack-utils": {
@@ -3141,9 +3493,9 @@
"license": "MIT"
},
"node_modules/@types/yargs": {
- "version": "17.0.33",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
- "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
+ "version": "17.0.35",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz",
+ "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==",
"license": "MIT",
"dependencies": {
"@types/yargs-parser": "*"
@@ -3239,6 +3591,22 @@
"node": ">= 14"
}
},
+ "node_modules/ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
"node_modules/anser": {
"version": "1.4.10",
"resolved": "https://registry.npmjs.org/anser/-/anser-1.4.10.tgz",
@@ -3339,6 +3707,24 @@
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"license": "Python-2.0"
},
+ "node_modules/aria-hidden": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz",
+ "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/array-timsort": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz",
+ "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==",
+ "license": "MIT"
+ },
"node_modules/asap": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
@@ -3351,23 +3737,6 @@
"integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
"license": "MIT"
},
- "node_modules/asynckit": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
- "license": "MIT"
- },
- "node_modules/axios": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz",
- "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==",
- "license": "MIT",
- "dependencies": {
- "follow-redirects": "^1.15.6",
- "form-data": "^4.0.4",
- "proxy-from-env": "^1.1.0"
- }
- },
"node_modules/babel-jest": {
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz",
@@ -3493,9 +3862,9 @@
}
},
"node_modules/babel-preset-current-node-syntax": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.1.tgz",
- "integrity": "sha512-23fWKohMTvS5s0wwJKycOe0dBdCwQ6+iiLaNR9zy8P13mtFRFM9qLLX6HJX5DL2pi/FNDf3fCQHM4FIMoHH/7w==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz",
+ "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==",
"license": "MIT",
"dependencies": {
"@babel/plugin-syntax-async-generators": "^7.8.4",
@@ -3650,6 +4019,24 @@
"node": ">=0.6"
}
},
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+ "license": "ISC"
+ },
"node_modules/bplist-creator": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.1.0.tgz",
@@ -3660,9 +4047,9 @@
}
},
"node_modules/bplist-parser": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.1.tgz",
- "integrity": "sha512-PyJxiNtA5T2PlLIeBot4lbp7rj4OadzjnMZD/G5zuBNt8ei/yCU7+wW0h2bag9vr8c+/WuRWmSxbqAl9hL1rBA==",
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.2.tgz",
+ "integrity": "sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ==",
"license": "MIT",
"dependencies": {
"big-integer": "1.6.x"
@@ -3774,26 +4161,25 @@
"node": ">= 0.8"
}
},
- "node_modules/call-bind-apply-helpers": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
- "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "node_modules/camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
"license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "function-bind": "^1.1.2"
- },
"engines": {
- "node": ">= 0.4"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/camelcase": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
- "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "node_modules/camelcase-css": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
+ "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
"license": "MIT",
"engines": {
- "node": ">=6"
+ "node": ">= 6"
}
},
"node_modules/caniuse-lite": {
@@ -3832,6 +4218,42 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
+ "node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "license": "MIT",
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/chokidar/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/chownr": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz",
@@ -3912,6 +4334,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/client-only": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
+ "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
+ "license": "MIT"
+ },
"node_modules/cliui": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
@@ -3967,6 +4395,15 @@
"node": ">=0.8"
}
},
+ "node_modules/clsx": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
+ "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/color": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
@@ -4008,18 +4445,6 @@
"simple-swizzle": "^0.2.2"
}
},
- "node_modules/combined-stream": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
- "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
- "license": "MIT",
- "dependencies": {
- "delayed-stream": "~1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
"node_modules/commander": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
@@ -4029,6 +4454,20 @@
"node": ">= 10"
}
},
+ "node_modules/comment-json": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.4.1.tgz",
+ "integrity": "sha512-r1To31BQD5060QdkC+Iheai7gHwoSZobzunqkf2/kQ6xIAfJyrKNAFUwdKvkK7Qgu7pVTKQEa7ok7Ed3ycAJgg==",
+ "license": "MIT",
+ "dependencies": {
+ "array-timsort": "^1.0.3",
+ "core-util-is": "^1.0.3",
+ "esprima": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/compressible": {
"version": "2.0.18",
"resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
@@ -4138,10 +4577,17 @@
"url": "https://opencollective.com/core-js"
}
},
+ "node_modules/core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+ "license": "MIT"
+ },
"node_modules/cross-fetch": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz",
"integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==",
+ "license": "MIT",
"dependencies": {
"node-fetch": "^2.7.0"
}
@@ -4173,14 +4619,84 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz",
"integrity": "sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==",
+ "license": "MIT",
"dependencies": {
"hyphenate-style-name": "^1.0.3"
}
},
+ "node_modules/css-select": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz",
+ "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-what": "^6.1.0",
+ "domhandler": "^5.0.2",
+ "domutils": "^3.0.1",
+ "nth-check": "^2.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/css-tree": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
+ "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
+ "license": "MIT",
+ "dependencies": {
+ "mdn-data": "2.0.14",
+ "source-map": "^0.6.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/css-tree/node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/css-what": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz",
+ "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "license": "MIT",
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
+ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
+ "devOptional": true,
+ "license": "MIT"
+ },
"node_modules/debug": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
- "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@@ -4242,15 +4758,6 @@
"node": ">=8"
}
},
- "node_modules/delayed-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
- "license": "MIT",
- "engines": {
- "node": ">=0.4.0"
- }
- },
"node_modules/depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@@ -4270,13 +4777,86 @@
"npm": "1.2.8000 || >= 1.4.16"
}
},
- "node_modules/detect-libc": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
- "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=8"
+ "node_modules/detect-libc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/detect-node-es": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
+ "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==",
+ "license": "MIT"
+ },
+ "node_modules/didyoumean": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
+ "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/dlv": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
+ "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
+ "license": "MIT"
+ },
+ "node_modules/dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/domutils": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
+ "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
}
},
"node_modules/dotenv": {
@@ -4306,20 +4886,6 @@
"url": "https://dotenvx.com"
}
},
- "node_modules/dunder-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
- "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.1",
- "es-errors": "^1.3.0",
- "gopd": "^1.2.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
"node_modules/eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
@@ -4333,9 +4899,9 @@
"license": "MIT"
},
"node_modules/electron-to-chromium": {
- "version": "1.5.261",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.261.tgz",
- "integrity": "sha512-cmyHEWFqEt3ICUNF93ShneOF47DHoSDbLb7E/AonsWcbzg95N+kPXeLNfkdzgTT/vEUcoW76fxbLBkeYtfoM8A==",
+ "version": "1.5.262",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.262.tgz",
+ "integrity": "sha512-NlAsMteRHek05jRUxUR0a5jpjYq9ykk6+kO0yRaMi5moe7u0fVIOeQ3Y30A8dIiWFBNUoQGi1ljb1i5VtS9WQQ==",
"license": "ISC"
},
"node_modules/emoji-regex": {
@@ -4353,6 +4919,18 @@
"node": ">= 0.8"
}
},
+ "node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
"node_modules/env-editor": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/env-editor/-/env-editor-0.4.2.tgz",
@@ -4371,51 +4949,6 @@
"stackframe": "^1.3.4"
}
},
- "node_modules/es-define-property": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
- "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-errors": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
- "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-object-atoms": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
- "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-set-tostringtag": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
- "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.6",
- "has-tostringtag": "^1.0.2",
- "hasown": "^2.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
"node_modules/escalade": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
@@ -4548,11 +5081,37 @@
"react-native": "*"
}
},
+ "node_modules/expo-build-properties": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/expo-build-properties/-/expo-build-properties-1.0.9.tgz",
+ "integrity": "sha512-2icttCy3OPTk/GWIFt+vwA+0hup53jnmYb7JKRbvNvrrOrz+WblzpeoiaOleI2dYG/vjwpNO8to8qVyKhYJtrQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^8.11.0",
+ "semver": "^7.6.0"
+ },
+ "peerDependencies": {
+ "expo": "*"
+ }
+ },
+ "node_modules/expo-build-properties/node_modules/semver": {
+ "version": "7.7.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
+ "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/expo-constants": {
"version": "18.0.10",
"resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-18.0.10.tgz",
"integrity": "sha512-Rhtv+X974k0Cahmvx6p7ER5+pNhBC0XbP1lRviL2J1Xl4sT2FBaIuIxF/0I0CbhOsySf0ksqc5caFweAy9Ewiw==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@expo/config": "~12.0.10",
"@expo/env": "~2.0.7"
@@ -4587,27 +5146,6 @@
"react-native": "*"
}
},
- "node_modules/expo-image-loader": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/expo-image-loader/-/expo-image-loader-6.0.0.tgz",
- "integrity": "sha512-nKs/xnOGw6ACb4g26xceBD57FKLFkSwEUTDXEDF3Gtcu3MqF3ZIYd3YM+sSb1/z9AKV1dYT7rMSGVNgsveXLIQ==",
- "license": "MIT",
- "peerDependencies": {
- "expo": "*"
- }
- },
- "node_modules/expo-image-picker": {
- "version": "17.0.8",
- "resolved": "https://registry.npmjs.org/expo-image-picker/-/expo-image-picker-17.0.8.tgz",
- "integrity": "sha512-489ByhVs2XPoAu9zodivAKLv7hG4S/FOe8hO/C2U6jVxmRjpAKakKNjMml0IwWjf1+c/RYBqm1XxKaZ+vq/fDQ==",
- "license": "MIT",
- "dependencies": {
- "expo-image-loader": "~6.0.0"
- },
- "peerDependencies": {
- "expo": "*"
- }
- },
"node_modules/expo-keep-awake": {
"version": "15.0.7",
"resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-15.0.7.tgz",
@@ -4618,6 +5156,21 @@
"react": "*"
}
},
+ "node_modules/expo-linking": {
+ "version": "8.0.9",
+ "resolved": "https://registry.npmjs.org/expo-linking/-/expo-linking-8.0.9.tgz",
+ "integrity": "sha512-a0UHhlVyfwIbn8b1PSFPoFiIDJeps2iEq109hVH3CHd0CMKuRxFfNio9Axe2BjXhiJCYWR4OV1iIyzY/GjiVkQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "expo-constants": "~18.0.10",
+ "invariant": "^2.2.4"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*"
+ }
+ },
"node_modules/expo-modules-autolinking": {
"version": "3.0.22",
"resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-3.0.22.tgz",
@@ -4647,120 +5200,81 @@
"react-native": "*"
}
},
- "node_modules/expo-server": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/expo-server/-/expo-server-1.0.4.tgz",
- "integrity": "sha512-IN06r3oPxFh3plSXdvBL7dx0x6k+0/g0bgxJlNISs6qL5Z+gyPuWS750dpTzOeu37KyBG0RcyO9cXUKzjYgd4A==",
- "license": "MIT",
- "engines": {
- "node": ">=20.16.0"
- }
- },
- "node_modules/expo-status-bar": {
- "version": "3.0.8",
- "resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-3.0.8.tgz",
- "integrity": "sha512-L248XKPhum7tvREoS1VfE0H6dPCaGtoUWzRsUv7hGKdiB4cus33Rc0sxkWkoQ77wE8stlnUlL5lvmT0oqZ3ZBw==",
- "license": "MIT",
- "dependencies": {
- "react-native-is-edge-to-edge": "^1.2.1"
- },
- "peerDependencies": {
- "react": "*",
- "react-native": "*"
- }
- },
- "node_modules/expo/node_modules/@expo/cli": {
- "version": "54.0.16",
- "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-54.0.16.tgz",
- "integrity": "sha512-hY/OdRaJMs5WsVPuVSZ+RLH3VObJmL/pv5CGCHEZHN2PxZjSZSdctyKV8UcFBXTF0yIKNAJ9XLs1dlNYXHh4Cw==",
+ "node_modules/expo-router": {
+ "version": "6.0.15",
+ "resolved": "https://registry.npmjs.org/expo-router/-/expo-router-6.0.15.tgz",
+ "integrity": "sha512-PAettvLifQzb6hibCmBqxbR9UljlH61GvDRLyarGxs/tG9OpMXCoZHZo8gGCO24K1/6cchBKBcjvQ0PRrKwPew==",
"license": "MIT",
"dependencies": {
- "@0no-co/graphql.web": "^1.0.8",
- "@expo/code-signing-certificates": "^0.0.5",
- "@expo/config": "~12.0.10",
- "@expo/config-plugins": "~54.0.2",
- "@expo/devcert": "^1.1.2",
- "@expo/env": "~2.0.7",
- "@expo/image-utils": "^0.8.7",
- "@expo/json-file": "^10.0.7",
- "@expo/mcp-tunnel": "~0.1.0",
- "@expo/metro": "~54.1.0",
- "@expo/metro-config": "~54.0.9",
- "@expo/osascript": "^2.3.7",
- "@expo/package-manager": "^1.9.8",
- "@expo/plist": "^0.4.7",
- "@expo/prebuild-config": "^54.0.6",
+ "@expo/metro-runtime": "^6.1.2",
"@expo/schema-utils": "^0.1.7",
- "@expo/spawn-async": "^1.7.2",
- "@expo/ws-tunnel": "^1.0.1",
- "@expo/xcpretty": "^4.3.0",
- "@react-native/dev-middleware": "0.81.5",
- "@urql/core": "^5.0.6",
- "@urql/exchange-retry": "^1.3.0",
- "accepts": "^1.3.8",
- "arg": "^5.0.2",
- "better-opn": "~3.0.2",
- "bplist-creator": "0.1.0",
- "bplist-parser": "^0.3.1",
- "chalk": "^4.0.0",
- "ci-info": "^3.3.0",
- "compression": "^1.7.4",
- "connect": "^3.7.0",
+ "@radix-ui/react-slot": "1.2.0",
+ "@radix-ui/react-tabs": "^1.1.12",
+ "@react-navigation/bottom-tabs": "^7.4.0",
+ "@react-navigation/native": "^7.1.8",
+ "@react-navigation/native-stack": "^7.3.16",
+ "client-only": "^0.0.1",
"debug": "^4.3.4",
- "env-editor": "^0.4.1",
+ "escape-string-regexp": "^4.0.0",
"expo-server": "^1.0.4",
- "freeport-async": "^2.0.0",
- "getenv": "^2.0.0",
- "glob": "^10.4.2",
- "lan-network": "^0.1.6",
- "minimatch": "^9.0.0",
- "node-forge": "^1.3.1",
- "npm-package-arg": "^11.0.0",
- "ora": "^3.4.0",
- "picomatch": "^3.0.1",
- "pretty-bytes": "^5.6.0",
- "pretty-format": "^29.7.0",
- "progress": "^2.0.3",
- "prompts": "^2.3.2",
- "qrcode-terminal": "0.11.0",
- "require-from-string": "^2.0.2",
- "requireg": "^0.2.2",
- "resolve": "^1.22.2",
- "resolve-from": "^5.0.0",
- "resolve.exports": "^2.0.3",
- "semver": "^7.6.0",
- "send": "^0.19.0",
- "slugify": "^1.3.4",
- "source-map-support": "~0.5.21",
- "stacktrace-parser": "^0.1.10",
- "structured-headers": "^0.4.1",
- "tar": "^7.4.3",
- "terminal-link": "^2.1.1",
- "undici": "^6.18.2",
- "wrap-ansi": "^7.0.0",
- "ws": "^8.12.1"
- },
- "bin": {
- "expo-internal": "build/bin/cli"
+ "fast-deep-equal": "^3.1.3",
+ "invariant": "^2.2.4",
+ "nanoid": "^3.3.8",
+ "query-string": "^7.1.3",
+ "react-fast-compare": "^3.2.2",
+ "react-native-is-edge-to-edge": "^1.1.6",
+ "semver": "~7.6.3",
+ "server-only": "^0.0.1",
+ "sf-symbols-typescript": "^2.1.0",
+ "shallowequal": "^1.1.0",
+ "use-latest-callback": "^0.2.1",
+ "vaul": "^1.1.2"
},
"peerDependencies": {
+ "@expo/metro-runtime": "^6.1.2",
+ "@react-navigation/drawer": "^7.5.0",
+ "@testing-library/react-native": ">= 12.0.0",
"expo": "*",
- "expo-router": "*",
- "react-native": "*"
+ "expo-constants": "^18.0.10",
+ "expo-linking": "^8.0.9",
+ "react": "*",
+ "react-dom": "*",
+ "react-native": "*",
+ "react-native-gesture-handler": "*",
+ "react-native-reanimated": "*",
+ "react-native-safe-area-context": ">= 5.4.0",
+ "react-native-screens": "*",
+ "react-native-web": "*",
+ "react-server-dom-webpack": ">= 19.0.0"
},
"peerDependenciesMeta": {
- "expo-router": {
+ "@react-navigation/drawer": {
"optional": true
},
- "react-native": {
+ "@testing-library/react-native": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ },
+ "react-native-gesture-handler": {
+ "optional": true
+ },
+ "react-native-reanimated": {
+ "optional": true
+ },
+ "react-native-web": {
+ "optional": true
+ },
+ "react-server-dom-webpack": {
"optional": true
}
}
},
- "node_modules/expo/node_modules/semver": {
- "version": "7.7.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
- "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "node_modules/expo-router/node_modules/semver": {
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+ "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -4769,23 +5283,56 @@
"node": ">=10"
}
},
- "node_modules/expo/node_modules/ws": {
- "version": "8.18.3",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
- "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
+ "node_modules/expo-server": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/expo-server/-/expo-server-1.0.4.tgz",
+ "integrity": "sha512-IN06r3oPxFh3plSXdvBL7dx0x6k+0/g0bgxJlNISs6qL5Z+gyPuWS750dpTzOeu37KyBG0RcyO9cXUKzjYgd4A==",
"license": "MIT",
"engines": {
- "node": ">=10.0.0"
+ "node": ">=20.16.0"
+ }
+ },
+ "node_modules/expo-splash-screen": {
+ "version": "31.0.11",
+ "resolved": "https://registry.npmjs.org/expo-splash-screen/-/expo-splash-screen-31.0.11.tgz",
+ "integrity": "sha512-D7MQflYn/PAN3+fACSyxHO4oxZMBezllbgFdVY8roAS1gXpCy8SS6LrGHTD0VpOPEp3X4Gn7evTnXSI9nFoI5Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@expo/prebuild-config": "^54.0.6"
},
"peerDependencies": {
- "bufferutil": "^4.0.1",
- "utf-8-validate": ">=5.0.2"
+ "expo": "*"
+ }
+ },
+ "node_modules/expo-status-bar": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-3.0.8.tgz",
+ "integrity": "sha512-L248XKPhum7tvREoS1VfE0H6dPCaGtoUWzRsUv7hGKdiB4cus33Rc0sxkWkoQ77wE8stlnUlL5lvmT0oqZ3ZBw==",
+ "license": "MIT",
+ "dependencies": {
+ "react-native-is-edge-to-edge": "^1.2.1"
},
- "peerDependenciesMeta": {
- "bufferutil": {
- "optional": true
- },
- "utf-8-validate": {
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*"
+ }
+ },
+ "node_modules/expo-system-ui": {
+ "version": "6.0.8",
+ "resolved": "https://registry.npmjs.org/expo-system-ui/-/expo-system-ui-6.0.8.tgz",
+ "integrity": "sha512-DzJYqG2fibBSLzPDL4BybGCiilYOtnI1OWhcYFwoM4k0pnEzMBt1Vj8Z67bXglDDuz2HCQPGNtB3tQft5saKqQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@react-native/normalize-colors": "0.81.5",
+ "debug": "^4.3.2"
+ },
+ "peerDependencies": {
+ "expo": "*",
+ "react-native": "*",
+ "react-native-web": "*"
+ },
+ "peerDependenciesMeta": {
+ "react-native-web": {
"optional": true
}
}
@@ -4802,12 +5349,65 @@
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"license": "MIT"
},
+ "node_modules/fast-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
"license": "MIT"
},
+ "node_modules/fast-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
+ "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/fastq": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
+ "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
"node_modules/fb-watchman": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
@@ -4821,6 +5421,7 @@
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.5.tgz",
"integrity": "sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg==",
+ "license": "MIT",
"dependencies": {
"cross-fetch": "^3.1.5",
"fbjs-css-vars": "^1.0.0",
@@ -4834,12 +5435,14 @@
"node_modules/fbjs-css-vars": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz",
- "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ=="
+ "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==",
+ "license": "MIT"
},
"node_modules/fbjs/node_modules/promise": {
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
"integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+ "license": "MIT",
"dependencies": {
"asap": "~2.0.3"
}
@@ -4920,26 +5523,6 @@
"integrity": "sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw==",
"license": "MIT"
},
- "node_modules/follow-redirects": {
- "version": "1.15.9",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
- "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
- "funding": [
- {
- "type": "individual",
- "url": "https://github.com/sponsors/RubenVerborgh"
- }
- ],
- "license": "MIT",
- "engines": {
- "node": ">=4.0"
- },
- "peerDependenciesMeta": {
- "debug": {
- "optional": true
- }
- }
- },
"node_modules/fontfaceobserver": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/fontfaceobserver/-/fontfaceobserver-2.3.0.tgz",
@@ -4962,22 +5545,6 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/form-data": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
- "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
- "license": "MIT",
- "dependencies": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.8",
- "es-set-tostringtag": "^2.1.0",
- "hasown": "^2.0.2",
- "mime-types": "^2.1.12"
- },
- "engines": {
- "node": ">= 6"
- }
- },
"node_modules/freeport-async": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/freeport-async/-/freeport-async-2.0.0.tgz",
@@ -5043,28 +5610,13 @@
"node": "6.* || 8.* || >= 10.*"
}
},
- "node_modules/get-intrinsic": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
- "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "node_modules/get-nonce": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz",
+ "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==",
"license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "es-define-property": "^1.0.1",
- "es-errors": "^1.3.0",
- "es-object-atoms": "^1.1.1",
- "function-bind": "^1.1.2",
- "get-proto": "^1.0.1",
- "gopd": "^1.2.0",
- "has-symbols": "^1.1.0",
- "hasown": "^2.0.2",
- "math-intrinsics": "^1.1.0"
- },
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": ">=6"
}
},
"node_modules/get-package-type": {
@@ -5076,19 +5628,6 @@
"node": ">=8.0.0"
}
},
- "node_modules/get-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
- "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
- "license": "MIT",
- "dependencies": {
- "dunder-proto": "^1.0.1",
- "es-object-atoms": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
"node_modules/getenv": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/getenv/-/getenv-2.0.0.tgz",
@@ -5118,6 +5657,18 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
"node_modules/global-dirs": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
@@ -5130,18 +5681,6 @@
"node": ">=4"
}
},
- "node_modules/gopd": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
- "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
"node_modules/graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
@@ -5157,33 +5696,6 @@
"node": ">=8"
}
},
- "node_modules/has-symbols": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
- "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-tostringtag": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
- "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
- "license": "MIT",
- "dependencies": {
- "has-symbols": "^1.0.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
@@ -5211,21 +5723,6 @@
"hermes-estree": "0.29.1"
}
},
- "node_modules/hoist-non-react-statics": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
- "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
- "license": "BSD-3-Clause",
- "dependencies": {
- "react-is": "^16.7.0"
- }
- },
- "node_modules/hoist-non-react-statics/node_modules/react-is": {
- "version": "16.13.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
- "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
- "license": "MIT"
- },
"node_modules/hosted-git-info": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz",
@@ -5285,7 +5782,8 @@
"node_modules/hyphenate-style-name": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz",
- "integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw=="
+ "integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==",
+ "license": "BSD-3-Clause"
},
"node_modules/ieee754": {
"version": "1.2.1",
@@ -5367,6 +5865,7 @@
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-7.0.1.tgz",
"integrity": "sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw==",
+ "license": "MIT",
"dependencies": {
"css-in-js-utils": "^3.1.0"
}
@@ -5380,6 +5879,24 @@
"loose-envify": "^1.0.0"
}
},
+ "node_modules/is-arrayish": {
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz",
+ "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==",
+ "license": "MIT"
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "license": "MIT",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/is-core-module": {
"version": "2.16.1",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
@@ -5410,6 +5927,15 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
@@ -5419,6 +5945,18 @@
"node": ">=8"
}
},
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
@@ -5428,14 +5966,6 @@
"node": ">=0.12.0"
}
},
- "node_modules/is-plain-obj": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
- "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/is-wsl": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
@@ -5634,18 +6164,6 @@
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
- "node_modules/jest-validate/node_modules/camelcase": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
- "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/jest-worker": {
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz",
@@ -5682,6 +6200,16 @@
"integrity": "sha512-dZ6Ra7u1G8c4Letq/B5EzAxj4tLFHL+cGtdpR+PVm4yzPDj+lCk+AbivWt1eOM+ikzkowtyV7qSqX6qr3t71Ww==",
"license": "MIT"
},
+ "node_modules/jiti": {
+ "version": "1.21.7",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
+ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "jiti": "bin/jiti.js"
+ }
+ },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -5718,6 +6246,12 @@
"node": ">=6"
}
},
+ "node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "license": "MIT"
+ },
"node_modules/json5": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
@@ -6031,6 +6565,18 @@
"url": "https://opencollective.com/parcel"
}
},
+ "node_modules/lilconfig": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
+ "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antonk52"
+ }
+ },
"node_modules/lines-and-columns": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
@@ -6168,6 +6714,17 @@
"yallist": "^3.0.2"
}
},
+ "node_modules/lucide-react-native": {
+ "version": "0.475.0",
+ "resolved": "https://registry.npmjs.org/lucide-react-native/-/lucide-react-native-0.475.0.tgz",
+ "integrity": "sha512-V5tho5qQ89GD4qdzL07ZyXdrnpXZFLirGfaG6BB2vKhO6X1iA7UYYqntgBQ//ZuTUEdevskl+dVT5O4A9oOJUg==",
+ "license": "ISC",
+ "peerDependencies": {
+ "react": "^16.5.1 || ^17.0.0 || ^18.0.0",
+ "react-native": "*",
+ "react-native-svg": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0"
+ }
+ },
"node_modules/makeerror": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
@@ -6183,14 +6740,11 @@
"integrity": "sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ==",
"license": "Apache-2.0"
},
- "node_modules/math-intrinsics": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
- "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
+ "node_modules/mdn-data": {
+ "version": "2.0.14",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
+ "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==",
+ "license": "CC0-1.0"
},
"node_modules/memoize-one": {
"version": "5.2.1",
@@ -6198,27 +6752,25 @@
"integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==",
"license": "MIT"
},
- "node_modules/merge-options": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz",
- "integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==",
- "dependencies": {
- "is-plain-obj": "^2.1.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
"license": "MIT"
},
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
"node_modules/metro": {
- "version": "0.83.3",
- "resolved": "https://registry.npmjs.org/metro/-/metro-0.83.3.tgz",
- "integrity": "sha512-+rP+/GieOzkt97hSJ0MrPOuAH/jpaS21ZDvL9DJ35QYRDlQcwzcvUlGUf79AnQxq/2NPiS/AULhhM4TKutIt8Q==",
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro/-/metro-0.83.2.tgz",
+ "integrity": "sha512-HQgs9H1FyVbRptNSMy/ImchTTE5vS2MSqLoOo7hbDoBq6hPPZokwJvBMwrYSxdjQZmLXz2JFZtdvS+ZfgTc9yw==",
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.24.7",
@@ -6242,18 +6794,18 @@
"jest-worker": "^29.7.0",
"jsc-safe-url": "^0.2.2",
"lodash.throttle": "^4.1.1",
- "metro-babel-transformer": "0.83.3",
- "metro-cache": "0.83.3",
- "metro-cache-key": "0.83.3",
- "metro-config": "0.83.3",
- "metro-core": "0.83.3",
- "metro-file-map": "0.83.3",
- "metro-resolver": "0.83.3",
- "metro-runtime": "0.83.3",
- "metro-source-map": "0.83.3",
- "metro-symbolicate": "0.83.3",
- "metro-transform-plugins": "0.83.3",
- "metro-transform-worker": "0.83.3",
+ "metro-babel-transformer": "0.83.2",
+ "metro-cache": "0.83.2",
+ "metro-cache-key": "0.83.2",
+ "metro-config": "0.83.2",
+ "metro-core": "0.83.2",
+ "metro-file-map": "0.83.2",
+ "metro-resolver": "0.83.2",
+ "metro-runtime": "0.83.2",
+ "metro-source-map": "0.83.2",
+ "metro-symbolicate": "0.83.2",
+ "metro-transform-plugins": "0.83.2",
+ "metro-transform-worker": "0.83.2",
"mime-types": "^2.1.27",
"nullthrows": "^1.1.1",
"serialize-error": "^2.1.0",
@@ -6270,9 +6822,9 @@
}
},
"node_modules/metro-babel-transformer": {
- "version": "0.83.3",
- "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.83.3.tgz",
- "integrity": "sha512-1vxlvj2yY24ES1O5RsSIvg4a4WeL7PFXgKOHvXTXiW0deLvQr28ExXj6LjwCCDZ4YZLhq6HddLpZnX4dEdSq5g==",
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.83.2.tgz",
+ "integrity": "sha512-rirY1QMFlA1uxH3ZiNauBninwTioOgwChnRdDcbB4tgRZ+bGX9DiXoh9QdpppiaVKXdJsII932OwWXGGV4+Nlw==",
"license": "MIT",
"dependencies": {
"@babel/core": "^7.25.2",
@@ -6300,24 +6852,24 @@
}
},
"node_modules/metro-cache": {
- "version": "0.83.3",
- "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.83.3.tgz",
- "integrity": "sha512-3jo65X515mQJvKqK3vWRblxDEcgY55Sk3w4xa6LlfEXgQ9g1WgMh9m4qVZVwgcHoLy0a2HENTPCCX4Pk6s8c8Q==",
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.83.2.tgz",
+ "integrity": "sha512-Z43IodutUZeIS7OTH+yQFjc59QlFJ6s5OvM8p2AP9alr0+F8UKr8ADzFzoGKoHefZSKGa4bJx7MZJLF6GwPDHQ==",
"license": "MIT",
"dependencies": {
"exponential-backoff": "^3.1.1",
"flow-enums-runtime": "^0.0.6",
"https-proxy-agent": "^7.0.5",
- "metro-core": "0.83.3"
+ "metro-core": "0.83.2"
},
"engines": {
"node": ">=20.19.4"
}
},
"node_modules/metro-cache-key": {
- "version": "0.83.3",
- "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.83.3.tgz",
- "integrity": "sha512-59ZO049jKzSmvBmG/B5bZ6/dztP0ilp0o988nc6dpaDsU05Cl1c/lRf+yx8m9WW/JVgbmfO5MziBU559XjI5Zw==",
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.83.2.tgz",
+ "integrity": "sha512-3EMG/GkGKYoTaf5RqguGLSWRqGTwO7NQ0qXKmNBjr0y6qD9s3VBXYlwB+MszGtmOKsqE9q3FPrE5Nd9Ipv7rZw==",
"license": "MIT",
"dependencies": {
"flow-enums-runtime": "^0.0.6"
@@ -6327,18 +6879,18 @@
}
},
"node_modules/metro-config": {
- "version": "0.83.3",
- "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.83.3.tgz",
- "integrity": "sha512-mTel7ipT0yNjKILIan04bkJkuCzUUkm2SeEaTads8VfEecCh+ltXchdq6DovXJqzQAXuR2P9cxZB47Lg4klriA==",
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.83.2.tgz",
+ "integrity": "sha512-1FjCcdBe3e3D08gSSiU9u3Vtxd7alGH3x/DNFqWDFf5NouX4kLgbVloDDClr1UrLz62c0fHh2Vfr9ecmrOZp+g==",
"license": "MIT",
"dependencies": {
"connect": "^3.6.5",
"flow-enums-runtime": "^0.0.6",
"jest-validate": "^29.7.0",
- "metro": "0.83.3",
- "metro-cache": "0.83.3",
- "metro-core": "0.83.3",
- "metro-runtime": "0.83.3",
+ "metro": "0.83.2",
+ "metro-cache": "0.83.2",
+ "metro-core": "0.83.2",
+ "metro-runtime": "0.83.2",
"yaml": "^2.6.1"
},
"engines": {
@@ -6346,23 +6898,23 @@
}
},
"node_modules/metro-core": {
- "version": "0.83.3",
- "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.83.3.tgz",
- "integrity": "sha512-M+X59lm7oBmJZamc96usuF1kusd5YimqG/q97g4Ac7slnJ3YiGglW5CsOlicTR5EWf8MQFxxjDoB6ytTqRe8Hw==",
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.83.2.tgz",
+ "integrity": "sha512-8DRb0O82Br0IW77cNgKMLYWUkx48lWxUkvNUxVISyMkcNwE/9ywf1MYQUE88HaKwSrqne6kFgCSA/UWZoUT0Iw==",
"license": "MIT",
"dependencies": {
"flow-enums-runtime": "^0.0.6",
"lodash.throttle": "^4.1.1",
- "metro-resolver": "0.83.3"
+ "metro-resolver": "0.83.2"
},
"engines": {
"node": ">=20.19.4"
}
},
"node_modules/metro-file-map": {
- "version": "0.83.3",
- "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.83.3.tgz",
- "integrity": "sha512-jg5AcyE0Q9Xbbu/4NAwwZkmQn7doJCKGW0SLeSJmzNB9Z24jBe0AL2PHNMy4eu0JiKtNWHz9IiONGZWq7hjVTA==",
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.83.2.tgz",
+ "integrity": "sha512-cMSWnEqZrp/dzZIEd7DEDdk72PXz6w5NOKriJoDN9p1TDQ5nAYrY2lHi8d6mwbcGLoSlWmpPyny9HZYFfPWcGQ==",
"license": "MIT",
"dependencies": {
"debug": "^4.4.0",
@@ -6380,9 +6932,9 @@
}
},
"node_modules/metro-minify-terser": {
- "version": "0.83.3",
- "resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.83.3.tgz",
- "integrity": "sha512-O2BmfWj6FSfzBLrNCXt/rr2VYZdX5i6444QJU0fFoc7Ljg+Q+iqebwE3K0eTvkI6TRjELsXk1cjU+fXwAR4OjQ==",
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.83.2.tgz",
+ "integrity": "sha512-zvIxnh7U0JQ7vT4quasKsijId3dOAWgq+ip2jF/8TMrPUqQabGrs04L2dd0haQJ+PA+d4VvK/bPOY8X/vL2PWw==",
"license": "MIT",
"dependencies": {
"flow-enums-runtime": "^0.0.6",
@@ -6393,9 +6945,9 @@
}
},
"node_modules/metro-resolver": {
- "version": "0.83.3",
- "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.83.3.tgz",
- "integrity": "sha512-0js+zwI5flFxb1ktmR///bxHYg7OLpRpWZlBBruYG8OKYxeMP7SV0xQ/o/hUelrEMdK4LJzqVtHAhBm25LVfAQ==",
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.83.2.tgz",
+ "integrity": "sha512-Yf5mjyuiRE/Y+KvqfsZxrbHDA15NZxyfg8pIk0qg47LfAJhpMVEX+36e6ZRBq7KVBqy6VDX5Sq55iHGM4xSm7Q==",
"license": "MIT",
"dependencies": {
"flow-enums-runtime": "^0.0.6"
@@ -6405,9 +6957,9 @@
}
},
"node_modules/metro-runtime": {
- "version": "0.83.3",
- "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.83.3.tgz",
- "integrity": "sha512-JHCJb9ebr9rfJ+LcssFYA2x1qPYuSD/bbePupIGhpMrsla7RCwC/VL3yJ9cSU+nUhU4c9Ixxy8tBta+JbDeZWw==",
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.83.2.tgz",
+ "integrity": "sha512-nnsPtgRvFbNKwemqs0FuyFDzXLl+ezuFsUXDbX8o0SXOfsOPijqiQrf3kuafO1Zx1aUWf4NOrKJMAQP5EEHg9A==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.25.0",
@@ -6418,9 +6970,9 @@
}
},
"node_modules/metro-source-map": {
- "version": "0.83.3",
- "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.83.3.tgz",
- "integrity": "sha512-xkC3qwUBh2psVZgVavo8+r2C9Igkk3DibiOXSAht1aYRRcztEZNFtAMtfSB7sdO2iFMx2Mlyu++cBxz/fhdzQg==",
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.83.2.tgz",
+ "integrity": "sha512-5FL/6BSQvshIKjXOennt9upFngq2lFvDakZn5LfauIVq8+L4sxXewIlSTcxAtzbtjAIaXeOSVMtCJ5DdfCt9AA==",
"license": "MIT",
"dependencies": {
"@babel/traverse": "^7.25.3",
@@ -6428,9 +6980,9 @@
"@babel/types": "^7.25.2",
"flow-enums-runtime": "^0.0.6",
"invariant": "^2.2.4",
- "metro-symbolicate": "0.83.3",
+ "metro-symbolicate": "0.83.2",
"nullthrows": "^1.1.1",
- "ob1": "0.83.3",
+ "ob1": "0.83.2",
"source-map": "^0.5.6",
"vlq": "^1.0.0"
},
@@ -6438,15 +6990,24 @@
"node": ">=20.19.4"
}
},
+ "node_modules/metro-source-map/node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/metro-symbolicate": {
- "version": "0.83.3",
- "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.83.3.tgz",
- "integrity": "sha512-F/YChgKd6KbFK3eUR5HdUsfBqVsanf5lNTwFd4Ca7uuxnHgBC3kR/Hba/RGkenR3pZaGNp5Bu9ZqqP52Wyhomw==",
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.83.2.tgz",
+ "integrity": "sha512-KoU9BLwxxED6n33KYuQQuc5bXkIxF3fSwlc3ouxrrdLWwhu64muYZNQrukkWzhVKRNFIXW7X2iM8JXpi2heIPw==",
"license": "MIT",
"dependencies": {
"flow-enums-runtime": "^0.0.6",
"invariant": "^2.2.4",
- "metro-source-map": "0.83.3",
+ "metro-source-map": "0.83.2",
"nullthrows": "^1.1.1",
"source-map": "^0.5.6",
"vlq": "^1.0.0"
@@ -6458,10 +7019,19 @@
"node": ">=20.19.4"
}
},
+ "node_modules/metro-symbolicate/node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/metro-transform-plugins": {
- "version": "0.83.3",
- "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.83.3.tgz",
- "integrity": "sha512-eRGoKJU6jmqOakBMH5kUB7VitEWiNrDzBHpYbkBXW7C5fUGeOd2CyqrosEzbMK5VMiZYyOcNFEphvxk3OXey2A==",
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.83.2.tgz",
+ "integrity": "sha512-5WlW25WKPkiJk2yA9d8bMuZrgW7vfA4f4MBb9ZeHbTB3eIAoNN8vS8NENgG/X/90vpTB06X66OBvxhT3nHwP6A==",
"license": "MIT",
"dependencies": {
"@babel/core": "^7.25.2",
@@ -6476,9 +7046,9 @@
}
},
"node_modules/metro-transform-worker": {
- "version": "0.83.3",
- "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.83.3.tgz",
- "integrity": "sha512-Ztekew9t/gOIMZX1tvJOgX7KlSLL5kWykl0Iwu2cL2vKMKVALRl1hysyhUw0vjpAvLFx+Kfq9VLjnHIkW32fPA==",
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.83.2.tgz",
+ "integrity": "sha512-G5DsIg+cMZ2KNfrdLnWMvtppb3+Rp1GMyj7Bvd9GgYc/8gRmvq1XVEF9XuO87Shhb03kFhGqMTgZerz3hZ1v4Q==",
"license": "MIT",
"dependencies": {
"@babel/core": "^7.25.2",
@@ -6486,13 +7056,13 @@
"@babel/parser": "^7.25.3",
"@babel/types": "^7.25.2",
"flow-enums-runtime": "^0.0.6",
- "metro": "0.83.3",
- "metro-babel-transformer": "0.83.3",
- "metro-cache": "0.83.3",
- "metro-cache-key": "0.83.3",
- "metro-minify-terser": "0.83.3",
- "metro-source-map": "0.83.3",
- "metro-transform-plugins": "0.83.3",
+ "metro": "0.83.2",
+ "metro-babel-transformer": "0.83.2",
+ "metro-cache": "0.83.2",
+ "metro-cache-key": "0.83.2",
+ "metro-minify-terser": "0.83.2",
+ "metro-source-map": "0.83.2",
+ "metro-transform-plugins": "0.83.2",
"nullthrows": "^1.1.1"
},
"engines": {
@@ -6520,6 +7090,36 @@
"hermes-estree": "0.32.0"
}
},
+ "node_modules/metro/node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/metro/node_modules/ws": {
+ "version": "7.5.10",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
+ "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.3.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": "^5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
"node_modules/micromatch": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
@@ -6679,13 +7279,313 @@
"type": "github",
"url": "https://github.com/sponsors/ai"
}
- ],
- "license": "MIT",
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/nativewind": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/nativewind/-/nativewind-4.2.1.tgz",
+ "integrity": "sha512-10uUB2Dlli3MH3NDL5nMHqJHz1A3e/E6mzjTj6cl7hHECClJ7HpE6v+xZL+GXdbwQSnWE+UWMIMsNz7yOQkAJQ==",
+ "license": "MIT",
+ "dependencies": {
+ "comment-json": "^4.2.5",
+ "debug": "^4.3.7",
+ "react-native-css-interop": "0.2.1"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "tailwindcss": ">3.3.0"
+ }
+ },
+ "node_modules/nativewind/node_modules/detect-libc": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
+ "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
+ "license": "Apache-2.0",
+ "bin": {
+ "detect-libc": "bin/detect-libc.js"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/nativewind/node_modules/lightningcss": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.27.0.tgz",
+ "integrity": "sha512-8f7aNmS1+etYSLHht0fQApPc2kNO8qGRutifN5rVIc6Xo6ABsEbqOr758UwI7ALVbTt4x1fllKt0PYgzD9S3yQ==",
+ "license": "MPL-2.0",
+ "dependencies": {
+ "detect-libc": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "lightningcss-darwin-arm64": "1.27.0",
+ "lightningcss-darwin-x64": "1.27.0",
+ "lightningcss-freebsd-x64": "1.27.0",
+ "lightningcss-linux-arm-gnueabihf": "1.27.0",
+ "lightningcss-linux-arm64-gnu": "1.27.0",
+ "lightningcss-linux-arm64-musl": "1.27.0",
+ "lightningcss-linux-x64-gnu": "1.27.0",
+ "lightningcss-linux-x64-musl": "1.27.0",
+ "lightningcss-win32-arm64-msvc": "1.27.0",
+ "lightningcss-win32-x64-msvc": "1.27.0"
+ }
+ },
+ "node_modules/nativewind/node_modules/lightningcss-darwin-arm64": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.27.0.tgz",
+ "integrity": "sha512-Gl/lqIXY+d+ySmMbgDf0pgaWSqrWYxVHoc88q+Vhf2YNzZ8DwoRzGt5NZDVqqIW5ScpSnmmjcgXP87Dn2ylSSQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/nativewind/node_modules/lightningcss-darwin-x64": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.27.0.tgz",
+ "integrity": "sha512-0+mZa54IlcNAoQS9E0+niovhyjjQWEMrwW0p2sSdLRhLDc8LMQ/b67z7+B5q4VmjYCMSfnFi3djAAQFIDuj/Tg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/nativewind/node_modules/lightningcss-freebsd-x64": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.27.0.tgz",
+ "integrity": "sha512-n1sEf85fePoU2aDN2PzYjoI8gbBqnmLGEhKq7q0DKLj0UTVmOTwDC7PtLcy/zFxzASTSBlVQYJUhwIStQMIpRA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/nativewind/node_modules/lightningcss-linux-arm-gnueabihf": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.27.0.tgz",
+ "integrity": "sha512-MUMRmtdRkOkd5z3h986HOuNBD1c2lq2BSQA1Jg88d9I7bmPGx08bwGcnB75dvr17CwxjxD6XPi3Qh8ArmKFqCA==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/nativewind/node_modules/lightningcss-linux-arm64-gnu": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.27.0.tgz",
+ "integrity": "sha512-cPsxo1QEWq2sfKkSq2Bq5feQDHdUEwgtA9KaB27J5AX22+l4l0ptgjMZZtYtUnteBofjee+0oW1wQ1guv04a7A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/nativewind/node_modules/lightningcss-linux-arm64-musl": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.27.0.tgz",
+ "integrity": "sha512-rCGBm2ax7kQ9pBSeITfCW9XSVF69VX+fm5DIpvDZQl4NnQoMQyRwhZQm9pd59m8leZ1IesRqWk2v/DntMo26lg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/nativewind/node_modules/lightningcss-linux-x64-gnu": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.27.0.tgz",
+ "integrity": "sha512-Dk/jovSI7qqhJDiUibvaikNKI2x6kWPN79AQiD/E/KeQWMjdGe9kw51RAgoWFDi0coP4jinaH14Nrt/J8z3U4A==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/nativewind/node_modules/lightningcss-linux-x64-musl": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.27.0.tgz",
+ "integrity": "sha512-QKjTxXm8A9s6v9Tg3Fk0gscCQA1t/HMoF7Woy1u68wCk5kS4fR+q3vXa1p3++REW784cRAtkYKrPy6JKibrEZA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/nativewind/node_modules/lightningcss-win32-arm64-msvc": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.27.0.tgz",
+ "integrity": "sha512-/wXegPS1hnhkeG4OXQKEMQeJd48RDC3qdh+OA8pCuOPCyvnm/yEayrJdJVqzBsqpy1aJklRCVxscpFur80o6iQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/nativewind/node_modules/lightningcss-win32-x64-msvc": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.27.0.tgz",
+ "integrity": "sha512-/OJLj94Zm/waZShL8nB5jsNj3CfNATLCTyFxZyouilfTmSoLDX7VlVAmhPHoZWVFp4vdmoiEbPEYC8HID3m6yw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/nativewind/node_modules/react-native-css-interop": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/react-native-css-interop/-/react-native-css-interop-0.2.1.tgz",
+ "integrity": "sha512-B88f5rIymJXmy1sNC/MhTkb3xxBej1KkuAt7TiT9iM7oXz3RM8Bn+7GUrfR02TvSgKm4cg2XiSuLEKYfKwNsjA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.22.15",
+ "@babel/traverse": "^7.23.0",
+ "@babel/types": "^7.23.0",
+ "debug": "^4.3.7",
+ "lightningcss": "~1.27.0",
+ "semver": "^7.6.3"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "react": ">=18",
+ "react-native": "*",
+ "react-native-reanimated": ">=3.6.2",
+ "tailwindcss": "~3"
+ },
+ "peerDependenciesMeta": {
+ "react-native-safe-area-context": {
+ "optional": true
+ },
+ "react-native-svg": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/nativewind/node_modules/semver": {
+ "version": "7.7.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
+ "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "license": "ISC",
"bin": {
- "nanoid": "bin/nanoid.cjs"
+ "semver": "bin/semver.js"
},
"engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ "node": ">=10"
}
},
"node_modules/negotiator": {
@@ -6707,6 +7607,7 @@
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "license": "MIT",
"dependencies": {
"whatwg-url": "^5.0.0"
},
@@ -6779,6 +7680,18 @@
"node": ">=10"
}
},
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
"node_modules/nullthrows": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz",
@@ -6786,9 +7699,9 @@
"license": "MIT"
},
"node_modules/ob1": {
- "version": "0.83.3",
- "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.83.3.tgz",
- "integrity": "sha512-egUxXCDwoWG06NGCS5s5AdcpnumHKJlfd3HH06P3m9TEMwwScfcY35wpQxbm9oHof+dM/lVH9Rfyu1elTVelSA==",
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.83.2.tgz",
+ "integrity": "sha512-XlK3w4M+dwd1g1gvHzVbxiXEbUllRONEgcF2uEO0zm4nxa0eKlh41c6N65q1xbiDOeKKda1tvNOAD33fNjyvCg==",
"license": "MIT",
"dependencies": {
"flow-enums-runtime": "^0.0.6"
@@ -6806,6 +7719,15 @@
"node": ">=0.10.0"
}
},
+ "node_modules/object-hash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
+ "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
@@ -7112,6 +8034,15 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
+ "node_modules/pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/pirates": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz",
@@ -7163,6 +8094,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"nanoid": "^3.3.7",
"picocolors": "^1.1.1",
@@ -7172,10 +8104,133 @@
"node": "^10 || ^12 || >=14"
}
},
+ "node_modules/postcss-import": {
+ "version": "15.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
+ "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.0.0",
+ "read-cache": "^1.0.0",
+ "resolve": "^1.1.7"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.0.0"
+ }
+ },
+ "node_modules/postcss-js": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz",
+ "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "camelcase-css": "^2.0.1"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >= 16"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4.21"
+ }
+ },
+ "node_modules/postcss-load-config": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz",
+ "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "lilconfig": "^3.1.1"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "peerDependencies": {
+ "jiti": ">=1.21.0",
+ "postcss": ">=8.0.9",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ },
+ "postcss": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/postcss-nested": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
+ "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "postcss-selector-parser": "^6.1.1"
+ },
+ "engines": {
+ "node": ">=12.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.14"
+ }
+ },
+ "node_modules/postcss-selector-parser": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
+ "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/postcss-value-parser": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
- "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
+ "license": "MIT"
},
"node_modules/pretty-bytes": {
"version": "5.6.0",
@@ -7215,6 +8270,12 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
+ "node_modules/pretty-format/node_modules/react-is": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "license": "MIT"
+ },
"node_modules/proc-log": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz",
@@ -7255,12 +8316,6 @@
"node": ">= 6"
}
},
- "node_modules/proxy-from-env": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
- "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
- "license": "MIT"
- },
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
@@ -7305,6 +8360,26 @@
"inherits": "~2.0.3"
}
},
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
"node_modules/range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@@ -7349,6 +8424,27 @@
"ws": "^7"
}
},
+ "node_modules/react-devtools-core/node_modules/ws": {
+ "version": "7.5.10",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
+ "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.3.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": "^5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
"node_modules/react-dom": {
"version": "19.1.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz",
@@ -7362,6 +8458,12 @@
"react": "^19.1.0"
}
},
+ "node_modules/react-fast-compare": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
+ "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==",
+ "license": "MIT"
+ },
"node_modules/react-freeze": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/react-freeze/-/react-freeze-1.0.4.tgz",
@@ -7375,9 +8477,9 @@
}
},
"node_modules/react-is": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
- "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "version": "19.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.0.tgz",
+ "integrity": "sha512-x3Ax3kNSMIIkyVYhWPyO09bu0uttcAIoecO/um/rKGQ4EltYWVYtyiGkS/3xMynrbVQdS69Jhlv8FXUEZehlzA==",
"license": "MIT"
},
"node_modules/react-native": {
@@ -7438,6 +8540,49 @@
}
}
},
+ "node_modules/react-native-css-interop": {
+ "version": "0.1.22",
+ "resolved": "https://registry.npmjs.org/react-native-css-interop/-/react-native-css-interop-0.1.22.tgz",
+ "integrity": "sha512-Mu01e+H9G+fxSWvwtgWlF5MJBJC4VszTCBXopIpeR171lbeBInHb8aHqoqRPxmJpi3xIHryzqKFOJYAdk7PBxg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.22.15",
+ "@babel/traverse": "^7.23.0",
+ "@babel/types": "^7.23.0",
+ "debug": "^4.3.7",
+ "lightningcss": "^1.27.0",
+ "semver": "^7.6.3"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "react": ">=18",
+ "react-native": "*",
+ "react-native-reanimated": ">=3.6.2",
+ "tailwindcss": "~3"
+ },
+ "peerDependenciesMeta": {
+ "react-native-safe-area-context": {
+ "optional": true
+ },
+ "react-native-svg": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-native-css-interop/node_modules/semver": {
+ "version": "7.7.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
+ "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/react-native-is-edge-to-edge": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/react-native-is-edge-to-edge/-/react-native-is-edge-to-edge-1.2.1.tgz",
@@ -7448,51 +8593,35 @@
"react-native": "*"
}
},
- "node_modules/react-native-paper": {
- "version": "5.14.5",
- "resolved": "https://registry.npmjs.org/react-native-paper/-/react-native-paper-5.14.5.tgz",
- "integrity": "sha512-eaIH5bUQjJ/mYm4AkI6caaiyc7BcHDwX6CqNDi6RIxfxfWxROsHpll1oBuwn/cFvknvA8uEAkqLk/vzVihI3AQ==",
+ "node_modules/react-native-reanimated": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-4.1.5.tgz",
+ "integrity": "sha512-UA6VUbxwhRjEw2gSNrvhkusUq3upfD3Cv+AnB07V+kC8kpvwRVI+ivwY95ePbWNFkFpP+Y2Sdw1WHpHWEV+P2Q==",
"license": "MIT",
- "workspaces": [
- "example",
- "docs"
- ],
+ "peer": true,
"dependencies": {
- "@callstack/react-theme-provider": "^3.0.9",
- "color": "^3.1.2",
- "use-latest-callback": "^0.2.3"
+ "react-native-is-edge-to-edge": "^1.2.1",
+ "semver": "7.7.2"
},
"peerDependencies": {
+ "@babel/core": "^7.0.0-0",
"react": "*",
"react-native": "*",
- "react-native-safe-area-context": "*"
- }
- },
- "node_modules/react-native-paper/node_modules/color": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz",
- "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==",
- "license": "MIT",
- "dependencies": {
- "color-convert": "^1.9.3",
- "color-string": "^1.6.0"
+ "react-native-worklets": ">=0.5.0"
}
},
- "node_modules/react-native-paper/node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "license": "MIT",
- "dependencies": {
- "color-name": "1.1.3"
+ "node_modules/react-native-reanimated/node_modules/semver": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
}
},
- "node_modules/react-native-paper/node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
- "license": "MIT"
- },
"node_modules/react-native-safe-area-context": {
"version": "5.6.2",
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-5.6.2.tgz",
@@ -7520,11 +8649,28 @@
"react-native": "*"
}
},
+ "node_modules/react-native-svg": {
+ "version": "15.12.1",
+ "resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-15.12.1.tgz",
+ "integrity": "sha512-vCuZJDf8a5aNC2dlMovEv4Z0jjEUET53lm/iILFnFewa15b4atjVxU6Wirm6O9y6dEsdjDZVD7Q3QM4T1wlI8g==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "css-select": "^5.1.0",
+ "css-tree": "^1.1.3",
+ "warn-once": "0.1.1"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*"
+ }
+ },
"node_modules/react-native-web": {
"version": "0.21.2",
"resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.21.2.tgz",
"integrity": "sha512-SO2t9/17zM4iEnFvlu2DA9jqNbzNhoUP+AItkoCOyFmDMOhUnBBznBDCYN92fGdfAkfQlWzPoez6+zLxFNsZEg==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/runtime": "^7.18.6",
"@react-native/normalize-colors": "^0.74.1",
@@ -7543,34 +8689,49 @@
"node_modules/react-native-web/node_modules/@react-native/normalize-colors": {
"version": "0.74.89",
"resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.74.89.tgz",
- "integrity": "sha512-qoMMXddVKVhZ8PA1AbUCk83trpd6N+1nF2A6k1i6LsQObyS92fELuk8kU/lQs6M7BsMHwqyLCpQJ1uFgNvIQXg=="
+ "integrity": "sha512-qoMMXddVKVhZ8PA1AbUCk83trpd6N+1nF2A6k1i6LsQObyS92fELuk8kU/lQs6M7BsMHwqyLCpQJ1uFgNvIQXg==",
+ "license": "MIT"
},
"node_modules/react-native-web/node_modules/memoize-one": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
- "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
- },
- "node_modules/react-native/node_modules/@react-native/virtualized-lists": {
- "version": "0.81.5",
- "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.81.5.tgz",
- "integrity": "sha512-UVXgV/db25OPIvwZySeToXD/9sKKhOdkcWmmf4Jh8iBZuyfML+/5CasaZ1E7Lqg6g3uqVQq75NqIwkYmORJMPw==",
- "license": "MIT",
- "dependencies": {
- "invariant": "^2.2.4",
- "nullthrows": "^1.1.1"
- },
- "engines": {
- "node": ">= 20.19.4"
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
+ "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==",
+ "license": "MIT"
+ },
+ "node_modules/react-native-worklets": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/react-native-worklets/-/react-native-worklets-0.6.1.tgz",
+ "integrity": "sha512-URca8l7c7Uog7gv4mcg9KILdJlnbvwdS5yfXQYf5TDkD2W1VY1sduEKrD+sA3lUPXH/TG1vmXAvNxCNwPMYgGg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/plugin-transform-arrow-functions": "^7.0.0-0",
+ "@babel/plugin-transform-class-properties": "^7.0.0-0",
+ "@babel/plugin-transform-classes": "^7.0.0-0",
+ "@babel/plugin-transform-nullish-coalescing-operator": "^7.0.0-0",
+ "@babel/plugin-transform-optional-chaining": "^7.0.0-0",
+ "@babel/plugin-transform-shorthand-properties": "^7.0.0-0",
+ "@babel/plugin-transform-template-literals": "^7.0.0-0",
+ "@babel/plugin-transform-unicode-regex": "^7.0.0-0",
+ "@babel/preset-typescript": "^7.16.7",
+ "convert-source-map": "^2.0.0",
+ "semver": "7.7.2"
},
"peerDependencies": {
- "@types/react": "^19.1.0",
+ "@babel/core": "^7.0.0-0",
"react": "*",
"react-native": "*"
+ }
+ },
+ "node_modules/react-native-worklets/node_modules/semver": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
},
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
+ "engines": {
+ "node": ">=10"
}
},
"node_modules/react-native/node_modules/brace-expansion": {
@@ -7626,9 +8787,9 @@
}
},
"node_modules/react-native/node_modules/semver": {
- "version": "7.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
- "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "version": "7.7.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
+ "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -7656,6 +8817,108 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-remove-scroll": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz",
+ "integrity": "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==",
+ "license": "MIT",
+ "dependencies": {
+ "react-remove-scroll-bar": "^2.3.7",
+ "react-style-singleton": "^2.2.3",
+ "tslib": "^2.1.0",
+ "use-callback-ref": "^1.3.3",
+ "use-sidecar": "^1.1.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-remove-scroll-bar": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz",
+ "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==",
+ "license": "MIT",
+ "dependencies": {
+ "react-style-singleton": "^2.2.2",
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-style-singleton": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz",
+ "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==",
+ "license": "MIT",
+ "dependencies": {
+ "get-nonce": "^1.0.0",
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/read-cache": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
+ "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
+ "license": "MIT",
+ "dependencies": {
+ "pify": "^2.3.0"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "license": "MIT",
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/readdirp/node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
"node_modules/regenerate": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
@@ -7830,6 +9093,16 @@
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
"license": "ISC"
},
+ "node_modules/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
@@ -7889,6 +9162,29 @@
"node": "*"
}
},
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
"node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -8101,10 +9397,17 @@
"node": ">= 0.8"
}
},
+ "node_modules/server-only": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/server-only/-/server-only-0.0.1.tgz",
+ "integrity": "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==",
+ "license": "MIT"
+ },
"node_modules/setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
- "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="
+ "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
+ "license": "MIT"
},
"node_modules/setprototypeof": {
"version": "1.2.0",
@@ -8112,6 +9415,21 @@
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
"license": "ISC"
},
+ "node_modules/sf-symbols-typescript": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/sf-symbols-typescript/-/sf-symbols-typescript-2.1.0.tgz",
+ "integrity": "sha512-ezT7gu/SHTPIOEEoG6TF+O0m5eewl0ZDAO4AtdBi5HjsrUI6JdCG17+Q8+aKp0heM06wZKApRCn5olNbs0Wb/A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/shallowequal": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
+ "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==",
+ "license": "MIT"
+ },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -8168,21 +9486,27 @@
"plist": "^3.0.5"
}
},
+ "node_modules/simple-plist/node_modules/bplist-parser": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.1.tgz",
+ "integrity": "sha512-PyJxiNtA5T2PlLIeBot4lbp7rj4OadzjnMZD/G5zuBNt8ei/yCU7+wW0h2bag9vr8c+/WuRWmSxbqAl9hL1rBA==",
+ "license": "MIT",
+ "dependencies": {
+ "big-integer": "1.6.x"
+ },
+ "engines": {
+ "node": ">= 5.10.0"
+ }
+ },
"node_modules/simple-swizzle": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
- "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz",
+ "integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==",
"license": "MIT",
"dependencies": {
"is-arrayish": "^0.3.1"
}
},
- "node_modules/simple-swizzle/node_modules/is-arrayish": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
- "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
- "license": "MIT"
- },
"node_modules/sisteransi": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
@@ -8207,15 +9531,6 @@
"node": ">=8.0.0"
}
},
- "node_modules/source-map": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
@@ -8433,7 +9748,8 @@
"node_modules/styleq": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/styleq/-/styleq-0.1.3.tgz",
- "integrity": "sha512-3ZUifmCDCQanjeej1f6kyl/BeP/Vae5EYkQ9iJfUm/QwZvlgnZzyflqAsAWYURdtea8Vkvswu2GrC57h3qffcA=="
+ "integrity": "sha512-3ZUifmCDCQanjeej1f6kyl/BeP/Vae5EYkQ9iJfUm/QwZvlgnZzyflqAsAWYURdtea8Vkvswu2GrC57h3qffcA==",
+ "license": "MIT"
},
"node_modules/sucrase": {
"version": "3.35.0",
@@ -8503,6 +9819,54 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/tailwind-merge": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.6.0.tgz",
+ "integrity": "sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/dcastil"
+ }
+ },
+ "node_modules/tailwindcss": {
+ "version": "3.4.18",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.18.tgz",
+ "integrity": "sha512-6A2rnmW5xZMdw11LYjhcI5846rt9pbLSabY5XPxo+XWdxwZaFEn47Go4NzFiHu9sNNmr/kXivP1vStfvMaK1GQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@alloc/quick-lru": "^5.2.0",
+ "arg": "^5.0.2",
+ "chokidar": "^3.6.0",
+ "didyoumean": "^1.2.2",
+ "dlv": "^1.1.3",
+ "fast-glob": "^3.3.2",
+ "glob-parent": "^6.0.2",
+ "is-glob": "^4.0.3",
+ "jiti": "^1.21.7",
+ "lilconfig": "^3.1.3",
+ "micromatch": "^4.0.8",
+ "normalize-path": "^3.0.0",
+ "object-hash": "^3.0.0",
+ "picocolors": "^1.1.1",
+ "postcss": "^8.4.47",
+ "postcss-import": "^15.1.0",
+ "postcss-js": "^4.0.1",
+ "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0",
+ "postcss-nested": "^6.2.0",
+ "postcss-selector-parser": "^6.1.2",
+ "resolve": "^1.22.8",
+ "sucrase": "^3.35.0"
+ },
+ "bin": {
+ "tailwind": "lib/cli.js",
+ "tailwindcss": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
"node_modules/tar": {
"version": "7.5.2",
"resolved": "https://registry.npmjs.org/tar/-/tar-7.5.2.tgz",
@@ -8691,7 +10055,8 @@
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+ "license": "MIT"
},
"node_modules/ts-interface-checker": {
"version": "0.1.13",
@@ -8699,6 +10064,12 @@
"integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
"license": "Apache-2.0"
},
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "license": "0BSD"
+ },
"node_modules/type-detect": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
@@ -8717,10 +10088,24 @@
"node": ">=8"
}
},
+ "node_modules/typescript": {
+ "version": "5.9.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
+ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
"node_modules/ua-parser-js": {
- "version": "1.0.40",
- "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.40.tgz",
- "integrity": "sha512-z6PJ8Lml+v3ichVojCiB8toQJBuwR42ySM4ezjXIqXK3M0HczmKQ3LF4rhU55PfD99KEEXQG6yb7iOMyvYuHew==",
+ "version": "1.0.41",
+ "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.41.tgz",
+ "integrity": "sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug==",
"funding": [
{
"type": "opencollective",
@@ -8735,6 +10120,7 @@
"url": "https://github.com/sponsors/faisalman"
}
],
+ "license": "MIT",
"bin": {
"ua-parser-js": "script/cli.js"
},
@@ -8752,9 +10138,9 @@
}
},
"node_modules/undici-types": {
- "version": "7.8.0",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz",
- "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==",
+ "version": "7.16.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
+ "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
"license": "MIT"
},
"node_modules/unicode-canonical-property-names-ecmascript": {
@@ -8848,24 +10234,73 @@
"browserslist": ">= 4.21.0"
}
},
+ "node_modules/use-callback-ref": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz",
+ "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/use-latest-callback": {
- "version": "0.2.4",
- "resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.2.4.tgz",
- "integrity": "sha512-LS2s2n1usUUnDq4oVh1ca6JFX9uSqUncTfAm44WMg0v6TxL7POUTk1B044NH8TeLkFbNajIsgDHcgNpNzZucdg==",
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.2.6.tgz",
+ "integrity": "sha512-FvRG9i1HSo0wagmX63Vrm8SnlUU3LMM3WyZkQ76RnslpBrX694AdG4A0zQBx2B3ZifFA0yv/BaEHGBnEax5rZg==",
"license": "MIT",
"peerDependencies": {
"react": ">=16.8"
}
},
+ "node_modules/use-sidecar": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz",
+ "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==",
+ "license": "MIT",
+ "dependencies": {
+ "detect-node-es": "^1.1.0",
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/use-sync-external-store": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz",
- "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==",
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz",
+ "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==",
"license": "MIT",
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "license": "MIT"
+ },
"node_modules/utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
@@ -8902,6 +10337,19 @@
"node": ">= 0.8"
}
},
+ "node_modules/vaul": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vaul/-/vaul-1.1.2.tgz",
+ "integrity": "sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-dialog": "^1.1.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc"
+ }
+ },
"node_modules/vlq": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz",
@@ -8933,13 +10381,10 @@
}
},
"node_modules/webidl-conversions": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz",
- "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=8"
- }
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+ "license": "BSD-2-Clause"
},
"node_modules/whatwg-fetch": {
"version": "3.6.20",
@@ -8951,6 +10396,7 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "license": "MIT",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
@@ -8970,10 +10416,14 @@
"node": ">=10"
}
},
- "node_modules/whatwg-url/node_modules/webidl-conversions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
+ "node_modules/whatwg-url-without-unicode/node_modules/webidl-conversions": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz",
+ "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=8"
+ }
},
"node_modules/which": {
"version": "2.0.2",
@@ -9121,16 +10571,16 @@
"license": "ISC"
},
"node_modules/ws": {
- "version": "7.5.10",
- "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
- "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
+ "version": "8.18.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
+ "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
"license": "MIT",
"engines": {
- "node": ">=8.3.0"
+ "node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
- "utf-8-validate": "^5.0.2"
+ "utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
diff --git a/mobile/package.json b/mobile/package.json
index c3b85321..eeea72c1 100644
--- a/mobile/package.json
+++ b/mobile/package.json
@@ -1,7 +1,7 @@
{
"name": "mobile",
"version": "1.0.0",
- "main": "index.js",
+ "main": "expo-router/entry",
"scripts": {
"start": "expo start",
"android": "expo start --android",
@@ -9,25 +9,40 @@
"web": "expo start --web"
},
"dependencies": {
- "@expo/metro-runtime": "~6.1.2",
- "@react-native-async-storage/async-storage": "^2.1.2",
- "@react-navigation/bottom-tabs": "^7.4.4",
- "@react-navigation/native": "^7.1.16",
- "@react-navigation/native-stack": "^7.3.23",
- "axios": "^1.11.0",
- "expo": "^54.0.25",
- "expo-image-picker": "~17.0.8",
+ "@expo-google-fonts/inter": "^0.2.3",
+ "@expo-google-fonts/space-grotesk": "^0.2.3",
+ "clsx": "^2.1.1",
+ "expo": "~54.0.25",
+ "expo-build-properties": "^1.0.9",
+ "expo-constants": "~18.0.10",
+ "expo-linking": "~8.0.9",
+ "expo-router": "~6.0.15",
+ "expo-splash-screen": "^31.0.11",
"expo-status-bar": "~3.0.8",
+ "expo-system-ui": "~6.0.8",
+ "lucide-react-native": "^0.475.0",
+ "nativewind": "^4.1.23",
"react": "19.1.0",
"react-dom": "19.1.0",
"react-native": "0.81.5",
- "react-native-paper": "^5.14.5",
- "react-native-safe-area-context": "^5.4.0",
- "react-native-screens": "^4.11.1",
- "react-native-web": "^0.21.0"
+ "react-native-css-interop": "^0.1.22",
+ "react-native-reanimated": "~4.1.1",
+ "react-native-safe-area-context": "~5.6.0",
+ "react-native-screens": "~4.16.0",
+ "react-native-svg": "15.12.1",
+ "react-native-web": "~0.21.0",
+ "react-native-worklets": "^0.6.1",
+ "tailwind-merge": "^2.5.2",
+ "tailwindcss": "^3.4.17"
},
"devDependencies": {
- "@babel/core": "^7.20.0"
+ "@babel/core": "^7.20.0",
+ "@types/react": "~19.1.10",
+ "typescript": "^5.1.3"
+ },
+ "overrides": {
+ "react": "19.1.0",
+ "react-dom": "19.1.0"
},
"private": true
}
diff --git a/mobile/screens/AccountScreen.js b/mobile/screens/AccountScreen.js
deleted file mode 100644
index 16ce8392..00000000
--- a/mobile/screens/AccountScreen.js
+++ /dev/null
@@ -1,87 +0,0 @@
-import { useContext } from "react";
-import { Alert, StyleSheet, View } from "react-native";
-import { Appbar, Avatar, Divider, List, Text } from "react-native-paper";
-import { AuthContext } from "../context/AuthContext";
-
-const AccountScreen = ({ navigation }) => {
- const { user, logout } = useContext(AuthContext);
-
- const handleLogout = () => {
- logout();
- };
-
- const handleComingSoon = () => {
- Alert.alert("Coming Soon", "This feature is not yet implemented.");
- };
-
- return (
-
-
-
-
-
-
- {user?.imageUrl && /^(https?:|data:image)/.test(user.imageUrl) ? (
-
- ) : (
-
- )}
-
- {user?.name}
-
-
- {user?.email}
-
-
-
-
- }
- onPress={() => navigation.navigate("EditProfile")}
- />
-
- }
- onPress={handleComingSoon}
- />
-
- }
- onPress={handleComingSoon}
- />
-
- }
- onPress={handleLogout}
- />
-
-
-
- );
-};
-
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- },
- content: {
- padding: 16,
- },
- profileSection: {
- alignItems: "center",
- marginBottom: 24,
- },
- name: {
- marginTop: 16,
- },
- email: {
- marginTop: 4,
- color: "gray",
- },
-});
-
-export default AccountScreen;
diff --git a/mobile/screens/AddExpenseScreen.js b/mobile/screens/AddExpenseScreen.js
deleted file mode 100644
index 59cb65ed..00000000
--- a/mobile/screens/AddExpenseScreen.js
+++ /dev/null
@@ -1,494 +0,0 @@
-import { useContext, useEffect, useState } from "react";
-import {
- Alert,
- KeyboardAvoidingView,
- Platform,
- StyleSheet,
- View,
-} from "react-native";
-import {
- ActivityIndicator,
- Button,
- Checkbox,
- Menu,
- Paragraph,
- SegmentedButtons,
- Text,
- TextInput,
- Title,
-} from "react-native-paper";
-import { createExpense, getGroupMembers } from "../api/groups";
-import { AuthContext } from "../context/AuthContext";
-
-const AddExpenseScreen = ({ route, navigation }) => {
- const { groupId } = route.params;
- const { token, user } = useContext(AuthContext);
- const [description, setDescription] = useState("");
- const [amount, setAmount] = useState("");
- const [members, setMembers] = useState([]);
- const [isLoading, setIsLoading] = useState(true);
- const [isSubmitting, setIsSubmitting] = useState(false);
- const [splitMethod, setSplitMethod] = useState("equal");
- const [payerId, setPayerId] = useState(null); // Initialize as null until members are loaded
- const [menuVisible, setMenuVisible] = useState(false);
-
- // State for different split methods
- const [percentages, setPercentages] = useState({});
- const [shares, setShares] = useState({});
- const [exactAmounts, setExactAmounts] = useState({});
- const [selectedMembers, setSelectedMembers] = useState({}); // For equal split
-
- useEffect(() => {
- const fetchMembers = async () => {
- try {
- const response = await getGroupMembers(groupId);
- setMembers(response.data);
- // Initialize split states
- const initialShares = {};
- const initialPercentages = {};
- const initialExactAmounts = {};
- const initialSelectedMembers = {};
- const numMembers = response.data.length;
-
- // Calculate percentages using integer math to avoid floating-point errors
- const basePercentage = Math.floor(100 / numMembers);
- const remainder = 100 - basePercentage * numMembers;
-
- response.data.forEach((member, index) => {
- initialShares[member.userId] = "1";
-
- // Distribute percentages using integer math
- let memberPercentage = basePercentage;
- // Distribute remainder to first members (could also be last, but first is simpler)
- if (index < remainder) {
- memberPercentage += 1;
- }
- initialPercentages[member.userId] = memberPercentage.toString();
-
- initialExactAmounts[member.userId] = "0.00";
- initialSelectedMembers[member.userId] = true; // Select all by default
- });
- setShares(initialShares);
- setPercentages(initialPercentages);
- setExactAmounts(initialExactAmounts);
- setSelectedMembers(initialSelectedMembers);
-
- // Set default payer to current user if they're a member
- const currentUserMember = response.data.find(
- (member) => member.userId === user._id
- );
- if (currentUserMember) {
- setPayerId(user._id);
- } else if (response.data.length > 0) {
- setPayerId(response.data[0].userId);
- }
- } catch (error) {
- console.error("Failed to fetch members:", error);
- Alert.alert("Error", "Failed to fetch group members.");
- } finally {
- setIsLoading(false);
- }
- };
- if (token && groupId) {
- fetchMembers();
- }
- }, [token, groupId]);
-
- const handleAddExpense = async () => {
- if (!description || !amount) {
- Alert.alert("Error", "Please fill in all fields.");
- return;
- }
- if (!payerId) {
- Alert.alert("Error", "Please select who paid for this expense.");
- return;
- }
- const numericAmount = parseFloat(amount);
- if (isNaN(numericAmount) || numericAmount <= 0) {
- Alert.alert("Error", "Please enter a valid amount.");
- return;
- }
-
- setIsSubmitting(true);
- let expenseData;
-
- try {
- let splits = [];
- let splitType = splitMethod;
-
- if (splitMethod === "equal") {
- const includedMembers = Object.keys(selectedMembers).filter(
- (userId) => selectedMembers[userId]
- );
- if (includedMembers.length === 0) {
- throw new Error("You must select at least one member for the split.");
- }
- const splitAmount =
- Math.round((numericAmount / includedMembers.length) * 100) / 100;
- // Calculate remainder to handle rounding
- const totalSplitAmount = splitAmount * includedMembers.length;
- const remainder =
- Math.round((numericAmount - totalSplitAmount) * 100) / 100;
-
- splits = includedMembers.map((userId, index) => ({
- userId,
- amount: index === 0 ? splitAmount + remainder : splitAmount, // Add remainder to first member
- type: "equal",
- }));
- splitType = "equal";
- } else if (splitMethod === "exact") {
- const total = Object.values(exactAmounts).reduce(
- (sum, val) => sum + parseFloat(val || "0"),
- 0
- );
- if (Math.abs(total - numericAmount) > 0.01) {
- throw new Error(
- `The exact amounts must add up to ${numericAmount.toFixed(
- 2
- )}. Current total: ${total.toFixed(2)}`
- );
- }
- splits = Object.entries(exactAmounts)
- .filter(([userId, value]) => parseFloat(value || "0") > 0)
- .map(([userId, value]) => ({
- userId,
- amount: Math.round(parseFloat(value) * 100) / 100,
- type: "unequal",
- }));
- splitType = "unequal"; // Backend uses 'unequal' for exact amounts
- } else if (splitMethod === "percentage") {
- const total = Object.values(percentages).reduce(
- (sum, val) => sum + parseFloat(val || "0"),
- 0
- );
- if (Math.abs(total - 100) > 0.01) {
- throw new Error(
- `Percentages must add up to 100%. Current total: ${total.toFixed(
- 2
- )}%`
- );
- }
- splits = Object.entries(percentages)
- .filter(([userId, value]) => parseFloat(value || "0") > 0)
- .map(([userId, value]) => ({
- userId,
- amount:
- Math.round(numericAmount * (parseFloat(value) / 100) * 100) / 100,
- type: "percentage",
- }));
- splitType = "percentage";
- } else if (splitMethod === "shares") {
- const nonZeroShares = Object.entries(shares).filter(
- ([userId, value]) => parseInt(value || "0", 10) > 0
- );
- const totalShares = nonZeroShares.reduce(
- (sum, [, value]) => sum + parseInt(value || "0", 10),
- 0
- );
-
- if (totalShares === 0) {
- throw new Error("Total shares cannot be zero.");
- }
-
- // Calculate amounts with proper rounding
- const amounts = nonZeroShares.map(([userId, value]) => {
- const shareRatio = parseInt(value, 10) / totalShares;
- return {
- userId,
- amount: Math.round(numericAmount * shareRatio * 100) / 100,
- type: "unequal",
- };
- });
-
- // Adjust for rounding errors
- const totalCalculated = amounts.reduce(
- (sum, item) => sum + item.amount,
- 0
- );
- const difference =
- Math.round((numericAmount - totalCalculated) * 100) / 100;
-
- if (Math.abs(difference) > 0) {
- amounts[0].amount =
- Math.round((amounts[0].amount + difference) * 100) / 100;
- }
-
- splits = amounts;
- splitType = "unequal"; // Backend uses 'unequal' for shares
- }
-
- expenseData = {
- description,
- amount: numericAmount,
- paidBy: payerId, // Use the selected payer
- splitType,
- splits,
- tags: [],
- };
-
- await createExpense(groupId, expenseData);
- Alert.alert("Success", "Expense added successfully.");
- navigation.goBack();
- } catch (error) {
- Alert.alert("Error", error.message || "Failed to create expense.");
- } finally {
- setIsSubmitting(false);
- }
- };
-
- const handleMemberSelect = (userId) => {
- setSelectedMembers((prev) => ({ ...prev, [userId]: !prev[userId] }));
- };
-
- // Helper function to auto-balance percentages
- const balancePercentages = (updatedPercentages) => {
- const total = Object.values(updatedPercentages).reduce(
- (sum, val) => sum + parseFloat(val || "0"),
- 0
- );
- const memberIds = Object.keys(updatedPercentages);
-
- if (total !== 100 && memberIds.length > 1) {
- // Find the last non-zero percentage to adjust
- const lastMemberId = memberIds[memberIds.length - 1];
- const otherTotal = Object.entries(updatedPercentages)
- .filter(([id]) => id !== lastMemberId)
- .reduce((sum, [, val]) => sum + parseFloat(val || "0"), 0);
-
- const newValue = Math.max(0, 100 - otherTotal);
- updatedPercentages[lastMemberId] = newValue.toFixed(2);
- }
-
- return updatedPercentages;
- };
-
- const renderSplitInputs = () => {
- const handleSplitChange = (setter, userId, value) => {
- if (setter === setPercentages) {
- // Auto-balance percentages when one changes
- const updatedPercentages = { ...percentages, [userId]: value };
- const balanced = balancePercentages(updatedPercentages);
- setter(balanced);
- } else {
- setter((prev) => ({ ...prev, [userId]: value }));
- }
- };
-
- switch (splitMethod) {
- case "equal":
- return members.map((member) => (
- handleMemberSelect(member.userId)}
- />
- ));
- case "exact":
- return members.map((member) => (
-
- handleSplitChange(setExactAmounts, member.userId, text)
- }
- keyboardType="numeric"
- style={styles.splitInput}
- />
- ));
- case "percentage":
- return members.map((member) => (
-
- handleSplitChange(setPercentages, member.userId, text)
- }
- keyboardType="numeric"
- style={styles.splitInput}
- />
- ));
- case "shares":
- return members.map((member) => (
-
- handleSplitChange(setShares, member.userId, text)
- }
- keyboardType="numeric"
- style={styles.splitInput}
- />
- ));
- default:
- return null;
- }
- };
-
- if (isLoading) {
- return (
-
-
-
- );
- }
-
- const selectedPayerName = payerId
- ? members.find((m) => m.userId === payerId)?.user.name || "Select Payer"
- : "Select Payer";
-
- return (
-
-
-
-
-
-
-
- Split Method
-
-
- {splitMethod === "equal" && (
-
- Select members to split the expense equally among them.
-
- )}
- {splitMethod === "exact" && (
-
- Enter exact amounts for each member. Total must equal $
- {amount || "0"}.
- {amount && (
-
- {" "}
- Current total: $
- {Object.values(exactAmounts)
- .reduce((sum, val) => sum + parseFloat(val || "0"), 0)
- .toFixed(2)}
-
- )}
-
- )}
- {splitMethod === "percentage" && (
-
- Enter percentages for each member. Total must equal 100%.
-
- {" "}
- Current total:{" "}
- {Object.values(percentages)
- .reduce((sum, val) => sum + parseFloat(val || "0"), 0)
- .toFixed(2)}
- %
-
-
- )}
- {splitMethod === "shares" && (
-
- Enter shares for each member. Higher shares = larger portion of the
- expense.
-
- )}
-
- {renderSplitInputs()}
-
-
-
-
- );
-};
-
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- },
- content: {
- flex: 1,
- padding: 16,
- paddingBottom: 32,
- },
- loaderContainer: {
- flex: 1,
- justifyContent: "center",
- alignItems: "center",
- },
- input: {
- marginBottom: 16,
- },
- button: {
- marginTop: 24,
- },
- splitTitle: {
- marginTop: 16,
- marginBottom: 8,
- },
- splitInputsContainer: {
- marginTop: 8,
- },
- splitInput: {
- marginBottom: 8,
- },
- helperText: {
- fontSize: 12,
- marginBottom: 8,
- opacity: 0.7,
- },
- totalText: {
- fontWeight: "bold",
- opacity: 1,
- },
-});
-
-export default AddExpenseScreen;
diff --git a/mobile/screens/EditProfileScreen.js b/mobile/screens/EditProfileScreen.js
deleted file mode 100644
index 8201b708..00000000
--- a/mobile/screens/EditProfileScreen.js
+++ /dev/null
@@ -1,153 +0,0 @@
-import * as ImagePicker from "expo-image-picker";
-import { useContext, useState } from "react";
-import { Alert, StyleSheet, View } from "react-native";
-import { Appbar, Avatar, Button, TextInput, Title } from "react-native-paper";
-import { updateUser } from "../api/auth";
-import { AuthContext } from "../context/AuthContext";
-
-const EditProfileScreen = ({ navigation }) => {
- const { user, token, updateUserInContext } = useContext(AuthContext);
- const [name, setName] = useState(user?.name || "");
- const [pickedImage, setPickedImage] = useState(null); // { uri, base64 }
- const [isSubmitting, setIsSubmitting] = useState(false);
-
- const handleUpdateProfile = async () => {
- if (!name) {
- Alert.alert("Error", "Name cannot be empty.");
- return;
- }
- setIsSubmitting(true);
- try {
- const updates = { name };
-
- // Add image if picked
- if (pickedImage?.base64) {
- // Dynamically determine MIME type from picker metadata
- const mime =
- pickedImage.mimeType && /image\//.test(pickedImage.mimeType)
- ? pickedImage.mimeType
- : "image/jpeg"; // fallback
- updates.imageUrl = `data:${mime};base64,${pickedImage.base64}`;
- }
-
- const response = await updateUser(updates);
- updateUserInContext(response.data);
- Alert.alert("Success", "Profile updated successfully.");
- navigation.goBack();
- } catch (error) {
- console.error("Failed to update profile:", error);
- Alert.alert("Error", "Failed to update profile.");
- } finally {
- setIsSubmitting(false);
- }
- };
-
- const pickImage = async () => {
- // Ask permissions
- const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
- if (status !== "granted") {
- Alert.alert(
- "Permission required",
- "We need media library permission to select an image."
- );
- return;
- }
- const result = await ImagePicker.launchImageLibraryAsync({
- mediaTypes: ImagePicker.MediaTypeOptions.Images,
- base64: true,
- allowsEditing: true,
- aspect: [1, 1],
- quality: 0.8,
- });
- if (!result.canceled && result.assets && result.assets.length > 0) {
- const asset = result.assets[0];
- // Capture mimeType (expo-image-picker provides mimeType on iOS/Android SDK 49+)
- let mimeType = asset.mimeType || asset.type; // expo sometimes supplies type like 'image'
- if (mimeType && !/image\//.test(mimeType)) {
- // if it's just 'image', normalize
- if (mimeType === 'image') mimeType = 'image/jpeg';
- }
- if (!mimeType || !/image\//.test(mimeType)) {
- // Attempt to infer from file extension as a lightweight fallback
- const ext = (asset.uri || "").split(".").pop()?.toLowerCase();
- if (ext === "png") mimeType = "image/png";
- else if (ext === "webp") mimeType = "image/webp";
- else if (ext === "gif") mimeType = "image/gif";
- else if (ext === "jpg" || ext === "jpeg") mimeType = "image/jpeg";
- else mimeType = "image/jpeg"; // safe default
- }
- setPickedImage({ uri: asset.uri, base64: asset.base64, mimeType });
- }
- };
-
- return (
-
-
- navigation.goBack()} />
-
-
-
- Edit Your Details
-
- {/* Profile Picture Section */}
-
- {pickedImage?.uri ? (
-
- ) : user?.imageUrl && /^(https?:|data:image)/.test(user.imageUrl) ? (
-
- ) : (
-
- )}
-
-
-
-
-
-
-
- );
-};
-
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- },
- content: {
- padding: 16,
- },
- profilePictureSection: {
- alignItems: "center",
- marginBottom: 24,
- },
- imageButton: {
- marginTop: 12,
- },
- input: {
- marginBottom: 16,
- },
- button: {
- marginTop: 8,
- },
-});
-
-export default EditProfileScreen;
diff --git a/mobile/screens/FriendsScreen.js b/mobile/screens/FriendsScreen.js
deleted file mode 100644
index 0da27955..00000000
--- a/mobile/screens/FriendsScreen.js
+++ /dev/null
@@ -1,306 +0,0 @@
-import { useIsFocused } from "@react-navigation/native";
-import { useContext, useEffect, useRef, useState } from "react";
-import { Alert, Animated, FlatList, StyleSheet, View } from "react-native";
-import {
- Appbar,
- Avatar,
- Divider,
- IconButton,
- List,
- Text,
-} from "react-native-paper";
-import { getFriendsBalance, getGroups } from "../api/groups";
-import { AuthContext } from "../context/AuthContext";
-import { formatCurrency } from "../utils/currency";
-
-const FriendsScreen = () => {
- const { token, user } = useContext(AuthContext);
- const [friends, setFriends] = useState([]);
- const [isLoading, setIsLoading] = useState(true);
- const [showTooltip, setShowTooltip] = useState(true);
- const isFocused = useIsFocused();
-
- useEffect(() => {
- const fetchData = async () => {
- setIsLoading(true);
- try {
- // Fetch friends balance + groups concurrently for group icons
- const friendsResponse = await getFriendsBalance();
- const friendsData = friendsResponse.data.friendsBalance || [];
- const groupsResponse = await getGroups();
- const groups = groupsResponse?.data?.groups || [];
- const groupMeta = new Map(
- groups.map((g) => [g._id, { name: g.name, imageUrl: g.imageUrl }])
- );
-
- const transformedFriends = friendsData.map((friend) => ({
- id: friend.userId,
- name: friend.userName,
- imageUrl: friend.userImageUrl || null,
- netBalance: friend.netBalance,
- groups: (friend.breakdown || []).map((group) => ({
- id: group.groupId,
- name: group.groupName,
- balance: group.balance,
- imageUrl: groupMeta.get(group.groupId)?.imageUrl || null,
- })),
- }));
-
- setFriends(transformedFriends);
- } catch (error) {
- console.error("Failed to fetch friends balance data:", error);
- Alert.alert("Error", "Failed to load friends balance data.");
- } finally {
- setIsLoading(false);
- }
- };
-
- if (token && isFocused) {
- fetchData();
- }
- }, [token, isFocused]);
-
- const renderFriend = ({ item }) => {
- const balanceColor = item.netBalance < 0 ? "red" : "green";
- const balanceText =
- item.netBalance < 0
- ? `You owe ${formatCurrency(Math.abs(item.netBalance))}`
- : `Owes you ${formatCurrency(item.netBalance)}`;
-
- // Determine if we have an image URL or a base64 payload
- const hasImage = !!item.imageUrl;
- let imageUri = null;
- if (hasImage) {
- // If it's a raw base64 string without prefix, add a default MIME prefix
- if (
- /^data:image/.test(item.imageUrl) ||
- /^https?:\/\//.test(item.imageUrl)
- ) {
- imageUri = item.imageUrl;
- } else if (/^[A-Za-z0-9+/=]+$/.test(item.imageUrl.substring(0, 50))) {
- imageUri = `data:image/jpeg;base64,${item.imageUrl}`;
- }
- }
-
- return (
-
- imageUri ? (
-
- ) : (
-
- )
- }
- >
- {item.groups.map((group) => {
- const groupBalanceColor = group.balance < 0 ? "red" : "green";
- const groupBalanceText =
- group.balance < 0
- ? `You owe ${formatCurrency(Math.abs(group.balance))}`
- : `Owes you ${formatCurrency(group.balance)}`;
- // Prepare group icon (imageUrl may be base64 or URL)
- let groupImageUri = null;
- if (group.imageUrl) {
- if (
- /^data:image/.test(group.imageUrl) ||
- /^https?:\/\//.test(group.imageUrl)
- ) {
- groupImageUri = group.imageUrl;
- } else if (
- /^[A-Za-z0-9+/=]+$/.test(group.imageUrl.substring(0, 50))
- ) {
- groupImageUri = `data:image/jpeg;base64,${group.imageUrl}`;
- }
- }
-
- return (
-
- groupImageUri ? (
-
- ) : (
-
- )
- }
- />
- );
- })}
-
- );
- };
-
- // Shimmer skeleton components
- const opacityAnim = useRef(new Animated.Value(0.3)).current;
- useEffect(() => {
- const loop = Animated.loop(
- Animated.sequence([
- Animated.timing(opacityAnim, {
- toValue: 1,
- duration: 700,
- useNativeDriver: true,
- }),
- Animated.timing(opacityAnim, {
- toValue: 0.3,
- duration: 700,
- useNativeDriver: true,
- }),
- ])
- );
- loop.start();
- return () => loop.stop();
- }, [opacityAnim]);
-
- const SkeletonRow = () => (
-
-
-
-
-
-
-
- );
-
- if (isLoading) {
- return (
-
-
-
-
-
- {Array.from({ length: 5 }).map((_, i) => (
-
- ))}
-
-
- );
- }
-
- return (
-
-
-
-
- {showTooltip && (
-
-
-
- 💡 These amounts show your direct balance with each friend across
- all shared groups. Check individual group details for optimized
- settlement suggestions.
-
- setShowTooltip(false)}
- style={styles.closeButton}
- />
-
-
- )}
- item.id}
- ItemSeparatorComponent={Divider}
- ListEmptyComponent={
- No balances with friends yet.
- }
- />
-
- );
-};
-
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- },
- loaderContainer: {
- flex: 1,
- justifyContent: "center",
- alignItems: "center",
- },
- explanationContainer: {
- backgroundColor: "#f0f8ff",
- margin: 8,
- borderRadius: 8,
- borderLeftWidth: 4,
- borderLeftColor: "#2196f3",
- },
- explanationContent: {
- flexDirection: "row",
- alignItems: "flex-start",
- padding: 12,
- },
- explanationText: {
- fontSize: 12,
- color: "#555",
- lineHeight: 16,
- flex: 1,
- paddingRight: 8,
- },
- closeButton: {
- margin: 0,
- marginTop: -4,
- },
- emptyText: {
- textAlign: "center",
- marginTop: 20,
- },
- skeletonContainer: {
- padding: 16,
- },
- skeletonRow: {
- flexDirection: "row",
- alignItems: "center",
- marginBottom: 14,
- },
- skeletonAvatar: {
- width: 48,
- height: 48,
- borderRadius: 24,
- backgroundColor: "#e0e0e0",
- },
- skeletonLine: {
- height: 14,
- backgroundColor: "#e0e0e0",
- borderRadius: 6,
- marginBottom: 6,
- },
- skeletonLineSmall: {
- height: 12,
- backgroundColor: "#e0e0e0",
- borderRadius: 6,
- },
-});
-
-export default FriendsScreen;
diff --git a/mobile/screens/GroupDetailsScreen.js b/mobile/screens/GroupDetailsScreen.js
deleted file mode 100644
index a1050b9f..00000000
--- a/mobile/screens/GroupDetailsScreen.js
+++ /dev/null
@@ -1,315 +0,0 @@
-import { useContext, useEffect, useState } from "react";
-import { Alert, FlatList, StyleSheet, Text, View } from "react-native";
-import {
- ActivityIndicator,
- Card,
- FAB,
- IconButton,
- Paragraph,
- Title,
-} from "react-native-paper";
-import {
- getGroupExpenses,
- getGroupMembers,
- getOptimizedSettlements,
-} from "../api/groups";
-import { AuthContext } from "../context/AuthContext";
-
-const GroupDetailsScreen = ({ route, navigation }) => {
- const { groupId, groupName } = route.params;
- const { token, user } = useContext(AuthContext);
- const [members, setMembers] = useState([]);
- const [expenses, setExpenses] = useState([]);
- const [settlements, setSettlements] = useState([]);
- const [isLoading, setIsLoading] = useState(true);
-
- // Currency configuration - can be made configurable later
- const currency = "₹"; // Default to INR, can be changed to '$' for USD
-
- // Helper function to format currency amounts
- const formatCurrency = (amount) => `${currency}${amount.toFixed(2)}`;
-
- const fetchData = async () => {
- try {
- setIsLoading(true);
- // Fetch members, expenses, and settlements in parallel
- const [membersResponse, expensesResponse, settlementsResponse] =
- await Promise.all([
- getGroupMembers(groupId),
- getGroupExpenses(groupId),
- getOptimizedSettlements(groupId),
- ]);
- setMembers(membersResponse.data);
- setExpenses(expensesResponse.data.expenses);
- setSettlements(settlementsResponse.data.optimizedSettlements || []);
- } catch (error) {
- console.error("Failed to fetch group details:", error);
- Alert.alert("Error", "Failed to fetch group details.");
- } finally {
- setIsLoading(false);
- }
- };
-
- useEffect(() => {
- navigation.setOptions({
- title: groupName,
- headerRight: () => (
- navigation.navigate("GroupSettings", { groupId })}
- />
- ),
- });
- if (token && groupId) {
- fetchData();
- }
- }, [token, groupId]);
-
- const getMemberName = (userId) => {
- const member = members.find((m) => m.userId === userId);
- return member ? member.user.name : "Unknown";
- };
-
- const renderExpense = ({ item }) => {
- const userSplit = item.splits.find((s) => s.userId === user._id);
- const userShare = userSplit ? userSplit.amount : 0;
- const paidByMe = (item.paidBy || item.createdBy) === user._id;
- const net = paidByMe ? item.amount - userShare : -userShare;
-
- let balanceText;
- let balanceColor = "black";
-
- if (net > 0) {
- balanceText = `You are owed ${formatCurrency(net)}`;
- balanceColor = "green";
- } else if (net < 0) {
- balanceText = `You borrowed ${formatCurrency(Math.abs(net))}`;
- balanceColor = "red";
- } else {
- balanceText = "You are settled for this expense.";
- }
-
- return (
-
-
- {item.description}
- Amount: {formatCurrency(item.amount)}
-
- Paid by: {getMemberName(item.paidBy || item.createdBy)}
-
- {balanceText}
-
-
- );
- };
-
- const renderSettlementSummary = () => {
- const userOwes = settlements.filter((s) => s.fromUserId === user._id);
- const userIsOwed = settlements.filter((s) => s.toUserId === user._id);
- const totalOwed = userOwes.reduce((sum, s) => sum + s.amount, 0);
- const totalToReceive = userIsOwed.reduce((sum, s) => sum + s.amount, 0);
-
- // If user is all settled up
- if (userOwes.length === 0 && userIsOwed.length === 0) {
- return (
-
- ✓ You are all settled up!
-
- );
- }
-
- return (
-
- {/* You owe section - only show if totalOwed > 0 */}
- {totalOwed > 0 && (
-
-
- You need to pay:{" "}
- {formatCurrency(totalOwed)}
-
- {userOwes.map((s, index) => (
-
-
-
- {getMemberName(s.toUserId)}
-
-
- {formatCurrency(s.amount)}
-
-
-
- ))}
-
- )}
-
- {/* You receive section - only show if totalToReceive > 0 */}
- {totalToReceive > 0 && (
-
-
- You will receive:{" "}
-
- {formatCurrency(totalToReceive)}
-
-
- {userIsOwed.map((s, index) => (
-
-
-
- {getMemberName(s.fromUserId)}
-
-
- {formatCurrency(s.amount)}
-
-
-
- ))}
-
- )}
-
- );
- };
-
- if (isLoading) {
- return (
-
-
-
- );
- }
-
- const renderHeader = () => (
- <>
-
-
- Settlement Summary
- {renderSettlementSummary()}
-
-
-
- Expenses
- >
- );
-
- return (
-
- item._id}
- ListHeaderComponent={renderHeader}
- ListEmptyComponent={
- No expenses recorded yet.
- }
- contentContainerStyle={{ paddingBottom: 80 }} // To avoid FAB overlap
- />
-
- navigation.navigate("AddExpense", { groupId: groupId })}
- />
-
- );
-};
-
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- },
- contentContainer: {
- flex: 1,
- padding: 16,
- },
- loaderContainer: {
- flex: 1,
- justifyContent: "center",
- alignItems: "center",
- },
- card: {
- marginBottom: 16,
- },
- expensesTitle: {
- marginTop: 16,
- marginBottom: 8,
- fontSize: 20,
- fontWeight: "bold",
- },
- memberText: {
- fontSize: 16,
- lineHeight: 24,
- },
- fab: {
- position: "absolute",
- margin: 16,
- right: 0,
- bottom: 0,
- },
- // Settlement Summary Styles
- settlementContainer: {
- marginBottom: 16,
- },
- settledContainer: {
- alignItems: "center",
- paddingVertical: 12,
- },
- settledText: {
- fontSize: 16,
- color: "#2e7d32",
- fontWeight: "500",
- },
- owedSection: {
- backgroundColor: "#ffebee",
- borderRadius: 8,
- padding: 12,
- borderLeftWidth: 4,
- borderLeftColor: "#d32f2f",
- },
- receiveSection: {
- backgroundColor: "#e8f5e8",
- borderRadius: 8,
- padding: 12,
- borderLeftWidth: 4,
- borderLeftColor: "#2e7d32",
- },
- sectionTitle: {
- fontSize: 16,
- fontWeight: "600",
- marginBottom: 8,
- color: "#333",
- },
- amountOwed: {
- color: "#d32f2f",
- fontWeight: "bold",
- },
- amountReceive: {
- color: "#2e7d32",
- fontWeight: "bold",
- },
- settlementItem: {
- marginVertical: 4,
- },
- personInfo: {
- flexDirection: "row",
- justifyContent: "space-between",
- alignItems: "center",
- paddingVertical: 4,
- },
- personName: {
- fontSize: 14,
- color: "#555",
- flex: 1,
- },
- settlementAmount: {
- fontSize: 14,
- fontWeight: "600",
- color: "#333",
- },
- emptyText: {
- fontSize: 14,
- color: "#666",
- paddingVertical: 8,
- },
-});
-
-export default GroupDetailsScreen;
diff --git a/mobile/screens/GroupSettingsScreen.js b/mobile/screens/GroupSettingsScreen.js
deleted file mode 100644
index 90de5d16..00000000
--- a/mobile/screens/GroupSettingsScreen.js
+++ /dev/null
@@ -1,426 +0,0 @@
-import * as ImagePicker from "expo-image-picker";
-import {
- useContext,
- useEffect,
- useLayoutEffect,
- useMemo,
- useState,
-} from "react";
-import {
- Alert,
- Image,
- ScrollView,
- Share,
- StyleSheet,
- View,
-} from "react-native";
-import {
- ActivityIndicator,
- Avatar,
- Button,
- Card,
- IconButton,
- List,
- Text,
- TextInput,
-} from "react-native-paper";
-import {
- deleteGroup as apiDeleteGroup,
- leaveGroup as apiLeaveGroup,
- removeMember as apiRemoveMember,
- updateGroup as apiUpdateGroup,
- getGroupById,
- getGroupMembers,
- getOptimizedSettlements,
-} from "../api/groups";
-import { AuthContext } from "../context/AuthContext";
-
-const ICON_CHOICES = ["👥", "🏠", "🎉", "🧳", "🍽️", "🚗", "🏖️", "🎮", "💼"];
-
-const GroupSettingsScreen = ({ route, navigation }) => {
- const { groupId } = route.params;
- const { token, user } = useContext(AuthContext);
- const [loading, setLoading] = useState(true);
- const [saving, setSaving] = useState(false);
- const [members, setMembers] = useState([]);
- const [group, setGroup] = useState(null);
- const [name, setName] = useState("");
- const [icon, setIcon] = useState("");
- const [pickedImage, setPickedImage] = useState(null); // { uri, base64 }
-
- const isAdmin = useMemo(() => {
- const me = members.find((m) => m.userId === user?._id);
- return me?.role === "admin";
- }, [members, user?._id]);
-
- const load = async () => {
- try {
- setLoading(true);
- const [gRes, mRes] = await Promise.all([
- getGroupById(groupId),
- getGroupMembers(groupId),
- ]);
- setGroup(gRes.data);
- setName(gRes.data.name);
- setIcon(gRes.data.imageUrl || gRes.data.icon || "");
- setMembers(mRes.data);
- } catch (e) {
- console.error("Failed to load group settings", e);
- Alert.alert("Error", "Failed to load group settings.");
- } finally {
- setLoading(false);
- }
- };
-
- useEffect(() => {
- if (token && groupId) load();
- }, [token, groupId]);
-
- useLayoutEffect(() => {
- navigation.setOptions({ title: "Group Settings" });
- }, [navigation]);
-
- const onSave = async () => {
- if (!isAdmin) return;
- const updates = {};
- if (name && name !== group?.name) updates.name = name;
-
- // Handle different icon types
- if (pickedImage?.base64) {
- // If user picked an image, use it as imageUrl
- updates.imageUrl = `data:image/jpeg;base64,${pickedImage.base64}`;
- } else if (icon && icon !== (group?.imageUrl || group?.icon || "")) {
- // If user selected an emoji and it's different from current
- // Check if it's an emoji (not a URL)
- const isEmoji = ICON_CHOICES.includes(icon);
- if (isEmoji) {
- updates.imageUrl = icon; // Store emoji as imageUrl for now
- } else {
- updates.imageUrl = icon; // Store other text/URL as imageUrl
- }
- }
-
- if (Object.keys(updates).length === 0)
- return Alert.alert("Nothing to update");
- try {
- setSaving(true);
- const res = await apiUpdateGroup(groupId, updates);
- setGroup(res.data);
- if (pickedImage) setPickedImage(null);
- Alert.alert("Updated", "Group updated successfully.");
- } catch (e) {
- console.error("Update failed", e);
- Alert.alert(
- "Error",
- e.response?.data?.detail || "Failed to update group"
- );
- } finally {
- setSaving(false);
- }
- };
-
- const pickImage = async () => {
- if (!isAdmin) return;
- // Ask permissions
- const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
- if (status !== "granted") {
- Alert.alert(
- "Permission required",
- "We need media library permission to select an image."
- );
- return;
- }
- const result = await ImagePicker.launchImageLibraryAsync({
- mediaTypes: ImagePicker.MediaTypeOptions.Images,
- base64: true,
- allowsEditing: true,
- aspect: [1, 1],
- quality: 0.8,
- });
- if (!result.canceled && result.assets && result.assets.length > 0) {
- const asset = result.assets[0];
- setPickedImage({ uri: asset.uri, base64: asset.base64 });
- }
- };
-
- const onShareInvite = async () => {
- try {
- const code = group?.joinCode;
- if (!code) return;
- await Share.share({
- message: `Join my group on Splitwiser! Use code ${code}`,
- });
- } catch (e) {
- console.error("Share failed", e);
- }
- };
-
- const onKick = (memberId, name) => {
- if (!isAdmin) return;
- if (memberId === user?._id) return; // safeguard
- Alert.alert("Remove member", `Are you sure you want to remove ${name}?`, [
- { text: "Cancel", style: "cancel" },
- {
- text: "Remove",
- style: "destructive",
- onPress: async () => {
- try {
- // Pre-check balances using optimized settlements
- const settlementsRes = await getOptimizedSettlements(groupId);
- const settlements =
- settlementsRes?.data?.optimizedSettlements || [];
- const hasUnsettled = settlements.some(
- (s) =>
- (s.fromUserId === memberId || s.toUserId === memberId) &&
- (s.amount || 0) > 0
- );
- if (hasUnsettled) {
- Alert.alert(
- "Cannot remove",
- "This member has unsettled balances in the group."
- );
- return;
- }
- await apiRemoveMember(groupId, memberId);
- await load();
- } catch (e) {
- console.error("Remove failed", e);
- Alert.alert(
- "Error",
- e.response?.data?.detail || "Failed to remove member"
- );
- }
- },
- },
- ]);
- };
-
- const onLeave = () => {
- Alert.alert(
- "Leave group",
- "You can leave only when your balances are settled. Continue?",
- [
- { text: "Cancel", style: "cancel" },
- {
- text: "Leave",
- style: "destructive",
- onPress: async () => {
- try {
- await apiLeaveGroup(groupId);
- Alert.alert("Left group");
- navigation.popToTop();
- } catch (e) {
- console.error("Leave failed", e);
- Alert.alert(
- "Cannot leave",
- e.response?.data?.detail || "Please settle balances first"
- );
- }
- },
- },
- ]
- );
- };
-
- const onDeleteGroup = () => {
- if (!isAdmin) return;
- // Only allow delete if no other members present
- const others = members.filter((m) => m.userId !== user?._id);
- if (others.length > 0) {
- Alert.alert(
- "Cannot delete",
- "Remove all members first, or transfer admin."
- );
- return;
- }
- Alert.alert(
- "Delete group",
- "This will permanently delete the group. Continue?",
- [
- { text: "Cancel", style: "cancel" },
- {
- text: "Delete",
- style: "destructive",
- onPress: async () => {
- try {
- await apiDeleteGroup(groupId);
- Alert.alert("Group deleted");
- navigation.popToTop();
- } catch (e) {
- console.error("Delete failed", e);
- Alert.alert(
- "Error",
- e.response?.data?.detail || "Failed to delete group"
- );
- }
- },
- },
- ]
- );
- };
-
- const renderMemberItem = (m) => {
- const isSelf = m.userId === user?._id;
- const displayName = m.user?.name || "Unknown";
- const imageUrl = m.user?.imageUrl;
- return (
-
- imageUrl ? (
-
- ) : (
-
- )
- }
- right={() =>
- isAdmin && !isSelf ? (
- onKick(m.userId, displayName)}
- />
- ) : null
- }
- />
- );
- };
-
- if (loading) {
- return (
-
-
-
- );
- }
-
- return (
-
-
-
-
-
-
- Icon
-
- {ICON_CHOICES.map((i) => (
-
- ))}
-
-
-
- {pickedImage?.uri ? (
-
- ) : group?.imageUrl &&
- /^(https?:|data:image)/.test(group.imageUrl) ? (
-
- ) : group?.imageUrl ? (
- {group.imageUrl}
- ) : null}
-
- {isAdmin && (
-
- )}
-
-
-
-
-
- {members.map(renderMemberItem)}
-
-
-
-
-
-
- Join Code: {group?.joinCode}
-
-
-
-
-
-
-
-
-
-
- {isAdmin && (
-
- )}
-
-
-
-
-
- );
-};
-
-const styles = StyleSheet.create({
- container: { flex: 1 },
- scrollContent: { padding: 16 },
- loaderContainer: { flex: 1, justifyContent: "center", alignItems: "center" },
- card: { marginBottom: 16 },
- iconRow: { flexDirection: "row", flexWrap: "wrap", marginBottom: 8 },
- iconBtn: { marginRight: 8, marginBottom: 8 },
-});
-
-export default GroupSettingsScreen;
diff --git a/mobile/screens/HomeScreen.js b/mobile/screens/HomeScreen.js
deleted file mode 100644
index dfb0eadd..00000000
--- a/mobile/screens/HomeScreen.js
+++ /dev/null
@@ -1,296 +0,0 @@
-import { useContext, useEffect, useState } from "react";
-import { Alert, FlatList, StyleSheet, View } from "react-native";
-import {
- ActivityIndicator,
- Appbar,
- Avatar,
- Button,
- Card,
- Modal,
- Portal,
- Text,
- TextInput,
-} from "react-native-paper";
-import { createGroup, getGroups, getOptimizedSettlements } from "../api/groups";
-import { AuthContext } from "../context/AuthContext";
-import { formatCurrency, getCurrencySymbol } from "../utils/currency";
-
-const HomeScreen = ({ navigation }) => {
- const { token, logout, user } = useContext(AuthContext);
- const [groups, setGroups] = useState([]);
- const [isLoading, setIsLoading] = useState(true);
- const [groupSettlements, setGroupSettlements] = useState({}); // Track settlement status for each group
-
- // State for the Create Group modal
- const [modalVisible, setModalVisible] = useState(false);
- const [newGroupName, setNewGroupName] = useState("");
- const [isCreatingGroup, setIsCreatingGroup] = useState(false);
-
- const showModal = () => setModalVisible(true);
- const hideModal = () => setModalVisible(false);
-
- // Calculate settlement status for a group
- const calculateSettlementStatus = async (groupId, userId) => {
- try {
- const response = await getOptimizedSettlements(groupId);
- const settlements = response.data.optimizedSettlements || [];
-
- // Check if user has any pending settlements
- const userOwes = settlements.filter((s) => s.fromUserId === userId);
- const userIsOwed = settlements.filter((s) => s.toUserId === userId);
-
- const totalOwed = userOwes.reduce((sum, s) => sum + (s.amount || 0), 0);
- const totalToReceive = userIsOwed.reduce(
- (sum, s) => sum + (s.amount || 0),
- 0
- );
-
- return {
- isSettled: totalOwed === 0 && totalToReceive === 0,
- owesAmount: totalOwed,
- owedAmount: totalToReceive,
- netBalance: totalToReceive - totalOwed,
- };
- } catch (error) {
- console.error(
- "Failed to fetch settlement status for group:",
- groupId,
- error
- );
- return {
- isSettled: true,
- owesAmount: 0,
- owedAmount: 0,
- netBalance: 0,
- };
- }
- };
-
- const fetchGroups = async () => {
- try {
- setIsLoading(true);
- const response = await getGroups();
- const groupsList = response.data.groups;
- setGroups(groupsList);
-
- // Fetch settlement status for each group
- if (user?._id) {
- const settlementPromises = groupsList.map(async (group) => {
- const status = await calculateSettlementStatus(group._id, user._id);
- return { groupId: group._id, status };
- });
-
- const settlementResults = await Promise.all(settlementPromises);
- const settlementMap = {};
- settlementResults.forEach(({ groupId, status }) => {
- settlementMap[groupId] = status;
- });
- setGroupSettlements(settlementMap);
- }
- } catch (error) {
- console.error("Failed to fetch groups:", error);
- Alert.alert("Error", "Failed to fetch groups.");
- } finally {
- setIsLoading(false);
- }
- };
-
- useEffect(() => {
- if (token) {
- fetchGroups();
- }
- }, [token]);
-
- const handleCreateGroup = async () => {
- if (!newGroupName) {
- Alert.alert("Error", "Please enter a group name.");
- return;
- }
- setIsCreatingGroup(true);
- try {
- await createGroup(newGroupName);
- hideModal();
- setNewGroupName("");
- await fetchGroups(); // Refresh the groups list
- } catch (error) {
- console.error("Failed to create group:", error);
- Alert.alert("Error", "Failed to create group.");
- } finally {
- setIsCreatingGroup(false);
- }
- };
-
- const currencySymbol = getCurrencySymbol();
-
- const renderGroup = ({ item }) => {
- const settlementStatus = groupSettlements[item._id];
-
- // Generate settlement status text
- const getSettlementStatusText = () => {
- if (!settlementStatus) {
- return "Calculating balances...";
- }
-
- if (settlementStatus.isSettled) {
- return "✓ You are settled up.";
- }
-
- if (settlementStatus.netBalance > 0) {
- return `You are owed ${formatCurrency(settlementStatus.netBalance)}.`;
- } else if (settlementStatus.netBalance < 0) {
- return `You owe ${formatCurrency(
- Math.abs(settlementStatus.netBalance)
- )}.`;
- }
-
- return "You are settled up.";
- };
-
- // Get text color based on settlement status
- const getStatusColor = () => {
- if (!settlementStatus || settlementStatus.isSettled) {
- return "#4CAF50"; // Green for settled
- }
-
- if (settlementStatus.netBalance > 0) {
- return "#4CAF50"; // Green for being owed money
- } else if (settlementStatus.netBalance < 0) {
- return "#F44336"; // Red for owing money
- }
-
- return "#4CAF50"; // Default green
- };
-
- const isImage =
- item.imageUrl && /^(https?:|data:image)/.test(item.imageUrl);
- const groupIcon = item.imageUrl || item.name?.charAt(0) || "?";
- return (
-
- navigation.navigate("GroupDetails", {
- groupId: item._id,
- groupName: item.name,
- groupIcon,
- })
- }
- >
-
- isImage ? (
-
- ) : (
-
- )
- }
- />
-
-
- {getSettlementStatusText()}
-
-
-
- );
- };
-
- return (
-
-
-
- Create a New Group
-
-
-
-
-
-
-
-
-
- navigation.navigate("JoinGroup", { onGroupJoined: fetchGroups })
- }
- />
-
-
- {isLoading ? (
-
-
-
- ) : (
- item._id}
- contentContainerStyle={styles.list}
- ListEmptyComponent={
-
- No groups found. Create or join one!
-
- }
- onRefresh={fetchGroups}
- refreshing={isLoading}
- />
- )}
-
- );
-};
-
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- },
- loaderContainer: {
- flex: 1,
- justifyContent: "center",
- alignItems: "center",
- },
- list: {
- padding: 16,
- },
- card: {
- marginBottom: 16,
- },
- settlementStatus: {
- fontWeight: "500",
- marginTop: 4,
- },
- emptyText: {
- textAlign: "center",
- marginTop: 20,
- },
- modalContainer: {
- backgroundColor: "white",
- padding: 20,
- margin: 20,
- borderRadius: 8,
- },
- modalTitle: {
- fontSize: 20,
- marginBottom: 20,
- textAlign: "center",
- },
- input: {
- marginBottom: 20,
- },
-});
-
-export default HomeScreen;
diff --git a/mobile/screens/JoinGroupScreen.js b/mobile/screens/JoinGroupScreen.js
deleted file mode 100644
index 153e4eac..00000000
--- a/mobile/screens/JoinGroupScreen.js
+++ /dev/null
@@ -1,79 +0,0 @@
-import { useContext, useState } from "react";
-import { Alert, StyleSheet, View } from "react-native";
-import { Appbar, Button, TextInput, Title } from "react-native-paper";
-import { joinGroup } from "../api/groups";
-import { AuthContext } from "../context/AuthContext";
-
-const JoinGroupScreen = ({ navigation, route }) => {
- const { token } = useContext(AuthContext);
- const [joinCode, setJoinCode] = useState("");
- const [isJoining, setIsJoining] = useState(false);
- const { onGroupJoined } = route.params;
-
- const handleJoinGroup = async () => {
- if (!joinCode) {
- Alert.alert("Error", "Please enter a join code.");
- return;
- }
- setIsJoining(true);
- try {
- await joinGroup(joinCode);
- Alert.alert("Success", "Successfully joined the group.");
- onGroupJoined(); // Call the callback to refresh the groups list
- navigation.goBack();
- } catch (error) {
- console.error("Failed to join group:", error);
- Alert.alert(
- "Error",
- "Failed to join group. Please check the code and try again."
- );
- } finally {
- setIsJoining(false);
- }
- };
-
- return (
-
-
- navigation.goBack()} />
-
-
-
- Enter Group Code
-
-
-
-
- );
-};
-
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- },
- content: {
- padding: 16,
- },
- input: {
- marginBottom: 16,
- },
- button: {
- marginTop: 8,
- },
-});
-
-export default JoinGroupScreen;
diff --git a/mobile/screens/LoginScreen.js b/mobile/screens/LoginScreen.js
deleted file mode 100644
index 076e9956..00000000
--- a/mobile/screens/LoginScreen.js
+++ /dev/null
@@ -1,77 +0,0 @@
-import React, { useState, useContext } from 'react';
-import { View, StyleSheet, Alert } from 'react-native';
-import { Button, Text, TextInput } from 'react-native-paper';
-import { AuthContext } from '../context/AuthContext';
-
-const LoginScreen = ({ navigation }) => {
- const [email, setEmail] = useState('');
- const [password, setPassword] = useState('');
- const [isLoading, setIsLoading] = useState(false);
- const { login } = useContext(AuthContext);
-
- const handleLogin = async () => {
- if (!email || !password) {
- Alert.alert('Error', 'Please enter both email and password.');
- return;
- }
- setIsLoading(true);
- const success = await login(email, password);
- setIsLoading(false);
- if (!success) {
- Alert.alert('Login Failed', 'Invalid email or password. Please try again.');
- }
- };
-
- return (
-
- Welcome Back!
-
-
-
-
-
- );
-};
-
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- justifyContent: 'center',
- padding: 16,
- },
- title: {
- textAlign: 'center',
- marginBottom: 24,
- },
- input: {
- marginBottom: 16,
- },
- button: {
- marginTop: 8,
- },
-});
-
-export default LoginScreen;
diff --git a/mobile/screens/SignupScreen.js b/mobile/screens/SignupScreen.js
deleted file mode 100644
index 5594be60..00000000
--- a/mobile/screens/SignupScreen.js
+++ /dev/null
@@ -1,103 +0,0 @@
-import React, { useState, useContext } from 'react';
-import { View, StyleSheet, Alert } from 'react-native';
-import { Button, Text, TextInput } from 'react-native-paper';
-import { AuthContext } from '../context/AuthContext';
-
-const SignupScreen = ({ navigation }) => {
- const [name, setName] = useState('');
- const [email, setEmail] = useState('');
- const [password, setPassword] = useState('');
- const [confirmPassword, setConfirmPassword] = useState('');
- const [isLoading, setIsLoading] = useState(false);
- const { signup } = useContext(AuthContext);
-
- const handleSignup = async () => {
- if (!name || !email || !password || !confirmPassword) {
- Alert.alert('Error', 'Please fill in all fields.');
- return;
- }
- if (password !== confirmPassword) {
- Alert.alert('Error', "Passwords don't match!");
- return;
- }
- setIsLoading(true);
- const success = await signup(name, email, password);
- setIsLoading(false);
- if (success) {
- Alert.alert(
- 'Success',
- 'Your account has been created successfully. Please log in.',
- [{ text: 'OK', onPress: () => navigation.navigate('Login') }]
- );
- } else {
- Alert.alert('Signup Failed', 'An error occurred. Please try again.');
- }
- };
-
- return (
-
- Create Account
-
-
-
-
-
-
-
- );
-};
-
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- justifyContent: 'center',
- padding: 16,
- },
- title: {
- textAlign: 'center',
- marginBottom: 24,
- },
- input: {
- marginBottom: 16,
- },
- button: {
- marginTop: 8,
- },
-});
-
-export default SignupScreen;
diff --git a/mobile/tailwind.config.js b/mobile/tailwind.config.js
new file mode 100644
index 00000000..f0a21cab
--- /dev/null
+++ b/mobile/tailwind.config.js
@@ -0,0 +1,32 @@
+/** @type {import('tailwindcss').Config} */
+module.exports = {
+ // NOTE: Update this to include the paths to all of your component files.
+ content: ["./app/**/*.{js,jsx,ts,tsx}", "./components/**/*.{js,jsx,ts,tsx}"],
+ presets: [require("nativewind/preset")],
+ theme: {
+ extend: {
+ fontFamily: {
+ sans: ['Inter_400Regular', 'sans-serif'],
+ mono: ['SpaceGrotesk_400Regular', 'monospace'],
+ 'sans-bold': ['Inter_700Bold', 'sans-serif'],
+ 'mono-bold': ['SpaceGrotesk_700Bold', 'monospace'],
+ },
+ colors: {
+ neo: {
+ main: '#8855ff',
+ second: '#ff9900',
+ accent: '#00cc88',
+ bg: '#f0f0f0',
+ dark: '#1a1a1a',
+ white: '#ffffff',
+ }
+ },
+ boxShadow: {
+ 'neo': '4px 4px 0px 0px #1a1a1a',
+ 'neo-sm': '2px 2px 0px 0px #1a1a1a',
+ 'neo-lg': '6px 6px 0px 0px #1a1a1a',
+ }
+ },
+ },
+ plugins: [],
+}
diff --git a/mobile/tsconfig.json b/mobile/tsconfig.json
new file mode 100644
index 00000000..ec6aeb73
--- /dev/null
+++ b/mobile/tsconfig.json
@@ -0,0 +1,19 @@
+{
+ "extends": "expo/tsconfig.base",
+ "compilerOptions": {
+ "strict": true,
+ "baseUrl": ".",
+ "paths": {
+ "@/*": [
+ "./*"
+ ]
+ }
+ },
+ "include": [
+ "**/*.ts",
+ "**/*.tsx",
+ ".expo/types/**/*.ts",
+ "expo-env.d.ts",
+ "nativewind-env.d.ts"
+ ]
+}
diff --git a/mobile/utils/balanceCalculator.js b/mobile/utils/balanceCalculator.js
deleted file mode 100644
index 3093dd8b..00000000
--- a/mobile/utils/balanceCalculator.js
+++ /dev/null
@@ -1,205 +0,0 @@
-/**
- * Utility functions for calculating friend balances across groups
- * Includes comprehensive null safety checks to prevent runtime errors
- *
- * Note: Uses 'paidBy' field to determine who actually paid for an expense,
- * with fallback to 'createdBy' for backward compatibility.
- */
-
-/**
- * Safely gets a value from an object with null/undefined protection
- * @param {Object} obj - The object to get value from
- * @param {string} path - Dot notation path (e.g., 'user.name')
- * @param {*} defaultValue - Default value if path doesn't exist
- * @returns {*} The value at the path or defaultValue
- */
-const safeGet = (obj, path, defaultValue = null) => {
- if (!obj || typeof obj !== 'object') return defaultValue;
-
- const keys = path.split('.');
- let current = obj;
-
- for (const key of keys) {
- if (current == null || typeof current !== 'object' || !(key in current)) {
- return defaultValue;
- }
- current = current[key];
- }
-
- return current !== null && current !== undefined ? current : defaultValue;
-};
-
-/**
- * Safely validates and extracts group details
- * @param {Object} group - Group object with details
- * @returns {Object|null} Validated group data or null if invalid
- */
-const validateGroupData = (group) => {
- if (!group || typeof group !== 'object') return null;
-
- const details = safeGet(group, 'details');
- if (!Array.isArray(details) || details.length < 2) return null;
-
- const [membersResponse, expensesResponse] = details;
-
- // Validate members response
- const members = safeGet(membersResponse, 'data');
- if (!Array.isArray(members)) return null;
-
- // Validate expenses response
- const expenses = safeGet(expensesResponse, 'data.expenses');
- if (!Array.isArray(expenses)) return null;
-
- return {
- id: safeGet(group, 'id') || safeGet(group, '_id'),
- name: safeGet(group, 'name', 'Unknown Group'),
- members,
- expenses
- };
-};
-
-/**
- * Safely finds a member by userId
- * @param {Array} members - Array of member objects
- * @param {string} userId - User ID to find
- * @returns {string} Member name or 'Unknown'
- */
-const getMemberName = (members, userId) => {
- if (!Array.isArray(members) || !userId) return 'Unknown';
-
- const member = members.find(m => safeGet(m, 'userId') === userId);
- return safeGet(member, 'user.name', 'Unknown');
-};
-
-/**
- * Processes a single expense and updates balances
- * @param {Object} expense - Expense object
- * @param {Object} balances - Current balances object
- * @param {Array} members - Group members
- * @param {Object} group - Group information
- * @param {string} currentUserId - Current user's ID
- */
-const processExpense = (expense, balances, members, group, currentUserId) => {
- if (!expense || typeof expense !== 'object' || !currentUserId) return;
-
- const payerId = safeGet(expense, 'paidBy') || safeGet(expense, 'createdBy');
- const splits = safeGet(expense, 'splits');
-
- if (!payerId || !Array.isArray(splits)) return;
-
- const payerIsMe = payerId === currentUserId;
-
- splits.forEach(split => {
- if (!split || typeof split !== 'object') return;
-
- const memberId = safeGet(split, 'userId');
- const splitAmount = parseFloat(safeGet(split, 'amount', 0));
-
- if (!memberId || isNaN(splitAmount) || splitAmount <= 0) return;
- if (memberId === payerId) return; // Payer doesn't owe themselves
-
- const memberIsMe = memberId === currentUserId;
-
- // Initialize balance structure if needed
- const initializeBalance = (userId) => {
- if (!balances[userId]) {
- balances[userId] = {
- name: getMemberName(members, userId),
- netBalance: 0,
- groups: {}
- };
- }
- if (!balances[userId].groups[group.id]) {
- balances[userId].groups[group.id] = {
- name: group.name,
- balance: 0
- };
- }
- };
-
- if (payerIsMe && !memberIsMe) {
- // I paid, they owe me
- initializeBalance(memberId);
- balances[memberId].netBalance += splitAmount;
- balances[memberId].groups[group.id].balance += splitAmount;
- } else if (!payerIsMe && memberIsMe) {
- // They paid, I owe them
- initializeBalance(payerId);
- balances[payerId].netBalance -= splitAmount;
- balances[payerId].groups[group.id].balance -= splitAmount;
- }
- });
-};
-
-/**
- * Formats balance data for UI consumption
- * @param {Object} balances - Raw balances object
- * @returns {Array} Formatted friends array for UI
- */
-const formatBalancesForUI = (balances) => {
- if (!balances || typeof balances !== 'object') return [];
-
- return Object.entries(balances).map(([id, data]) => {
- if (!data || typeof data !== 'object') return null;
-
- const groups = safeGet(data, 'groups', {});
- const formattedGroups = Object.entries(groups).map(([groupId, groupData]) => ({
- id: groupId,
- name: safeGet(groupData, 'name', 'Unknown Group'),
- balance: parseFloat(safeGet(groupData, 'balance', 0))
- })).filter(group => group.id && !isNaN(group.balance));
-
- return {
- id,
- name: safeGet(data, 'name', 'Unknown'),
- netBalance: parseFloat(safeGet(data, 'netBalance', 0)),
- groups: formattedGroups
- };
- }).filter(friend => friend !== null && friend.id);
-};
-
-/**
- * Main function to calculate friend balances from groups with details
- * @param {Array} groupsWithDetails - Array of groups with their details
- * @param {string} currentUserId - Current user's ID
- * @returns {Array} Formatted array of friends with balance information
- */
-export const calculateFriendBalances = (groupsWithDetails, currentUserId) => {
- if (!Array.isArray(groupsWithDetails) || !currentUserId) {
- console.warn('Invalid input to calculateFriendBalances:', { groupsWithDetails, currentUserId });
- return [];
- }
-
- const balances = {};
-
- groupsWithDetails.forEach(group => {
- try {
- const validatedGroup = validateGroupData(group);
- if (!validatedGroup) {
- console.warn('Invalid group data, skipping:', group);
- return;
- }
-
- const { members, expenses } = validatedGroup;
-
- expenses.forEach(expense => {
- try {
- processExpense(expense, balances, members, validatedGroup, currentUserId);
- } catch (error) {
- console.error('Error processing expense:', error, expense);
- }
- });
- } catch (error) {
- console.error('Error processing group:', error, group);
- }
- });
-
- return formatBalancesForUI(balances);
-};
-
-export default {
- calculateFriendBalances,
- safeGet,
- validateGroupData,
- getMemberName
-};
diff --git a/mobile/utils/currency.js b/mobile/utils/currency.js
deleted file mode 100644
index 436059f9..00000000
--- a/mobile/utils/currency.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// Centralized currency formatting utility
-// Future enhancement: make currency code/user preference dynamic (user.profile.currency)
-
-const DEFAULT_CURRENCY_SYMBOL = "₹"; // INR default
-
-export const getCurrencySymbol = () => DEFAULT_CURRENCY_SYMBOL;
-
-export const formatCurrency = (amount) => {
- if (amount == null || isNaN(Number(amount)))
- return `${DEFAULT_CURRENCY_SYMBOL}0.00`;
- const num = Number(amount);
- if (!Number.isFinite(num)) {
- return `${DEFAULT_CURRENCY_SYMBOL}0.00`;
- }
- return `${DEFAULT_CURRENCY_SYMBOL}${num.toFixed(2)}`;
-};
-
-export default {
- getCurrencySymbol,
- formatCurrency,
-};