From 607f521c1ca43669a3ac267998e179d519ceec7f Mon Sep 17 00:00:00 2001
From: JosephShortt <josephshortt1@gmail.com>
Date: Tue, 13 May 2025 19:23:42 +0200
Subject: [PATCH] Working todo app
---
app.json | 4 +-
app/(tabs)/_layout.tsx | 52 +--
app/(tabs)/index.tsx | 330 +++++++++++---
firebaseConfig.js | 20 +
package-lock.json | 958 ++++++++++++++++++++++++++++++++++++++++-
package.json | 15 +-
6 files changed, 1270 insertions(+), 109 deletions(-)
create mode 100644 firebaseConfig.js
diff --git a/app.json b/app.json
index 3868970..a6a4599 100644
--- a/app.json
+++ b/app.json
@@ -9,7 +9,8 @@
"userInterfaceStyle": "automatic",
"newArchEnabled": true,
"ios": {
- "supportsTablet": true
+ "supportsTablet": true,
+ "bundleIdentifier": "com.anonymous.TodoListApp"
},
"android": {
"adaptiveIcon": {
@@ -25,6 +26,7 @@
},
"plugins": [
"expo-router",
+ "expo-dev-client",
[
"expo-splash-screen",
{
diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx
index cfbc1e2..655e77d 100644
--- a/app/(tabs)/_layout.tsx
+++ b/app/(tabs)/_layout.tsx
@@ -1,45 +1,27 @@
+// app/(tabs)/_layout.tsx
import { Tabs } from 'expo-router';
-import React from 'react';
-import { Platform } from 'react-native';
-
-import { HapticTab } from '@/components/HapticTab';
-import { IconSymbol } from '@/components/ui/IconSymbol';
-import TabBarBackground from '@/components/ui/TabBarBackground';
-import { Colors } from '@/constants/Colors';
-import { useColorScheme } from '@/hooks/useColorScheme';
-
-export default function TabLayout() {
- const colorScheme = useColorScheme();
+import { MaterialIcons } from '@expo/vector-icons';
+export default function TabsLayout() {
return (
- <Tabs
- screenOptions={{
- tabBarActiveTintColor: Colors[colorScheme ?? 'light'].tint,
- headerShown: false,
- tabBarButton: HapticTab,
- tabBarBackground: TabBarBackground,
- tabBarStyle: Platform.select({
- ios: {
- // Use a transparent background on iOS to show the blur effect
- position: 'absolute',
- },
- default: {},
- }),
- }}>
+ <Tabs>
<Tabs.Screen
name="index"
options={{
- title: 'Home',
- tabBarIcon: ({ color }) => <IconSymbol size={28} name="house.fill" color={color} />,
- }}
- />
- <Tabs.Screen
- name="explore"
- options={{
- title: 'Explore',
- tabBarIcon: ({ color }) => <IconSymbol size={28} name="paperplane.fill" color={color} />,
+ title: 'Todo List',
+ tabBarLabel: 'Todo List',
+ headerStyle: {
+ backgroundColor: '#0096FF',
+ },
+ headerTintColor: '#fff',
+ headerTitleStyle: {
+ fontWeight: 'bold',
+ },
+ tabBarIcon: ({ color }) => (
+ <MaterialIcons name="check-circle" size={24} color={color} />
+ ),
}}
/>
</Tabs>
);
-}
+}
\ No newline at end of file
diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx
index 462e8cd..6f24404 100644
--- a/app/(tabs)/index.tsx
+++ b/app/(tabs)/index.tsx
@@ -1,75 +1,281 @@
-import { Image } from 'expo-image';
-import { Platform, StyleSheet } from 'react-native';
+// app/(tabs)/index.tsx
+import React, { useState, useEffect } from 'react';
+import {
+ StyleSheet,
+ Text,
+ View,
+ TextInput,
+ TouchableOpacity,
+ FlatList,
+ KeyboardAvoidingView,
+ Platform,
+ ActivityIndicator,
+ Alert,
+} from 'react-native';
+import { MaterialIcons } from '@expo/vector-icons';
+import { db } from '../../firebaseConfig';
+import {
+ collection,
+ addDoc,
+ query,
+ onSnapshot,
+ doc,
+ deleteDoc,
+ updateDoc,
+ serverTimestamp,
+ orderBy
+} from 'firebase/firestore';
-import { HelloWave } from '@/components/HelloWave';
-import ParallaxScrollView from '@/components/ParallaxScrollView';
-import { ThemedText } from '@/components/ThemedText';
-import { ThemedView } from '@/components/ThemedView';
+//Interface defiens the structure of a task
+interface Task {
+ id: string;
+ title: string;
+ completed: boolean;
+ createdAt: any;
+}
+
+
+export default function TodoScreen() {
+ //State to manage the input field for a new task
+ const [task, setTask] = useState<string>('');
+ //State for the list of tasks
+ const [tasks, setTasks] = useState<Task[]>([]);
+ // State to track if data is still loading
+ const [loading, setLoading] = useState<boolean>(true);
+
+ //useffect to fetch todos from firebase when component loads
+ useEffect(() => {
+ const q = query(
+ collection(db, 'tasks'),
+ orderBy('createdAt', 'desc')
+ );
+
+ // Set up real-time listener for database changes
+ const unsubscribe = onSnapshot(q, (snapshot) => {
+ // Map the Firebase documents to Task interface
+ const taskList = snapshot.docs.map(doc => ({
+ id: doc.id,
+ ...doc.data()
+ })) as Task[];
+ // Update state with the tasks
+ setTasks(taskList);
+ // Set loading to false since data is received
+ setLoading(false);
+ }, (error) => {
+ console.error("Error fetching tasks: ", error);
+ Alert.alert("Error", "Failed to load tasks. Please try again later.");
+ setLoading(false);
+ });
+ // Clean up the listener when component unmounts
+ return () => unsubscribe();
+ }, []);
+
+ // Function to add a new task to Firebase
+ const addTask = async () => {
+ // Validate that task is not empty
+ if (task.trim() === '') {
+ Alert.alert("Error", "Please enter a task");
+ return;
+ }
+
+ try {
+ await addDoc(collection(db, 'tasks'), {
+ title: task,
+ completed: false,
+ createdAt: serverTimestamp() // Use Firebase server timestamp for consistent timing
+ });
-export default function HomeScreen() {
+ // Clear the input field after adding
+ setTask('');
+ } catch (error) {
+ console.error("Error adding task: ", error);
+ Alert.alert("Error", "Failed to add task. Please try again.");
+ }
+ };
+ // Function to delete a task from Firebase given its id
+ const deleteTask = async (id: string) => {
+ try {
+ await deleteDoc(doc(db, 'tasks', id));
+ } catch (error) {
+ console.error("Error deleting task: ", error);
+ Alert.alert("Error", "Failed to delete task. Please try again.");
+ }
+ };
+ // Function to set completed status of a task
+ const toggleComplete = async (id: string, completed: boolean) => {
+ try {
+ //update the completed field of a task to its opposite value
+ await updateDoc(doc(db, 'tasks', id), {
+ completed: !completed
+ });
+ } catch (error) {
+ console.error("Error updating task: ", error);
+ Alert.alert("Error", "Failed to update task. Please try again.");
+ }
+ };
+
+ // Function to render each task item in the FlatList
+ const renderItem = ({ item }: { item: Task }) => (
+ <View style={styles.taskContainer}>
+ {/*Show the checkbox for marking as complete*/}
+ <TouchableOpacity
+ style={styles.taskCheckbox}
+ onPress={() => toggleComplete(item.id, item.completed)}
+ >
+ <MaterialIcons
+ name={item.completed ? "check-box" : "check-box-outline-blank"}
+ size={24}
+ color={item.completed ? "#0096FF" : "#808080"}
+ />
+ </TouchableOpacity>
+ {/*Shows the todo title, and with a strike through it if its marked as complete */}
+ <Text
+ style={[
+ styles.taskTitle,
+ item.completed && styles.completedTask
+ ]}
+ >
+ {item.title}
+ </Text>
+ {/*Shows the delete button and calls delete task if pressed*/}
+ <TouchableOpacity
+ style={styles.deleteButton}
+ onPress={() => deleteTask(item.id)}
+ >
+ <MaterialIcons name="delete" size={24} color="#FF6347" />
+ </TouchableOpacity>
+ </View>
+ );
+ //If the data is loading, it shows the loading indicstor
+ if (loading) {
+ return (
+ <View style={styles.centered}>
+ <ActivityIndicator size="large" color="#0096FF" />
+ </View>
+ );
+ }
+
+ //Main component render
return (
- <ParallaxScrollView
- headerBackgroundColor={{ light: '#A1CEDC', dark: '#1D3D47' }}
- headerImage={
- <Image
- source={require('@/assets/images/partial-react-logo.png')}
- style={styles.reactLogo}
+ //Adjusts layout when keyboard comes up
+ <KeyboardAvoidingView
+ //Uses padding on ios and height on android
+ behavior={Platform.OS === "ios" ? "padding" : "height"}
+ style={styles.container}
+ >
+ <View style={styles.content}>
+ {/*If no tasks are found, show text */}
+ {tasks.length === 0 ? (
+ <View style={styles.emptyContainer}>
+ <Text style={styles.emptyText}>No tasks yet. Add one below!</Text>
+ </View>
+ ) : (
+ //Show the tasks in flatlist format
+ <FlatList
+ data={tasks}
+ renderItem={renderItem}
+ //Uses each tasks id to keep track of them
+ keyExtractor={item => item.id}
+ style={styles.list}
+ />
+ )}
+ </View>
+
+ {/*View for the add task*/}
+ <View style={styles.inputContainer}>
+ <TextInput
+ style={styles.input}
+ placeholder="Add a new task..."
+ value={task}
+ //Updtates the usestate on the text box
+ onChangeText={setTask}
+ onSubmitEditing={addTask}
/>
- }>
- <ThemedView style={styles.titleContainer}>
- <ThemedText type="title">Welcome!</ThemedText>
- <HelloWave />
- </ThemedView>
- <ThemedView style={styles.stepContainer}>
- <ThemedText type="subtitle">Step 1: Try it</ThemedText>
- <ThemedText>
- Edit <ThemedText type="defaultSemiBold">app/(tabs)/index.tsx</ThemedText> to see changes.
- Press{' '}
- <ThemedText type="defaultSemiBold">
- {Platform.select({
- ios: 'cmd + d',
- android: 'cmd + m',
- web: 'F12',
- })}
- </ThemedText>{' '}
- to open developer tools.
- </ThemedText>
- </ThemedView>
- <ThemedView style={styles.stepContainer}>
- <ThemedText type="subtitle">Step 2: Explore</ThemedText>
- <ThemedText>
- {`Tap the Explore tab to learn more about what's included in this starter app.`}
- </ThemedText>
- </ThemedView>
- <ThemedView style={styles.stepContainer}>
- <ThemedText type="subtitle">Step 3: Get a fresh start</ThemedText>
- <ThemedText>
- {`When you're ready, run `}
- <ThemedText type="defaultSemiBold">npm run reset-project</ThemedText> to get a fresh{' '}
- <ThemedText type="defaultSemiBold">app</ThemedText> directory. This will move the current{' '}
- <ThemedText type="defaultSemiBold">app</ThemedText> to{' '}
- <ThemedText type="defaultSemiBold">app-example</ThemedText>.
- </ThemedText>
- </ThemedView>
- </ParallaxScrollView>
+ <TouchableOpacity style={styles.addButton} onPress={addTask}>
+ <MaterialIcons name="add" size={24} color="white" />
+ </TouchableOpacity>
+ </View>
+ </KeyboardAvoidingView>
);
}
const styles = StyleSheet.create({
- titleContainer: {
+ container: {
+ flex: 1,
+ backgroundColor: '#f5f5f5',
+ },
+ centered: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+ content: {
+ flex: 1,
+ padding: 20,
+ },
+ list: {
+ flex: 1,
+ },
+ emptyContainer: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+ emptyText: {
+ fontSize: 18,
+ color: '#808080',
+ textAlign: 'center',
+ },
+ taskContainer: {
+ backgroundColor: 'white',
+ borderRadius: 10,
+ padding: 15,
+ marginBottom: 15,
flexDirection: 'row',
alignItems: 'center',
- gap: 8,
+ shadowColor: '#000',
+ shadowOffset: { width: 0, height: 1 },
+ shadowOpacity: 0.2,
+ shadowRadius: 2,
+ elevation: 2,
+ },
+ taskCheckbox: {
+ marginRight: 10,
},
- stepContainer: {
- gap: 8,
- marginBottom: 8,
+ taskTitle: {
+ flex: 1,
+ fontSize: 16,
},
- reactLogo: {
- height: 178,
- width: 290,
- bottom: 0,
- left: 0,
- position: 'absolute',
+ completedTask: {
+ textDecorationLine: 'line-through',
+ color: '#808080',
+ },
+ deleteButton: {
+ padding: 5,
+ },
+ inputContainer: {
+ flexDirection: 'row',
+ padding: 15,
+ backgroundColor: 'white',
+ borderTopWidth: 1,
+ borderTopColor: '#e0e0e0',
+ },
+ input: {
+ flex: 1,
+ height: 50,
+ borderWidth: 1,
+ borderColor: '#e0e0e0',
+ borderRadius: 10,
+ paddingHorizontal: 15,
+ backgroundColor: '#f9f9f9',
+ },
+ addButton: {
+ width: 50,
+ height: 50,
+ backgroundColor: '#0096FF',
+ borderRadius: 10,
+ justifyContent: 'center',
+ alignItems: 'center',
+ marginLeft: 10,
},
-});
+});
\ No newline at end of file
diff --git a/firebaseConfig.js b/firebaseConfig.js
new file mode 100644
index 0000000..ec9ce87
--- /dev/null
+++ b/firebaseConfig.js
@@ -0,0 +1,20 @@
+// firebaseConfig.ts
+import { initializeApp } from 'firebase/app';
+import { getFirestore } from 'firebase/firestore';
+
+const firebaseConfig = {
+ apiKey: "AIzaSyDsbzctSY3E_b-MqQ2pq09aUG3k4yBtDJg",
+ authDomain: "todolistapp-e8db3.firebaseapp.com",
+ projectId: "todolistapp-e8db3",
+ storageBucket: "todolistapp-e8db3.appspot.com",
+ messagingSenderId: "517113574716",
+ appId: "1:517113574716:web:e97608938c0e6169315a39",
+ measurementId: "G-NY6SF36Y5Q"
+};
+
+const app = initializeApp(firebaseConfig);
+const db = getFirestore(app);
+
+
+
+export { db };
diff --git a/package-lock.json b/package-lock.json
index af612e9..29ed89d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,10 +11,12 @@
"@expo/vector-icons": "^14.1.0",
"@react-navigation/bottom-tabs": "^7.3.10",
"@react-navigation/elements": "^2.3.8",
- "@react-navigation/native": "^7.1.6",
+ "@react-navigation/native": "^7.1.9",
+ "@react-navigation/stack": "^7.3.2",
"expo": "~53.0.9",
"expo-blur": "~14.1.4",
"expo-constants": "~17.1.6",
+ "expo-dev-client": "~5.1.8",
"expo-font": "~13.3.1",
"expo-haptics": "~14.1.4",
"expo-image": "~2.1.7",
@@ -25,6 +27,7 @@
"expo-symbols": "~0.4.4",
"expo-system-ui": "~5.0.7",
"expo-web-browser": "~14.1.6",
+ "firebase": "^11.7.1",
"react": "19.0.0",
"react-dom": "19.0.0",
"react-native": "0.79.2",
@@ -2260,6 +2263,645 @@
"@babel/highlight": "^7.10.4"
}
},
+ "node_modules/@firebase/analytics": {
+ "version": "0.10.13",
+ "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.13.tgz",
+ "integrity": "sha512-X+6wMOPgA9l0AeeMdMcMfaCP4XKPvrhx55MGuMrfHvUrOvFKldpzBum7KkoGJMoexKmqmKP+mCmJMY9Fb8K6Hw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/component": "0.6.14",
+ "@firebase/installations": "0.6.14",
+ "@firebase/logger": "0.4.4",
+ "@firebase/util": "1.11.1",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/analytics-compat": {
+ "version": "0.2.19",
+ "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.19.tgz",
+ "integrity": "sha512-l/PYILG9Tu4D5XtazqzvT5J6f7B/laqlaoSjiee6QdQkEg1kmMIeAaLKWGbf8tR/T3g6Lv3lx1AwJBuLhVaqTQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/analytics": "0.10.13",
+ "@firebase/analytics-types": "0.8.3",
+ "@firebase/component": "0.6.14",
+ "@firebase/util": "1.11.1",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/analytics-types": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.3.tgz",
+ "integrity": "sha512-VrIp/d8iq2g501qO46uGz3hjbDb8xzYMrbu8Tp0ovzIzrvJZ2fvmj649gTjge/b7cCCcjT0H37g1gVtlNhnkbg==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@firebase/app": {
+ "version": "0.12.1",
+ "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.12.1.tgz",
+ "integrity": "sha512-ASExOlmmjRMdwOQ65Oj6R9JBqa7iiT1/LgZjtbU7FqxoJZNWHrt39NJ/z2bjyYDdAHX8jkY7muFqzahScCXgfA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/component": "0.6.14",
+ "@firebase/logger": "0.4.4",
+ "@firebase/util": "1.11.1",
+ "idb": "7.1.1",
+ "tslib": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@firebase/app-check": {
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.9.1.tgz",
+ "integrity": "sha512-3gt4yt7oFXalJ2pLpawxKZI9lLLv2Jo2H3AoVKv9Fqy6zQmAC0nSItt9JUl2iDNd11V/bj4OC5rfoAjtyK22dQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/component": "0.6.14",
+ "@firebase/logger": "0.4.4",
+ "@firebase/util": "1.11.1",
+ "tslib": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/app-check-compat": {
+ "version": "0.3.22",
+ "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.22.tgz",
+ "integrity": "sha512-Tag7kI0vnzlsKrpnnhUgbTTTv2NNGR+Sf2pHiy3QApOaOG5tx6W5OQyvKv3+KaGbjEU19mvgOzOe1q5XHDoRvQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/app-check": "0.9.1",
+ "@firebase/app-check-types": "0.5.3",
+ "@firebase/component": "0.6.14",
+ "@firebase/logger": "0.4.4",
+ "@firebase/util": "1.11.1",
+ "tslib": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/app-check-interop-types": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz",
+ "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@firebase/app-check-types": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.3.tgz",
+ "integrity": "sha512-hyl5rKSj0QmwPdsAxrI5x1otDlByQ7bvNvVt8G/XPO2CSwE++rmSVf3VEhaeOR4J8ZFaF0Z0NDSmLejPweZ3ng==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@firebase/app-compat": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.3.1.tgz",
+ "integrity": "sha512-NCW2H/FawF0cBs3ciRx7NLt0H/VKn71H/q1RfTfctFez7maZ3KJi8QudpmIwoEqEW1N5HiXWxKAHY18Uo6o2Bg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/app": "0.12.1",
+ "@firebase/component": "0.6.14",
+ "@firebase/logger": "0.4.4",
+ "@firebase/util": "1.11.1",
+ "tslib": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@firebase/app-types": {
+ "version": "0.9.3",
+ "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz",
+ "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@firebase/auth": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.10.2.tgz",
+ "integrity": "sha512-HHudcj3CJyXpoMKslNOVHGSNJdAUjvy5xBA/G/uPb32QFqvx5F3EW9RDYvve2IHEN7Vpc1QTkk/28J32x83UGA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/component": "0.6.14",
+ "@firebase/logger": "0.4.4",
+ "@firebase/util": "1.11.1",
+ "tslib": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x",
+ "@react-native-async-storage/async-storage": "^1.18.1"
+ },
+ "peerDependenciesMeta": {
+ "@react-native-async-storage/async-storage": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@firebase/auth-compat": {
+ "version": "0.5.22",
+ "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.22.tgz",
+ "integrity": "sha512-RC7QdBIgg/hyxhJW2sso9Syb9iSr2wZ+vB6c/PnN+64uNZhp8bdxauhmDJGmbvStwCf/l2RpBsusVXQXVMnrgQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/auth": "1.10.2",
+ "@firebase/auth-types": "0.13.0",
+ "@firebase/component": "0.6.14",
+ "@firebase/util": "1.11.1",
+ "tslib": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/auth-interop-types": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz",
+ "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@firebase/auth-types": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.13.0.tgz",
+ "integrity": "sha512-S/PuIjni0AQRLF+l9ck0YpsMOdE8GO2KU6ubmBB7P+7TJUCQDa3R1dlgYm9UzGbbePMZsp0xzB93f2b/CgxMOg==",
+ "license": "Apache-2.0",
+ "peerDependencies": {
+ "@firebase/app-types": "0.x",
+ "@firebase/util": "1.x"
+ }
+ },
+ "node_modules/@firebase/component": {
+ "version": "0.6.14",
+ "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.14.tgz",
+ "integrity": "sha512-kf/zAT8GQJ9nYoHuj0mv7twp1QzifKYrO+GsmsVHHM+Hi9KkmI7E3B3J0CtihHpb34vinl4gbJrYJ2p2wfvc9A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/util": "1.11.1",
+ "tslib": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@firebase/data-connect": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@firebase/data-connect/-/data-connect-0.3.5.tgz",
+ "integrity": "sha512-YtiSRdiJicaXuyRC/yJjErQ/aHIlWt2umcBSpggYCP9TqKRIsJtgoskSSGzWJhzHn13BojYa7rWXmutTc5tovg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/auth-interop-types": "0.2.4",
+ "@firebase/component": "0.6.14",
+ "@firebase/logger": "0.4.4",
+ "@firebase/util": "1.11.1",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/database": {
+ "version": "1.0.15",
+ "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.15.tgz",
+ "integrity": "sha512-xmeTqKoIB2u1AXvLc1jq3Val0QAHUr49YycAr6feoDD7zM9dCjSk8rq9s1ESTv+tbbqS2BRoTpjIvxwXRTKhQQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/app-check-interop-types": "0.3.3",
+ "@firebase/auth-interop-types": "0.2.4",
+ "@firebase/component": "0.6.14",
+ "@firebase/logger": "0.4.4",
+ "@firebase/util": "1.11.1",
+ "faye-websocket": "0.11.4",
+ "tslib": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@firebase/database-compat": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.6.tgz",
+ "integrity": "sha512-vv15b1E59sLwoVdjGKvJ75ok9Qu1VRJC/7KXAQGnXvURAL199Ndy1YEw6/GA9twoFlLCYnd2ltxxB2pPiL1Vqw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/component": "0.6.14",
+ "@firebase/database": "1.0.15",
+ "@firebase/database-types": "1.0.11",
+ "@firebase/logger": "0.4.4",
+ "@firebase/util": "1.11.1",
+ "tslib": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@firebase/database-types": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.11.tgz",
+ "integrity": "sha512-LBZG/nT6GbntbIdGxBNvu9PBtj4xUEE9wX8AFF6njFK/MufYBESiKqT+jhDwmbcM4zAha9U0Pcca8FvJ1z1bYw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/app-types": "0.9.3",
+ "@firebase/util": "1.11.1"
+ }
+ },
+ "node_modules/@firebase/firestore": {
+ "version": "4.7.12",
+ "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.7.12.tgz",
+ "integrity": "sha512-50KRdSp8xA7+G0wfWxlnCoEN951mt8BVdLMxeP57Rehj2DqIb41q6Fc6JH0dfQ4TlMqWua1YfVY1jPEAaHVF9w==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/component": "0.6.14",
+ "@firebase/logger": "0.4.4",
+ "@firebase/util": "1.11.1",
+ "@firebase/webchannel-wrapper": "1.0.3",
+ "@grpc/grpc-js": "~1.9.0",
+ "@grpc/proto-loader": "^0.7.8",
+ "tslib": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/firestore-compat": {
+ "version": "0.3.47",
+ "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.47.tgz",
+ "integrity": "sha512-8fs4Zz2nXOgOf62wCK06Fo6uMGojyEhNEg/x2Pdnir9H9AH4T5T5q4/0MXdgPFSNBFcrPl+SVlmD1WTEZL+XGA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/component": "0.6.14",
+ "@firebase/firestore": "4.7.12",
+ "@firebase/firestore-types": "3.0.3",
+ "@firebase/util": "1.11.1",
+ "tslib": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/firestore-types": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.3.tgz",
+ "integrity": "sha512-hD2jGdiWRxB/eZWF89xcK9gF8wvENDJkzpVFb4aGkzfEaKxVRD1kjz1t1Wj8VZEp2LCB53Yx1zD8mrhQu87R6Q==",
+ "license": "Apache-2.0",
+ "peerDependencies": {
+ "@firebase/app-types": "0.x",
+ "@firebase/util": "1.x"
+ }
+ },
+ "node_modules/@firebase/functions": {
+ "version": "0.12.4",
+ "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.12.4.tgz",
+ "integrity": "sha512-XAvDHvJ1222+9lPHssgRzALejCSW/CN+mlyLbLXHSJHujfIfn9yPHOcAj9KfACavd+F8ey7h4mpxfHowczpVXw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/app-check-interop-types": "0.3.3",
+ "@firebase/auth-interop-types": "0.2.4",
+ "@firebase/component": "0.6.14",
+ "@firebase/messaging-interop-types": "0.2.3",
+ "@firebase/util": "1.11.1",
+ "tslib": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/functions-compat": {
+ "version": "0.3.21",
+ "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.21.tgz",
+ "integrity": "sha512-FFtdZt6ve6VxOW6Y6IytR5wXXRQ0/IXTXsztrPd9HhilzzbHbXKYyyvODrnHfraslTW50gdZlj7WlZieiVhcig==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/component": "0.6.14",
+ "@firebase/functions": "0.12.4",
+ "@firebase/functions-types": "0.6.3",
+ "@firebase/util": "1.11.1",
+ "tslib": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/functions-types": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.3.tgz",
+ "integrity": "sha512-EZoDKQLUHFKNx6VLipQwrSMh01A1SaL3Wg6Hpi//x6/fJ6Ee4hrAeswK99I5Ht8roiniKHw4iO0B1Oxj5I4plg==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@firebase/installations": {
+ "version": "0.6.14",
+ "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.14.tgz",
+ "integrity": "sha512-uE837g9+sv6PfjWPgOfG3JtjZ+hJ7KBHO4UVenVsvhzgOxFkvLjO/bgE7fyvsaD3fOHSXunx3adRIg4eUEMPyA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/component": "0.6.14",
+ "@firebase/util": "1.11.1",
+ "idb": "7.1.1",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/installations-compat": {
+ "version": "0.2.14",
+ "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.14.tgz",
+ "integrity": "sha512-6+xTtM2WwnVWY2qO8seWZqkrwhklFsgDCzmburqppHrGXW7Saxpyb+EqSHjFRcQleq5UGFwo0xqorLCwHa9WXA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/component": "0.6.14",
+ "@firebase/installations": "0.6.14",
+ "@firebase/installations-types": "0.5.3",
+ "@firebase/util": "1.11.1",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/installations-types": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.3.tgz",
+ "integrity": "sha512-2FJI7gkLqIE0iYsNQ1P751lO3hER+Umykel+TkLwHj6plzWVxqvfclPUZhcKFVQObqloEBTmpi2Ozn7EkCABAA==",
+ "license": "Apache-2.0",
+ "peerDependencies": {
+ "@firebase/app-types": "0.x"
+ }
+ },
+ "node_modules/@firebase/logger": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.4.tgz",
+ "integrity": "sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@firebase/messaging": {
+ "version": "0.12.18",
+ "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.18.tgz",
+ "integrity": "sha512-2MGhUGoCZloB7ysoYzG/T2nnRmHYLT+AcqYouZuD6APabpkDhF8lHsmSQq4MFSlXhI3DKFOXxjuvbY8ec4C2JQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/component": "0.6.14",
+ "@firebase/installations": "0.6.14",
+ "@firebase/messaging-interop-types": "0.2.3",
+ "@firebase/util": "1.11.1",
+ "idb": "7.1.1",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/messaging-compat": {
+ "version": "0.2.18",
+ "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.18.tgz",
+ "integrity": "sha512-Msrm6krO0SNqJak5cLK1IuNYmQgWwofE/o2Zz/k1Ckb9qZTMjfmKkjWq7II9se+BFsPAe3YH+05Kx2RldwYYGw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/component": "0.6.14",
+ "@firebase/messaging": "0.12.18",
+ "@firebase/util": "1.11.1",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/messaging-interop-types": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.3.tgz",
+ "integrity": "sha512-xfzFaJpzcmtDjycpDeCUj0Ge10ATFi/VHVIvEEjDNc3hodVBQADZ7BWQU7CuFpjSHE+eLuBI13z5F/9xOoGX8Q==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@firebase/performance": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.7.3.tgz",
+ "integrity": "sha512-PNBBbMskmSK8D8S1uZRzTqC2LpPDxVw/RbM5IsfrzyyJcyT6Lo+L8Y1vjBvVuK2Mw6pS6M6TgGncf2s+wq3kRA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/component": "0.6.14",
+ "@firebase/installations": "0.6.14",
+ "@firebase/logger": "0.4.4",
+ "@firebase/util": "1.11.1",
+ "tslib": "^2.1.0",
+ "web-vitals": "^4.2.4"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/performance-compat": {
+ "version": "0.2.16",
+ "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.16.tgz",
+ "integrity": "sha512-B0Wv11TnS4leQmkCHDx/quyy3B6Qz+Zog0y/um2dSlfwO8YnbfJYqG+zUlJsCs/dB8dnyNbcP0o80cZq6y8UyQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/component": "0.6.14",
+ "@firebase/logger": "0.4.4",
+ "@firebase/performance": "0.7.3",
+ "@firebase/performance-types": "0.2.3",
+ "@firebase/util": "1.11.1",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/performance-types": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.3.tgz",
+ "integrity": "sha512-IgkyTz6QZVPAq8GSkLYJvwSLr3LS9+V6vNPQr0x4YozZJiLF5jYixj0amDtATf1X0EtYHqoPO48a9ija8GocxQ==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@firebase/remote-config": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.6.1.tgz",
+ "integrity": "sha512-nlZ75rEVuGFGjUHuQuZIeLTTyHgCjW4jD2uCXu6mwNrQ6Mh18gjN3rS0Pfxz40NYcNlzfWPf0uvA4CYMXWa6yA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/component": "0.6.14",
+ "@firebase/installations": "0.6.14",
+ "@firebase/logger": "0.4.4",
+ "@firebase/util": "1.11.1",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/remote-config-compat": {
+ "version": "0.2.14",
+ "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.14.tgz",
+ "integrity": "sha512-qr0H1+y58ErLRbvD58IzlyVK+DjtGCNRDq0E1EM6xj5K3rB+3Ifmwq1EU5gzX0kI+xQlXYNHMFYxd+PTgwblUg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/component": "0.6.14",
+ "@firebase/logger": "0.4.4",
+ "@firebase/remote-config": "0.6.1",
+ "@firebase/remote-config-types": "0.4.0",
+ "@firebase/util": "1.11.1",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/remote-config-types": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.4.0.tgz",
+ "integrity": "sha512-7p3mRE/ldCNYt8fmWMQ/MSGRmXYlJ15Rvs9Rk17t8p0WwZDbeK7eRmoI1tvCPaDzn9Oqh+yD6Lw+sGLsLg4kKg==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@firebase/storage": {
+ "version": "0.13.8",
+ "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.13.8.tgz",
+ "integrity": "sha512-DjO8bSbwY/o+dbri3wear1gkrorgTpqi4uBTMoZZ02WOVR1A5AX8k/eYpUVuAvWyEDMWz/ECv4PgEokNajDsow==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/component": "0.6.14",
+ "@firebase/util": "1.11.1",
+ "tslib": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/storage-compat": {
+ "version": "0.3.18",
+ "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.18.tgz",
+ "integrity": "sha512-2A4LoqVV4GG8YlLU07ktjw8Xl558odeTg9a24wnT4P8Syf17Q6TjYCTwYGaFxYjQ00V7HUh9TfJIg9uO5zjeJw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/component": "0.6.14",
+ "@firebase/storage": "0.13.8",
+ "@firebase/storage-types": "0.8.3",
+ "@firebase/util": "1.11.1",
+ "tslib": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/storage-types": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.3.tgz",
+ "integrity": "sha512-+Muk7g9uwngTpd8xn9OdF/D48uiQ7I1Fae7ULsWPuKoCH3HU7bfFPhxtJYzyhjdniowhuDpQcfPmuNRAqZEfvg==",
+ "license": "Apache-2.0",
+ "peerDependencies": {
+ "@firebase/app-types": "0.x",
+ "@firebase/util": "1.x"
+ }
+ },
+ "node_modules/@firebase/util": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.11.1.tgz",
+ "integrity": "sha512-RXg4WE8C2LUrvoV/TMGRTu223zZf9Dq9MR8yHZio9nF9TpLnpCPURw9VWWB2WATDl6HfIdWfl2x2SJYtHkN4hw==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@firebase/vertexai": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@firebase/vertexai/-/vertexai-1.2.2.tgz",
+ "integrity": "sha512-DtHkD24fkewl88MRYlAdvyo1yXg2AQMa/3u+eW47EKKifKoVfDSyN9HVCP51saqzlRmDaeVuS1i2CY3Tu16lgQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/app-check-interop-types": "0.3.3",
+ "@firebase/component": "0.6.14",
+ "@firebase/logger": "0.4.4",
+ "@firebase/util": "1.11.1",
+ "tslib": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x",
+ "@firebase/app-types": "0.x"
+ }
+ },
+ "node_modules/@firebase/webchannel-wrapper": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-1.0.3.tgz",
+ "integrity": "sha512-2xCRM9q9FlzGZCdgDMJwc0gyUkWFtkosy7Xxr6sFgQwn+wMNIWd7xIvYNauU1r64B5L5rsGKy/n9TKJ0aAFeqQ==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@grpc/grpc-js": {
+ "version": "1.9.15",
+ "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.15.tgz",
+ "integrity": "sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@grpc/proto-loader": "^0.7.8",
+ "@types/node": ">=12.12.47"
+ },
+ "engines": {
+ "node": "^8.13.0 || >=10.10.0"
+ }
+ },
+ "node_modules/@grpc/proto-loader": {
+ "version": "0.7.15",
+ "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz",
+ "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "lodash.camelcase": "^4.3.0",
+ "long": "^5.0.0",
+ "protobufjs": "^7.2.5",
+ "yargs": "^17.7.2"
+ },
+ "bin": {
+ "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/@humanfs/core": {
"version": "0.19.1",
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
@@ -2742,6 +3384,70 @@
"node": ">=14"
}
},
+ "node_modules/@protobufjs/aspromise": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
+ "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@protobufjs/base64": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
+ "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@protobufjs/codegen": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
+ "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@protobufjs/eventemitter": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
+ "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@protobufjs/fetch": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
+ "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@protobufjs/aspromise": "^1.1.1",
+ "@protobufjs/inquire": "^1.1.0"
+ }
+ },
+ "node_modules/@protobufjs/float": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
+ "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@protobufjs/inquire": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
+ "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@protobufjs/path": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
+ "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@protobufjs/pool": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
+ "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@protobufjs/utf8": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
+ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==",
+ "license": "BSD-3-Clause"
+ },
"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",
@@ -3151,6 +3857,24 @@
"nanoid": "^3.3.11"
}
},
+ "node_modules/@react-navigation/stack": {
+ "version": "7.3.2",
+ "resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-7.3.2.tgz",
+ "integrity": "sha512-DAkuLCguUFjeOTmNtklMZSQJPcG3sl5h5M7VVms4xdGHO6RtNJ3ntJGTXYK/yFcDedLURKqBlJl5+4yTLORitQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@react-navigation/elements": "^2.4.2",
+ "color": "^4.2.3"
+ },
+ "peerDependencies": {
+ "@react-navigation/native": "^7.1.9",
+ "react": ">= 18.2.0",
+ "react-native": "*",
+ "react-native-gesture-handler": ">= 2.0.0",
+ "react-native-safe-area-context": ">= 4.0.0",
+ "react-native-screens": ">= 4.0.0"
+ }
+ },
"node_modules/@rtsao/scc": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
@@ -6295,6 +7019,80 @@
"react-native": "*"
}
},
+ "node_modules/expo-dev-client": {
+ "version": "5.1.8",
+ "resolved": "https://registry.npmjs.org/expo-dev-client/-/expo-dev-client-5.1.8.tgz",
+ "integrity": "sha512-IopYPgBi3JflksO5ieTphbKsbYHy9iIVdT/d69It++y0iBMSm0oBIoDmUijrHKjE3fV6jnrwrm8luU13/mzIQQ==",
+ "license": "MIT",
+ "dependencies": {
+ "expo-dev-launcher": "5.1.11",
+ "expo-dev-menu": "6.1.10",
+ "expo-dev-menu-interface": "1.10.0",
+ "expo-manifests": "~0.16.4",
+ "expo-updates-interface": "~1.1.0"
+ },
+ "peerDependencies": {
+ "expo": "*"
+ }
+ },
+ "node_modules/expo-dev-launcher": {
+ "version": "5.1.11",
+ "resolved": "https://registry.npmjs.org/expo-dev-launcher/-/expo-dev-launcher-5.1.11.tgz",
+ "integrity": "sha512-bN0+nv5H038s8Gzf8i16hwCyD3sWDmHp7vb+QbL1i6B3XNnICCKS/H/3VH6H3PRMvCmoLGPlg+ODDqGlf0nu3g==",
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "8.11.0",
+ "expo-dev-menu": "6.1.10",
+ "expo-manifests": "~0.16.4",
+ "resolve-from": "^5.0.0"
+ },
+ "peerDependencies": {
+ "expo": "*"
+ }
+ },
+ "node_modules/expo-dev-launcher/node_modules/ajv": {
+ "version": "8.11.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz",
+ "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==",
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/expo-dev-launcher/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/expo-dev-menu": {
+ "version": "6.1.10",
+ "resolved": "https://registry.npmjs.org/expo-dev-menu/-/expo-dev-menu-6.1.10.tgz",
+ "integrity": "sha512-LaI0Bw5zzw5XefjYSX6YaMydzk0YBysjqQoxzj6ufDyKgwAfPmFwOLkZ03DOSerc9naezGLNAGgTEN6QTgMmgQ==",
+ "license": "MIT",
+ "dependencies": {
+ "expo-dev-menu-interface": "1.10.0"
+ },
+ "peerDependencies": {
+ "expo": "*"
+ }
+ },
+ "node_modules/expo-dev-menu-interface": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/expo-dev-menu-interface/-/expo-dev-menu-interface-1.10.0.tgz",
+ "integrity": "sha512-NxtM/qot5Rh2cY333iOE87dDg1S8CibW+Wu4WdLua3UMjy81pXYzAGCZGNOeY7k9GpNFqDPNDXWyBSlk9r2pBg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "expo": "*"
+ }
+ },
"node_modules/expo-file-system": {
"version": "18.1.10",
"resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-18.1.10.tgz",
@@ -6344,6 +7142,12 @@
}
}
},
+ "node_modules/expo-json-utils": {
+ "version": "0.15.0",
+ "resolved": "https://registry.npmjs.org/expo-json-utils/-/expo-json-utils-0.15.0.tgz",
+ "integrity": "sha512-duRT6oGl80IDzH2LD2yEFWNwGIC2WkozsB6HF3cDYNoNNdUvFk6uN3YiwsTsqVM/D0z6LEAQ01/SlYvN+Fw0JQ==",
+ "license": "MIT"
+ },
"node_modules/expo-keep-awake": {
"version": "14.1.4",
"resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-14.1.4.tgz",
@@ -6368,6 +7172,19 @@
"react-native": "*"
}
},
+ "node_modules/expo-manifests": {
+ "version": "0.16.5",
+ "resolved": "https://registry.npmjs.org/expo-manifests/-/expo-manifests-0.16.5.tgz",
+ "integrity": "sha512-zLUeJogn2C7qOE75Zz7jcmJorMfIbSRR35ctspN0OK/Hq/+PAAptA8p9jNVC8xp/91uP9uI8f3xPhh+A11eR2A==",
+ "license": "MIT",
+ "dependencies": {
+ "@expo/config": "~11.0.10",
+ "expo-json-utils": "~0.15.0"
+ },
+ "peerDependencies": {
+ "expo": "*"
+ }
+ },
"node_modules/expo-modules-autolinking": {
"version": "2.1.10",
"resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-2.1.10.tgz",
@@ -6507,6 +7324,15 @@
}
}
},
+ "node_modules/expo-updates-interface": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/expo-updates-interface/-/expo-updates-interface-1.1.0.tgz",
+ "integrity": "sha512-DeB+fRe0hUDPZhpJ4X4bFMAItatFBUPjw/TVSbJsaf3Exeami+2qbbJhWkcTMoYHOB73nOIcaYcWXYJnCJXO0w==",
+ "license": "MIT",
+ "peerDependencies": {
+ "expo": "*"
+ }
+ },
"node_modules/expo-web-browser": {
"version": "14.1.6",
"resolved": "https://registry.npmjs.org/expo-web-browser/-/expo-web-browser-14.1.6.tgz",
@@ -6751,6 +7577,18 @@
"reusify": "^1.0.4"
}
},
+ "node_modules/faye-websocket": {
+ "version": "0.11.4",
+ "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz",
+ "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "websocket-driver": ">=0.5.1"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
"node_modules/fb-watchman": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
@@ -6918,6 +7756,42 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/firebase": {
+ "version": "11.7.1",
+ "resolved": "https://registry.npmjs.org/firebase/-/firebase-11.7.1.tgz",
+ "integrity": "sha512-Jr0uKRwHAtnlyHis9+48mo3aXeChekaxhy6kSaqBC44qdogwAlTWiY3OTqmRomGA8B62rqS3LwpNyAEZsrhf7w==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@firebase/analytics": "0.10.13",
+ "@firebase/analytics-compat": "0.2.19",
+ "@firebase/app": "0.12.1",
+ "@firebase/app-check": "0.9.1",
+ "@firebase/app-check-compat": "0.3.22",
+ "@firebase/app-compat": "0.3.1",
+ "@firebase/app-types": "0.9.3",
+ "@firebase/auth": "1.10.2",
+ "@firebase/auth-compat": "0.5.22",
+ "@firebase/data-connect": "0.3.5",
+ "@firebase/database": "1.0.15",
+ "@firebase/database-compat": "2.0.6",
+ "@firebase/firestore": "4.7.12",
+ "@firebase/firestore-compat": "0.3.47",
+ "@firebase/functions": "0.12.4",
+ "@firebase/functions-compat": "0.3.21",
+ "@firebase/installations": "0.6.14",
+ "@firebase/installations-compat": "0.2.14",
+ "@firebase/messaging": "0.12.18",
+ "@firebase/messaging-compat": "0.2.18",
+ "@firebase/performance": "0.7.3",
+ "@firebase/performance-compat": "0.2.16",
+ "@firebase/remote-config": "0.6.1",
+ "@firebase/remote-config-compat": "0.2.14",
+ "@firebase/storage": "0.13.8",
+ "@firebase/storage-compat": "0.3.18",
+ "@firebase/util": "1.11.1",
+ "@firebase/vertexai": "1.2.2"
+ }
+ },
"node_modules/flat-cache": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
@@ -7443,6 +8317,12 @@
"node": ">= 0.8"
}
},
+ "node_modules/http-parser-js": {
+ "version": "0.5.10",
+ "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz",
+ "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==",
+ "license": "MIT"
+ },
"node_modules/https-proxy-agent": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
@@ -7475,6 +8355,12 @@
"node": ">=0.10.0"
}
},
+ "node_modules/idb": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz",
+ "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==",
+ "license": "ISC"
+ },
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
@@ -8754,6 +9640,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/lodash.camelcase": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
+ "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
+ "license": "MIT"
+ },
"node_modules/lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
@@ -8856,6 +9748,12 @@
"node": ">=4"
}
},
+ "node_modules/long": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
+ "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
+ "license": "Apache-2.0"
+ },
"node_modules/loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
@@ -10270,6 +11168,30 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/protobufjs": {
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.1.tgz",
+ "integrity": "sha512-3qx3IRjR9WPQKagdwrKjO3Gu8RgQR2qqw+1KnigWhoVjFqegIj1K3bP11sGqhxrO46/XL7lekuG4jmjL+4cLsw==",
+ "hasInstallScript": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@protobufjs/aspromise": "^1.1.2",
+ "@protobufjs/base64": "^1.1.2",
+ "@protobufjs/codegen": "^2.0.4",
+ "@protobufjs/eventemitter": "^1.1.0",
+ "@protobufjs/fetch": "^1.1.0",
+ "@protobufjs/float": "^1.0.2",
+ "@protobufjs/inquire": "^1.1.0",
+ "@protobufjs/path": "^1.1.2",
+ "@protobufjs/pool": "^1.1.0",
+ "@protobufjs/utf8": "^1.1.0",
+ "@types/node": ">=13.7.0",
+ "long": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
"node_modules/proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@@ -12286,9 +13208,7 @@
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
- "dev": true,
- "license": "0BSD",
- "optional": true
+ "license": "0BSD"
},
"node_modules/type-check": {
"version": "0.4.0",
@@ -12629,7 +13549,6 @@
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
- "dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"punycode": "^2.1.0"
@@ -12719,12 +13638,41 @@
"defaults": "^1.0.3"
}
},
+ "node_modules/web-vitals": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.4.tgz",
+ "integrity": "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==",
+ "license": "Apache-2.0"
+ },
"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==",
"license": "BSD-2-Clause"
},
+ "node_modules/websocket-driver": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
+ "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "http-parser-js": ">=0.5.1",
+ "safe-buffer": ">=5.1.0",
+ "websocket-extensions": ">=0.1.1"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/websocket-extensions": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
+ "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
"node_modules/whatwg-fetch": {
"version": "3.6.20",
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz",
diff --git a/package.json b/package.json
index aff4e7e..416a2c4 100644
--- a/package.json
+++ b/package.json
@@ -5,8 +5,8 @@
"scripts": {
"start": "expo start",
"reset-project": "node ./scripts/reset-project.js",
- "android": "expo start --android",
- "ios": "expo start --ios",
+ "android": "expo run:android",
+ "ios": "expo run:ios",
"web": "expo start --web",
"lint": "expo lint"
},
@@ -14,7 +14,8 @@
"@expo/vector-icons": "^14.1.0",
"@react-navigation/bottom-tabs": "^7.3.10",
"@react-navigation/elements": "^2.3.8",
- "@react-navigation/native": "^7.1.6",
+ "@react-navigation/native": "^7.1.9",
+ "@react-navigation/stack": "^7.3.2",
"expo": "~53.0.9",
"expo-blur": "~14.1.4",
"expo-constants": "~17.1.6",
@@ -28,6 +29,7 @@
"expo-symbols": "~0.4.4",
"expo-system-ui": "~5.0.7",
"expo-web-browser": "~14.1.6",
+ "firebase": "^11.7.1",
"react": "19.0.0",
"react-dom": "19.0.0",
"react-native": "0.79.2",
@@ -36,14 +38,15 @@
"react-native-safe-area-context": "5.4.0",
"react-native-screens": "~4.10.0",
"react-native-web": "~0.20.0",
- "react-native-webview": "13.13.5"
+ "react-native-webview": "13.13.5",
+ "expo-dev-client": "~5.1.8"
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@types/react": "~19.0.10",
- "typescript": "~5.8.3",
"eslint": "^9.25.0",
- "eslint-config-expo": "~9.2.0"
+ "eslint-config-expo": "~9.2.0",
+ "typescript": "~5.8.3"
},
"private": true
}
--
GitLab