diff options
99 files changed, 6172 insertions, 0 deletions
diff --git a/.DS_Store b/.DS_Store Binary files differnew file mode 100644 index 0000000..60c030b --- /dev/null +++ b/.DS_Store diff --git a/.expo/README.md b/.expo/README.md new file mode 100644 index 0000000..563b815 --- /dev/null +++ b/.expo/README.md @@ -0,0 +1,14 @@ +> Why do I have a folder named ".expo" in my project? + +The ".expo" folder is created when an Expo project is started using "expo start" command. + +> What do the files contain? + +- "devices.json": contains information about devices that have recently opened this project. This is used to populate the "Development sessions" list in your development builds. +- "settings.json": contains the server configuration that is used to serve the application manifest. +- "dev/logs/": contains structured JSONL event logs from CLI commands (e.g. start.log, export.log). These are truncated on each run. + +> Should I commit the ".expo" folder? + +No, you should not share the ".expo" folder. It does not contain any information that is relevant for other developers working on the project, it is specific to your machine. +Upon project creation, the ".expo" folder is already added to your ".gitignore" file. diff --git a/.expo/dev/logs/start.log b/.expo/dev/logs/start.log new file mode 100644 index 0000000..a7b78f4 --- /dev/null +++ b/.expo/dev/logs/start.log @@ -0,0 +1,425 @@ +{"_e":"root:init","_t":1786664384002,"format":"v0-jsonl","version":"57.0.14"} +{"_e":"devserver:start","_t":1786664384064,"mode":"development","web":true,"baseUrl":"","asyncRoutes":false,"routerRoot":"../../../src/app","serverComponents":false,"serverActions":false,"serverRendering":true,"apiRoutes":false,"exporting":false} +{"_e":"metro:config","_t":1786664384333,"serverRoot":"../../..","projectRoot":"../../..","exporting":false,"flags":{"autolinkingModuleResolution":false,"serverActions":false,"serverComponents":false,"reactCompiler":true,"optimizeGraph":false,"treeshaking":false,"logbox":false}} +{"_e":"expo:dev-tools-plugin:load","_t":1786664384465,"plugins":[]} +{"_e":"metro:instantiate","_t":1786664384918,"atlas":false,"workers":4,"host":"::","port":8081} +{"_e":"metro:bundling:started","_t":1786664408833,"id":"1","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786664408833,"id":"1","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786664408837,"id":"1","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786664409163,"id":"1","progress":0.010000000000000002,"total":1,"current":1} +{"_e":"metro:bundling:progress","_t":1786664409265,"id":"1","progress":0.1322314049586777,"total":11,"current":4} +{"_e":"metro:bundling:progress","_t":1786664409346,"id":"1","progress":0.20661157024793386,"total":11,"current":5} +{"_e":"metro:bundling:progress","_t":1786664409448,"id":"1","progress":0.20661157024793386,"total":127,"current":9} +{"_e":"metro:bundling:progress","_t":1786664409550,"id":"1","progress":0.20661157024793386,"total":141,"current":15} +{"_e":"metro:bundling:progress","_t":1786664409650,"id":"1","progress":0.20661157024793386,"total":160,"current":38} +{"_e":"metro:bundling:progress","_t":1786664409751,"id":"1","progress":0.20661157024793386,"total":174,"current":49} +{"_e":"metro:bundling:progress","_t":1786664409851,"id":"1","progress":0.20661157024793386,"total":213,"current":77} +{"_e":"metro:bundling:progress","_t":1786664409952,"id":"1","progress":0.20661157024793386,"total":269,"current":114} +{"_e":"metro:bundling:progress","_t":1786664410054,"id":"1","progress":0.20786947644607867,"total":329,"current":150} +{"_e":"metro:bundling:progress","_t":1786664410154,"id":"1","progress":0.26234384295062463,"total":369,"current":189} +{"_e":"metro:bundling:progress","_t":1786664410255,"id":"1","progress":0.30978350729909493,"total":433,"current":241} +{"_e":"metro:bundling:progress","_t":1786664410355,"id":"1","progress":0.3770390889504463,"total":456,"current":280} +{"_e":"metro:bundling:progress","_t":1786664410455,"id":"1","progress":0.38727919099633445,"total":466,"current":290} +{"_e":"metro:bundling:progress","_t":1786664410557,"id":"1","progress":0.38727919099633445,"total":516,"current":312} +{"_e":"metro:bundling:progress","_t":1786664410659,"id":"1","progress":0.3895017079861291,"total":556,"current":347} +{"_e":"metro:bundling:progress","_t":1786664410758,"id":"1","progress":0.4587420149891857,"total":564,"current":382} +{"_e":"metro:bundling:progress","_t":1786664410860,"id":"1","progress":0.5694541345950145,"total":595,"current":449} +{"_e":"metro:bundling:progress","_t":1786664410960,"id":"1","progress":0.5694541345950145,"total":635,"current":472} +{"_e":"metro:bundling:progress","_t":1786664411060,"id":"1","progress":0.5694541345950145,"total":673,"current":499} +{"_e":"metro:bundling:progress","_t":1786664411160,"id":"1","progress":0.5694541345950145,"total":734,"current":537} +{"_e":"metro:bundling:progress","_t":1786664411261,"id":"1","progress":0.5694541345950145,"total":763,"current":572} +{"_e":"metro:bundling:progress","_t":1786664411362,"id":"1","progress":0.5873356140208807,"total":809,"current":620} +{"_e":"metro:bundling:progress","_t":1786664411463,"id":"1","progress":0.5873356140208807,"total":825,"current":630} +{"_e":"metro:bundling:progress","_t":1786664411564,"id":"1","progress":0.5873356140208807,"total":873,"current":663} +{"_e":"metro:bundling:progress","_t":1786664411665,"id":"1","progress":0.5873356140208807,"total":896,"current":685} +{"_e":"metro:bundling:progress","_t":1786664411765,"id":"1","progress":0.5873356140208807,"total":950,"current":718} +{"_e":"metro:bundling:progress","_t":1786664411866,"id":"1","progress":0.5873356140208807,"total":978,"current":745} +{"_e":"metro:bundling:progress","_t":1786664411970,"id":"1","progress":0.5992252141094498,"total":996,"current":771} +{"_e":"metro:bundling:progress","_t":1786664412072,"id":"1","progress":0.6141503970360315,"total":1017,"current":797} +{"_e":"metro:bundling:progress","_t":1786664412171,"id":"1","progress":0.6362518382194855,"total":1023,"current":816} +{"_e":"metro:bundling:progress","_t":1786664412293,"id":"1","progress":0.6531535588762611,"total":1027,"current":830} +{"_e":"metro:bundling:progress","_t":1786664412393,"id":"1","progress":0.6531535588762611,"total":1091,"current":853} +{"_e":"metro:bundling:progress","_t":1786664412493,"id":"1","progress":0.6534394873457454,"total":1101,"current":890} +{"_e":"metro:bundling:progress","_t":1786664412593,"id":"1","progress":0.6976985727375618,"total":1111,"current":928} +{"_e":"metro:bundling:progress","_t":1786664412694,"id":"1","progress":0.7246341902082449,"total":1116,"current":950} +{"_e":"metro:bundling:progress","_t":1786664412795,"id":"1","progress":0.7457295489486213,"total":1136,"current":981} +{"_e":"metro:bundling:progress","_t":1786664412896,"id":"1","progress":0.7680848377730085,"total":1157,"current":1014} +{"_e":"metro:bundling:progress","_t":1786664412998,"id":"1","progress":0.7751167051907102,"total":1179,"current":1038} +{"_e":"metro:bundling:progress","_t":1786664413098,"id":"1","progress":0.7751167051907102,"total":1198,"current":1048} +{"_e":"metro:bundling:progress","_t":1786664413198,"id":"1","progress":0.7751167051907102,"total":1223,"current":1057} +{"_e":"metro:bundling:progress","_t":1786664413306,"id":"1","progress":0.7751167051907102,"total":1224,"current":1060} +{"_e":"metro:bundling:progress","_t":1786664413405,"id":"1","progress":0.7751167051907102,"total":1271,"current":1095} +{"_e":"metro:bundling:progress","_t":1786664413506,"id":"1","progress":0.7816979845156236,"total":1286,"current":1137} +{"_e":"metro:bundling:progress","_t":1786664413606,"id":"1","progress":0.8322312266116275,"total":1288,"current":1175} +{"_e":"metro:bundling:progress","_t":1786664413706,"id":"1","progress":0.843456297584273,"total":1299,"current":1193} +{"_e":"metro:bundling:progress","_t":1786664413806,"id":"1","progress":0.845954335743401,"total":1321,"current":1215} +{"_e":"metro:bundling:progress","_t":1786664413907,"id":"1","progress":0.845954335743401,"total":1344,"current":1236} +{"_e":"metro:bundling:progress","_t":1786664414006,"id":"1","progress":0.845954335743401,"total":1386,"current":1264} +{"_e":"metro:bundling:progress","_t":1786664414107,"id":"1","progress":0.845954335743401,"total":1416,"current":1301} +{"_e":"metro:bundling:progress","_t":1786664414221,"id":"1","progress":0.8498936954496207,"total":1434,"current":1322} +{"_e":"metro:bundling:progress","_t":1786664414342,"id":"1","progress":0.8576258196537953,"total":1434,"current":1328} +{"_e":"metro:bundling:progress","_t":1786664414448,"id":"1","progress":0.8692896560712251,"total":1434,"current":1337} +{"_e":"metro:bundling:progress","_t":1786664414548,"id":"1","progress":0.8855058148858574,"total":1441,"current":1356} +{"_e":"metro:bundling:progress","_t":1786664414648,"id":"1","progress":0.9034025321769098,"total":1474,"current":1401} +{"_e":"metro:bundling:progress","_t":1786664414748,"id":"1","progress":0.9230044615496745,"total":1477,"current":1419} +{"_e":"metro:bundling:progress","_t":1786664414848,"id":"1","progress":0.9385569717588258,"total":1506,"current":1459} +{"_e":"metro:bundling:progress","_t":1786664414948,"id":"1","progress":0.9385569717588258,"total":1586,"current":1495} +{"_e":"metro:bundling:progress","_t":1786664415049,"id":"1","progress":0.9385569717588258,"total":1654,"current":1550} +{"_e":"metro:bundling:progress","_t":1786664415149,"id":"1","progress":0.9385569717588258,"total":1686,"current":1606} +{"_e":"metro:bundling:progress","_t":1786664415249,"id":"1","progress":0.9385569717588258,"total":1717,"current":1659} +{"_e":"metro:bundling:progress","_t":1786664415349,"id":"1","progress":0.9524686765626291,"total":1746,"current":1704} +{"_e":"metro:bundling:progress","_t":1786664415450,"id":"1","progress":0.9852984754451719,"total":1762,"current":1749} +{"_e":"metro:bundling:progress","_t":1786664415555,"id":"1","progress":0.999,"total":1764,"current":1764} +{"_e":"metro:bundling:done","_t":1786664415732,"id":"1","total":1764,"ms":6898.292666} +{"_e":"metro:bundling:started","_t":1786664592238,"id":"7","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786664592239,"id":"7","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786664592244,"id":"7","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786664592344,"id":"7","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786664592442,"id":"7","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786664592542,"id":"7","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:done","_t":1786664592659,"id":"7","total":1,"ms":420.139083} +{"_e":"metro:bundling:started","_t":1786664597650,"id":"8","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786664597650,"id":"8","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:done","_t":1786664597704,"id":"8","total":1,"ms":53.752208} +{"_e":"metro:client_log","_t":1786667131853,"level":"error","data":["[Error: Cannot find native module 'ExpoSecureStore']","\n\n\u001b[1mCode: AuthContext.tsx\u001b[22m\n\u001b[0m \u001b[90m 1 |\u001b[39m \u001b[36mimport\u001b[39m { \u001b[33mUser\u001b[39m } \u001b[36mfrom\u001b[39m \u001b[32m'@/types'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m 2 |\u001b[39m \u001b[36mimport\u001b[39m \u001b[33mReact\u001b[39m\u001b[33m,\u001b[39m { createContext\u001b[33m,\u001b[39m useContext\u001b[33m,\u001b[39m useEffect\u001b[33m,\u001b[39m useState } \u001b[36mfrom\u001b[39m \u001b[32m'react'\u001b[39m\u001b[33m;\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 3 |\u001b[39m \u001b[36mimport\u001b[39m \u001b[33m*\u001b[39m \u001b[36mas\u001b[39m \u001b[33mSecureStore\u001b[39m \u001b[36mfrom\u001b[39m \u001b[32m'expo-secure-store'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 4 |\u001b[39m \u001b[36mimport\u001b[39m \u001b[33m*\u001b[39m \u001b[36mas\u001b[39m \u001b[33mLocalAuthentication\u001b[39m \u001b[36mfrom\u001b[39m \u001b[32m'expo-local-authentication'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m 5 |\u001b[39m \u001b[36mimport\u001b[39m { setApiToken } \u001b[36mfrom\u001b[39m \u001b[32m'@/services/api'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m 6 |\u001b[39m\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m <global> (src/contexts/AuthContext.tsx:3)\u001b[39m\n\u001b[90m <global> (src/app/_layout.tsx:1)\u001b[39m"]} +{"_e":"metro:bundling:started","_t":1786667163530,"id":"d","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786667163530,"id":"d","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:done","_t":1786667163582,"id":"d","total":1,"ms":52.1765} +{"_e":"metro:client_log","_t":1786667165117,"level":"warn","data":["Route \"./_layout.tsx\" is missing the required default export. Ensure a React component is exported as default."]} +{"_e":"metro:client_log","_t":1786667165121,"level":"warn","data":["Route \"./_layout.tsx\" is missing the required default export. Ensure a React component is exported as default."]} +{"_e":"metro:client_log","_t":1786667165132,"level":"error","data":["[Error: Cannot find native module 'ExpoSecureStore']","\n\n\u001b[1mCode: AuthContext.tsx\u001b[22m\n\u001b[0m \u001b[90m 1 |\u001b[39m \u001b[36mimport\u001b[39m { \u001b[33mUser\u001b[39m } \u001b[36mfrom\u001b[39m \u001b[32m'@/types'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m 2 |\u001b[39m \u001b[36mimport\u001b[39m \u001b[33mReact\u001b[39m\u001b[33m,\u001b[39m { createContext\u001b[33m,\u001b[39m useContext\u001b[33m,\u001b[39m useEffect\u001b[33m,\u001b[39m useState } \u001b[36mfrom\u001b[39m \u001b[32m'react'\u001b[39m\u001b[33m;\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 3 |\u001b[39m \u001b[36mimport\u001b[39m \u001b[33m*\u001b[39m \u001b[36mas\u001b[39m \u001b[33mSecureStore\u001b[39m \u001b[36mfrom\u001b[39m \u001b[32m'expo-secure-store'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 4 |\u001b[39m \u001b[36mimport\u001b[39m \u001b[33m*\u001b[39m \u001b[36mas\u001b[39m \u001b[33mLocalAuthentication\u001b[39m \u001b[36mfrom\u001b[39m \u001b[32m'expo-local-authentication'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m 5 |\u001b[39m \u001b[36mimport\u001b[39m { setApiToken } \u001b[36mfrom\u001b[39m \u001b[32m'@/services/api'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m 6 |\u001b[39m\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m <global> (src/contexts/AuthContext.tsx:3)\u001b[39m\n\u001b[90m <global> (src/app/_layout.tsx:1)\u001b[39m","\n\n\u001b[1mCode: ExpoRoot.js\u001b[22m\n\u001b[0m \u001b[90m 83 |\u001b[39m initialMetrics\u001b[33m:\u001b[39m \u001b[33mINITIAL_METRICS\u001b[39m\u001b[33m,\u001b[39m children\u001b[33m:\u001b[39m children }) }) }))\u001b[33m;\u001b[39m\n \u001b[90m 84 |\u001b[39m }\u001b[33m,\u001b[39m [\u001b[33mParentWrapper\u001b[39m])\u001b[33m;\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 85 |\u001b[39m \u001b[36mreturn\u001b[39m (\u001b[35m0\u001b[39m\u001b[33m,\u001b[39m jsx_runtime_1\u001b[33m.\u001b[39mjsx)(\u001b[33mContextNavigator\u001b[39m\u001b[33m,\u001b[39m { \u001b[33m...\u001b[39mprops\u001b[33m,\u001b[39m wrapper\u001b[33m:\u001b[39m wrapper })\u001b[33m;\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 86 |\u001b[39m }\n \u001b[90m 87 |\u001b[39m \u001b[36mconst\u001b[39m initialUrl \u001b[33m=\u001b[39m react_native_1\u001b[33m.\u001b[39m\u001b[33mPlatform\u001b[39m\u001b[33m.\u001b[39m\u001b[33mOS\u001b[39m \u001b[33m===\u001b[39m \u001b[32m'web'\u001b[39m \u001b[33m&&\u001b[39m \u001b[36mtypeof\u001b[39m window \u001b[33m!==\u001b[39m \u001b[32m'undefined'\u001b[39m\n \u001b[90m 88 |\u001b[39m \u001b[33m?\u001b[39m \u001b[36mnew\u001b[39m \u001b[33mURL\u001b[39m(window\u001b[33m.\u001b[39mlocation\u001b[33m.\u001b[39mhref)\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[2m\u001b[90m ExpoRoot (node_modules/expo-router/build/ExpoRoot.js:85:33)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m App (node_modules/expo-router/build/qualified-entry.js:20:91)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m WithDevTools (node_modules/expo/src/launch/withDevTools.tsx:21:12)\u001b[39m\u001b[22m"]} +{"_e":"metro:client_log","_t":1786667165155,"level":"error","data":["[Error: Cannot find native module 'ExpoSecureStore']","\n\n\u001b[1mCode: AuthContext.tsx\u001b[22m\n\u001b[0m \u001b[90m 1 |\u001b[39m \u001b[36mimport\u001b[39m { \u001b[33mUser\u001b[39m } \u001b[36mfrom\u001b[39m \u001b[32m'@/types'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m 2 |\u001b[39m \u001b[36mimport\u001b[39m \u001b[33mReact\u001b[39m\u001b[33m,\u001b[39m { createContext\u001b[33m,\u001b[39m useContext\u001b[33m,\u001b[39m useEffect\u001b[33m,\u001b[39m useState } \u001b[36mfrom\u001b[39m \u001b[32m'react'\u001b[39m\u001b[33m;\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 3 |\u001b[39m \u001b[36mimport\u001b[39m \u001b[33m*\u001b[39m \u001b[36mas\u001b[39m \u001b[33mSecureStore\u001b[39m \u001b[36mfrom\u001b[39m \u001b[32m'expo-secure-store'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 4 |\u001b[39m \u001b[36mimport\u001b[39m \u001b[33m*\u001b[39m \u001b[36mas\u001b[39m \u001b[33mLocalAuthentication\u001b[39m \u001b[36mfrom\u001b[39m \u001b[32m'expo-local-authentication'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m 5 |\u001b[39m \u001b[36mimport\u001b[39m { setApiToken } \u001b[36mfrom\u001b[39m \u001b[32m'@/services/api'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m 6 |\u001b[39m\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m <global> (src/contexts/AuthContext.tsx:3)\u001b[39m\n\u001b[90m <global> (src/app/_layout.tsx:1)\u001b[39m","\n\n\u001b[1mCode: ExpoRoot.js\u001b[22m\n\u001b[0m \u001b[90m 83 |\u001b[39m initialMetrics\u001b[33m:\u001b[39m \u001b[33mINITIAL_METRICS\u001b[39m\u001b[33m,\u001b[39m children\u001b[33m:\u001b[39m children }) }) }))\u001b[33m;\u001b[39m\n \u001b[90m 84 |\u001b[39m }\u001b[33m,\u001b[39m [\u001b[33mParentWrapper\u001b[39m])\u001b[33m;\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 85 |\u001b[39m \u001b[36mreturn\u001b[39m (\u001b[35m0\u001b[39m\u001b[33m,\u001b[39m jsx_runtime_1\u001b[33m.\u001b[39mjsx)(\u001b[33mContextNavigator\u001b[39m\u001b[33m,\u001b[39m { \u001b[33m...\u001b[39mprops\u001b[33m,\u001b[39m wrapper\u001b[33m:\u001b[39m wrapper })\u001b[33m;\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 86 |\u001b[39m }\n \u001b[90m 87 |\u001b[39m \u001b[36mconst\u001b[39m initialUrl \u001b[33m=\u001b[39m react_native_1\u001b[33m.\u001b[39m\u001b[33mPlatform\u001b[39m\u001b[33m.\u001b[39m\u001b[33mOS\u001b[39m \u001b[33m===\u001b[39m \u001b[32m'web'\u001b[39m \u001b[33m&&\u001b[39m \u001b[36mtypeof\u001b[39m window \u001b[33m!==\u001b[39m \u001b[32m'undefined'\u001b[39m\n \u001b[90m 88 |\u001b[39m \u001b[33m?\u001b[39m \u001b[36mnew\u001b[39m \u001b[33mURL\u001b[39m(window\u001b[33m.\u001b[39mlocation\u001b[33m.\u001b[39mhref)\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[2m\u001b[90m ExpoRoot (node_modules/expo-router/build/ExpoRoot.js:85:33)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m App (node_modules/expo-router/build/qualified-entry.js:20:91)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m WithDevTools (node_modules/expo/src/launch/withDevTools.tsx:21:12)\u001b[39m\u001b[22m"]} +{"_e":"metro:client_log","_t":1786667165161,"level":"error","data":["[Error: Cannot find native module 'ExpoSecureStore']","\n\n\u001b[1mCode: AuthContext.tsx\u001b[22m\n\u001b[0m \u001b[90m 1 |\u001b[39m \u001b[36mimport\u001b[39m { \u001b[33mUser\u001b[39m } \u001b[36mfrom\u001b[39m \u001b[32m'@/types'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m 2 |\u001b[39m \u001b[36mimport\u001b[39m \u001b[33mReact\u001b[39m\u001b[33m,\u001b[39m { createContext\u001b[33m,\u001b[39m useContext\u001b[33m,\u001b[39m useEffect\u001b[33m,\u001b[39m useState } \u001b[36mfrom\u001b[39m \u001b[32m'react'\u001b[39m\u001b[33m;\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 3 |\u001b[39m \u001b[36mimport\u001b[39m \u001b[33m*\u001b[39m \u001b[36mas\u001b[39m \u001b[33mSecureStore\u001b[39m \u001b[36mfrom\u001b[39m \u001b[32m'expo-secure-store'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 4 |\u001b[39m \u001b[36mimport\u001b[39m \u001b[33m*\u001b[39m \u001b[36mas\u001b[39m \u001b[33mLocalAuthentication\u001b[39m \u001b[36mfrom\u001b[39m \u001b[32m'expo-local-authentication'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m 5 |\u001b[39m \u001b[36mimport\u001b[39m { setApiToken } \u001b[36mfrom\u001b[39m \u001b[32m'@/services/api'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m 6 |\u001b[39m\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m <global> (src/contexts/AuthContext.tsx:3)\u001b[39m\n\u001b[90m <global> (src/app/_layout.tsx:1)\u001b[39m","\n\n\u001b[1mCode: ExpoRoot.js\u001b[22m\n\u001b[0m \u001b[90m 83 |\u001b[39m initialMetrics\u001b[33m:\u001b[39m \u001b[33mINITIAL_METRICS\u001b[39m\u001b[33m,\u001b[39m children\u001b[33m:\u001b[39m children }) }) }))\u001b[33m;\u001b[39m\n \u001b[90m 84 |\u001b[39m }\u001b[33m,\u001b[39m [\u001b[33mParentWrapper\u001b[39m])\u001b[33m;\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 85 |\u001b[39m \u001b[36mreturn\u001b[39m (\u001b[35m0\u001b[39m\u001b[33m,\u001b[39m jsx_runtime_1\u001b[33m.\u001b[39mjsx)(\u001b[33mContextNavigator\u001b[39m\u001b[33m,\u001b[39m { \u001b[33m...\u001b[39mprops\u001b[33m,\u001b[39m wrapper\u001b[33m:\u001b[39m wrapper })\u001b[33m;\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 86 |\u001b[39m }\n \u001b[90m 87 |\u001b[39m \u001b[36mconst\u001b[39m initialUrl \u001b[33m=\u001b[39m react_native_1\u001b[33m.\u001b[39m\u001b[33mPlatform\u001b[39m\u001b[33m.\u001b[39m\u001b[33mOS\u001b[39m \u001b[33m===\u001b[39m \u001b[32m'web'\u001b[39m \u001b[33m&&\u001b[39m \u001b[36mtypeof\u001b[39m window \u001b[33m!==\u001b[39m \u001b[32m'undefined'\u001b[39m\n \u001b[90m 88 |\u001b[39m \u001b[33m?\u001b[39m \u001b[36mnew\u001b[39m \u001b[33mURL\u001b[39m(window\u001b[33m.\u001b[39mlocation\u001b[33m.\u001b[39mhref)\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[2m\u001b[90m ExpoRoot (node_modules/expo-router/build/ExpoRoot.js:85:33)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m App (node_modules/expo-router/build/qualified-entry.js:20:91)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m WithDevTools (node_modules/expo/src/launch/withDevTools.tsx:21:12)\u001b[39m\u001b[22m"]} +{"_e":"metro:client_log","_t":1786667165164,"level":"error","data":["[Error: Cannot find native module 'ExpoSecureStore']","\n\n\u001b[1mCode: AuthContext.tsx\u001b[22m\n\u001b[0m \u001b[90m 1 |\u001b[39m \u001b[36mimport\u001b[39m { \u001b[33mUser\u001b[39m } \u001b[36mfrom\u001b[39m \u001b[32m'@/types'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m 2 |\u001b[39m \u001b[36mimport\u001b[39m \u001b[33mReact\u001b[39m\u001b[33m,\u001b[39m { createContext\u001b[33m,\u001b[39m useContext\u001b[33m,\u001b[39m useEffect\u001b[33m,\u001b[39m useState } \u001b[36mfrom\u001b[39m \u001b[32m'react'\u001b[39m\u001b[33m;\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 3 |\u001b[39m \u001b[36mimport\u001b[39m \u001b[33m*\u001b[39m \u001b[36mas\u001b[39m \u001b[33mSecureStore\u001b[39m \u001b[36mfrom\u001b[39m \u001b[32m'expo-secure-store'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 4 |\u001b[39m \u001b[36mimport\u001b[39m \u001b[33m*\u001b[39m \u001b[36mas\u001b[39m \u001b[33mLocalAuthentication\u001b[39m \u001b[36mfrom\u001b[39m \u001b[32m'expo-local-authentication'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m 5 |\u001b[39m \u001b[36mimport\u001b[39m { setApiToken } \u001b[36mfrom\u001b[39m \u001b[32m'@/services/api'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m 6 |\u001b[39m\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m <global> (src/contexts/AuthContext.tsx:3)\u001b[39m\n\u001b[90m <global> (src/app/_layout.tsx:1)\u001b[39m","\n\n\u001b[1mCode: ExpoRoot.js\u001b[22m\n\u001b[0m \u001b[90m 83 |\u001b[39m initialMetrics\u001b[33m:\u001b[39m \u001b[33mINITIAL_METRICS\u001b[39m\u001b[33m,\u001b[39m children\u001b[33m:\u001b[39m children }) }) }))\u001b[33m;\u001b[39m\n \u001b[90m 84 |\u001b[39m }\u001b[33m,\u001b[39m [\u001b[33mParentWrapper\u001b[39m])\u001b[33m;\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 85 |\u001b[39m \u001b[36mreturn\u001b[39m (\u001b[35m0\u001b[39m\u001b[33m,\u001b[39m jsx_runtime_1\u001b[33m.\u001b[39mjsx)(\u001b[33mContextNavigator\u001b[39m\u001b[33m,\u001b[39m { \u001b[33m...\u001b[39mprops\u001b[33m,\u001b[39m wrapper\u001b[33m:\u001b[39m wrapper })\u001b[33m;\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 86 |\u001b[39m }\n \u001b[90m 87 |\u001b[39m \u001b[36mconst\u001b[39m initialUrl \u001b[33m=\u001b[39m react_native_1\u001b[33m.\u001b[39m\u001b[33mPlatform\u001b[39m\u001b[33m.\u001b[39m\u001b[33mOS\u001b[39m \u001b[33m===\u001b[39m \u001b[32m'web'\u001b[39m \u001b[33m&&\u001b[39m \u001b[36mtypeof\u001b[39m window \u001b[33m!==\u001b[39m \u001b[32m'undefined'\u001b[39m\n \u001b[90m 88 |\u001b[39m \u001b[33m?\u001b[39m \u001b[36mnew\u001b[39m \u001b[33mURL\u001b[39m(window\u001b[33m.\u001b[39mlocation\u001b[33m.\u001b[39mhref)\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[2m\u001b[90m ExpoRoot (node_modules/expo-router/build/ExpoRoot.js:85:33)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m App (node_modules/expo-router/build/qualified-entry.js:20:91)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m WithDevTools (node_modules/expo/src/launch/withDevTools.tsx:21:12)\u001b[39m\u001b[22m"]} +{"_e":"metro:client_log","_t":1786667165167,"level":"error","data":["[Error: Cannot find native module 'ExpoSecureStore']","\n\n\u001b[1mCode: AuthContext.tsx\u001b[22m\n\u001b[0m \u001b[90m 1 |\u001b[39m \u001b[36mimport\u001b[39m { \u001b[33mUser\u001b[39m } \u001b[36mfrom\u001b[39m \u001b[32m'@/types'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m 2 |\u001b[39m \u001b[36mimport\u001b[39m \u001b[33mReact\u001b[39m\u001b[33m,\u001b[39m { createContext\u001b[33m,\u001b[39m useContext\u001b[33m,\u001b[39m useEffect\u001b[33m,\u001b[39m useState } \u001b[36mfrom\u001b[39m \u001b[32m'react'\u001b[39m\u001b[33m;\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 3 |\u001b[39m \u001b[36mimport\u001b[39m \u001b[33m*\u001b[39m \u001b[36mas\u001b[39m \u001b[33mSecureStore\u001b[39m \u001b[36mfrom\u001b[39m \u001b[32m'expo-secure-store'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 4 |\u001b[39m \u001b[36mimport\u001b[39m \u001b[33m*\u001b[39m \u001b[36mas\u001b[39m \u001b[33mLocalAuthentication\u001b[39m \u001b[36mfrom\u001b[39m \u001b[32m'expo-local-authentication'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m 5 |\u001b[39m \u001b[36mimport\u001b[39m { setApiToken } \u001b[36mfrom\u001b[39m \u001b[32m'@/services/api'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m 6 |\u001b[39m\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m <global> (src/contexts/AuthContext.tsx:3)\u001b[39m\n\u001b[90m <global> (src/app/_layout.tsx:1)\u001b[39m","\n\n\u001b[1mCode: ExpoRoot.js\u001b[22m\n\u001b[0m \u001b[90m 83 |\u001b[39m initialMetrics\u001b[33m:\u001b[39m \u001b[33mINITIAL_METRICS\u001b[39m\u001b[33m,\u001b[39m children\u001b[33m:\u001b[39m children }) }) }))\u001b[33m;\u001b[39m\n \u001b[90m 84 |\u001b[39m }\u001b[33m,\u001b[39m [\u001b[33mParentWrapper\u001b[39m])\u001b[33m;\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 85 |\u001b[39m \u001b[36mreturn\u001b[39m (\u001b[35m0\u001b[39m\u001b[33m,\u001b[39m jsx_runtime_1\u001b[33m.\u001b[39mjsx)(\u001b[33mContextNavigator\u001b[39m\u001b[33m,\u001b[39m { \u001b[33m...\u001b[39mprops\u001b[33m,\u001b[39m wrapper\u001b[33m:\u001b[39m wrapper })\u001b[33m;\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 86 |\u001b[39m }\n \u001b[90m 87 |\u001b[39m \u001b[36mconst\u001b[39m initialUrl \u001b[33m=\u001b[39m react_native_1\u001b[33m.\u001b[39m\u001b[33mPlatform\u001b[39m\u001b[33m.\u001b[39m\u001b[33mOS\u001b[39m \u001b[33m===\u001b[39m \u001b[32m'web'\u001b[39m \u001b[33m&&\u001b[39m \u001b[36mtypeof\u001b[39m window \u001b[33m!==\u001b[39m \u001b[32m'undefined'\u001b[39m\n \u001b[90m 88 |\u001b[39m \u001b[33m?\u001b[39m \u001b[36mnew\u001b[39m \u001b[33mURL\u001b[39m(window\u001b[33m.\u001b[39mlocation\u001b[33m.\u001b[39mhref)\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[2m\u001b[90m ExpoRoot (node_modules/expo-router/build/ExpoRoot.js:85:33)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m App (node_modules/expo-router/build/qualified-entry.js:20:91)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m WithDevTools (node_modules/expo/src/launch/withDevTools.tsx:21:12)\u001b[39m\u001b[22m"]} +{"_e":"metro:client_log","_t":1786667165171,"level":"error","data":["[Error: Cannot find native module 'ExpoSecureStore']","\n\n\u001b[1mCode: AuthContext.tsx\u001b[22m\n\u001b[0m \u001b[90m 1 |\u001b[39m \u001b[36mimport\u001b[39m { \u001b[33mUser\u001b[39m } \u001b[36mfrom\u001b[39m \u001b[32m'@/types'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m 2 |\u001b[39m \u001b[36mimport\u001b[39m \u001b[33mReact\u001b[39m\u001b[33m,\u001b[39m { createContext\u001b[33m,\u001b[39m useContext\u001b[33m,\u001b[39m useEffect\u001b[33m,\u001b[39m useState } \u001b[36mfrom\u001b[39m \u001b[32m'react'\u001b[39m\u001b[33m;\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 3 |\u001b[39m \u001b[36mimport\u001b[39m \u001b[33m*\u001b[39m \u001b[36mas\u001b[39m \u001b[33mSecureStore\u001b[39m \u001b[36mfrom\u001b[39m \u001b[32m'expo-secure-store'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 4 |\u001b[39m \u001b[36mimport\u001b[39m \u001b[33m*\u001b[39m \u001b[36mas\u001b[39m \u001b[33mLocalAuthentication\u001b[39m \u001b[36mfrom\u001b[39m \u001b[32m'expo-local-authentication'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m 5 |\u001b[39m \u001b[36mimport\u001b[39m { setApiToken } \u001b[36mfrom\u001b[39m \u001b[32m'@/services/api'\u001b[39m\u001b[33m;\u001b[39m\n \u001b[90m 6 |\u001b[39m\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m <global> (src/contexts/AuthContext.tsx:3)\u001b[39m\n\u001b[90m <global> (src/app/_layout.tsx:1)\u001b[39m","\n\n\u001b[1mCode: ExpoRoot.js\u001b[22m\n\u001b[0m \u001b[90m 83 |\u001b[39m initialMetrics\u001b[33m:\u001b[39m \u001b[33mINITIAL_METRICS\u001b[39m\u001b[33m,\u001b[39m children\u001b[33m:\u001b[39m children }) }) }))\u001b[33m;\u001b[39m\n \u001b[90m 84 |\u001b[39m }\u001b[33m,\u001b[39m [\u001b[33mParentWrapper\u001b[39m])\u001b[33m;\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 85 |\u001b[39m \u001b[36mreturn\u001b[39m (\u001b[35m0\u001b[39m\u001b[33m,\u001b[39m jsx_runtime_1\u001b[33m.\u001b[39mjsx)(\u001b[33mContextNavigator\u001b[39m\u001b[33m,\u001b[39m { \u001b[33m...\u001b[39mprops\u001b[33m,\u001b[39m wrapper\u001b[33m:\u001b[39m wrapper })\u001b[33m;\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 86 |\u001b[39m }\n \u001b[90m 87 |\u001b[39m \u001b[36mconst\u001b[39m initialUrl \u001b[33m=\u001b[39m react_native_1\u001b[33m.\u001b[39m\u001b[33mPlatform\u001b[39m\u001b[33m.\u001b[39m\u001b[33mOS\u001b[39m \u001b[33m===\u001b[39m \u001b[32m'web'\u001b[39m \u001b[33m&&\u001b[39m \u001b[36mtypeof\u001b[39m window \u001b[33m!==\u001b[39m \u001b[32m'undefined'\u001b[39m\n \u001b[90m 88 |\u001b[39m \u001b[33m?\u001b[39m \u001b[36mnew\u001b[39m \u001b[33mURL\u001b[39m(window\u001b[33m.\u001b[39mlocation\u001b[33m.\u001b[39mhref)\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[2m\u001b[90m ExpoRoot (node_modules/expo-router/build/ExpoRoot.js:85:33)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m App (node_modules/expo-router/build/qualified-entry.js:20:91)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m WithDevTools (node_modules/expo/src/launch/withDevTools.tsx:21:12)\u001b[39m\u001b[22m"]} +{"_e":"metro:client_log","_t":1786667165173,"level":"error","data":["[TypeError: Cannot read property 'ErrorBoundary' of undefined]","\n\n\u001b[1mCode: useScreens.js\u001b[22m\n\u001b[0m \u001b[90m 139 |\u001b[39m })\u001b[33m,\u001b[39m [sorted\u001b[33m,\u001b[39m protectedScreens])\u001b[33m;\u001b[39m\n \u001b[90m 140 |\u001b[39m }\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 141 |\u001b[39m \u001b[36mfunction\u001b[39m fromImport(value\u001b[33m,\u001b[39m { \u001b[33mErrorBoundary\u001b[39m\u001b[33m,\u001b[39m \u001b[33mSuspenseFallback\u001b[39m\u001b[33m,\u001b[39m \u001b[33m...\u001b[39mcomponent }) {\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 142 |\u001b[39m \u001b[90m// If possible, add a more helpful display name for the component stack to improve debugging of React errors such as `Text strings must be rendered within a <Text> component.`.\u001b[39m\n \u001b[90m 143 |\u001b[39m \u001b[36mif\u001b[39m (component\u001b[33m?\u001b[39m\u001b[33m.\u001b[39m\u001b[36mdefault\u001b[39m \u001b[33m&&\u001b[39m __DEV__) {\n \u001b[90m 144 |\u001b[39m component\u001b[33m.\u001b[39m\u001b[36mdefault\u001b[39m\u001b[33m.\u001b[39mdisplayName \u001b[33m?\u001b[39m\u001b[33m?\u001b[39m\u001b[33m=\u001b[39m \u001b[32m`${component.default.name ?? 'Route'}(${value.contextKey})`\u001b[39m\u001b[33m;\u001b[39m\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[2m\u001b[90m fromImport (node_modules/expo-router/build/useScreens.js:141)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m getQualifiedRouteComponent (node_modules/expo-router/build/useScreens.js:206:34)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m useStore (node_modules/expo-router/build/global-state/useStore.js:55:68)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m ContextNavigator (node_modules/expo-router/build/ExpoRoot.js:122:46)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m callComponent.react_stack_bottom_frame (node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-dev.js:17130:29)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m renderWithHooks (node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-dev.js:5648:40)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m updateFunctionComponent (node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-dev.js:8081:34)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m beginWork (node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-dev.js:9340:41)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m run (<native>)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m runWithFiberInDEV (node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-dev.js:697:33)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m performUnitOfWork (node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-dev.js:14134:39)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m workLoopSync (node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-dev.js:13966:58)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m renderRootSync (node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-dev.js:13947:23)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m performWorkOnRoot (node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-dev.js:13160:43)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m performWorkOnRootViaSchedulerTask (node_modules/react-native/Libraries/Renderer/implementations/ReactFabric-dev.js:3673:24)\u001b[39m\u001b[22m","\n\n\u001b[1mCode: ExpoRoot.js\u001b[22m\n\u001b[0m \u001b[90m 83 |\u001b[39m initialMetrics\u001b[33m:\u001b[39m \u001b[33mINITIAL_METRICS\u001b[39m\u001b[33m,\u001b[39m children\u001b[33m:\u001b[39m children }) }) }))\u001b[33m;\u001b[39m\n \u001b[90m 84 |\u001b[39m }\u001b[33m,\u001b[39m [\u001b[33mParentWrapper\u001b[39m])\u001b[33m;\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 85 |\u001b[39m \u001b[36mreturn\u001b[39m (\u001b[35m0\u001b[39m\u001b[33m,\u001b[39m jsx_runtime_1\u001b[33m.\u001b[39mjsx)(\u001b[33mContextNavigator\u001b[39m\u001b[33m,\u001b[39m { \u001b[33m...\u001b[39mprops\u001b[33m,\u001b[39m wrapper\u001b[33m:\u001b[39m wrapper })\u001b[33m;\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 86 |\u001b[39m }\n \u001b[90m 87 |\u001b[39m \u001b[36mconst\u001b[39m initialUrl \u001b[33m=\u001b[39m react_native_1\u001b[33m.\u001b[39m\u001b[33mPlatform\u001b[39m\u001b[33m.\u001b[39m\u001b[33mOS\u001b[39m \u001b[33m===\u001b[39m \u001b[32m'web'\u001b[39m \u001b[33m&&\u001b[39m \u001b[36mtypeof\u001b[39m window \u001b[33m!==\u001b[39m \u001b[32m'undefined'\u001b[39m\n \u001b[90m 88 |\u001b[39m \u001b[33m?\u001b[39m \u001b[36mnew\u001b[39m \u001b[33mURL\u001b[39m(window\u001b[33m.\u001b[39mlocation\u001b[33m.\u001b[39mhref)\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[2m\u001b[90m ExpoRoot (node_modules/expo-router/build/ExpoRoot.js:85:33)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m App (node_modules/expo-router/build/qualified-entry.js:20:91)\u001b[39m\u001b[22m\n\u001b[2m\u001b[90m WithDevTools (node_modules/expo/src/launch/withDevTools.tsx:21:12)\u001b[39m\u001b[22m"]} +{"_e":"root:init","_t":1786667211050,"format":"v0-jsonl","version":"57.0.14"} +{"_e":"devserver:start","_t":1786667211071,"mode":"development","web":true,"baseUrl":"","asyncRoutes":false,"routerRoot":"../../../src/app","serverComponents":false,"serverActions":false,"serverRendering":true,"apiRoutes":false,"exporting":false} +{"_e":"metro:config","_t":1786667211289,"serverRoot":"../../..","projectRoot":"../../..","exporting":false,"flags":{"autolinkingModuleResolution":false,"serverActions":false,"serverComponents":false,"reactCompiler":true,"optimizeGraph":false,"treeshaking":false,"logbox":false}} +{"_e":"expo:dev-tools-plugin:load","_t":1786667211403,"plugins":[]} +{"_e":"metro:instantiate","_t":1786667212134,"atlas":false,"workers":4,"host":"::","port":8081} +{"_e":"metro:bundling:started","_t":1786667240898,"id":"1","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786667240898,"id":"1","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786667240907,"id":"1","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786667241007,"id":"1","progress":0.1326138527849243,"total":346,"current":126} +{"_e":"metro:bundling:progress","_t":1786667241107,"id":"1","progress":0.3692790571921489,"total":859,"current":522} +{"_e":"metro:bundling:progress","_t":1786667241207,"id":"1","progress":0.8449980401909084,"total":1102,"current":1013} +{"_e":"metro:bundling:progress","_t":1786667241307,"id":"1","progress":0.9943741321166435,"total":1420,"current":1416} +{"_e":"metro:bundling:done","_t":1786667241363,"id":"1","total":1420,"ms":464.47725} +{"_e":"metro:bundling:started","_t":1786667417285,"id":"2","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786667417285,"id":"2","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:done","_t":1786667417340,"id":"2","total":1,"ms":55.097375} +{"_e":"metro:bundling:started","_t":1786667518688,"id":"3","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786667518688,"id":"3","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:done","_t":1786667518744,"id":"3","total":1,"ms":56.403833} +{"_e":"root:init","_t":1786667657727,"format":"v0-jsonl","version":"57.0.14"} +{"_e":"devserver:start","_t":1786667657746,"mode":"development","web":true,"baseUrl":"","asyncRoutes":false,"routerRoot":"../../../src/app","serverComponents":false,"serverActions":false,"serverRendering":true,"apiRoutes":false,"exporting":false} +{"_e":"metro:config","_t":1786667657939,"serverRoot":"../../..","projectRoot":"../../..","exporting":false,"flags":{"autolinkingModuleResolution":false,"serverActions":false,"serverComponents":false,"reactCompiler":true,"optimizeGraph":false,"treeshaking":false,"logbox":false}} +{"_e":"expo:dev-tools-plugin:load","_t":1786667658037,"plugins":[]} +{"_e":"metro:instantiate","_t":1786667658593,"atlas":false,"workers":4,"host":"::","port":8081} +{"_e":"metro:bundling:started","_t":1786667689111,"id":"1","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786667689111,"id":"1","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786667689120,"id":"1","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786667689221,"id":"1","progress":0.19285574312029335,"total":378,"current":166} +{"_e":"metro:bundling:progress","_t":1786667689321,"id":"1","progress":0.5127939459070457,"total":789,"current":565} +{"_e":"metro:bundling:progress","_t":1786667689421,"id":"1","progress":0.843252736604642,"total":1028,"current":944} +{"_e":"metro:bundling:progress","_t":1786667689523,"id":"1","progress":0.9688792757740022,"total":1339,"current":1318} +{"_e":"metro:bundling:progress","_t":1786667689624,"id":"1","progress":0.9985124583687641,"total":1344,"current":1343} +{"_e":"metro:bundling:progress","_t":1786667689815,"id":"1","progress":0.999,"total":1344,"current":1344} +{"_e":"metro:bundling:done","_t":1786667689874,"id":"1","total":1344,"ms":763.056417} +{"_e":"metro:bundling:started","_t":1786667983327,"id":"2","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786667983328,"id":"2","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:done","_t":1786667983402,"id":"2","total":1,"ms":74.646375} +{"_e":"metro:bundling:started","_t":1786667988361,"id":"3","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786667988362,"id":"3","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:done","_t":1786667988427,"id":"3","total":1,"ms":65.752125} +{"_e":"metro:client_log","_t":1786668102509,"level":"warn","data":["Route \"./login.tsx\" is missing the required default export. Ensure a React component is exported as default."]} +{"_e":"metro:client_log","_t":1786668671321,"level":"warn","data":["Route \"./(app)/_layout.tsx\" is missing the required default export. Ensure a React component is exported as default."]} +{"_e":"metro:client_log","_t":1786668877358,"level":"warn","data":["[Layout children]: Too many screens defined. Route \"register\" is extraneous."]} +{"_e":"metro:client_log","_t":1786668877397,"level":"warn","data":["Unable to get the view config for default view from module &s ExpoLinearGradient"]} +{"_e":"metro:bundling:started","_t":1786668924449,"id":"8","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786668924449,"id":"8","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786668924455,"id":"8","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786668924555,"id":"8","progress":0.09467455621301776,"total":13,"current":4} +{"_e":"metro:bundling:progress","_t":1786668924669,"id":"8","progress":0.09467455621301776,"total":20,"current":6} +{"_e":"metro:bundling:progress","_t":1786668924678,"id":"8","progress":0.12249999999999998,"total":20,"current":7} +{"_e":"metro:bundling:progress","_t":1786668924779,"id":"8","progress":0.12249999999999998,"total":126,"current":13} +{"_e":"metro:bundling:progress","_t":1786668924882,"id":"8","progress":0.12249999999999998,"total":153,"current":20} +{"_e":"metro:bundling:progress","_t":1786668924984,"id":"8","progress":0.12249999999999998,"total":176,"current":27} +{"_e":"metro:bundling:progress","_t":1786668925086,"id":"8","progress":0.12249999999999998,"total":193,"current":37} +{"_e":"metro:bundling:progress","_t":1786668925187,"id":"8","progress":0.12249999999999998,"total":210,"current":43} +{"_e":"metro:bundling:progress","_t":1786668925287,"id":"8","progress":0.12249999999999998,"total":244,"current":75} +{"_e":"metro:bundling:progress","_t":1786668925387,"id":"8","progress":0.18890234613991932,"total":283,"current":123} +{"_e":"metro:bundling:progress","_t":1786668925487,"id":"8","progress":0.28141731112433077,"total":328,"current":174} +{"_e":"metro:bundling:progress","_t":1786668925587,"id":"8","progress":0.29374745061476604,"total":393,"current":213} +{"_e":"metro:bundling:progress","_t":1786668925687,"id":"8","progress":0.3407062042733218,"total":454,"current":265} +{"_e":"metro:bundling:progress","_t":1786668925792,"id":"8","progress":0.3731830450052029,"total":496,"current":303} +{"_e":"metro:bundling:progress","_t":1786668925898,"id":"8","progress":0.4026887344112459,"total":509,"current":323} +{"_e":"metro:bundling:progress","_t":1786668925998,"id":"8","progress":0.4127654388490157,"total":551,"current":354} +{"_e":"metro:bundling:progress","_t":1786668926098,"id":"8","progress":0.4127654388490157,"total":604,"current":388} +{"_e":"metro:bundling:progress","_t":1786668926198,"id":"8","progress":0.5043058181054401,"total":621,"current":441} +{"_e":"metro:bundling:progress","_t":1786668926298,"id":"8","progress":0.5780826404635928,"total":630,"current":479} +{"_e":"metro:bundling:progress","_t":1786668926398,"id":"8","progress":0.6347492297139384,"total":669,"current":533} +{"_e":"metro:bundling:progress","_t":1786668926498,"id":"8","progress":0.6634182019066738,"total":717,"current":584} +{"_e":"metro:bundling:progress","_t":1786668926598,"id":"8","progress":0.6634182019066738,"total":789,"current":628} +{"_e":"metro:bundling:progress","_t":1786668926699,"id":"8","progress":0.6634182019066738,"total":830,"current":662} +{"_e":"metro:bundling:progress","_t":1786668926800,"id":"8","progress":0.6634182019066738,"total":855,"current":689} +{"_e":"metro:bundling:progress","_t":1786668926900,"id":"8","progress":0.6634182019066738,"total":902,"current":722} +{"_e":"metro:bundling:progress","_t":1786668927001,"id":"8","progress":0.6634182019066738,"total":922,"current":746} +{"_e":"metro:bundling:progress","_t":1786668927101,"id":"8","progress":0.6634182019066738,"total":978,"current":778} +{"_e":"metro:bundling:progress","_t":1786668927206,"id":"8","progress":0.6634182019066738,"total":1000,"current":808} +{"_e":"metro:bundling:progress","_t":1786668927306,"id":"8","progress":0.6720752867365943,"total":1010,"current":828} +{"_e":"metro:bundling:progress","_t":1786668927418,"id":"8","progress":0.6892441693327318,"total":1013,"current":841} +{"_e":"metro:bundling:progress","_t":1786668927520,"id":"8","progress":0.7190246571594678,"total":1026,"current":870} +{"_e":"metro:bundling:progress","_t":1786668927619,"id":"8","progress":0.7806462310598867,"total":1039,"current":918} +{"_e":"metro:bundling:progress","_t":1786668927719,"id":"8","progress":0.8247073098143357,"total":1045,"current":949} +{"_e":"metro:bundling:progress","_t":1786668927821,"id":"8","progress":0.8599937700249198,"total":1060,"current":983} +{"_e":"metro:bundling:progress","_t":1786668927924,"id":"8","progress":0.8786872215914054,"total":1070,"current":1003} +{"_e":"metro:bundling:progress","_t":1786668928024,"id":"8","progress":0.9038018389941828,"total":1095,"current":1041} +{"_e":"metro:bundling:progress","_t":1786668928124,"id":"8","progress":0.9622845137591454,"total":1103,"current":1082} +{"_e":"metro:bundling:progress","_t":1786668928224,"id":"8","progress":0.9683953324457671,"total":1130,"current":1112} +{"_e":"metro:bundling:progress","_t":1786668928324,"id":"8","progress":0.9683953324457671,"total":1199,"current":1154} +{"_e":"metro:bundling:progress","_t":1786668928425,"id":"8","progress":0.9683953324457671,"total":1229,"current":1204} +{"_e":"metro:bundling:progress","_t":1786668928525,"id":"8","progress":0.9683953324457671,"total":1306,"current":1258} +{"_e":"metro:bundling:progress","_t":1786668928628,"id":"8","progress":0.9790738224650464,"total":1331,"current":1317} +{"_e":"metro:bundling:progress","_t":1786668928729,"id":"8","progress":0.9790738224650464,"total":1366,"current":1346} +{"_e":"metro:bundling:progress","_t":1786668928830,"id":"8","progress":0.9898071287761735,"total":1370,"current":1363} +{"_e":"metro:bundling:progress","_t":1786668928931,"id":"8","progress":0.999,"total":1375,"current":1375} +{"_e":"metro:bundling:done","_t":1786668929022,"id":"8","total":1375,"ms":4572.863958} +{"_e":"metro:bundling:started","_t":1786668934022,"id":"9","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786668934022,"id":"9","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786668934026,"id":"9","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:done","_t":1786668934095,"id":"9","total":1,"ms":72.474542} +{"_e":"metro:client_log","_t":1786668936416,"level":"warn","data":["[Layout children]: Too many screens defined. Route \"register\" is extraneous."]} +{"_e":"metro:client_log","_t":1786668936491,"level":"warn","data":["Unable to get the view config for default view from module &s ExpoLinearGradient"]} +{"_e":"metro:bundling:started","_t":1786668940099,"id":"a","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786668940099,"id":"a","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:done","_t":1786668940158,"id":"a","total":1,"ms":59.636334} +{"_e":"metro:client_log","_t":1786668942560,"level":"warn","data":["[Layout children]: Too many screens defined. Route \"register\" is extraneous."]} +{"_e":"metro:client_log","_t":1786668942634,"level":"warn","data":["Unable to get the view config for default view from module &s ExpoLinearGradient"]} +{"_e":"metro:bundling:started","_t":1786668990201,"id":"b","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786668990202,"id":"b","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786668990209,"id":"b","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:done","_t":1786668990344,"id":"b","total":1,"ms":142.19725} +{"_e":"metro:client_log","_t":1786668992770,"level":"warn","data":["[Layout children]: Too many screens defined. Route \"register\" is extraneous."]} +{"_e":"metro:client_log","_t":1786668992848,"level":"warn","data":["Unable to get the view config for default view from module &s ExpoLinearGradient"]} +{"_e":"root:init","_t":1786669142655,"format":"v0-jsonl","version":"57.0.14"} +{"_e":"devserver:start","_t":1786669142675,"mode":"development","web":true,"baseUrl":"","asyncRoutes":false,"routerRoot":"../../../src/app","serverComponents":false,"serverActions":false,"serverRendering":true,"apiRoutes":false,"exporting":false} +{"_e":"metro:config","_t":1786669142883,"serverRoot":"../../..","projectRoot":"../../..","exporting":false,"flags":{"autolinkingModuleResolution":false,"serverActions":false,"serverComponents":false,"reactCompiler":true,"optimizeGraph":false,"treeshaking":false,"logbox":false}} +{"_e":"expo:dev-tools-plugin:load","_t":1786669142997,"plugins":[]} +{"_e":"metro:instantiate","_t":1786669143551,"atlas":false,"workers":4,"host":"::","port":8081} +{"_e":"metro:bundling:started","_t":1786669172072,"id":"1","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786669172072,"id":"1","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786669172078,"id":"1","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786669172178,"id":"1","progress":0.2373970122227252,"total":470,"current":229} +{"_e":"metro:bundling:progress","_t":1786669172278,"id":"1","progress":0.49891672987289054,"total":899,"current":635} +{"_e":"metro:bundling:progress","_t":1786669172378,"id":"1","progress":0.744792644023269,"total":1095,"current":945} +{"_e":"metro:bundling:progress","_t":1786669172478,"id":"1","progress":0.8793117898492595,"total":1445,"current":1355} +{"_e":"metro:bundling:progress","_t":1786669172578,"id":"1","progress":0.9224745033406198,"total":1669,"current":1603} +{"_e":"metro:bundling:progress","_t":1786669172678,"id":"1","progress":0.9988548526561777,"total":1746,"current":1745} +{"_e":"metro:bundling:progress","_t":1786669172795,"id":"1","progress":0.999,"total":1746,"current":1746} +{"_e":"metro:bundling:done","_t":1786669172853,"id":"1","total":1746,"ms":780.973583} +{"_e":"metro:client_log","_t":1786669175178,"level":"warn","data":["[Layout children]: Too many screens defined. Route \"register\" is extraneous."]} +{"_e":"metro:client_log","_t":1786669177912,"level":"error","data":["[ReferenceError: Property 'FadeInUp' doesn't exist]","\n\n\u001b[1mCode: login.tsx\u001b[22m\n\u001b[0m \u001b[90m 44 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mKeyboardAvoidingView\u001b[39m style\u001b[33m=\u001b[39m{styles\u001b[33m.\u001b[39mcontainer} behavior\u001b[33m=\u001b[39m{\u001b[33mPlatform\u001b[39m\u001b[33m.\u001b[39m\u001b[33mOS\u001b[39m \u001b[33m===\u001b[39m \u001b[32m'ios'\u001b[39m \u001b[33m?\u001b[39m \u001b[32m'padding'\u001b[39m \u001b[33m:\u001b[39m undefined}\u001b[33m>\u001b[39m\n \u001b[90m 45 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mView\u001b[39m style\u001b[33m=\u001b[39m{[styles\u001b[33m.\u001b[39mcontent\u001b[33m,\u001b[39m { paddingTop\u001b[33m:\u001b[39m insets\u001b[33m.\u001b[39mtop \u001b[33m+\u001b[39m \u001b[33mSpacing\u001b[39m\u001b[33m.\u001b[39mxxl }]}\u001b[33m>\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 46 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mAnimated\u001b[39m\u001b[33m.\u001b[39m\u001b[33mView\u001b[39m entering\u001b[33m=\u001b[39m{\u001b[33mFadeInUp\u001b[39m\u001b[33m.\u001b[39mduration(\u001b[35m600\u001b[39m)} style\u001b[33m=\u001b[39m{styles\u001b[33m.\u001b[39mheader}\u001b[33m>\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 47 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mText\u001b[39m style\u001b[33m=\u001b[39m{styles\u001b[33m.\u001b[39mtitle}\u001b[33m>\u001b[39m\u001b[33mYABA\u001b[39m\u001b[33m<\u001b[39m\u001b[33m/\u001b[39m\u001b[33mText\u001b[39m\u001b[33m>\u001b[39m\n \u001b[90m 48 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mText\u001b[39m style\u001b[33m=\u001b[39m{styles\u001b[33m.\u001b[39msubtitle}\u001b[33m>\u001b[39m\u001b[33mO\u001b[39m seu dinheiro\u001b[33m,\u001b[39m no seu controle\u001b[33m.\u001b[39m\u001b[33m<\u001b[39m\u001b[33m/\u001b[39m\u001b[33mText\u001b[39m\u001b[33m>\u001b[39m\n \u001b[90m 49 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33m/\u001b[39m\u001b[33mAnimated\u001b[39m\u001b[33m.\u001b[39m\u001b[33mView\u001b[39m\u001b[33m>\u001b[39m\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m LoginScreen (src/app/login.tsx:46:42)\u001b[39m","\n\n\u001b[1mCode: _layout.tsx\u001b[22m\n\u001b[0m \u001b[90m 30 |\u001b[39m \u001b[36mreturn\u001b[39m (\n \u001b[90m 31 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mView\u001b[39m style\u001b[33m=\u001b[39m{{ flex\u001b[33m:\u001b[39m \u001b[35m1\u001b[39m\u001b[33m,\u001b[39m backgroundColor\u001b[33m:\u001b[39m \u001b[33mColors\u001b[39m\u001b[33m.\u001b[39mbackground }}\u001b[33m>\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 32 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mStack\u001b[39m screenOptions\u001b[33m=\u001b[39m{{ headerShown\u001b[33m:\u001b[39m \u001b[36mfalse\u001b[39m\u001b[33m,\u001b[39m contentStyle\u001b[33m:\u001b[39m { backgroundColor\u001b[33m:\u001b[39m \u001b[33mColors\u001b[39m\u001b[33m.\u001b[39mbackground } }}\u001b[33m>\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 33 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mStack\u001b[39m\u001b[33m.\u001b[39m\u001b[33mScreen\u001b[39m name\u001b[33m=\u001b[39m\u001b[32m\"(app)\"\u001b[39m \u001b[33m/\u001b[39m\u001b[33m>\u001b[39m\n \u001b[90m 34 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mStack\u001b[39m\u001b[33m.\u001b[39m\u001b[33mScreen\u001b[39m name\u001b[33m=\u001b[39m\u001b[32m\"login\"\u001b[39m \u001b[33m/\u001b[39m\u001b[33m>\u001b[39m\n \u001b[90m 35 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mStack\u001b[39m\u001b[33m.\u001b[39m\u001b[33mScreen\u001b[39m name\u001b[33m=\u001b[39m\u001b[32m\"register\"\u001b[39m \u001b[33m/\u001b[39m\u001b[33m>\u001b[39m\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m RootContent (src/app/_layout.tsx:32:13)\u001b[39m\n\u001b[90m RootLayout (src/app/_layout.tsx:50:17)\u001b[39m"]} +{"_e":"metro:client_log","_t":1786669304305,"level":"warn","data":["[Layout children]: Too many screens defined. Route \"register\" is extraneous."]} +{"_e":"metro:client_log","_t":1786669304461,"level":"error","data":["[ReferenceError: Property 'Button' doesn't exist]","\n\n\u001b[1mCode: login.tsx\u001b[22m\n\u001b[0m \u001b[90m 70 |\u001b[39m \u001b[33m/\u001b[39m\u001b[33m>\u001b[39m\n \u001b[90m 71 |\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 72 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mButton\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 73 |\u001b[39m id\u001b[33m=\u001b[39m\u001b[32m\"login-button\"\u001b[39m\n \u001b[90m 74 |\u001b[39m label\u001b[33m=\u001b[39m\u001b[32m\"Entrar\"\u001b[39m\n \u001b[90m 75 |\u001b[39m fullWidth\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m LoginScreen (src/app/login.tsx:72:22)\u001b[39m","\n\n\u001b[1mCode: _layout.tsx\u001b[22m\n\u001b[0m \u001b[90m 30 |\u001b[39m \u001b[36mreturn\u001b[39m (\n \u001b[90m 31 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mView\u001b[39m style\u001b[33m=\u001b[39m{{ flex\u001b[33m:\u001b[39m \u001b[35m1\u001b[39m\u001b[33m,\u001b[39m backgroundColor\u001b[33m:\u001b[39m \u001b[33mColors\u001b[39m\u001b[33m.\u001b[39mbackground }}\u001b[33m>\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 32 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mStack\u001b[39m screenOptions\u001b[33m=\u001b[39m{{ headerShown\u001b[33m:\u001b[39m \u001b[36mfalse\u001b[39m\u001b[33m,\u001b[39m contentStyle\u001b[33m:\u001b[39m { backgroundColor\u001b[33m:\u001b[39m \u001b[33mColors\u001b[39m\u001b[33m.\u001b[39mbackground } }}\u001b[33m>\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 33 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mStack\u001b[39m\u001b[33m.\u001b[39m\u001b[33mScreen\u001b[39m name\u001b[33m=\u001b[39m\u001b[32m\"(app)\"\u001b[39m \u001b[33m/\u001b[39m\u001b[33m>\u001b[39m\n \u001b[90m 34 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mStack\u001b[39m\u001b[33m.\u001b[39m\u001b[33mScreen\u001b[39m name\u001b[33m=\u001b[39m\u001b[32m\"login\"\u001b[39m \u001b[33m/\u001b[39m\u001b[33m>\u001b[39m\n \u001b[90m 35 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mStack\u001b[39m\u001b[33m.\u001b[39m\u001b[33mScreen\u001b[39m name\u001b[33m=\u001b[39m\u001b[32m\"register\"\u001b[39m \u001b[33m/\u001b[39m\u001b[33m>\u001b[39m\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m RootContent (src/app/_layout.tsx:32:13)\u001b[39m\n\u001b[90m RootLayout (src/app/_layout.tsx:50:17)\u001b[39m"]} +{"_e":"metro:bundling:started","_t":1786669364003,"id":"a","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786669364004,"id":"a","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:done","_t":1786669364078,"id":"a","total":1,"ms":73.626166} +{"_e":"metro:client_log","_t":1786669366264,"level":"warn","data":["[Layout children]: Too many screens defined. Route \"register\" is extraneous."]} +{"_e":"metro:client_log","_t":1786669366558,"level":"error","data":["[ReferenceError: Property 'Button' doesn't exist]","\n\n\u001b[1mCode: login.tsx\u001b[22m\n\u001b[0m \u001b[90m 70 |\u001b[39m \u001b[33m/\u001b[39m\u001b[33m>\u001b[39m\n \u001b[90m 71 |\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 72 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mButton\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 73 |\u001b[39m id\u001b[33m=\u001b[39m\u001b[32m\"login-button\"\u001b[39m\n \u001b[90m 74 |\u001b[39m label\u001b[33m=\u001b[39m\u001b[32m\"Entrar\"\u001b[39m\n \u001b[90m 75 |\u001b[39m fullWidth\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m LoginScreen (src/app/login.tsx:72:22)\u001b[39m","\n\n\u001b[1mCode: _layout.tsx\u001b[22m\n\u001b[0m \u001b[90m 30 |\u001b[39m \u001b[36mreturn\u001b[39m (\n \u001b[90m 31 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mView\u001b[39m style\u001b[33m=\u001b[39m{{ flex\u001b[33m:\u001b[39m \u001b[35m1\u001b[39m\u001b[33m,\u001b[39m backgroundColor\u001b[33m:\u001b[39m \u001b[33mColors\u001b[39m\u001b[33m.\u001b[39mbackground }}\u001b[33m>\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 32 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mStack\u001b[39m screenOptions\u001b[33m=\u001b[39m{{ headerShown\u001b[33m:\u001b[39m \u001b[36mfalse\u001b[39m\u001b[33m,\u001b[39m contentStyle\u001b[33m:\u001b[39m { backgroundColor\u001b[33m:\u001b[39m \u001b[33mColors\u001b[39m\u001b[33m.\u001b[39mbackground } }}\u001b[33m>\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 33 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mStack\u001b[39m\u001b[33m.\u001b[39m\u001b[33mScreen\u001b[39m name\u001b[33m=\u001b[39m\u001b[32m\"(app)\"\u001b[39m \u001b[33m/\u001b[39m\u001b[33m>\u001b[39m\n \u001b[90m 34 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mStack\u001b[39m\u001b[33m.\u001b[39m\u001b[33mScreen\u001b[39m name\u001b[33m=\u001b[39m\u001b[32m\"login\"\u001b[39m \u001b[33m/\u001b[39m\u001b[33m>\u001b[39m\n \u001b[90m 35 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mStack\u001b[39m\u001b[33m.\u001b[39m\u001b[33mScreen\u001b[39m name\u001b[33m=\u001b[39m\u001b[32m\"register\"\u001b[39m \u001b[33m/\u001b[39m\u001b[33m>\u001b[39m\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m RootContent (src/app/_layout.tsx:32:13)\u001b[39m\n\u001b[90m RootLayout (src/app/_layout.tsx:50:17)\u001b[39m"]} +{"_e":"metro:bundling:started","_t":1786669370848,"id":"f","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786669370849,"id":"f","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:done","_t":1786669370909,"id":"f","total":1,"ms":60.586041} +{"_e":"metro:client_log","_t":1786669373087,"level":"warn","data":["[Layout children]: Too many screens defined. Route \"register\" is extraneous."]} +{"_e":"metro:client_log","_t":1786669373347,"level":"error","data":["[ReferenceError: Property 'Button' doesn't exist]","\n\n\u001b[1mCode: login.tsx\u001b[22m\n\u001b[0m \u001b[90m 70 |\u001b[39m \u001b[33m/\u001b[39m\u001b[33m>\u001b[39m\n \u001b[90m 71 |\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 72 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mButton\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 73 |\u001b[39m id\u001b[33m=\u001b[39m\u001b[32m\"login-button\"\u001b[39m\n \u001b[90m 74 |\u001b[39m label\u001b[33m=\u001b[39m\u001b[32m\"Entrar\"\u001b[39m\n \u001b[90m 75 |\u001b[39m fullWidth\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m LoginScreen (src/app/login.tsx:72:22)\u001b[39m","\n\n\u001b[1mCode: _layout.tsx\u001b[22m\n\u001b[0m \u001b[90m 30 |\u001b[39m \u001b[36mreturn\u001b[39m (\n \u001b[90m 31 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mView\u001b[39m style\u001b[33m=\u001b[39m{{ flex\u001b[33m:\u001b[39m \u001b[35m1\u001b[39m\u001b[33m,\u001b[39m backgroundColor\u001b[33m:\u001b[39m \u001b[33mColors\u001b[39m\u001b[33m.\u001b[39mbackground }}\u001b[33m>\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 32 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mStack\u001b[39m screenOptions\u001b[33m=\u001b[39m{{ headerShown\u001b[33m:\u001b[39m \u001b[36mfalse\u001b[39m\u001b[33m,\u001b[39m contentStyle\u001b[33m:\u001b[39m { backgroundColor\u001b[33m:\u001b[39m \u001b[33mColors\u001b[39m\u001b[33m.\u001b[39mbackground } }}\u001b[33m>\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 33 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mStack\u001b[39m\u001b[33m.\u001b[39m\u001b[33mScreen\u001b[39m name\u001b[33m=\u001b[39m\u001b[32m\"(app)\"\u001b[39m \u001b[33m/\u001b[39m\u001b[33m>\u001b[39m\n \u001b[90m 34 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mStack\u001b[39m\u001b[33m.\u001b[39m\u001b[33mScreen\u001b[39m name\u001b[33m=\u001b[39m\u001b[32m\"login\"\u001b[39m \u001b[33m/\u001b[39m\u001b[33m>\u001b[39m\n \u001b[90m 35 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mStack\u001b[39m\u001b[33m.\u001b[39m\u001b[33mScreen\u001b[39m name\u001b[33m=\u001b[39m\u001b[32m\"register\"\u001b[39m \u001b[33m/\u001b[39m\u001b[33m>\u001b[39m\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m RootContent (src/app/_layout.tsx:32:13)\u001b[39m\n\u001b[90m RootLayout (src/app/_layout.tsx:50:17)\u001b[39m"]} +{"_e":"root:init","_t":1786669402477,"format":"v0-jsonl","version":"57.0.14"} +{"_e":"devserver:start","_t":1786669402488,"mode":"development","web":true,"baseUrl":"","asyncRoutes":false,"routerRoot":"../../../src/app","serverComponents":false,"serverActions":false,"serverRendering":true,"apiRoutes":false,"exporting":false} +{"_e":"metro:config","_t":1786669402675,"serverRoot":"../../..","projectRoot":"../../..","exporting":false,"flags":{"autolinkingModuleResolution":false,"serverActions":false,"serverComponents":false,"reactCompiler":true,"optimizeGraph":false,"treeshaking":false,"logbox":false}} +{"_e":"expo:dev-tools-plugin:load","_t":1786669402765,"plugins":[]} +{"_e":"metro:instantiate","_t":1786669403417,"atlas":false,"workers":4,"host":"::","port":8081} +{"_e":"metro:bundling:started","_t":1786669438125,"id":"1","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786669438125,"id":"1","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786669438131,"id":"1","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786669438231,"id":"1","progress":0.30918488105301295,"total":455,"current":253} +{"_e":"metro:bundling:progress","_t":1786669438332,"id":"1","progress":0.5655653894210746,"total":980,"current":737} +{"_e":"metro:bundling:progress","_t":1786669438431,"id":"1","progress":0.8075607257179918,"total":1401,"current":1259} +{"_e":"metro:bundling:done","_t":1786669438565,"id":"1","total":1401,"ms":439.637667} +{"_e":"metro:client_log","_t":1786669441376,"level":"warn","data":["[Layout children]: Too many screens defined. Route \"register\" is extraneous."]} +{"_e":"metro:client_log","_t":1786669441676,"level":"error","data":["[ReferenceError: Property 'Button' doesn't exist]","\n\n\u001b[1mCode: login.tsx\u001b[22m\n\u001b[0m \u001b[90m 70 |\u001b[39m \u001b[33m/\u001b[39m\u001b[33m>\u001b[39m\n \u001b[90m 71 |\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 72 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mButton\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 73 |\u001b[39m id\u001b[33m=\u001b[39m\u001b[32m\"login-button\"\u001b[39m\n \u001b[90m 74 |\u001b[39m label\u001b[33m=\u001b[39m\u001b[32m\"Entrar\"\u001b[39m\n \u001b[90m 75 |\u001b[39m fullWidth\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m LoginScreen (src/app/login.tsx:72:22)\u001b[39m","\n\n\u001b[1mCode: _layout.tsx\u001b[22m\n\u001b[0m \u001b[90m 30 |\u001b[39m \u001b[36mreturn\u001b[39m (\n \u001b[90m 31 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mView\u001b[39m style\u001b[33m=\u001b[39m{{ flex\u001b[33m:\u001b[39m \u001b[35m1\u001b[39m\u001b[33m,\u001b[39m backgroundColor\u001b[33m:\u001b[39m \u001b[33mColors\u001b[39m\u001b[33m.\u001b[39mbackground }}\u001b[33m>\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 32 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mStack\u001b[39m screenOptions\u001b[33m=\u001b[39m{{ headerShown\u001b[33m:\u001b[39m \u001b[36mfalse\u001b[39m\u001b[33m,\u001b[39m contentStyle\u001b[33m:\u001b[39m { backgroundColor\u001b[33m:\u001b[39m \u001b[33mColors\u001b[39m\u001b[33m.\u001b[39mbackground } }}\u001b[33m>\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 33 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mStack\u001b[39m\u001b[33m.\u001b[39m\u001b[33mScreen\u001b[39m name\u001b[33m=\u001b[39m\u001b[32m\"(app)\"\u001b[39m \u001b[33m/\u001b[39m\u001b[33m>\u001b[39m\n \u001b[90m 34 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mStack\u001b[39m\u001b[33m.\u001b[39m\u001b[33mScreen\u001b[39m name\u001b[33m=\u001b[39m\u001b[32m\"login\"\u001b[39m \u001b[33m/\u001b[39m\u001b[33m>\u001b[39m\n \u001b[90m 35 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mStack\u001b[39m\u001b[33m.\u001b[39m\u001b[33mScreen\u001b[39m name\u001b[33m=\u001b[39m\u001b[32m\"register\"\u001b[39m \u001b[33m/\u001b[39m\u001b[33m>\u001b[39m\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m RootContent (src/app/_layout.tsx:32:13)\u001b[39m\n\u001b[90m RootLayout (src/app/_layout.tsx:50:17)\u001b[39m"]} +{"_e":"metro:client_log","_t":1786669661366,"level":"warn","data":["[Layout children]: Too many screens defined. Route \"register\" is extraneous."]} +{"_e":"metro:client_log","_t":1786669661471,"level":"error","data":["[ReferenceError: Property 'Button' doesn't exist]","\n\n\u001b[1mCode: login.tsx\u001b[22m\n\u001b[0m \u001b[90m 71 |\u001b[39m\n \u001b[90m 72 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mButton\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 73 |\u001b[39m id\u001b[33m=\u001b[39m\u001b[32m\"login-button\"\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 74 |\u001b[39m label\u001b[33m=\u001b[39m\u001b[32m\"Entrar\"\u001b[39m\n \u001b[90m 75 |\u001b[39m fullWidth\n \u001b[90m 76 |\u001b[39m onPress\u001b[33m=\u001b[39m{handleLogin}\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m LoginScreen (src/app/login.tsx:73:42)\u001b[39m","\n\n\u001b[1mCode: _layout.tsx\u001b[22m\n\u001b[0m \u001b[90m 30 |\u001b[39m \u001b[36mreturn\u001b[39m (\n \u001b[90m 31 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mView\u001b[39m style\u001b[33m=\u001b[39m{{ flex\u001b[33m:\u001b[39m \u001b[35m1\u001b[39m\u001b[33m,\u001b[39m backgroundColor\u001b[33m:\u001b[39m \u001b[33mColors\u001b[39m\u001b[33m.\u001b[39mbackground }}\u001b[33m>\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 32 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mStack\u001b[39m screenOptions\u001b[33m=\u001b[39m{{ headerShown\u001b[33m:\u001b[39m \u001b[36mfalse\u001b[39m\u001b[33m,\u001b[39m contentStyle\u001b[33m:\u001b[39m { backgroundColor\u001b[33m:\u001b[39m \u001b[33mColors\u001b[39m\u001b[33m.\u001b[39mbackground } }}\u001b[33m>\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 33 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mStack\u001b[39m\u001b[33m.\u001b[39m\u001b[33mScreen\u001b[39m name\u001b[33m=\u001b[39m\u001b[32m\"(app)\"\u001b[39m \u001b[33m/\u001b[39m\u001b[33m>\u001b[39m\n \u001b[90m 34 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mStack\u001b[39m\u001b[33m.\u001b[39m\u001b[33mScreen\u001b[39m name\u001b[33m=\u001b[39m\u001b[32m\"login\"\u001b[39m \u001b[33m/\u001b[39m\u001b[33m>\u001b[39m\n \u001b[90m 35 |\u001b[39m \u001b[33m<\u001b[39m\u001b[33mStack\u001b[39m\u001b[33m.\u001b[39m\u001b[33mScreen\u001b[39m name\u001b[33m=\u001b[39m\u001b[32m\"register\"\u001b[39m \u001b[33m/\u001b[39m\u001b[33m>\u001b[39m\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m RootContent (src/app/_layout.tsx:32:13)\u001b[39m\n\u001b[90m RootLayout (src/app/_layout.tsx:50:17)\u001b[39m"]} +{"_e":"metro:client_log","_t":1786669704278,"level":"warn","data":["[Layout children]: Too many screens defined. Route \"register\" is extraneous."]} +{"_e":"metro:client_log","_t":1786669729835,"level":"warn","data":["[Layout children]: Too many screens defined. Route \"register\" is extraneous."]} +{"_e":"metro:bundling:failed","_t":1786669797566,"id":null,"message":"Unable to resolve \"@/components/ui/Button\" from \"src/app/register.tsx\"\n 6 | import * as LocalAuthentication from 'expo-local-authentication';\n 7 | import * as SecureStore from 'expo-secure-store';\n> 8 | import { Button } from '@/components/ui/Button';\n | ^\n 9 | import { Input } from '@/components/ui/Input';\n 10 | import { Colors, Spacing, Typography } from '@/theme/tokens';\n 11 | import { useAuth } from '@/contexts/AuthContext';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/register.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@/components/ui/Button\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@/components/ui/Button","originModulePath":"src/app/register.tsx"} +{"_e":"metro:bundling:failed","_t":1786669797720,"id":null,"message":"Unable to resolve \"@/components/ui/Button\" from \"src/app/register.tsx\"\n 6 | import * as LocalAuthentication from 'expo-local-authentication';\n 7 | import * as SecureStore from 'expo-secure-store';\n> 8 | import { Button } from '@/components/ui/Button';\n | ^\n 9 | import { Input } from '@/components/ui/Input';\n 10 | import { Colors, Spacing, Typography } from '@/theme/tokens';\n 11 | import { useAuth } from '@/contexts/AuthContext';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/register.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@/components/ui/Button\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@/components/ui/Button","originModulePath":"src/app/register.tsx"} +{"_e":"metro:bundling:failed","_t":1786669798743,"id":null,"message":"Unable to resolve \"@/components/ui/Button\" from \"src/app/register.tsx\"\n 6 | import * as LocalAuthentication from 'expo-local-authentication';\n 7 | import * as SecureStore from 'expo-secure-store';\n> 8 | import { Button } from '@/components/ui/Button';\n | ^\n 9 | import { Input } from '@/components/ui/Input';\n 10 | import { Colors, Spacing, Typography } from '@/theme/tokens';\n 11 | import { useAuth } from '@/contexts/AuthContext';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/register.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@/components/ui/Button\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@/components/ui/Button","originModulePath":"src/app/register.tsx"} +{"_e":"metro:bundling:failed","_t":1786669798811,"id":null,"message":"Unable to resolve \"@/components/ui/Button\" from \"src/app/register.tsx\"\n 6 | import * as LocalAuthentication from 'expo-local-authentication';\n 7 | import * as SecureStore from 'expo-secure-store';\n> 8 | import { Button } from '@/components/ui/Button';\n | ^\n 9 | import { Input } from '@/components/ui/Input';\n 10 | import { Colors, Spacing, Typography } from '@/theme/tokens';\n 11 | import { useAuth } from '@/contexts/AuthContext';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/register.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@/components/ui/Button\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@/components/ui/Button","originModulePath":"src/app/register.tsx"} +{"_e":"metro:bundling:failed","_t":1786669800791,"id":null,"message":"Unable to resolve \"@/components/ui/Button\" from \"src/app/register.tsx\"\n 6 | import * as LocalAuthentication from 'expo-local-authentication';\n 7 | import * as SecureStore from 'expo-secure-store';\n> 8 | import { Button } from '@/components/ui/Button';\n | ^\n 9 | import { Input } from '@/components/ui/Input';\n 10 | import { Colors, Spacing, Typography } from '@/theme/tokens';\n 11 | import { useAuth } from '@/contexts/AuthContext';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/register.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@/components/ui/Button\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@/components/ui/Button","originModulePath":"src/app/register.tsx"} +{"_e":"metro:bundling:failed","_t":1786669802489,"id":null,"message":"Unable to resolve \"@/components/ui/Button\" from \"src/app/register.tsx\"\n 6 | import * as LocalAuthentication from 'expo-local-authentication';\n 7 | import * as SecureStore from 'expo-secure-store';\n> 8 | import { Button } from '@/components/ui/Button';\n | ^\n 9 | import { Input } from '@/components/ui/Input';\n 10 | import { Colors, Spacing, Typography } from '@/theme/tokens';\n 11 | import { useAuth } from '@/contexts/AuthContext';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/register.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@/components/ui/Button\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@/components/ui/Button","originModulePath":"src/app/register.tsx"} +{"_e":"metro:bundling:failed","_t":1786669803514,"id":null,"message":"Unable to resolve \"@/components/ui/Button\" from \"src/app/register.tsx\"\n 6 | import * as LocalAuthentication from 'expo-local-authentication';\n 7 | import * as SecureStore from 'expo-secure-store';\n> 8 | import { Button } from '@/components/ui/Button';\n | ^\n 9 | import { Input } from '@/components/ui/Input';\n 10 | import { Colors, Spacing, Typography } from '@/theme/tokens';\n 11 | import { useAuth } from '@/contexts/AuthContext';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/register.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@/components/ui/Button\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@/components/ui/Button","originModulePath":"src/app/register.tsx"} +{"_e":"metro:bundling:failed","_t":1786669803729,"id":null,"message":"Unable to resolve \"@/components/ui/Button\" from \"src/app/register.tsx\"\n 6 | import * as LocalAuthentication from 'expo-local-authentication';\n 7 | import * as SecureStore from 'expo-secure-store';\n> 8 | import { Button } from '@/components/ui/Button';\n | ^\n 9 | import { Input } from '@/components/ui/Input';\n 10 | import { Colors, Spacing, Typography } from '@/theme/tokens';\n 11 | import { useAuth } from '@/contexts/AuthContext';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/register.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@/components/ui/Button\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@/components/ui/Button","originModulePath":"src/app/register.tsx"} +{"_e":"metro:bundling:failed","_t":1786669805935,"id":null,"message":"Unable to resolve \"@/components/ui/Button\" from \"src/app/register.tsx\"\n 6 | import * as LocalAuthentication from 'expo-local-authentication';\n 7 | import * as SecureStore from 'expo-secure-store';\n> 8 | import { Button } from '@/components/ui/Button';\n | ^\n 9 | import { Input } from '@/components/ui/Input';\n 10 | import { Colors, Spacing, Typography } from '@/theme/tokens';\n 11 | import { useAuth } from '@/contexts/AuthContext';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/register.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@/components/ui/Button\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@/components/ui/Button","originModulePath":"src/app/register.tsx"} +{"_e":"metro:bundling:failed","_t":1786669899473,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/Button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/theme/tokens';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669899505,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/Button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/theme/tokens';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669900463,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/Button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/theme/tokens';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669900710,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/Button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/theme/tokens';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669902722,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/Button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/theme/tokens';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669903744,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/Button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/theme/tokens';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669903990,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/Button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/theme/tokens';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669905934,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/Button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/theme/tokens';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669908904,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669908912,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669909961,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669910484,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669912137,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669913157,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669913462,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669915844,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669925595,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669925927,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669926214,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669926797,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669927334,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669927726,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669928054,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669928316,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669928604,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669928857,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669929052,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669929341,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669930964,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669931335,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669935249,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669935571,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669935804,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669936061,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669936572,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669936854,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669937150,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669937524,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669937752,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669942049,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669942315,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669942636,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669942871,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669943064,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669951314,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:bundling:failed","_t":1786669951707,"id":null,"message":"Unable to resolve \"@expo/vector-icons\" from \"src/app/biometrics.tsx\"\n 4 | import * as SecureStore from 'expo-secure-store';\n 5 | import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated';\n> 6 | import { Feather } from '@expo/vector-icons';\n | ^\n 7 | import { useSafeAreaInsets } from 'react-native-safe-area-context';\n 8 | import { Button } from '@/components/ui/button';\n 9 | import { Colors, Spacing, Typography, Radius } from '@/constants/theme';","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/biometrics.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@expo/vector-icons\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@expo/vector-icons","originModulePath":"src/app/biometrics.tsx"} +{"_e":"metro:client_log","_t":1786670156434,"level":"error","data":["API Error (400):","{\"error\":\"Email já está em uso.\"}","\n\n\u001b[1mCode: api.ts\u001b[22m\n\u001b[0m \u001b[90m 39 |\u001b[39m \u001b[36mif\u001b[39m (\u001b[33m!\u001b[39mresponse\u001b[33m.\u001b[39mok) {\n \u001b[90m 40 |\u001b[39m \u001b[36mconst\u001b[39m errorText \u001b[33m=\u001b[39m \u001b[36mawait\u001b[39m response\u001b[33m.\u001b[39mtext()\u001b[33m;\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 41 |\u001b[39m console\u001b[33m.\u001b[39merror(\u001b[32m`API Error (${response.status}):`\u001b[39m\u001b[33m,\u001b[39m errorText)\u001b[33m;\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 42 |\u001b[39m \u001b[36mthrow\u001b[39m \u001b[36mnew\u001b[39m \u001b[33mError\u001b[39m(\u001b[32m`API Error: ${response.status}`\u001b[39m)\u001b[33m;\u001b[39m\n \u001b[90m 43 |\u001b[39m }\n \u001b[90m 44 |\u001b[39m \u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m fetcher (src/services/api.ts:41:26)\u001b[39m"]} +{"_e":"metro:client_log","_t":1786670156435,"level":"error","data":["Fetch Error on /auth/register:","[Error: API Error: 400]","\n\n\u001b[1mCode: api.ts\u001b[22m\n\u001b[0m \u001b[90m 40 |\u001b[39m \u001b[36mconst\u001b[39m errorText \u001b[33m=\u001b[39m \u001b[36mawait\u001b[39m response\u001b[33m.\u001b[39mtext()\u001b[33m;\u001b[39m\n \u001b[90m 41 |\u001b[39m console\u001b[33m.\u001b[39merror(\u001b[32m`API Error (${response.status}):`\u001b[39m\u001b[33m,\u001b[39m errorText)\u001b[33m;\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 42 |\u001b[39m \u001b[36mthrow\u001b[39m \u001b[36mnew\u001b[39m \u001b[33mError\u001b[39m(\u001b[32m`API Error: ${response.status}`\u001b[39m)\u001b[33m;\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 43 |\u001b[39m }\n \u001b[90m 44 |\u001b[39m \n \u001b[90m 45 |\u001b[39m \u001b[36mconst\u001b[39m data \u001b[33m=\u001b[39m \u001b[36mawait\u001b[39m response\u001b[33m.\u001b[39mjson()\u001b[33m;\u001b[39m\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m fetcher (src/services/api.ts:42:28)\u001b[39m"]} +{"_e":"metro:client_log","_t":1786670446248,"level":"error","data":["API Error (400):","{\"error\":\"Email já está em uso.\"}","\n\n\u001b[1mCode: api.ts\u001b[22m\n\u001b[0m \u001b[90m 39 |\u001b[39m \u001b[36mif\u001b[39m (\u001b[33m!\u001b[39mresponse\u001b[33m.\u001b[39mok) {\n \u001b[90m 40 |\u001b[39m \u001b[36mconst\u001b[39m errorText \u001b[33m=\u001b[39m \u001b[36mawait\u001b[39m response\u001b[33m.\u001b[39mtext()\u001b[33m;\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 41 |\u001b[39m console\u001b[33m.\u001b[39merror(\u001b[32m`API Error (${response.status}):`\u001b[39m\u001b[33m,\u001b[39m errorText)\u001b[33m;\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 42 |\u001b[39m \u001b[36mthrow\u001b[39m \u001b[36mnew\u001b[39m \u001b[33mError\u001b[39m(\u001b[32m`API Error: ${response.status}`\u001b[39m)\u001b[33m;\u001b[39m\n \u001b[90m 43 |\u001b[39m }\n \u001b[90m 44 |\u001b[39m \u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m fetcher (src/services/api.ts:41:26)\u001b[39m"]} +{"_e":"metro:client_log","_t":1786670446249,"level":"error","data":["Fetch Error on /auth/register:","[Error: API Error: 400]","\n\n\u001b[1mCode: api.ts\u001b[22m\n\u001b[0m \u001b[90m 40 |\u001b[39m \u001b[36mconst\u001b[39m errorText \u001b[33m=\u001b[39m \u001b[36mawait\u001b[39m response\u001b[33m.\u001b[39mtext()\u001b[33m;\u001b[39m\n \u001b[90m 41 |\u001b[39m console\u001b[33m.\u001b[39merror(\u001b[32m`API Error (${response.status}):`\u001b[39m\u001b[33m,\u001b[39m errorText)\u001b[33m;\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 42 |\u001b[39m \u001b[36mthrow\u001b[39m \u001b[36mnew\u001b[39m \u001b[33mError\u001b[39m(\u001b[32m`API Error: ${response.status}`\u001b[39m)\u001b[33m;\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 43 |\u001b[39m }\n \u001b[90m 44 |\u001b[39m \n \u001b[90m 45 |\u001b[39m \u001b[36mconst\u001b[39m data \u001b[33m=\u001b[39m \u001b[36mawait\u001b[39m response\u001b[33m.\u001b[39mjson()\u001b[33m;\u001b[39m\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m fetcher (src/services/api.ts:42:28)\u001b[39m"]} +{"_e":"metro:client_log","_t":1786670496583,"level":"error","data":["API Error (401):","{\"error\":\"Email ou senha inválidos.\"}","\n\n\u001b[1mCode: api.ts\u001b[22m\n\u001b[0m \u001b[90m 39 |\u001b[39m \u001b[36mif\u001b[39m (\u001b[33m!\u001b[39mresponse\u001b[33m.\u001b[39mok) {\n \u001b[90m 40 |\u001b[39m \u001b[36mconst\u001b[39m errorText \u001b[33m=\u001b[39m \u001b[36mawait\u001b[39m response\u001b[33m.\u001b[39mtext()\u001b[33m;\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 41 |\u001b[39m console\u001b[33m.\u001b[39merror(\u001b[32m`API Error (${response.status}):`\u001b[39m\u001b[33m,\u001b[39m errorText)\u001b[33m;\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 42 |\u001b[39m \u001b[36mthrow\u001b[39m \u001b[36mnew\u001b[39m \u001b[33mError\u001b[39m(\u001b[32m`API Error: ${response.status}`\u001b[39m)\u001b[33m;\u001b[39m\n \u001b[90m 43 |\u001b[39m }\n \u001b[90m 44 |\u001b[39m \u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m fetcher (src/services/api.ts:41:26)\u001b[39m"]} +{"_e":"metro:client_log","_t":1786670496587,"level":"error","data":["Fetch Error on /auth/login:","[Error: API Error: 401]","\n\n\u001b[1mCode: api.ts\u001b[22m\n\u001b[0m \u001b[90m 40 |\u001b[39m \u001b[36mconst\u001b[39m errorText \u001b[33m=\u001b[39m \u001b[36mawait\u001b[39m response\u001b[33m.\u001b[39mtext()\u001b[33m;\u001b[39m\n \u001b[90m 41 |\u001b[39m console\u001b[33m.\u001b[39merror(\u001b[32m`API Error (${response.status}):`\u001b[39m\u001b[33m,\u001b[39m errorText)\u001b[33m;\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 42 |\u001b[39m \u001b[36mthrow\u001b[39m \u001b[36mnew\u001b[39m \u001b[33mError\u001b[39m(\u001b[32m`API Error: ${response.status}`\u001b[39m)\u001b[33m;\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 43 |\u001b[39m }\n \u001b[90m 44 |\u001b[39m \n \u001b[90m 45 |\u001b[39m \u001b[36mconst\u001b[39m data \u001b[33m=\u001b[39m \u001b[36mawait\u001b[39m response\u001b[33m.\u001b[39mjson()\u001b[33m;\u001b[39m\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m fetcher (src/services/api.ts:42:28)\u001b[39m"]} +{"_e":"metro:client_log","_t":1786670513450,"level":"error","data":["API Error (401):","{\"error\":\"Email ou senha inválidos.\"}","\n\n\u001b[1mCode: api.ts\u001b[22m\n\u001b[0m \u001b[90m 39 |\u001b[39m \u001b[36mif\u001b[39m (\u001b[33m!\u001b[39mresponse\u001b[33m.\u001b[39mok) {\n \u001b[90m 40 |\u001b[39m \u001b[36mconst\u001b[39m errorText \u001b[33m=\u001b[39m \u001b[36mawait\u001b[39m response\u001b[33m.\u001b[39mtext()\u001b[33m;\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 41 |\u001b[39m console\u001b[33m.\u001b[39merror(\u001b[32m`API Error (${response.status}):`\u001b[39m\u001b[33m,\u001b[39m errorText)\u001b[33m;\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 42 |\u001b[39m \u001b[36mthrow\u001b[39m \u001b[36mnew\u001b[39m \u001b[33mError\u001b[39m(\u001b[32m`API Error: ${response.status}`\u001b[39m)\u001b[33m;\u001b[39m\n \u001b[90m 43 |\u001b[39m }\n \u001b[90m 44 |\u001b[39m \u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m fetcher (src/services/api.ts:41:26)\u001b[39m"]} +{"_e":"metro:client_log","_t":1786670513453,"level":"error","data":["Fetch Error on /auth/login:","[Error: API Error: 401]","\n\n\u001b[1mCode: api.ts\u001b[22m\n\u001b[0m \u001b[90m 40 |\u001b[39m \u001b[36mconst\u001b[39m errorText \u001b[33m=\u001b[39m \u001b[36mawait\u001b[39m response\u001b[33m.\u001b[39mtext()\u001b[33m;\u001b[39m\n \u001b[90m 41 |\u001b[39m console\u001b[33m.\u001b[39merror(\u001b[32m`API Error (${response.status}):`\u001b[39m\u001b[33m,\u001b[39m errorText)\u001b[33m;\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 42 |\u001b[39m \u001b[36mthrow\u001b[39m \u001b[36mnew\u001b[39m \u001b[33mError\u001b[39m(\u001b[32m`API Error: ${response.status}`\u001b[39m)\u001b[33m;\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 43 |\u001b[39m }\n \u001b[90m 44 |\u001b[39m \n \u001b[90m 45 |\u001b[39m \u001b[36mconst\u001b[39m data \u001b[33m=\u001b[39m \u001b[36mawait\u001b[39m response\u001b[33m.\u001b[39mjson()\u001b[33m;\u001b[39m\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m fetcher (src/services/api.ts:42:28)\u001b[39m"]} +{"_e":"metro:client_log","_t":1786670525231,"level":"error","data":["API Error (401):","{\"error\":\"Email ou senha inválidos.\"}","\n\n\u001b[1mCode: api.ts\u001b[22m\n\u001b[0m \u001b[90m 39 |\u001b[39m \u001b[36mif\u001b[39m (\u001b[33m!\u001b[39mresponse\u001b[33m.\u001b[39mok) {\n \u001b[90m 40 |\u001b[39m \u001b[36mconst\u001b[39m errorText \u001b[33m=\u001b[39m \u001b[36mawait\u001b[39m response\u001b[33m.\u001b[39mtext()\u001b[33m;\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 41 |\u001b[39m console\u001b[33m.\u001b[39merror(\u001b[32m`API Error (${response.status}):`\u001b[39m\u001b[33m,\u001b[39m errorText)\u001b[33m;\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 42 |\u001b[39m \u001b[36mthrow\u001b[39m \u001b[36mnew\u001b[39m \u001b[33mError\u001b[39m(\u001b[32m`API Error: ${response.status}`\u001b[39m)\u001b[33m;\u001b[39m\n \u001b[90m 43 |\u001b[39m }\n \u001b[90m 44 |\u001b[39m \u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m fetcher (src/services/api.ts:41:26)\u001b[39m"]} +{"_e":"metro:client_log","_t":1786670525235,"level":"error","data":["Fetch Error on /auth/login:","[Error: API Error: 401]","\n\n\u001b[1mCode: api.ts\u001b[22m\n\u001b[0m \u001b[90m 40 |\u001b[39m \u001b[36mconst\u001b[39m errorText \u001b[33m=\u001b[39m \u001b[36mawait\u001b[39m response\u001b[33m.\u001b[39mtext()\u001b[33m;\u001b[39m\n \u001b[90m 41 |\u001b[39m console\u001b[33m.\u001b[39merror(\u001b[32m`API Error (${response.status}):`\u001b[39m\u001b[33m,\u001b[39m errorText)\u001b[33m;\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 42 |\u001b[39m \u001b[36mthrow\u001b[39m \u001b[36mnew\u001b[39m \u001b[33mError\u001b[39m(\u001b[32m`API Error: ${response.status}`\u001b[39m)\u001b[33m;\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 43 |\u001b[39m }\n \u001b[90m 44 |\u001b[39m \n \u001b[90m 45 |\u001b[39m \u001b[36mconst\u001b[39m data \u001b[33m=\u001b[39m \u001b[36mawait\u001b[39m response\u001b[33m.\u001b[39mjson()\u001b[33m;\u001b[39m\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m fetcher (src/services/api.ts:42:28)\u001b[39m"]} +{"_e":"metro:client_log","_t":1786670536089,"level":"error","data":["API Error (401):","{\"error\":\"Email ou senha inválidos.\"}","\n\n\u001b[1mCode: api.ts\u001b[22m\n\u001b[0m \u001b[90m 39 |\u001b[39m \u001b[36mif\u001b[39m (\u001b[33m!\u001b[39mresponse\u001b[33m.\u001b[39mok) {\n \u001b[90m 40 |\u001b[39m \u001b[36mconst\u001b[39m errorText \u001b[33m=\u001b[39m \u001b[36mawait\u001b[39m response\u001b[33m.\u001b[39mtext()\u001b[33m;\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 41 |\u001b[39m console\u001b[33m.\u001b[39merror(\u001b[32m`API Error (${response.status}):`\u001b[39m\u001b[33m,\u001b[39m errorText)\u001b[33m;\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 42 |\u001b[39m \u001b[36mthrow\u001b[39m \u001b[36mnew\u001b[39m \u001b[33mError\u001b[39m(\u001b[32m`API Error: ${response.status}`\u001b[39m)\u001b[33m;\u001b[39m\n \u001b[90m 43 |\u001b[39m }\n \u001b[90m 44 |\u001b[39m \u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m fetcher (src/services/api.ts:41:26)\u001b[39m"]} +{"_e":"metro:client_log","_t":1786670536092,"level":"error","data":["Fetch Error on /auth/login:","[Error: API Error: 401]","\n\n\u001b[1mCode: api.ts\u001b[22m\n\u001b[0m \u001b[90m 40 |\u001b[39m \u001b[36mconst\u001b[39m errorText \u001b[33m=\u001b[39m \u001b[36mawait\u001b[39m response\u001b[33m.\u001b[39mtext()\u001b[33m;\u001b[39m\n \u001b[90m 41 |\u001b[39m console\u001b[33m.\u001b[39merror(\u001b[32m`API Error (${response.status}):`\u001b[39m\u001b[33m,\u001b[39m errorText)\u001b[33m;\u001b[39m\n\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 42 |\u001b[39m \u001b[36mthrow\u001b[39m \u001b[36mnew\u001b[39m \u001b[33mError\u001b[39m(\u001b[32m`API Error: ${response.status}`\u001b[39m)\u001b[33m;\u001b[39m\n \u001b[90m |\u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\n \u001b[90m 43 |\u001b[39m }\n \u001b[90m 44 |\u001b[39m \n \u001b[90m 45 |\u001b[39m \u001b[36mconst\u001b[39m data \u001b[33m=\u001b[39m \u001b[36mawait\u001b[39m response\u001b[33m.\u001b[39mjson()\u001b[33m;\u001b[39m\u001b[0m\n\u001b[1mCall Stack\u001b[22m\n\u001b[90m fetcher (src/services/api.ts:42:28)\u001b[39m"]} +{"_e":"metro:client_log","_t":1786670555045,"level":"warn","data":["Unable to get the view config for ExpoBlurView from module &s ExpoBlur"]} +{"_e":"root:init","_t":1786670664496,"format":"v0-jsonl","version":"57.0.14"} +{"_e":"devserver:start","_t":1786670664510,"mode":"development","web":true,"baseUrl":"","asyncRoutes":false,"routerRoot":"../../../src/app","serverComponents":false,"serverActions":false,"serverRendering":true,"apiRoutes":false,"exporting":false} +{"_e":"metro:config","_t":1786670664699,"serverRoot":"../../..","projectRoot":"../../..","exporting":false,"flags":{"autolinkingModuleResolution":false,"serverActions":false,"serverComponents":false,"reactCompiler":true,"optimizeGraph":false,"treeshaking":false,"logbox":false}} +{"_e":"expo:dev-tools-plugin:load","_t":1786670664898,"plugins":[]} +{"_e":"metro:instantiate","_t":1786670665436,"atlas":false,"workers":4,"host":"::","port":8081} +{"_e":"metro:bundling:started","_t":1786670695643,"id":"1","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786670695645,"id":"1","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786670695652,"id":"1","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786670695752,"id":"1","progress":0.1810774105930285,"total":376,"current":160} +{"_e":"metro:bundling:progress","_t":1786670695852,"id":"1","progress":0.48884683311194294,"total":728,"current":509} +{"_e":"metro:bundling:progress","_t":1786670695952,"id":"1","progress":0.6365863226315231,"total":1217,"current":971} +{"_e":"metro:bundling:progress","_t":1786670696052,"id":"1","progress":0.9012369843107826,"total":1579,"current":1499} +{"_e":"metro:bundling:done","_t":1786670696180,"id":"1","total":1579,"ms":535.292083} +{"_e":"metro:bundling:started","_t":1786670918236,"id":"2","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786670918236,"id":"2","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:done","_t":1786670918326,"id":"2","total":1,"ms":89.640708} +{"_e":"root:init","_t":1786708630838,"format":"v0-jsonl","version":"57.0.14"} +{"_e":"devserver:start","_t":1786708630861,"mode":"development","web":true,"baseUrl":"","asyncRoutes":false,"routerRoot":"../../../src/app","serverComponents":false,"serverActions":false,"serverRendering":true,"apiRoutes":false,"exporting":false} +{"_e":"metro:config","_t":1786708631096,"serverRoot":"../../..","projectRoot":"../../..","exporting":false,"flags":{"autolinkingModuleResolution":false,"serverActions":false,"serverComponents":false,"reactCompiler":true,"optimizeGraph":false,"treeshaking":false,"logbox":false}} +{"_e":"expo:dev-tools-plugin:load","_t":1786708631228,"plugins":[]} +{"_e":"metro:instantiate","_t":1786708631929,"atlas":false,"workers":4,"host":"::","port":8081} +{"_e":"metro:bundling:started","_t":1786708662422,"id":"1","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786708662422,"id":"1","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786708662426,"id":"1","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786708662526,"id":"1","progress":0.2433484135841837,"total":448,"current":221} +{"_e":"metro:bundling:progress","_t":1786708662626,"id":"1","progress":0.5102040816326531,"total":875,"current":625} +{"_e":"metro:bundling:progress","_t":1786708662726,"id":"1","progress":0.9316296380589206,"total":1121,"current":1082} +{"_e":"metro:bundling:progress","_t":1786708662827,"id":"1","progress":0.9985113511553523,"total":1343,"current":1342} +{"_e":"metro:bundling:progress","_t":1786708662998,"id":"1","progress":0.999,"total":1343,"current":1343} +{"_e":"metro:bundling:progress","_t":1786708663098,"id":"1","progress":0.999,"total":1705,"current":1670} +{"_e":"metro:bundling:progress","_t":1786708663198,"id":"1","progress":0.999,"total":1821,"current":1819} +{"_e":"metro:bundling:progress","_t":1786708663299,"id":"1","progress":0.999,"total":1824,"current":1822} +{"_e":"metro:bundling:progress","_t":1786708663457,"id":"1","progress":0.999,"total":1824,"current":1823} +{"_e":"metro:bundling:progress","_t":1786708663458,"id":"1","progress":0.999,"total":1824,"current":1824} +{"_e":"metro:bundling:failed","_t":1786708663459,"id":"1","message":"Unable to resolve \"@/screens/DashboardScreen\" from \"src/app/(app)/(tabs)/index.tsx\"\n> 1 | import DashboardScreen from '@/screens/DashboardScreen';\n | ^\n 2 | export default DashboardScreen;\n 3 |","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/app/(app)/(tabs)/index.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@/screens/DashboardScreen\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":"@/screens/DashboardScreen","originModulePath":"src/app/(app)/(tabs)/index.tsx"} +{"_e":"metro:bundling:started","_t":1786708698008,"id":"2","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786708698008,"id":"2","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786708698010,"id":"2","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786708698110,"id":"2","progress":0.30050117154005934,"total":467,"current":256} +{"_e":"metro:bundling:progress","_t":1786708698210,"id":"2","progress":0.5684581465928307,"total":1199,"current":904} +{"_e":"metro:bundling:progress","_t":1786708698310,"id":"2","progress":0.8633092882267152,"total":1496,"current":1390} +{"_e":"metro:bundling:failed","_t":1786708698371,"id":"2","message":"As of SDK 56, expo-router is no longer compatible with react-navigation. For more information, see https://docs.expo.dev/router/migrate/sdk-55-to-56/. You can disable this check by setting the environment variable EXPO_ROUTER_DISABLE_RN_NAVIGATION_CHECK=1.","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/screens/dashboard-screen.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@react-navigation/native\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app/(app)/(tabs)/index.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@/screens/dashboard-screen\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":null,"originModulePath":null} +{"_e":"metro:bundling:started","_t":1786708912534,"id":"3","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786708912534,"id":"3","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786708912538,"id":"3","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786708912638,"id":"3","progress":0.17693373645754598,"total":378,"current":159} +{"_e":"metro:bundling:progress","_t":1786708912738,"id":"3","progress":0.466776091676154,"total":947,"current":647} +{"_e":"metro:bundling:progress","_t":1786708912840,"id":"3","progress":0.7518748881428149,"total":1362,"current":1181} +{"_e":"metro:bundling:progress","_t":1786708912945,"id":"3","progress":0.8895057571869575,"total":1741,"current":1642} +{"_e":"metro:bundling:progress","_t":1786708913044,"id":"3","progress":0.9989062073555536,"total":1828,"current":1827} +{"_e":"metro:bundling:progress","_t":1786708913146,"id":"3","progress":0.9989062073555536,"total":1841,"current":1830} +{"_e":"metro:bundling:progress","_t":1786708913248,"id":"3","progress":0.9989062073555536,"total":1862,"current":1834} +{"_e":"metro:bundling:progress","_t":1786708913365,"id":"3","progress":0.9989062073555536,"total":1870,"current":1841} +{"_e":"metro:bundling:progress","_t":1786708913476,"id":"3","progress":0.9989062073555536,"total":1870,"current":1845} +{"_e":"metro:bundling:progress","_t":1786708913584,"id":"3","progress":0.9989062073555536,"total":1870,"current":1852} +{"_e":"metro:bundling:progress","_t":1786708913684,"id":"3","progress":0.9989062073555536,"total":1872,"current":1862} +{"_e":"metro:bundling:progress","_t":1786708913785,"id":"3","progress":0.9989062073555536,"total":1888,"current":1873} +{"_e":"metro:bundling:progress","_t":1786708913885,"id":"3","progress":0.9989062073555536,"total":1972,"current":1894} +{"_e":"metro:bundling:progress","_t":1786708913985,"id":"3","progress":0.9989062073555536,"total":1979,"current":1935} +{"_e":"metro:bundling:progress","_t":1786708914086,"id":"3","progress":0.9989062073555536,"total":1993,"current":1989} +{"_e":"metro:bundling:done","_t":1786708914220,"id":"3","total":1993,"ms":1686.217166} +{"_e":"metro:bundling:started","_t":1786709009016,"id":"9","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786709009017,"id":"9","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786709009029,"id":"9","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:done","_t":1786709009122,"id":"9","total":1,"ms":105.456209} +{"_e":"metro:client_log","_t":1786709014683,"level":"warn","data":["[Layout children]: Too many screens defined. Route \"salary\" is extraneous."]} +{"_e":"metro:client_log","_t":1786709014699,"level":"warn","data":["[Layout children]: Too many screens defined. Route \"recurring\" is extraneous."]} +{"_e":"metro:client_log","_t":1786709014699,"level":"warn","data":["[Layout children]: Too many screens defined. Route \"expenses\" is extraneous."]} +{"_e":"metro:bundling:started","_t":1786709571016,"id":"a","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786709571017,"id":"a","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786709571026,"id":"a","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:failed","_t":1786709571112,"id":"a","message":"As of SDK 56, expo-router is no longer compatible with react-navigation. For more information, see https://docs.expo.dev/router/migrate/sdk-55-to-56/. You can disable this check by setting the environment variable EXPO_ROUTER_DISABLE_RN_NAVIGATION_CHECK=1.","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/screens/salary-screen.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@react-navigation/native\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app/(app)/(tabs)/salary.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@/screens/salary-screen\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":null,"originModulePath":null} +{"_e":"metro:bundling:started","_t":1786709812789,"id":"b","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786709812790,"id":"b","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786709812798,"id":"b","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786709812899,"id":"b","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:done","_t":1786709812977,"id":"b","total":1,"ms":186.96025} +{"_e":"metro:client_log","_t":1786709818803,"level":"warn","data":["[Layout children]: Too many screens defined. Route \"recurring\" is extraneous."]} +{"_e":"metro:client_log","_t":1786709818828,"level":"warn","data":["[Layout children]: Too many screens defined. Route \"expenses\" is extraneous."]} +{"_e":"metro:server_log","_t":1786710024430,"level":"error","data":["[timeout] connection terminated with Device for app='%s' on device='%s' after not responding for %s seconds.","com.anonymous.yaba","SM-S918B - 16 - API 36","60"]} +{"_e":"metro:bundling:started","_t":1786730119994,"id":"c","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786730119996,"id":"c","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786730120004,"id":"c","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786730120104,"id":"c","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786730120287,"id":"c","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786730120389,"id":"c","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786730120502,"id":"c","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786730120603,"id":"c","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:failed","_t":1786730120702,"id":"c","message":"As of SDK 56, expo-router is no longer compatible with react-navigation. For more information, see https://docs.expo.dev/router/migrate/sdk-55-to-56/. You can disable this check by setting the environment variable EXPO_ROUTER_DISABLE_RN_NAVIGATION_CHECK=1.","importStack":"\u001b[1mImport stack:\u001b[22m\n\n\u001b[90m \u001b[39msrc/screens/recurring-expenses-screen.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@react-navigation/native\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app/(app)/(tabs)/recurring.tsx\n\u001b[90m |\u001b[39m \u001b[36mimport\u001b[39m \u001b[32m\"@/screens/recurring-expenses-screen\"\u001b[39m\n\n\u001b[90m \u001b[39msrc/app\u001b[2m (require.context)\u001b[22m\n","filename":null,"targetModuleName":null,"originModulePath":null} +{"_e":"metro:bundling:started","_t":1786730134607,"id":"d","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786730134607,"id":"d","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786730134615,"id":"d","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786730134717,"id":"d","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786730134818,"id":"d","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:done","_t":1786730134882,"id":"d","total":1,"ms":274.4905} +{"_e":"metro:client_log","_t":1786730140883,"level":"warn","data":["[Layout children]: Too many screens defined. Route \"expenses\" is extraneous."]} +{"_e":"metro:bundling:started","_t":1786730330101,"id":"e","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786730330102,"id":"e","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:progress","_t":1786730330110,"id":"e","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:done","_t":1786730330242,"id":"e","total":1,"ms":140.914208} +{"_e":"metro:bundling:started","_t":1786730404864,"id":"f","platform":"android","environment":null,"entry":"node_modules/expo-router/entry.js"} +{"_e":"metro:bundling:progress","_t":1786730404865,"id":"f","progress":0,"total":1,"current":0} +{"_e":"metro:bundling:done","_t":1786730404939,"id":"f","total":1,"ms":73.694709} diff --git a/.expo/devices.json b/.expo/devices.json new file mode 100644 index 0000000..571b1da --- /dev/null +++ b/.expo/devices.json @@ -0,0 +1,8 @@ +{ + "devices": [ + { + "installationId": "f06b0747-5dd9-402d-ad65-d21673fd02e8", + "lastUsed": 1786730404334 + } + ] +} diff --git a/.expo/types/router.d.ts b/.expo/types/router.d.ts new file mode 100644 index 0000000..fe9ff7f --- /dev/null +++ b/.expo/types/router.d.ts @@ -0,0 +1,14 @@ +/* eslint-disable */ +import * as Router from 'expo-router'; + +export * from 'expo-router'; + +declare module 'expo-router' { + export namespace ExpoRouter { + export interface __routes<T extends string | object = string> { + hrefInputParams: { pathname: Router.RelativePathString, params?: Router.UnknownInputParams } | { pathname: Router.ExternalPathString, params?: Router.UnknownInputParams } | { pathname: `/biometrics`; params?: Router.UnknownInputParams; } | { pathname: `/login`; params?: Router.UnknownInputParams; } | { pathname: `/register`; params?: Router.UnknownInputParams; } | { pathname: `/_sitemap`; params?: Router.UnknownInputParams; } | { pathname: `${'/(app)'}${'/(tabs)'}` | `/`; params?: Router.UnknownInputParams; } | { pathname: `${'/(app)'}${'/(tabs)'}/salary` | `/salary`; params?: Router.UnknownInputParams; } | { pathname: `${'/(app)'}${'/(tabs)'}/recurring` | `/recurring`; params?: Router.UnknownInputParams; } | { pathname: `${'/(app)'}${'/(tabs)'}/expenses` | `/expenses`; params?: Router.UnknownInputParams; }; + hrefOutputParams: { pathname: Router.RelativePathString, params?: Router.UnknownOutputParams } | { pathname: Router.ExternalPathString, params?: Router.UnknownOutputParams } | { pathname: `/biometrics`; params?: Router.UnknownOutputParams; } | { pathname: `/login`; params?: Router.UnknownOutputParams; } | { pathname: `/register`; params?: Router.UnknownOutputParams; } | { pathname: `/_sitemap`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(app)'}${'/(tabs)'}` | `/`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(app)'}${'/(tabs)'}/salary` | `/salary`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(app)'}${'/(tabs)'}/recurring` | `/recurring`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(app)'}${'/(tabs)'}/expenses` | `/expenses`; params?: Router.UnknownOutputParams; }; + href: Router.RelativePathString | Router.ExternalPathString | `/biometrics${`?${string}` | `#${string}` | ''}` | `/login${`?${string}` | `#${string}` | ''}` | `/register${`?${string}` | `#${string}` | ''}` | `/_sitemap${`?${string}` | `#${string}` | ''}` | `${'/(app)'}${'/(tabs)'}${`?${string}` | `#${string}` | ''}` | `/${`?${string}` | `#${string}` | ''}` | `${'/(app)'}${'/(tabs)'}/salary${`?${string}` | `#${string}` | ''}` | `/salary${`?${string}` | `#${string}` | ''}` | `${'/(app)'}${'/(tabs)'}/recurring${`?${string}` | `#${string}` | ''}` | `/recurring${`?${string}` | `#${string}` | ''}` | `${'/(app)'}${'/(tabs)'}/expenses${`?${string}` | `#${string}` | ''}` | `/expenses${`?${string}` | `#${string}` | ''}` | { pathname: Router.RelativePathString, params?: Router.UnknownInputParams } | { pathname: Router.ExternalPathString, params?: Router.UnknownInputParams } | { pathname: `/biometrics`; params?: Router.UnknownInputParams; } | { pathname: `/login`; params?: Router.UnknownInputParams; } | { pathname: `/register`; params?: Router.UnknownInputParams; } | { pathname: `/_sitemap`; params?: Router.UnknownInputParams; } | { pathname: `${'/(app)'}${'/(tabs)'}` | `/`; params?: Router.UnknownInputParams; } | { pathname: `${'/(app)'}${'/(tabs)'}/salary` | `/salary`; params?: Router.UnknownInputParams; } | { pathname: `${'/(app)'}${'/(tabs)'}/recurring` | `/recurring`; params?: Router.UnknownInputParams; } | { pathname: `${'/(app)'}${'/(tabs)'}/expenses` | `/expenses`; params?: Router.UnknownInputParams; }; + } + } +} diff --git a/.expo/web/cache/production/images/android-adaptive-background/android-adaptive-background-fb139c2dee362ebf2070e23b96da6fc0d43f8492de38b8af1fd7223e19b5861d-cover-transparent/icon_108.png b/.expo/web/cache/production/images/android-adaptive-background/android-adaptive-background-fb139c2dee362ebf2070e23b96da6fc0d43f8492de38b8af1fd7223e19b5861d-cover-transparent/icon_108.png Binary files differnew file mode 100644 index 0000000..1e9b3d1 --- /dev/null +++ b/.expo/web/cache/production/images/android-adaptive-background/android-adaptive-background-fb139c2dee362ebf2070e23b96da6fc0d43f8492de38b8af1fd7223e19b5861d-cover-transparent/icon_108.png diff --git a/.expo/web/cache/production/images/android-adaptive-background/android-adaptive-background-fb139c2dee362ebf2070e23b96da6fc0d43f8492de38b8af1fd7223e19b5861d-cover-transparent/icon_162.png b/.expo/web/cache/production/images/android-adaptive-background/android-adaptive-background-fb139c2dee362ebf2070e23b96da6fc0d43f8492de38b8af1fd7223e19b5861d-cover-transparent/icon_162.png Binary files differnew file mode 100644 index 0000000..c02225f --- /dev/null +++ b/.expo/web/cache/production/images/android-adaptive-background/android-adaptive-background-fb139c2dee362ebf2070e23b96da6fc0d43f8492de38b8af1fd7223e19b5861d-cover-transparent/icon_162.png diff --git a/.expo/web/cache/production/images/android-adaptive-background/android-adaptive-background-fb139c2dee362ebf2070e23b96da6fc0d43f8492de38b8af1fd7223e19b5861d-cover-transparent/icon_216.png b/.expo/web/cache/production/images/android-adaptive-background/android-adaptive-background-fb139c2dee362ebf2070e23b96da6fc0d43f8492de38b8af1fd7223e19b5861d-cover-transparent/icon_216.png Binary files differnew file mode 100644 index 0000000..dde133a --- /dev/null +++ b/.expo/web/cache/production/images/android-adaptive-background/android-adaptive-background-fb139c2dee362ebf2070e23b96da6fc0d43f8492de38b8af1fd7223e19b5861d-cover-transparent/icon_216.png diff --git a/.expo/web/cache/production/images/android-adaptive-background/android-adaptive-background-fb139c2dee362ebf2070e23b96da6fc0d43f8492de38b8af1fd7223e19b5861d-cover-transparent/icon_324.png b/.expo/web/cache/production/images/android-adaptive-background/android-adaptive-background-fb139c2dee362ebf2070e23b96da6fc0d43f8492de38b8af1fd7223e19b5861d-cover-transparent/icon_324.png Binary files differnew file mode 100644 index 0000000..55a3581 --- /dev/null +++ b/.expo/web/cache/production/images/android-adaptive-background/android-adaptive-background-fb139c2dee362ebf2070e23b96da6fc0d43f8492de38b8af1fd7223e19b5861d-cover-transparent/icon_324.png diff --git a/.expo/web/cache/production/images/android-adaptive-background/android-adaptive-background-fb139c2dee362ebf2070e23b96da6fc0d43f8492de38b8af1fd7223e19b5861d-cover-transparent/icon_432.png b/.expo/web/cache/production/images/android-adaptive-background/android-adaptive-background-fb139c2dee362ebf2070e23b96da6fc0d43f8492de38b8af1fd7223e19b5861d-cover-transparent/icon_432.png Binary files differnew file mode 100644 index 0000000..d190cdd --- /dev/null +++ b/.expo/web/cache/production/images/android-adaptive-background/android-adaptive-background-fb139c2dee362ebf2070e23b96da6fc0d43f8492de38b8af1fd7223e19b5861d-cover-transparent/icon_432.png diff --git a/.expo/web/cache/production/images/android-adaptive-foreground/android-adaptive-foreground-9e3d0315a33c6799de601dd34cd8bf8cc3a8d16f3bf75592baec2ceb7240b391-cover-transparent/icon_108.png b/.expo/web/cache/production/images/android-adaptive-foreground/android-adaptive-foreground-9e3d0315a33c6799de601dd34cd8bf8cc3a8d16f3bf75592baec2ceb7240b391-cover-transparent/icon_108.png Binary files differnew file mode 100644 index 0000000..46ea7d0 --- /dev/null +++ b/.expo/web/cache/production/images/android-adaptive-foreground/android-adaptive-foreground-9e3d0315a33c6799de601dd34cd8bf8cc3a8d16f3bf75592baec2ceb7240b391-cover-transparent/icon_108.png diff --git a/.expo/web/cache/production/images/android-adaptive-foreground/android-adaptive-foreground-9e3d0315a33c6799de601dd34cd8bf8cc3a8d16f3bf75592baec2ceb7240b391-cover-transparent/icon_162.png b/.expo/web/cache/production/images/android-adaptive-foreground/android-adaptive-foreground-9e3d0315a33c6799de601dd34cd8bf8cc3a8d16f3bf75592baec2ceb7240b391-cover-transparent/icon_162.png Binary files differnew file mode 100644 index 0000000..49a260f --- /dev/null +++ b/.expo/web/cache/production/images/android-adaptive-foreground/android-adaptive-foreground-9e3d0315a33c6799de601dd34cd8bf8cc3a8d16f3bf75592baec2ceb7240b391-cover-transparent/icon_162.png diff --git a/.expo/web/cache/production/images/android-adaptive-foreground/android-adaptive-foreground-9e3d0315a33c6799de601dd34cd8bf8cc3a8d16f3bf75592baec2ceb7240b391-cover-transparent/icon_216.png b/.expo/web/cache/production/images/android-adaptive-foreground/android-adaptive-foreground-9e3d0315a33c6799de601dd34cd8bf8cc3a8d16f3bf75592baec2ceb7240b391-cover-transparent/icon_216.png Binary files differnew file mode 100644 index 0000000..671b75f --- /dev/null +++ b/.expo/web/cache/production/images/android-adaptive-foreground/android-adaptive-foreground-9e3d0315a33c6799de601dd34cd8bf8cc3a8d16f3bf75592baec2ceb7240b391-cover-transparent/icon_216.png diff --git a/.expo/web/cache/production/images/android-adaptive-foreground/android-adaptive-foreground-9e3d0315a33c6799de601dd34cd8bf8cc3a8d16f3bf75592baec2ceb7240b391-cover-transparent/icon_324.png b/.expo/web/cache/production/images/android-adaptive-foreground/android-adaptive-foreground-9e3d0315a33c6799de601dd34cd8bf8cc3a8d16f3bf75592baec2ceb7240b391-cover-transparent/icon_324.png Binary files differnew file mode 100644 index 0000000..ba86612 --- /dev/null +++ b/.expo/web/cache/production/images/android-adaptive-foreground/android-adaptive-foreground-9e3d0315a33c6799de601dd34cd8bf8cc3a8d16f3bf75592baec2ceb7240b391-cover-transparent/icon_324.png diff --git a/.expo/web/cache/production/images/android-adaptive-foreground/android-adaptive-foreground-9e3d0315a33c6799de601dd34cd8bf8cc3a8d16f3bf75592baec2ceb7240b391-cover-transparent/icon_432.png b/.expo/web/cache/production/images/android-adaptive-foreground/android-adaptive-foreground-9e3d0315a33c6799de601dd34cd8bf8cc3a8d16f3bf75592baec2ceb7240b391-cover-transparent/icon_432.png Binary files differnew file mode 100644 index 0000000..3468026 --- /dev/null +++ b/.expo/web/cache/production/images/android-adaptive-foreground/android-adaptive-foreground-9e3d0315a33c6799de601dd34cd8bf8cc3a8d16f3bf75592baec2ceb7240b391-cover-transparent/icon_432.png diff --git a/.expo/web/cache/production/images/android-adaptive-monochrome/android-adaptive-monochrome-6371fc2c12e33ad2215a86c281db3d682a81bebe7c957a842c13b8bf00cceb83-cover-transparent/icon_108.png b/.expo/web/cache/production/images/android-adaptive-monochrome/android-adaptive-monochrome-6371fc2c12e33ad2215a86c281db3d682a81bebe7c957a842c13b8bf00cceb83-cover-transparent/icon_108.png Binary files differnew file mode 100644 index 0000000..12a3278 --- /dev/null +++ b/.expo/web/cache/production/images/android-adaptive-monochrome/android-adaptive-monochrome-6371fc2c12e33ad2215a86c281db3d682a81bebe7c957a842c13b8bf00cceb83-cover-transparent/icon_108.png diff --git a/.expo/web/cache/production/images/android-adaptive-monochrome/android-adaptive-monochrome-6371fc2c12e33ad2215a86c281db3d682a81bebe7c957a842c13b8bf00cceb83-cover-transparent/icon_162.png b/.expo/web/cache/production/images/android-adaptive-monochrome/android-adaptive-monochrome-6371fc2c12e33ad2215a86c281db3d682a81bebe7c957a842c13b8bf00cceb83-cover-transparent/icon_162.png Binary files differnew file mode 100644 index 0000000..fc1087b --- /dev/null +++ b/.expo/web/cache/production/images/android-adaptive-monochrome/android-adaptive-monochrome-6371fc2c12e33ad2215a86c281db3d682a81bebe7c957a842c13b8bf00cceb83-cover-transparent/icon_162.png diff --git a/.expo/web/cache/production/images/android-adaptive-monochrome/android-adaptive-monochrome-6371fc2c12e33ad2215a86c281db3d682a81bebe7c957a842c13b8bf00cceb83-cover-transparent/icon_216.png b/.expo/web/cache/production/images/android-adaptive-monochrome/android-adaptive-monochrome-6371fc2c12e33ad2215a86c281db3d682a81bebe7c957a842c13b8bf00cceb83-cover-transparent/icon_216.png Binary files differnew file mode 100644 index 0000000..2809d31 --- /dev/null +++ b/.expo/web/cache/production/images/android-adaptive-monochrome/android-adaptive-monochrome-6371fc2c12e33ad2215a86c281db3d682a81bebe7c957a842c13b8bf00cceb83-cover-transparent/icon_216.png diff --git a/.expo/web/cache/production/images/android-adaptive-monochrome/android-adaptive-monochrome-6371fc2c12e33ad2215a86c281db3d682a81bebe7c957a842c13b8bf00cceb83-cover-transparent/icon_324.png b/.expo/web/cache/production/images/android-adaptive-monochrome/android-adaptive-monochrome-6371fc2c12e33ad2215a86c281db3d682a81bebe7c957a842c13b8bf00cceb83-cover-transparent/icon_324.png Binary files differnew file mode 100644 index 0000000..9dbe470 --- /dev/null +++ b/.expo/web/cache/production/images/android-adaptive-monochrome/android-adaptive-monochrome-6371fc2c12e33ad2215a86c281db3d682a81bebe7c957a842c13b8bf00cceb83-cover-transparent/icon_324.png diff --git a/.expo/web/cache/production/images/android-adaptive-monochrome/android-adaptive-monochrome-6371fc2c12e33ad2215a86c281db3d682a81bebe7c957a842c13b8bf00cceb83-cover-transparent/icon_432.png b/.expo/web/cache/production/images/android-adaptive-monochrome/android-adaptive-monochrome-6371fc2c12e33ad2215a86c281db3d682a81bebe7c957a842c13b8bf00cceb83-cover-transparent/icon_432.png Binary files differnew file mode 100644 index 0000000..8736a27 --- /dev/null +++ b/.expo/web/cache/production/images/android-adaptive-monochrome/android-adaptive-monochrome-6371fc2c12e33ad2215a86c281db3d682a81bebe7c957a842c13b8bf00cceb83-cover-transparent/icon_432.png diff --git a/.expo/web/cache/production/images/android-standard-circle/android-standard-circle-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_144.png b/.expo/web/cache/production/images/android-standard-circle/android-standard-circle-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_144.png Binary files differnew file mode 100644 index 0000000..c8c582d --- /dev/null +++ b/.expo/web/cache/production/images/android-standard-circle/android-standard-circle-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_144.png diff --git a/.expo/web/cache/production/images/android-standard-circle/android-standard-circle-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_192.png b/.expo/web/cache/production/images/android-standard-circle/android-standard-circle-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_192.png Binary files differnew file mode 100644 index 0000000..2c3e350 --- /dev/null +++ b/.expo/web/cache/production/images/android-standard-circle/android-standard-circle-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_192.png diff --git a/.expo/web/cache/production/images/android-standard-circle/android-standard-circle-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_48.png b/.expo/web/cache/production/images/android-standard-circle/android-standard-circle-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_48.png Binary files differnew file mode 100644 index 0000000..dd4b27a --- /dev/null +++ b/.expo/web/cache/production/images/android-standard-circle/android-standard-circle-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_48.png diff --git a/.expo/web/cache/production/images/android-standard-circle/android-standard-circle-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_72.png b/.expo/web/cache/production/images/android-standard-circle/android-standard-circle-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_72.png Binary files differnew file mode 100644 index 0000000..2153670 --- /dev/null +++ b/.expo/web/cache/production/images/android-standard-circle/android-standard-circle-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_72.png diff --git a/.expo/web/cache/production/images/android-standard-circle/android-standard-circle-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_96.png b/.expo/web/cache/production/images/android-standard-circle/android-standard-circle-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_96.png Binary files differnew file mode 100644 index 0000000..79a6f3d --- /dev/null +++ b/.expo/web/cache/production/images/android-standard-circle/android-standard-circle-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_96.png diff --git a/.expo/web/cache/production/images/android-standard-square/android-standard-square-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_144.png b/.expo/web/cache/production/images/android-standard-square/android-standard-square-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_144.png Binary files differnew file mode 100644 index 0000000..05e3e1c --- /dev/null +++ b/.expo/web/cache/production/images/android-standard-square/android-standard-square-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_144.png diff --git a/.expo/web/cache/production/images/android-standard-square/android-standard-square-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_192.png b/.expo/web/cache/production/images/android-standard-square/android-standard-square-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_192.png Binary files differnew file mode 100644 index 0000000..13f9687 --- /dev/null +++ b/.expo/web/cache/production/images/android-standard-square/android-standard-square-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_192.png diff --git a/.expo/web/cache/production/images/android-standard-square/android-standard-square-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_48.png b/.expo/web/cache/production/images/android-standard-square/android-standard-square-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_48.png Binary files differnew file mode 100644 index 0000000..7d14513 --- /dev/null +++ b/.expo/web/cache/production/images/android-standard-square/android-standard-square-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_48.png diff --git a/.expo/web/cache/production/images/android-standard-square/android-standard-square-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_72.png b/.expo/web/cache/production/images/android-standard-square/android-standard-square-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_72.png Binary files differnew file mode 100644 index 0000000..6b743ad --- /dev/null +++ b/.expo/web/cache/production/images/android-standard-square/android-standard-square-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_72.png diff --git a/.expo/web/cache/production/images/android-standard-square/android-standard-square-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_96.png b/.expo/web/cache/production/images/android-standard-square/android-standard-square-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_96.png Binary files differnew file mode 100644 index 0000000..553d6b5 --- /dev/null +++ b/.expo/web/cache/production/images/android-standard-square/android-standard-square-7a667804bb80a6a424a5daf18a2599c4f32237cf06fe78fc0de45dbb09e0eccf-cover-transparent/icon_96.png diff --git a/.expo/web/cache/production/images/splash-android/splash-android-27b060a757a29038c9618586baa0ba3894dbe60d084c6059df497ff429c2d92f-contain/icon_114.png b/.expo/web/cache/production/images/splash-android/splash-android-27b060a757a29038c9618586baa0ba3894dbe60d084c6059df497ff429c2d92f-contain/icon_114.png Binary files differnew file mode 100644 index 0000000..6c88010 --- /dev/null +++ b/.expo/web/cache/production/images/splash-android/splash-android-27b060a757a29038c9618586baa0ba3894dbe60d084c6059df497ff429c2d92f-contain/icon_114.png diff --git a/.expo/web/cache/production/images/splash-android/splash-android-27b060a757a29038c9618586baa0ba3894dbe60d084c6059df497ff429c2d92f-contain/icon_152.png b/.expo/web/cache/production/images/splash-android/splash-android-27b060a757a29038c9618586baa0ba3894dbe60d084c6059df497ff429c2d92f-contain/icon_152.png Binary files differnew file mode 100644 index 0000000..c0a217a --- /dev/null +++ b/.expo/web/cache/production/images/splash-android/splash-android-27b060a757a29038c9618586baa0ba3894dbe60d084c6059df497ff429c2d92f-contain/icon_152.png diff --git a/.expo/web/cache/production/images/splash-android/splash-android-27b060a757a29038c9618586baa0ba3894dbe60d084c6059df497ff429c2d92f-contain/icon_228.png b/.expo/web/cache/production/images/splash-android/splash-android-27b060a757a29038c9618586baa0ba3894dbe60d084c6059df497ff429c2d92f-contain/icon_228.png Binary files differnew file mode 100644 index 0000000..c9289ca --- /dev/null +++ b/.expo/web/cache/production/images/splash-android/splash-android-27b060a757a29038c9618586baa0ba3894dbe60d084c6059df497ff429c2d92f-contain/icon_228.png diff --git a/.expo/web/cache/production/images/splash-android/splash-android-27b060a757a29038c9618586baa0ba3894dbe60d084c6059df497ff429c2d92f-contain/icon_304.png b/.expo/web/cache/production/images/splash-android/splash-android-27b060a757a29038c9618586baa0ba3894dbe60d084c6059df497ff429c2d92f-contain/icon_304.png Binary files differnew file mode 100644 index 0000000..365ebab --- /dev/null +++ b/.expo/web/cache/production/images/splash-android/splash-android-27b060a757a29038c9618586baa0ba3894dbe60d084c6059df497ff429c2d92f-contain/icon_304.png diff --git a/.expo/web/cache/production/images/splash-android/splash-android-27b060a757a29038c9618586baa0ba3894dbe60d084c6059df497ff429c2d92f-contain/icon_76.png b/.expo/web/cache/production/images/splash-android/splash-android-27b060a757a29038c9618586baa0ba3894dbe60d084c6059df497ff429c2d92f-contain/icon_76.png Binary files differnew file mode 100644 index 0000000..dd7546a --- /dev/null +++ b/.expo/web/cache/production/images/splash-android/splash-android-27b060a757a29038c9618586baa0ba3894dbe60d084c6059df497ff429c2d92f-contain/icon_76.png diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..041ad3c --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ + +# @generated expo-cli sync-2b81b286409207a5da26e14c78851eb30d8ccbdb +# The following patterns were generated by expo-cli + +expo-env.d.ts +# @end expo-cli + +node_modules/ +android/ +ios/
\ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..0e6bc80 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,3 @@ +# Expo HAS CHANGED + +Read the exact versioned docs at https://docs.expo.dev/versions/v57.0.0/ before writing any code. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..43c994c --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015-present 650 Industries, Inc. (aka Expo) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..4d67aec --- /dev/null +++ b/README.md @@ -0,0 +1,56 @@ +# Welcome to your Expo app 👋 + +This is an [Expo](https://expo.dev) project created with [`create-expo-app`](https://www.npmjs.com/package/create-expo-app). + +## Get started + +1. Install dependencies + + ```bash + npm install + ``` + +2. Start the app + + ```bash + npx expo start + ``` + +In the output, you'll find options to open the app in a + +- [development build](https://docs.expo.dev/develop/development-builds/introduction/) +- [Android emulator](https://docs.expo.dev/workflow/android-studio-emulator/) +- [iOS simulator](https://docs.expo.dev/workflow/ios-simulator/) +- [Expo Go](https://expo.dev/go), a limited sandbox for trying out app development with Expo + +You can start developing by editing the files inside the **app** directory. This project uses [file-based routing](https://docs.expo.dev/router/introduction). + +## Get a fresh project + +When you're ready, run: + +```bash +npm run reset-project +``` + +This command will move the starter code to the **app-example** directory and create a blank **app** directory where you can start developing. + +### Other setup steps + +- To set up ESLint for linting, run `npx expo lint`, or follow our guide on ["Using ESLint and Prettier"](https://docs.expo.dev/guides/using-eslint/) +- If you'd like to set up unit testing, follow our guide on ["Unit Testing with Jest"](https://docs.expo.dev/develop/unit-testing/) +- Learn more about the TypeScript setup in this template in our guide on ["Using TypeScript"](https://docs.expo.dev/guides/typescript/) + +## Learn more + +To learn more about developing your project with Expo, look at the following resources: + +- [Expo documentation](https://docs.expo.dev/): Learn fundamentals, or go into advanced topics with our [guides](https://docs.expo.dev/guides). +- [Learn Expo tutorial](https://docs.expo.dev/tutorial/introduction/): Follow a step-by-step tutorial where you'll create a project that runs on Android, iOS, and the web. + +## Join the community + +Join our community of developers creating universal apps. + +- [Expo on GitHub](https://github.com/expo/expo): View our open source platform and contribute. +- [Discord community](https://chat.expo.dev): Chat with Expo users and ask questions. diff --git a/app.json b/app.json new file mode 100644 index 0000000..334b661 --- /dev/null +++ b/app.json @@ -0,0 +1,52 @@ +{ + "expo": { + "name": "YABA", + "slug": "YABA", + "version": "1.0.0", + "orientation": "portrait", + "icon": "./assets/images/icon.png", + "scheme": "YABA", + "userInterfaceStyle": "automatic", + "ios": { + "icon": "./assets/expo.icon" + }, + "android": { + "adaptiveIcon": { + "backgroundColor": "#E6F4FE", + "foregroundImage": "./assets/images/android-icon-foreground.png", + "backgroundImage": "./assets/images/android-icon-background.png", + "monochromeImage": "./assets/images/android-icon-monochrome.png" + }, + "predictiveBackGestureEnabled": false, + "package": "com.lucas.yaba" + }, + "web": { + "output": "static", + "favicon": "./assets/images/favicon.png" + }, + "plugins": [ + "expo-router", + [ + "expo-splash-screen", + { + "backgroundColor": "#208AEF", + "image": "./assets/images/splash-icon.png", + "imageWidth": 76 + } + ], + "expo-secure-store", + "expo-font", + "expo-status-bar" + ], + "experiments": { + "typedRoutes": true, + "reactCompiler": true + }, + "extra": { + "router": {}, + "eas": { + "projectId": "29008d68-2bba-4ab2-8d77-6d2cf5d78f1a" + } + } + } +} diff --git a/assets/.DS_Store b/assets/.DS_Store Binary files differnew file mode 100644 index 0000000..59fbaf7 --- /dev/null +++ b/assets/.DS_Store diff --git a/assets/expo.icon/Assets/expo-symbol 2.svg b/assets/expo.icon/Assets/expo-symbol 2.svg new file mode 100644 index 0000000..51d3676 --- /dev/null +++ b/assets/expo.icon/Assets/expo-symbol 2.svg @@ -0,0 +1,3 @@ +<svg width="652" height="606" viewBox="0 0 652 606" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M353.554 0H298.446C273.006 0 249.684 14.6347 237.962 37.9539L4.37994 502.646C-1.04325 513.435 -1.45067 526.178 3.2716 537.313L22.6123 582.918C34.6475 611.297 72.5404 614.156 88.4414 587.885L309.863 222.063C313.34 216.317 319.439 212.826 326 212.826C332.561 212.826 338.659 216.317 342.137 222.063L563.559 587.885C579.46 614.156 617.352 611.297 629.388 582.918L648.728 537.313C653.451 526.178 653.043 513.435 647.62 502.646L414.038 37.9539C402.316 14.6347 378.994 0 353.554 0Z" fill="white"/> +</svg> diff --git a/assets/expo.icon/Assets/grid.png b/assets/expo.icon/Assets/grid.png Binary files differnew file mode 100644 index 0000000..eefea24 --- /dev/null +++ b/assets/expo.icon/Assets/grid.png diff --git a/assets/expo.icon/icon.json b/assets/expo.icon/icon.json new file mode 100644 index 0000000..7a2c33c --- /dev/null +++ b/assets/expo.icon/icon.json @@ -0,0 +1,40 @@ +{ + "fill" : { + "automatic-gradient" : "extended-srgb:0.00000,0.47843,1.00000,1.00000" + }, + "groups" : [ + { + "layers" : [ + { + "image-name" : "expo-symbol 2.svg", + "name" : "expo-symbol 2", + "position" : { + "scale" : 1, + "translation-in-points" : [ + 1.1008400065293245e-05, + -16.046875 + ] + } + }, + { + "image-name" : "grid.png", + "name" : "grid" + } + ], + "shadow" : { + "kind" : "neutral", + "opacity" : 0.5 + }, + "translucency" : { + "enabled" : true, + "value" : 0.5 + } + } + ], + "supported-platforms" : { + "circles" : [ + "watchOS" + ], + "squares" : "shared" + } +}
\ No newline at end of file diff --git a/assets/images/android-icon-background.png b/assets/images/android-icon-background.png Binary files differnew file mode 100644 index 0000000..5ffefc5 --- /dev/null +++ b/assets/images/android-icon-background.png diff --git a/assets/images/android-icon-foreground.png b/assets/images/android-icon-foreground.png Binary files differnew file mode 100644 index 0000000..3a9e501 --- /dev/null +++ b/assets/images/android-icon-foreground.png diff --git a/assets/images/android-icon-monochrome.png b/assets/images/android-icon-monochrome.png Binary files differnew file mode 100644 index 0000000..77484eb --- /dev/null +++ b/assets/images/android-icon-monochrome.png diff --git a/assets/images/expo-badge-white.png b/assets/images/expo-badge-white.png Binary files differnew file mode 100644 index 0000000..2863067 --- /dev/null +++ b/assets/images/expo-badge-white.png diff --git a/assets/images/expo-badge.png b/assets/images/expo-badge.png Binary files differnew file mode 100644 index 0000000..5d5c5bb --- /dev/null +++ b/assets/images/expo-badge.png diff --git a/assets/images/expo-logo.png b/assets/images/expo-logo.png Binary files differnew file mode 100644 index 0000000..6b1642a --- /dev/null +++ b/assets/images/expo-logo.png diff --git a/assets/images/favicon.png b/assets/images/favicon.png Binary files differnew file mode 100644 index 0000000..408bd74 --- /dev/null +++ b/assets/images/favicon.png diff --git a/assets/images/icon.png b/assets/images/icon.png Binary files differnew file mode 100644 index 0000000..d611bd6 --- /dev/null +++ b/assets/images/icon.png diff --git a/assets/images/logo-glow.png b/assets/images/logo-glow.png Binary files differnew file mode 100644 index 0000000..edc99be --- /dev/null +++ b/assets/images/logo-glow.png diff --git a/assets/images/react-logo.png b/assets/images/react-logo.png Binary files differnew file mode 100644 index 0000000..9d72a9f --- /dev/null +++ b/assets/images/react-logo.png diff --git a/assets/images/react-logo@2x.png b/assets/images/react-logo@2x.png Binary files differnew file mode 100644 index 0000000..2229b13 --- /dev/null +++ b/assets/images/react-logo@2x.png diff --git a/assets/images/react-logo@3x.png b/assets/images/react-logo@3x.png Binary files differnew file mode 100644 index 0000000..a99b203 --- /dev/null +++ b/assets/images/react-logo@3x.png diff --git a/assets/images/splash-icon.png b/assets/images/splash-icon.png Binary files differnew file mode 100644 index 0000000..6b1642a --- /dev/null +++ b/assets/images/splash-icon.png diff --git a/assets/images/tabIcons/explore.png b/assets/images/tabIcons/explore.png Binary files differnew file mode 100644 index 0000000..73d8258 --- /dev/null +++ b/assets/images/tabIcons/explore.png diff --git a/assets/images/tabIcons/explore@2x.png b/assets/images/tabIcons/explore@2x.png Binary files differnew file mode 100644 index 0000000..21b9bd2 --- /dev/null +++ b/assets/images/tabIcons/explore@2x.png diff --git a/assets/images/tabIcons/explore@3x.png b/assets/images/tabIcons/explore@3x.png Binary files differnew file mode 100644 index 0000000..422202d --- /dev/null +++ b/assets/images/tabIcons/explore@3x.png diff --git a/assets/images/tabIcons/home.png b/assets/images/tabIcons/home.png Binary files differnew file mode 100644 index 0000000..ad5699c --- /dev/null +++ b/assets/images/tabIcons/home.png diff --git a/assets/images/tabIcons/home@2x.png b/assets/images/tabIcons/home@2x.png Binary files differnew file mode 100644 index 0000000..22a1f2c --- /dev/null +++ b/assets/images/tabIcons/home@2x.png diff --git a/assets/images/tabIcons/home@3x.png b/assets/images/tabIcons/home@3x.png Binary files differnew file mode 100644 index 0000000..f5d1f9a --- /dev/null +++ b/assets/images/tabIcons/home@3x.png diff --git a/assets/images/tutorial-web.png b/assets/images/tutorial-web.png Binary files differnew file mode 100644 index 0000000..e4a8c58 --- /dev/null +++ b/assets/images/tutorial-web.png diff --git a/bun.lock b/bun.lock new file mode 100644 index 0000000..790417e --- /dev/null +++ b/bun.lock @@ -0,0 +1,1386 @@ +{ + "lockfileVersion": 1, + "configVersion": 1, + "workspaces": { + "": { + "name": "yaba", + "dependencies": { + "@expo-google-fonts/dm-sans": "^0.4.2", + "@expo/ui": "~57.0.10", + "@expo/vector-icons": "^15.0.2", + "@react-navigation/bottom-tabs": "^7.18.16", + "expo": "~57.0.12", + "expo-blur": "~57.0.2", + "expo-constants": "~57.0.10", + "expo-dev-client": "~57.0.11", + "expo-device": "~57.0.1", + "expo-font": "~57.0.1", + "expo-glass-effect": "~57.0.1", + "expo-haptics": "~57.0.1", + "expo-image": "~57.0.2", + "expo-linear-gradient": "~57.0.1", + "expo-linking": "~57.0.5", + "expo-local-authentication": "~57.0.2", + "expo-router": "~57.0.12", + "expo-secure-store": "~57.0.1", + "expo-splash-screen": "~57.0.6", + "expo-status-bar": "~57.0.1", + "expo-symbols": "~57.0.2", + "expo-system-ui": "~57.0.2", + "expo-web-browser": "~57.0.2", + "react": "19.2.3", + "react-dom": "19.2.3", + "react-native": "0.86.2", + "react-native-gesture-handler": "~2.32.0", + "react-native-gifted-charts": "^1.4.78", + "react-native-reanimated": "4.5.1", + "react-native-safe-area-context": "~5.7.0", + "react-native-screens": "~4.26.0", + "react-native-svg": "15.15.4", + "react-native-web": "~0.21.0", + "react-native-worklets": "0.10.1", + }, + "devDependencies": { + "@types/react": "~19.2.2", + "typescript": "~6.0.3", + }, + }, + }, + "packages": { + "@adobe/css-tools": ["@adobe/css-tools@4.5.0", "", {}, "sha512-6OzddxPio9UiWTCemp4N8cYLV2ZN1ncRnV1cVGtve7dhPOtRkleRyx32GQCYSwDYgaHU3USMm84tNsvKzRCa1Q=="], + + "@babel/code-frame": ["@babel/code-frame@7.29.7", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw=="], + + "@babel/compat-data": ["@babel/compat-data@7.29.7", "", {}, "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg=="], + + "@babel/core": ["@babel/core@7.29.7", "", { "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/generator": "^7.29.7", "@babel/helper-compilation-targets": "^7.29.7", "@babel/helper-module-transforms": "^7.29.7", "@babel/helpers": "^7.29.7", "@babel/parser": "^7.29.7", "@babel/template": "^7.29.7", "@babel/traverse": "^7.29.7", "@babel/types": "^7.29.7", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA=="], + + "@babel/generator": ["@babel/generator@7.29.8", "", { "dependencies": { "@babel/parser": "^7.29.8", "@babel/types": "^7.29.8", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg=="], + + "@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.29.7", "", { "dependencies": { "@babel/types": "^7.29.7" } }, "sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw=="], + + "@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.29.7", "", { "dependencies": { "@babel/compat-data": "^7.29.7", "@babel/helper-validator-option": "^7.29.7", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g=="], + + "@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.29.7", "@babel/helper-member-expression-to-functions": "^7.29.7", "@babel/helper-optimise-call-expression": "^7.29.7", "@babel/helper-replace-supers": "^7.29.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7", "@babel/traverse": "^7.29.7", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg=="], + + "@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.29.7", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-907Uymvqgg1dwUA+7IGwFAOSYzQOuzPXKNJ1yxzwPffzkYFg2q2eHi1fIOs6sXkG9NbIUMunnUlkYsfRFNvomg=="], + + "@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.8", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "debug": "^4.4.3", "lodash.debounce": "^4.0.8", "resolve": "^1.22.11" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA=="], + + "@babel/helper-globals": ["@babel/helper-globals@7.29.7", "", {}, "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA=="], + + "@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.29.7", "", { "dependencies": { "@babel/traverse": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg=="], + + "@babel/helper-module-imports": ["@babel/helper-module-imports@7.29.7", "", { "dependencies": { "@babel/traverse": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g=="], + + "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.29.7", "", { "dependencies": { "@babel/helper-module-imports": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7", "@babel/traverse": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg=="], + + "@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.29.7", "", { "dependencies": { "@babel/types": "^7.29.7" } }, "sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong=="], + + "@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.29.7", "", {}, "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw=="], + + "@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.29.7", "@babel/helper-wrap-function": "^7.29.7", "@babel/traverse": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-16AMiW26DbXWBbr3B8wNozKM0ydMLB892vaOaJW/fPJdnT8vJk5sdkQcU/isqUxyCE0cEoa8wZOcbgDuC4b6Og=="], + + "@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.29.7", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.29.7", "@babel/helper-optimise-call-expression": "^7.29.7", "@babel/traverse": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ=="], + + "@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.29.7", "", { "dependencies": { "@babel/traverse": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ=="], + + "@babel/helper-string-parser": ["@babel/helper-string-parser@7.29.7", "", {}, "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw=="], + + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="], + + "@babel/helper-validator-option": ["@babel/helper-validator-option@7.29.7", "", {}, "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw=="], + + "@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.29.7", "", { "dependencies": { "@babel/template": "^7.29.7", "@babel/traverse": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-iES0Skag9ERIF68aXadpO6dbXa03mNWK3sEqJaMnLNs/eC3l0lkImdfoy6Y09/SfkpawdAB4RjQ7PVA7TcVGdw=="], + + "@babel/helpers": ["@babel/helpers@7.29.7", "", { "dependencies": { "@babel/template": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg=="], + + "@babel/parser": ["@babel/parser@7.29.8", "", { "dependencies": { "@babel/types": "^7.29.8" }, "bin": "./bin/babel-parser.js" }, "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA=="], + + "@babel/plugin-proposal-decorators": ["@babel/plugin-proposal-decorators@7.29.7", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7", "@babel/plugin-syntax-decorators": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-EtU0Hi3GvrTqD56xKmZvV/uCXK2ZbwVNPNLAquVItcAZpUhkXwWlo3Fmj0c2LxgSf2I8IDULeAepwNP1OefLXg=="], + + "@babel/plugin-proposal-export-default-from": ["@babel/plugin-proposal-export-default-from@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-p+G5BNXDcy3bOXplhY4HybQ1GxH3i2Tppmdm/3epyRu2VgJJZuUlZ61MqRTg582Q7ZLBdP7fePYvsumSEkMxcQ=="], + + "@babel/plugin-syntax-decorators": ["@babel/plugin-syntax-decorators@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-9MTTLbF39X6sqM92JPEsoI7++26hjZvzkxKZy64aMhWLH2mPkJ/Q3AV4QLmls3R14FpSpkOwQQfUh962JGQxxg=="], + + "@babel/plugin-syntax-dynamic-import": ["@babel/plugin-syntax-dynamic-import@7.8.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ=="], + + "@babel/plugin-syntax-export-default-from": ["@babel/plugin-syntax-export-default-from@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-foag0BB37ROhdeIX9O8G0jX7hw0UekJc04cHMrYLOnrErsnBKqJGHJ8eDRpoCFZBvEPPygmmtw4qyU97qa4oOw=="], + + "@babel/plugin-syntax-flow": ["@babel/plugin-syntax-flow@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ajMX6QPcyomotqwpzhkYGxcK2i/us0rs1Qo9QvUpa+Fca0FTmqrzKrctoIYLMxcOhGZldGT/BAVkRGTWBiR8gQ=="], + + "@babel/plugin-syntax-jsx": ["@babel/plugin-syntax-jsx@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A=="], + + "@babel/plugin-syntax-nullish-coalescing-operator": ["@babel/plugin-syntax-nullish-coalescing-operator@7.8.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ=="], + + "@babel/plugin-syntax-optional-chaining": ["@babel/plugin-syntax-optional-chaining@7.8.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg=="], + + "@babel/plugin-syntax-typescript": ["@babel/plugin-syntax-typescript@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA=="], + + "@babel/plugin-transform-arrow-functions": ["@babel/plugin-transform-arrow-functions@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-N7zArUXWzAMzm+/N0uPBeVB3Fam5lMxtUwMmDK5f/IBBS7a7p1qeUoxd/6CckXoxUdgsntq1Dh8xNW06maZbDQ=="], + + "@babel/plugin-transform-async-generator-functions": ["@babel/plugin-transform-async-generator-functions@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7", "@babel/helper-remap-async-to-generator": "^7.29.7", "@babel/traverse": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-d98gXZkgswvkyohMBABkhm3GeXhYj8psWfwQ2C7gtfrKGTykQa/iOIi+JJhwMjPlZ6Vm2XN+DCf3Es1EoG4ZLA=="], + + "@babel/plugin-transform-async-to-generator": ["@babel/plugin-transform-async-to-generator@7.29.7", "", { "dependencies": { "@babel/helper-module-imports": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7", "@babel/helper-remap-async-to-generator": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-pcUb2SS+RMo9TWVBwKGI5ShtoG7R+zBsFmCKDa6fe8c+hPr3XJlZgoE5j6i8W7gDjhyvy+85vmYexanvXh3d1w=="], + + "@babel/plugin-transform-block-scoping": ["@babel/plugin-transform-block-scoping@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ONyr4+AZhKh8yKWInVxU9AXA9EbsyeLcL6V0dJy6M2/62vuvpGm29zzuymbTpdc451GEpDIdAyPLP3r+P61yKQ=="], + + "@babel/plugin-transform-class-properties": ["@babel/plugin-transform-class-properties@7.29.7", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-GtcpjFvanPfzNQi3eTitsCqtRRmmqzpy/A+yhTR1HaZo1Ly3EA8ZXxlPyHdR8/IuRMYc3E4wdGBewB2QKQjAaA=="], + + "@babel/plugin-transform-class-static-block": ["@babel/plugin-transform-class-static-block@7.29.7", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.12.0" } }, "sha512-kibJgmEdX2iMwsHY2tSZNDgj8PwIlCQz7FK9KuGKO8zsuoUwSEhoNnNVp/emKWrbY4HeO6kkXfdMqRKKKXBm2A=="], + + "@babel/plugin-transform-classes": ["@babel/plugin-transform-classes@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.29.7", "@babel/helper-compilation-targets": "^7.29.7", "@babel/helper-globals": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7", "@babel/helper-replace-supers": "^7.29.7", "@babel/traverse": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-qV0OGGBVacduzQHE649JyCneOFI/maT+YKsO+K4Yi3xv2wTPNjM/W2o2gdzMwEAZz7fXNTHAe0NcSg30bIN69g=="], + + "@babel/plugin-transform-destructuring": ["@babel/plugin-transform-destructuring@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7", "@babel/traverse": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-iPX8aD6H9zV5s7ZsqTdNocPN/MGQ5sSMnElKrktxjJRMnB2jN/1p2+R7GkfD6CAYoVFqy5A4XnSIUeGgJzIWpg=="], + + "@babel/plugin-transform-export-namespace-from": ["@babel/plugin-transform-export-namespace-from@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-24B2nOy2TeJSMheqwPD4DDQOV/elLSIlKxjZt4i05H5AgdPdWR3n18HnNrcJ+j76WJd9gbwb9jPjNYUy6RautA=="], + + "@babel/plugin-transform-flow-strip-types": ["@babel/plugin-transform-flow-strip-types@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7", "@babel/plugin-syntax-flow": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-wRHeUjUjCZnMHmiO5bRgjFLcoEh7JyTdByOW11ahhwNa4V0bmeGEaIvt51yq0zQp2yWIpqfxXXPyUP6GFJZHOQ=="], + + "@babel/plugin-transform-for-of": ["@babel/plugin-transform-for-of@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-zeSIHh0+E1Um1WJRXCFlHQYu2ieJNdivLLjlBEp+dIBu3S51n+SZZmIXjxnItw6pz56Cn+KvK68BIBVsxq2JiQ=="], + + "@babel/plugin-transform-logical-assignment-operators": ["@babel/plugin-transform-logical-assignment-operators@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-A0H91hh6W8MFRkp5TqJmMr39jzGD1A1E1Ysiv2O06Sfbhkapm+XyIzxWCEh5kqwOZ1/8QZ0dY3SeQ7XBqfJd5Q=="], + + "@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.29.7", "", { "dependencies": { "@babel/helper-module-transforms": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-j0vCldybPC5b5dwCQOJ21uKtHzt7hxLygJTg9eF1ScfaikEDNfzn94XoW5Fi+seBR0nCyL23xaBFFkq7dTM8XQ=="], + + "@babel/plugin-transform-named-capturing-groups-regex": ["@babel/plugin-transform-named-capturing-groups-regex@7.29.7", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-vuFoLwr4qnv2xbZ16SQd6uPcH5FNrLHhk/Jzo++0XJFcaDsr4gjJVg6j398oMHiC+83k/GiBzviwF5KBJkPUtQ=="], + + "@babel/plugin-transform-nullish-coalescing-operator": ["@babel/plugin-transform-nullish-coalescing-operator@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-idmp1dFaekP9GbcMvG24Kvw2BfhFZjHnNJCkV4WuIY4PskJzwI3f1N5OdgYke38T7rftO6ERulFRn2cFeZwRkg=="], + + "@babel/plugin-transform-object-rest-spread": ["@babel/plugin-transform-object-rest-spread@7.29.7", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7", "@babel/plugin-transform-destructuring": "^7.29.7", "@babel/plugin-transform-parameters": "^7.29.7", "@babel/traverse": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Ld98jn4c0smUywL57m7SgsHq3OpThOa6LqZJif3G6jYOovPleoFhVrBJ1WegRApSFB2wu4+RelAj9AC9G08Z4A=="], + + "@babel/plugin-transform-optional-catch-binding": ["@babel/plugin-transform-optional-catch-binding@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-sLsyndxK2VwX6yNUOakMb7Sh553ZTe/vVM1XJ+9Z5aW1ytsc8xOIwmyk05NNjN60vkc5/KqoTH6hB4V41LJhng=="], + + "@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6GM1dhvK3gNODkXcEcMCOLEDCLSoZ/sBbro2Ax8HURyasQ4NshagQixkRFdh5niI6E4gmA/jYI/4aT7rRos3ZQ=="], + + "@babel/plugin-transform-parameters": ["@babel/plugin-transform-parameters@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ZDOBqV/qLYJI0YElr8DcENEyARsFQeESqWXH6gZlghYXuPPjvweuDhP4VyEi4BlUBlLRFZVjxoZDMjxhLW766g=="], + + "@babel/plugin-transform-private-methods": ["@babel/plugin-transform-private-methods@7.29.7", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-/6Rz4DK1ETDEM/bWHsPHcaEe7ZaT1EqSXjtSP/L0DijOYuaUhiRiOKcwpZ8P7zR4xXEHc2ITdiCgBm9Tpyv9ug=="], + + "@babel/plugin-transform-private-property-in-object": ["@babel/plugin-transform-private-property-in-object@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.29.7", "@babel/helper-create-class-features-plugin": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+BNo06dnrzdNNqCm1X6YUaVv0DKk8Q+JYcoZfOkLhYWNCXzlwTSRq8zGWayT1csjcpNXV9CQTBRRbmTLZac5cA=="], + + "@babel/plugin-transform-react-display-name": ["@babel/plugin-transform-react-display-name@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+1wdDMGNb4UPeY3Q4L5yLiYe6TXPXubs4NjrgRFw13hPRLJfEMw2Q5OXkee6/IfdqePIeW4Jjwe3aBh7SdKz4Q=="], + + "@babel/plugin-transform-react-jsx": ["@babel/plugin-transform-react-jsx@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.29.7", "@babel/helper-module-imports": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7", "@babel/plugin-syntax-jsx": "^7.29.7", "@babel/types": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-WsZulLVBUHXVj2cUcPVx6UE21TpalB6bHbSFErKT0Ib++ax24jjXe73FqlWvdylFOjiuPHYi6VCcgRad1ItN+A=="], + + "@babel/plugin-transform-react-jsx-development": ["@babel/plugin-transform-react-jsx-development@7.29.7", "", { "dependencies": { "@babel/plugin-transform-react-jsx": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Xfy3UVMF04+ypnFbkhvfqtmvwfe92qwQdbGZVonhE+6v35GzlofmOnA1szaZqzb9xYWr0nl1e5EMmzi0DNON1g=="], + + "@babel/plugin-transform-react-jsx-self": ["@babel/plugin-transform-react-jsx-self@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw=="], + + "@babel/plugin-transform-react-jsx-source": ["@babel/plugin-transform-react-jsx-source@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q=="], + + "@babel/plugin-transform-react-pure-annotations": ["@babel/plugin-transform-react-pure-annotations@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-H5E+HBgDpr6Q5t+Aj11tL7XkIui1jhbIoArVQnqjgXo5/3YxkN7ZEBcWF4RQlB0T4rrxJQbXS6kiFV6B7XTqUA=="], + + "@babel/plugin-transform-regenerator": ["@babel/plugin-transform-regenerator@7.29.8", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-0UpIXPtdDtMXfnV2OJAVMLpj3H/92vmkA6lpSRakmycJvj3VUy6Xs1dM8tXRugupykr5WB+LpiVl0J8LMVg2mg=="], + + "@babel/plugin-transform-runtime": ["@babel/plugin-transform-runtime@7.29.7", "", { "dependencies": { "@babel/helper-module-imports": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7", "babel-plugin-polyfill-corejs2": "^0.4.14", "babel-plugin-polyfill-corejs3": "^0.13.0", "babel-plugin-polyfill-regenerator": "^0.6.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-xmAscdE/AsqRW7vutbPNoUmu/nF5SrLKPs7aoJgEjo35lLKA/Bc0i2rMv/hr1+Y0o1bQCiVtith3u2vdgRL39Q=="], + + "@babel/plugin-transform-shorthand-properties": ["@babel/plugin-transform-shorthand-properties@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-I+WYbGBAiCn7nA6xBrlgPH+MB7HWb4u8pv5S0Pv7OtwNvIFvCCb24YlttKEeUFVurfBCEaOTnuhlqsb7f0Z5Dg=="], + + "@babel/plugin-transform-template-literals": ["@babel/plugin-transform-template-literals@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-NCSEJ4sLFU2gqAub45HYh4fus2yQ36rr6ei6vpU7NdoJqCpxvEG8E6eJpscGyXP3VHD2Ny+fSXr04k1hoUrFqA=="], + + "@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.29.7", "@babel/helper-create-class-features-plugin": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7", "@babel/plugin-syntax-typescript": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-jK52h8LaLc7JarhQV2ofeFMts4H7vnOXnqZNA6fYglBTZewRBE51KWt3BUltW1P+KoPsYkHoJeXePuz4zo2LMw=="], + + "@babel/plugin-transform-unicode-regex": ["@babel/plugin-transform-unicode-regex@7.29.7", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-7D/x/23/d/3VqZ0QA+LGbZMlGwZjztBygSWWWsfTPoQ1oQ6Q1P6Mr3d0kk42XabyUVw+fha3LqdRsFqeKqvCyA=="], + + "@babel/preset-typescript": ["@babel/preset-typescript@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7", "@babel/helper-validator-option": "^7.29.7", "@babel/plugin-syntax-jsx": "^7.29.7", "@babel/plugin-transform-modules-commonjs": "^7.29.7", "@babel/plugin-transform-typescript": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-/Foi8vKY2EVbed/1eZx0gJEEwHAIxogrySI7rULcRIvhZzbvoE/b5qG5Ghc0WKAFKOHA9SD1x7RsFlOYdutIiQ=="], + + "@babel/runtime": ["@babel/runtime@7.29.7", "", {}, "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw=="], + + "@babel/template": ["@babel/template@7.29.7", "", { "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/parser": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg=="], + + "@babel/traverse": ["@babel/traverse@7.29.8", "", { "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/generator": "^7.29.8", "@babel/helper-globals": "^7.29.7", "@babel/parser": "^7.29.8", "@babel/template": "^7.29.7", "@babel/types": "^7.29.8", "debug": "^4.3.1" } }, "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg=="], + + "@babel/types": ["@babel/types@7.29.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg=="], + + "@egjs/hammerjs": ["@egjs/hammerjs@2.0.17", "", { "dependencies": { "@types/hammerjs": "^2.0.36" } }, "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A=="], + + "@expo-google-fonts/dm-sans": ["@expo-google-fonts/dm-sans@0.4.2", "", {}, "sha512-e/fLH5aCJzkEenz7axvEn8N7IJAKhUwNjIxS75h9j+Ip1M9S7d22M19gJN3A7QW4egVkBJRyQh1hQFhngQn9yA=="], + + "@expo-google-fonts/material-symbols": ["@expo-google-fonts/material-symbols@0.4.43", "", {}, "sha512-jJzgVcbkJnl48X5iBFNaL5CQHwoBElJapl8unc2Ri8DnyuBR+gRiuAD4gu3ESZjjo3sknIoYIwloOsWzKbLknQ=="], + + "@expo/cli": ["@expo/cli@57.0.14", "", { "dependencies": { "@expo/code-signing-certificates": "^0.0.6", "@expo/config": "~57.0.7", "@expo/config-plugins": "~57.0.7", "@expo/devcert": "^1.2.1", "@expo/env": "~2.4.2", "@expo/image-utils": "^0.11.4", "@expo/inline-modules": "^0.1.5", "@expo/json-file": "^11.0.1", "@expo/log-box": "^57.0.2", "@expo/metro": "~56.0.0", "@expo/metro-config": "~57.0.8", "@expo/metro-file-map": "^57.0.1", "@expo/osascript": "^2.7.1", "@expo/package-manager": "^1.13.1", "@expo/plist": "^0.8.1", "@expo/prebuild-config": "^57.0.11", "@expo/require-utils": "^57.0.4", "@expo/router-server": "^57.0.5", "@expo/schema-utils": "^57.0.2", "@expo/spawn-async": "^1.8.0", "@expo/ws-tunnel": "^2.0.0", "@expo/xcpretty": "^4.4.4", "@react-native/dev-middleware": "0.86.2", "accepts": "^1.3.8", "agent-cli-detector": "^0.1.2", "arg": "^5.0.2", "bplist-creator": "0.1.0", "bplist-parser": "^0.3.1", "chalk": "^4.0.0", "ci-info": "^3.3.0", "compression": "^1.7.4", "connect": "^3.7.0", "debug": "^4.3.4", "dnssd-advertise": "^1.1.4", "expo-server": "^57.0.2", "fetch-nodeshim": "^0.4.10", "getenv": "^2.0.0", "glob": "^13.0.0", "lan-network": "^0.2.1", "multitars": "^1.0.0", "node-forge": "^1.3.3", "npm-package-arg": "^11.0.0", "ora": "^3.4.0", "picomatch": "^4.0.4", "pretty-format": "^29.7.0", "progress": "^2.0.3", "prompts": "^2.3.2", "resolve-from": "^5.0.0", "semver": "^7.6.0", "send": "^0.19.0", "slugify": "^1.3.4", "stacktrace-parser": "^0.1.10", "structured-headers": "^0.4.1", "terminal-link": "^2.1.1", "toqr": "^0.1.1", "wrap-ansi": "^7.0.0", "ws": "^8.12.1", "zod": "^3.25.76" }, "peerDependencies": { "expo": "*", "expo-router": "*", "react-native": "*" }, "optionalPeers": ["expo-router", "react-native"], "bin": { "expo-internal": "main.js" } }, "sha512-yu3sie3cDPDXBTUMvivqguW+lT8jnLIF8Q6e75MRaq7BoAzihor0KrJwtXAtC4ep5eOYYC1otEvtOuctG1xf8Q=="], + + "@expo/code-signing-certificates": ["@expo/code-signing-certificates@0.0.6", "", { "dependencies": { "node-forge": "^1.3.3" } }, "sha512-iNe0puxwBNEcuua9gmTGzq+SuMDa0iATai1FlFTMHJ/vUmKvN/V//drXoLJkVb5i5H3iE/n/qIJxyoBnXouD0w=="], + + "@expo/config": ["@expo/config@57.0.7", "", { "dependencies": { "@expo/config-plugins": "~57.0.7", "@expo/config-types": "^57.0.2", "@expo/json-file": "^11.0.1", "@expo/require-utils": "^57.0.4", "deepmerge": "^4.3.1", "getenv": "^2.0.0", "glob": "^13.0.0", "resolve-workspace-root": "^2.0.0", "semver": "^7.6.0", "slugify": "^1.3.4" } }, "sha512-4A+V8x5OmQqNm76l84S+RrB6kVoeFrvcm/Xn/6d+ELPF/HeucDheAFchdYxYNy+NEvWzuNlI/oCvrftIeK+dbQ=="], + + "@expo/config-plugins": ["@expo/config-plugins@57.0.7", "", { "dependencies": { "@expo/config-types": "^57.0.2", "@expo/json-file": "~11.0.1", "@expo/plist": "^0.8.1", "@expo/require-utils": "^57.0.4", "@expo/sdk-runtime-versions": "^1.0.0", "chalk": "^4.1.2", "debug": "^4.3.5", "getenv": "^2.0.0", "glob": "^13.0.0", "semver": "^7.5.4", "slugify": "^1.6.6", "xcode": "^3.0.1", "xml2js": "0.6.0" } }, "sha512-jvXMiNuH8W7fmU9yCk4/jVwDX2G/5rWUg5PZ22mriccEeQVS9HJjQiUHivMaK6MxEG5L9f0RPScxe/nQfnpQvg=="], + + "@expo/config-types": ["@expo/config-types@57.0.2", "", {}, "sha512-ewW08OonrcRIsRKIlFvvcmmafE5zemb1ocu3HkNwtVPyRtj2w42pZCAkMIROYpcVBaPnc3mDT9UZDzwXWC3i6g=="], + + "@expo/devcert": ["@expo/devcert@1.2.1", "", { "dependencies": { "@expo/sudo-prompt": "^9.3.1", "debug": "^3.1.0" } }, "sha512-qC4eaxmKMTmJC2ahwyui6ud8f3W60Ss7pMkpBq40Hu3zyiAaugPXnZ24145U7K36qO9UHdZUVxsCvIpz2RYYCA=="], + + "@expo/devtools": ["@expo/devtools@57.0.1", "", { "dependencies": { "chalk": "^4.1.2" }, "peerDependencies": { "react": "*", "react-native": "*" }, "optionalPeers": ["react", "react-native"] }, "sha512-GyUf+wFNkbttaX0jR7MZa9bm77U0IrLg6d2AjpxdyoXw/w4abHoXG0oFufwLMgP9zLTd5+Ct4X/ffNUTnlzZgg=="], + + "@expo/dom-webview": ["@expo/dom-webview@57.0.1", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-lAKsME4SAq+8sf56oN0DX5TBYyruupoRxbWbD2xf9RnKY8y6x8eb9LCE5pxSN0qyWdqnp+0wmyWzDkKboThKAw=="], + + "@expo/env": ["@expo/env@2.4.2", "", { "dependencies": { "chalk": "^4.0.0", "debug": "^4.3.4", "getenv": "^2.0.0" } }, "sha512-28pqaEqwnmLduZ00Pq9HkSzE5wbj1MTwp5/n8nm8rD8MCjR9eUnVOwmNksPI3Be2ReAPO/DbPn1puy0mvoocsQ=="], + + "@expo/expo-modules-macros-plugin": ["@expo/expo-modules-macros-plugin@0.6.1", "", {}, "sha512-cpsLZE4rqkc1Y3eZTkxB98jrqY1YXgetmtxFt8q89jBRmk3quRuk1BZo+VcnCSObZardjg99r1k5xijEMONFGA=="], + + "@expo/fingerprint": ["@expo/fingerprint@0.20.7", "", { "dependencies": { "@expo/env": "^2.4.2", "@expo/spawn-async": "^1.8.0", "arg": "^5.0.2", "chalk": "^4.1.2", "debug": "^4.3.4", "getenv": "^2.0.0", "glob": "^13.0.0", "ignore": "^5.3.1", "minimatch": "^10.2.2", "resolve-from": "^5.0.0", "semver": "^7.6.0" }, "bin": { "fingerprint": "bin/cli.js" } }, "sha512-tYyZD4XZSn1C30pr9IvjN/BjAqpf6r9e1NL09lPvheO1DMLByOVdmMHFLSwW8Pu6veVgzue7GDWmq9P8mc8GMg=="], + + "@expo/image-utils": ["@expo/image-utils@0.11.4", "", { "dependencies": { "@expo/require-utils": "^57.0.4", "@expo/spawn-async": "^1.8.0", "chalk": "^4.0.0", "getenv": "^2.0.0", "jimp-compact": "0.16.1", "parse-png": "^2.1.0", "semver": "^7.6.0" } }, "sha512-pn/4770DIEOcYZr484uazuwg20FX/qaDkeMRF6J+oxejynDmEmO8wLsCudaNShFE0BhyKGQTYrs2rsRhqrqESw=="], + + "@expo/inline-modules": ["@expo/inline-modules@0.1.5", "", { "dependencies": { "@expo/config-plugins": "~57.0.7" } }, "sha512-LC+kWeIwnvsGIvDaFBd8uzleWzWZiZTCG7CmtfxBLjW/Gify596X67ZqTi76iHzm5KToAfwwX0nppAKPDA9vQw=="], + + "@expo/json-file": ["@expo/json-file@11.0.1", "", { "dependencies": { "@babel/code-frame": "^7.20.0", "json5": "^2.2.3" } }, "sha512-zxHWj4MKKMAL29ZQSY/Fssx4Thluk40JmuGNaeS078wy/NhlFhnVi+rHHunulE3xJAJ0CM73m8VK2+GkF9eRwQ=="], + + "@expo/local-build-cache-provider": ["@expo/local-build-cache-provider@57.0.6", "", { "dependencies": { "@expo/config": "~57.0.7", "chalk": "^4.1.2" } }, "sha512-6aFMROb1SzIvrefpwhgS5QGNELU9T2lpK0Hcl6oiZ4/mbKgZRk0WEPauo/dHH6IgDmyK25InCMHF5nj7XY4LWg=="], + + "@expo/log-box": ["@expo/log-box@57.0.2", "", { "dependencies": { "@expo/dom-webview": "^57.0.1", "anser": "^1.4.9", "stacktrace-parser": "^0.1.10" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-ZsFyfIR7YCbQAdVLzuTUmMHofZC7ZS9ywYCJNPlLc78x59cI8GwXFEIVbRjjC0uJERpNtXx/tsNNnkhexXlzMw=="], + + "@expo/metro": ["@expo/metro@56.0.0", "", { "dependencies": { "metro": "0.84.4", "metro-babel-transformer": "0.84.4", "metro-cache": "0.84.4", "metro-cache-key": "0.84.4", "metro-config": "0.84.4", "metro-core": "0.84.4", "metro-file-map": "0.84.4", "metro-minify-terser": "0.84.4", "metro-resolver": "0.84.4", "metro-runtime": "0.84.4", "metro-source-map": "0.84.4", "metro-symbolicate": "0.84.4", "metro-transform-plugins": "0.84.4", "metro-transform-worker": "0.84.4" } }, "sha512-5gIgQHtEpjjvsjKfVtIv23a98LLRV0/y07PDShEwYSytAMlE3FSF8RHXqtHc1sUJL6dn7hnuIBpIbrLXXuVi0A=="], + + "@expo/metro-config": ["@expo/metro-config@57.0.8", "", { "dependencies": { "@babel/code-frame": "^7.20.0", "@babel/core": "^7.20.0", "@babel/generator": "^7.20.5", "@expo/config": "~57.0.7", "@expo/env": "~2.4.2", "@expo/json-file": "~11.0.1", "@expo/metro": "~56.0.0", "@expo/require-utils": "^57.0.4", "@expo/spawn-async": "^1.8.0", "@jridgewell/gen-mapping": "^0.3.13", "@jridgewell/remapping": "^2.3.5", "@jridgewell/sourcemap-codec": "^1.5.5", "browserslist": "^4.25.0", "chalk": "^4.1.0", "debug": "^4.3.2", "getenv": "^2.0.0", "glob": "^13.0.0", "hermes-parser": "^0.36.0", "jsc-safe-url": "^0.2.4", "lightningcss": "^1.30.1", "picomatch": "^4.0.4", "postcss": "^8.5.14", "resolve-from": "^5.0.0" }, "peerDependencies": { "expo": "*" }, "optionalPeers": ["expo"] }, "sha512-cZOVjbljqRBMCXcloc5k23gsFOhWdiKXhDkp5jU/wY6IXR6G7cYtNOwxKfxI1QLhs0KcXY0gDmZ2UIueoHzY7g=="], + + "@expo/metro-file-map": ["@expo/metro-file-map@57.0.1", "", { "dependencies": { "debug": "^4.3.4", "fb-watchman": "^2.0.2", "invariant": "^2.2.4", "jest-worker": "^29.7.0", "micromatch": "^4.0.4", "walker": "^1.0.8" } }, "sha512-8JXfVstZN7QnP4NianZZnlTVboOWR0sG8trUDNajOjnbGlPln29vponXM84tY+3tAHapz5/TxE53L0ixUwqPtA=="], + + "@expo/metro-runtime": ["@expo/metro-runtime@57.0.9", "", { "dependencies": { "@expo/log-box": "^57.0.2", "anser": "^1.4.9", "pretty-format": "^29.7.0", "stacktrace-parser": "^0.1.10", "whatwg-fetch": "^3.0.0" }, "peerDependencies": { "expo": "*", "react": "*", "react-dom": "*", "react-native": "*" }, "optionalPeers": ["react-dom"] }, "sha512-gtly6wOk59Ip7S5NtYSYMmMmz7VyKeNWo/dERF7b1q3Rmek4fBwEV5tTHIXaDTKboAryXdWR9gjSv1DzErP/Dg=="], + + "@expo/osascript": ["@expo/osascript@2.7.1", "", { "dependencies": { "@expo/spawn-async": "^1.8.0" } }, "sha512-Zn03EX6In7ts2lPUW2ESUSkEhEWQN1qqsiXjadtZMJOuZRkMiAg1ZQHuvz9DjByDWNJ2pBwAGyrts9lj9k389g=="], + + "@expo/package-manager": ["@expo/package-manager@1.13.1", "", { "dependencies": { "@expo/json-file": "^11.0.1", "@expo/spawn-async": "^1.8.0", "chalk": "^4.0.0", "npm-package-arg": "^11.0.0", "ora": "^3.4.0", "resolve-workspace-root": "^2.0.0" } }, "sha512-y/K+CaYYpZpNGZhSX4HyLT/vyIunFjNfyoxNysPBCefeLKI/VCx6f9LNPzrxayr3rCYO5bl9O8H+HRQK265Nkg=="], + + "@expo/plist": ["@expo/plist@0.8.1", "", { "dependencies": { "@xmldom/xmldom": "^0.8.8", "base64-js": "^1.5.1", "xmlbuilder": "^15.1.1" } }, "sha512-3gTReGIUm0oRaMClsAJYxBnVPCl6fVpsl8HS+DTVxDhW4GyVyxg9E/Znm3BvcHtUJ51RJJI14pC1wvrNilCRHw=="], + + "@expo/prebuild-config": ["@expo/prebuild-config@57.0.11", "", { "dependencies": { "@expo/config": "~57.0.7", "@expo/config-plugins": "~57.0.7", "@expo/config-types": "^57.0.2", "@expo/image-utils": "^0.11.4", "@expo/json-file": "^11.0.1", "@react-native/normalize-colors": "0.86.2", "debug": "^4.3.1", "expo-modules-autolinking": "~57.0.9", "resolve-from": "^5.0.0", "semver": "^7.6.0" } }, "sha512-GcBX2xQ6l4VrkxmlAXm6lVUeHhnURe0Jh86hNVQqoYYIFflUx4IFmMm9B9bN0mbp/Jb+j+CGjkSPQcIYq9NM/Q=="], + + "@expo/require-utils": ["@expo/require-utils@57.0.4", "", { "dependencies": { "@babel/code-frame": "^7.20.0", "@babel/core": "^7.25.2", "@babel/plugin-transform-modules-commonjs": "^7.24.8" }, "peerDependencies": { "typescript": "^5.0.0 || ^5.0.0-0 || ^6.0.0 || ^7.0.0" }, "optionalPeers": ["typescript"] }, "sha512-e7xbg/9BTQcsZE/oErafZXtI7kh5IgfasLJ97J5sFSzX2cA74pDvdlhW1KHVSaDkQyQv6h1LSLhsY7dEeOk7hw=="], + + "@expo/router-server": ["@expo/router-server@57.0.5", "", { "dependencies": { "debug": "^4.3.4" }, "peerDependencies": { "@expo/metro-runtime": "^57.0.8", "expo": "*", "expo-constants": "^57.0.9", "expo-font": "^57.0.1", "expo-router": "*", "expo-server": "^57.0.1", "react": "*", "react-dom": "*", "react-server-dom-webpack": "~19.0.1 || ~19.1.2 || ~19.2.1" }, "optionalPeers": ["@expo/metro-runtime", "expo-router", "react-dom", "react-server-dom-webpack"] }, "sha512-vke39l0bo3H2q9JB/KXpAJ7HpscdTG3Mktbxanc8yn3riWzzSsnv0uxwZGZCrZrnDQzFxlLTXgbZrGkU26ng1w=="], + + "@expo/schema-utils": ["@expo/schema-utils@57.0.2", "", {}, "sha512-fMu/jyN0l1Wzv7XkeWR4IYCx1M8ryui3FdBNGrWwbRgJ7EhxXxK8E2jxP2W3pbgUwUY0V3hG8+GyfCZwny+Lxw=="], + + "@expo/sdk-runtime-versions": ["@expo/sdk-runtime-versions@1.0.0", "", {}, "sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ=="], + + "@expo/spawn-async": ["@expo/spawn-async@1.8.0", "", { "dependencies": { "cross-spawn": "^7.0.6" } }, "sha512-eb9xxd/LbuEGSdua4NumCu/McVB9EM+F/JxB9pWgnERw4HQ9XyTNH1KapG6oqLWR8TuRK2LQfzJlmNi94CVobw=="], + + "@expo/sudo-prompt": ["@expo/sudo-prompt@9.3.2", "", {}, "sha512-HHQigo3rQWKMDzYDLkubN5WQOYXJJE2eNqIQC2axC2iO3mHdwnIR7FgZVvHWtBwAdzBgAP0ECp8KqS8TiMKvgw=="], + + "@expo/ui": ["@expo/ui@57.0.10", "", { "dependencies": { "sf-symbols-typescript": "^2.1.0", "vaul": "^1.1.2" }, "peerDependencies": { "@babel/core": "*", "expo": "*", "react": "*", "react-dom": "*", "react-native": "*", "react-native-worklets": "*" }, "optionalPeers": ["@babel/core", "react-dom", "react-native-worklets"] }, "sha512-cYVo6R6JmJgza2p1jyE1lGfNPWncHJGWRxhTyOi+pLRAAdiwo8Z2LcdaArewEXVUwJTQhczLRxeXGL0i99NUwQ=="], + + "@expo/vector-icons": ["@expo/vector-icons@15.1.1", "", { "peerDependencies": { "expo-font": ">=14.0.4", "react": "*", "react-native": "*" } }, "sha512-Iu2VkcoI5vygbtYngm7jb4ifxElNVXQYdDrYkT7UCEIiKLeWnQY0wf2ZhHZ+Wro6Sc5TaumpKUOqDRpLi5rkvw=="], + + "@expo/ws-tunnel": ["@expo/ws-tunnel@2.0.0", "", { "peerDependencies": { "ws": "^8.0.0" } }, "sha512-j+JfTRdCk820J9dU0sA2SqshQIKFOMo7ED84w9MJFcebfbNQgsLztEY/SABDkGnjatrW4xGqnUhVRxSBVyCkXw=="], + + "@expo/xcpretty": ["@expo/xcpretty@4.4.4", "", { "dependencies": { "@babel/code-frame": "^7.20.0", "chalk": "^4.1.0", "js-yaml": "^4.1.0" }, "bin": { "excpretty": "build/cli.js" } }, "sha512-4aQzz9vgxcNXFfo/iyNgDDYfsU5XGKKxWxZopw0cVotHiW+U8IJbIxMaxsINs6bHhtkG3StKNPcOrn3eBuxKPw=="], + + "@isaacs/ttlcache": ["@isaacs/ttlcache@1.4.1", "", {}, "sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA=="], + + "@jest/schemas": ["@jest/schemas@29.6.3", "", { "dependencies": { "@sinclair/typebox": "^0.27.8" } }, "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA=="], + + "@jest/types": ["@jest/types@29.6.3", "", { "dependencies": { "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^17.0.8", "chalk": "^4.0.0" } }, "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw=="], + + "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], + + "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], + + "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], + + "@jridgewell/source-map": ["@jridgewell/source-map@0.3.11", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" } }, "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA=="], + + "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], + + "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], + + "@radix-ui/primitive": ["@radix-ui/primitive@1.1.7", "", {}, "sha512-rqWnm76nYT8HoNNqEjpgJ7Pw/DrBj5iBTrmEPo6HTX5+VJyBNOqTdv4g89G63HuR5g0AaENoAcH7Is5fF2kZ8Q=="], + + "@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.15", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.5", "@radix-ui/react-context": "1.2.2", "@radix-ui/react-primitive": "2.1.10", "@radix-ui/react-slot": "1.3.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-9W+B9NPF0NaaPh/1NJd3+KqsnlLqU9H7T2rvww+fp+T/evVXdNAyYcnfRQZFOjkR1ajQp3yORlqnI8soawLvNA=="], + + "@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.5", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-+48PbAAbq3didjJxa+OaWY2ZwgAKsNiRGyeHKszblZMQ+kcpd9pAaT11cMkGEie0vsOi3QdeTE6d5Fe3Gn61kA=="], + + "@radix-ui/react-context": ["@radix-ui/react-context@1.2.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-RHCUGwKHDr0hDGg4X7ma4JG4/+12qxw8rkh5QKdDldlCvtja6nUx1Ef/8HVrJze81lEsgLQlqjzjGNHantgnQA=="], + + "@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.23", "", { "dependencies": { "@radix-ui/primitive": "1.1.7", "@radix-ui/react-compose-refs": "1.1.5", "@radix-ui/react-context": "1.2.2", "@radix-ui/react-dismissable-layer": "1.1.19", "@radix-ui/react-focus-guards": "1.1.6", "@radix-ui/react-focus-scope": "1.1.16", "@radix-ui/react-id": "1.1.4", "@radix-ui/react-portal": "1.1.17", "@radix-ui/react-presence": "1.1.10", "@radix-ui/react-primitive": "2.1.10", "@radix-ui/react-slot": "1.3.3", "@radix-ui/react-use-controllable-state": "1.2.6", "@radix-ui/react-use-layout-effect": "1.1.4", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Ksw4WeROkO4rC9k/onilX/Ao2Cr1ku1unMNH+XSCcP4jSXYu7HDsg9n4ojMjVb22XpYjAQ9qfrFlVbru1vXDUA=="], + + "@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.4", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-5pzg4FGQNpExhnhT2zlrP1wZFaYCd1K0nYWoFAdcYoYK868IEigqMX3B3f8yIoRlAhAeDWciLI6ZdCKHF9P4Vg=="], + + "@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.19", "", { "dependencies": { "@radix-ui/primitive": "1.1.7", "@radix-ui/react-compose-refs": "1.1.5", "@radix-ui/react-primitive": "2.1.10", "@radix-ui/react-use-callback-ref": "1.1.4", "@radix-ui/react-use-effect-event": "0.0.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-8g4pfOL9HoKKLWGiypT+dphVqjFfmcXO5GBnhsG6zI+lxAx/8feQpr+1LSN8Re3hiZ+XkLNS4O9ztK11/LzQ6w=="], + + "@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.6", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-RNOJjfZMTyBM6xYmV3IVGXkPjIhcBAuv48POevAXwrGJhkWZ9p1rFoIS1JFooPuT193AZmRsCPhpoVJxx6OPoQ=="], + + "@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.16", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.5", "@radix-ui/react-primitive": "2.1.10", "@radix-ui/react-use-callback-ref": "1.1.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-wmRZ2WWLvmt6KHy2rNPOdPUjwq5xOHY02+m+udwJTn0aNIox/rkskAvJTyTLGhPK6KgrUjlJUJpgmx/+wFiFIQ=="], + + "@radix-ui/react-id": ["@radix-ui/react-id@1.1.4", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-TMQp2llA+RYn7JcjnrMnz7wN4pcVttPZnRZo52PLQsoLVKzNlVwUeHmfePgTgRluXFvlD3GD5g5MOVVTJCO0qA=="], + + "@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.17", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.10", "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-vKQLcWypUnwZVvfV7UkGahH2g6ySe8M8R+zYBwPrv5byZ9QAW6cQVvNKo7GgmD+p8aYb6D9JBuvy8/WhOno2wQ=="], + + "@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.10", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-3wyzCQ6+ubRA+D4uv9m95JYLXxmOHp05qjrkjeA7uKHHtjpPggQzc6DAb0URl7j67oR0K2foO4ip27TiX037Bw=="], + + "@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.10", "", { "dependencies": { "@radix-ui/react-slot": "1.3.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-MucOnzh6hR5mid6VpkbglRAMYMjKLqRnGBbjXkzjK52fuQDd1qbkx78a5P40mkcnVXJdEVxm26E9OPAiUq7nBg=="], + + "@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.19", "", { "dependencies": { "@radix-ui/primitive": "1.1.7", "@radix-ui/react-collection": "1.1.15", "@radix-ui/react-compose-refs": "1.1.5", "@radix-ui/react-context": "1.2.2", "@radix-ui/react-direction": "1.1.4", "@radix-ui/react-id": "1.1.4", "@radix-ui/react-primitive": "2.1.10", "@radix-ui/react-use-callback-ref": "1.1.4", "@radix-ui/react-use-controllable-state": "1.2.6", "@radix-ui/react-use-is-hydrated": "0.1.3", "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-V9jI6hDjT7l3jsCQD9bLNvDLM3tH/gdbOTp7Tefp3hbbgCGQoK7tUvrWiRlcoBHIZ809ElXwNQwVo0B98LuTXQ=="], + + "@radix-ui/react-slot": ["@radix-ui/react-slot@1.3.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.5" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-qx7oqnYbxnK9kYI9m317qmFmEgo6ywqWvbTogdj7cL9p3/yx4M48p7Rnw5z3H890cL/ow/EeWJsuTykeZVXP5Q=="], + + "@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.21", "", { "dependencies": { "@radix-ui/primitive": "1.1.7", "@radix-ui/react-context": "1.2.2", "@radix-ui/react-direction": "1.1.4", "@radix-ui/react-id": "1.1.4", "@radix-ui/react-presence": "1.1.10", "@radix-ui/react-primitive": "2.1.10", "@radix-ui/react-roving-focus": "1.1.19", "@radix-ui/react-use-controllable-state": "1.2.6" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-UKxJlZid7FVtsk/WTxj4i4uSEgj2Au+KBbS7SQyTlzMhhn+86Cz3tISZdTa87bfEfcuvZezf2ZsxD4xuEKtkog=="], + + "@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.4", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-R6OUY2e2fA6Yn6s+VSx5KBV6Nx8LQEhu+cz7LCej18rQ1HLyg9PSC9jP/ZNx0o6FAIK9c0F1kHylzSxKsdlkrQ=="], + + "@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.6", "", { "dependencies": { "@radix-ui/primitive": "1.1.7", "@radix-ui/react-use-effect-event": "0.0.5", "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-uEQJGT97ZA/TgP/Hydw47lHu+/vQj6z/0jA+WeTbK1o9Rx45GImjpD0tc3W5ad3D6XTSR6e1yEO0FvGq6WQfVQ=="], + + "@radix-ui/react-use-effect-event": ["@radix-ui/react-use-effect-event@0.0.5", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-7cshFL8HGS/7HEiHH+9kL9HBwp2sa9yX18Knwek6KYWmXwM7pegMgta2AXMQKI+rq3JnfSj9x8wYqFMTdG1Jgg=="], + + "@radix-ui/react-use-is-hydrated": ["@radix-ui/react-use-is-hydrated@0.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-umO/aJ+82CpOnhDZUTbILCQf7kU/g0iv+oGs/Q8jw7IkhWBzaEP4sA268PhFAJTFetbwp3ICc6ktpI4TqtxcIw=="], + + "@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.4", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-K20DkRkUwDnxEYMBPcg3Y6voLkEy5p5QQmszZgLngKKiC7dzBR/aEuK3w1qlx2JWDUNH6FluahYdgR3BP+QbYw=="], + + "@react-native-masked-view/masked-view": ["@react-native-masked-view/masked-view@0.3.2", "", { "peerDependencies": { "react": ">=16", "react-native": ">=0.57" } }, "sha512-XwuQoW7/GEgWRMovOQtX3A4PrXhyaZm0lVUiY8qJDvdngjLms9Cpdck6SmGAUNqQwcj2EadHC1HwL0bEyoa/SQ=="], + + "@react-native/assets-registry": ["@react-native/assets-registry@0.86.2", "", {}, "sha512-vcX/mBjWAVnWofu7KecotquI2unZ/tITwA7OGdq/mdY/zmGXIEvYhfEYyOQij/LRqi9WAL+iizInTBWnxDhK/Q=="], + + "@react-native/babel-plugin-codegen": ["@react-native/babel-plugin-codegen@0.86.2", "", { "dependencies": { "@babel/traverse": "^7.29.0", "@react-native/codegen": "0.86.2" } }, "sha512-NNDZqOlNbH5SzgPks1jFDYH3234Rpa5e/nhZymxhIiBH3NcE3uD+rGj/HWXhH7nHF2ToGK6XbUpqy7nmJPeh+g=="], + + "@react-native/babel-preset": ["@react-native/babel-preset@0.87.0", "", { "dependencies": { "@babel/core": "^7.25.2", "@babel/plugin-proposal-export-default-from": "^7.24.7", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-default-from": "^7.24.7", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-transform-async-generator-functions": "^7.25.4", "@babel/plugin-transform-async-to-generator": "^7.24.7", "@babel/plugin-transform-block-scoping": "^7.25.0", "@babel/plugin-transform-class-properties": "^7.25.4", "@babel/plugin-transform-classes": "^7.25.4", "@babel/plugin-transform-destructuring": "^7.24.8", "@babel/plugin-transform-flow-strip-types": "^7.25.2", "@babel/plugin-transform-for-of": "^7.24.7", "@babel/plugin-transform-modules-commonjs": "^7.24.8", "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", "@babel/plugin-transform-optional-catch-binding": "^7.24.7", "@babel/plugin-transform-optional-chaining": "^7.24.8", "@babel/plugin-transform-private-methods": "^7.24.7", "@babel/plugin-transform-private-property-in-object": "^7.24.7", "@babel/plugin-transform-react-display-name": "^7.24.7", "@babel/plugin-transform-react-jsx": "^7.25.2", "@babel/plugin-transform-react-jsx-self": "^7.24.7", "@babel/plugin-transform-react-jsx-source": "^7.24.7", "@babel/plugin-transform-regenerator": "^7.24.7", "@babel/plugin-transform-runtime": "^7.24.7", "@babel/plugin-transform-typescript": "^7.25.2", "@babel/plugin-transform-unicode-regex": "^7.24.7", "@react-native/babel-plugin-codegen": "0.87.0", "babel-plugin-syntax-hermes-parser": "0.36.1", "babel-plugin-transform-flow-enums": "^0.0.2", "react-refresh": "^0.14.0" } }, "sha512-vthkHlSDWFVCQtQ22JZadM1J7wicn0773sP0C8wMb+2g6+6hn1209A1rMJz0ijpTI+RQ4XyQRmbnyTsf4kuIWg=="], + + "@react-native/codegen": ["@react-native/codegen@0.86.2", "", { "dependencies": { "@babel/core": "^7.25.2", "@babel/parser": "^7.29.0", "hermes-parser": "0.36.0", "invariant": "^2.2.4", "nullthrows": "^1.1.1", "tinyglobby": "^0.2.15", "yargs": "^17.6.2" } }, "sha512-xKkudsahUJ1n//55g4fXk5BStVqqmZlz8HQveL45ZxcfDnwvhuYe2GymksQANFsSN+slvrarjrfq8kIxJzbceA=="], + + "@react-native/community-cli-plugin": ["@react-native/community-cli-plugin@0.86.2", "", { "dependencies": { "@react-native/dev-middleware": "0.86.2", "debug": "^4.4.0", "invariant": "^2.2.4", "metro": "^0.84.3", "metro-config": "^0.84.3", "metro-core": "^0.84.3", "semver": "^7.1.3" }, "peerDependencies": { "@react-native-community/cli": "*", "@react-native/metro-config": "0.86.2" }, "optionalPeers": ["@react-native-community/cli", "@react-native/metro-config"] }, "sha512-YHXNKoM6Y/HjREySZ5arET2xgiHgg67r1MdwJB//MPJAJ0Xc5g0u6UHxY9VzsHO3Y07dre6s0BinYwjt1SEWvQ=="], + + "@react-native/debugger-frontend": ["@react-native/debugger-frontend@0.86.2", "", {}, "sha512-KGS1aV5F6cIqpnoIUhLBXyVzy1oAj8jBFGau6vX4Vy0HXRJN7p+68RU7x6NuyraHvQcR14ccMGT5TkFuNjQ4gA=="], + + "@react-native/debugger-shell": ["@react-native/debugger-shell@0.86.2", "", { "dependencies": { "cross-spawn": "^7.0.6", "debug": "^4.4.0", "fb-dotslash": "0.5.8" } }, "sha512-/TaVJ2+gGajZPJGrFaObUQmHmlaxAlfmOPZicl6pNKDUjzSgFMpcLkdTOExvb+USYTVdGX1XwxXyvjQdUO2bvg=="], + + "@react-native/dev-middleware": ["@react-native/dev-middleware@0.86.2", "", { "dependencies": { "@isaacs/ttlcache": "^1.4.1", "@react-native/debugger-frontend": "0.86.2", "@react-native/debugger-shell": "0.86.2", "chrome-launcher": "^0.15.2", "chromium-edge-launcher": "^0.3.0", "connect": "^3.6.5", "debug": "^4.4.0", "invariant": "^2.2.4", "nullthrows": "^1.1.1", "open": "^7.0.3", "serve-static": "^1.16.2", "ws": "^7.5.10" } }, "sha512-B7L0vKvg+IcEElT7Vpqh1xj5yJAqWUegjbP+bQRaorJMAYnv11GkliTnZV2AdTDfZQJWgOEx8i8LGkHkUg7bnA=="], + + "@react-native/gradle-plugin": ["@react-native/gradle-plugin@0.86.2", "", {}, "sha512-2F6x14NcHMpVmfTTFKfMkpV5dZedZrLiv6PE+c3vgnesV2bjleUBydr4U+NI8VkI7OwW71L0A5qQ76I9LCrfoQ=="], + + "@react-native/js-polyfills": ["@react-native/js-polyfills@0.86.2", "", {}, "sha512-bIwNcGBaQ74shB5z1mRkxOpjikimuwsnOCEkZSzL67Z1FTyK1ObpENfyd2QvcvVW9Cjl+tHuw9ynpBnb2jPoJQ=="], + + "@react-native/metro-babel-transformer": ["@react-native/metro-babel-transformer@0.87.0", "", { "dependencies": { "@babel/core": "^7.25.2", "@react-native/babel-preset": "0.87.0", "hermes-parser": "0.36.1", "nullthrows": "^1.1.1" } }, "sha512-z57jsBX3q0fh2jTnrXisBo8A5qfkVFrnVJ0HMKRa8+cVsw/bz6MiEkXA/dsBK8eJfjawccxzXhAIzTzwbnxl4Q=="], + + "@react-native/metro-config": ["@react-native/metro-config@0.87.0", "", { "dependencies": { "@react-native/js-polyfills": "0.87.0", "@react-native/metro-babel-transformer": "0.87.0", "metro-config": "^0.87.0", "metro-runtime": "^0.87.0" } }, "sha512-Pg0DmsJ/DbLP8JuxnRSDmrIaQjKhpzd2uYAZRyB2A8fJQzJWpAFLr7TUAXhiGD5025F6+PVPAnJL3HXaeMfZqQ=="], + + "@react-native/normalize-colors": ["@react-native/normalize-colors@0.86.2", "", {}, "sha512-EzPFc9Y6lzYOWeso2almwXI7f8+qReHxWvT+algsOczb2UhWXIWXDoSvkdwoSfiwwmGt/ijJgKJoeHlzPkLwRg=="], + + "@react-native/virtualized-lists": ["@react-native/virtualized-lists@0.86.2", "", { "dependencies": { "invariant": "^2.2.4", "nullthrows": "^1.1.1" }, "peerDependencies": { "@types/react": "^19.2.0", "react": "*", "react-native": "0.86.2" }, "optionalPeers": ["@types/react"] }, "sha512-uO0J72gh3EvE+1/GHRk18QRyBDTRHRB0AraAfojsRjbT7VMuJwKrZYaKGshavoaEud6aw00ZB9/8mTMIKjjcAw=="], + + "@react-navigation/bottom-tabs": ["@react-navigation/bottom-tabs@7.18.16", "", { "dependencies": { "@react-navigation/elements": "^2.9.38", "color": "^4.2.3", "sf-symbols-typescript": "^2.1.0" }, "peerDependencies": { "@react-navigation/native": "^7.3.16", "react": ">= 18.2.0", "react-native": "*", "react-native-safe-area-context": ">= 4.0.0", "react-native-screens": ">= 4.0.0" } }, "sha512-5tBFuxvsCQBvYauDZK6u/uPdD86i/caWgBzABlZfTh8W2J7YZSHjT9SWOsquSMmR6dpcNj6idMd4utCNzuOnZg=="], + + "@react-navigation/core": ["@react-navigation/core@7.21.12", "", { "dependencies": { "@react-navigation/routers": "^7.6.4", "escape-string-regexp": "^4.0.0", "fast-deep-equal": "^3.1.3", "nanoid": "^3.3.11", "query-string": "^7.1.3", "react-is": "^19.1.0", "use-latest-callback": "^0.2.4", "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "react": ">= 18.2.0" } }, "sha512-FopGMGy5df+IMqUYg9w7ygwK0oP4RaQbMnpb7VFP30+vZdd8MqsAGc+bZZwdiVSnzK9hzhgJtZV9XF0ZFlUYOQ=="], + + "@react-navigation/elements": ["@react-navigation/elements@2.9.38", "", { "dependencies": { "color": "^4.2.3", "use-latest-callback": "^0.2.4", "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "@react-native-masked-view/masked-view": ">= 0.2.0", "@react-navigation/native": "^7.3.16", "react": ">= 18.2.0", "react-native": "*", "react-native-safe-area-context": ">= 4.0.0" }, "optionalPeers": ["@react-native-masked-view/masked-view"] }, "sha512-M/2HWDiSO4zO7VyfAnovrTPWOAzTC+1DnVT7ZWZW93+/KVRF9OYlqixIUpPenQ0iQh2j1EaQ4zOe/134Arisqw=="], + + "@react-navigation/native": ["@react-navigation/native@7.3.16", "", { "dependencies": { "@react-navigation/core": "^7.21.12", "escape-string-regexp": "^4.0.0", "fast-deep-equal": "^3.1.3", "nanoid": "^3.3.11", "standard-navigation": "^0.0.8", "use-latest-callback": "^0.2.4" }, "peerDependencies": { "react": ">= 18.2.0", "react-native": "*" } }, "sha512-Wy/6mai2HpA5AEVFk7JFfvv4RUArwuN2UenP/fc3NK7kOyfSlNu1tmb/3JDPpMzPIRbF1MPB8PKAHjVB29qNEQ=="], + + "@react-navigation/routers": ["@react-navigation/routers@7.6.4", "", { "dependencies": { "nanoid": "^3.3.11" } }, "sha512-GI7eJm8/KsZUQaYcXvEExikKurRZRgEsSzyZ7faENfi65yqJBCXjDMwyN1pF6pNW1MoLH1ErDwDivFxY6BzD3w=="], + + "@sinclair/typebox": ["@sinclair/typebox@0.27.12", "", {}, "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g=="], + + "@testing-library/dom": ["@testing-library/dom@10.4.1", "", { "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", "@types/aria-query": "^5.0.1", "aria-query": "5.3.0", "dom-accessibility-api": "^0.5.9", "lz-string": "^1.5.0", "picocolors": "1.1.1", "pretty-format": "^27.0.2" } }, "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg=="], + + "@testing-library/jest-dom": ["@testing-library/jest-dom@6.10.0", "", { "dependencies": { "@adobe/css-tools": "^4.4.0", "aria-query": "^5.0.0", "css.escape": "^1.5.1", "dom-accessibility-api": "^0.6.3", "picocolors": "^1.1.1", "redent": "^3.0.0" }, "peerDependencies": { "@testing-library/dom": ">=10 <11" } }, "sha512-HQwu0KaB2zyT0iLzBL+8CLyZDL3KlZlZJ+2iyc9uCUnlJVskJU/UlPuVCyIPhtukjPQdT2QNoR5nCP5FqTmmDQ=="], + + "@testing-library/user-event": ["@testing-library/user-event@14.6.4", "", { "peerDependencies": { "@testing-library/dom": ">=7.21.4" } }, "sha512-QCGwP6QrjypBLwyj5cuyfVamkaIEy/XGY+1VDehbtbQqOggYmTFpFOdWR5mPz14vX8vXLMVjDHlRNBcClyO9ew=="], + + "@types/aria-query": ["@types/aria-query@5.0.4", "", {}, "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw=="], + + "@types/hammerjs": ["@types/hammerjs@2.0.46", "", {}, "sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw=="], + + "@types/istanbul-lib-coverage": ["@types/istanbul-lib-coverage@2.0.6", "", {}, "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w=="], + + "@types/istanbul-lib-report": ["@types/istanbul-lib-report@3.0.3", "", { "dependencies": { "@types/istanbul-lib-coverage": "*" } }, "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA=="], + + "@types/istanbul-reports": ["@types/istanbul-reports@3.0.4", "", { "dependencies": { "@types/istanbul-lib-report": "*" } }, "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ=="], + + "@types/node": ["@types/node@26.2.0", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-5IviulTZeRNp2vAJ514cc/HUlY5nZ9fCbq9DMyC52BrhFZACo3nI0R7qBxhQmo/d27NFe96ur/b7Wwxklda+kg=="], + + "@types/react": ["@types/react@19.2.18", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-AnzbBERsrLKtk2XSfTbYRLjQPdy116Sty4q+T+Bp3IC4l6jNBvreVPAHmpq9qhXQM7CXZPjLVmGMw9sy+hxQ3w=="], + + "@types/react-test-renderer": ["@types/react-test-renderer@19.1.0", "", { "dependencies": { "@types/react": "*" } }, "sha512-XD0WZrHqjNrxA/MaR9O22w/RNidWR9YZmBdRGI7wcnWGrv/3dA8wKCJ8m63Sn+tLJhcjmuhOi629N66W6kgWzQ=="], + + "@types/yargs": ["@types/yargs@17.0.35", "", { "dependencies": { "@types/yargs-parser": "*" } }, "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg=="], + + "@types/yargs-parser": ["@types/yargs-parser@21.0.3", "", {}, "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ=="], + + "@ungap/structured-clone": ["@ungap/structured-clone@1.3.3", "", {}, "sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg=="], + + "@xmldom/xmldom": ["@xmldom/xmldom@0.8.14", "", {}, "sha512-T4EDRUBVZYRldYApjEJiU0e1stYWaRAX7CuSnKzrpwdZKo53zGV8/pqfzV6FfwNl9YThD2OumQYvqtvjvgG7aQ=="], + + "abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="], + + "accepts": ["accepts@1.3.8", "", { "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" } }, "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw=="], + + "acorn": ["acorn@8.18.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ=="], + + "agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + + "agent-cli-detector": ["agent-cli-detector@0.1.5", "", { "bin": { "agent-cli-detector": "dist/cli.js" } }, "sha512-6xvLw0EGPuxoYGZeqyMV4AK+WoZ31jsqb7a5pln1BTf6oDFsrgvfCJT7E7y9oAqifJZhJ3fZ0J36H7o6JzrB0Q=="], + + "anser": ["anser@1.4.10", "", {}, "sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww=="], + + "ansi-escapes": ["ansi-escapes@4.3.2", "", { "dependencies": { "type-fest": "^0.21.3" } }, "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ=="], + + "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="], + + "arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="], + + "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], + + "aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="], + + "aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="], + + "asap": ["asap@2.0.6", "", {}, "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="], + + "babel-plugin-polyfill-corejs2": ["babel-plugin-polyfill-corejs2@0.4.17", "", { "dependencies": { "@babel/compat-data": "^7.28.6", "@babel/helper-define-polyfill-provider": "^0.6.8", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w=="], + + "babel-plugin-polyfill-corejs3": ["babel-plugin-polyfill-corejs3@0.13.0", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.5", "core-js-compat": "^3.43.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A=="], + + "babel-plugin-polyfill-regenerator": ["babel-plugin-polyfill-regenerator@0.6.8", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.8" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg=="], + + "babel-plugin-react-compiler": ["babel-plugin-react-compiler@1.0.0", "", { "dependencies": { "@babel/types": "^7.26.0" } }, "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw=="], + + "babel-plugin-react-native-web": ["babel-plugin-react-native-web@0.21.2", "", {}, "sha512-SPD0J6qjJn8231i0HZhlAGH6NORe+QvRSQM2mwQEzJ2Fb3E4ruWTiiicPlHjmeWShDXLcvoorOCXjeR7k/lyWA=="], + + "babel-plugin-syntax-hermes-parser": ["babel-plugin-syntax-hermes-parser@0.36.0", "", { "dependencies": { "hermes-parser": "0.36.0" } }, "sha512-LhD0xdoedDw7ansQgXbB2DADLZIK/LRXuWNBPuVzMc5S2WK5GyT89tCM+cQzxFGO0mGyLK6D5TrVOJJzAoDy8Q=="], + + "babel-plugin-transform-flow-enums": ["babel-plugin-transform-flow-enums@0.0.2", "", { "dependencies": { "@babel/plugin-syntax-flow": "^7.12.1" } }, "sha512-g4aaCrDDOsWjbm0PUUeVnkcVd6AKJsVc/MbnPhEotEpkeJQP6b8nzewohQi7+QS8UyPehOhGWn0nOwjvWpmMvQ=="], + + "babel-preset-expo": ["babel-preset-expo@57.0.6", "", { "dependencies": { "@babel/generator": "^7.20.5", "@babel/helper-module-imports": "^7.25.9", "@babel/plugin-proposal-decorators": "^7.12.9", "@babel/plugin-proposal-export-default-from": "^7.24.7", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-default-from": "^7.24.7", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-transform-async-generator-functions": "^7.25.4", "@babel/plugin-transform-async-to-generator": "^7.24.7", "@babel/plugin-transform-block-scoping": "^7.25.0", "@babel/plugin-transform-class-properties": "^7.25.4", "@babel/plugin-transform-class-static-block": "^7.27.1", "@babel/plugin-transform-classes": "^7.25.4", "@babel/plugin-transform-destructuring": "^7.24.8", "@babel/plugin-transform-export-namespace-from": "^7.25.9", "@babel/plugin-transform-flow-strip-types": "^7.25.2", "@babel/plugin-transform-for-of": "^7.24.7", "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", "@babel/plugin-transform-modules-commonjs": "^7.24.8", "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", "@babel/plugin-transform-object-rest-spread": "^7.24.7", "@babel/plugin-transform-optional-catch-binding": "^7.24.7", "@babel/plugin-transform-optional-chaining": "^7.24.8", "@babel/plugin-transform-parameters": "^7.24.7", "@babel/plugin-transform-private-methods": "^7.24.7", "@babel/plugin-transform-private-property-in-object": "^7.24.7", "@babel/plugin-transform-react-display-name": "^7.24.7", "@babel/plugin-transform-react-jsx": "^7.28.6", "@babel/plugin-transform-react-jsx-development": "^7.27.1", "@babel/plugin-transform-react-pure-annotations": "^7.27.1", "@babel/plugin-transform-runtime": "^7.24.7", "@babel/plugin-transform-typescript": "^7.25.2", "@babel/plugin-transform-unicode-regex": "^7.24.7", "@babel/preset-typescript": "^7.23.0", "@react-native/babel-plugin-codegen": "0.86.2", "babel-plugin-react-compiler": "^1.0.0", "babel-plugin-react-native-web": "~0.21.0", "babel-plugin-syntax-hermes-parser": "^0.36.0", "babel-plugin-transform-flow-enums": "^0.0.2", "debug": "^4.3.4" }, "peerDependencies": { "@babel/runtime": "^7.20.0", "expo": "*", "expo-widgets": "^57.0.8", "react-refresh": ">=0.14.0 <1.0.0" }, "optionalPeers": ["@babel/runtime", "expo", "expo-widgets"] }, "sha512-ASyy0iP7yPQtq2QaMEnZG4O7YQ/x4sTMguk7PZcow2OHFnWsBpX6v+UCmh/uwCzGfD1q93jDQEuACWwWx4kSrw=="], + + "balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + + "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], + + "baseline-browser-mapping": ["baseline-browser-mapping@2.11.14", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-JyJ954WzuIR8/FFzX0o5krdSTrBAkcCSRfWSleRsIHSWV+cZe2FI1PKggVkFke1hBldRs+LRxUczzE9iPmgZww=="], + + "big-integer": ["big-integer@1.6.52", "", {}, "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg=="], + + "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="], + + "bplist-creator": ["bplist-creator@0.1.0", "", { "dependencies": { "stream-buffers": "2.2.x" } }, "sha512-sXaHZicyEEmY86WyueLTQesbeoH/mquvarJaQNbjuOQO+7gbFcDEWqKmcWA4cOTLzFlfgvkiVxolk1k5bBIpmg=="], + + "bplist-parser": ["bplist-parser@0.3.2", "", { "dependencies": { "big-integer": "1.6.x" } }, "sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ=="], + + "brace-expansion": ["brace-expansion@5.0.9", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg=="], + + "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], + + "browserslist": ["browserslist@4.28.8", "", { "dependencies": { "baseline-browser-mapping": "^2.11.12", "caniuse-lite": "^1.0.30001809", "electron-to-chromium": "^1.5.402", "node-releases": "^2.0.53", "update-browserslist-db": "^1.3.0" }, "bin": { "browserslist": "cli.js" } }, "sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA=="], + + "bser": ["bser@2.1.1", "", { "dependencies": { "node-int64": "^0.4.0" } }, "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ=="], + + "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="], + + "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="], + + "camelcase": ["camelcase@6.3.0", "", {}, "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="], + + "caniuse-lite": ["caniuse-lite@1.0.30001809", "", {}, "sha512-xxWVywk6a6Arlk+hymeycyn/VgqEfLDxupvhH/xiY5SJ/18kmi9o6MiO320DCUzypORHLtvh0I4i04tUhCNHNQ=="], + + "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], + + "chrome-launcher": ["chrome-launcher@0.15.2", "", { "dependencies": { "@types/node": "*", "escape-string-regexp": "^4.0.0", "is-wsl": "^2.2.0", "lighthouse-logger": "^1.0.0" }, "bin": { "print-chrome-path": "bin/print-chrome-path.js" } }, "sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ=="], + + "chromium-edge-launcher": ["chromium-edge-launcher@0.3.0", "", { "dependencies": { "@types/node": "*", "escape-string-regexp": "^4.0.0", "is-wsl": "^2.2.0", "lighthouse-logger": "^1.0.0", "mkdirp": "^1.0.4" } }, "sha512-p03azHlGjtyRvFEee3cyvtsRYdniSkwjkzmM/KmVnqT5d7QkkwpJBhis/zCLMYdQMVJ5tt140TBNqqrZPaWeFA=="], + + "ci-info": ["ci-info@3.9.0", "", {}, "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ=="], + + "cli-cursor": ["cli-cursor@2.1.0", "", { "dependencies": { "restore-cursor": "^2.0.0" } }, "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw=="], + + "cli-spinners": ["cli-spinners@2.9.2", "", {}, "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg=="], + + "client-only": ["client-only@0.0.1", "", {}, "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="], + + "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], + + "clone": ["clone@1.0.4", "", {}, "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg=="], + + "color": ["color@4.2.3", "", { "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" } }, "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A=="], + + "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], + + "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + + "color-string": ["color-string@1.9.1", "", { "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg=="], + + "commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="], + + "compressible": ["compressible@2.0.18", "", { "dependencies": { "mime-db": ">= 1.43.0 < 2" } }, "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg=="], + + "compression": ["compression@1.8.1", "", { "dependencies": { "bytes": "3.1.2", "compressible": "~2.0.18", "debug": "2.6.9", "negotiator": "~0.6.4", "on-headers": "~1.1.0", "safe-buffer": "5.2.1", "vary": "~1.1.2" } }, "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w=="], + + "connect": ["connect@3.7.0", "", { "dependencies": { "debug": "2.6.9", "finalhandler": "1.1.2", "parseurl": "~1.3.3", "utils-merge": "1.0.1" } }, "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ=="], + + "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], + + "core-js-compat": ["core-js-compat@3.50.0", "", { "dependencies": { "browserslist": "^4.28.7" } }, "sha512-XGpFGbMLHwSt74YLTKho7Ib242qi6O8MSX+sRokV4oz7iKXvQWGYZthjIhjRGMxjzVkAubBO512dKGYcefmX3Q=="], + + "cross-fetch": ["cross-fetch@3.2.0", "", { "dependencies": { "node-fetch": "^2.7.0" } }, "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q=="], + + "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], + + "css-in-js-utils": ["css-in-js-utils@3.1.0", "", { "dependencies": { "hyphenate-style-name": "^1.0.3" } }, "sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A=="], + + "css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="], + + "css-tree": ["css-tree@1.1.3", "", { "dependencies": { "mdn-data": "2.0.14", "source-map": "^0.6.1" } }, "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q=="], + + "css-what": ["css-what@6.2.2", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="], + + "css.escape": ["css.escape@1.5.1", "", {}, "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg=="], + + "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], + + "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" }, "peerDependencies": { "supports-color": "*" }, "optionalPeers": ["supports-color"] }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + + "decode-uri-component": ["decode-uri-component@0.2.2", "", {}, "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ=="], + + "deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="], + + "defaults": ["defaults@1.0.4", "", { "dependencies": { "clone": "^1.0.2" } }, "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A=="], + + "depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="], + + "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], + + "destroy": ["destroy@1.2.0", "", {}, "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="], + + "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + + "detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="], + + "dnssd-advertise": ["dnssd-advertise@1.1.6", "", {}, "sha512-Ndrrf6BMPalkQPd/zubL+4YghH2J9NspapQ09uDXwYbvOPkP0oaqf5CkcwJ0b50kS2O3ul6yVu+jz+RY62Cejg=="], + + "dom-accessibility-api": ["dom-accessibility-api@0.6.3", "", {}, "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w=="], + + "dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="], + + "domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="], + + "domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="], + + "domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="], + + "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], + + "electron-to-chromium": ["electron-to-chromium@1.5.405", "", {}, "sha512-bNglH7lPH5l+yHOes7Zr4VqxhOy4BQ9ZBUX4VdoFgxMpzJk7W1ZoO3Vgd9Pxa9PyjQ76sfm2aKH/nzEcCNRlew=="], + + "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + + "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="], + + "entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + + "error-stack-parser": ["error-stack-parser@2.1.4", "", { "dependencies": { "stackframe": "^1.3.4" } }, "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ=="], + + "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], + + "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], + + "escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="], + + "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], + + "etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="], + + "event-target-shim": ["event-target-shim@5.0.1", "", {}, "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="], + + "expo": ["expo@57.0.12", "", { "dependencies": { "@babel/runtime": "^7.20.0", "@expo/cli": "^57.0.14", "@expo/config": "~57.0.7", "@expo/config-plugins": "~57.0.7", "@expo/devtools": "~57.0.1", "@expo/dom-webview": "~57.0.1", "@expo/fingerprint": "^0.20.7", "@expo/local-build-cache-provider": "^57.0.6", "@expo/log-box": "^57.0.2", "@expo/metro": "~56.0.0", "@expo/metro-config": "~57.0.8", "@ungap/structured-clone": "^1.3.0", "babel-preset-expo": "~57.0.6", "expo-asset": "~57.0.10", "expo-constants": "~57.0.10", "expo-file-system": "~57.0.2", "expo-font": "~57.0.1", "expo-keep-awake": "~57.0.1", "expo-modules-autolinking": "~57.0.9", "expo-modules-core": "~57.0.10", "pretty-format": "^29.7.0", "react-refresh": "^0.14.2", "whatwg-url-minimum": "^0.1.2" }, "peerDependencies": { "@expo/metro-runtime": "*", "react": "*", "react-dom": "*", "react-native": "*", "react-native-web": "*", "react-native-webview": "*" }, "optionalPeers": ["@expo/metro-runtime", "react-dom", "react-native-web", "react-native-webview"], "bin": { "expo": "bin/cli", "fingerprint": "bin/fingerprint", "expo-modules-autolinking": "bin/autolinking" } }, "sha512-sVgXaMjh5uapBvBkik3QibxbKI2g1zNtNeHntjRfixWAI3tlQZbaK4ACdInY4+jUBVymkf8u9BXJUaSes9jdtA=="], + + "expo-asset": ["expo-asset@57.0.10", "", { "dependencies": { "@expo/image-utils": "^0.11.4", "expo-constants": "~57.0.10" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-32QpNkWlb8ftxq3ClAriwFXcZlpzuP7Qx4z3Gc9vhbAm1QZzGsCN+PwYt3fN8W46HBw5qaI6DSXcAyBlYzeVqA=="], + + "expo-blur": ["expo-blur@57.0.2", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-Aoud8H8lmlNkbRufyvRLefmGFELdBf1n5Te/Xm+Zx8ORINH+aXL+gKb5mbftFSha860+I7pMArz77TBYz8HDVg=="], + + "expo-constants": ["expo-constants@57.0.10", "", { "dependencies": { "@expo/env": "~2.4.2" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-GCDXYEsloBfouMdT3BzoGhAkcLnYxEFNLQoSbNKIvIrD9FY5MmSeWuvRSveJdOiuydwQY2iH6hy020vTaQflCQ=="], + + "expo-dev-client": ["expo-dev-client@57.0.11", "", { "dependencies": { "expo-dev-launcher": "~57.0.11", "expo-dev-menu": "~57.0.11", "expo-dev-menu-interface": "~57.0.0", "expo-manifests": "~57.0.1", "expo-updates-interface": "~57.0.1" }, "peerDependencies": { "expo": "*" } }, "sha512-IHatS97Vl0eQT8IG1Tsc10qDoyItxwjOw9AXLAbub+3uU7KljcqnXiCWRlhsI5KTjWV9/Dboc8psgiRb7oXXQw=="], + + "expo-dev-launcher": ["expo-dev-launcher@57.0.11", "", { "dependencies": { "@expo/schema-utils": "^57.0.2", "expo-dev-menu": "~57.0.11", "expo-manifests": "~57.0.1" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-PpYoSmtMkvLYG9xVVHv8ZDMMsHR0D5ax9lFTgy+e6WT98NLUTwTexlObOkjCB80cfiGaKfmOZEKyXRiec3Lgag=="], + + "expo-dev-menu": ["expo-dev-menu@57.0.11", "", { "dependencies": { "expo-dev-menu-interface": "~57.0.0" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-XY+rT7JALQAMBVYLLGfTwZ/E9igLDtUnyCPox1xxWaH6n7T3LJyxVb5unoORYhF4HzHQoxxeeHd6hg5P4AfyrQ=="], + + "expo-dev-menu-interface": ["expo-dev-menu-interface@57.0.0", "", { "peerDependencies": { "expo": "*" } }, "sha512-F47VdzOHYc19FhI/jBgctpO8a5UskTIxG6a1E5t3W5gF8VImuvBQffdXXfLHhsuCl7dS3v3U0R45cleeVXO1Zg=="], + + "expo-device": ["expo-device@57.0.1", "", { "dependencies": { "ua-parser-js": "^0.7.33" }, "peerDependencies": { "expo": "*" } }, "sha512-jyEMDUticH+dhcL3GHa2aiifOvGXJsmb3oVT2R2q4i8bN7Bddy61+NkpMmuS2VAZrvoLQwf0TJJ/1vi1ukvutA=="], + + "expo-file-system": ["expo-file-system@57.0.2", "", { "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-bPgzpaOJ3NWHZxV++Osj/1QoFzFe/QOo1jBF4EODJdiZgrrxyi2dv+7PLhKuut5QqPBuihUOITRh3s5jhRtA5A=="], + + "expo-font": ["expo-font@57.0.1", "", { "dependencies": { "fontfaceobserver": "^2.1.0" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-QyS9L1Kh9sKJg4gfU6rdbpxpmH+DyzBX8z6jVvXMUDoqLr1GqmkO/Wu379KCXjL///kWbhpNlbi7AgBuj4VdIQ=="], + + "expo-glass-effect": ["expo-glass-effect@57.0.1", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-m/n8maxqNcHk6ZDhuqXBfD5Kt1Iz3M8xykVgdB0iSCIXvF70IqWXmQhX8Psswhrp8eZ+3r0mAD0Jh/2gFA3QaA=="], + + "expo-haptics": ["expo-haptics@57.0.1", "", { "peerDependencies": { "expo": "*" } }, "sha512-8VhbnxlIrfXjP0syZr1JT197nafYicQu9119adOJnX62osU9Cw+PdDnAx/6LxuKJRzQdwxOMq7b7eWjhNL5zAQ=="], + + "expo-image": ["expo-image@57.0.2", "", { "dependencies": { "sf-symbols-typescript": "^2.2.0" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*", "react-native-web": "*" }, "optionalPeers": ["react-native-web"] }, "sha512-SAHDJiQ/Sf8JJ6NJ5/RbSewo8HtQtIGn4bDEgcvipwIw5lPURP0vXPzIOIrZ/ZroZ0abPgwTaWmkspoEO8Sxcw=="], + + "expo-json-utils": ["expo-json-utils@57.0.1", "", {}, "sha512-cgTe1NqzQdYs/WN+3nIY5IZg8s0pb0xaTUbhYvxQDn137GbwRfHoGM2se3m3Vsl4Qu+B9G4RPEK5WJDEU2Do7g=="], + + "expo-keep-awake": ["expo-keep-awake@57.0.1", "", { "peerDependencies": { "expo": "*", "react": "*" } }, "sha512-28lkFImeXTS+bhAjuCFV7w7tW5bXg27BJVrxv+nC/nyYa86qEa0oFeHwqol6ha5k4pdVDQgBF09GM4A1k76Ssg=="], + + "expo-linear-gradient": ["expo-linear-gradient@57.0.1", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-CpS8eMqoIWcHVGKV66zbDvzotCw9qYp3f8CuI9N+h1LaO0tMLUzBpkhAKePUsXlpN3yolYlHFSPkfVZ/uSh+iA=="], + + "expo-linking": ["expo-linking@57.0.5", "", { "dependencies": { "expo-constants": "~57.0.9", "invariant": "^2.2.4" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-SmJI3wr0EVfeKPGf+Qgr9gUbrXk8mM0ATqYLvAX/EAzawDjohPzMJ5pTt7TYMX0Wknj4XCtyCQrGhnERMXT6cQ=="], + + "expo-local-authentication": ["expo-local-authentication@57.0.2", "", { "dependencies": { "invariant": "^2.2.4" }, "peerDependencies": { "expo": "*" } }, "sha512-8K4zcrQ5wZkRS1rwEWY8qHbeGVMNh35e9D1VTVKlMHz1O47itW+pW6iBVuqwGFLozN4fRBeEDQH8hu9Gt58YuQ=="], + + "expo-manifests": ["expo-manifests@57.0.1", "", { "dependencies": { "expo-json-utils": "~57.0.1" }, "peerDependencies": { "expo": "*" } }, "sha512-qB/mDG2dYdl+EvUeQuqP8KFYCFgFCQjJYdWIHo8SFBgDzMYmdF286DFY2M1M9Okr99wkb5M4tgA3aCcwv3aEQA=="], + + "expo-modules-autolinking": ["expo-modules-autolinking@57.0.9", "", { "dependencies": { "@expo/require-utils": "^57.0.4", "@expo/spawn-async": "^1.8.0", "chalk": "^4.1.0", "commander": "^7.2.0" }, "bin": { "expo-modules-autolinking": "bin/expo-modules-autolinking.js" } }, "sha512-lj2nsAKMMRLXSFnGgaaQrWJ2fdSpLPc/bca6Rkiw4g8zYPn7qX4MRUJgavvzm/hBrzvMnlhXVgJtidOGuwBh+w=="], + + "expo-modules-core": ["expo-modules-core@57.0.10", "", { "dependencies": { "@expo/expo-modules-macros-plugin": "0.6.1", "expo-modules-jsi": "~57.0.4", "invariant": "^2.2.4" }, "peerDependencies": { "react": "*", "react-native": "*", "react-native-worklets": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0" }, "optionalPeers": ["react-native-worklets"] }, "sha512-aRi3G8OctoyZl8x9CLTVpbPljClfKm2eqKRgBzhcGsrH3gS1t5Y2ye7+PIZK4XK2VVP5iGqygN2b1vtqRo3xVQ=="], + + "expo-modules-jsi": ["expo-modules-jsi@57.0.4", "", { "peerDependencies": { "react-native": "*" } }, "sha512-vt7FyqUqqFXiRVnBqYD7y+GSPTgeua5Ocoy0+SYt+RSHkZEA2Fyop7If3g1TYDzQObYybPRo7TG2Rle1XLaWFw=="], + + "expo-router": ["expo-router@57.0.12", "", { "dependencies": { "@expo/log-box": "^57.0.2", "@expo/metro-runtime": "^57.0.9", "@expo/schema-utils": "^57.0.2", "@expo/ui": "^57.0.10", "@radix-ui/react-slot": "^1.2.0", "@radix-ui/react-tabs": "^1.1.12", "@react-native-masked-view/masked-view": "^0.3.2", "@testing-library/jest-dom": "^6.9.1", "@testing-library/user-event": "^14.6.1", "client-only": "^0.0.1", "color": "^4.2.3", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", "expo-glass-effect": "^57.0.1", "expo-server": "^57.0.2", "expo-symbols": "^57.0.2", "fast-deep-equal": "^3.1.3", "invariant": "^2.2.4", "nanoid": "^3.3.8", "query-string": "^7.1.3", "react-fast-compare": "^3.2.2", "react-is": "^19.1.0", "react-native-drawer-layout": "^4.2.2", "react-native-screens": "^4.26.0", "server-only": "^0.0.1", "sf-symbols-typescript": "^2.1.0", "shallowequal": "^1.1.0", "standard-navigation": "^0.0.5", "vaul": "^1.1.2" }, "peerDependencies": { "@testing-library/react-native": ">= 13.2.0", "expo": "*", "expo-constants": "^57.0.10", "expo-linking": "^57.0.5", "react": "*", "react-dom": "*", "react-native": "*", "react-native-gesture-handler": "*", "react-native-reanimated": "*", "react-native-safe-area-context": ">= 5.4.0", "react-native-web": "*", "react-server-dom-webpack": "~19.0.4 || ~19.1.5 || ~19.2.4" }, "optionalPeers": ["@testing-library/react-native", "react-dom", "react-native-gesture-handler", "react-native-reanimated", "react-native-web", "react-server-dom-webpack"] }, "sha512-vA+RUSzMwHmWa/pQpoYqJoTbhIQaX/OzvMvOlWVBeMflF1RC40zCzqLiXMKimWfEUh/G6ITnz31EtpNKUghxQw=="], + + "expo-secure-store": ["expo-secure-store@57.0.1", "", { "peerDependencies": { "expo": "*" } }, "sha512-tLa1VmSadOq19mA/dwkl99RbHyjLE0T1qqBYMY3/OsguZTI+rlrDy/DDJjupqlVtmr95hD7o1pYqx5aL+B4YMA=="], + + "expo-server": ["expo-server@57.0.2", "", {}, "sha512-GzfiSHC19xU7I0Dq4O/7DOtWdmc14vynpxBb9nWDRvsF+7RjoSIdkVePFhx4Qm6ILFNbo6KxFGu95QnDdKxUdw=="], + + "expo-splash-screen": ["expo-splash-screen@57.0.6", "", { "dependencies": { "@expo/config-plugins": "~57.0.7", "@expo/image-utils": "^0.11.4", "xml2js": "0.6.0" }, "peerDependencies": { "expo": "*" } }, "sha512-FY0E7hMyXVAsNh18yGzIjdooPXdjafalEb6mk2EcqNPjXspHuu+pVEhUscEunw4wF8F/w6MOpT7UfOwHVWez9g=="], + + "expo-status-bar": ["expo-status-bar@57.0.1", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-Xwaq1gAoVRWx5dPG5VhT5RSbnI9OilhZnO5qoPBnUaBAa5VzRzfdS8q0/bsPt0jR2DKLtGuP0bQ6efMJ4RIMDg=="], + + "expo-symbols": ["expo-symbols@57.0.2", "", { "dependencies": { "@expo-google-fonts/material-symbols": "^0.4.1", "sf-symbols-typescript": "^2.0.0" }, "peerDependencies": { "expo": "*", "expo-font": "*", "react": "*", "react-native": "*" } }, "sha512-qZ0iqOflm5lZGwRsQ5Y8sDksw3GAUKwHSX1bJBoocXf7gu14vafIXXYWte+JT9VfXAUGyKodJhLHP/GoOrcNWg=="], + + "expo-system-ui": ["expo-system-ui@57.0.2", "", { "dependencies": { "@react-native/normalize-colors": "0.86.2", "debug": "^4.3.2" }, "peerDependencies": { "expo": "*", "react-native": "*", "react-native-web": "*" }, "optionalPeers": ["react-native-web"] }, "sha512-zABCRqFSioDBAo/RtmS0dQiGgDtDPZUVk01Y3Ti4ducobNM4HTM2sNAtq+YPpEUhaVW3hccPVsEUH4LK/ADVhA=="], + + "expo-updates-interface": ["expo-updates-interface@57.0.1", "", { "peerDependencies": { "expo": "*" } }, "sha512-+LUWwJ0gf/TEKMVdQAw/Gjih4dvrk+URgy24X9qEGKuuMDZqjBRm9T4yQyBVALGL5TTdPUaB6ILxx3lshm3pwQ=="], + + "expo-web-browser": ["expo-web-browser@57.0.2", "", { "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-3vl5kvd7PB48ub6PpNIJUuPxO8xVa6D8RnIgNba6SXRwqFprOfeEZgwTgtm41kz0AAtvMOztUVNEUkwrHKjqMQ=="], + + "exponential-backoff": ["exponential-backoff@3.1.3", "", {}, "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA=="], + + "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], + + "fb-dotslash": ["fb-dotslash@0.5.8", "", { "bin": { "dotslash": "bin/dotslash" } }, "sha512-XHYLKk9J4BupDxi9bSEhkfss0m+Vr9ChTrjhf9l2iw3jB5C7BnY4GVPoMcqbrTutsKJso6yj2nAB6BI/F2oZaA=="], + + "fb-watchman": ["fb-watchman@2.0.2", "", { "dependencies": { "bser": "2.1.1" } }, "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA=="], + + "fbjs": ["fbjs@3.0.5", "", { "dependencies": { "cross-fetch": "^3.1.5", "fbjs-css-vars": "^1.0.0", "loose-envify": "^1.0.0", "object-assign": "^4.1.0", "promise": "^7.1.1", "setimmediate": "^1.0.5", "ua-parser-js": "^1.0.35" } }, "sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg=="], + + "fbjs-css-vars": ["fbjs-css-vars@1.0.2", "", {}, "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ=="], + + "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + + "fetch-nodeshim": ["fetch-nodeshim@0.4.10", "", {}, "sha512-m6I8ALe4L4XpdETy7MJZWs6L1IVMbjs99bwbpIKphxX+0CTns4IKDWJY0LWfr4YsFjfg+z1TjzTMU8lKl8rG0w=="], + + "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], + + "filter-obj": ["filter-obj@1.1.0", "", {}, "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ=="], + + "finalhandler": ["finalhandler@1.1.2", "", { "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "on-finished": "~2.3.0", "parseurl": "~1.3.3", "statuses": "~1.5.0", "unpipe": "~1.0.0" } }, "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA=="], + + "flow-enums-runtime": ["flow-enums-runtime@0.0.6", "", {}, "sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw=="], + + "fontfaceobserver": ["fontfaceobserver@2.3.0", "", {}, "sha512-6FPvD/IVyT4ZlNe7Wcn5Fb/4ChigpucKYSvD6a+0iMoLn2inpo711eyIcKjmDtE5XNcgAkSH9uN/nfAeZzHEfg=="], + + "fresh": ["fresh@0.5.2", "", {}, "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="], + + "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], + + "gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="], + + "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="], + + "get-nonce": ["get-nonce@1.0.1", "", {}, "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q=="], + + "getenv": ["getenv@2.0.0", "", {}, "sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ=="], + + "gifted-charts-core": ["gifted-charts-core@0.1.82", "", { "peerDependencies": { "react": "*", "react-native": "*", "react-native-svg": "*" } }, "sha512-2rwYFUj16Vod10Q0tBo5IZCfWqvIGBEWN/4XECnbbZrHmhkn+NpbaRHDg+ajyKgASUka/qT98eWQsVa8xZvPqA=="], + + "glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], + + "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], + + "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], + + "hasown": ["hasown@2.0.4", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A=="], + + "hermes-compiler": ["hermes-compiler@250829098.0.16", "", {}, "sha512-xsgzk+mUyvt9t1nUbF8USBlYxajTUtPJhVZ86q85s/SEoMKCF+52YZcudb0ENSnV3T3lV9mgB3s6R7+pH90zgw=="], + + "hermes-estree": ["hermes-estree@0.36.1", "", {}, "sha512-guv1nQ6IJ7S83NRFPWc3SA7IBZrdNC9kapwOq6uXvF4wP+sDCgjzQbKPCoyYmoyZRzztF/n/c36l/rccCZSiCw=="], + + "hermes-parser": ["hermes-parser@0.36.1", "", { "dependencies": { "hermes-estree": "0.36.1" } }, "sha512-GApNk4zLHi2UWoWZZkx7LNCOSzLSc5lB55pZ/PhK7ycFeg7u5LcF88p/WbpIi1XUDtE0MpHE3uRR3u3KB7TjSQ=="], + + "hoist-non-react-statics": ["hoist-non-react-statics@3.3.2", "", { "dependencies": { "react-is": "^16.7.0" } }, "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw=="], + + "hosted-git-info": ["hosted-git-info@7.0.2", "", { "dependencies": { "lru-cache": "^10.0.1" } }, "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w=="], + + "http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="], + + "https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], + + "hyphenate-style-name": ["hyphenate-style-name@1.1.0", "", {}, "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw=="], + + "ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], + + "image-size": ["image-size@1.2.1", "", { "dependencies": { "queue": "6.0.2" }, "bin": { "image-size": "bin/image-size.js" } }, "sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw=="], + + "indent-string": ["indent-string@4.0.0", "", {}, "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="], + + "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], + + "inline-style-prefixer": ["inline-style-prefixer@7.0.1", "", { "dependencies": { "css-in-js-utils": "^3.1.0" } }, "sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw=="], + + "invariant": ["invariant@2.2.4", "", { "dependencies": { "loose-envify": "^1.0.0" } }, "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA=="], + + "is-arrayish": ["is-arrayish@0.3.4", "", {}, "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA=="], + + "is-core-module": ["is-core-module@2.16.2", "", { "dependencies": { "hasown": "^2.0.3" } }, "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA=="], + + "is-docker": ["is-docker@2.2.1", "", { "bin": { "is-docker": "cli.js" } }, "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ=="], + + "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], + + "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], + + "is-wsl": ["is-wsl@2.2.0", "", { "dependencies": { "is-docker": "^2.0.0" } }, "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww=="], + + "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], + + "jest-get-type": ["jest-get-type@29.6.3", "", {}, "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw=="], + + "jest-util": ["jest-util@29.7.0", "", { "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", "graceful-fs": "^4.2.9", "picomatch": "^2.2.3" } }, "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA=="], + + "jest-validate": ["jest-validate@29.7.0", "", { "dependencies": { "@jest/types": "^29.6.3", "camelcase": "^6.2.0", "chalk": "^4.0.0", "jest-get-type": "^29.6.3", "leven": "^3.1.0", "pretty-format": "^29.7.0" } }, "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw=="], + + "jest-worker": ["jest-worker@29.7.0", "", { "dependencies": { "@types/node": "*", "jest-util": "^29.7.0", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" } }, "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw=="], + + "jimp-compact": ["jimp-compact@0.16.1", "", {}, "sha512-dZ6Ra7u1G8c4Letq/B5EzAxj4tLFHL+cGtdpR+PVm4yzPDj+lCk+AbivWt1eOM+ikzkowtyV7qSqX6qr3t71Ww=="], + + "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], + + "js-yaml": ["js-yaml@4.3.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ=="], + + "jsc-safe-url": ["jsc-safe-url@0.2.4", "", {}, "sha512-0wM3YBWtYePOjfyXQH5MWQ8H7sdk5EXSwZvmSLKk2RboVQ2Bu239jycHDz5J/8Blf3K0Qnoy2b6xD+z10MFB+Q=="], + + "jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="], + + "json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="], + + "kleur": ["kleur@3.0.3", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="], + + "lan-network": ["lan-network@0.2.1", "", { "bin": { "lan-network": "dist/lan-network-cli.js" } }, "sha512-ONPnazC96VKDntab9j9JKwIWhZ4ZUceB4A9Epu4Ssg0hYFmtHZSeQ+n15nIwTFmcBUKtExOer8WTJ4GF9MO64A=="], + + "leven": ["leven@3.1.0", "", {}, "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A=="], + + "lighthouse-logger": ["lighthouse-logger@1.4.2", "", { "dependencies": { "debug": "^2.6.9", "marky": "^1.2.2" } }, "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g=="], + + "lightningcss": ["lightningcss@1.33.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.33.0", "lightningcss-darwin-arm64": "1.33.0", "lightningcss-darwin-x64": "1.33.0", "lightningcss-freebsd-x64": "1.33.0", "lightningcss-linux-arm-gnueabihf": "1.33.0", "lightningcss-linux-arm64-gnu": "1.33.0", "lightningcss-linux-arm64-musl": "1.33.0", "lightningcss-linux-x64-gnu": "1.33.0", "lightningcss-linux-x64-musl": "1.33.0", "lightningcss-win32-arm64-msvc": "1.33.0", "lightningcss-win32-x64-msvc": "1.33.0" } }, "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA=="], + + "lightningcss-android-arm64": ["lightningcss-android-arm64@1.33.0", "", { "os": "android", "cpu": "arm64" }, "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg=="], + + "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.33.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg=="], + + "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.33.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ=="], + + "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.33.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg=="], + + "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.33.0", "", { "os": "linux", "cpu": "arm" }, "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ=="], + + "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.33.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg=="], + + "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.33.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ=="], + + "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.33.0", "", { "os": "linux", "cpu": "x64" }, "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg=="], + + "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.33.0", "", { "os": "linux", "cpu": "x64" }, "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw=="], + + "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.33.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA=="], + + "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.33.0", "", { "os": "win32", "cpu": "x64" }, "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA=="], + + "lodash.debounce": ["lodash.debounce@4.0.8", "", {}, "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="], + + "lodash.throttle": ["lodash.throttle@4.1.1", "", {}, "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="], + + "log-symbols": ["log-symbols@2.2.0", "", { "dependencies": { "chalk": "^2.0.1" } }, "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg=="], + + "loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="], + + "lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], + + "lz-string": ["lz-string@1.5.0", "", { "bin": { "lz-string": "bin/bin.js" } }, "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ=="], + + "makeerror": ["makeerror@1.0.12", "", { "dependencies": { "tmpl": "1.0.5" } }, "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg=="], + + "marky": ["marky@1.3.0", "", {}, "sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ=="], + + "mdn-data": ["mdn-data@2.0.14", "", {}, "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow=="], + + "memoize-one": ["memoize-one@5.2.1", "", {}, "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q=="], + + "merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="], + + "metro": ["metro@0.84.4", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/core": "^7.25.2", "@babel/generator": "^7.29.1", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/traverse": "^7.29.0", "@babel/types": "^7.29.0", "accepts": "^2.0.0", "ci-info": "^2.0.0", "connect": "^3.6.5", "debug": "^4.4.0", "error-stack-parser": "^2.0.6", "flow-enums-runtime": "^0.0.6", "graceful-fs": "^4.2.4", "hermes-parser": "0.35.0", "image-size": "^1.0.2", "invariant": "^2.2.4", "jest-worker": "^29.7.0", "jsc-safe-url": "^0.2.2", "lodash.throttle": "^4.1.1", "metro-babel-transformer": "0.84.4", "metro-cache": "0.84.4", "metro-cache-key": "0.84.4", "metro-config": "0.84.4", "metro-core": "0.84.4", "metro-file-map": "0.84.4", "metro-resolver": "0.84.4", "metro-runtime": "0.84.4", "metro-source-map": "0.84.4", "metro-symbolicate": "0.84.4", "metro-transform-plugins": "0.84.4", "metro-transform-worker": "0.84.4", "mime-types": "^3.0.1", "nullthrows": "^1.1.1", "serialize-error": "^2.1.0", "source-map": "^0.5.6", "throat": "^5.0.0", "ws": "^7.5.10", "yargs": "^17.6.2" }, "bin": { "metro": "src/cli.js" } }, "sha512-8ETTubqfD6ornDy2zYDvRcKnVDOXdFJsjetYDBsY4oAsb6NJkiwFR+FaMESyGppFmQUyBQA4H4sFGxzcQSGtFA=="], + + "metro-babel-transformer": ["metro-babel-transformer@0.84.4", "", { "dependencies": { "@babel/core": "^7.25.2", "flow-enums-runtime": "^0.0.6", "hermes-parser": "0.35.0", "metro-cache-key": "0.84.4", "nullthrows": "^1.1.1" } }, "sha512-rvCfz8snl9h20VcvpOHxZuHP1SlAkv4HXbzw7nyyVwu6Eqo5PRerbakQ9XmUCOsRy70spJ37O+G1TK8oMzo48g=="], + + "metro-cache": ["metro-cache@0.84.4", "", { "dependencies": { "exponential-backoff": "^3.1.1", "flow-enums-runtime": "^0.0.6", "https-proxy-agent": "^7.0.5", "metro-core": "0.84.4" } }, "sha512-gpcFQdSLUwUCk71saKoE64jLFbx2nwTfVCcPSULMNT8QYq0p1eZZE29Jvd0HtT/UlhC3ZOutLxJME5xqD2JUZg=="], + + "metro-cache-key": ["metro-cache-key@0.84.4", "", { "dependencies": { "flow-enums-runtime": "^0.0.6" } }, "sha512-wVO79aGrkYImpnaVS4+d5RrRBRPX31QtvKB3wKGBuiNSznduZTQHzsrJZRroFJSwnygrzdsGUtDQPuqqFjFdvw=="], + + "metro-config": ["metro-config@0.84.4", "", { "dependencies": { "connect": "^3.6.5", "flow-enums-runtime": "^0.0.6", "jest-validate": "^29.7.0", "metro": "0.84.4", "metro-cache": "0.84.4", "metro-core": "0.84.4", "metro-runtime": "0.84.4", "yaml": "^2.6.1" } }, "sha512-PMotGDjXcXLWo2TMRH+VR99phFNgYTwqh4OoieIKK3yTJa1Jmkl+fZJxDO0jfBvNF+WESHciHvpNuBtXaF3B0Q=="], + + "metro-core": ["metro-core@0.84.4", "", { "dependencies": { "flow-enums-runtime": "^0.0.6", "lodash.throttle": "^4.1.1", "metro-resolver": "0.84.4" } }, "sha512-HONpWC5LGXZn3ffkd4Hu6AIrfE7j4Z0g0wMo/goV24WOB3lhuFZ40KgvaDiSw8iyQHloMYay5N/wPX+z8oN/PQ=="], + + "metro-file-map": ["metro-file-map@0.84.4", "", { "dependencies": { "debug": "^4.4.0", "fb-watchman": "^2.0.0", "flow-enums-runtime": "^0.0.6", "graceful-fs": "^4.2.4", "invariant": "^2.2.4", "jest-worker": "^29.7.0", "micromatch": "^4.0.4", "nullthrows": "^1.1.1", "walker": "^1.0.7" } }, "sha512-KSVDi/u60hKPx++NLu3MTIvyjzNoJnFAF8PQFxaj1jiSka/wjw+Ua6sNuJ0TDHQv+7AAoFQxeMgaRAe8Yic5wQ=="], + + "metro-minify-terser": ["metro-minify-terser@0.84.4", "", { "dependencies": { "flow-enums-runtime": "^0.0.6", "terser": "^5.15.0" } }, "sha512-5qpbaVOMC7CPitIpuewzVeGw7E+C3ykbv2mqTjQLl85Z3annSVGlSCTcsZjqXZzjupfK4Ztj3dDc4kc44NZwtQ=="], + + "metro-resolver": ["metro-resolver@0.84.4", "", { "dependencies": { "flow-enums-runtime": "^0.0.6" } }, "sha512-1qLgbxQ5ZGhhutuPot1Yp348ofDsATL2WkrHF65TobqTT9K3P9qJXw38bomk7ncp5B7OYMfWwtyBZo1lCV792A=="], + + "metro-runtime": ["metro-runtime@0.84.4", "", { "dependencies": { "@babel/runtime": "^7.25.0", "flow-enums-runtime": "^0.0.6" } }, "sha512-Jibypds4g7AhzdRKY+kDoj51s5EXMwgyp5ddtlreDAsWefMdOx+agWqgm0H2XSZ/ueanHHVM89fnf5OJnlxa8Q=="], + + "metro-source-map": ["metro-source-map@0.84.4", "", { "dependencies": { "@babel/traverse": "^7.29.0", "@babel/types": "^7.29.0", "flow-enums-runtime": "^0.0.6", "invariant": "^2.2.4", "metro-symbolicate": "0.84.4", "nullthrows": "^1.1.1", "ob1": "0.84.4", "source-map": "^0.5.6", "vlq": "^1.0.0" } }, "sha512-jbWkPxIesVuo1IWkvezmMJld6iu8nD62GsrZiV6jP37AOdbo4OBq1FJ+qkOg8sV05wAHB//jAbziuW0SlJfW4g=="], + + "metro-symbolicate": ["metro-symbolicate@0.84.4", "", { "dependencies": { "flow-enums-runtime": "^0.0.6", "invariant": "^2.2.4", "metro-source-map": "0.84.4", "nullthrows": "^1.1.1", "source-map": "^0.5.6", "vlq": "^1.0.0" }, "bin": { "metro-symbolicate": "src/index.js" } }, "sha512-OnfpacxUqGPZQ27t8qK9mFa7uqHIlVWeqRqkCbvMvreEBiamEeOn8krKtcwgP5M4cYDPwuSmCTopHMVthqG4zA=="], + + "metro-transform-plugins": ["metro-transform-plugins@0.84.4", "", { "dependencies": { "@babel/core": "^7.25.2", "@babel/generator": "^7.29.1", "@babel/template": "^7.28.6", "@babel/traverse": "^7.29.0", "flow-enums-runtime": "^0.0.6", "nullthrows": "^1.1.1" } }, "sha512-kehr6HbAecqD0/a3xLXobELdPaAmRAl8bel0qagPF4vhZtux93nS8S4eq2kgKt6J2GnQpVjSoW1PXdst04mwow=="], + + "metro-transform-worker": ["metro-transform-worker@0.84.4", "", { "dependencies": { "@babel/core": "^7.25.2", "@babel/generator": "^7.29.1", "@babel/parser": "^7.29.0", "@babel/types": "^7.29.0", "flow-enums-runtime": "^0.0.6", "metro": "0.84.4", "metro-babel-transformer": "0.84.4", "metro-cache": "0.84.4", "metro-cache-key": "0.84.4", "metro-minify-terser": "0.84.4", "metro-source-map": "0.84.4", "metro-transform-plugins": "0.84.4", "nullthrows": "^1.1.1" } }, "sha512-W1IYMvvXTu4MxYr7d9h7CeG2vpIr3bmLLIavkPY4O1ilzDrvS8z/NEe6y+pC44Ff7raMXQgYSfdqDUwN/i39gg=="], + + "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], + + "mime": ["mime@1.6.0", "", { "bin": { "mime": "cli.js" } }, "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="], + + "mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], + + "mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], + + "mimic-fn": ["mimic-fn@1.2.0", "", {}, "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ=="], + + "min-indent": ["min-indent@1.0.1", "", {}, "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg=="], + + "minimatch": ["minimatch@10.2.6", "", { "dependencies": { "brace-expansion": "^5.0.8" } }, "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A=="], + + "minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], + + "mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="], + + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "multitars": ["multitars@1.0.2", "", {}, "sha512-6GwVw5eLi9sThdtlS4PKwC7yRLaf45pYhIEzKBHdKxi+YOXGKFX8acIniH+Uh/+k9mS2lQOupTccjoe5r0/1IQ=="], + + "nanoid": ["nanoid@3.3.18", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w=="], + + "negotiator": ["negotiator@0.6.3", "", {}, "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="], + + "node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], + + "node-forge": ["node-forge@1.4.0", "", {}, "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ=="], + + "node-int64": ["node-int64@0.4.0", "", {}, "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw=="], + + "node-releases": ["node-releases@2.0.53", "", {}, "sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ=="], + + "npm-package-arg": ["npm-package-arg@11.0.3", "", { "dependencies": { "hosted-git-info": "^7.0.0", "proc-log": "^4.0.0", "semver": "^7.3.5", "validate-npm-package-name": "^5.0.0" } }, "sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw=="], + + "nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="], + + "nullthrows": ["nullthrows@1.1.1", "", {}, "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw=="], + + "ob1": ["ob1@0.84.4", "", { "dependencies": { "flow-enums-runtime": "^0.0.6" } }, "sha512-eJXMpz4aQHXF/YBB9ddqZDIS+ooO91hObo9FoW/xBkr54/zCwYYCDqT/O54vNo8kOkWs5Ou/y28NgdrV0edQNA=="], + + "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], + + "on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="], + + "on-headers": ["on-headers@1.1.0", "", {}, "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A=="], + + "onetime": ["onetime@2.0.1", "", { "dependencies": { "mimic-fn": "^1.0.0" } }, "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ=="], + + "open": ["open@7.4.2", "", { "dependencies": { "is-docker": "^2.0.0", "is-wsl": "^2.1.1" } }, "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q=="], + + "ora": ["ora@3.4.0", "", { "dependencies": { "chalk": "^2.4.2", "cli-cursor": "^2.1.0", "cli-spinners": "^2.0.0", "log-symbols": "^2.2.0", "strip-ansi": "^5.2.0", "wcwidth": "^1.0.1" } }, "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg=="], + + "parse-png": ["parse-png@2.1.0", "", { "dependencies": { "pngjs": "^3.3.0" } }, "sha512-Nt/a5SfCLiTnQAjx3fHlqp8hRgTL3z7kTQZzvIMS9uCAepnCyjpdEc6M/sz69WqMBdaDBw9sF1F1UaHROYzGkQ=="], + + "parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="], + + "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], + + "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="], + + "path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="], + + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], + + "picomatch": ["picomatch@4.0.5", "", {}, "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A=="], + + "plist": ["plist@3.1.1", "", { "dependencies": { "@xmldom/xmldom": "^0.9.10", "base64-js": "^1.5.1", "xmlbuilder": "^15.1.1" } }, "sha512-ZIfcLJC+7E7FBFnDxm9MPmt7D+DidyQ26lewieO75AdhA2ayMtsJSES0iWzqJQbcVRSrTufQoy0DR94xHue0oA=="], + + "pngjs": ["pngjs@3.4.0", "", {}, "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w=="], + + "postcss": ["postcss@8.5.26", "", { "dependencies": { "nanoid": "^3.3.17", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ=="], + + "postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="], + + "pretty-format": ["pretty-format@29.7.0", "", { "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" } }, "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ=="], + + "proc-log": ["proc-log@4.2.0", "", {}, "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA=="], + + "progress": ["progress@2.0.3", "", {}, "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="], + + "promise": ["promise@8.3.0", "", { "dependencies": { "asap": "~2.0.6" } }, "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg=="], + + "prompts": ["prompts@2.4.2", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="], + + "query-string": ["query-string@7.1.3", "", { "dependencies": { "decode-uri-component": "^0.2.2", "filter-obj": "^1.1.0", "split-on-first": "^1.0.0", "strict-uri-encode": "^2.0.0" } }, "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg=="], + + "queue": ["queue@6.0.2", "", { "dependencies": { "inherits": "~2.0.3" } }, "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA=="], + + "range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="], + + "react": ["react@19.2.3", "", {}, "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA=="], + + "react-devtools-core": ["react-devtools-core@6.1.5", "", { "dependencies": { "shell-quote": "^1.6.1", "ws": "^7" } }, "sha512-ePrwPfxAnB+7hgnEr8vpKxL9cmnp7F322t8oqcPshbIQQhDKgFDW4tjhF2wjVbdXF9O/nyuy3sQWd9JGpiLPvA=="], + + "react-dom": ["react-dom@19.2.3", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.3" } }, "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg=="], + + "react-fast-compare": ["react-fast-compare@3.2.2", "", {}, "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ=="], + + "react-freeze": ["react-freeze@1.0.4", "", { "peerDependencies": { "react": ">=17.0.0" } }, "sha512-r4F0Sec0BLxWicc7HEyo2x3/2icUTrRmDjaaRyzzn+7aDyFZliszMDOgLVwSnQnYENOlL1o569Ze2HZefk8clA=="], + + "react-is": ["react-is@19.2.8", "", {}, "sha512-s5un28nYxKJw5gvUHyW5PCC28CvBqLu9r3cWgzHT4Vo/5fqqkFcdRYsGcKf50WMPpjjFZS5d76fn3YCo2njKwQ=="], + + "react-native": ["react-native@0.86.2", "", { "dependencies": { "@react-native/assets-registry": "0.86.2", "@react-native/codegen": "0.86.2", "@react-native/community-cli-plugin": "0.86.2", "@react-native/gradle-plugin": "0.86.2", "@react-native/js-polyfills": "0.86.2", "@react-native/normalize-colors": "0.86.2", "@react-native/virtualized-lists": "0.86.2", "abort-controller": "^3.0.0", "anser": "^1.4.9", "ansi-regex": "^5.0.0", "babel-plugin-syntax-hermes-parser": "0.36.0", "base64-js": "^1.5.1", "commander": "^12.0.0", "flow-enums-runtime": "^0.0.6", "hermes-compiler": "250829098.0.16", "invariant": "^2.2.4", "memoize-one": "^5.0.0", "metro-runtime": "^0.84.3", "metro-source-map": "^0.84.3", "nullthrows": "^1.1.1", "pretty-format": "^29.7.0", "promise": "^8.3.0", "react-devtools-core": "^6.1.5", "react-refresh": "^0.14.0", "regenerator-runtime": "^0.13.2", "scheduler": "0.27.0", "semver": "^7.1.3", "stacktrace-parser": "^0.1.10", "tinyglobby": "^0.2.15", "whatwg-fetch": "^3.0.0", "ws": "^7.5.10", "yargs": "^17.6.2" }, "peerDependencies": { "@react-native/jest-preset": "0.86.2", "@types/react": "^19.1.1", "react": "^19.2.3" }, "optionalPeers": ["@react-native/jest-preset", "@types/react"], "bin": { "react-native": "cli.js" } }, "sha512-zbJXGZpwfZGA79Z9ob6Atvfx4nAQL8yJBa35s58E4Oo+khPykfQP2sTeumkKbjwajFYfVayg8pj7Il9nIfTk7A=="], + + "react-native-drawer-layout": ["react-native-drawer-layout@4.2.10", "", { "dependencies": { "color": "^4.2.3", "use-latest-callback": "^0.2.4" }, "peerDependencies": { "react": ">= 18.2.0", "react-native": "*", "react-native-gesture-handler": ">= 2.0.0", "react-native-reanimated": ">= 2.0.0" } }, "sha512-O6TQdZ5LSm3dqnuR4rX9KPtE+9dVg7jsezEYz1l01rkQTe4fQvYZIoPu2sZFl5X2N70uhRdjnPULySVR3sBUwA=="], + + "react-native-gesture-handler": ["react-native-gesture-handler@2.32.0", "", { "dependencies": { "@egjs/hammerjs": "^2.0.17", "@types/react-test-renderer": "^19.1.0", "hoist-non-react-statics": "^3.3.0", "invariant": "^2.2.4" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-uYIMOKlKENORq2SABE+jIjbPU+h5I/sQKcq2v16zRq848nwEp1fWRVwML4QWqijc8UcXJC25o54S8GQd4Mf2OA=="], + + "react-native-gifted-charts": ["react-native-gifted-charts@1.4.78", "", { "dependencies": { "gifted-charts-core": "0.1.82" }, "peerDependencies": { "expo-linear-gradient": "*", "react": "*", "react-native": "*", "react-native-linear-gradient": "*", "react-native-svg": "*" }, "optionalPeers": ["expo-linear-gradient", "react-native-linear-gradient"] }, "sha512-6TGFeu7UkUi4LKJFiOjoFfdTNgTw4UyPaeCoIfo/YYT3a374pJ4bzKok3G9VM9J1JBlALtlKxl/oUOLPNwrawA=="], + + "react-native-is-edge-to-edge": ["react-native-is-edge-to-edge@1.3.1", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-NIXU/iT5+ORyCc7p0z2nnlkouYKX425vuU1OEm6bMMtWWR9yvb+Xg5AZmImTKoF9abxCPqrKC3rOZsKzUYgYZA=="], + + "react-native-reanimated": ["react-native-reanimated@4.5.1", "", { "dependencies": { "react-native-is-edge-to-edge": "^1.3.1", "semver": "^7.7.3" }, "peerDependencies": { "react": "*", "react-native": "0.83 - 0.86", "react-native-worklets": "0.10.x" } }, "sha512-RnMvtDuR+68ig864gAvZCOdZehqhC5rFmMo0kn+ARfgVSTvFeF6IFLBVgMPUu0KwihaapEyW24WRi6nEyy1kSA=="], + + "react-native-safe-area-context": ["react-native-safe-area-context@5.7.0", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-/9/MtQz8ODphjsLdZ+GZAIcC/RtoqW9EeShf7Uvnfgm/pzYrJ75y3PV/J1wuAV1T5Dye5ygq4EAW20RoBq0ABQ=="], + + "react-native-screens": ["react-native-screens@4.26.2", "", { "dependencies": { "react-freeze": "^1.0.0", "warn-once": "^0.1.0" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-2XnWsZToKj76trGtEZzx5ELD/qOICFEprEeUntImmitQFVUkea27fiWdUSITArI356Y1qynpXZINW+Unbhky/A=="], + + "react-native-svg": ["react-native-svg@15.15.4", "", { "dependencies": { "css-select": "^5.1.0", "css-tree": "^1.1.3", "warn-once": "0.1.1" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-boT/vIRgj6zZKBpfTPJJiYWMbZE9duBMOwPK6kCSTgxsS947IFMOq9OgIFkpWZTB7t229H24pDRkh3W9ZK/J1A=="], + + "react-native-web": ["react-native-web@0.21.2", "", { "dependencies": { "@babel/runtime": "^7.18.6", "@react-native/normalize-colors": "^0.74.1", "fbjs": "^3.0.4", "inline-style-prefixer": "^7.0.1", "memoize-one": "^6.0.0", "nullthrows": "^1.1.1", "postcss-value-parser": "^4.2.0", "styleq": "^0.1.3" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" } }, "sha512-SO2t9/17zM4iEnFvlu2DA9jqNbzNhoUP+AItkoCOyFmDMOhUnBBznBDCYN92fGdfAkfQlWzPoez6+zLxFNsZEg=="], + + "react-native-worklets": ["react-native-worklets@0.10.1", "", { "dependencies": { "@babel/plugin-transform-arrow-functions": "^7.27.1", "@babel/plugin-transform-class-properties": "^7.28.6", "@babel/plugin-transform-classes": "^7.28.6", "@babel/plugin-transform-nullish-coalescing-operator": "^7.28.6", "@babel/plugin-transform-optional-chaining": "^7.28.6", "@babel/plugin-transform-shorthand-properties": "^7.27.1", "@babel/plugin-transform-template-literals": "^7.27.1", "@babel/plugin-transform-unicode-regex": "^7.27.1", "@babel/preset-typescript": "^7.28.5", "@babel/types": "^7.27.1", "convert-source-map": "^2.0.0", "semver": "^7.7.4" }, "peerDependencies": { "@babel/core": "*", "@react-native/metro-config": "*", "react": "*", "react-native": "0.83 - 0.86" } }, "sha512-62mRM19bDpfpdI8HLkEErcdOsrAPDtE9lA/sw+5lLRpzBHNhxaoj9QyY2KjXqUmirelxkX4zuPGTC3VdA0feJA=="], + + "react-refresh": ["react-refresh@0.14.2", "", {}, "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA=="], + + "react-remove-scroll": ["react-remove-scroll@2.7.2", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", "use-callback-ref": "^1.3.3", "use-sidecar": "^1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q=="], + + "react-remove-scroll-bar": ["react-remove-scroll-bar@2.3.8", "", { "dependencies": { "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q=="], + + "react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="], + + "redent": ["redent@3.0.0", "", { "dependencies": { "indent-string": "^4.0.0", "strip-indent": "^3.0.0" } }, "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg=="], + + "regenerate": ["regenerate@1.4.2", "", {}, "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A=="], + + "regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="], + + "regenerator-runtime": ["regenerator-runtime@0.13.11", "", {}, "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="], + + "regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="], + + "regjsgen": ["regjsgen@0.8.0", "", {}, "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q=="], + + "regjsparser": ["regjsparser@0.13.2", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NgRBy2Nx/bE+9F27nVHnqcN5HjyLmecqsqx2PJHu3/IEtADD4WuxuXIVExD5PoSDFVrl78dOonfcOe5O+5nbzQ=="], + + "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], + + "resolve": ["resolve@1.22.12", "", { "dependencies": { "es-errors": "^1.3.0", "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA=="], + + "resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="], + + "resolve-workspace-root": ["resolve-workspace-root@2.0.1", "", {}, "sha512-nR23LHAvaI6aHtMg6RWoaHpdR4D881Nydkzi2CixINyg9T00KgaJdJI6Vwty+Ps8WLxZHuxsS0BseWjxSA4C+w=="], + + "restore-cursor": ["restore-cursor@2.0.0", "", { "dependencies": { "onetime": "^2.0.0", "signal-exit": "^3.0.2" } }, "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q=="], + + "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], + + "sax": ["sax@1.6.1", "", {}, "sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q=="], + + "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], + + "semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "send": ["send@0.19.2", "", { "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "~0.5.2", "http-errors": "~2.0.1", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "~2.4.1", "range-parser": "~1.2.1", "statuses": "~2.0.2" } }, "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg=="], + + "serialize-error": ["serialize-error@2.1.0", "", {}, "sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw=="], + + "serve-static": ["serve-static@1.16.3", "", { "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "~0.19.1" } }, "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA=="], + + "server-only": ["server-only@0.0.1", "", {}, "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA=="], + + "setimmediate": ["setimmediate@1.0.5", "", {}, "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="], + + "setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="], + + "sf-symbols-typescript": ["sf-symbols-typescript@2.2.0", "", {}, "sha512-TPbeg0b7ylrswdGCji8FRGFAKuqbpQlLbL8SOle3j1iHSs5Ob5mhvMAxWN2UItOjgALAB5Zp3fmMfj8mbWvXKw=="], + + "shallowequal": ["shallowequal@1.1.0", "", {}, "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ=="], + + "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], + + "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], + + "shell-quote": ["shell-quote@1.10.0", "", {}, "sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA=="], + + "signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], + + "simple-plist": ["simple-plist@1.3.1", "", { "dependencies": { "bplist-creator": "0.1.0", "bplist-parser": "0.3.1", "plist": "^3.0.5" } }, "sha512-iMSw5i0XseMnrhtIzRb7XpQEXepa9xhWxGUojHBL43SIpQuDQkh3Wpy67ZbDzZVr6EKxvwVChnVpdl8hEVLDiw=="], + + "simple-swizzle": ["simple-swizzle@0.2.4", "", { "dependencies": { "is-arrayish": "^0.3.1" } }, "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw=="], + + "sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="], + + "slugify": ["slugify@1.6.9", "", {}, "sha512-vZ7rfeehZui7wQs438JXBckYLkIIdfHOXsaVEUMyS5fHo1483l1bMdo0EDSWYclY0yZKFOipDy4KHuKs6ssvdg=="], + + "source-map": ["source-map@0.5.7", "", {}, "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ=="], + + "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], + + "source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="], + + "split-on-first": ["split-on-first@1.1.0", "", {}, "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw=="], + + "stackframe": ["stackframe@1.3.4", "", {}, "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw=="], + + "stacktrace-parser": ["stacktrace-parser@0.1.11", "", { "dependencies": { "type-fest": "^0.7.1" } }, "sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg=="], + + "standard-navigation": ["standard-navigation@0.0.5", "", {}, "sha512-YAmzwAiiQVocZxO/VGPFiQHcu5pKiz09QIGC0MK6aRMoa3E0QkoTQgcqJr7ZZ3OMiNhu4DkaGElFI5htjOIDbw=="], + + "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], + + "stream-buffers": ["stream-buffers@2.2.0", "", {}, "sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg=="], + + "strict-uri-encode": ["strict-uri-encode@2.0.0", "", {}, "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ=="], + + "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + + "strip-ansi": ["strip-ansi@5.2.0", "", { "dependencies": { "ansi-regex": "^4.1.0" } }, "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA=="], + + "strip-indent": ["strip-indent@3.0.0", "", { "dependencies": { "min-indent": "^1.0.0" } }, "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ=="], + + "structured-headers": ["structured-headers@0.4.1", "", {}, "sha512-0MP/Cxx5SzeeZ10p/bZI0S6MpgD+yxAhi1BOQ34jgnMXsCq3j1t6tQnZu+KdlL7dvJTLT3g9xN8tl10TqgFMcg=="], + + "styleq": ["styleq@0.1.3", "", {}, "sha512-3ZUifmCDCQanjeej1f6kyl/BeP/Vae5EYkQ9iJfUm/QwZvlgnZzyflqAsAWYURdtea8Vkvswu2GrC57h3qffcA=="], + + "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], + + "supports-hyperlinks": ["supports-hyperlinks@2.3.0", "", { "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" } }, "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA=="], + + "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], + + "terminal-link": ["terminal-link@2.1.1", "", { "dependencies": { "ansi-escapes": "^4.2.1", "supports-hyperlinks": "^2.0.0" } }, "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ=="], + + "terser": ["terser@5.50.0", "", { "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "bin": { "terser": "bin/terser" } }, "sha512-CN9BVxWhgS/hRxtUMjtC2uRWSTcSfQFHMDWma6sKKfIivCD91sM+FOPfvwoaRMqCSrUpe1nv3jDamd9eEQ4y+w=="], + + "throat": ["throat@5.0.0", "", {}, "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA=="], + + "tinyglobby": ["tinyglobby@0.2.17", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g=="], + + "tmpl": ["tmpl@1.0.5", "", {}, "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw=="], + + "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], + + "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="], + + "toqr": ["toqr@0.1.1", "", {}, "sha512-FWAPzCIHZHnrE/5/w9MPk0kK25hSQSH2IKhYh9PyjS3SG/+IEMvlwIHbhz+oF7xl54I+ueZlVnMjyzdSwLmAwA=="], + + "tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="], + + "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + + "type-fest": ["type-fest@0.7.1", "", {}, "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg=="], + + "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="], + + "ua-parser-js": ["ua-parser-js@0.7.41", "", { "bin": { "ua-parser-js": "script/cli.js" } }, "sha512-O3oYyCMPYgNNHuO7Jjk3uacJWZF8loBgwrfd/5LE/HyZ3lUIOdniQ7DNXJcIgZbwioZxk0fLfI4EVnetdiX5jg=="], + + "undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="], + + "unicode-canonical-property-names-ecmascript": ["unicode-canonical-property-names-ecmascript@2.0.1", "", {}, "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg=="], + + "unicode-match-property-ecmascript": ["unicode-match-property-ecmascript@2.0.0", "", { "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" } }, "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q=="], + + "unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="], + + "unicode-property-aliases-ecmascript": ["unicode-property-aliases-ecmascript@2.2.0", "", {}, "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ=="], + + "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="], + + "update-browserslist-db": ["update-browserslist-db@1.3.1", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-ZZ61DsRsOnakl74HAmp3oSN4aXUmEWXf+i/yv0h7tIBfICc3VdrFErQKUUKPgu3AMsTUMbcongALEN4l6GSUrQ=="], + + "use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="], + + "use-latest-callback": ["use-latest-callback@0.2.6", "", { "peerDependencies": { "react": ">=16.8" } }, "sha512-FvRG9i1HSo0wagmX63Vrm8SnlUU3LMM3WyZkQ76RnslpBrX694AdG4A0zQBx2B3ZifFA0yv/BaEHGBnEax5rZg=="], + + "use-sidecar": ["use-sidecar@1.1.3", "", { "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ=="], + + "use-sync-external-store": ["use-sync-external-store@1.6.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w=="], + + "utils-merge": ["utils-merge@1.0.1", "", {}, "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="], + + "uuid": ["uuid@7.0.3", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg=="], + + "validate-npm-package-name": ["validate-npm-package-name@5.0.1", "", {}, "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ=="], + + "vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="], + + "vaul": ["vaul@1.1.2", "", { "dependencies": { "@radix-ui/react-dialog": "^1.1.1" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA=="], + + "vlq": ["vlq@1.0.1", "", {}, "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w=="], + + "walker": ["walker@1.0.8", "", { "dependencies": { "makeerror": "1.0.12" } }, "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ=="], + + "warn-once": ["warn-once@0.1.1", "", {}, "sha512-VkQZJbO8zVImzYFteBXvBOZEl1qL175WH8VmZcxF2fZAoudNhNDvHi+doCaAEdU2l2vtcIwa2zn0QK5+I1HQ3Q=="], + + "wcwidth": ["wcwidth@1.0.1", "", { "dependencies": { "defaults": "^1.0.3" } }, "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg=="], + + "webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="], + + "whatwg-fetch": ["whatwg-fetch@3.6.20", "", {}, "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg=="], + + "whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="], + + "whatwg-url-minimum": ["whatwg-url-minimum@0.1.2", "", {}, "sha512-XPEm0XFQWNVG292lII1PrRRJl3sItrs7CettZ4ncYxuDVpLyy+NwlGyut2hXI0JswcJUxeCH+CyOJK0ZzAXD6A=="], + + "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], + + "wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + + "ws": ["ws@7.5.13", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-rsKI6xDBFVf4r/x8XyChGK04QR/XHroxs/jUcoWvtEZM8TPU/X/uIY9B1CsSzYws9ZJb/6bbBu7dPhFW00CAoA=="], + + "xcode": ["xcode@3.0.1", "", { "dependencies": { "simple-plist": "^1.1.0", "uuid": "^7.0.3" } }, "sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA=="], + + "xml2js": ["xml2js@0.6.0", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-eLTh0kA8uHceqesPqSE+VvO1CDDJWMwlQfB6LuN6T8w6MaDJ8Txm8P7s5cHD0miF0V+GGTZrDQfxPZQVsur33w=="], + + "xmlbuilder": ["xmlbuilder@11.0.1", "", {}, "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="], + + "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], + + "yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], + + "yaml": ["yaml@2.9.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA=="], + + "yargs": ["yargs@17.7.3", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g=="], + + "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], + + "zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + + "@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "@babel/helper-create-class-features-plugin/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "@babel/helper-create-regexp-features-plugin/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "@babel/plugin-transform-runtime/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "@expo/cli/ws": ["ws@8.21.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw=="], + + "@expo/devcert/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="], + + "@expo/plist/xmlbuilder": ["xmlbuilder@15.1.1", "", {}, "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="], + + "@expo/ws-tunnel/ws": ["ws@8.21.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw=="], + + "@react-native/babel-preset/@react-native/babel-plugin-codegen": ["@react-native/babel-plugin-codegen@0.87.0", "", { "dependencies": { "@babel/traverse": "^7.29.0", "@react-native/codegen": "0.87.0" } }, "sha512-q0CCSAYgomb2G1fkmJ5ughwvVLqjHcdJ4w3Ffxw4YsdBenWYZsnMARyr/ghvcvfV33/YsZQhdMZ3XnpG6oth/Q=="], + + "@react-native/babel-preset/babel-plugin-syntax-hermes-parser": ["babel-plugin-syntax-hermes-parser@0.36.1", "", { "dependencies": { "hermes-parser": "0.36.1" } }, "sha512-ycduwJbvdvIMmVvlAZqGggS+pm5Eu4Bk9pcV9Sm2Z4PJNRVsKkv0g7vHj+LeuC1gHTeF67sJXFOq61IlqCa2hA=="], + + "@react-native/codegen/hermes-parser": ["hermes-parser@0.36.0", "", { "dependencies": { "hermes-estree": "0.36.0" } }, "sha512-GdpwMmH5x6IpC1cijvcvYnlPB60Mh6kTSF/NFdYV/j56gYdi+0RIakYs+eqOV+bbO0SW7mgVVGSsTJxyPQfo3w=="], + + "@react-native/metro-config/@react-native/js-polyfills": ["@react-native/js-polyfills@0.87.0", "", {}, "sha512-iwX3S/6XnR/TkOIk6Cz+FjeToDM/a4M1Cz/o1tfDakULjhKMI/UBtta1DsJgeg5c4WIJjkD4c8XlAJEb8pWOtg=="], + + "@react-native/metro-config/metro-config": ["metro-config@0.87.0", "", { "dependencies": { "connect": "^3.6.5", "flow-enums-runtime": "^0.0.6", "jest-validate": "^29.7.0", "metro": "0.87.0", "metro-cache": "0.87.0", "metro-core": "0.87.0", "metro-runtime": "0.87.0" } }, "sha512-yZ9QAIzWH9MxwrzwRlX/CBGRWOT14l7klSDYg8hdtSdnoUs5A7MQRdHE2KB9iHVzGQW5wgWM5aXJswNeWbSQPA=="], + + "@react-native/metro-config/metro-runtime": ["metro-runtime@0.87.0", "", { "dependencies": { "@babel/runtime": "^7.25.0", "flow-enums-runtime": "^0.0.6" } }, "sha512-XsXZkgEwI0ZMYSBfvOMAbenzwa60XlObXJ27g6/Khgrz9ESbiBbAsd7hR62G2jRBYOhGAzG61Gk22dpRJj/mdw=="], + + "@react-navigation/native/standard-navigation": ["standard-navigation@0.0.8", "", { "peerDependencies": { "react": "*" } }, "sha512-TyVbo7INUDWtsUWDFn8RR7kwR87U0S4xHfLfbbnyeC581TmmyqQ+eM+nPw8rQTSD8QitRVcYfPaSHr/QJiUy1g=="], + + "@testing-library/dom/aria-query": ["aria-query@5.3.0", "", { "dependencies": { "dequal": "^2.0.3" } }, "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A=="], + + "@testing-library/dom/dom-accessibility-api": ["dom-accessibility-api@0.5.16", "", {}, "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg=="], + + "@testing-library/dom/pretty-format": ["pretty-format@27.5.1", "", { "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" } }, "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ=="], + + "ansi-escapes/type-fest": ["type-fest@0.21.3", "", {}, "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w=="], + + "babel-plugin-polyfill-corejs2/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "babel-plugin-syntax-hermes-parser/hermes-parser": ["hermes-parser@0.36.0", "", { "dependencies": { "hermes-estree": "0.36.0" } }, "sha512-GdpwMmH5x6IpC1cijvcvYnlPB60Mh6kTSF/NFdYV/j56gYdi+0RIakYs+eqOV+bbO0SW7mgVVGSsTJxyPQfo3w=="], + + "chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + + "cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "compressible/mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], + + "compression/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], + + "compression/negotiator": ["negotiator@0.6.4", "", {}, "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w=="], + + "connect/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], + + "css-tree/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], + + "expo-modules-autolinking/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="], + + "fbjs/promise": ["promise@7.3.1", "", { "dependencies": { "asap": "~2.0.3" } }, "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg=="], + + "fbjs/ua-parser-js": ["ua-parser-js@1.0.41", "", { "bin": { "ua-parser-js": "script/cli.js" } }, "sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug=="], + + "finalhandler/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], + + "finalhandler/encodeurl": ["encodeurl@1.0.2", "", {}, "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="], + + "finalhandler/on-finished": ["on-finished@2.3.0", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww=="], + + "finalhandler/statuses": ["statuses@1.5.0", "", {}, "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA=="], + + "hoist-non-react-statics/react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="], + + "hosted-git-info/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + + "jest-util/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], + + "jest-worker/supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="], + + "lighthouse-logger/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], + + "log-symbols/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="], + + "metro/accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], + + "metro/ci-info": ["ci-info@2.0.0", "", {}, "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ=="], + + "metro/hermes-parser": ["hermes-parser@0.35.0", "", { "dependencies": { "hermes-estree": "0.35.0" } }, "sha512-9JLjeHxBx8T4CAsydZR49PNZUaix+WpQJwu9p2010lu+7Kwl6D/7wYFFJxoz+aXkaaClp9Zfg6W6/zVlSJORaA=="], + + "metro/mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], + + "metro-babel-transformer/hermes-parser": ["hermes-parser@0.35.0", "", { "dependencies": { "hermes-estree": "0.35.0" } }, "sha512-9JLjeHxBx8T4CAsydZR49PNZUaix+WpQJwu9p2010lu+7Kwl6D/7wYFFJxoz+aXkaaClp9Zfg6W6/zVlSJORaA=="], + + "micromatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], + + "ora/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="], + + "path-scurry/lru-cache": ["lru-cache@11.5.2", "", {}, "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g=="], + + "plist/@xmldom/xmldom": ["@xmldom/xmldom@0.9.11", "", {}, "sha512-tW8bcK3hsG0/uqSnNz6TK4BkcuZSezoU7DlnYssILmZDktPnSHHuDJJFM0AJv+13gz2r0iGdrj6qqKeUnxXEDg=="], + + "plist/xmlbuilder": ["xmlbuilder@15.1.1", "", {}, "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="], + + "pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="], + + "react-native-web/@react-native/normalize-colors": ["@react-native/normalize-colors@0.74.89", "", {}, "sha512-qoMMXddVKVhZ8PA1AbUCk83trpd6N+1nF2A6k1i6LsQObyS92fELuk8kU/lQs6M7BsMHwqyLCpQJ1uFgNvIQXg=="], + + "react-native-web/memoize-one": ["memoize-one@6.0.0", "", {}, "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="], + + "send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], + + "simple-plist/bplist-parser": ["bplist-parser@0.3.1", "", { "dependencies": { "big-integer": "1.6.x" } }, "sha512-PyJxiNtA5T2PlLIeBot4lbp7rj4OadzjnMZD/G5zuBNt8ei/yCU7+wW0h2bag9vr8c+/WuRWmSxbqAl9hL1rBA=="], + + "source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], + + "string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "strip-ansi/ansi-regex": ["ansi-regex@4.1.1", "", {}, "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g=="], + + "terser/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], + + "wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + + "wrap-ansi/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "@react-native/babel-preset/@react-native/babel-plugin-codegen/@react-native/codegen": ["@react-native/codegen@0.87.0", "", { "dependencies": { "@babel/core": "^7.25.2", "@babel/parser": "^7.29.0", "hermes-parser": "0.36.1", "invariant": "^2.2.4", "nullthrows": "^1.1.1", "tinyglobby": "^0.2.15", "yargs": "^17.6.2" } }, "sha512-odcBGR0A9Ee83A/XvzOp9juGRkSQOQcI4ZYs+3H20MySMxvZJ34/2nVHoxdmj0YY0Mn6gF8BjLzYkL0axbHuCA=="], + + "@react-native/codegen/hermes-parser/hermes-estree": ["hermes-estree@0.36.0", "", {}, "sha512-A1+8zn5oss2CFP7pKsOaxorQG6FNIz1WU1VDqruLPPZl3LVgeE2C5xfFg8Ow6/Ow4mSslLLtYP1J3n38eKyW9w=="], + + "@react-native/metro-config/metro-config/metro": ["metro@0.87.0", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/core": "^7.25.2", "@babel/generator": "^7.29.1", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/traverse": "^7.29.0", "@babel/types": "^7.29.0", "accepts": "^2.0.0", "ci-info": "^2.0.0", "connect": "^3.6.5", "debug": "^4.4.0", "error-stack-parser": "^2.0.6", "flow-enums-runtime": "^0.0.6", "graceful-fs": "^4.2.4", "hermes-parser": "0.36.1", "image-size": "^1.0.2", "invariant": "^2.2.4", "jest-worker": "^29.7.0", "jsc-safe-url": "^0.2.2", "lodash.throttle": "^4.1.1", "metro-babel-transformer": "0.87.0", "metro-cache": "0.87.0", "metro-cache-key": "0.87.0", "metro-config": "0.87.0", "metro-core": "0.87.0", "metro-file-map": "0.87.0", "metro-resolver": "0.87.0", "metro-runtime": "0.87.0", "metro-source-map": "0.87.0", "metro-symbolicate": "0.87.0", "metro-transform-plugins": "0.87.0", "metro-transform-worker": "0.87.0", "mime-types": "^3.0.1", "nullthrows": "^1.1.1", "serialize-error": "^2.1.0", "source-map": "^0.5.6", "throat": "^5.0.0", "ws": "^7.5.10", "yargs": "^17.6.2" }, "bin": { "metro": "src/cli.js" } }, "sha512-fRqFhSzQhLNQSCvJFeuRzBRXAOOKXf1O8d2cvmMtG6yFR0jCllQ7vBsXoLP18yuqtf+N1XwWXTPF11eWy9q6dQ=="], + + "@react-native/metro-config/metro-config/metro-cache": ["metro-cache@0.87.0", "", { "dependencies": { "exponential-backoff": "^3.1.1", "flow-enums-runtime": "^0.0.6", "https-proxy-agent": "^7.0.5", "metro-core": "0.87.0" } }, "sha512-146vS1BMSKcp99jddOhFBfHwzUEWN35NrsnSJDF2sQQ0ZT5OsBcOjd574PM233TWEZISRJ5DOK+vokD+1ubx+w=="], + + "@react-native/metro-config/metro-config/metro-core": ["metro-core@0.87.0", "", { "dependencies": { "flow-enums-runtime": "^0.0.6", "lodash.throttle": "^4.1.1", "metro-resolver": "0.87.0" } }, "sha512-yW57+pCOHRC/CJZ99GA2PTd+30dORwDAjUPRCokj91IWW5In9Jwtt2FB5wACrGO8P0GHTyVHdTwDNyZsNndUbA=="], + + "@testing-library/dom/pretty-format/react-is": ["react-is@17.0.2", "", {}, "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="], + + "babel-plugin-syntax-hermes-parser/hermes-parser/hermes-estree": ["hermes-estree@0.36.0", "", {}, "sha512-A1+8zn5oss2CFP7pKsOaxorQG6FNIz1WU1VDqruLPPZl3LVgeE2C5xfFg8Ow6/Ow4mSslLLtYP1J3n38eKyW9w=="], + + "compression/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], + + "connect/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], + + "finalhandler/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], + + "lighthouse-logger/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], + + "log-symbols/chalk/ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "^1.9.0" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="], + + "log-symbols/chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], + + "log-symbols/chalk/supports-color": ["supports-color@5.5.0", "", { "dependencies": { "has-flag": "^3.0.0" } }, "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="], + + "metro-babel-transformer/hermes-parser/hermes-estree": ["hermes-estree@0.35.0", "", {}, "sha512-xVx5Opwy8Oo1I5yGpVRhCvWL/iV3M+ylksSKVNlxxD90cpDpR/AR1jLYqK8HWihm065a6UI3HeyAmYzwS8NOOg=="], + + "metro/accepts/negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], + + "metro/hermes-parser/hermes-estree": ["hermes-estree@0.35.0", "", {}, "sha512-xVx5Opwy8Oo1I5yGpVRhCvWL/iV3M+ylksSKVNlxxD90cpDpR/AR1jLYqK8HWihm065a6UI3HeyAmYzwS8NOOg=="], + + "metro/mime-types/mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], + + "ora/chalk/ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "^1.9.0" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="], + + "ora/chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], + + "ora/chalk/supports-color": ["supports-color@5.5.0", "", { "dependencies": { "has-flag": "^3.0.0" } }, "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="], + + "send/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], + + "@react-native/metro-config/metro-config/metro/accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], + + "@react-native/metro-config/metro-config/metro/ci-info": ["ci-info@2.0.0", "", {}, "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ=="], + + "@react-native/metro-config/metro-config/metro/metro-babel-transformer": ["metro-babel-transformer@0.87.0", "", { "dependencies": { "@babel/core": "^7.25.2", "flow-enums-runtime": "^0.0.6", "hermes-parser": "0.36.1", "metro-cache-key": "0.87.0", "nullthrows": "^1.1.1" } }, "sha512-IEn1K1FyY4J1sA5y6zqDjf2OkfmpTEqhZOeP6MJX8HepSW0cuHGw1m8bYOdv2adkG3XUE9dtM0csUs0gP/Xa5w=="], + + "@react-native/metro-config/metro-config/metro/metro-cache-key": ["metro-cache-key@0.87.0", "", { "dependencies": { "flow-enums-runtime": "^0.0.6" } }, "sha512-Q+MPt6jl0zQogr4Q02WaJK6HY+GtE5A0nzj8kIV1Owgrx6OMNvm6scPTr1SM/R4LpCE8EH/Y5qfbXQ84GHTr0Q=="], + + "@react-native/metro-config/metro-config/metro/metro-file-map": ["metro-file-map@0.87.0", "", { "dependencies": { "debug": "^4.4.0", "fb-watchman": "^2.0.0", "flow-enums-runtime": "^0.0.6", "graceful-fs": "^4.2.4", "invariant": "^2.2.4", "jest-worker": "^29.7.0", "micromatch": "^4.0.4", "nullthrows": "^1.1.1", "walker": "^1.0.7" } }, "sha512-Dc57t8jsINwA90bbVlqaeDlxf1rVGgj5SmOEnOMbaHNUM/HCYYTJxPV8SRdOBwh7qTz/biO9vaQvBTjRBgbbsg=="], + + "@react-native/metro-config/metro-config/metro/metro-resolver": ["metro-resolver@0.87.0", "", { "dependencies": { "flow-enums-runtime": "^0.0.6" } }, "sha512-Xl3M9R3KToaHJvXlI2lSOxtYHitzxite+195DSi00HL9PcS7Xik5+3xlRjfkKb3FA86SZxYPj+WJwlcfgaZoxg=="], + + "@react-native/metro-config/metro-config/metro/metro-source-map": ["metro-source-map@0.87.0", "", { "dependencies": { "@babel/traverse": "^7.29.0", "@babel/types": "^7.29.0", "flow-enums-runtime": "^0.0.6", "invariant": "^2.2.4", "metro-symbolicate": "0.87.0", "nullthrows": "^1.1.1", "ob1": "0.87.0", "source-map": "^0.5.6", "vlq": "^1.0.0" } }, "sha512-31BrYqu1c2co93rF1LN9Pw+7g+BrfDyxJkNQWrYm+pfA/+eVYVumF7tFMHbXLePLmHfhvSgVvbK6su1Oyiw1ng=="], + + "@react-native/metro-config/metro-config/metro/metro-symbolicate": ["metro-symbolicate@0.87.0", "", { "dependencies": { "flow-enums-runtime": "^0.0.6", "invariant": "^2.2.4", "metro-source-map": "0.87.0", "nullthrows": "^1.1.1", "source-map": "^0.5.6", "vlq": "^1.0.0" }, "bin": { "metro-symbolicate": "src/index.js" } }, "sha512-uOpTxAXu74N+RSujUZ78L6gjI6bDdnz6XuW+AIUNuubZDEQPIpaX0StzIb0GMeQWP6zfHOHwFrWPP5Iquu1GXw=="], + + "@react-native/metro-config/metro-config/metro/metro-transform-plugins": ["metro-transform-plugins@0.87.0", "", { "dependencies": { "@babel/core": "^7.25.2", "@babel/generator": "^7.29.1", "@babel/template": "^7.28.6", "@babel/traverse": "^7.29.0", "flow-enums-runtime": "^0.0.6", "nullthrows": "^1.1.1" } }, "sha512-i8keUe9+BaSwMuQM26DGheElCpTtflAKIrSwJAm8ZsgDb50RAUQus+e6zt2suaJXJ1OxZa7vqgtqoZxdniM6Fw=="], + + "@react-native/metro-config/metro-config/metro/metro-transform-worker": ["metro-transform-worker@0.87.0", "", { "dependencies": { "@babel/core": "^7.25.2", "@babel/generator": "^7.29.1", "@babel/parser": "^7.29.0", "@babel/types": "^7.29.0", "flow-enums-runtime": "^0.0.6", "metro": "0.87.0", "metro-babel-transformer": "0.87.0", "metro-cache": "0.87.0", "metro-cache-key": "0.87.0", "metro-minify-terser": "0.87.0", "metro-source-map": "0.87.0", "metro-transform-plugins": "0.87.0", "nullthrows": "^1.1.1" } }, "sha512-YftLzNJxCTYxEN5k4AzR8KYwiENTEuz30L+4QeoMrtDd+U8mDThZg/ArR3JVRd8LaikwPOjVAS5SP3xPJN0AaA=="], + + "@react-native/metro-config/metro-config/metro/mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], + + "@react-native/metro-config/metro-config/metro-core/metro-resolver": ["metro-resolver@0.87.0", "", { "dependencies": { "flow-enums-runtime": "^0.0.6" } }, "sha512-Xl3M9R3KToaHJvXlI2lSOxtYHitzxite+195DSi00HL9PcS7Xik5+3xlRjfkKb3FA86SZxYPj+WJwlcfgaZoxg=="], + + "log-symbols/chalk/ansi-styles/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="], + + "log-symbols/chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="], + + "ora/chalk/ansi-styles/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="], + + "ora/chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="], + + "@react-native/metro-config/metro-config/metro/accepts/negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], + + "@react-native/metro-config/metro-config/metro/metro-source-map/ob1": ["ob1@0.87.0", "", { "dependencies": { "flow-enums-runtime": "^0.0.6" } }, "sha512-8Q8sKCiUwsxgSmjDtVWyRgmxsgeJXXam3oQH6Id8ADfNaJMV6GZKyeAl8+pGVVdgwAZabfk5+aExle7AP/nZiA=="], + + "@react-native/metro-config/metro-config/metro/metro-transform-worker/metro-minify-terser": ["metro-minify-terser@0.87.0", "", { "dependencies": { "flow-enums-runtime": "^0.0.6", "terser": "^5.15.0" } }, "sha512-tPa0O983PDutFu3LXbArRH5NduogcKrvW6fs9VHhksTKUA1iqDyoD1ZSj/Me52xJ6T9/9pOwIVyj9ulKc/zMkg=="], + + "@react-native/metro-config/metro-config/metro/mime-types/mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], + + "log-symbols/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="], + + "ora/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="], + } +} diff --git a/eas.json b/eas.json new file mode 100644 index 0000000..c6a91e8 --- /dev/null +++ b/eas.json @@ -0,0 +1,21 @@ +{ + "cli": { + "version": ">= 21.8.0", + "appVersionSource": "remote" + }, + "build": { + "development": { + "developmentClient": true, + "distribution": "internal" + }, + "preview": { + "distribution": "internal" + }, + "production": { + "autoIncrement": true + } + }, + "submit": { + "production": {} + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..73ebdb4 --- /dev/null +++ b/package.json @@ -0,0 +1,54 @@ +{ + "name": "yaba", + "main": "expo-router/entry", + "version": "1.0.0", + "dependencies": { + "@expo-google-fonts/dm-sans": "^0.4.2", + "@expo/ui": "~57.0.10", + "@expo/vector-icons": "^15.0.2", + "@react-navigation/bottom-tabs": "^7.18.16", + "expo": "~57.0.12", + "expo-blur": "~57.0.2", + "expo-constants": "~57.0.10", + "expo-dev-client": "~57.0.11", + "expo-device": "~57.0.1", + "expo-font": "~57.0.1", + "expo-glass-effect": "~57.0.1", + "expo-haptics": "~57.0.1", + "expo-image": "~57.0.2", + "expo-linear-gradient": "~57.0.1", + "expo-linking": "~57.0.5", + "expo-local-authentication": "~57.0.2", + "expo-router": "~57.0.12", + "expo-secure-store": "~57.0.1", + "expo-splash-screen": "~57.0.6", + "expo-status-bar": "~57.0.1", + "expo-symbols": "~57.0.2", + "expo-system-ui": "~57.0.2", + "expo-web-browser": "~57.0.2", + "react": "19.2.3", + "react-dom": "19.2.3", + "react-native": "0.86.2", + "react-native-gesture-handler": "~2.32.0", + "react-native-gifted-charts": "^1.4.78", + "react-native-reanimated": "4.5.1", + "react-native-safe-area-context": "~5.7.0", + "react-native-screens": "~4.26.0", + "react-native-svg": "15.15.4", + "react-native-web": "~0.21.0", + "react-native-worklets": "0.10.1" + }, + "devDependencies": { + "@types/react": "~19.2.2", + "typescript": "~6.0.3" + }, + "scripts": { + "start": "expo start", + "reset-project": "node ./scripts/reset-project.js", + "android": "expo run:android", + "ios": "expo run:ios", + "web": "expo start --web", + "lint": "expo lint" + }, + "private": true +} diff --git a/scripts/reset-project.js b/scripts/reset-project.js new file mode 100644 index 0000000..055d15b --- /dev/null +++ b/scripts/reset-project.js @@ -0,0 +1,114 @@ +#!/usr/bin/env node + +/** + * This script is used to reset the project to a blank state. + * It deletes or moves the /src and /scripts directories to /example based on user input and creates a new /src/app directory with an index.tsx and _layout.tsx file. + * You can remove the `reset-project` script from package.json and safely delete this file after running it. + */ + +const fs = require("fs"); +const path = require("path"); +const readline = require("readline"); + +const root = process.cwd(); +const oldDirs = ["src", "scripts"]; +const exampleDir = "example"; +const newAppDir = "src/app"; +const exampleDirPath = path.join(root, exampleDir); + +const indexContent = `import { Text, View, StyleSheet } from "react-native"; + +export default function Index() { + return ( + <View style={styles.container}> + <Text>Edit src/app/index.tsx to edit this screen.</Text> + </View> + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: "center", + justifyContent: "center", + }, +}); +`; + +const layoutContent = `import { Stack } from "expo-router"; + +export default function RootLayout() { + return <Stack />; +} +`; + +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, +}); + +const moveDirectories = async (userInput) => { + try { + if (userInput === "y") { + // Create the app-example directory + await fs.promises.mkdir(exampleDirPath, { recursive: true }); + console.log(`📁 /${exampleDir} directory created.`); + } + + // Move old directories to new app-example directory or delete them + for (const dir of oldDirs) { + const oldDirPath = path.join(root, dir); + if (fs.existsSync(oldDirPath)) { + if (userInput === "y") { + const newDirPath = path.join(root, exampleDir, dir); + await fs.promises.rename(oldDirPath, newDirPath); + console.log(`➡️ /${dir} moved to /${exampleDir}/${dir}.`); + } else { + await fs.promises.rm(oldDirPath, { recursive: true, force: true }); + console.log(`❌ /${dir} deleted.`); + } + } else { + console.log(`➡️ /${dir} does not exist, skipping.`); + } + } + + // Create new /src/app directory + const newAppDirPath = path.join(root, newAppDir); + await fs.promises.mkdir(newAppDirPath, { recursive: true }); + console.log("\n📁 New /src/app directory created."); + + // Create index.tsx + const indexPath = path.join(newAppDirPath, "index.tsx"); + await fs.promises.writeFile(indexPath, indexContent); + console.log("📄 src/app/index.tsx created."); + + // Create _layout.tsx + const layoutPath = path.join(newAppDirPath, "_layout.tsx"); + await fs.promises.writeFile(layoutPath, layoutContent); + console.log("📄 src/app/_layout.tsx created."); + + console.log("\n✅ Project reset complete. Next steps:"); + console.log( + `1. Run \`npx expo start\` to start a development server.\n2. Edit src/app/index.tsx to edit the main screen.\n3. Put all your application code in /src, only screens and layout files should be in /src/app.${ + userInput === "y" + ? `\n4. Delete the /${exampleDir} directory when you're done referencing it.` + : "" + }` + ); + } catch (error) { + console.error(`❌ Error during script execution: ${error.message}`); + } +}; + +rl.question( + "Do you want to move existing files to /example instead of deleting them? (Y/n): ", + (answer) => { + const userInput = answer.trim().toLowerCase() || "y"; + if (userInput === "y" || userInput === "n") { + moveDirectories(userInput).finally(() => rl.close()); + } else { + console.log("❌ Invalid input. Please enter 'Y' or 'N'."); + rl.close(); + } + } +); diff --git a/src/app/(app)/(tabs)/_layout.tsx b/src/app/(app)/(tabs)/_layout.tsx new file mode 100644 index 0000000..5033232 --- /dev/null +++ b/src/app/(app)/(tabs)/_layout.tsx @@ -0,0 +1,169 @@ +import React from 'react'; +import { Platform, StyleSheet, TouchableOpacity, View } from 'react-native'; +import { Tabs } from 'expo-router'; +import { BlurView } from 'expo-blur'; +import { Feather } from '@expo/vector-icons'; +import Animated, { + useAnimatedStyle, + withSpring, + withTiming, +} from 'react-native-reanimated'; +import * as Haptics from 'expo-haptics'; +import { Colors, Spacing } from '@/constants/theme'; + +function TabBarIcon({ + name, + isFocused, +}: { + name: keyof typeof Feather.glyphMap; + isFocused: boolean; +}) { + const animatedIconStyle = useAnimatedStyle(() => { + return { + transform: [ + { scale: withSpring(isFocused ? 1.15 : 1, { damping: 12, stiffness: 300 }) }, + ], + }; + }); + + const animatedIndicatorStyle = useAnimatedStyle(() => { + return { + opacity: withTiming(isFocused ? 1 : 0, { duration: 200 }), + transform: [ + { scale: withSpring(isFocused ? 1 : 0.5, { damping: 15, stiffness: 300 }) }, + ], + }; + }); + + return ( + <View style={styles.iconContainer}> + <Animated.View style={animatedIconStyle}> + <Feather + name={name} + size={22} + color={isFocused ? Colors.primaryLight : Colors.textMuted} + /> + </Animated.View> + <Animated.View style={[styles.indicator, animatedIndicatorStyle]} /> + </View> + ); +} + +function CustomTabBar({ state, descriptors, navigation }: any) { + return ( + <View style={styles.tabBarContainer}> + <BlurView + intensity={Platform.OS === 'ios' ? 80 : 100} + tint="dark" + style={styles.blurView} + > + {state.routes.map((route: any, index: number) => { + const { options } = descriptors[route.key]; + const isFocused = state.index === index; + + const onPress = () => { + const event = navigation.emit({ + type: 'tabPress', + target: route.key, + canPreventDefault: true, + }); + + if (!isFocused && !event.defaultPrevented) { + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); + navigation.navigate(route.name); + } + }; + + let iconName: keyof typeof Feather.glyphMap = 'home'; + if (route.name === 'index') iconName = 'pie-chart'; + else if (route.name === 'salary') iconName = 'dollar-sign'; + else if (route.name === 'recurring') iconName = 'repeat'; + else if (route.name === 'expenses') iconName = 'plus-square'; + + return ( + <TouchableOpacity + key={route.key} + accessibilityRole="button" + accessibilityState={isFocused ? { selected: true } : {}} + accessibilityLabel={options.tabBarAccessibilityLabel} + onPress={onPress} + style={styles.tabItem} + activeOpacity={1} + > + <TabBarIcon name={iconName} isFocused={isFocused} /> + </TouchableOpacity> + ); + })} + </BlurView> + </View> + ); +} + +export default function TabsLayout() { + return ( + <Tabs + tabBar={(props) => <CustomTabBar {...props} />} + screenOptions={{ + headerShown: false, + }} + > + <Tabs.Screen name="index" options={{ title: 'Dashboard' }} /> + <Tabs.Screen name="salary" options={{ title: 'Salário' }} /> + <Tabs.Screen name="recurring" options={{ title: 'Gastos Fixos' }} /> + <Tabs.Screen name="expenses" options={{ title: 'Gastos do Mês' }} /> + </Tabs> + ); +} + +const styles = StyleSheet.create({ + tabBarContainer: { + position: 'absolute', + bottom: Platform.OS === 'ios' ? 30 : 20, + left: 24, + right: 24, + borderRadius: 32, + ...Platform.select({ + ios: { + shadowColor: '#000', + shadowOffset: { width: 0, height: 8 }, + shadowOpacity: 0.5, + shadowRadius: 16, + }, + android: { + elevation: 10, + }, + }), + }, + blurView: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-around', + borderRadius: 32, + backgroundColor: 'rgba(22, 27, 34, 0.75)', + borderWidth: 1, + borderColor: 'rgba(255, 255, 255, 0.08)', + overflow: 'hidden', + height: 64, + paddingHorizontal: Spacing.sm, + }, + tabItem: { + flex: 1, + alignItems: 'center', + justifyContent: 'center', + height: '100%', + }, + iconContainer: { + alignItems: 'center', + justifyContent: 'center', + width: 44, + height: 44, + }, + indicator: { + position: 'absolute', + bottom: -2, + width: 4, + height: 4, + borderRadius: 2, + backgroundColor: Colors.primaryLight, + }, +}); diff --git a/src/app/(app)/(tabs)/expenses.tsx b/src/app/(app)/(tabs)/expenses.tsx new file mode 100644 index 0000000..c313dc6 --- /dev/null +++ b/src/app/(app)/(tabs)/expenses.tsx @@ -0,0 +1,2 @@ +import OneTimeExpensesScreen from '@/screens/one-time-expenses-screen'; +export default OneTimeExpensesScreen; diff --git a/src/app/(app)/(tabs)/index.tsx b/src/app/(app)/(tabs)/index.tsx new file mode 100644 index 0000000..73bede0 --- /dev/null +++ b/src/app/(app)/(tabs)/index.tsx @@ -0,0 +1,2 @@ +import DashboardScreen from '@/screens/dashboard-screen'; +export default DashboardScreen; diff --git a/src/app/(app)/(tabs)/recurring.tsx b/src/app/(app)/(tabs)/recurring.tsx new file mode 100644 index 0000000..c5340ed --- /dev/null +++ b/src/app/(app)/(tabs)/recurring.tsx @@ -0,0 +1,2 @@ +import RecurringExpensesScreen from '@/screens/recurring-expenses-screen'; +export default RecurringExpensesScreen; diff --git a/src/app/(app)/(tabs)/salary.tsx b/src/app/(app)/(tabs)/salary.tsx new file mode 100644 index 0000000..1d30bb1 --- /dev/null +++ b/src/app/(app)/(tabs)/salary.tsx @@ -0,0 +1,2 @@ +import SalaryScreen from '@/screens/salary-screen'; +export default SalaryScreen; diff --git a/src/app/(app)/_layout.tsx b/src/app/(app)/_layout.tsx new file mode 100644 index 0000000..6099274 --- /dev/null +++ b/src/app/(app)/_layout.tsx @@ -0,0 +1,21 @@ +import { Colors } from "@/constants/theme"; +import { useAuth } from "@/contexts/AuthContext"; +import { Redirect, Slot } from "expo-router"; +import { ActivityIndicator, View } from "react-native"; + +export default function AppLayout() { + const { user, isLoading } = useAuth(); + + if (isLoading) { + return ( + <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: Colors.background }}> + <ActivityIndicator size="large" color={Colors.primary} /> + </View> + ); + } + + if (!user) + return <Redirect href="/login" />; + + return <Slot />; +}
\ No newline at end of file diff --git a/src/app/_layout.tsx b/src/app/_layout.tsx new file mode 100644 index 0000000..fe9f265 --- /dev/null +++ b/src/app/_layout.tsx @@ -0,0 +1,54 @@ +import { SplashScreen, Stack } from 'expo-router'; +import { useState, useEffect } from 'react'; +import { StatusBar } from 'expo-status-bar'; +import { SafeAreaProvider } from 'react-native-safe-area-context'; +import { useAppFonts } from '@/hooks/use-app-hooks'; +import { AuthProvider, useAuth } from '@/contexts/AuthContext'; +import { Colors } from '@/constants/theme'; + +import { AnimatedSplashScreen } from '@/components/animated-splash-screen'; +import { View } from 'react-native'; + +SplashScreen.preventAutoHideAsync(); + +function RootContent() { + const { isLoading } = useAuth(); + const { fontsLoaded, fontsError } = useAppFonts(); + const [splashFinished, setSplashFinished] = useState(false); + + const isAppReady = !isLoading; + + useEffect(() => { + if (fontsLoaded || fontsError) { + SplashScreen.hideAsync(); + } + }, [fontsLoaded, fontsError]); + + if (!fontsLoaded && !fontsError) + return null; + + return ( + <View style={{ flex: 1, backgroundColor: Colors.background }}> + <Stack screenOptions={{ headerShown: false, contentStyle: { backgroundColor: Colors.background } }}> + <Stack.Screen name="(app)" /> + <Stack.Screen name="login" /> + <Stack.Screen name="register" /> + </Stack> + + {!splashFinished && ( + <AnimatedSplashScreen isAppReady={isAppReady} onAnimationComplete={() => setSplashFinished(true)} /> + )} + </View> + ) +} + +export default function RootLayout() { + return ( + <SafeAreaProvider> + <StatusBar style="light" /> + <AuthProvider> + <RootContent /> + </AuthProvider> + </SafeAreaProvider> + ) +} diff --git a/src/app/biometrics.tsx b/src/app/biometrics.tsx new file mode 100644 index 0000000..500adc9 --- /dev/null +++ b/src/app/biometrics.tsx @@ -0,0 +1,120 @@ +import React from 'react'; +import { View, Text, StyleSheet } from 'react-native'; +import { useRouter } from 'expo-router'; +import * as SecureStore from 'expo-secure-store'; +import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated'; +import { Feather } from '@expo/vector-icons'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; +import { Button } from '@/components/ui/button'; +import { Colors, Spacing, Typography, Radius } from '@/constants/theme'; +import { BlurView } from 'expo-blur'; + +export default function BiometricsScreen() { + const router = useRouter(); + const insets = useSafeAreaInsets(); + + async function handleAccept() { + await SecureStore.setItemAsync('yaba_use_biometrics', 'true'); + router.replace('/'); + } + + function handleDecline() { + router.replace('/'); + } + + return ( + <View style={[styles.container, { paddingTop: insets.top, paddingBottom: insets.bottom }]}> + + <View style={styles.content}> + <Animated.View entering={FadeInDown.duration(600).delay(100)} style={styles.iconContainer}> + <View style={styles.iconBackground}> + <Feather size={64} color={Colors.primary} /> + </View> + </Animated.View> + + <Animated.View entering={FadeInUp.duration(600).delay(200)} style={styles.textContainer}> + <Text style={styles.title}>Login por Biometria</Text> + <Text style={styles.subtitle}> + Deseja utilizar sua biometria (Face ID / Digital) para acessar o app mais rapidamente nas próximas vezes? + </Text> + </Animated.View> + </View> + + <Animated.View entering={FadeInUp.duration(600).delay(400)} style={styles.footer}> + <BlurView intensity={80} tint="dark" style={styles.blurContainer}> + <Button + label="Sim, usar biometria" + onPress={handleAccept} + fullWidth + style={styles.primaryButton} + /> + <Button + label="Não, manter acesso livre" + variant="ghost" + onPress={handleDecline} + fullWidth + /> + </BlurView> + </Animated.View> + </View> + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: Colors.background, + justifyContent: 'space-between', + }, + content: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + paddingHorizontal: Spacing.xl, + gap: Spacing.xxl, + }, + iconContainer: { + alignItems: 'center', + }, + iconBackground: { + width: 120, + height: 120, + borderRadius: 60, + backgroundColor: 'rgba(238, 250, 13, 0.1)', + alignItems: 'center', + justifyContent: 'center', + borderWidth: 1, + borderColor: 'rgba(238, 250, 13, 0.2)', + }, + textContainer: { + alignItems: 'center', + gap: Spacing.sm, + }, + title: { + ...Typography.h1, + color: Colors.textPrimary, + textAlign: 'center', + }, + subtitle: { + ...Typography.bodyLarge, + color: Colors.textSecondary, + textAlign: 'center', + lineHeight: 24, + }, + footer: { + paddingHorizontal: Spacing.lg, + paddingBottom: Spacing.lg, + }, + blurContainer: { + padding: Spacing.lg, + borderRadius: Radius.lg, + gap: Spacing.md, + backgroundColor: 'rgba(22, 27, 34, 0.6)', + borderWidth: 1, + borderColor: 'rgba(255, 255, 255, 0.08)', + overflow: 'hidden', + }, + primaryButton: { + height: 56, + } +}); diff --git a/src/app/login.tsx b/src/app/login.tsx new file mode 100644 index 0000000..15ec3be --- /dev/null +++ b/src/app/login.tsx @@ -0,0 +1,144 @@ +import { useAuth } from "@/contexts/AuthContext"; +import { Link, useRouter } from "expo-router"; +import { useState } from "react"; +import { + Alert, + KeyboardAvoidingView, + Platform, + StyleSheet, + Text, + View, +} from "react-native"; +import { useSafeAreaInsets } from "react-native-safe-area-context"; +import * as LocalAuthentication from "expo-local-authentication"; +import Animated, { FadeInDown, FadeInUp } from "react-native-reanimated"; +import { Colors, Spacing, Typography } from "@/constants/theme"; +import { Input } from "@/components/ui/input"; +import { Button } from "@/components/ui/button"; + +export default function LoginScreen() { + const insets = useSafeAreaInsets(); + const router = useRouter(); + const { login } = useAuth(); + + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const [isLoading, setIsLoading] = useState(false); + + async function handleLogin() { + if (!email || !password) { + Alert.alert("Erro", "Por favor, preencha todos os campos."); + return; + } + + try { + setIsLoading(true); + await login({ email: email.trim(), password }); + + const hasHardware = await LocalAuthentication.hasHardwareAsync(); + const isEnrolled = await LocalAuthentication.isEnrolledAsync(); + + if (hasHardware && isEnrolled) { + router.replace("/biometrics"); + } else { + router.replace("/"); + } + } catch (error) { + Alert.alert("Erro", "Falha ao fazer login. Verifique suas credenciais e tente novamente."); + } finally { + setIsLoading(false); + } + } + + return ( + <KeyboardAvoidingView style={styles.container} behavior={Platform.OS === "ios" ? "padding" : undefined}> + <View style={[styles.content, { paddingTop: insets.top + Spacing.xxl }]}> + <Animated.View entering={FadeInUp.duration(600)} style={styles.header}> + <Text style={styles.title}>YABA</Text> + <Text style={styles.subtitle}>O seu dinheiro, no seu controle.</Text> + </Animated.View> + + <Animated.View entering={FadeInDown.delay(200).duration(600)} style={styles.form}> + <Input + id="login-email" + label="E-mail" + placeholder="seu@email.com" + value={email} + onChangeText={setEmail} + keyboardType="email-address" + autoCapitalize="none" + /> + <Input + id="login-password" + label="Senha" + placeholder="********" + value={password} + onChangeText={setPassword} + secureTextEntry + /> + + <Button + id="login-button" + label="Entrar" + fullWidth + onPress={handleLogin} + loading={isLoading} + disabled={isLoading} + /> + + <View style={styles.footer}> + <Text style={styles.footerText}>Não tem uma conta? </Text> + <Link href="/register" asChild> + <Text style={styles.linkText}>Cadastre-se</Text> + </Link> + </View> + </Animated.View> + </View> + </KeyboardAvoidingView> + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: Colors.background, + }, + content: { + flex: 1, + padding: Spacing.xl, + justifyContent: "center", + }, + header: { + alignItems: "center", + marginBottom: Spacing.xl, + }, + title: { + ...Typography.h1, + fontSize: 48, + color: Colors.primaryLight, + letterSpacing: 2, + fontFamily: "DMSans_700Bold", + }, + subtitle: { + ...Typography.body, + color: Colors.textSecondary, + marginTop: Spacing.xs, + }, + form: { + gap: Spacing.lg, + }, + footer: { + flexDirection: "row", + justifyContent: "center", + marginTop: Spacing.xl, + }, + footerText: { + ...Typography.body, + color: Colors.textSecondary, + }, + linkText: { + ...Typography.body, + color: Colors.primaryLight, + fontFamily: "DMSans_700Bold", + }, +});
\ No newline at end of file diff --git a/src/app/register.tsx b/src/app/register.tsx new file mode 100644 index 0000000..aac588d --- /dev/null +++ b/src/app/register.tsx @@ -0,0 +1,142 @@ +import React, { useState } from 'react'; +import { View, StyleSheet, Text, KeyboardAvoidingView, Platform, Alert, ScrollView } from 'react-native'; +import { Link, useRouter } from 'expo-router'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; +import Animated, { FadeInDown, FadeInUp } from 'react-native-reanimated'; +import * as LocalAuthentication from 'expo-local-authentication'; +import * as SecureStore from 'expo-secure-store'; +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { Colors, Spacing, Typography } from '@/constants/theme'; +import { useAuth } from '@/contexts/AuthContext'; + +export default function RegisterScreen() { + const insets = useSafeAreaInsets(); + const router = useRouter(); + const { register } = useAuth(); + + const [name, setName] = useState(''); + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); + const [isLoading, setIsLoading] = useState(false); + + async function handleRegister() { + if (!name || !email || !password) { + Alert.alert('Erro', 'Preencha todos os campos.'); + return; + } + try { + setIsLoading(true); + await register({ name: name.trim(), email: email.trim(), password }); + + const hasHardware = await LocalAuthentication.hasHardwareAsync(); + const isEnrolled = await LocalAuthentication.isEnrolledAsync(); + + if (hasHardware && isEnrolled) { + router.replace('/biometrics'); + } else { + router.replace('/'); + } + } catch (err: any) { + Alert.alert('Erro no cadastro', 'Verifique seus dados.'); + setIsLoading(false); + } + } + + return ( + <KeyboardAvoidingView style={styles.container} behavior={Platform.OS === 'ios' ? 'padding' : undefined}> + <ScrollView contentContainerStyle={[styles.content, { paddingTop: insets.top + Spacing.xl }]}> + <Animated.View entering={FadeInUp.duration(600)} style={styles.header}> + <Text style={styles.title}>Criar Conta</Text> + <Text style={styles.subtitle}>Junte-se ao YABA e organize sua vida financeira.</Text> + </Animated.View> + + <Animated.View entering={FadeInDown.delay(200).duration(600)} style={styles.form}> + <Input + id="register-name" + label="Nome" + placeholder="Como quer ser chamado?" + value={name} + onChangeText={setName} + /> + <Input + id="register-email" + label="E-mail" + placeholder="seu@email.com" + value={email} + onChangeText={setEmail} + keyboardType="email-address" + autoCapitalize="none" + /> + <Input + id="register-password" + label="Senha" + placeholder="No mínimo 6 caracteres" + value={password} + onChangeText={setPassword} + secureTextEntry + /> + + <Button + id="register-button" + label="Cadastrar" + fullWidth + onPress={handleRegister} + loading={isLoading} + disabled={isLoading} + /> + + <View style={styles.footer}> + <Text style={styles.footerText}>Já tem uma conta? </Text> + <Link href="/login" asChild> + <Text style={styles.linkText}>Faça login</Text> + </Link> + </View> + </Animated.View> + </ScrollView> + </KeyboardAvoidingView> + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: Colors.background, + }, + content: { + flexGrow: 1, + padding: Spacing.xl, + justifyContent: 'center', + }, + header: { + alignItems: 'center', + marginBottom: Spacing.xl, + }, + title: { + ...Typography.h1, + color: Colors.textPrimary, + }, + subtitle: { + ...Typography.body, + color: Colors.textSecondary, + marginTop: Spacing.xs, + textAlign: 'center', + }, + form: { + gap: Spacing.lg, + }, + footer: { + flexDirection: 'row', + justifyContent: 'center', + marginTop: Spacing.xl, + }, + footerText: { + ...Typography.body, + color: Colors.textSecondary, + }, + linkText: { + ...Typography.body, + color: Colors.primaryLight, + fontFamily: 'DMSans_700Bold', + }, +}); diff --git a/src/components/animated-splash-screen.tsx b/src/components/animated-splash-screen.tsx new file mode 100644 index 0000000..7ecfdef --- /dev/null +++ b/src/components/animated-splash-screen.tsx @@ -0,0 +1,103 @@ +import React, { useEffect } from 'react'; +import { StyleSheet, View, Text } from 'react-native'; +import Animated, { + useAnimatedStyle, + useSharedValue, + withTiming, + withSpring, + Easing, + runOnJS, + withDelay, +} from 'react-native-reanimated'; +import { Colors } from '@/constants/theme'; +import { LinearGradient } from 'expo-linear-gradient'; + +interface Props { + isAppReady: boolean; + onAnimationComplete: () => void; +} + +export function AnimatedSplashScreen({ isAppReady, onAnimationComplete }: Props) { + const opacity = useSharedValue(1); + const scale = useSharedValue(1); + const textOpacity = useSharedValue(0); + const textTranslateY = useSharedValue(20); + const logoScale = useSharedValue(0.8); + + useEffect(() => { + textOpacity.value = withTiming(1, { duration: 1000 }); + textTranslateY.value = withSpring(0, { damping: 14, stiffness: 100 }); + logoScale.value = withSpring(1, { damping: 10, stiffness: 100 }); + }, []); + + useEffect(() => { + if (isAppReady) { + opacity.value = withDelay( + 600, + withTiming(0, { duration: 700, easing: Easing.inOut(Easing.ease) }, (finished) => { + if (finished) { + runOnJS(onAnimationComplete)(); + } + }) + ); + + scale.value = withDelay( + 600, + withTiming(1.3, { duration: 700, easing: Easing.inOut(Easing.ease) }) + ); + } + }, [isAppReady]); + + const animatedContainerStyle = useAnimatedStyle(() => ({ + opacity: opacity.value, + transform: [{ scale: scale.value }], + })); + + const animatedTextStyle = useAnimatedStyle(() => ({ + opacity: textOpacity.value, + transform: [ + { translateY: textTranslateY.value }, + { scale: logoScale.value } + ], + })); + + return ( + <Animated.View style={[styles.container, animatedContainerStyle]}> + <LinearGradient + colors={['#0D2818', Colors.background]} + style={StyleSheet.absoluteFill} + start={{ x: 0, y: 0 }} + end={{ x: 0, y: 1 }} + /> + <Animated.View style={animatedTextStyle}> + <Text style={styles.logoText}>YABA</Text> + <Text style={styles.subText}>Finanças Pessoais</Text> + </Animated.View> + </Animated.View> + ); +} + +const styles = StyleSheet.create({ + container: { + ...StyleSheet.absoluteFill, + justifyContent: 'center', + alignItems: 'center', + zIndex: 9999, + }, + logoText: { + fontFamily: 'Outfit_700Bold', + fontSize: 72, + color: Colors.white, + letterSpacing: -2, + textAlign: 'center', + }, + subText: { + fontFamily: 'DMSans_500Medium', + fontSize: 16, + color: Colors.primaryLight, + letterSpacing: 2, + textTransform: 'uppercase', + textAlign: 'center', + marginTop: 8, + } +}); diff --git a/src/components/expense-row.tsx b/src/components/expense-row.tsx new file mode 100644 index 0000000..0f58c78 --- /dev/null +++ b/src/components/expense-row.tsx @@ -0,0 +1,213 @@ +import React from 'react'; +import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'; +import Animated, { FadeInDown, LinearTransition } from 'react-native-reanimated'; +import { Colors, Radius, Spacing, Typography } from '@/constants/theme'; +import type { OneTimeExpense, RecurringExpense } from '@/types'; + +const CATEGORY_EMOJI: Record<string, string> = { + moradia: '🏠', + alimentação: '🍽️', + transporte: '🚗', + saúde: '💊', + educação: '📚', + lazer: '🎬', + serviços: '⚙️', + outros: '📦', +}; + +interface ExpenseRowProps { + name: string; + amount: number; + category: string; + subtitle?: string; + index?: number; + onPress?: () => void; + rightElement?: React.ReactNode; + type?: 'expense' | 'income'; +} + +export function ExpenseRow({ + name, + amount, + category, + subtitle, + index = 0, + onPress, + rightElement, + type = 'expense', +}: ExpenseRowProps) { + const emoji = CATEGORY_EMOJI[category] ?? '📦'; + const prefix = type === 'income' ? '+ ' : '- '; + const amountColor = type === 'income' ? Colors.positive : Colors.negative; + + const formattedAmount = amount.toLocaleString('pt-BR', { + style: 'currency', + currency: 'BRL', + minimumFractionDigits: 2, + }); + + return ( + <Animated.View + entering={FadeInDown.delay(index * 60).springify()} + layout={LinearTransition.springify()} + > + <TouchableOpacity + style={styles.row} + onPress={onPress} + activeOpacity={0.7} + disabled={!onPress} + accessibilityRole="button" + accessibilityLabel={`${name}, ${formattedAmount}`} + > + <View style={styles.iconBox}> + <Text style={styles.emoji}>{emoji}</Text> + </View> + + <View style={styles.info}> + <Text style={styles.name} numberOfLines={1}> + {name} + </Text> + {subtitle ? ( + <Text style={styles.subtitle} numberOfLines={1}> + {subtitle} + </Text> + ) : null} + </View> + + <View style={styles.right}> + <Text style={[styles.amount, { color: amountColor }]}> + {prefix}{formattedAmount} + </Text> + {rightElement} + </View> + </TouchableOpacity> + </Animated.View> + ); +} + +interface RecurringExpenseRowProps { + expense: RecurringExpense; + index?: number; + onToggle: () => void; + onPress: () => void; +} + +export function RecurringExpenseRow({ + expense, + index = 0, + onToggle, + onPress, +}: RecurringExpenseRowProps) { + return ( + <ExpenseRow + name={expense.name} + amount={expense.amount} + category={expense.category} + type={expense.type} + subtitle={expense.due_day ? `Vence dia ${expense.due_day}` : undefined} + index={index} + onPress={onPress} + rightElement={ + <TouchableOpacity + style={[ + styles.toggleBadge, + expense.is_active ? styles.toggleActive : styles.toggleInactive, + ]} + onPress={onToggle} + hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }} + accessibilityLabel={expense.is_active ? 'Desativar gasto' : 'Ativar gasto'} + accessibilityRole="switch" + > + <Text style={styles.toggleText}> + {expense.is_active ? 'Ativo' : 'Pausado'} + </Text> + </TouchableOpacity> + } + /> + ); +} + +interface OneTimeExpenseRowProps { + expense: OneTimeExpense; + index?: number; + onPress: () => void; +} + +export function OneTimeExpenseRow({ + expense, + index = 0, + onPress, +}: OneTimeExpenseRowProps) { + const date = new Date(expense.expense_date + 'T12:00:00'); + const formattedDate = date.toLocaleDateString('pt-BR', { + day: '2-digit', + month: 'short', + }); + + return ( + <ExpenseRow + name={expense.name} + amount={expense.amount} + category={expense.category} + subtitle={formattedDate} + index={index} + onPress={onPress} + type={expense.type} + /> + ); +} + +const styles = StyleSheet.create({ + row: { + flexDirection: 'row', + alignItems: 'center', + paddingVertical: Spacing.md, + gap: Spacing.md, + }, + iconBox: { + width: 44, + height: 44, + borderRadius: Radius.md, + backgroundColor: Colors.surfaceElevated, + alignItems: 'center', + justifyContent: 'center', + }, + emoji: { + fontSize: 22, + }, + info: { + flex: 1, + gap: 2, + }, + name: { + ...Typography.bodyLarge, + color: Colors.textPrimary, + }, + subtitle: { + ...Typography.caption, + color: Colors.textSecondary, + }, + right: { + alignItems: 'flex-end', + gap: Spacing.xs, + }, + amount: { + ...Typography.bodyLarge, + fontFamily: 'DMSans_600SemiBold', + }, + toggleBadge: { + paddingHorizontal: Spacing.sm, + paddingVertical: 2, + borderRadius: Radius.full, + }, + toggleActive: { + backgroundColor: `${Colors.positive}22`, + }, + toggleInactive: { + backgroundColor: `${Colors.textMuted}22`, + }, + toggleText: { + ...Typography.caption, + color: Colors.textSecondary, + }, +}); diff --git a/src/components/ui/action-modal.tsx b/src/components/ui/action-modal.tsx new file mode 100644 index 0000000..a1d95be --- /dev/null +++ b/src/components/ui/action-modal.tsx @@ -0,0 +1,107 @@ +import React from 'react'; +import { Modal, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; +import { BlurView } from 'expo-blur'; +import Animated, { FadeIn, FadeInDown, FadeOut, FadeOutDown } from 'react-native-reanimated'; +import { Colors, Radius, Spacing, Typography } from '@/constants/theme'; +import { Button } from './button'; + +interface ActionModalProps { + visible: boolean; + title: string; + message: string; + confirmText?: string; + cancelText?: string; + onConfirm: () => void; + onCancel: () => void; + isDestructive?: boolean; +} + +export function ActionModal({ + visible, + title, + message, + confirmText = 'Confirmar', + cancelText = 'Cancelar', + onConfirm, + onCancel, + isDestructive = false, +}: ActionModalProps) { + if (!visible) return null; + + return ( + <Modal visible={visible} transparent animationType="none" onRequestClose={onCancel}> + <Animated.View entering={FadeIn.duration(200)} exiting={FadeOut.duration(200)} style={styles.overlay}> + <TouchableOpacity style={styles.backdrop} activeOpacity={1} onPress={onCancel} /> + + <Animated.View entering={FadeInDown.duration(300).springify()} exiting={FadeOutDown.duration(200)} style={styles.modalContainer}> + <BlurView intensity={80} tint="dark" style={styles.blurView}> + <View style={styles.content}> + <Text style={styles.title}>{title}</Text> + <Text style={styles.message}>{message}</Text> + + <View style={styles.actions}> + <Button + label={cancelText} + variant="ghost" + onPress={onCancel} + style={styles.actionButton} + /> + <Button + label={confirmText} + variant={isDestructive ? 'danger' : 'primary'} + onPress={onConfirm} + style={styles.actionButton} + /> + </View> + </View> + </BlurView> + </Animated.View> + </Animated.View> + </Modal> + ); +} + +const styles = StyleSheet.create({ + overlay: { + flex: 1, + justifyContent: 'flex-end', + backgroundColor: 'rgba(0, 0, 0, 0.4)', + }, + backdrop: { + ...StyleSheet.absoluteFill, + }, + modalContainer: { + padding: Spacing.md, + paddingBottom: Spacing.xxl, + }, + blurView: { + borderRadius: Radius.lg, + overflow: 'hidden', + borderWidth: 1, + borderColor: 'rgba(255, 255, 255, 0.08)', + }, + content: { + padding: Spacing.xl, + gap: Spacing.md, + backgroundColor: 'rgba(22, 27, 34, 0.6)', + }, + title: { + ...Typography.h2, + color: Colors.textPrimary, + textAlign: 'center', + }, + message: { + ...Typography.body, + color: Colors.textSecondary, + textAlign: 'center', + lineHeight: 22, + }, + actions: { + flexDirection: 'row', + gap: Spacing.sm, + marginTop: Spacing.md, + }, + actionButton: { + flex: 1, + }, +}); diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx new file mode 100644 index 0000000..3486ff7 --- /dev/null +++ b/src/components/ui/button.tsx @@ -0,0 +1,141 @@ +import React from 'react'; +import { + ActivityIndicator, + StyleSheet, + Text, + TouchableOpacity, + type TouchableOpacityProps, + View, +} from 'react-native'; +import Animated, { + useAnimatedStyle, + useSharedValue, + withSpring, +} from 'react-native-reanimated'; +import { Colors, Radius, Spacing, Typography } from '@/constants/theme'; + +const AnimatedTouchable = Animated.createAnimatedComponent(TouchableOpacity); + +interface ButtonProps extends TouchableOpacityProps { + label: string; + variant?: 'primary' | 'secondary' | 'ghost' | 'danger'; + loading?: boolean; + fullWidth?: boolean; +} + +export function Button({ + label, + variant = 'primary', + loading = false, + fullWidth = false, + onPress, + disabled, + style, + ...rest +}: ButtonProps) { + const scale = useSharedValue(1); + + const animatedStyle = useAnimatedStyle(() => ({ + transform: [{ scale: scale.value }], + })); + + function handlePressIn() { + scale.value = withSpring(0.96, { damping: 15, stiffness: 400 }); + } + + function handlePressOut() { + scale.value = withSpring(1, { damping: 15, stiffness: 400 }); + } + + const containerStyle = [ + styles.base, + styles[variant], + fullWidth && styles.fullWidth, + (disabled || loading) && styles.disabled, + style, + ]; + + const textColor = + variant === 'secondary' || variant === 'ghost' + ? Colors.textPrimary + : Colors.white; + + return ( + <AnimatedTouchable + style={[animatedStyle, containerStyle]} + onPress={onPress} + onPressIn={handlePressIn} + onPressOut={handlePressOut} + disabled={disabled || loading} + activeOpacity={1} + {...rest} + > + {loading ? ( + <ActivityIndicator color={textColor} size="small" /> + ) : ( + <Text style={[styles.label, { color: textColor }]}>{label}</Text> + )} + </AnimatedTouchable> + ); +} + +interface IconButtonProps { + onPress: () => void; + children: React.ReactNode; + accessibilityLabel: string; +} + +export function IconButton({ onPress, children, accessibilityLabel }: IconButtonProps) { + return ( + <TouchableOpacity + style={styles.iconButton} + onPress={onPress} + hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }} + accessibilityLabel={accessibilityLabel} + accessibilityRole="button" + > + <View>{children}</View> + </TouchableOpacity> + ); +} + +const styles = StyleSheet.create({ + base: { + height: 52, + borderRadius: Radius.md, + alignItems: 'center', + justifyContent: 'center', + paddingHorizontal: Spacing.lg, + minWidth: 44, // touch target mínimo + }, + primary: { + backgroundColor: Colors.primary, + }, + secondary: { + backgroundColor: Colors.surfaceElevated, + borderWidth: 1, + borderColor: Colors.border, + }, + ghost: { + backgroundColor: Colors.transparent, + }, + danger: { + backgroundColor: Colors.negative, + }, + fullWidth: { + width: '100%', + }, + disabled: { + opacity: 0.5, + }, + label: { + ...Typography.bodyLarge, + fontFamily: 'DMSans_600SemiBold', + }, + iconButton: { + width: 44, + height: 44, + alignItems: 'center', + justifyContent: 'center', + }, +}); diff --git a/src/components/ui/expenses-chart.tsx b/src/components/ui/expenses-chart.tsx new file mode 100644 index 0000000..efd5dee --- /dev/null +++ b/src/components/ui/expenses-chart.tsx @@ -0,0 +1,187 @@ +import React from 'react'; +import { StyleSheet, Text, View } from 'react-native'; +import { PieChart } from 'react-native-gifted-charts'; +import { Colors, Radius, Spacing, Typography } from '@/constants/theme'; +import type { DashboardExpenseItem } from '@/types'; +import { Card, SectionLabel } from './primitives'; + +interface ExpensesChartProps { + recurring: DashboardExpenseItem[]; + oneTime: DashboardExpenseItem[]; +} + +const CATEGORY_COLORS: Record<string, string> = { + moradia: '#4C6EF5', + alimentação: '#FA5252', + transporte: '#FAB005', + saúde: '#12B886', + educação: '#BE4BDB', + lazer: '#FF922B', + serviços: '#228BE6', + outros: '#868E96', +}; + +const CATEGORY_LABELS: Record<string, string> = { + moradia: 'Moradia', + alimentação: 'Alimentação', + transporte: 'Transporte', + saúde: 'Saúde', + educação: 'Educação', + lazer: 'Lazer', + serviços: 'Serviços', + outros: 'Outros', +}; + +export function ExpensesChart({ recurring, oneTime }: ExpensesChartProps) { + const categoryTotals: Record<string, number> = {}; + + const allExpenses = [ + ...recurring.filter(e => e.is_active && e.type === 'expense'), + ...oneTime.filter(e => e.type === 'expense') + ]; + + if (allExpenses.length === 0) { + return ( + <Card style={styles.card}> + <SectionLabel text="Análise de Gastos" /> + <View style={styles.emptyContainer}> + <Text style={styles.emptyText}>Não há despesas para analisar neste mês.</Text> + </View> + </Card> + ); + } + + let totalExpenses = 0; + allExpenses.forEach(e => { + if (!categoryTotals[e.category]) { + categoryTotals[e.category] = 0; + } + categoryTotals[e.category] += e.amount; + totalExpenses += e.amount; + }); + + const pieData = Object.keys(categoryTotals) + .map(category => ({ + value: categoryTotals[category], + color: CATEGORY_COLORS[category] || CATEGORY_COLORS.outros, + label: CATEGORY_LABELS[category] || 'Outros', + percentage: ((categoryTotals[category] / totalExpenses) * 100).toFixed(0) + '%', + })) + .sort((a, b) => b.value - a.value); + + return ( + <Card style={styles.card}> + <SectionLabel text="Análise de Gastos" /> + + <View style={styles.chartRow}> + <View style={styles.chartWrapper}> + <PieChart + data={pieData} + donut + radius={70} + innerRadius={50} + innerCircleColor={Colors.surface} + centerLabelComponent={() => { + return ( + <View style={styles.centerLabel}> + <Text style={styles.centerLabelValue}> + {totalExpenses.toLocaleString('pt-BR', { + style: 'currency', + currency: 'BRL', + minimumFractionDigits: 0, + maximumFractionDigits: 0, + })} + </Text> + <Text style={styles.centerLabelText}>Total</Text> + </View> + ); + }} + /> + </View> + + <View style={styles.legendContainer}> + {pieData.map((item, index) => ( + <View key={index} style={styles.legendItem}> + <View style={[styles.legendDot, { backgroundColor: item.color }]} /> + <View style={styles.legendTextWrapper}> + <Text style={styles.legendLabel} numberOfLines={1}>{item.label}</Text> + <Text style={styles.legendValue}> + {item.value.toLocaleString('pt-BR', { + style: 'currency', + currency: 'BRL', + })} ({item.percentage}) + </Text> + </View> + </View> + ))} + </View> + </View> + </Card> + ); +} + +const styles = StyleSheet.create({ + card: { + gap: Spacing.md, + }, + emptyContainer: { + paddingVertical: Spacing.xl, + alignItems: 'center', + justifyContent: 'center', + }, + emptyText: { + ...Typography.body, + color: Colors.textMuted, + }, + chartRow: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + }, + chartWrapper: { + alignItems: 'center', + justifyContent: 'center', + }, + centerLabel: { + alignItems: 'center', + justifyContent: 'center', + }, + centerLabelValue: { + ...Typography.body, + fontFamily: 'DMSans_700Bold', + color: Colors.textPrimary, + fontSize: 14, + }, + centerLabelText: { + ...Typography.caption, + color: Colors.textSecondary, + fontSize: 10, + }, + legendContainer: { + flex: 1, + marginLeft: Spacing.lg, + gap: Spacing.sm, + }, + legendItem: { + flexDirection: 'row', + alignItems: 'center', + }, + legendDot: { + width: 10, + height: 10, + borderRadius: 5, + marginRight: Spacing.xs, + }, + legendTextWrapper: { + flex: 1, + }, + legendLabel: { + ...Typography.caption, + color: Colors.textSecondary, + }, + legendValue: { + ...Typography.caption, + color: Colors.textPrimary, + fontFamily: 'DMSans_600SemiBold', + }, +}); diff --git a/src/components/ui/input.tsx b/src/components/ui/input.tsx new file mode 100644 index 0000000..25728df --- /dev/null +++ b/src/components/ui/input.tsx @@ -0,0 +1,98 @@ +import React, { forwardRef, useState } from 'react'; +import { + StyleSheet, + Text, + TextInput, + type TextInputProps, + View, +} from 'react-native'; +import { Colors, Radius, Spacing, Typography } from '@/constants/theme'; + +interface InputProps extends TextInputProps { + label: string; + error?: string; + hint?: string; + prefix?: string; +} + +export const Input = forwardRef<TextInput, InputProps>(function Input( + { label, error, hint, prefix, style, ...rest }, + ref, +) { + const [focused, setFocused] = useState(false); + + return ( + <View style={styles.wrapper}> + <Text style={styles.label}>{label}</Text> + <View + style={[ + styles.inputRow, + focused && styles.inputRowFocused, + !!error && styles.inputRowError, + ]} + > + {prefix ? <Text style={styles.prefix}>{prefix}</Text> : null} + <TextInput + ref={ref} + style={[styles.input, style]} + placeholderTextColor={Colors.textMuted} + onFocus={() => setFocused(true)} + onBlur={() => setFocused(false)} + selectionColor={Colors.primaryLight} + {...rest} + /> + </View> + {error ? ( + <Text style={styles.error}>{error}</Text> + ) : hint ? ( + <Text style={styles.hint}>{hint}</Text> + ) : null} + </View> + ); +}); + +const styles = StyleSheet.create({ + wrapper: { + gap: Spacing.xs, + }, + label: { + ...Typography.caption, + color: Colors.textSecondary, + textTransform: 'uppercase', + letterSpacing: 1, + }, + inputRow: { + flexDirection: 'row', + alignItems: 'center', + backgroundColor: Colors.surfaceElevated, + borderRadius: Radius.md, + borderWidth: 1, + borderColor: Colors.border, + paddingHorizontal: Spacing.md, + height: 52, + }, + inputRowFocused: { + borderColor: Colors.primaryLight, + }, + inputRowError: { + borderColor: Colors.negative, + }, + prefix: { + ...Typography.bodyLarge, + color: Colors.textSecondary, + marginRight: Spacing.sm, + }, + input: { + flex: 1, + ...Typography.bodyLarge, + color: Colors.textPrimary, + }, + error: { + ...Typography.caption, + color: Colors.negative, + }, + hint: { + ...Typography.caption, + color: Colors.textMuted, + }, +}); diff --git a/src/components/ui/options-modal.tsx b/src/components/ui/options-modal.tsx new file mode 100644 index 0000000..8d5d984 --- /dev/null +++ b/src/components/ui/options-modal.tsx @@ -0,0 +1,137 @@ +import React from 'react'; +import { Modal, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; +import { BlurView } from 'expo-blur'; +import Animated, { FadeIn, FadeInDown, FadeOut, FadeOutDown } from 'react-native-reanimated'; +import { Feather } from '@expo/vector-icons'; +import { Colors, Radius, Spacing, Typography } from '@/constants/theme'; + +export interface MenuOption { + label: string; + icon?: keyof typeof Feather.glyphMap; + destructive?: boolean; + onPress: () => void; +} + +interface OptionsModalProps { + visible: boolean; + title?: string; + options: MenuOption[]; + onClose: () => void; +} + +export function OptionsModal({ visible, title, options, onClose }: OptionsModalProps) { + if (!visible) return null; + + return ( + <Modal visible={visible} transparent animationType="none" onRequestClose={onClose}> + <Animated.View entering={FadeIn.duration(200)} exiting={FadeOut.duration(200)} style={styles.overlay}> + <TouchableOpacity style={styles.backdrop} activeOpacity={1} onPress={onClose} /> + + <Animated.View entering={FadeInDown.duration(300).springify()} exiting={FadeOutDown.duration(200)} style={styles.modalContainer}> + <BlurView intensity={80} tint="dark" style={styles.blurView}> + <View style={styles.content}> + {title && <Text style={styles.title}>{title}</Text>} + + <View style={styles.optionsList}> + {options.map((option, index) => ( + <TouchableOpacity + key={index} + style={[styles.optionButton, index < options.length - 1 && styles.optionBorder]} + onPress={() => { + onClose(); + setTimeout(option.onPress, 50); + }} + > + {option.icon && ( + <Feather + name={option.icon} + size={20} + color={option.destructive ? Colors.negative : Colors.textPrimary} + style={styles.optionIcon} + /> + )} + <Text style={[styles.optionText, option.destructive && styles.optionTextDestructive]}> + {option.label} + </Text> + </TouchableOpacity> + ))} + </View> + + <TouchableOpacity style={styles.cancelButton} onPress={onClose}> + <Text style={styles.cancelText}>Cancelar</Text> + </TouchableOpacity> + </View> + </BlurView> + </Animated.View> + </Animated.View> + </Modal> + ); +} + +const styles = StyleSheet.create({ + overlay: { + flex: 1, + justifyContent: 'flex-end', + backgroundColor: 'rgba(0, 0, 0, 0.4)', + }, + backdrop: { + ...StyleSheet.absoluteFill, + }, + modalContainer: { + padding: Spacing.md, + paddingBottom: Spacing.xxl, + }, + blurView: { + borderRadius: Radius.lg, + overflow: 'hidden', + borderWidth: 1, + borderColor: 'rgba(255, 255, 255, 0.08)', + }, + content: { + padding: Spacing.md, + gap: Spacing.md, + backgroundColor: 'rgba(22, 27, 34, 0.6)', + }, + title: { + ...Typography.body, + color: Colors.textSecondary, + textAlign: 'center', + marginBottom: Spacing.xs, + }, + optionsList: { + backgroundColor: 'rgba(255,255,255,0.05)', + borderRadius: Radius.md, + overflow: 'hidden', + }, + optionButton: { + flexDirection: 'row', + alignItems: 'center', + padding: Spacing.md, + backgroundColor: 'transparent', + }, + optionBorder: { + borderBottomWidth: 1, + borderBottomColor: 'rgba(255,255,255,0.05)', + }, + optionIcon: { + marginRight: Spacing.sm, + }, + optionText: { + ...Typography.bodyLarge, + color: Colors.textPrimary, + }, + optionTextDestructive: { + color: Colors.negative, + }, + cancelButton: { + padding: Spacing.md, + backgroundColor: 'rgba(255,255,255,0.1)', + borderRadius: Radius.md, + alignItems: 'center', + }, + cancelText: { + ...Typography.bodyLarge, + color: Colors.textPrimary, + fontFamily: 'DMSans_600SemiBold', + }, +}); diff --git a/src/components/ui/primitives.tsx b/src/components/ui/primitives.tsx new file mode 100644 index 0000000..d598bd2 --- /dev/null +++ b/src/components/ui/primitives.tsx @@ -0,0 +1,104 @@ +import React from 'react'; +import { StyleSheet, Text, View } from 'react-native'; +import { Colors, Radius, Shadow, Spacing, Typography } from '@/constants/theme'; + +interface CardProps { + children: React.ReactNode; + style?: object; +} + +export function Card({ children, style }: CardProps) { + return <View style={[styles.card, style]}>{children}</View>; +} + +interface LabelProps { + text: string; + color?: string; +} + +export function SectionLabel({ text, color = Colors.textSecondary }: LabelProps) { + return <Text style={[styles.label, { color }]}>{text}</Text>; +} + +interface CurrencyDisplayProps { + amount: number; + size?: 'display' | 'large' | 'normal'; + showSign?: boolean; +} + +export function CurrencyDisplay({ + amount, + size = 'normal', + showSign = false, +}: CurrencyDisplayProps) { + const isNegative = amount < 0; + const color = isNegative ? Colors.negative : Colors.positive; + const formatted = Math.abs(amount).toLocaleString('pt-BR', { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + }); + const sign = showSign ? (isNegative ? '- ' : '+ ') : ''; + + const textStyle = + size === 'display' + ? styles.displayAmount + : size === 'large' + ? styles.largeAmount + : styles.normalAmount; + + return ( + <View style={styles.currencyRow}> + <Text style={[styles.currencyPrefix, { color }]}> + {sign}R${' '} + </Text> + <Text style={[textStyle, { color }]}>{formatted}</Text> + </View> + ); +} + +interface DividerProps { + style?: object; +} + +export function Divider({ style }: DividerProps) { + return <View style={[styles.divider, style]} />; +} + +const styles = StyleSheet.create({ + card: { + backgroundColor: Colors.surface, + borderRadius: Radius.lg, + padding: Spacing.lg, + borderWidth: 1, + borderColor: Colors.border, + ...Shadow.card, + }, + label: { + ...Typography.caption, + textTransform: 'uppercase', + letterSpacing: 1.2, + }, + currencyRow: { + flexDirection: 'row', + alignItems: 'flex-end', + }, + currencyPrefix: { + ...Typography.currencyLabel, + paddingBottom: 4, + }, + displayAmount: { + ...Typography.display, + }, + largeAmount: { + ...Typography.h1, + }, + normalAmount: { + ...Typography.bodyLarge, + fontFamily: 'DMSans_600SemiBold', + }, + divider: { + height: 1, + backgroundColor: Colors.border, + marginVertical: Spacing.md, + }, +}); diff --git a/src/constants/theme.ts b/src/constants/theme.ts new file mode 100644 index 0000000..880e3d8 --- /dev/null +++ b/src/constants/theme.ts @@ -0,0 +1,99 @@ +export const Colors = { + background: '#0D1117', + surface: '#161B22', + surfaceElevated: '#1C2333', + border: '#2A3444', + + primary: '#1A6B3C', + primaryLight: '#24A55A', + accent: '#C9A84C', + + positive: '#24A55A', + negative: '#E05252', + warning: '#E0A84C', + + textPrimary: '#E6EDF3', + textSecondary: '#8B949E', + textMuted: '#484F58', + textOnPrimary: '#FFFFFF', + + white: '#FFFFFF', + transparent: 'transparent', +} as const; + +export const Typography = { + display: { + fontFamily: 'DMSans_700Bold', + fontSize: 52, + lineHeight: 60, + letterSpacing: -1.5, + }, + h1: { + fontFamily: 'DMSans_700Bold', + fontSize: 28, + lineHeight: 34, + letterSpacing: -0.5, + }, + h2: { + fontFamily: 'DMSans_600SemiBold', + fontSize: 20, + lineHeight: 26, + letterSpacing: -0.3, + }, + bodyLarge: { + fontFamily: 'DMSans_400Regular', + fontSize: 17, + lineHeight: 24, + }, + body: { + fontFamily: 'DMSans_400Regular', + fontSize: 15, + lineHeight: 22, + }, + caption: { + fontFamily: 'DMSans_400Regular', + fontSize: 12, + lineHeight: 16, + letterSpacing: 0.3, + }, + currencyLabel: { + fontFamily: 'DMSans_300Light', + fontSize: 24, + lineHeight: 32, + letterSpacing: -0.5, + }, +} as const; + +export const Spacing = { + xs: 4, + sm: 8, + md: 16, + lg: 24, + xl: 32, + xxl: 48, +} as const; + +export const Radius = { + sm: 8, + md: 12, + lg: 16, + xl: 24, + full: 9999, +} as const; + +export const Shadow = { + card: { + shadowColor: '#000', + shadowOffset: { width: 0, height: 4 }, + shadowOpacity: 0.3, + shadowRadius: 8, + elevation: 8, + }, + glow: { + shadowColor: Colors.primary, + shadowOffset: { width: 0, height: 0 }, + shadowOpacity: 0.4, + shadowRadius: 16, + elevation: 12, + }, +} as const; diff --git a/src/contexts/AuthContext.tsx b/src/contexts/AuthContext.tsx new file mode 100644 index 0000000..d2fd7a9 --- /dev/null +++ b/src/contexts/AuthContext.tsx @@ -0,0 +1,107 @@ +import { User } from '@/types'; +import React, { createContext, useContext, useEffect, useState } from 'react'; +import * as SecureStore from 'expo-secure-store'; +import * as LocalAuthentication from 'expo-local-authentication'; +import { apiLogin, apiRegister, LoginPayload, RegisterPayload, setApiToken } from '@/services/api'; + +interface AuthContextData { + user: User | null; + token: string | null; + isLoading: boolean; + login: (data: LoginPayload) => Promise<void>; + register: (data: RegisterPayload) => Promise<void>; + logout: () => Promise<void>; + updateUser: (newUser: User) => Promise<void>; +} + +const AuthContext = createContext<AuthContextData>({} as AuthContextData); + +export function AuthProvider({ children }: { children: React.ReactNode }) { + const [user, setUser] = useState<User | null>(null); + const [token, setToken] = useState<string | null>(null); + const [isLoading, setIsLoading] = useState<boolean>(true); + + useEffect(() => { + async function loadStorageData() { + try { + const storedToken = await SecureStore.getItemAsync('yaba_token'); + const storedUser = await SecureStore.getItemAsync('yaba_user'); + const useBiometrics = await SecureStore.getItemAsync('yaba_use_biometrics'); + + if (storedToken && storedUser) { + let authenticated = true; + + if (useBiometrics === 'true') { + const hasHardware = await LocalAuthentication.hasHardwareAsync(); + const isEnrolled = await LocalAuthentication.isEnrolledAsync(); + + if (hasHardware && isEnrolled) { + const result = await LocalAuthentication.authenticateAsync({ + promptMessage: 'Use sua digital para continuar', + fallbackLabel: 'Usar senha', + }); + + authenticated = result.success; + } + } + + if (authenticated) { + setApiToken(storedToken); + setToken(storedToken); + setUser(JSON.parse(storedUser)); + } else { + await SecureStore.deleteItemAsync('yaba_token'); + await SecureStore.deleteItemAsync('yaba_user'); + } + } + } catch (error) { + console.error('Error loading storage data:', error); + } finally { + setIsLoading(false); + } + } + + loadStorageData(); + }, []); + + async function login(data: LoginPayload) { + const res = await apiLogin(data); + await SecureStore.setItemAsync('yaba_token', res.token); + await SecureStore.setItemAsync('yaba_user', JSON.stringify(res.user)); + setApiToken(res.token); + setToken(res.token); + setUser(res.user); + } + + async function register(data: RegisterPayload) { + const res = await apiRegister(data); + await SecureStore.setItemAsync('yaba_token', res.token); + await SecureStore.setItemAsync('yaba_user', JSON.stringify(res.user)); + setApiToken(res.token); + setToken(res.token); + setUser(res.user); + } + + async function logout() { + await SecureStore.deleteItemAsync('yaba_token'); + await SecureStore.deleteItemAsync('yaba_user'); + setApiToken(null); + setToken(null); + setUser(null); + } + + async function updateUser(newUser: User) { + await SecureStore.setItemAsync('yaba_user', JSON.stringify(newUser)); + setUser(newUser); + } + + return ( + <AuthContext.Provider value={{ user, token, isLoading, login, register, logout, updateUser }}> + {children} + </AuthContext.Provider> + ); +} + +export function useAuth() { + return useContext(AuthContext); +}
\ No newline at end of file diff --git a/src/global.css b/src/global.css new file mode 100644 index 0000000..c8fe503 --- /dev/null +++ b/src/global.css @@ -0,0 +1,9 @@ +:root { + --font-display: + Spline Sans, Inter, ui-sans-serif, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, + Segoe UI Symbol, Noto Color Emoji; + --font-mono: + ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace; + --font-rounded: 'SF Pro Rounded', 'Hiragino Maru Gothic ProN', Meiryo, 'MS PGothic', sans-serif; + --font-serif: Georgia, 'Times New Roman', serif; +} diff --git a/src/hooks/use-app-hooks.ts b/src/hooks/use-app-hooks.ts new file mode 100644 index 0000000..f10d1ef --- /dev/null +++ b/src/hooks/use-app-hooks.ts @@ -0,0 +1,20 @@ +import { useFonts } from 'expo-font'; +import { DMSans_300Light, DMSans_400Regular, DMSans_600SemiBold, DMSans_700Bold } from '@expo-google-fonts/dm-sans'; +import { calcularSalarioLiquido, type ResultadoCalculo } from '@/utils/tax-calculator'; + +export function useAppFonts() { + const [loaded, error] = useFonts({ + DMSans_300Light, + DMSans_400Regular, + DMSans_600SemiBold, + DMSans_700Bold, + }); + + return { fontsLoaded: loaded, fontsError: error }; +} + +export function useSalaryCalculator(grossSalaryStr: string): ResultadoCalculo | null { + const value = parseFloat(grossSalaryStr.replace(',', '.')); + if (isNaN(value) || value <= 0) return null; + return calcularSalarioLiquido(value); +}
\ No newline at end of file diff --git a/src/screens/dashboard-screen.tsx b/src/screens/dashboard-screen.tsx new file mode 100644 index 0000000..c4a533c --- /dev/null +++ b/src/screens/dashboard-screen.tsx @@ -0,0 +1,440 @@ +import React, { useCallback, useState } from 'react'; +import { + ActivityIndicator, + RefreshControl, + ScrollView, + StyleSheet, + Text, + TouchableOpacity, + View, +} from 'react-native'; +import { Feather } from '@expo/vector-icons'; +import { LinearGradient } from 'expo-linear-gradient'; +import Animated, { + FadeInDown, + FadeInUp, + LinearTransition, +} from 'react-native-reanimated'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; +import { Card, CurrencyDisplay, Divider, SectionLabel } from '@/components/ui/primitives'; +import { ExpensesChart } from '@/components/ui/expenses-chart'; +import { Colors, Spacing, Typography } from '@/constants/theme'; +import { getDashboard } from '@/services/api'; +import type { DashboardData } from '@/types'; +import { useAuth } from '@/contexts/AuthContext'; +import { useRouter, useFocusEffect } from 'expo-router'; +import { useIsFocused } from "expo-router/react-navigation"; + +const MONTH_NAMES = [ + '', 'Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', + 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro', +]; + +export default function DashboardScreen() { + const insets = useSafeAreaInsets(); + const [refreshing, setRefreshing] = useState(false); + const [data, setData] = useState<DashboardData | null>(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState<string | null>(null); + const { user, logout } = useAuth(); + const router = useRouter(); + const isFocused = useIsFocused(); + + const [targetMonth, setTargetMonth] = useState(() => new Date().getMonth() + 1); + const [targetYear, setTargetYear] = useState(() => new Date().getFullYear()); + + const fetchDashboard = useCallback(async () => { + if (!user) return; + try { + setError(null); + const res = await getDashboard(user.id, targetMonth, targetYear); + setData(res); + } catch (err) { + setError('Não foi possível carregar os dados.'); + } finally { + setLoading(false); + } + }, [targetMonth, targetYear, user]); + + useFocusEffect( + useCallback(() => { + fetchDashboard(); + }, [fetchDashboard]) + ); + + async function handleRefresh() { + setRefreshing(true); + await fetchDashboard(); + setRefreshing(false); + } + + if (loading) { + return ( + <View style={[styles.container, styles.centered]}> + <ActivityIndicator size="large" color={Colors.primary} /> + </View> + ); + } + + if (error || !data) { + return ( + <View style={[styles.container, styles.centered]}> + <Text style={styles.errorText}>{error}</Text> + </View> + ); + } + + const isPositive = data.balance.available >= 0; + const monthName = MONTH_NAMES[data.period.month]; + + return ( + <View style={[styles.container, { paddingTop: insets.top }]}> + <LinearGradient + colors={['#0D2818', Colors.background]} + style={styles.headerGradient} + start={{ x: 0, y: 0 }} + end={{ x: 0, y: 1 }} + /> + + {isFocused && ( + <ScrollView + contentContainerStyle={[styles.scroll, { paddingBottom: insets.bottom + 80 }]} + showsVerticalScrollIndicator={false} + refreshControl={ + <RefreshControl + refreshing={refreshing} + onRefresh={handleRefresh} + tintColor={Colors.primaryLight} + /> + } + > + <Animated.View entering={FadeInUp.duration(500)} style={styles.headerTop}> + <View style={styles.greeting}> + <Text style={styles.greetingText}>Olá, {data.user.name} 👋</Text> + + <View style={styles.monthSelector}> + <TouchableOpacity + onPress={() => { + let m = targetMonth - 1; + let y = targetYear; + if (m < 1) { m = 12; y -= 1; } + setTargetMonth(m); + setTargetYear(y); + setLoading(true); + }} + style={styles.monthButton} + > + <Feather name="chevron-left" size={20} color={Colors.textSecondary} /> + </TouchableOpacity> + + <Text style={styles.periodText}> + {monthName} {data.period.year} + </Text> + + <TouchableOpacity + onPress={() => { + let m = targetMonth + 1; + let y = targetYear; + if (m > 12) { m = 1; y += 1; } + setTargetMonth(m); + setTargetYear(y); + setLoading(true); + }} + style={styles.monthButton} + > + <Feather name="chevron-right" size={20} color={Colors.textSecondary} /> + </TouchableOpacity> + </View> + </View> + + <TouchableOpacity + style={styles.logoutBtn} + onPress={async () => { + await logout(); + router.replace('/login'); + }} + > + <Feather name="log-out" size={20} color={Colors.textSecondary} /> + </TouchableOpacity> + </Animated.View> + + <Animated.View entering={FadeInUp.delay(100).duration(500)} layout={LinearTransition.springify()}> + <Card style={[styles.heroCard, isPositive ? styles.heroPositive : styles.heroNegative]}> + <SectionLabel + text="Saldo Disponível" + color={isPositive ? Colors.positive : Colors.negative} + /> + <View style={styles.heroBalance}> + <CurrencyDisplay amount={data.balance.available} size="display" /> + </View> + + <View style={styles.ratioSection}> + <View style={styles.ratioBar}> + <View + style={[ + styles.ratioFill, + { + width: `${Math.min(data.balance.expense_ratio, 100)}%` as `${number}%`, + backgroundColor: + data.balance.expense_ratio > 80 ? Colors.negative : Colors.primary, + }, + ]} + /> + </View> + <Text style={styles.ratioText}> + {data.balance.expense_ratio.toFixed(1)}% do salário comprometido + </Text> + </View> + </Card> + </Animated.View> + + <Animated.View entering={FadeInDown.delay(200).duration(500)} layout={LinearTransition.springify()}> + <Card style={styles.card}> + <SectionLabel text="Salário" /> + <View style={styles.salaryRow}> + <View style={styles.salaryItem}> + <Text style={styles.salaryLabel}>Bruto</Text> + <Text style={styles.salaryValue}> + {data.salary.gross.toLocaleString('pt-BR', { + style: 'currency', + currency: 'BRL', + minimumFractionDigits: 0, + })} + </Text> + </View> + <View style={styles.salaryArrow}> + <Text style={styles.salaryArrowText}>→</Text> + </View> + <View style={styles.salaryItem}> + <Text style={styles.salaryLabel}>Líquido</Text> + <Text style={[styles.salaryValue, { color: Colors.positive }]}> + {data.salary.effective_net.toLocaleString('pt-BR', { + style: 'currency', + currency: 'BRL', + minimumFractionDigits: 0, + })} + </Text> + </View> + </View> + <Divider /> + <View style={styles.taxRow}> + <Text style={styles.taxLabel}>INSS</Text> + <Text style={styles.taxValue}> + -{data.salary.inss_discount.toLocaleString('pt-BR', { + style: 'currency', + currency: 'BRL', + })} + </Text> + </View> + <View style={styles.taxRow}> + <Text style={styles.taxLabel}>IRRF</Text> + <Text style={styles.taxValue}> + -{data.salary.irrf_discount.toLocaleString('pt-BR', { + style: 'currency', + currency: 'BRL', + })} + </Text> + </View> + </Card> + </Animated.View> + + <Animated.View entering={FadeInDown.delay(250).duration(500)} layout={LinearTransition.springify()}> + <ExpensesChart + recurring={data.expenses.recurring_list} + oneTime={data.expenses.one_time_list} + /> + </Animated.View> + + <Animated.View entering={FadeInDown.delay(300).duration(500)} layout={LinearTransition.springify()}> + <Card style={styles.card}> + <View style={[styles.sectionHeader, { marginBottom: 0 }]}> + <SectionLabel text="Lançamentos Fixos" /> + <Text + style={[ + styles.totalBadge, + data.expenses.recurring_total < 0 ? { color: Colors.positive } : { color: Colors.negative } + ]} + > + {data.expenses.recurring_total < 0 ? '+ ' : (data.expenses.recurring_total > 0 ? '- ' : '')} + {Math.abs(data.expenses.recurring_total).toLocaleString('pt-BR', { + style: 'currency', + currency: 'BRL', + minimumFractionDigits: 0, + })} + </Text> + </View> + </Card> + </Animated.View> + + <Animated.View entering={FadeInDown.delay(400).duration(500)} layout={LinearTransition.springify()}> + <Card style={styles.card}> + <View style={[styles.sectionHeader, { marginBottom: 0 }]}> + <SectionLabel text="Lançamentos do Mês" /> + <Text + style={[ + styles.totalBadge, + data.expenses.one_time_total < 0 ? { color: Colors.positive } : { color: Colors.negative } + ]} + > + {data.expenses.one_time_total < 0 ? '+ ' : (data.expenses.one_time_total > 0 ? '- ' : '')} + {Math.abs(data.expenses.one_time_total).toLocaleString('pt-BR', { + style: 'currency', + currency: 'BRL', + minimumFractionDigits: 0, + })} + </Text> + </View> + </Card> + </Animated.View> + </ScrollView> + )} + </View> + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: Colors.background, + }, + centered: { + justifyContent: 'center', + alignItems: 'center', + }, + errorText: { + ...Typography.body, + color: Colors.negative, + }, + headerGradient: { + position: 'absolute', + top: 0, + left: 0, + right: 0, + height: 200, + }, + scroll: { + padding: Spacing.md, + gap: Spacing.md, + }, + headerTop: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'flex-start', + paddingVertical: Spacing.sm, + }, + greeting: { + flex: 1, + }, + logoutBtn: { + padding: 8, + backgroundColor: 'rgba(255,255,255,0.05)', + borderRadius: 12, + }, + greetingText: { + ...Typography.h2, + color: Colors.textPrimary, + }, + periodText: { + ...Typography.caption, + color: Colors.textSecondary, + textTransform: 'uppercase', + letterSpacing: 1.5, + }, + monthSelector: { + flexDirection: 'row', + alignItems: 'center', + marginTop: 6, + gap: Spacing.xs, + }, + monthButton: { + padding: 4, + }, + card: { + gap: Spacing.sm, + }, + heroCard: { + gap: Spacing.md, + borderWidth: 1, + }, + heroPositive: { + borderColor: `${Colors.positive}40`, + }, + heroNegative: { + borderColor: `${Colors.negative}40`, + }, + heroBalance: { + marginTop: Spacing.xs, + }, + ratioSection: { + gap: Spacing.xs, + }, + ratioBar: { + height: 4, + backgroundColor: Colors.border, + borderRadius: 2, + overflow: 'hidden', + }, + ratioFill: { + height: '100%', + borderRadius: 2, + }, + ratioText: { + ...Typography.caption, + color: Colors.textMuted, + }, + salaryRow: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + marginTop: Spacing.sm, + }, + salaryItem: { + flex: 1, + gap: 4, + }, + salaryLabel: { + ...Typography.caption, + color: Colors.textMuted, + textTransform: 'uppercase', + letterSpacing: 1, + }, + salaryValue: { + ...Typography.h2, + color: Colors.textPrimary, + }, + salaryArrow: { + paddingHorizontal: Spacing.md, + }, + salaryArrowText: { + ...Typography.h2, + color: Colors.textMuted, + }, + taxRow: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + }, + taxLabel: { + ...Typography.body, + color: Colors.textSecondary, + }, + taxValue: { + ...Typography.body, + color: Colors.negative, + fontFamily: 'DMSans_600SemiBold', + }, + sectionHeader: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + marginBottom: Spacing.xs, + }, + totalBadge: { + ...Typography.body, + color: Colors.negative, + fontFamily: 'DMSans_600SemiBold', + }, + rowDivider: { + marginVertical: 0, + }, +}); diff --git a/src/screens/one-time-expenses-screen.tsx b/src/screens/one-time-expenses-screen.tsx new file mode 100644 index 0000000..c84a39f --- /dev/null +++ b/src/screens/one-time-expenses-screen.tsx @@ -0,0 +1,485 @@ +import React, { useCallback, useState } from 'react'; +import { + Alert, + ScrollView, + StyleSheet, + Text, + TouchableOpacity, + View, +} from 'react-native'; +import Animated, { FadeInDown, LinearTransition } from 'react-native-reanimated'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; +import * as Haptics from 'expo-haptics'; +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { Card, Divider, SectionLabel } from '@/components/ui/primitives'; +import { OneTimeExpenseRow } from '@/components/expense-row'; +import { Colors, Radius, Spacing, Typography } from '@/constants/theme'; +import type { Category, OneTimeExpense } from '@/types'; +import { + createOneTimeExpense, + updateOneTimeExpense, + deleteOneTimeExpense, + getOneTimeExpenses, +} from '@/services/api'; +import { useAuth } from '@/contexts/AuthContext'; +import { ActionModal } from '@/components/ui/action-modal'; +import { OptionsModal } from '@/components/ui/options-modal'; +import { useFocusEffect } from 'expo-router'; +import { useIsFocused } from "expo-router/react-navigation"; + +const CATEGORIES: { value: Category; emoji: string; label: string }[] = [ + { value: 'alimentação', emoji: '🍽️', label: 'Alimentação' }, + { value: 'lazer', emoji: '🎬', label: 'Lazer' }, + { value: 'transporte', emoji: '🚗', label: 'Transporte' }, + { value: 'saúde', emoji: '💊', label: 'Saúde' }, + { value: 'moradia', emoji: '🏠', label: 'Moradia' }, + { value: 'educação', emoji: '📚', label: 'Educação' }, + { value: 'serviços', emoji: '⚙️', label: 'Serviços' }, + { value: 'outros', emoji: '📦', label: 'Outros' }, +]; + +export default function OneTimeExpensesScreen() { + const insets = useSafeAreaInsets(); + const { user } = useAuth(); + const [expenses, setExpenses] = useState<OneTimeExpense[]>([]); + const [showForm, setShowForm] = useState(false); + const [loading, setLoading] = useState(true); + + const [name, setName] = useState(''); + const [amount, setAmount] = useState(''); + const [selectedCategory, setSelectedCategory] = useState<Category>('outros'); + const [expenseType, setExpenseType] = useState<'expense' | 'income'>('expense'); + const [notes, setNotes] = useState(''); + const [isSubmitting, setIsSubmitting] = useState(false); + + const [expenseToDelete, setExpenseToDelete] = useState<number | null>(null); + const [selectedExpense, setSelectedExpense] = useState<OneTimeExpense | null>(null); + const [editingExpenseId, setEditingExpenseId] = useState<number | null>(null); + + const isFocused = useIsFocused(); + + const fetchExpenses = useCallback(async () => { + if (!user) return; + try { + setLoading(true); + const data = await getOneTimeExpenses(user.id); + setExpenses(data); + } catch (err) { + Alert.alert('Erro', 'Não foi possível carregar os gastos do mês.'); + } finally { + setLoading(false); + } + }, [user]); + + useFocusEffect( + useCallback(() => { + fetchExpenses(); + }, [fetchExpenses]) + ); + + const monthTotal = expenses.reduce((sum, e) => { + return sum + (e.type === 'income' ? -e.amount : e.amount); + }, 0); + const isTotalIncome = monthTotal < 0; + const absTotal = Math.abs(monthTotal); + const formattedTotal = absTotal.toLocaleString('pt-BR', { + style: 'currency', + currency: 'BRL', + }); + + async function handleAdd() { + const amountNum = parseFloat(amount.replace(',', '.')); + if (!name.trim() || isNaN(amountNum) || amountNum <= 0) { + Alert.alert('Dados inválidos', 'Preencha o nome e um valor válido.'); + return; + } + + try { + if (!user) return; + setIsSubmitting(true); + + if (editingExpenseId) { + const updated = await updateOneTimeExpense(user.id, editingExpenseId, { + name: name.trim(), + amount: amountNum, + category: selectedCategory, + type: expenseType, + notes: notes.trim() || null, + }); + setExpenses((prev) => prev.map((e) => e.id === editingExpenseId ? updated : e)); + Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success); + } else { + const today = new Date().toISOString().split('T')[0]; + const newExpense = await createOneTimeExpense(user.id, { + name: name.trim(), + amount: amountNum, + category: selectedCategory, + type: expenseType, + expense_date: today, + notes: notes.trim() || null, + }); + setExpenses((prev) => [...prev, newExpense]); + Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success); + } + + setName(''); + setAmount(''); + setNotes(''); + setExpenseType('expense'); + setShowForm(false); + setEditingExpenseId(null); + } catch (err) { + Alert.alert('Erro', 'Não foi possível salvar o lançamento.'); + } finally { + setIsSubmitting(false); + } + } + + function handleDelete(id: number) { + setExpenseToDelete(id); + setSelectedExpense(null); + } + + function handleEdit(expense: OneTimeExpense) { + setName(expense.name); + setAmount(expense.amount.toString()); + setSelectedCategory(expense.category); + setExpenseType(expense.type); + setNotes(expense.notes || ''); + setEditingExpenseId(expense.id); + setSelectedExpense(null); + setShowForm(true); + } + + async function confirmDelete() { + if (!user || expenseToDelete === null) return; + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium); + try { + await deleteOneTimeExpense(user.id, expenseToDelete); + setExpenses((prev) => prev.filter((e) => e.id !== expenseToDelete)); + } catch (err) { + Alert.alert('Erro', 'Não foi possível remover o lançamento.'); + } finally { + setExpenseToDelete(null); + } + } + + return ( + <View style={[styles.container, { paddingTop: insets.top }]}> + {isFocused && ( + <ScrollView + contentContainerStyle={[ + styles.scroll, + { paddingBottom: insets.bottom + Spacing.xxl }, + ]} + keyboardShouldPersistTaps="handled" + showsVerticalScrollIndicator={false} + > + <Animated.View entering={FadeInDown.duration(400)} style={styles.header}> + <View> + <Text style={styles.title}>Lançamentos</Text> + <Text style={styles.subtitle}> + Saldo líquido:{' '} + <Text + style={[ + styles.totalHighlight, + isTotalIncome ? { color: Colors.positive } : { color: Colors.negative } + ]} + > + {isTotalIncome ? '+ ' : (monthTotal > 0 ? '- ' : '')}{formattedTotal} + </Text> + </Text> + </View> + <TouchableOpacity + id="onetime-add-button" + style={[styles.addButton, showForm && styles.addButtonActive]} + onPress={() => { + if (showForm) { + setEditingExpenseId(null); + setName(''); + setAmount(''); + setNotes(''); + } + setShowForm((v) => !v); + }} + accessibilityLabel="Adicionar lançamento" + accessibilityRole="button" + > + <Text style={styles.addButtonText}>{showForm ? '✕' : '+'}</Text> + </TouchableOpacity> + </Animated.View> + + {showForm && ( + <Animated.View entering={FadeInDown.duration(300)}> + <Card style={styles.formCard}> + <SectionLabel text={editingExpenseId ? "Editar Lançamento" : "Novo Lançamento"} /> + + <View style={styles.typeSelector}> + <TouchableOpacity + style={[styles.typeButton, expenseType === 'expense' && styles.typeButtonExpenseActive]} + onPress={() => setExpenseType('expense')} + > + <Text style={[styles.typeButtonText, expenseType === 'expense' && { color: Colors.negative }]}> + Despesa + </Text> + </TouchableOpacity> + <TouchableOpacity + style={[styles.typeButton, expenseType === 'income' && styles.typeButtonIncomeActive]} + onPress={() => setExpenseType('income')} + > + <Text style={[styles.typeButtonText, expenseType === 'income' && { color: Colors.positive }]}> + Receita + </Text> + </TouchableOpacity> + </View> + + <Input + id="one-time-name-input" + label="Descrição" + value={name} + onChangeText={setName} + placeholder="Ex: iFood, Cinema, Uber..." + /> + + <Input + id="one-time-amount-input" + label="Valor" + prefix="R$" + value={amount} + onChangeText={setAmount} + keyboardType="decimal-pad" + placeholder="0,00" + /> + + <View> + <Text style={styles.catLabel}>Categoria</Text> + <View style={styles.categoryGrid}> + {CATEGORIES.map((cat) => ( + <TouchableOpacity + key={cat.value} + style={[ + styles.catChip, + selectedCategory === cat.value && styles.catChipSelected, + ]} + onPress={() => setSelectedCategory(cat.value)} + accessibilityLabel={cat.label} + accessibilityRole="radio" + > + <Text style={styles.catEmoji}>{cat.emoji}</Text> + <Text + style={[ + styles.catText, + selectedCategory === cat.value && styles.catTextSelected, + ]} + > + {cat.label} + </Text> + </TouchableOpacity> + ))} + </View> + </View> + + <Input + id="one-time-notes-input" + label="Observações (opcional)" + value={notes} + onChangeText={setNotes} + placeholder="Ex: almoço de aniversário" + multiline + /> + + <Button + id="one-time-save-button" + label={expenseType === 'income' ? 'Adicionar Receita' : 'Adicionar Gasto'} + fullWidth + onPress={handleAdd} + loading={isSubmitting} + disabled={isSubmitting} + style={expenseType === 'income' ? { backgroundColor: Colors.positive } : undefined} + /> + </Card> + </Animated.View> + )} + + <Animated.View layout={LinearTransition.springify()}> + <Card style={styles.listCard}> + <SectionLabel text={`${expenses.length} lançamentos este mês`} /> + {expenses.length === 0 ? ( + <Text style={styles.emptyText}> + Nenhum lançamento registrado este mês.{'\n'}Toque em + para adicionar. + </Text> + ) : ( + expenses.map((expense, i) => ( + <React.Fragment key={expense.id}> + {i > 0 && <Divider style={styles.rowDivider} />} + <OneTimeExpenseRow + expense={expense} + index={i} + onPress={() => setSelectedExpense(expense)} + /> + </React.Fragment> + )) + )} + </Card> + </Animated.View> + </ScrollView> + )} + + <ActionModal + visible={expenseToDelete !== null} + title="Remover lançamento" + message="Deseja realmente remover este lançamento? Esta ação não pode ser desfeita." + confirmText="Remover" + isDestructive={true} + onCancel={() => setExpenseToDelete(null)} + onConfirm={confirmDelete} + /> + + <OptionsModal + visible={selectedExpense !== null} + title={selectedExpense?.name} + onClose={() => setSelectedExpense(null)} + options={[ + { + label: 'Editar', + icon: 'edit-2', + onPress: () => selectedExpense && handleEdit(selectedExpense), + }, + { + label: 'Excluir', + icon: 'trash-2', + destructive: true, + onPress: () => selectedExpense && handleDelete(selectedExpense.id), + } + ]} + /> + </View> + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: Colors.background, + }, + scroll: { + padding: Spacing.md, + gap: Spacing.md, + }, + header: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'flex-start', + }, + title: { + ...Typography.h1, + color: Colors.textPrimary, + }, + subtitle: { + ...Typography.body, + color: Colors.textSecondary, + marginTop: 4, + }, + totalHighlight: { + color: Colors.negative, + fontFamily: 'DMSans_600SemiBold', + }, + addButton: { + width: 44, + height: 44, + borderRadius: 22, + backgroundColor: Colors.primary, + alignItems: 'center', + justifyContent: 'center', + }, + addButtonActive: { + backgroundColor: Colors.surfaceElevated, + borderWidth: 1, + borderColor: Colors.border, + }, + addButtonText: { + ...Typography.h2, + color: Colors.white, + }, + formCard: { + gap: Spacing.md, + }, + typeSelector: { + flexDirection: 'row', + gap: Spacing.sm, + }, + typeButton: { + flex: 1, + paddingVertical: Spacing.sm, + alignItems: 'center', + borderRadius: Radius.md, + borderWidth: 1, + borderColor: Colors.border, + backgroundColor: Colors.surfaceElevated, + }, + typeButtonExpenseActive: { + borderColor: Colors.negative, + backgroundColor: `${Colors.negative}1A`, + }, + typeButtonIncomeActive: { + borderColor: Colors.positive, + backgroundColor: `${Colors.positive}1A`, + }, + typeButtonText: { + ...Typography.body, + color: Colors.textSecondary, + fontFamily: 'DMSans_600SemiBold', + }, + listCard: { + gap: Spacing.xs, + }, + rowDivider: { + marginVertical: 0, + }, + emptyText: { + ...Typography.body, + color: Colors.textMuted, + textAlign: 'center', + paddingVertical: Spacing.xl, + lineHeight: 24, + }, + catLabel: { + ...Typography.caption, + color: Colors.textSecondary, + textTransform: 'uppercase', + letterSpacing: 1, + marginBottom: Spacing.sm, + }, + categoryGrid: { + flexDirection: 'row', + flexWrap: 'wrap', + gap: Spacing.sm, + }, + catChip: { + flexDirection: 'row', + alignItems: 'center', + gap: Spacing.xs, + paddingVertical: Spacing.sm, + paddingHorizontal: Spacing.md, + borderRadius: Radius.full, + backgroundColor: Colors.surfaceElevated, + borderWidth: 1, + borderColor: Colors.border, + }, + catChipSelected: { + borderColor: Colors.primaryLight, + backgroundColor: `${Colors.primary}33`, + }, + catEmoji: { + fontSize: 14, + }, + catText: { + ...Typography.caption, + color: Colors.textSecondary, + }, + catTextSelected: { + color: Colors.primaryLight, + fontFamily: 'DMSans_600SemiBold', + }, +}); diff --git a/src/screens/recurring-expenses-screen.tsx b/src/screens/recurring-expenses-screen.tsx new file mode 100644 index 0000000..ea6f165 --- /dev/null +++ b/src/screens/recurring-expenses-screen.tsx @@ -0,0 +1,442 @@ +import React, { useCallback, useState } from 'react'; +import { + Alert, + Platform, + ScrollView, + StyleSheet, + Text, + TouchableOpacity, + View, +} from 'react-native'; +import Animated, { FadeInDown, LinearTransition } from 'react-native-reanimated'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; +import * as Haptics from 'expo-haptics'; +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { Card, Divider, SectionLabel } from '@/components/ui/primitives'; +import { RecurringExpenseRow } from '@/components/expense-row'; +import { Colors, Spacing, Typography } from '@/constants/theme'; +import type { RecurringExpense } from '@/types'; +import { + createRecurringExpense, + deleteRecurringExpense, + getRecurringExpenses, + toggleRecurringExpense, + updateRecurringExpense, +} from '@/services/api'; +import { useAuth } from '@/contexts/AuthContext'; +import { ActionModal } from '@/components/ui/action-modal'; +import { OptionsModal } from '@/components/ui/options-modal'; +import { useFocusEffect } from 'expo-router'; +import { useIsFocused } from "expo-router/react-navigation"; + +export default function RecurringExpensesScreen() { + const insets = useSafeAreaInsets(); + const { user } = useAuth(); + const [expenses, setExpenses] = useState<RecurringExpense[]>([]); + const [showForm, setShowForm] = useState(false); + const [loading, setLoading] = useState(true); + + const [name, setName] = useState(''); + const [amount, setAmount] = useState(''); + const [expenseType, setExpenseType] = useState<'expense' | 'income'>('expense'); + const [dueDay, setDueDay] = useState(''); + const [isSubmitting, setIsSubmitting] = useState(false); + + const [expenseToDelete, setExpenseToDelete] = useState<number | null>(null); + const [selectedExpense, setSelectedExpense] = useState<RecurringExpense | null>(null); + const [editingExpenseId, setEditingExpenseId] = useState<number | null>(null); + + const isFocused = useIsFocused(); + + const fetchExpenses = useCallback(async () => { + if (!user) return; + try { + setLoading(true); + const data = await getRecurringExpenses(user.id); + setExpenses(data); + } catch (err) { + Alert.alert('Erro', 'Não foi possível carregar os gastos.'); + } finally { + setLoading(false); + } + }, [user]); + + useFocusEffect( + useCallback(() => { + fetchExpenses(); + }, [fetchExpenses]) + ); + + const activeTotal = expenses + .filter((e) => e.is_active) + .reduce((sum, e) => { + return sum + (e.type === 'income' ? -e.amount : e.amount); + }, 0); + + const isTotalIncome = activeTotal < 0; + const absTotal = Math.abs(activeTotal); + const formattedTotal = absTotal.toLocaleString('pt-BR', { + style: 'currency', + currency: 'BRL', + }); + + async function handleToggle(id: number) { + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); + + setExpenses((prev) => + prev.map((e) => (e.id === id ? { ...e, is_active: !e.is_active } : e)), + ); + try { + if (!user) return; + await toggleRecurringExpense(user.id, id); + } catch (err) { + setExpenses((prev) => + prev.map((e) => (e.id === id ? { ...e, is_active: !e.is_active } : e)), + ); + Alert.alert('Erro', 'Não foi possível alterar o status do gasto.'); + } + } + + async function handleAdd() { + const amountNum = parseFloat(amount.replace(',', '.')); + if (!name.trim() || isNaN(amountNum) || amountNum <= 0) { + Alert.alert('Dados inválidos', 'Preencha o nome e um valor válido.'); + return; + } + + try { + if (!user) return; + setIsSubmitting(true); + + if (editingExpenseId) { + const updated = await updateRecurringExpense(user.id, editingExpenseId, { + name: name.trim(), + amount: amountNum, + category: 'outros', + type: expenseType, + due_day: dueDay ? parseInt(dueDay, 10) : null, + }); + setExpenses((prev) => prev.map((e) => e.id === editingExpenseId ? updated : e)); + Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success); + } else { + const newExpense = await createRecurringExpense(user.id, { + name: name.trim(), + amount: amountNum, + category: 'outros', + type: expenseType, + due_day: dueDay ? parseInt(dueDay, 10) : null, + is_active: true, + starts_at: new Date().toISOString().split('T')[0], + ends_at: null, + }); + setExpenses((prev) => [...prev, newExpense]); + Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success); + } + + setName(''); + setAmount(''); + setExpenseType('expense'); + setDueDay(''); + setShowForm(false); + setEditingExpenseId(null); + } catch (err) { + Alert.alert('Erro', 'Não foi possível salvar o lançamento.'); + } finally { + setIsSubmitting(false); + } + } + + function handleDelete(id: number) { + setExpenseToDelete(id); + setSelectedExpense(null); + } + + function handleEdit(expense: RecurringExpense) { + setName(expense.name); + setAmount(expense.amount.toString()); + setExpenseType(expense.type); + setDueDay(expense.due_day ? expense.due_day.toString() : ''); + setEditingExpenseId(expense.id); + setSelectedExpense(null); + setShowForm(true); + } + + async function confirmDelete() { + if (!user || expenseToDelete === null) return; + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium); + try { + await deleteRecurringExpense(user.id, expenseToDelete); + setExpenses((prev) => prev.filter((e) => e.id !== expenseToDelete)); + } catch (err) { + Alert.alert('Erro', 'Não foi possível remover o gasto.'); + } finally { + setExpenseToDelete(null); + } + } + + return ( + <View style={[styles.container, { paddingTop: insets.top }]}> + {isFocused && ( + <ScrollView + contentContainerStyle={[ + styles.scroll, + { paddingBottom: insets.bottom + 80 }, + ]} + keyboardShouldPersistTaps="handled" + showsVerticalScrollIndicator={false} + > + <Animated.View entering={FadeInDown.duration(400)} style={styles.header}> + <View> + <Text style={styles.title}>Lançamentos Fixos</Text> + <Text style={styles.subtitle}> + Saldo líquido:{' '} + <Text + style={[ + styles.totalHighlight, + isTotalIncome ? { color: Colors.positive } : { color: Colors.negative } + ]} + > + {isTotalIncome ? '+ ' : (activeTotal > 0 ? '- ' : '')}{formattedTotal} + </Text> + </Text> + </View> + <TouchableOpacity + id="recurring-add-button" + style={[styles.addButton, showForm && styles.addButtonActive]} + onPress={() => { + if (showForm) { + setEditingExpenseId(null); + setName(''); + setAmount(''); + setDueDay(''); + } + setShowForm((v) => !v); + }} + accessibilityLabel="Adicionar lançamento fixo" + accessibilityRole="button" + > + <Text style={styles.addButtonText}>{showForm ? '✕' : '+'}</Text> + </TouchableOpacity> + </Animated.View> + + {showForm && ( + <Animated.View entering={FadeInDown.duration(300)}> + <Card style={styles.formCard}> + <SectionLabel text={editingExpenseId ? "Editar Lançamento" : "Novo Lançamento Fixo"} /> + <Input + id="recurring-name-input" + label="Nome" + value={name} + onChangeText={setName} + placeholder="Ex: Academia, Netflix..." + /> + <Input + id="recurring-amount-input" + label="Valor Mensal" + prefix="R$" + value={amount} + onChangeText={setAmount} + keyboardType="decimal-pad" + placeholder="0,00" + /> + + <View style={styles.typeToggle}> + <TouchableOpacity + style={[styles.typeButton, expenseType === 'expense' && styles.typeButtonExpense]} + onPress={() => setExpenseType('expense')} + > + <Text style={[styles.typeButtonText, expenseType === 'expense' && styles.typeButtonTextActive]}> + Despesa + </Text> + </TouchableOpacity> + <TouchableOpacity + style={[styles.typeButton, expenseType === 'income' && styles.typeButtonIncome]} + onPress={() => setExpenseType('income')} + > + <Text style={[styles.typeButtonText, expenseType === 'income' && styles.typeButtonTextActive]}> + Receita + </Text> + </TouchableOpacity> + </View> + + <Input + id="recurring-due-day-input" + label="Dia de Vencimento (opcional)" + value={dueDay} + onChangeText={setDueDay} + keyboardType="number-pad" + placeholder="Ex: 5" + hint="Dia do mês em que costuma vencer" + /> + <Button + id="recurring-save-button" + label={editingExpenseId ? "Salvar Alterações" : "Adicionar Lançamento Fixo"} + fullWidth + onPress={handleAdd} + loading={isSubmitting} + disabled={isSubmitting} + /> + </Card> + </Animated.View> + )} + + <Animated.View layout={LinearTransition.springify()}> + <Card style={styles.listCard}> + <SectionLabel text={`${expenses.length} lançamentos cadastrados`} /> + {expenses.length === 0 ? ( + <Text style={styles.emptyText}> + Nenhum lançamento fixo cadastrado.{'\n'}Toque em + para adicionar. + </Text> + ) : ( + expenses.map((expense, i) => ( + <React.Fragment key={expense.id}> + {i > 0 && <Divider style={styles.rowDivider} />} + <RecurringExpenseRow + expense={expense} + index={i} + onToggle={() => handleToggle(expense.id)} + onPress={() => setSelectedExpense(expense)} + /> + </React.Fragment> + )) + )} + </Card> + </Animated.View> + </ScrollView> + )} + + <ActionModal + visible={expenseToDelete !== null} + title="Remover lançamento fixo" + message="Deseja realmente remover este lançamento? Ele deixará de afetar seu saldo mensal." + confirmText="Remover" + isDestructive={true} + onCancel={() => setExpenseToDelete(null)} + onConfirm={confirmDelete} + /> + + <OptionsModal + visible={selectedExpense !== null} + title={selectedExpense?.name} + onClose={() => setSelectedExpense(null)} + options={[ + { + label: 'Editar', + icon: 'edit-2', + onPress: () => selectedExpense && handleEdit(selectedExpense), + }, + { + label: selectedExpense?.is_active ? 'Pausar' : 'Ativar', + icon: selectedExpense?.is_active ? 'pause-circle' : 'play-circle', + onPress: () => { + if (selectedExpense) { + handleToggle(selectedExpense.id); + setSelectedExpense(null); + } + }, + }, + { + label: 'Excluir', + icon: 'trash-2', + destructive: true, + onPress: () => selectedExpense && handleDelete(selectedExpense.id), + } + ]} + /> + </View> + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: Colors.background, + }, + scroll: { + padding: Spacing.md, + gap: Spacing.md, + }, + header: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'flex-start', + }, + title: { + ...Typography.h1, + color: Colors.textPrimary, + }, + subtitle: { + ...Typography.body, + color: Colors.textSecondary, + marginTop: 4, + }, + totalHighlight: { + color: Colors.negative, + fontFamily: 'DMSans_600SemiBold', + }, + addButton: { + width: 44, + height: 44, + borderRadius: 22, + backgroundColor: Colors.primary, + alignItems: 'center', + justifyContent: 'center', + }, + addButtonActive: { + backgroundColor: Colors.surfaceElevated, + borderWidth: 1, + borderColor: Colors.border, + }, + addButtonText: { + ...Typography.h2, + color: Colors.white, + }, + formCard: { + gap: Spacing.md, + }, + listCard: { + gap: Spacing.xs, + }, + rowDivider: { + marginVertical: 0, + }, + emptyText: { + ...Typography.body, + color: Colors.textMuted, + textAlign: 'center', + paddingVertical: Spacing.xl, + lineHeight: 24, + }, + typeToggle: { + flexDirection: 'row', + gap: Spacing.sm, + marginBottom: Spacing.sm, + }, + typeButton: { + flex: 1, + paddingVertical: Spacing.sm, + alignItems: 'center', + borderRadius: 12, + backgroundColor: Colors.surfaceElevated, + borderWidth: 1, + borderColor: Colors.border, + }, + typeButtonExpense: { + backgroundColor: `${Colors.negative}15`, + borderColor: `${Colors.negative}40`, + }, + typeButtonIncome: { + backgroundColor: `${Colors.positive}15`, + borderColor: `${Colors.positive}40`, + }, + typeButtonText: { + ...Typography.body, + color: Colors.textSecondary, + fontFamily: 'DMSans_500Medium', + }, + typeButtonTextActive: { + color: Colors.textPrimary, + fontFamily: 'DMSans_700Bold', + }, +}); diff --git a/src/screens/salary-screen.tsx b/src/screens/salary-screen.tsx new file mode 100644 index 0000000..6847c4b --- /dev/null +++ b/src/screens/salary-screen.tsx @@ -0,0 +1,232 @@ +import { useState } from 'react'; +import { + Alert, + ScrollView, + StyleSheet, + Text, + View, +} from 'react-native'; +import Animated, { FadeInDown, LinearTransition } from 'react-native-reanimated'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; +import * as Haptics from 'expo-haptics'; +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { Card, Divider, SectionLabel } from '@/components/ui/primitives'; +import { useSalaryCalculator } from '@/hooks/use-app-hooks'; +import { Colors, Spacing, Typography } from '@/constants/theme'; +import { formatCurrency } from '@/utils/tax-calculator'; +import { updateUserSalary } from '@/services/api'; +import { useAuth } from '@/contexts/AuthContext'; +import { useIsFocused } from "expo-router/react-navigation"; + +export default function SalaryScreen() { + const insets = useSafeAreaInsets(); + const { user, updateUser } = useAuth(); + const isFocused = useIsFocused(); + + const [grossStr, setGrossStr] = useState(user?.gross_salary ? String(user.gross_salary) : ''); + const [netOverrideStr, setNetOverrideStr] = useState( + user?.net_salary_override ? String(user.net_salary_override) : '' + ); + const [isOverriding, setIsOverriding] = useState(!!user?.net_salary_override); + + const result = useSalaryCalculator(grossStr); + + const effectiveNet = isOverriding + ? parseFloat(netOverrideStr.replace(',', '.')) || 0 + : (result?.salarioLiquidoCalculado ?? 0); + + const [isSaving, setIsSaving] = useState(false); + const [saved, setSaved] = useState(false); + + async function handleSave() { + if (!result || !user) return; + try { + setIsSaving(true); + setSaved(false); + const updatedUser = await updateUserSalary(user.id, { + gross_salary: result.salarioBruto, + net_salary_override: isOverriding ? effectiveNet : null, + }); + await updateUser(updatedUser); + Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success); + setSaved(true); + setTimeout(() => setSaved(false), 2500); + } catch (err) { + Alert.alert('Erro', 'Não foi possível salvar o salário.'); + } finally { + setIsSaving(false); + } + } + + function handleToggleOverride() { + if (isOverriding) { + setNetOverrideStr(''); + setIsOverriding(false); + } else { + setNetOverrideStr(result?.salarioLiquidoCalculado.toFixed(2) ?? ''); + setIsOverriding(true); + } + } + + return ( + <View style={[styles.container, { paddingTop: insets.top }]}> + {isFocused && ( + <ScrollView + contentContainerStyle={[ + styles.scroll, + { paddingBottom: insets.bottom + Spacing.xxl }, + ]} + keyboardShouldPersistTaps="handled" + showsVerticalScrollIndicator={false} + > + <Animated.View entering={FadeInDown.duration(400)}> + <Text style={styles.title}>Meu Salário</Text> + <Text style={styles.subtitle}> + Informe seu salário bruto e ajuste o líquido se necessário. + </Text> + </Animated.View> + + <Animated.View entering={FadeInDown.delay(100).duration(400)}> + <Input + id="salary-gross-input" + label="Salário Bruto" + prefix="R$" + value={grossStr} + onChangeText={setGrossStr} + keyboardType="decimal-pad" + placeholder="0,00" + hint="Valor antes dos descontos (INSS, IRRF)" + /> + </Animated.View> + + {result && ( + <Animated.View entering={FadeInDown.delay(150).duration(400)} layout={LinearTransition.springify()}> + <Card style={styles.resultCard}> + <SectionLabel text="Cálculo Automático" /> + + <View style={styles.resultRow}> + <Text style={styles.resultLabel}>Salário Bruto</Text> + <Text style={[styles.resultValue, { color: Colors.textPrimary }]}> + {formatCurrency(result.salarioBruto)} + </Text> + </View> + + <View style={styles.resultRow}> + <Text style={styles.resultLabel}>Desconto INSS</Text> + <Text style={[styles.resultValue, { color: Colors.negative }]}> + - {formatCurrency(result.descontoINSS)} + </Text> + </View> + + <View style={styles.resultRow}> + <Text style={styles.resultLabel}>Desconto IRRF</Text> + <Text style={[styles.resultValue, { color: Colors.negative }]}> + - {formatCurrency(result.descontoIRRF)} + </Text> + </View> + + <Divider /> + + <View style={styles.resultRow}> + <Text style={[styles.resultLabel, { color: Colors.textPrimary }]}> + Salário Líquido + </Text> + <Text style={[styles.resultValue, { color: Colors.positive }]}> + {formatCurrency(result.salarioLiquidoCalculado)} + </Text> + </View> + </Card> + </Animated.View> + )} + + {result && ( + <Animated.View + entering={FadeInDown.delay(200).duration(400)} + layout={LinearTransition.springify()} + style={styles.overrideSection} + > + <Button + label={ + isOverriding + ? 'Usar valor calculado' + : 'Tenho outros descontos (ajustar manualmente)' + } + variant="ghost" + onPress={handleToggleOverride} + /> + + {isOverriding && ( + <Animated.View entering={FadeInDown.duration(300)}> + <Input + id="salary-net-override-input" + label="Salário Líquido Real" + prefix="R$" + value={netOverrideStr} + onChangeText={setNetOverrideStr} + keyboardType="decimal-pad" + placeholder="0,00" + hint="Descontos extras: plano de saúde, VT, previdência privada, etc." + /> + </Animated.View> + )} + </Animated.View> + )} + + {result && ( + <Animated.View entering={FadeInDown.delay(300).duration(400)} layout={LinearTransition.springify()}> + <Button + id="salary-save-button" + label={saved ? 'Salvo com sucesso! ✓' : 'Salvar Salário'} + fullWidth + onPress={handleSave} + disabled={!result || isSaving || saved} + loading={isSaving} + style={saved ? { backgroundColor: Colors.positive } : undefined} + /> + </Animated.View> + )} + </ScrollView> + )} + </View> + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: Colors.background, + }, + scroll: { + padding: Spacing.md, + gap: Spacing.lg, + }, + title: { + ...Typography.h1, + color: Colors.textPrimary, + marginBottom: Spacing.xs, + }, + subtitle: { + ...Typography.body, + color: Colors.textSecondary, + }, + resultCard: { + gap: Spacing.sm, + }, + resultRow: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + }, + resultLabel: { + ...Typography.body, + color: Colors.textSecondary, + }, + resultValue: { + ...Typography.body, + fontFamily: 'DMSans_600SemiBold', + }, + overrideSection: { + gap: Spacing.md, + }, +}); diff --git a/src/services/api.ts b/src/services/api.ts new file mode 100644 index 0000000..edd376e --- /dev/null +++ b/src/services/api.ts @@ -0,0 +1,165 @@ +import { Platform } from 'react-native'; +import type { DashboardData, OneTimeExpense, RecurringExpense, User } from '@/types'; + +export type LoginPayload = any; +export type RegisterPayload = any; + +const BASE_URL = 'http://64.181.172.51:3333/api/v1' + +let currentToken: string | null = null; + +export function setApiToken(token: string | null) { + currentToken = token; +} + +async function fetcher<T>(endpoint: string, options?: RequestInit): Promise<T> { + const url = `${BASE_URL}${endpoint}`; + try { + const headers: Record<string, string> = {}; + if (options?.body) { + headers['Content-Type'] = 'application/json'; + } + if (currentToken) { + headers['Authorization'] = `Bearer ${currentToken}`; + } + + const response = await fetch(url, { + ...options, + headers: { + ...headers, + ...options?.headers, + }, + }); + + if (!response.ok) { + const errorText = await response.text(); + console.error(`API Error (${response.status}):`, errorText); + throw new Error(`API Error: ${response.status}`); + } + + const data = await response.json(); + return data; + } catch (error) { + console.error(`Fetch Error on ${endpoint}:`, error); + throw error; + } +} + +export async function apiLogin(data: any): Promise<{ user: User; token: string }> { + const result = await fetcher<{ data: { user: User; token: string } }>('/auth/login', { + method: 'POST', + body: JSON.stringify(data), + }); + return result.data; +} + +export async function apiRegister(data: any): Promise<{ user: User; token: string }> { + const result = await fetcher<{ data: { user: User; token: string } }>('/auth/register', { + method: 'POST', + body: JSON.stringify(data), + }); + return result.data; +} + +export async function getDashboard(userId: number, month?: number, year?: number): Promise<DashboardData> { + const params = new URLSearchParams(); + if (month) params.append('month', month.toString()); + if (year) params.append('year', year.toString()); + const qs = params.toString() ? `?${params.toString()}` : ''; + + const result = await fetcher<{ data: DashboardData }>(`/users/${userId}/dashboard${qs}`); + return result.data; +} + +export async function updateUserSalary( + userId: number, + data: { gross_salary: number; net_salary_override: number | null }, +): Promise<User> { + const result = await fetcher<{ data: User }>(`/users/${userId}`, { + method: 'PUT', + body: JSON.stringify(data), + }); + return result.data; +} + +export async function getRecurringExpenses(userId: number): Promise<RecurringExpense[]> { + const result = await fetcher<{ data: RecurringExpense[] }>(`/users/${userId}/recurring-expenses`); + return result.data; +} + +export async function createRecurringExpense( + userId: number, + data: Omit<RecurringExpense, 'id' | 'user_id' | 'created_at' | 'updated_at'>, +): Promise<RecurringExpense> { + const result = await fetcher<{ data: RecurringExpense }>(`/users/${userId}/recurring-expenses`, { + method: 'POST', + body: JSON.stringify(data), + }); + return result.data; +} + +export async function toggleRecurringExpense( + userId: number, + expenseId: number, +): Promise<RecurringExpense> { + const result = await fetcher<{ data: RecurringExpense }>(`/users/${userId}/recurring-expenses/${expenseId}/toggle`, { + method: 'PATCH', + }); + return result.data; +} + +export async function updateRecurringExpense( + userId: number, + expenseId: number, + data: Partial<Omit<RecurringExpense, 'id' | 'user_id' | 'created_at' | 'updated_at'>>, +): Promise<RecurringExpense> { + const result = await fetcher<{ data: RecurringExpense }>(`/users/${userId}/recurring-expenses/${expenseId}`, { + method: 'PUT', + body: JSON.stringify(data), + }); + return result.data; +} + +export async function deleteRecurringExpense(userId: number, expenseId: number): Promise<void> { + await fetcher(`/users/${userId}/recurring-expenses/${expenseId}`, { + method: 'DELETE', + }); +} + +export async function getOneTimeExpenses(userId: number, month?: number, year?: number): Promise<OneTimeExpense[]> { + const params = new URLSearchParams(); + if (month) params.append('month', month.toString()); + if (year) params.append('year', year.toString()); + const qs = params.toString() ? `?${params.toString()}` : ''; + const result = await fetcher<{ data: OneTimeExpense[] }>(`/users/${userId}/one-time-expenses${qs}`); + return result.data; +} + +export async function createOneTimeExpense( + userId: number, + data: Omit<OneTimeExpense, 'id' | 'user_id' | 'created_at' | 'updated_at'>, +): Promise<OneTimeExpense> { + const result = await fetcher<{ data: OneTimeExpense }>(`/users/${userId}/one-time-expenses`, { + method: 'POST', + body: JSON.stringify(data), + }); + return result.data; +} + +export async function updateOneTimeExpense( + userId: number, + expenseId: number, + data: Partial<Omit<OneTimeExpense, 'id' | 'user_id' | 'created_at' | 'updated_at'>>, +): Promise<OneTimeExpense> { + const result = await fetcher<{ data: OneTimeExpense }>(`/users/${userId}/one-time-expenses/${expenseId}`, { + method: 'PUT', + body: JSON.stringify(data), + }); + return result.data; +} + +export async function deleteOneTimeExpense(userId: number, expenseId: number): Promise<void> { + await fetcher(`/users/${userId}/one-time-expenses/${expenseId}`, { + method: 'DELETE', + }); +} diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 0000000..7554419 --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,98 @@ +export interface User { + id: number; + name: string; + gross_salary: number; + net_salary_override: number | null; + created_at: string; + updated_at: string; +} + +export interface Income { + id: number; + user_id: number; + gross_salary: number; + calculated_net_salary: number; + effective_net_salary: number; + reference_month: number; + reference_year: number; + description: string | null; + created_at: string; + updated_at: string; +} + +export type Category = + | 'moradia' + | 'alimentação' + | 'transporte' + | 'saúde' + | 'educação' + | 'lazer' + | 'serviços' + | 'outros'; + +export interface RecurringExpense { + id: number; + user_id: number; + name: string; + amount: number; + category: Category; + type: 'expense' | 'income'; + due_day: number | null; + is_active: boolean; + starts_at: string; + ends_at: string | null; + created_at: string; + updated_at: string; +} + +export interface OneTimeExpense { + id: number; + user_id: number; + name: string; + amount: number; + category: Category; + type: 'expense' | 'income'; + expense_date: string; + notes: string | null; + created_at: string; + updated_at: string; +} + +export interface DashboardExpenseItem { + id: number; + name: string; + amount: number; + category: string; + type: 'expense' | 'income'; + is_active?: boolean; + expense_date?: string; +} + +export interface DashboardData { + user: { + id: number; + name: string; + gross_salary: number; + net_salary_override: number | null; + }; + period: { month: number; year: number }; + salary: { + gross: number; + calculated_net: number; + effective_net: number; + inss_discount: number; + irrf_discount: number; + has_override: boolean; + }; + expenses: { + recurring_total: number; + one_time_total: number; + total: number; + recurring_list: DashboardExpenseItem[]; + one_time_list: DashboardExpenseItem[]; + }; + balance: { + available: number; + expense_ratio: number; + }; +} diff --git a/src/utils/tax-calculator.ts b/src/utils/tax-calculator.ts new file mode 100644 index 0000000..64b1c08 --- /dev/null +++ b/src/utils/tax-calculator.ts @@ -0,0 +1,85 @@ +const INSS_TABLE = [ + { upTo: 1_518.0, rate: 0.075 }, + { upTo: 2_793.88, rate: 0.09 }, + { upTo: 4_190.83, rate: 0.12 }, + { upTo: 8_157.41, rate: 0.14 }, +] as const; + +const INSS_TETO = 908.86; + +export function calcularINSS(salarioBruto: number): number { + if (salarioBruto <= 0) return 0; + if (salarioBruto > INSS_TABLE[INSS_TABLE.length - 1].upTo) return INSS_TETO; + + let inss = 0; + let limiteAnterior = 0; + + for (const faixa of INSS_TABLE) { + const baseNaFaixa = Math.min(salarioBruto, faixa.upTo) - limiteAnterior; + if (baseNaFaixa <= 0) break; + inss += baseNaFaixa * faixa.rate; + limiteAnterior = faixa.upTo; + } + + return parseFloat(inss.toFixed(2)); +} + +interface FaixaIRRF { + upTo: number | null; + rate: number; + deduction: number; +} + +const IRRF_TABLE: FaixaIRRF[] = [ + { upTo: 2_259.2, rate: 0, deduction: 0 }, + { upTo: 2_826.65, rate: 0.075, deduction: 169.44 }, + { upTo: 3_751.05, rate: 0.15, deduction: 381.44 }, + { upTo: 4_664.68, rate: 0.225, deduction: 662.77 }, + { upTo: null, rate: 0.275, deduction: 896.0 }, +]; + +export function calcularIRRF(salarioBruto: number, inss: number): number { + const base = salarioBruto - inss; + if (base <= 0) return 0; + + const faixa = IRRF_TABLE.find((f) => f.upTo === null || base <= f.upTo)!; + return parseFloat(Math.max(0, base * faixa.rate - faixa.deduction).toFixed(2)); +} + +export interface ResultadoCalculo { + salarioBruto: number; + descontoINSS: number; + descontoIRRF: number; + totalDescontos: number; + salarioLiquidoCalculado: number; +} + +export function calcularSalarioLiquido(salarioBruto: number): ResultadoCalculo { + const descontoINSS = calcularINSS(salarioBruto); + const descontoIRRF = calcularIRRF(salarioBruto, descontoINSS); + const totalDescontos = parseFloat((descontoINSS + descontoIRRF).toFixed(2)); + const salarioLiquidoCalculado = parseFloat( + (salarioBruto - totalDescontos).toFixed(2), + ); + return { salarioBruto, descontoINSS, descontoIRRF, totalDescontos, salarioLiquidoCalculado }; +} + +export function formatCurrency(value: number): string { + return value.toLocaleString('pt-BR', { + style: 'currency', + currency: 'BRL', + minimumFractionDigits: 2, + }); +} + +export function formatCurrencyCompact(value: number): string { + if (Math.abs(value) >= 1_000) { + return value.toLocaleString('pt-BR', { + style: 'currency', + currency: 'BRL', + minimumFractionDigits: 0, + maximumFractionDigits: 0, + }); + } + return formatCurrency(value); +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..2e9a669 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "expo/tsconfig.base", + "compilerOptions": { + "strict": true, + "paths": { + "@/*": [ + "./src/*" + ], + "@/assets/*": [ + "./assets/*" + ] + } + }, + "include": [ + "**/*.ts", + "**/*.tsx", + ".expo/types/**/*.ts", + "expo-env.d.ts" + ] +} |