Merge branch '60-create-enum-for-type-of-category' into 'main'

Resolve "create enum for type of category"

Closes #60

See merge request thschleicher/interaktive-systeme!51
This commit is contained in:
jastornig 2024-01-25 19:43:07 +00:00
commit 93757d52d7
17 changed files with 712 additions and 292 deletions

View file

@ -5,6 +5,7 @@ import { SafeAreaView } from 'react-native-safe-area-context';
import { AutoDecimalInput, CustomColorPicker, NavigationButton, TypeSelectorSwitch } from "../../../components"; import { AutoDecimalInput, CustomColorPicker, NavigationButton, TypeSelectorSwitch } from "../../../components";
import { addCategory } from "../../../services/database"; import { addCategory } from "../../../services/database";
import { useTheme } from "../../contexts/ThemeContext"; import { useTheme } from "../../contexts/ThemeContext";
import { CategoryType } from "../../../types/dbItems";
export default function Page() { export default function Page() {
const {colors} = useTheme(); const {colors} = useTheme();
@ -13,7 +14,9 @@ export default function Page() {
const [categoryName, setCategoryName] = useState<string>(""); const [categoryName, setCategoryName] = useState<string>("");
const [categoryColor, setCategoryColor] = useState<string>('#' + Math.floor(Math.random()*16777215).toString(16)); const [categoryColor, setCategoryColor] = useState<string>('#' + Math.floor(Math.random()*16777215).toString(16));
const [selectedType, setSelectedType] = useState<string>("expense");
const [selectedType, setSelectedType] = useState<CategoryType>(CategoryType.EXPENSE);
const [amount, setAmount] = useState(0); const [amount, setAmount] = useState(0);
return ( return (
@ -35,7 +38,7 @@ export default function Page() {
<TypeSelectorSwitch <TypeSelectorSwitch
currentSelected={selectedType} currentSelected={selectedType}
handleButtonPress={(type) => { handleButtonPress={(type: CategoryType) => {
setSelectedType(type); setSelectedType(type);
}} }}
/> />

View file

@ -6,6 +6,7 @@ import useFetch from "../../../hooks/useFetch";
import { deleteCategory, deleteExpense, updateCategory } from "../../../services/database"; import { deleteCategory, deleteExpense, updateCategory } from "../../../services/database";
import { useTheme } from "../../contexts/ThemeContext"; import { useTheme } from "../../contexts/ThemeContext";
import { SafeAreaView } from 'react-native-safe-area-context'; import { SafeAreaView } from 'react-native-safe-area-context';
import { CategoryType } from "../../../types/dbItems";
const addCategory = () => { const addCategory = () => {
const {colors} = useTheme(); const {colors} = useTheme();
@ -13,7 +14,7 @@ const addCategory = () => {
const [categoryName, setCategoryName] = useState(category_name.toString()); const [categoryName, setCategoryName] = useState(category_name.toString());
const [categoryColor, setCategoryColor] = useState(category_color.toString()); const [categoryColor, setCategoryColor] = useState(category_color.toString());
const [selectedType, setSelectedType] = useState(category_type.toString()); const [selectedType, setSelectedType] = useState<CategoryType>(category_type === "expense" ? CategoryType.EXPENSE : CategoryType.SAVING);
const [amount, setAmount] = useState(Number.parseFloat(category_amount.toString())); const [amount, setAmount] = useState(Number.parseFloat(category_amount.toString()));
const {data} = useFetch({sql: "SELECT * FROM expense WHERE category_guid = ?", args: [category_guid.toString()]}); const {data} = useFetch({sql: "SELECT * FROM expense WHERE category_guid = ?", args: [category_guid.toString()]});

View file

@ -67,7 +67,6 @@ export default function Page() {
}) })
}, [data, searchString, selectedPage]); }, [data, searchString, selectedPage]);
console.log(selectedPage)
return ( return (
<SafeAreaView style={[styles.safeAreaViewStyle, {backgroundColor: containerColor}]}> <SafeAreaView style={[styles.safeAreaViewStyle, {backgroundColor: containerColor}]}>
<View style={{flex: 1, marginHorizontal: 10}}> <View style={{flex: 1, marginHorizontal: 10}}>

View file

@ -4,7 +4,7 @@ import { SIZES } from '../../../constants/theme'
import { SafeAreaView } from 'react-native-safe-area-context' import { SafeAreaView } from 'react-native-safe-area-context'
import { ButtonSetting, ToggleSetting } from '../../../components' import { ButtonSetting, ToggleSetting } from '../../../components'
import { useTheme } from '../../contexts/ThemeContext' import { useTheme } from '../../contexts/ThemeContext'
import { deleteExpenses, DEV_populateDatabase } from '../../../services/database' import { deleteCategories, deleteExpenses, DEV_populateDatabase } from '../../../services/database'
import { useAuth } from '../../contexts/AuthContext' import { useAuth } from '../../contexts/AuthContext'
import { TouchableOpacity } from 'react-native-gesture-handler' import { TouchableOpacity } from 'react-native-gesture-handler'
@ -50,17 +50,14 @@ export default function userSettings() {
<View style={styles.settingsContainer}> <View style={styles.settingsContainer}>
<ToggleSetting settingsTitle='Use System Theme' value={systemTheme} onChange={handleSystemTheme}/> <ToggleSetting settingsTitle='Use System Theme' value={systemTheme} onChange={handleSystemTheme}/>
<ToggleSetting settingsTitle='Dark Mode' disabled={systemTheme} onChange={handleDarkMode} value={darkMode}/> <ToggleSetting settingsTitle='Dark Mode' disabled={systemTheme} onChange={handleDarkMode} value={darkMode}/>
<ButtonSetting settingsTitle='Reset Expenses' onPress={() => { <ButtonSetting settingsTitle='Reset Database' onPress={()=> {
deleteExpenses().then(() => { const deleteAll = async () => {
console.log("Expenses Deleted!"); await deleteExpenses();
})}} await deleteCategories();
/>
<ButtonSetting settingsTitle='Populate Database' onPress={() => {
const del = async () => {
await DEV_populateDatabase()
} }
del() deleteAll();
}}/> }}
/>
</View> </View>
</View> </View>

View file

@ -1,24 +1,39 @@
import React from 'react'; import React from 'react';
import { SafeAreaView } from 'react-native';
import { Graph } from '../../../components'; import { Graph } from '../../../components';
import BudgetOverview from '../../../components/stats/BudgetOverview'; import BudgetOverview from '../../../components/stats/BudgetOverview';
import BudgetRemaining from '../../../components/stats/BudgetRemaining'; import BudgetRemaining from '../../../components/stats/SavingsOverview';
import SavingsOverview from '../../../components/stats/SavingsOverview'; import SavingsOverview from '../../../components/stats/SavingsOverview';
import Widget from '../../../components/stats/Widget'; import Widget from '../../../components/stats/Widget';
import FinancialAdvice from '../../../components/stats/FinancialAdvice';
import BudgetTotal from '../../../components/stats/BudgetTotal';
import { ScrollView } from 'react-native-gesture-handler';
import { SafeAreaView } from 'react-native-safe-area-context';
import DebugMenu from '../../../services/DebugMenu';
export default function Page() { export default function Page() {
return ( return (
<SafeAreaView style={{flex:1}}> <SafeAreaView style={{flex:1}}>
<ScrollView>
{/* <DebugMenu/> */}
<Widget title="Budget Overview"/> <Widget title="Budget Overview"/>
<Graph/> <Graph/>
<BudgetRemaining/>
<Widget> <Widget>
<BudgetOverview/> <BudgetOverview/>
</Widget> </Widget>
<Widget> <Widget>
<SavingsOverview/> <SavingsOverview/>
</Widget> </Widget>
<Widget>
<BudgetTotal/>
</Widget>
{/* <Widget title='"Financial" Tips' backgroundColor='orange'>
<FinancialAdvice/>
</Widget> */}
</ScrollView>
</SafeAreaView> </SafeAreaView>
); );
} }

View file

@ -54,9 +54,7 @@ export default function AddItem() {
useEffect(()=>{ useEffect(()=>{
if(searchParams.category !== undefined){ if(searchParams.category !== undefined){
console.log(searchParams.category)
executeQuery({sql: "SELECT * FROM category WHERE guid = ?", args: [searchParams.category]}).then((result) =>{ executeQuery({sql: "SELECT * FROM category WHERE guid = ?", args: [searchParams.category]}).then((result) =>{
console.log("then")
if("rows" in result[0]){ if("rows" in result[0]){
const category = result[0]["rows"][0]; const category = result[0]["rows"][0];
setSelectedCategory({name: category["name"], color: category["color"], guid: category["guid"]}) setSelectedCategory({name: category["name"], color: category["color"], guid: category["guid"]})

View file

@ -1,10 +1,11 @@
import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
import { useTheme } from "../../app/contexts/ThemeContext"; import { useTheme } from "../../app/contexts/ThemeContext";
import { CategoryType } from "../../types/dbItems";
export type TypeSelectorSwitchProperties = { export type TypeSelectorSwitchProperties = {
handleButtonPress: (type: string) => void, handleButtonPress: (type: CategoryType) => void,
currentSelected: string, currentSelected: CategoryType,
} }
const TypeSelectorSwitch = (properties: TypeSelectorSwitchProperties) => { const TypeSelectorSwitch = (properties: TypeSelectorSwitchProperties) => {
@ -14,17 +15,17 @@ const TypeSelectorSwitch = (properties: TypeSelectorSwitchProperties) => {
<View style={styles.containerStyle}> <View style={styles.containerStyle}>
<TouchableOpacity <TouchableOpacity
onPress={() => { onPress={() => {
properties.handleButtonPress("expense"); properties.handleButtonPress(CategoryType.EXPENSE);
}} }}
style={[styles.touchableOpacityStyle, properties.currentSelected == "expense" ? {backgroundColor: colors.accentColor} : {backgroundColor: colors.elementDefaultColor}] style={[styles.touchableOpacityStyle, properties.currentSelected == CategoryType.EXPENSE ? {backgroundColor: colors.accentColor} : {backgroundColor: colors.elementDefaultColor}]
}> }>
<Text style={[styles.textStyle, {color: colors.primaryText}]}>Expenses</Text> <Text style={[styles.textStyle, {color: colors.primaryText}]}>Expenses</Text>
</TouchableOpacity> </TouchableOpacity>
<TouchableOpacity <TouchableOpacity
onPress={() => { onPress={() => {
properties.handleButtonPress("saving"); properties.handleButtonPress(CategoryType.SAVING);
}} }}
style={[styles.touchableOpacityStyle, properties.currentSelected == "saving" ? {backgroundColor: colors.accentColor} : {backgroundColor: colors.elementDefaultColor}] style={[styles.touchableOpacityStyle, properties.currentSelected == CategoryType.SAVING ? {backgroundColor: colors.accentColor} : {backgroundColor: colors.elementDefaultColor}]
}> }>
<Text style={[styles.textStyle, {color: colors.primaryText}]}>Savings</Text> <Text style={[styles.textStyle, {color: colors.primaryText}]}>Savings</Text>
</TouchableOpacity> </TouchableOpacity>

View file

@ -1,34 +1,9 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { View, Text, StyleSheet } from 'react-native'; import { Text, StyleSheet } from 'react-native';
import { useTheme } from '../../app/contexts/ThemeContext'; import { useTheme } from '../../app/contexts/ThemeContext';
import useFetch from '../../hooks/useFetch'; import useFetch from '../../hooks/useFetch';
import { CategoryType } from '../../types/dbItems';
const BudgetOverview = () => { import {useCategoryData} from '../../hooks/useCategoryData';
const { colors } = useTheme();
const [spent, setSpent] = useState(0);
const [budget, setBudget] = useState(0);
const spentQuery = {
sql: "SELECT SUM(e.amount) as total FROM expense e LEFT JOIN category c ON e.category_guid = c.guid WHERE c.type = 'budget'",
args: []
};
const budgetQuery = {
sql: "SELECT SUM(allocated_amount) as total FROM category WHERE type = 'budget'",
args: []
};
const { data: spentData, isLoading: spentLoading } = useFetch(spentQuery);
const { data: budgetData, isLoading: budgetLoading } = useFetch(budgetQuery);
useEffect(() => {
if (spentData) {
setSpent(spentData[0]?.total || 0);
}
if (budgetData) {
setBudget(budgetData[0]?.total || 0);
}
}, [spentData, budgetData]);
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
@ -39,24 +14,43 @@ const BudgetOverview = () => {
}, },
text: { text: {
fontSize: 26, fontSize: 26,
color: colors.primaryText color: `black`
}, },
boldText: { boldText: {
fontWeight: 'bold' fontWeight: 'bold'
} },
negativeText: {
color: 'red',
},
positiveText: {
color: 'green',
},
}); });
if (spentLoading || budgetLoading) { interface BudgetTotalProps {
goodColor?: string;
badColor?: string;
}
const BudgetTotal: React.FC<BudgetTotalProps> = ({ goodColor = 'green', badColor = 'red' }) => {
const { colors } = useTheme();
const { data, isLoading } = useCategoryData(CategoryType.EXPENSE);
const { total, expenseTotal } = data;
const remaining = total - expenseTotal;
if (isLoading) {
return <Text>Loading...</Text>; return <Text>Loading...</Text>;
} }
return ( return (
<View style={styles.container}> <Text style={[styles.text, { color: colors.primaryText }]}>
<Text style={styles.text}> <>
You have spent <Text style={styles.boldText}>{spent.toFixed(2)}</Text> out of your budget of <Text style={styles.boldText}>{budget.toFixed(2)}</Text>. You have spent <Text style={[styles.boldText, { color: goodColor }]}>{expenseTotal.toFixed(2)}</Text> out of your Budget of <Text style={[styles.boldText]}>{total.toFixed(2)} </Text>
</>
</Text> </Text>
</View>
); );
}; };
export default BudgetOverview; export default BudgetTotal;

View file

@ -1,55 +0,0 @@
import React, { useState, useEffect } from 'react';
import { Text, StyleSheet } from 'react-native';
import { useTheme } from '../../app/contexts/ThemeContext';
import useFetch from '../../hooks/useFetch';
const styles = StyleSheet.create({
text: {
fontSize: 26,
},
boldText: {
fontWeight: 'bold',
},
});
const BudgetRemaining = () => {
const { colors } = useTheme();
const [spent, setSpent] = useState(0);
const [budget, setBudget] = useState(0);
const spentQuery = {
sql: "SELECT SUM(amount) as total FROM expense",
args: []
};
const budgetQuery = {
sql: "SELECT SUM(allocated_amount) as total FROM category WHERE type = 'budget'",
args: []
};
const { data: spentData, isLoading: spentLoading } = useFetch(spentQuery);
const { data: budgetData, isLoading: budgetLoading } = useFetch(budgetQuery);
useEffect(() => {
if (spentData) {
setSpent(spentData[0]?.total || 0);
}
if (budgetData) {
setBudget(budgetData[0]?.total || 0);
}
}, [spentData, budgetData]);
const remaining = budget - spent;
if (spentLoading || budgetLoading) {
return <Text>Loading...</Text>;
}
return (
<Text style={[styles.text, {color: colors.primaryText}]}>
You have <Text style={styles.boldText}>{remaining.toFixed(2)}</Text> left.
</Text>
);
};
export default BudgetRemaining;

View file

@ -0,0 +1,62 @@
import React, { useState, useEffect } from 'react';
import { Text, StyleSheet } from 'react-native';
import { useTheme } from '../../app/contexts/ThemeContext';
import useFetch from '../../hooks/useFetch';
import { CategoryType } from '../../types/dbItems';
import {useCategoryData} from '../../hooks/useCategoryData';
const styles = StyleSheet.create({
container: {
margin: 10,
borderRadius: 5,
alignItems: 'center',
justifyContent: 'center'
},
text: {
fontSize: 26,
color: `black`
},
boldText: {
fontWeight: 'bold'
},
negativeText: {
color: 'red',
},
positiveText: {
color: 'green',
},
});
interface BudgetTotalProps {
goodColor?: string;
badColor?: string;
}
const BudgetTotal: React.FC<BudgetTotalProps> = ({ goodColor = 'green', badColor = 'red' }) => {
const { colors } = useTheme();
const { data, isLoading } = useCategoryData(CategoryType.EXPENSE);
const { total, expenseTotal } = data;
const remaining = total - expenseTotal;
if (isLoading) {
return <Text>Loading...</Text>;
}
return (
<Text style={[styles.text, { color: colors.primaryText }]}>
{remaining >= 0 ? (
<>
Your remaining overall Budget is <Text style={[styles.boldText, { color: goodColor }]}>{remaining.toFixed(2)}</Text>
</>
) : (
<>
Your Budget is overspent by <Text style={[styles.boldText, { color: badColor }]}>-{Math.abs(remaining).toFixed(2)}</Text>
</>
)}
</Text>
);
};
export default BudgetTotal;

View file

@ -1,34 +1,9 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { View, Text, StyleSheet } from 'react-native'; import { Text, StyleSheet } from 'react-native';
import { useTheme } from '../../app/contexts/ThemeContext'; import { useTheme } from '../../app/contexts/ThemeContext';
import useFetch from '../../hooks/useFetch'; import useFetch from '../../hooks/useFetch';
import { CategoryType } from '../../types/dbItems';
const SavingsOverview = () => { import {useCategoryData} from '../../hooks/useCategoryData';
const { colors } = useTheme();
const [saved, setSaved] = useState(0);
const [goal, setGoal] = useState(0);
const savedQuery = {
sql: "SELECT SUM(e.amount) as total FROM expense e LEFT JOIN category c ON e.category_guid = c.guid WHERE c.type = 'savings'",
args: []
};
const goalQuery = {
sql: "SELECT SUM(allocated_amount) as total FROM category WHERE type = 'budget'",
args: []
};
const { data: savedData, isLoading: savedLoading } = useFetch(savedQuery);
const { data: goalData, isLoading: goalLoading } = useFetch(goalQuery);
useEffect(() => {
if (savedData) {
setSaved(savedData[0]?.total || 0);
}
if (goalData) {
setGoal(goalData[0]?.total || 0);
}
}, [savedData, goalData]);
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
@ -39,24 +14,49 @@ const SavingsOverview = () => {
}, },
text: { text: {
fontSize: 26, fontSize: 26,
color: colors.primaryText color: `black`
}, },
boldText: { boldText: {
fontWeight: 'bold' fontWeight: 'bold'
} },
negativeText: {
color: 'red',
},
positiveText: {
color: 'green',
},
}); });
if (savedLoading || goalLoading) { interface BudgetTotalProps {
goodColor?: string;
badColor?: string;
}
const BudgetTotal: React.FC<BudgetTotalProps> = ({ goodColor = 'green', badColor = 'red' }) => {
const { colors } = useTheme();
const { data, isLoading } = useCategoryData(CategoryType.SAVING);
const { total, expenseTotal } = data;
const remaining = total - expenseTotal;
if (isLoading) {
return <Text>Loading...</Text>; return <Text>Loading...</Text>;
} }
return ( return (
<View style={styles.container}> <Text style={[styles.text, { color: colors.primaryText }]}>
<Text style={styles.text}> {remaining >= 0 ? (
You have saved <Text style={styles.boldText}>{saved.toFixed(2)}</Text> out of your goal of <Text style={styles.boldText}>{goal.toFixed(2)}</Text>. <>
You have saved <Text style={[styles.boldText, { color: badColor }]}>{expenseTotal.toFixed(2)}</Text> out of your Goal of <Text style={[styles.boldText]}>{total.toFixed(2)}</Text>
</>
) : (
<>
You have surpassed your Savings Goal of <Text style={[styles.boldText]}>{total.toFixed(2)}</Text> by <Text style={[styles.boldText, { color: goodColor }]}>{Math.abs(remaining).toFixed(2)}</Text>
</>
)}
</Text> </Text>
</View>
); );
}; };
export default SavingsOverview; export default BudgetTotal;

33
hooks/useCategoryData.ts Normal file
View file

@ -0,0 +1,33 @@
import { useState, useEffect } from 'react';
import useFetch from './useFetch';
import { CategoryType } from '../types/dbItems';
export const useCategoryData = (CategoryType: string) => {
const [data, setData] = useState({ total: 0, expenseTotal: 0 });
const [isLoading, setLoading] = useState(true);
const categoryQuery = {
sql: `SELECT SUM(allocated_amount) as total FROM category WHERE type = '${CategoryType.toString()}'`,
args: []
};
const expenseQuery = {
sql: `SELECT SUM(e.amount) as total FROM expense e JOIN category c ON e.category_guid = c.guid WHERE c.type = '${CategoryType.toString()}'`,
args: []
};
const { data: categoryData, isLoading: categoryLoading } = useFetch(categoryQuery);
const { data: expenseData, isLoading: expenseLoading } = useFetch(expenseQuery);
useEffect(() => {
if (categoryData && expenseData) {
setData({
total: categoryData[0]?.total || 0,
expenseTotal: expenseData[0]?.total || 0
});
}
setLoading(categoryLoading || expenseLoading);
}, [categoryData, categoryLoading, expenseData, expenseLoading]);
return { categoryData, expenseData, isLoading, data };
};

559
package-lock.json generated
View file

@ -28,7 +28,7 @@
"react-native-calendars": "^1.1303.0", "react-native-calendars": "^1.1303.0",
"react-native-chart-kit": "^6.12.0", "react-native-chart-kit": "^6.12.0",
"react-native-gesture-handler": "~2.12.0", "react-native-gesture-handler": "~2.12.0",
"react-native-reanimated": "^3.3.0", "react-native-reanimated": "~3.3.0",
"react-native-safe-area-context": "4.6.3", "react-native-safe-area-context": "4.6.3",
"react-native-screens": "~3.22.0", "react-native-screens": "~3.22.0",
"react-native-uuid": "^2.0.1", "react-native-uuid": "^2.0.1",
@ -78,19 +78,19 @@
} }
}, },
"node_modules/@babel/core": { "node_modules/@babel/core": {
"version": "7.23.6", "version": "7.23.7",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.6.tgz", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz",
"integrity": "sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw==", "integrity": "sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==",
"dependencies": { "dependencies": {
"@ampproject/remapping": "^2.2.0", "@ampproject/remapping": "^2.2.0",
"@babel/code-frame": "^7.23.5", "@babel/code-frame": "^7.23.5",
"@babel/generator": "^7.23.6", "@babel/generator": "^7.23.6",
"@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-compilation-targets": "^7.23.6",
"@babel/helper-module-transforms": "^7.23.3", "@babel/helper-module-transforms": "^7.23.3",
"@babel/helpers": "^7.23.6", "@babel/helpers": "^7.23.7",
"@babel/parser": "^7.23.6", "@babel/parser": "^7.23.6",
"@babel/template": "^7.22.15", "@babel/template": "^7.22.15",
"@babel/traverse": "^7.23.6", "@babel/traverse": "^7.23.7",
"@babel/types": "^7.23.6", "@babel/types": "^7.23.6",
"convert-source-map": "^2.0.0", "convert-source-map": "^2.0.0",
"debug": "^4.1.0", "debug": "^4.1.0",
@ -158,9 +158,9 @@
} }
}, },
"node_modules/@babel/helper-create-class-features-plugin": { "node_modules/@babel/helper-create-class-features-plugin": {
"version": "7.23.6", "version": "7.23.7",
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.6.tgz", "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.7.tgz",
"integrity": "sha512-cBXU1vZni/CpGF29iTu4YRbOZt3Wat6zCoMDxRF1MayiEc4URxOj31tT65HUM0CRpMowA3HCJaAOVOUnMf96cw==", "integrity": "sha512-xCoqR/8+BoNnXOY7RVSgv6X+o7pmT5q1d+gGcRlXYkI+9B31glE4jeejhKVpA04O1AtzOt7OSQ6VYKP5FcRl9g==",
"dependencies": { "dependencies": {
"@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-annotate-as-pure": "^7.22.5",
"@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-environment-visitor": "^7.22.20",
@ -403,12 +403,12 @@
} }
}, },
"node_modules/@babel/helpers": { "node_modules/@babel/helpers": {
"version": "7.23.6", "version": "7.23.7",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.6.tgz", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.7.tgz",
"integrity": "sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA==", "integrity": "sha512-6AMnjCoC8wjqBzDHkuqpa7jAKwvMo4dC+lr/TFBz+ucfulO1XMpDnwWPGBNwClOKZ8h6xn5N81W/R5OrcKtCbQ==",
"dependencies": { "dependencies": {
"@babel/template": "^7.22.15", "@babel/template": "^7.22.15",
"@babel/traverse": "^7.23.6", "@babel/traverse": "^7.23.7",
"@babel/types": "^7.23.6" "@babel/types": "^7.23.6"
}, },
"engines": { "engines": {
@ -470,9 +470,9 @@
} }
}, },
"node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": {
"version": "7.23.3", "version": "7.23.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.3.tgz", "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.7.tgz",
"integrity": "sha512-XaJak1qcityzrX0/IU5nKHb34VaibwP3saKqG6a/tppelgllOH13LUann4ZCIBcVOeE6H18K4Vx9QKkVww3z/w==", "integrity": "sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==",
"dependencies": { "dependencies": {
"@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-environment-visitor": "^7.22.20",
"@babel/helper-plugin-utils": "^7.22.5" "@babel/helper-plugin-utils": "^7.22.5"
@ -519,15 +519,12 @@
} }
}, },
"node_modules/@babel/plugin-proposal-decorators": { "node_modules/@babel/plugin-proposal-decorators": {
"version": "7.23.6", "version": "7.23.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.23.6.tgz", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.23.7.tgz",
"integrity": "sha512-D7Ccq9LfkBFnow3azZGJvZYgcfeqAw3I1e5LoTpj6UKIFQilh8yqXsIGcRIqbBdsPWIz+Ze7ZZfggSj62Qp+Fg==", "integrity": "sha512-b1s5JyeMvqj7d9m9KhJNHKc18gEJiSyVzVX3bwbiPalQBQpuvfPh6lA9F7Kk/dWH0TIiXRpB9yicwijY6buPng==",
"dependencies": { "dependencies": {
"@babel/helper-create-class-features-plugin": "^7.23.6", "@babel/helper-create-class-features-plugin": "^7.23.7",
"@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5",
"@babel/helper-replace-supers": "^7.22.20",
"@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
"@babel/helper-split-export-declaration": "^7.22.6",
"@babel/plugin-syntax-decorators": "^7.23.3" "@babel/plugin-syntax-decorators": "^7.23.3"
}, },
"engines": { "engines": {
@ -977,9 +974,9 @@
} }
}, },
"node_modules/@babel/plugin-transform-async-generator-functions": { "node_modules/@babel/plugin-transform-async-generator-functions": {
"version": "7.23.4", "version": "7.23.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.4.tgz", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.7.tgz",
"integrity": "sha512-efdkfPhHYTtn0G6n2ddrESE91fgXxjlqLsnUtPWnJs4a4mZIbUaK7ffqKIIUKXSHwcDvaCVX6GXkaJJFqtX7jw==", "integrity": "sha512-PdxEpL71bJp1byMG0va5gwQcXHxuEYC/BgI/e88mGTtohbZN28O5Yit0Plkkm/dBzCF/BxmbNcses1RH1T+urA==",
"dependencies": { "dependencies": {
"@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-environment-visitor": "^7.22.20",
"@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5",
@ -1647,15 +1644,15 @@
} }
}, },
"node_modules/@babel/plugin-transform-runtime": { "node_modules/@babel/plugin-transform-runtime": {
"version": "7.23.6", "version": "7.23.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.6.tgz", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.7.tgz",
"integrity": "sha512-kF1Zg62aPseQ11orDhFRw+aPG/eynNQtI+TyY+m33qJa2cJ5EEvza2P2BNTIA9E5MyqFABHEyY6CPHwgdy9aNg==", "integrity": "sha512-fa0hnfmiXc9fq/weK34MUV0drz2pOL/vfKWvN7Qw127hiUPabFCUMgAbYWcchRzMJit4o5ARsK/s+5h0249pLw==",
"dependencies": { "dependencies": {
"@babel/helper-module-imports": "^7.22.15", "@babel/helper-module-imports": "^7.22.15",
"@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5",
"babel-plugin-polyfill-corejs2": "^0.4.6", "babel-plugin-polyfill-corejs2": "^0.4.7",
"babel-plugin-polyfill-corejs3": "^0.8.5", "babel-plugin-polyfill-corejs3": "^0.8.7",
"babel-plugin-polyfill-regenerator": "^0.5.3", "babel-plugin-polyfill-regenerator": "^0.5.4",
"semver": "^6.3.1" "semver": "^6.3.1"
}, },
"engines": { "engines": {
@ -1813,9 +1810,9 @@
} }
}, },
"node_modules/@babel/preset-env": { "node_modules/@babel/preset-env": {
"version": "7.23.6", "version": "7.23.7",
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.6.tgz", "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.7.tgz",
"integrity": "sha512-2XPn/BqKkZCpzYhUUNZ1ssXw7DcXfKQEjv/uXZUXgaebCMYmkEsfZ2yY+vv+xtXv50WmL5SGhyB6/xsWxIvvOQ==", "integrity": "sha512-SY27X/GtTz/L4UryMNJ6p4fH4nsgWbz84y9FE0bQeWJP6O5BhgVCt53CotQKHCOeXJel8VyhlhujhlltKms/CA==",
"dependencies": { "dependencies": {
"@babel/compat-data": "^7.23.5", "@babel/compat-data": "^7.23.5",
"@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-compilation-targets": "^7.23.6",
@ -1823,7 +1820,7 @@
"@babel/helper-validator-option": "^7.23.5", "@babel/helper-validator-option": "^7.23.5",
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3",
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3",
"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.3", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.7",
"@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2",
"@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-async-generators": "^7.8.4",
"@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-properties": "^7.12.13",
@ -1844,7 +1841,7 @@
"@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5",
"@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
"@babel/plugin-transform-arrow-functions": "^7.23.3", "@babel/plugin-transform-arrow-functions": "^7.23.3",
"@babel/plugin-transform-async-generator-functions": "^7.23.4", "@babel/plugin-transform-async-generator-functions": "^7.23.7",
"@babel/plugin-transform-async-to-generator": "^7.23.3", "@babel/plugin-transform-async-to-generator": "^7.23.3",
"@babel/plugin-transform-block-scoped-functions": "^7.23.3", "@babel/plugin-transform-block-scoped-functions": "^7.23.3",
"@babel/plugin-transform-block-scoping": "^7.23.4", "@babel/plugin-transform-block-scoping": "^7.23.4",
@ -1892,9 +1889,9 @@
"@babel/plugin-transform-unicode-regex": "^7.23.3", "@babel/plugin-transform-unicode-regex": "^7.23.3",
"@babel/plugin-transform-unicode-sets-regex": "^7.23.3", "@babel/plugin-transform-unicode-sets-regex": "^7.23.3",
"@babel/preset-modules": "0.1.6-no-external-plugins", "@babel/preset-modules": "0.1.6-no-external-plugins",
"babel-plugin-polyfill-corejs2": "^0.4.6", "babel-plugin-polyfill-corejs2": "^0.4.7",
"babel-plugin-polyfill-corejs3": "^0.8.5", "babel-plugin-polyfill-corejs3": "^0.8.7",
"babel-plugin-polyfill-regenerator": "^0.5.3", "babel-plugin-polyfill-regenerator": "^0.5.4",
"core-js-compat": "^3.31.0", "core-js-compat": "^3.31.0",
"semver": "^6.3.1" "semver": "^6.3.1"
}, },
@ -1953,14 +1950,14 @@
} }
}, },
"node_modules/@babel/register": { "node_modules/@babel/register": {
"version": "7.22.15", "version": "7.23.7",
"resolved": "https://registry.npmjs.org/@babel/register/-/register-7.22.15.tgz", "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.23.7.tgz",
"integrity": "sha512-V3Q3EqoQdn65RCgTLwauZaTfd1ShhwPmbBv+1dkZV/HpCGMKVyn6oFcRlI7RaKqiDQjX2Qd3AuoEguBgdjIKlg==", "integrity": "sha512-EjJeB6+kvpk+Y5DAkEAmbOBEFkh9OASx0huoEkqYTFxAZHzOAX2Oh5uwAUuL2rUddqfM0SA+KPXV2TbzoZ2kvQ==",
"dependencies": { "dependencies": {
"clone-deep": "^4.0.1", "clone-deep": "^4.0.1",
"find-cache-dir": "^2.0.0", "find-cache-dir": "^2.0.0",
"make-dir": "^2.1.0", "make-dir": "^2.1.0",
"pirates": "^4.0.5", "pirates": "^4.0.6",
"source-map-support": "^0.5.16" "source-map-support": "^0.5.16"
}, },
"engines": { "engines": {
@ -2005,9 +2002,9 @@
"integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA=="
}, },
"node_modules/@babel/runtime": { "node_modules/@babel/runtime": {
"version": "7.23.6", "version": "7.23.7",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.6.tgz", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.7.tgz",
"integrity": "sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==", "integrity": "sha512-w06OXVOFso7LcbzMiDGt+3X7Rh7Ho8MmgPoWU3rarH+8upf+wSU/grlGbWzQyr3DkdN6ZeuMFjpdwW0Q+HxobA==",
"dependencies": { "dependencies": {
"regenerator-runtime": "^0.14.0" "regenerator-runtime": "^0.14.0"
}, },
@ -2029,9 +2026,9 @@
} }
}, },
"node_modules/@babel/traverse": { "node_modules/@babel/traverse": {
"version": "7.23.6", "version": "7.23.7",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz",
"integrity": "sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==", "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==",
"dependencies": { "dependencies": {
"@babel/code-frame": "^7.23.5", "@babel/code-frame": "^7.23.5",
"@babel/generator": "^7.23.6", "@babel/generator": "^7.23.6",
@ -3365,6 +3362,95 @@
"@hapi/hoek": "^9.0.0" "@hapi/hoek": "^9.0.0"
} }
}, },
"node_modules/@isaacs/cliui": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
"integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
"dependencies": {
"string-width": "^5.1.2",
"string-width-cjs": "npm:string-width@^4.2.0",
"strip-ansi": "^7.0.1",
"strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
"wrap-ansi": "^8.1.0",
"wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/@isaacs/cliui/node_modules/ansi-regex": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
"integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
}
},
"node_modules/@isaacs/cliui/node_modules/ansi-styles": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/@isaacs/cliui/node_modules/emoji-regex": {
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
},
"node_modules/@isaacs/cliui/node_modules/string-width": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
"dependencies": {
"eastasianwidth": "^0.2.0",
"emoji-regex": "^9.2.2",
"strip-ansi": "^7.0.1"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@isaacs/cliui/node_modules/strip-ansi": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
"dependencies": {
"ansi-regex": "^6.0.1"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
"node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
"dependencies": {
"ansi-styles": "^6.1.0",
"string-width": "^5.0.1",
"strip-ansi": "^7.0.1"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
"node_modules/@istanbuljs/load-nyc-config": { "node_modules/@istanbuljs/load-nyc-config": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
@ -4277,6 +4363,15 @@
"url": "https://github.com/sponsors/isaacs" "url": "https://github.com/sponsors/isaacs"
} }
}, },
"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==",
"optional": true,
"engines": {
"node": ">=14"
}
},
"node_modules/@radix-ui/react-compose-refs": { "node_modules/@radix-ui/react-compose-refs": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.0.tgz", "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.0.tgz",
@ -6512,9 +6607,9 @@
} }
}, },
"node_modules/@types/babel__traverse": { "node_modules/@types/babel__traverse": {
"version": "7.20.4", "version": "7.20.5",
"resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz", "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz",
"integrity": "sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==", "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@babel/types": "^7.20.7" "@babel/types": "^7.20.7"
@ -6572,9 +6667,9 @@
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "20.10.5", "version": "20.10.7",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.7.tgz",
"integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==", "integrity": "sha512-fRbIKb8C/Y2lXxB5eVMj4IU7xpdox0Lh8bUPEdtLysaylsml1hOOx1+STloRs/B9nf7C6kPRmmg/V7aQW7usNg==",
"dependencies": { "dependencies": {
"undici-types": "~5.26.4" "undici-types": "~5.26.4"
} }
@ -6586,14 +6681,14 @@
"dev": true "dev": true
}, },
"node_modules/@types/qs": { "node_modules/@types/qs": {
"version": "6.9.10", "version": "6.9.11",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz",
"integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==" "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ=="
}, },
"node_modules/@types/react": { "node_modules/@types/react": {
"version": "18.2.45", "version": "18.2.47",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.45.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.47.tgz",
"integrity": "sha512-TtAxCNrlrBp8GoeEp1npd5g+d/OejJHFxS3OWmrPBMFaVQMSN0OFySozJio5BHxTuTeug00AVXVAjfDSfk+lUg==", "integrity": "sha512-xquNkkOirwyCgoClNk85BjP+aqnIS+ckAJ8i37gAbDs14jfW/J23f2GItAf33oiUPQnqNMALiFeoM9Y5mbjpVQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@types/prop-types": "*", "@types/prop-types": "*",
@ -6700,9 +6795,9 @@
} }
}, },
"node_modules/acorn": { "node_modules/acorn": {
"version": "8.11.2", "version": "8.11.3",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
"integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
"bin": { "bin": {
"acorn": "bin/acorn" "acorn": "bin/acorn"
}, },
@ -7685,9 +7780,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001570", "version": "1.0.30001576",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001576.tgz",
"integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", "integrity": "sha512-ff5BdakGe2P3SQsMsiqmt1Lc8221NR1VzHj5jXN5vBny9A6fpze94HiVV/n7XRosOlsShJcvMv5mdnpjOGCEgg==",
"funding": [ "funding": [
{ {
"type": "opencollective", "type": "opencollective",
@ -8052,9 +8147,9 @@
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="
}, },
"node_modules/core-js-compat": { "node_modules/core-js-compat": {
"version": "3.34.0", "version": "3.35.0",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.34.0.tgz", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.35.0.tgz",
"integrity": "sha512-4ZIyeNbW/Cn1wkMMDy+mvrRUxrwFNjKwbhCfQpDd+eLgYipDqp8oGFGtLmhh18EDPKA0g3VUBYOxQGGwvWLVpA==", "integrity": "sha512-5blwFAddknKeNgsjBzilkdQ0+YK8L1PfqPYq40NOYMYFSS38qj+hpTcLLWwpIwA2A5bje/x5jmVn2tzUMg9IVw==",
"dependencies": { "dependencies": {
"browserslist": "^4.22.2" "browserslist": "^4.22.2"
}, },
@ -8654,15 +8749,20 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
},
"node_modules/ee-first": { "node_modules/ee-first": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.4.615", "version": "1.4.623",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.615.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.623.tgz",
"integrity": "sha512-/bKPPcgZVUziECqDc+0HkT87+0zhaWSZHNXqF8FLd2lQcptpmUFwoCSWjCdOng9Gdq+afKArPdEg/0ZW461Eng==" "integrity": "sha512-lKoz10iCYlP1WtRYdh5MvocQPWVRoI7ysp6qf18bmeBgR8abE6+I2CsfyNKztRDZvhdWc+krKT6wS7Neg8sw3A=="
}, },
"node_modules/emittery": { "node_modules/emittery": {
"version": "0.13.1", "version": "0.13.1",
@ -9552,6 +9652,86 @@
"resolved": "https://registry.npmjs.org/fontfaceobserver/-/fontfaceobserver-2.3.0.tgz", "resolved": "https://registry.npmjs.org/fontfaceobserver/-/fontfaceobserver-2.3.0.tgz",
"integrity": "sha512-6FPvD/IVyT4ZlNe7Wcn5Fb/4ChigpucKYSvD6a+0iMoLn2inpo711eyIcKjmDtE5XNcgAkSH9uN/nfAeZzHEfg==" "integrity": "sha512-6FPvD/IVyT4ZlNe7Wcn5Fb/4ChigpucKYSvD6a+0iMoLn2inpo711eyIcKjmDtE5XNcgAkSH9uN/nfAeZzHEfg=="
}, },
"node_modules/foreground-child": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
"integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==",
"dependencies": {
"cross-spawn": "^7.0.0",
"signal-exit": "^4.0.1"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/foreground-child/node_modules/cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
"which": "^2.0.1"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/foreground-child/node_modules/path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"engines": {
"node": ">=8"
}
},
"node_modules/foreground-child/node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dependencies": {
"shebang-regex": "^3.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/foreground-child/node_modules/shebang-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"engines": {
"node": ">=8"
}
},
"node_modules/foreground-child/node_modules/signal-exit": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/foreground-child/node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dependencies": {
"isexe": "^2.0.0"
},
"bin": {
"node-which": "bin/node-which"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/form-data": { "node_modules/form-data": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
@ -10030,9 +10210,9 @@
} }
}, },
"node_modules/image-size": { "node_modules/image-size": {
"version": "1.0.2", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/image-size/-/image-size-1.0.2.tgz", "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz",
"integrity": "sha512-xfOoWjceHntRb3qFCrh5ZFORYH8XCdYpASltMhZ/Q0KZiOwjdE/Yl2QCiWdwD+lygV5bMCvauzgu5PxBX/Yerg==", "integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==",
"dependencies": { "dependencies": {
"queue": "6.0.2" "queue": "6.0.2"
}, },
@ -10040,7 +10220,7 @@
"image-size": "bin/image-size.js" "image-size": "bin/image-size.js"
}, },
"engines": { "engines": {
"node": ">=14.0.0" "node": ">=16.x"
} }
}, },
"node_modules/immediate": { "node_modules/immediate": {
@ -10522,6 +10702,23 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/jackspeak": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz",
"integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==",
"dependencies": {
"@isaacs/cliui": "^8.0.2"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
},
"optionalDependencies": {
"@pkgjs/parseargs": "^0.11.0"
}
},
"node_modules/jest": { "node_modules/jest": {
"version": "29.7.0", "version": "29.7.0",
"resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz",
@ -14506,9 +14703,9 @@
} }
}, },
"node_modules/moment": { "node_modules/moment": {
"version": "2.29.4", "version": "2.30.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
"optional": true, "optional": true,
"engines": { "engines": {
"node": "*" "node": "*"
@ -15160,6 +15357,37 @@
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
}, },
"node_modules/path-scurry": {
"version": "1.10.1",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz",
"integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==",
"dependencies": {
"lru-cache": "^9.1.1 || ^10.0.0",
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/path-scurry/node_modules/lru-cache": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz",
"integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==",
"engines": {
"node": "14 || >=16.14"
}
},
"node_modules/path-scurry/node_modules/minipass": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz",
"integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==",
"engines": {
"node": ">=16 || 14 >=14.17"
}
},
"node_modules/path-type": { "node_modules/path-type": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
@ -15382,9 +15610,9 @@
"integrity": "sha512-3ojrFwjnnw8Q9242TzgXuTD+eKiutbzyslcq1ydfu82Db2y+Ogbmyrkpv0Hgj31qwT3lbS9+QAAO/pIQM35XRw==" "integrity": "sha512-3ojrFwjnnw8Q9242TzgXuTD+eKiutbzyslcq1ydfu82Db2y+Ogbmyrkpv0Hgj31qwT3lbS9+QAAO/pIQM35XRw=="
}, },
"node_modules/postcss": { "node_modules/postcss": {
"version": "8.4.32", "version": "8.4.33",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz",
"integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==", "integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==",
"funding": [ "funding": [
{ {
"type": "opencollective", "type": "opencollective",
@ -16006,9 +16234,9 @@
} }
}, },
"node_modules/react-native-web": { "node_modules/react-native-web": {
"version": "0.19.9", "version": "0.19.10",
"resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.19.9.tgz", "resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.19.10.tgz",
"integrity": "sha512-m69arZbS6FV+BNSKE6R/NQwUX+CzxCkYM7AJlSLlS8dz3BDzlaxG8Bzqtzv/r3r1YFowhnZLBXVKIwovKDw49g==", "integrity": "sha512-IQoHiTQq8egBCVVwmTrYcFLgEFyb4LMZYEktHn4k22JMk9+QTCEz5WTfvr+jdNoeqj/7rtE81xgowKbfGO74qg==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.18.6", "@babel/runtime": "^7.18.6",
"@react-native/normalize-color": "^2.1.0", "@react-native/normalize-color": "^2.1.0",
@ -16887,6 +17115,28 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/string-width-cjs": {
"name": "string-width",
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/string-width-cjs/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",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"engines": {
"node": ">=8"
}
},
"node_modules/string-width/node_modules/is-fullwidth-code-point": { "node_modules/string-width/node_modules/is-fullwidth-code-point": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
@ -16906,6 +17156,18 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/strip-ansi-cjs": {
"name": "strip-ansi",
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dependencies": {
"ansi-regex": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/strip-bom": { "node_modules/strip-bom": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
@ -16959,13 +17221,13 @@
"integrity": "sha512-3ZUifmCDCQanjeej1f6kyl/BeP/Vae5EYkQ9iJfUm/QwZvlgnZzyflqAsAWYURdtea8Vkvswu2GrC57h3qffcA==" "integrity": "sha512-3ZUifmCDCQanjeej1f6kyl/BeP/Vae5EYkQ9iJfUm/QwZvlgnZzyflqAsAWYURdtea8Vkvswu2GrC57h3qffcA=="
}, },
"node_modules/sucrase": { "node_modules/sucrase": {
"version": "3.34.0", "version": "3.35.0",
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
"integrity": "sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==", "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
"dependencies": { "dependencies": {
"@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/gen-mapping": "^0.3.2",
"commander": "^4.0.0", "commander": "^4.0.0",
"glob": "7.1.6", "glob": "^10.3.10",
"lines-and-columns": "^1.1.6", "lines-and-columns": "^1.1.6",
"mz": "^2.7.0", "mz": "^2.7.0",
"pirates": "^4.0.1", "pirates": "^4.0.1",
@ -16976,7 +17238,15 @@
"sucrase-node": "bin/sucrase-node" "sucrase-node": "bin/sucrase-node"
}, },
"engines": { "engines": {
"node": ">=8" "node": ">=16 || 14 >=14.17"
}
},
"node_modules/sucrase/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dependencies": {
"balanced-match": "^1.0.0"
} }
}, },
"node_modules/sucrase/node_modules/commander": { "node_modules/sucrase/node_modules/commander": {
@ -16987,6 +17257,49 @@
"node": ">= 6" "node": ">= 6"
} }
}, },
"node_modules/sucrase/node_modules/glob": {
"version": "10.3.10",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz",
"integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==",
"dependencies": {
"foreground-child": "^3.1.0",
"jackspeak": "^2.3.5",
"minimatch": "^9.0.1",
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0",
"path-scurry": "^1.10.1"
},
"bin": {
"glob": "dist/esm/bin.mjs"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/sucrase/node_modules/minimatch": {
"version": "9.0.3",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
"integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/sucrase/node_modules/minipass": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz",
"integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==",
"engines": {
"node": ">=16 || 14 >=14.17"
}
},
"node_modules/sudo-prompt": { "node_modules/sudo-prompt": {
"version": "8.2.5", "version": "8.2.5",
"resolved": "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-8.2.5.tgz", "resolved": "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-8.2.5.tgz",
@ -17349,9 +17662,12 @@
} }
}, },
"node_modules/traverse": { "node_modules/traverse": {
"version": "0.6.7", "version": "0.6.8",
"resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.8.tgz",
"integrity": "sha512-/y956gpUo9ZNCb99YjxG7OaslxZWHfCHAUUfshwqOXmxUIvqLjVO581BT+gM59+QV9tFe6/CGG53tsA1Y7RSdg==", "integrity": "sha512-aXJDbk6SnumuaZSANd21XAo15ucCDE38H4fkqiGsc3MhCK+wOlZvLP9cB/TvpHT0mOyWgC4Z8EwRlzqYSUzdsA==",
"engines": {
"node": ">= 0.4"
},
"funding": { "funding": {
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
@ -17829,6 +18145,53 @@
"url": "https://github.com/chalk/wrap-ansi?sponsor=1" "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
} }
}, },
"node_modules/wrap-ansi-cjs": {
"name": "wrap-ansi",
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
"node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/wrap-ansi-cjs/node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/wrap-ansi-cjs/node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/wrap-ansi/node_modules/ansi-styles": { "node_modules/wrap-ansi/node_modules/ansi-styles": {
"version": "4.3.0", "version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
@ -17875,9 +18238,9 @@
} }
}, },
"node_modules/ws": { "node_modules/ws": {
"version": "8.15.1", "version": "8.16.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.15.1.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz",
"integrity": "sha512-W5OZiCjXEmk0yZ66ZN82beM5Sz7l7coYxpRkzS+p9PP+ToQry8szKh+61eNktr7EA9DOwvFGhfC605jDHbP6QQ==", "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==",
"engines": { "engines": {
"node": ">=10.0.0" "node": ">=10.0.0"
}, },

View file

@ -38,7 +38,7 @@
"react-native-calendars": "^1.1303.0", "react-native-calendars": "^1.1303.0",
"react-native-chart-kit": "^6.12.0", "react-native-chart-kit": "^6.12.0",
"react-native-gesture-handler": "~2.12.0", "react-native-gesture-handler": "~2.12.0",
"react-native-reanimated": "^3.3.0", "react-native-reanimated": "~3.3.0",
"react-native-safe-area-context": "4.6.3", "react-native-safe-area-context": "4.6.3",
"react-native-screens": "~3.22.0", "react-native-screens": "~3.22.0",
"react-native-uuid": "^2.0.1", "react-native-uuid": "^2.0.1",

View file

@ -2,6 +2,7 @@ import React from 'react';
import { View, Button, Alert } from 'react-native'; import { View, Button, Alert } from 'react-native';
import { addCategory, addExpense, deleteExpenses, deleteCategories, DEV_populateDatabase, deleteDatabase } from './database'; import { addCategory, addExpense, deleteExpenses, deleteCategories, DEV_populateDatabase, deleteDatabase } from './database';
import uuid from 'react-native-uuid'; import uuid from 'react-native-uuid';
import { CategoryType } from '../types/dbItems';
const randomColors = ["red", "blue", "green", "purple", "yellow"]; const randomColors = ["red", "blue", "green", "purple", "yellow"];
@ -46,7 +47,7 @@ const DebugMenu = () => {
const allocated_amount = getRandomNumber(); const allocated_amount = getRandomNumber();
const type = "expense"; const type = "expense";
addCategory(name, color, type, allocated_amount) addCategory(name, color, CategoryType.EXPENSE, allocated_amount)
.then(() => Alert.alert("Category Added", `Name: ${name}, Color: ${color}`)) .then(() => Alert.alert("Category Added", `Name: ${name}, Color: ${color}`))
.catch((error: any) => console.error("Error adding category: ", error)); .catch((error: any) => console.error("Error adding category: ", error));
}; };

View file

@ -4,15 +4,18 @@ import uuid from "react-native-uuid";
import { Query } from "expo-sqlite"; import { Query } from "expo-sqlite";
import { SimpleDate } from "../util/SimpleDate"; import { SimpleDate } from "../util/SimpleDate";
import { CategoryType } from "../types/dbItems";
let db: SQLite.SQLiteDatabase; let db: SQLite.SQLiteDatabase;
export const initDatabase = async () => { export const initDatabase = async () => {
db = SQLite.openDatabase("interactive_systeme.db"); db = SQLite.openDatabase("interactive_systeme.db");
try { try {
await db.transactionAsync(async (tx: SQLite.SQLTransactionAsync) => { await db.transactionAsync(async (tx: SQLite.SQLTransactionAsync) => {
await tx.executeSqlAsync( await tx.executeSqlAsync(
"CREATE TABLE IF NOT EXISTS category (guid VARCHAR(36) PRIMARY KEY, name TEXT, color TEXT, type TEXT, allocated_amount DOUBLE);" "CREATE TABLE IF NOT EXISTS category (guid VARCHAR(36) PRIMARY KEY, name TEXT, color TEXT, type string, allocated_amount DOUBLE);"
); );
await tx.executeSqlAsync( await tx.executeSqlAsync(
"CREATE TABLE IF NOT EXISTS expense (guid VARCHAR(36) PRIMARY KEY, name TEXT, category_guid VARCHAR(36), datetime DATETIME, amount DOUBLE, FOREIGN KEY (category_guid) REFERENCES category(guid));" "CREATE TABLE IF NOT EXISTS expense (guid VARCHAR(36) PRIMARY KEY, name TEXT, category_guid VARCHAR(36), datetime DATETIME, amount DOUBLE, FOREIGN KEY (category_guid) REFERENCES category(guid));"
@ -24,11 +27,11 @@ export const initDatabase = async () => {
} }
}; };
export const updateCategory = async (guid: string, name: string, color: string, type: string, allocated_amount: number) => { export const updateCategory = async (guid: string, name: string, color: string, CategoryType: CategoryType, allocated_amount: number) => {
try { try {
await db.transactionAsync(async (tx) => { await db.transactionAsync(async (tx) => {
await tx.executeSqlAsync("UPDATE category SET name = ?, color = ?, type = ?, allocated_amount = ? WHERE guid = ?", [name, color, type, allocated_amount, guid]); await tx.executeSqlAsync("UPDATE category SET name = ?, color = ?, type = ?, allocated_amount = ? WHERE guid = ?", [name, color, CategoryType, allocated_amount, guid]);
}); });
} catch (error) { } catch (error) {
console.log("Error updating category: ", error); console.log("Error updating category: ", error);
@ -36,7 +39,7 @@ export const updateCategory = async (guid: string, name: string, color: string,
} }
}; };
export const addCategory = async (name: string, color: string, type: string, allocated_amount: number) => { export const addCategory = async (name: string, color: string, CategoryType: CategoryType, allocated_amount: number) => {
//needs user input validation for type and color (should be validated by this function) //needs user input validation for type and color (should be validated by this function)
@ -45,7 +48,7 @@ export const addCategory = async (name: string, color: string, type: string, all
try { try {
await db.transactionAsync(async (tx) => { await db.transactionAsync(async (tx) => {
await tx.executeSqlAsync("INSERT INTO category (guid, name, color, type, allocated_amount) VALUES (?, ?, ?, ?, ?);", await tx.executeSqlAsync("INSERT INTO category (guid, name, color, type, allocated_amount) VALUES (?, ?, ?, ?, ?);",
[UUID.toString(), name, color, type, allocated_amount] [UUID.toString(), name, color, CategoryType, allocated_amount]
); );
}); });
} catch (error) { } catch (error) {
@ -171,8 +174,9 @@ export const DEV_populateDatabase = async () => {
for(let i=0; i < 5; i++){ for(let i=0; i < 5; i++){
let random = Math.floor(Math.random() * colors.length); let random = Math.floor(Math.random() * colors.length);
await addCategory(`Category ${i}`, colors[random], "budget", 50) await addCategory(`Category ${i}`, colors[random], CategoryType.EXPENSE, 50)
await addCategory(`Category ${i+6}`, colors[random], "budget", 50) random = Math.floor(Math.random() * colors.length);
await addCategory(`Category ${i+6}`, colors[random], CategoryType.SAVING, 50)
} }
const result = await executeQuery({sql:"SELECT * from category", args:[]}) const result = await executeQuery({sql:"SELECT * from category", args:[]})
let categories: {[column: string]: any}[]; let categories: {[column: string]: any}[];

View file

@ -1,3 +1,7 @@
export enum CategoryType {
SAVING = "saving",
EXPENSE = "expense",
}
export interface Category { export interface Category {
guid? : string; guid? : string;
name? : string; name? : string;