From b1400767fe526078f70fe800a88e563b5c02dc5b Mon Sep 17 00:00:00 2001 From: Luna D Dragon Date: Wed, 14 Oct 2026 12:18:46 +0530 Subject: [PATCH] todo: authenticated shit --- touchgrass.app/.prettierrc | 6 + touchgrass.app/app.json | 10 +- .../assets/oauth-client-metadata.json | 29 +-- touchgrass.app/bun.lock | 210 +++++++++++++++--- touchgrass.app/eslint.config.js | 14 +- touchgrass.app/lex.config.ts | 20 +- .../lexicons-src/gay/lunarequest/pubkey.ts | 34 +-- .../gay/lunarequest/touchedgrass.ts | 37 +-- .../gay/lunarequest/touchgrass/pubkey.json | 8 +- .../lunarequest/touchgrass/touchedgrass.json | 8 +- .../{metro.config.js => metro.config.cjs} | 3 +- touchgrass.app/nativewind-env.d.ts | 3 +- touchgrass.app/package.json | 32 ++- touchgrass.app/postcss.config.mjs | 2 +- .../src/app/(authenticated)/_layout.tsx | 12 - .../src/app/(authenticated)/home.tsx | 134 ----------- .../src/app/(authenticated)/logout.tsx | 5 + .../src/app/(authenticated)/scan.tsx | 14 ++ touchgrass.app/src/app/_layout.tsx | 15 +- touchgrass.app/src/app/about.tsx | 33 +++ touchgrass.app/src/app/index.tsx | 94 +++++++- touchgrass.app/src/app/sign-in.tsx | 116 +++++----- touchgrass.app/src/components/BurgerMenu.tsx | 51 +++++ touchgrass.app/src/components/NavBar.tsx | 48 ++++ touchgrass.app/src/components/OAuthForm.tsx | 177 +++++++++++++-- touchgrass.app/src/components/QRcode.tsx | 124 +++++++++++ .../src/components/SessionProvider.tsx | 178 +++++++++++---- .../src/components/TypeAheadResults.tsx | 50 +++++ touchgrass.app/src/components/common/types.ts | 8 + .../gay/lunarequest/touchgrass/pubkey.ts | 48 ++-- .../lunarequest/touchgrass/touchedgrass.ts | 48 ++-- touchgrass.app/src/lib/atproto.ts | 11 +- touchgrass.app/tsconfig.json | 49 +--- 33 files changed, 1128 insertions(+), 503 deletions(-) create mode 100644 touchgrass.app/.prettierrc rename touchgrass.app/{metro.config.js => metro.config.cjs} (81%) delete mode 100644 touchgrass.app/src/app/(authenticated)/_layout.tsx delete mode 100644 touchgrass.app/src/app/(authenticated)/home.tsx create mode 100644 touchgrass.app/src/app/(authenticated)/logout.tsx create mode 100644 touchgrass.app/src/app/(authenticated)/scan.tsx create mode 100644 touchgrass.app/src/app/about.tsx create mode 100644 touchgrass.app/src/components/BurgerMenu.tsx create mode 100644 touchgrass.app/src/components/NavBar.tsx create mode 100644 touchgrass.app/src/components/QRcode.tsx create mode 100644 touchgrass.app/src/components/TypeAheadResults.tsx create mode 100644 touchgrass.app/src/components/common/types.ts diff --git a/touchgrass.app/.prettierrc b/touchgrass.app/.prettierrc new file mode 100644 index 0000000..5af07a2 --- /dev/null +++ b/touchgrass.app/.prettierrc @@ -0,0 +1,6 @@ +{ + "printWidth": 100, + "tabWidth": 2, + "singleQuote": false, + "bracketSameLine": true +} diff --git a/touchgrass.app/app.json b/touchgrass.app/app.json index 4316ac8..a70abeb 100644 --- a/touchgrass.app/app.json +++ b/touchgrass.app/app.json @@ -31,7 +31,15 @@ "imageWidth": 76 } ], - "expo-secure-store" + "expo-secure-store", + [ + "expo-camera", + { + "cameraPermission": "Allow $(PRODUCT_NAME) to access your camera", + "barcodeScannerEnabled": true + } + ], + "@react-native-vector-icons/fontawesome6" ], "experiments": { "typedRoutes": true, diff --git a/touchgrass.app/assets/oauth-client-metadata.json b/touchgrass.app/assets/oauth-client-metadata.json index e0c5e0e..f04e3ed 100644 --- a/touchgrass.app/assets/oauth-client-metadata.json +++ b/touchgrass.app/assets/oauth-client-metadata.json @@ -1,19 +1,12 @@ { - "client_id": "https://touchgrass.lunarequest.gay/oauth-client-metadata.json", - "client_name": "Touch Grass", - "client_uri": "https://touchgrass.lunarequest.gay", - "redirect_uris": [ - "gay.lunarequest.touchgrass:/auth/callback" - ], - "scope": "atproto repo:gay.lunarequest.touchgrass.pubkey repo:gay.lunarequest.touchgrass.touchedgrass", - "token_endpoint_auth_method": "none", - "response_types": [ - "code" - ], - "grant_types": [ - "authorization_code", - "refresh_token" - ], - "application_type": "native", - "dpop_bound_access_tokens": true -} \ No newline at end of file + "client_id": "https://touchgrass.lunarequest.gay/oauth-client-metadata.json", + "client_name": "Touch Grass", + "client_uri": "https://touchgrass.lunarequest.gay", + "redirect_uris": ["gay.lunarequest.touchgrass:/auth/callback"], + "scope": "atproto repo:gay.lunarequest.touchgrass.pubkey repo:gay.lunarequest.touchgrass.touchedgrass", + "token_endpoint_auth_method": "none", + "response_types": ["code"], + "grant_types": ["authorization_code", "refresh_token"], + "application_type": "native", + "dpop_bound_access_tokens": true +} diff --git a/touchgrass.app/bun.lock b/touchgrass.app/bun.lock index 1f56b80..22b3946 100644 --- a/touchgrass.app/bun.lock +++ b/touchgrass.app/bun.lock @@ -5,29 +5,31 @@ "": { "name": "touchgrass.app", "dependencies": { - "@atcute/atproto": "^4.0.4", - "@atcute/client": "^5.1.2", - "@atcute/identity": "^2", - "@atcute/identity-resolver": "^2", "@atcute/lex-cli": "^3.3.0", "@atcute/lexicons": "^2", "@atproto/api": "^0.24.3", + "@atproto/common-web": "^0.5.14", "@atproto/oauth-client-expo": "^0.2.6", - "@expo/ui": "~57.0.22", + "@expo/ui": "~57.0.23", + "@noble/post-quantum": "^0.7.1", + "@react-native-async-storage/async-storage": "2.2.0", + "@react-native-vector-icons/fontawesome6": "^13.1.5", "@react-native/typescript-config": "^0.87.1", "@types/node": "^26.6.4", "core-js": "^3.50.0", - "expo": "^57.0.27", + "expo": "~57.0.28", + "expo-blur": "~57.0.3", + "expo-camera": "~57.0.6", "expo-constants": "~57.0.21", - "expo-dev-client": "~57.0.19", + "expo-dev-client": "~57.0.20", "expo-device": "~57.0.2", "expo-font": "~57.0.4", "expo-glass-effect": "~57.0.4", "expo-image": "~57.0.5", "expo-linking": "~57.0.12", - "expo-router": "~57.0.25", + "expo-router": "~57.0.26", "expo-secure-store": "~57.0.4", - "expo-splash-screen": "~57.0.9", + "expo-splash-screen": "~57.0.10", "expo-status-bar": "~57.0.1", "expo-symbols": "~57.0.3", "expo-system-ui": "~57.0.4", @@ -37,12 +39,17 @@ "react-dom": "19.2.3", "react-native": "0.86.3", "react-native-css": "3.1.0-rc.0", + "react-native-device-info": "^15.0.2", "react-native-gesture-handler": "~2.32.0", + "react-native-get-random-values": "~1.11.0", "react-native-mmkv": "^4.3.2", "react-native-nitro-modules": "^0.37.1", + "react-native-nitro-totp": "^2.0.1", + "react-native-qrcode-svg": "^6.3.26", "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-url-polyfill": "^4.0.0", "react-native-web": "~0.21.0", "react-native-worklets": "0.10.1", @@ -54,8 +61,11 @@ "babel-preset-expo": "^57.0.14", "eslint": "^9", "eslint-config-expo": "~57.0.2", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-prettier": "^5.5.6", "lightningcss": "1.30.1", "postcss": "8.5.29", + "prettier": "^3.9.10", "prettier-plugin-tailwindcss": "^0.5.11", "tailwindcss": "4.1.12", "typescript": "~6.0.3", @@ -71,16 +81,12 @@ "packages": { "@alloc/quick-lru": ["@alloc/quick-lru@5.3.0", "", {}, "sha512-U4+70Pc5ZS9osnCBCE5Jha/ciHM+Yp+CNMNC/7HvYbNRk1Ldd+f7qO65W5qfhu/TCv+/ozljlXXe9Nj8419DMA=="], - "@atcute/atproto": ["@atcute/atproto@4.0.4", "", { "dependencies": { "@atcute/lexicons": "^2.0.3" } }, "sha512-aEp5wQVPVbZcFJUwoi54tyT+ehRI/xtPe9T0zIvcryHAVXF/zxHtNboM+htbZLOAGsDFsqzgCyxph0Bafw7L8w=="], - "@atcute/car": ["@atcute/car@6.1.0", "", { "dependencies": { "@atcute/cbor": "^2.3.8", "@atcute/cid": "^2.5.0", "@atcute/uint8array": "^1.2.0", "@atcute/varint": "^2.0.2" } }, "sha512-Dp7MlyI3YT7NiIUK6bm2ZyA95Pdun+DuFlcr40ZsGdqhOkKrctZT7wMZXSs6IYd7RorjSnddEJDh51hqrkNSPQ=="], "@atcute/cbor": ["@atcute/cbor@2.3.8", "", { "dependencies": { "@atcute/cid": "^2.5.0", "@atcute/multibase": "^1.2.5", "@atcute/uint8array": "^1.2.0" } }, "sha512-gazXBcNTr2U3cRaCjfRbq2GKHJnWapUUA3mgehL+0tbVXEty2wf/LIwF9z46gjqjX2DYGGwkybF8lTI3dzHaNQ=="], "@atcute/cid": ["@atcute/cid@2.5.0", "", { "dependencies": { "@atcute/multibase": "^1.2.5", "@atcute/uint8array": "^1.2.0" } }, "sha512-CAZyzUdaQhuC+S7tGjoC7vgyDI2X4JU+CPO/7WjEU7HlNsAGXjSkD++5TlfnSWGDqUeqpjMZjUfFBZYHKzPHew=="], - "@atcute/client": ["@atcute/client@5.1.2", "", { "dependencies": { "@atcute/identity": "^2.0.2", "@atcute/lexicons": "^2.1.0" } }, "sha512-V3MOJudmmbuiFfrmLR3/ZGA+PKcI4E4ZNEDGKMX/YrvFrHyElD1/gb8NxLesrlIcHefiulqfX9dAl6hOkIt7CA=="], - "@atcute/crypto": ["@atcute/crypto@2.4.4", "", { "dependencies": { "@atcute/multibase": "^1.2.5", "@atcute/uint8array": "^1.1.5", "@noble/secp256k1": "^3.1.0" } }, "sha512-Yc7lXz4ndDjbs+/WrKeGS+sVEr+sx8xi5zSVInKNl0FAEY6KbvcT+bjaU9A3erUVviFp9yEcu/1aSg/f+GPpBg=="], "@atcute/identity": ["@atcute/identity@2.0.2", "", { "dependencies": { "@atcute/lexicons": "^2.0.3", "valibot": "^1.4.2" } }, "sha512-amr/EQceqVtBVmjBK4uUF7nKKYuRttadigpvOcAn4dnO6SNSwSjQi8KDH9LnukEotPsSP4UDsQvNfHWEoUcslw=="], @@ -325,7 +331,7 @@ "@expo-google-fonts/material-symbols": ["@expo-google-fonts/material-symbols@0.4.49", "", {}, "sha512-HtoaXYCk7A9kOjwoxrjq6i0iDtAoQnOPm31zUn+TgmKlHVUU+yyqvQDxN830MvGmBQV8eINv/SK7JRtWhB2xcg=="], - "@expo/cli": ["@expo/cli@57.0.28", "", { "dependencies": { "@expo/code-signing-certificates": "^0.0.6", "@expo/config": "~57.0.10", "@expo/config-plugins": "~57.0.10", "@expo/devcert": "^1.2.1", "@expo/env": "~2.4.3", "@expo/image-utils": "^0.11.6", "@expo/inline-modules": "^0.1.7", "@expo/json-file": "^11.0.1", "@expo/log-box": "^57.0.4", "@expo/metro": "~56.0.2", "@expo/metro-config": "~57.0.13", "@expo/metro-file-map": "^57.0.4", "@expo/osascript": "^2.7.1", "@expo/package-manager": "^1.13.1", "@expo/plist": "^0.8.1", "@expo/prebuild-config": "^57.0.17", "@expo/require-utils": "^57.0.6", "@expo/router-server": "^57.0.12", "@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.3", "accepts": "^1.3.8", "agent-cli-detector": "0.1.7", "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.3", "fetch-nodeshim": "^0.4.10", "getenv": "^2.0.0", "glob": "^13.0.0", "lan-network": "^0.2.1", "multitars": "^1.0.2", "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", "sandbox-cli-detector": "^0.2.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-4969gk/B2JyP3kAv2ftpwU1f9dLG2j9TsQuYCTTjfnyRx0O49Jwu1O1mie2c3HmKXbwfNA6QTS+3i3sNetMTag=="], + "@expo/cli": ["@expo/cli@57.0.29", "", { "dependencies": { "@expo/code-signing-certificates": "^0.0.6", "@expo/config": "~57.0.10", "@expo/config-plugins": "~57.0.10", "@expo/devcert": "^1.2.1", "@expo/env": "~2.4.3", "@expo/image-utils": "^0.11.6", "@expo/inline-modules": "^0.1.8", "@expo/json-file": "^11.0.1", "@expo/log-box": "^57.0.4", "@expo/metro": "~56.0.2", "@expo/metro-config": "~57.0.13", "@expo/metro-file-map": "^57.0.4", "@expo/osascript": "^2.7.1", "@expo/package-manager": "^1.13.1", "@expo/plist": "^0.8.1", "@expo/prebuild-config": "^57.0.18", "@expo/require-utils": "^57.0.6", "@expo/router-server": "^57.0.12", "@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.3", "accepts": "^1.3.8", "agent-cli-detector": "0.1.7", "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.3", "fetch-nodeshim": "^0.4.10", "getenv": "^2.0.0", "glob": "^13.0.0", "lan-network": "^0.2.1", "multitars": "^1.0.2", "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", "sandbox-cli-detector": "^0.2.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-OBmtg+74j6dEEQjKTgRDjQBvLSkKyP2cDTuGIrJTdgG4gZ1HCEBZj18Kyk9UfdYRXgJdixSVAQMCZK6/Q6l2QQ=="], "@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=="], @@ -345,15 +351,15 @@ "@expo/expo-modules-macros-plugin": ["@expo/expo-modules-macros-plugin@0.6.1", "", {}, "sha512-cpsLZE4rqkc1Y3eZTkxB98jrqY1YXgetmtxFt8q89jBRmk3quRuk1BZo+VcnCSObZardjg99r1k5xijEMONFGA=="], - "@expo/fingerprint": ["@expo/fingerprint@0.20.13", "", { "dependencies": { "@expo/env": "^2.4.3", "@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-h1x+w+JpNRu88a/5SMZRzJs9YDGR/f7R8ApCr7OdenhqmJ00hFxQMzvxajDLL+1P2Y2g/ND0xksusqvBqWSW5Q=="], + "@expo/fingerprint": ["@expo/fingerprint@0.20.14", "", { "dependencies": { "@expo/env": "^2.4.3", "@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-7sihStGX1ZepJBNbYgeQY7cU2GQ+PSkSROe3g7JOQqnT6OOuX0rXKY0ZNoVnlB2Y/H5FWnnJ6QrPlK3fNg9+bQ=="], "@expo/image-utils": ["@expo/image-utils@0.11.6", "", { "dependencies": { "@expo/require-utils": "^57.0.6", "@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-rmMpn7QGp6pUGRCQ3vvB9RP/vqq2q/PpToRh4dL/FbhSZOLZ1YTotpuLHf71FGOEfgKil/4PCd3hkWe/CCeiEg=="], - "@expo/inline-modules": ["@expo/inline-modules@0.1.7", "", { "dependencies": { "@expo/config-plugins": "~57.0.9" } }, "sha512-Bz/khd1gIJqDkje7t5ejD5e9jFbm4xEJzWSwRKadRo6gruepbw1xJ3Eb+e58OS8fY1ZNQYjzZbspnuph67sN0g=="], + "@expo/inline-modules": ["@expo/inline-modules@0.1.8", "", { "dependencies": { "@expo/config-plugins": "~57.0.10" } }, "sha512-5OCHzv/VHVuam9UT6/yeArtUnmkp5VdAH6k4JwdRzK/34ukzdjQK7B9n71fiswZKtm2MmZlPuy4hJo2Ao8CZNw=="], "@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.8", "", { "dependencies": { "@expo/config": "~57.0.9", "chalk": "^4.1.2" } }, "sha512-SEdE0pAQrr90bRh3MNR0ZuwoIBw390cYdFgbn7Vk0Mtm9EHaBfP7kYj+2hXnXZJgOEm3/JMtfoD3rV7rWA9FGg=="], + "@expo/local-build-cache-provider": ["@expo/local-build-cache-provider@57.0.9", "", { "dependencies": { "@expo/config": "~57.0.10", "chalk": "^4.1.2" } }, "sha512-hox13/K/dqvKG7StLYs9nwyNR/mJ5ieAkNN8jTee6liMPyUQTfpzgticRyWnVxj49Fr8PpTaQab/ArYVEBJOcQ=="], "@expo/log-box": ["@expo/log-box@57.0.4", "", { "dependencies": { "@expo/dom-webview": "^57.0.1", "anser": "^1.4.9", "stacktrace-parser": "^0.1.10" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-IxwS9s1L2muj8mj8AQSuiy7u8OFJdc02NRFo2me/Tj6DiaeG5SREqmpBE4rQpR2cadqSg5jl8Qab8Cjie616dg=="], @@ -371,7 +377,7 @@ "@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.17", "", { "dependencies": { "@expo/config": "~57.0.10", "@expo/config-plugins": "~57.0.10", "@expo/config-types": "^57.0.2", "@expo/image-utils": "^0.11.6", "@expo/json-file": "^11.0.1", "@react-native/normalize-colors": "0.86.3", "debug": "^4.3.1", "expo-modules-autolinking": "~57.0.14", "resolve-from": "^5.0.0", "semver": "^7.6.0" } }, "sha512-PnPw4QT8afAA1RqTktK89+JpyJz46cZsZx6gEAe6QCHgOHc7dlA0rXlOFy0xbHpBnYT8x7wl6vTz2ydT99gykw=="], + "@expo/prebuild-config": ["@expo/prebuild-config@57.0.18", "", { "dependencies": { "@expo/config": "~57.0.10", "@expo/config-plugins": "~57.0.10", "@expo/config-types": "^57.0.2", "@expo/image-utils": "^0.11.6", "@expo/json-file": "^11.0.1", "@react-native/normalize-colors": "0.86.3", "debug": "^4.3.1", "expo-modules-autolinking": "~57.0.15", "resolve-from": "^5.0.0", "semver": "^7.6.0" } }, "sha512-q/Jijt1H2GT1TlD+C9UOLmErjujjieUs+Rpdo6+L5IBRaW+gXJY0oFqlpyKvOwziQIv4AYL7vZFn6I+OyRgRXQ=="], "@expo/require-utils": ["@expo/require-utils@57.0.6", "", { "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-PKWfFdMgwWrlSP6NGplCi2nK0dEM5MeJ2Cj1ijr5VWTmZ+pKsJsJw2dWkBtlFDyxMY8eUjCPZ7hoqFEnbc0Pcw=="], @@ -385,7 +391,7 @@ "@expo/sudo-prompt": ["@expo/sudo-prompt@9.3.2", "", {}, "sha512-HHQigo3rQWKMDzYDLkubN5WQOYXJJE2eNqIQC2axC2iO3mHdwnIR7FgZVvHWtBwAdzBgAP0ECp8KqS8TiMKvgw=="], - "@expo/ui": ["@expo/ui@57.0.22", "", { "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-v0p397fI7XhYBt+O5Q4MCWKB1lwR8cA2xjoQbc/V6W+EmP9qU1sHh0eQ7QHdeE/lyNjWW4wIut0/H/8OjcHo3w=="], + "@expo/ui": ["@expo/ui@57.0.23", "", { "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-5QW1uzs8cGBlBKQvzNLDmmAeTCiJn4HVCYC2tddyOtXnXsUKGY7Rvgw6otr9Q2rPcOY5mC34wJIspViamvptww=="], "@expo/ws-tunnel": ["@expo/ws-tunnel@2.0.1", "", { "peerDependencies": { "ws": "^8.0.0" } }, "sha512-mljsRffbOHzmSimYQbQu9h9NR3alwCCwEEouRGFL4QRTt8dNvsNtKEPa/5jHmtDLDtsh4xXsWKwzjN9BTpeXHQ=="], @@ -425,6 +431,14 @@ "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.2.5", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.4", "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.4" } }, "sha512-HshSvXzmBxNzqejd3k/KemgQ3hdREUYFRRrgxOZ+gPljDIsO2SDZrVZMd4Z/HsxudQbE62OVyVFE8z9BCurfjA=="], + "@noble/ciphers": ["@noble/ciphers@2.4.0", "", {}, "sha512-AnjFn0Jv92laAkvMrghlFZq4qQCIN/4DxFV/eooqtC2YTjB7kBeLMS2T9KJX4Dn+ZVXLOwK0lSgqDtx9gvxtiw=="], + + "@noble/curves": ["@noble/curves@2.4.0", "", { "dependencies": { "@noble/hashes": "2.4.0" } }, "sha512-P4/62zrgfH33CneE3Dn4WhJVA22YUU0eR51wKIan4NVRvwsA0YnPTwWGpNbpuacSujmSFLvyzpyuR30+fbq2Ew=="], + + "@noble/hashes": ["@noble/hashes@2.4.0", "", {}, "sha512-X5XaVWZIBCT7HHZGm5I7ZQXDwLG+bGXuSrMQAW+7Zvl87h1kmc1ZB1VSRJcpUfoUrGQp4Fkoxm5kZ+Ms+aW+eA=="], + + "@noble/post-quantum": ["@noble/post-quantum@0.7.1", "", { "dependencies": { "@noble/ciphers": "2.4.0", "@noble/curves": "2.4.0", "@noble/hashes": "2.4.0" } }, "sha512-+P9981IiAnVh+rmcubozzVwrEy3XsN/tMhTnvsjV9VDaYpOnNCqWqKo2FLWxbu92YHfjGIlE5XnW175UK+ln+Q=="], + "@noble/secp256k1": ["@noble/secp256k1@3.2.0", "", {}, "sha512-Z3ZAWOTxJ0EuTuZTi7Y69iK7GgrLHh8sgm45lVDhg/b3Nk1TpAiKhick2KkZisHuupeepSkyIydN/J459SdX1w=="], "@nolyfill/is-core-module": ["@nolyfill/is-core-module@1.0.39", "", {}, "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA=="], @@ -437,6 +451,8 @@ "@optique/run": ["@optique/run@1.3.4", "", { "dependencies": { "@optique/core": "1.3.4" } }, "sha512-oyW1b6DIa4Fo/nGKT7Ph/7zsuAE96O08d9dU7BqdJb45m1vrzg4dgMeqLikKhA5jOJ2aIsJhsqKClCmepYHWug=="], + "@pkgr/core": ["@pkgr/core@0.3.6", "", {}, "sha512-SEeaJLb3qBNF/OaXnaR1NmmBbFYk1zC0ZH/52fATcRPLFg/p791YrcyFFy44Bo9sLaGuSuLp5Q6axbb/O+v/RA=="], + "@radix-ui/primitive": ["@radix-ui/primitive@1.1.7", "", {}, "sha512-rqWnm76nYT8HoNNqEjpgJ7Pw/DrBj5iBTrmEPo6HTX5+VJyBNOqTdv4g89G63HuR5g0AaENoAcH7Is5fF2kZ8Q=="], "@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.16", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.5", "@radix-ui/react-context": "1.2.2", "@radix-ui/react-primitive": "2.1.11", "@radix-ui/react-slot": "1.4.0" }, "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-yEQrjfI5eBbeYEJXOASpm+gs9eNHY8+UjkZ81GzcuwdLrSMOlEM8jnGoGdeGo92oiBMkuwZUhHTsnsrDiJLcyA=="], @@ -479,8 +495,14 @@ "@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-async-storage/async-storage": ["@react-native-async-storage/async-storage@2.2.0", "", { "dependencies": { "merge-options": "^3.0.4" }, "peerDependencies": { "react-native": "^0.0.0-0 || >=0.65 <1.0" } }, "sha512-gvRvjR5JAaUZF8tv2Kcq/Gbt3JHwbKFYfmb445rhOj6NUMx3qPLixmDx5pZAyb9at1bYvJ4/eTUipU5aki45xw=="], + "@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-vector-icons/common": ["@react-native-vector-icons/common@13.0.4", "", { "dependencies": { "find-up": "^8.0.0", "picocolors": "^1.1.1", "plist": "^3.1.0" }, "peerDependencies": { "@react-native-vector-icons/get-image": "^13.0.2", "@react-native/assets-registry": "*", "expo-font": "*", "react": "*", "react-native": "*" }, "optionalPeers": ["@react-native-vector-icons/get-image", "@react-native/assets-registry", "expo-font"], "bin": { "rnvi-update-plist": "lib/commonjs/scripts/updatePlist.js" } }, "sha512-1MvNyRf3KIW747rJsmka/+EdEwV92ccVHedEXFV2kQ0lo6D7uvrIBTtffeDidN4//l8+R4bN3IiQv0tXQzaRXQ=="], + + "@react-native-vector-icons/fontawesome6": ["@react-native-vector-icons/fontawesome6@13.1.5", "", { "dependencies": { "@react-native-vector-icons/common": "^13.0.4" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" }, "optionalPeers": ["expo"] }, "sha512-72z/rpMBIE7NZunmlGeKyntfbPxDkPGtQM9V4XVLptwysmx9Jbnc5STN2zKVtPCRWSifykIuiNNAc/yAomIrBg=="], + "@react-native/assets-registry": ["@react-native/assets-registry@0.86.3", "", {}, "sha512-TDhgCZA4wjJg84d5A9swiOQYPIWSKEEVdg9IwMFZDupQzW/F3QoLUrfAJOcalgqTDA9/buTB8awhE3Whwg6u9Q=="], "@react-native/babel-plugin-codegen": ["@react-native/babel-plugin-codegen@0.86.3", "", { "dependencies": { "@babel/traverse": "^7.29.0", "@react-native/codegen": "0.86.3" } }, "sha512-O6Xza4JBGPIU8J7YbKTyBoYL4thpy8jMW/oaLDWdAyOwYHKIjK47pAL5HUEbOe2bWz2PEKjbYRF2ApkJv1ottQ=="], @@ -551,6 +573,8 @@ "@types/debug": ["@types/debug@4.1.13", "", { "dependencies": { "@types/ms": "*" } }, "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw=="], + "@types/emscripten": ["@types/emscripten@1.41.6", "", {}, "sha512-uN+9i8bFT5CUcZfyIEYDrSueACEyKGbUs5kC/72DGlZZoinh84sJfVV0i8UOJD1asdzkvLPBRrKs41kZ8MdEXg=="], + "@types/estree": ["@types/estree@1.0.9", "", {}, "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg=="], "@types/hammerjs": ["@types/hammerjs@2.0.46", "", {}, "sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw=="], @@ -643,7 +667,7 @@ "@unrs/resolver-binding-win32-x64-msvc": ["@unrs/resolver-binding-win32-x64-msvc@1.12.2", "", { "os": "win32", "cpu": "x64" }, "sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA=="], - "@xmldom/xmldom": ["@xmldom/xmldom@0.8.15", "", {}, "sha512-/5NV/vDALVFDXgLmfsy9TRCBlKwO2LNBFzpzvb9iIj+jR+eSc6DLYYvVOdivT/jm7MtU6TebYuRmzEOI7w40UA=="], + "@xmldom/xmldom": ["@xmldom/xmldom@0.9.12", "", {}, "sha512-5AXjrcMClTryPe9LgZrygpB1lj7s0S9E0+W+AHaVKAVyHanafK86iPSvG5xHVSp/jC+VH1UXu0TAEmY279xH7A=="], "abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="], @@ -717,12 +741,16 @@ "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], + "barcode-detector": ["barcode-detector@3.2.2", "", { "dependencies": { "zxing-wasm": "3.1.3" } }, "sha512-/4QOrrNrCRmDSBWiiP4aC72dnkuXUEdcFRidHgbPRXUpy82XcCMvJssI6fEs6JT42LS7DvBVZO70qasJbYKyrA=="], + "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], "baseline-browser-mapping": ["baseline-browser-mapping@2.11.28", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-br0LOmjJqr6Rt4AEkadbcNf67Zpo7EPwKsWbjnRrJIa1QYFHQBqM4C7F2WTbV8ahTEcg1Eo+Y0aWjjORInYFyA=="], "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=="], @@ -807,6 +835,12 @@ "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=="], + "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], "data-view-buffer": ["data-view-buffer@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-data-view": "^1.0.2" } }, "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ=="], @@ -817,6 +851,8 @@ "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + "decamelize": ["decamelize@1.2.0", "", {}, "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA=="], + "decode-uri-component": ["decode-uri-component@0.2.2", "", {}, "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ=="], "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="], @@ -837,10 +873,20 @@ "detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="], + "dijkstrajs": ["dijkstrajs@1.0.3", "", {}, "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA=="], + "dnssd-advertise": ["dnssd-advertise@1.1.6", "", {}, "sha512-Ndrrf6BMPalkQPd/zubL+4YghH2J9NspapQ09uDXwYbvOPkP0oaqf5CkcwJ0b50kS2O3ul6yVu+jz+RY62Cejg=="], "doctrine": ["doctrine@2.1.0", "", { "dependencies": { "esutils": "^2.0.2" } }, "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw=="], + "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=="], + "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], @@ -853,6 +899,8 @@ "enhanced-resolve": ["enhanced-resolve@5.26.0", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.3" } }, "sha512-9vhedylFonb2YGogzUKX6+Ja72gOJbN1QHAqdrvqLwhdl/QWbKopzoUC9EbQNVsAns/bx/4uyqalrQAoy1IByw=="], + "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-abstract": ["es-abstract@1.24.2", "", { "dependencies": { "array-buffer-byte-length": "^1.0.2", "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "data-view-buffer": "^1.0.2", "data-view-byte-length": "^1.0.2", "data-view-byte-offset": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "es-set-tostringtag": "^2.1.0", "es-to-primitive": "^1.3.0", "function.prototype.name": "^1.1.8", "get-intrinsic": "^1.3.0", "get-proto": "^1.0.1", "get-symbol-description": "^1.1.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "internal-slot": "^1.1.0", "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", "is-data-view": "^1.0.2", "is-negative-zero": "^2.0.3", "is-regex": "^1.2.1", "is-set": "^2.0.3", "is-shared-array-buffer": "^1.0.4", "is-string": "^1.1.1", "is-typed-array": "^1.1.15", "is-weakref": "^1.1.1", "math-intrinsics": "^1.1.0", "object-inspect": "^1.13.4", "object-keys": "^1.1.1", "object.assign": "^4.1.7", "own-keys": "^1.0.1", "regexp.prototype.flags": "^1.5.4", "safe-array-concat": "^1.1.3", "safe-push-apply": "^1.0.0", "safe-regex-test": "^1.1.0", "set-proto": "^1.0.0", "stop-iteration-iterator": "^1.1.0", "string.prototype.trim": "^1.2.10", "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", "typed-array-buffer": "^1.0.3", "typed-array-byte-length": "^1.0.3", "typed-array-byte-offset": "^1.0.4", "typed-array-length": "^1.0.7", "unbox-primitive": "^1.1.0", "which-typed-array": "^1.1.19" } }, "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg=="], @@ -883,6 +931,8 @@ "eslint-config-expo": ["eslint-config-expo@57.0.2", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "^8.59.0", "@typescript-eslint/parser": "^8.59.0", "eslint-import-resolver-typescript": "^3.6.3", "eslint-plugin-expo": "^1.1.0", "eslint-plugin-import": "^2.30.0", "eslint-plugin-react": "^7.37.3", "eslint-plugin-react-hooks": "^7.0.0", "globals": "^16.0.0" }, "peerDependencies": { "eslint": ">=8.10" } }, "sha512-dOWkx+MWclLVnYpPPBzas4sfnPaAjk+fe/dbvJSzbWtHUR4fGGaTT/lTcOpxqhwRIlTKKBUYGKude0tcTBsZHg=="], + "eslint-config-prettier": ["eslint-config-prettier@10.1.8", "", { "peerDependencies": { "eslint": ">=7.0.0" }, "bin": { "eslint-config-prettier": "bin/cli.js" } }, "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w=="], + "eslint-import-resolver-node": ["eslint-import-resolver-node@0.3.10", "", { "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.16.1", "resolve": "^2.0.0-next.6" } }, "sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ=="], "eslint-import-resolver-typescript": ["eslint-import-resolver-typescript@3.10.1", "", { "dependencies": { "@nolyfill/is-core-module": "1.0.39", "debug": "^4.4.0", "get-tsconfig": "^4.10.0", "is-bun-module": "^2.0.0", "stable-hash": "^0.0.5", "tinyglobby": "^0.2.13", "unrs-resolver": "^1.6.2" }, "peerDependencies": { "eslint": "*", "eslint-plugin-import": "*", "eslint-plugin-import-x": "*" }, "optionalPeers": ["eslint-plugin-import", "eslint-plugin-import-x"] }, "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ=="], @@ -893,6 +943,8 @@ "eslint-plugin-import": ["eslint-plugin-import@2.32.0", "", { "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", "array.prototype.findlastindex": "^1.2.6", "array.prototype.flat": "^1.3.3", "array.prototype.flatmap": "^1.3.3", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", "eslint-module-utils": "^2.12.1", "hasown": "^2.0.2", "is-core-module": "^2.16.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", "object.fromentries": "^2.0.8", "object.groupby": "^1.0.3", "object.values": "^1.2.1", "semver": "^6.3.1", "string.prototype.trimend": "^1.0.9", "tsconfig-paths": "^3.15.0" }, "peerDependencies": { "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA=="], + "eslint-plugin-prettier": ["eslint-plugin-prettier@5.5.6", "", { "dependencies": { "prettier-linter-helpers": "^1.0.1", "synckit": "^0.11.13" }, "peerDependencies": { "@types/eslint": ">=8.0.0", "eslint": ">=8.0.0", "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", "prettier": ">=3.0.0" }, "optionalPeers": ["@types/eslint", "eslint-config-prettier"] }, "sha512-ifetmTcxWfz+4qRW3pH/ujdTq2jQIj59AxJMIN26K5avYgU8dxycUETQonWiW+wPrYXA0j3Try0l1CnwVQtDqQ=="], + "eslint-plugin-react": ["eslint-plugin-react@7.37.5", "", { "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", "array.prototype.flatmap": "^1.3.3", "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", "es-iterator-helpers": "^1.2.1", "estraverse": "^5.3.0", "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", "object.entries": "^1.1.9", "object.fromentries": "^2.0.8", "object.values": "^1.2.1", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.5", "semver": "^6.3.1", "string.prototype.matchall": "^4.0.12", "string.prototype.repeat": "^1.0.0" }, "peerDependencies": { "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA=="], "eslint-plugin-react-hooks": ["eslint-plugin-react-hooks@7.1.1", "", { "dependencies": { "@babel/core": "^7.24.4", "@babel/parser": "^7.24.4", "hermes-parser": "^0.25.1", "zod": "^3.25.0 || ^4.0.0", "zod-validation-error": "^3.5.0 || ^4.0.0" }, "peerDependencies": { "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0" } }, "sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g=="], @@ -919,17 +971,21 @@ "event-target-shim": ["event-target-shim@5.0.1", "", {}, "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="], - "expo": ["expo@57.0.27", "", { "dependencies": { "@babel/runtime": "^7.20.0", "@expo/cli": "^57.0.28", "@expo/config": "~57.0.10", "@expo/config-plugins": "~57.0.10", "@expo/devtools": "~57.0.1", "@expo/dom-webview": "~57.0.1", "@expo/fingerprint": "^0.20.13", "@expo/local-build-cache-provider": "^57.0.8", "@expo/log-box": "^57.0.4", "@expo/metro": "~56.0.2", "@expo/metro-config": "~57.0.13", "@ungap/structured-clone": "^1.3.0", "babel-preset-expo": "~57.0.14", "expo-asset": "~57.0.19", "expo-constants": "~57.0.21", "expo-file-system": "~57.0.7", "expo-font": "~57.0.4", "expo-keep-awake": "~57.0.2", "expo-modules-autolinking": "~57.0.14", "expo-modules-core": "~57.0.21", "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-Jc3nByHsmzjakvIrqV3/3viVj+jFw1OCfMc+WpClemwL3/hSrS7ktkVCACSTI7/j+1uH+eHmBJwe1kujDLMnbQ=="], + "expo": ["expo@57.0.28", "", { "dependencies": { "@babel/runtime": "^7.20.0", "@expo/cli": "^57.0.29", "@expo/config": "~57.0.10", "@expo/config-plugins": "~57.0.10", "@expo/devtools": "~57.0.1", "@expo/dom-webview": "~57.0.1", "@expo/fingerprint": "^0.20.14", "@expo/local-build-cache-provider": "^57.0.9", "@expo/log-box": "^57.0.4", "@expo/metro": "~56.0.2", "@expo/metro-config": "~57.0.13", "@ungap/structured-clone": "^1.3.0", "babel-preset-expo": "~57.0.15", "expo-asset": "~57.0.19", "expo-constants": "~57.0.21", "expo-file-system": "~57.0.7", "expo-font": "~57.0.4", "expo-keep-awake": "~57.0.2", "expo-modules-autolinking": "~57.0.15", "expo-modules-core": "~57.0.22", "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-Bh9PgT1wLdcSOi8uXvUtHYh12zz9kx3zjD8Pm7O8EAsZW0W42dVog3/UhY2qJnlOkSDpTQJTnX8jsi2J5xn2OA=="], "expo-asset": ["expo-asset@57.0.19", "", { "dependencies": { "@expo/image-utils": "^0.11.6", "expo-constants": "~57.0.21" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-y9ymKidyPBDUFXljbvo7LNgivQvMhEJEoEXi6aLRugUxRDUvAKoZsy+KB5UXSjLMS7l7JNDwYKk5thovI0MLog=="], + "expo-blur": ["expo-blur@57.0.3", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-uyBeJwxIuXzWXXNrnRub5pcF8VzQsiOz0VBTWDpMG2UztmaFyfAz6pI/GCwRtWpHhiOpLoJj79WLdg1GMB+9cg=="], + + "expo-camera": ["expo-camera@57.0.6", "", { "dependencies": { "barcode-detector": "^3.0.0" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*", "react-native-web": "*" }, "optionalPeers": ["react-native-web"] }, "sha512-eswB77bOzQ2OEvll/hV5VnzywaICFnYF21HIwcyokebFcSTSMfGQk8+VW06DRec9JnWuRExs0QXlfxyMPjS6KQ=="], + "expo-constants": ["expo-constants@57.0.21", "", { "dependencies": { "@expo/env": "~2.4.3" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-D5fV2GELYGbNkoiEVZZp5zrUXZDaAx6ZzErDzGirm3jCjOhaE8iU/GyJiB0ZQE+K4Bg8gY82nIQ/RZR8CJLVjA=="], - "expo-dev-client": ["expo-dev-client@57.0.19", "", { "dependencies": { "expo-dev-launcher": "~57.0.20", "expo-dev-menu": "~57.0.18", "expo-dev-menu-interface": "~57.0.0", "expo-manifests": "~57.0.2", "expo-updates-interface": "~57.0.2" }, "peerDependencies": { "expo": "*" } }, "sha512-7giMK6BLL685GECHem2UAQvS473ImZLi5l+Q5tq+XSyv6I9UNVPs0p07mKwgBzq8z7DR3d4nTl702ziFxTjO3Q=="], + "expo-dev-client": ["expo-dev-client@57.0.20", "", { "dependencies": { "expo-dev-launcher": "~57.0.21", "expo-dev-menu": "~57.0.20", "expo-dev-menu-interface": "~57.0.0", "expo-manifests": "~57.0.2", "expo-updates-interface": "~57.0.2" }, "peerDependencies": { "expo": "*" } }, "sha512-ko5FzWsUPuG4aiQfmqxQA5yAdmal6SSICB70KJLChQYzWo+XDoTpXRgEpzQSr1Ku8KyKW0lkEa48xbnKSgd1xQ=="], - "expo-dev-launcher": ["expo-dev-launcher@57.0.20", "", { "dependencies": { "@expo/schema-utils": "^57.0.2", "expo-dev-menu": "~57.0.18", "expo-manifests": "~57.0.2" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-F6oAHaDn9j3L/gyMGE+OalriX6PHZWnZLxpN5jc6crTrp8f6hSwGhmsHpAvdOzijfMjyi3R2UkcISFsCIIQYFA=="], + "expo-dev-launcher": ["expo-dev-launcher@57.0.21", "", { "dependencies": { "@expo/schema-utils": "^57.0.2", "expo-dev-menu": "~57.0.20", "expo-manifests": "~57.0.2" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-dXa1bhCEtSXn4y34rydBvArmoZtcLK7zY0FN3x1JFPTGh81OXUGZWhyzLCAI9nhI23L/MTy7cGCeNyeJmC1ITw=="], - "expo-dev-menu": ["expo-dev-menu@57.0.19", "", { "dependencies": { "expo-dev-menu-interface": "~57.0.0" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-7mE4TytDPgF+a5hisGQKpzd8WfEb7cQOHNARAXSJqogR33qeHVaYfXtsC/DLMV/oAhPr5/rItknT1LyIWbQZUQ=="], + "expo-dev-menu": ["expo-dev-menu@57.0.20", "", { "dependencies": { "expo-dev-menu-interface": "~57.0.0" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-xpf7Rkj++sBA285GqWVJTtl5j/TychD980GKqWA5lVFKM41+xUNmyPMOfO18heAKvX9i620ZHVoHiBGD+6pCdA=="], "expo-dev-menu-interface": ["expo-dev-menu-interface@57.0.0", "", { "peerDependencies": { "expo": "*" } }, "sha512-F47VdzOHYc19FhI/jBgctpO8a5UskTIxG6a1E5t3W5gF8VImuvBQffdXXfLHhsuCl7dS3v3U0R45cleeVXO1Zg=="], @@ -951,19 +1007,19 @@ "expo-manifests": ["expo-manifests@57.0.2", "", { "dependencies": { "expo-json-utils": "~57.0.2" }, "peerDependencies": { "expo": "*" } }, "sha512-pPIIcKR73OShwlWMg8H90WRzKUd2krDdKlKAwuQV1FtUwE7H3hQEFw0ePFQY9yFoGMF/77ryYwNKfI5umMcCog=="], - "expo-modules-autolinking": ["expo-modules-autolinking@57.0.14", "", { "dependencies": { "@expo/require-utils": "^57.0.6", "@expo/spawn-async": "^1.8.0", "chalk": "^4.1.0", "commander": "^7.2.0" }, "bin": { "expo-modules-autolinking": "bin/expo-modules-autolinking.js" } }, "sha512-dWql3NU2tvgfwkdZY3u9Sy3iWRA4IGDk91aOGZAJm3ZqudFxDRzAxlh8oQCVQ81Z+U9VmlUXw/4P9CbL33Ty0A=="], + "expo-modules-autolinking": ["expo-modules-autolinking@57.0.15", "", { "dependencies": { "@expo/require-utils": "^57.0.6", "@expo/spawn-async": "^1.8.0", "chalk": "^4.1.0", "commander": "^7.2.0" }, "bin": { "expo-modules-autolinking": "bin/expo-modules-autolinking.js" } }, "sha512-TY7Sy7MaIBFNMTTsmNtrkdyFwG3abE4gU2WJ6B4Qh9zXOMhtghHvVYTPh9bujHOY/2bscj8dOTqXnZ8iTVtwmg=="], - "expo-modules-core": ["expo-modules-core@57.0.21", "", { "dependencies": { "@expo/expo-modules-macros-plugin": "0.6.1", "expo-modules-jsi": "~57.1.1", "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-g0pf9/tQ6IdJWCzr6PDrEiYT8mTaOhMRnXm3T2XtSzJJaNYgnyyDonkkPN1wd2+PqojIBPhytqqzeLxjM5y/Wg=="], + "expo-modules-core": ["expo-modules-core@57.0.22", "", { "dependencies": { "@expo/expo-modules-macros-plugin": "0.6.1", "expo-modules-jsi": "~57.1.2", "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-IQTSHU690fleLZ6b36OCqt04KFStxA/k7El2vweOWhlFZ58hpNSQMK2Fosc1nIvlOnqqVRDcTAq+prJEOHLmBg=="], - "expo-modules-jsi": ["expo-modules-jsi@57.1.1", "", { "peerDependencies": { "react-native": "*" } }, "sha512-ssnwz3ZuIgCbZj5A3J6NlhQrXZojg+BjkeWrOWqVJhyMHlV/A/cRT7s986chKku97BFt6ucmDu6/BCzrV45Wcw=="], + "expo-modules-jsi": ["expo-modules-jsi@57.1.2", "", { "peerDependencies": { "react-native": "*" } }, "sha512-DYhBwO0fqcKIUma4jF16zRDP/m6ZbawEZbo4eX3gdekREIFqrrz8HKWXydgNUqOyOQcUkdrkZatxi2I9+V6E8g=="], - "expo-router": ["expo-router@57.0.25", "", { "dependencies": { "@expo/log-box": "^57.0.4", "@expo/metro-runtime": "^57.0.16", "@expo/schema-utils": "^57.0.2", "@expo/ui": "^57.0.22", "@radix-ui/react-slot": "^1.2.0", "@radix-ui/react-tabs": "^1.1.12", "@react-native-masked-view/masked-view": "^0.3.2", "client-only": "^0.0.1", "color": "^4.2.3", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", "expo-glass-effect": "^57.0.4", "expo-server": "^57.0.3", "expo-symbols": "^57.0.3", "fast-deep-equal": "^3.1.3", "invariant": "^2.2.4", "nanoid": "^3.3.18", "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.21", "expo-linking": "^57.0.12", "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-S/xWUGeVqMozG8gFJT0CHOVErZEbQnsAEAqlBIvHJSUZPH0hBcxy2kduUrV7ZDLNI4xCPIlOJ4SI29X/1z/hxw=="], + "expo-router": ["expo-router@57.0.26", "", { "dependencies": { "@expo/log-box": "^57.0.4", "@expo/metro-runtime": "^57.0.16", "@expo/schema-utils": "^57.0.2", "@expo/ui": "^57.0.23", "@radix-ui/react-slot": "^1.2.0", "@radix-ui/react-tabs": "^1.1.12", "@react-native-masked-view/masked-view": "^0.3.2", "client-only": "^0.0.1", "color": "^4.2.3", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", "expo-glass-effect": "^57.0.4", "expo-server": "^57.0.3", "expo-symbols": "^57.0.3", "fast-deep-equal": "^3.1.3", "invariant": "^2.2.4", "nanoid": "^3.3.18", "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.21", "expo-linking": "^57.0.12", "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-iSF+LEbbvGkYGA2j8qWvF1woxrA7EWHZF+SNdTPR7dmi6myPOJsDGdwfWlXA74Gns8T7AuyfuDsxIsqEJ45BhQ=="], "expo-secure-store": ["expo-secure-store@57.0.4", "", { "peerDependencies": { "expo": "*" } }, "sha512-7zBA1RThURTXdP4w65kBzZNbcSsfArqVd+p+ETAnPRWXO8J296Qd0YaCVyRpJ0HSwlCnGdvOnqO+NgSreHsOhA=="], "expo-server": ["expo-server@57.0.3", "", {}, "sha512-aK+LdKzauHSGmsOStZtyxdzv0zWssCkxTw3m4QuOhfDSJsZaMRTd9O41d8ixU/QfELTbaJ0oRNcF7JFV/7O9YQ=="], - "expo-splash-screen": ["expo-splash-screen@57.0.9", "", { "dependencies": { "@expo/config-plugins": "~57.0.9", "@expo/image-utils": "^0.11.5", "xml2js": "0.6.0" }, "peerDependencies": { "expo": "*" } }, "sha512-7cKDn7uBwg0RkcmY015/5j9st4msWJ4zQiPmQdVZoppW3cFSbv05n7xhM6CjUU466Tx4VRTqDF21HuIHkmnEtA=="], + "expo-splash-screen": ["expo-splash-screen@57.0.10", "", { "dependencies": { "@expo/config-plugins": "~57.0.10", "@expo/image-utils": "^0.11.6", "xml2js": "0.6.0" }, "peerDependencies": { "expo": "*" } }, "sha512-W7++tMiyVMviWPTvaTXKpcOwwu5SbriwA2n0ewEhC+ic1LFaUNTUXiIXr95MVMSHaLRgtIG9dGyCTCb+NkekkA=="], "expo-status-bar": ["expo-status-bar@57.0.1", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-Xwaq1gAoVRWx5dPG5VhT5RSbnI9OilhZnO5qoPBnUaBAa5VzRzfdS8q0/bsPt0jR2DKLtGuP0bQ6efMJ4RIMDg=="], @@ -977,8 +1033,12 @@ "exponential-backoff": ["exponential-backoff@3.1.3", "", {}, "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA=="], + "fast-base64-decode": ["fast-base64-decode@1.0.0", "", {}, "sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q=="], + "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], + "fast-diff": ["fast-diff@1.3.0", "", {}, "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw=="], + "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="], "fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="], @@ -1143,6 +1203,8 @@ "is-number-object": ["is-number-object@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" } }, "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw=="], + "is-plain-obj": ["is-plain-obj@2.1.0", "", {}, "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA=="], + "is-regex": ["is-regex@1.2.1", "", { "dependencies": { "call-bound": "^1.0.2", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g=="], "is-set": ["is-set@2.0.3", "", {}, "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg=="], @@ -1259,8 +1321,12 @@ "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], + "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-options": ["merge-options@3.0.4", "", { "dependencies": { "is-plain-obj": "^2.1.0" } }, "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ=="], + "merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="], "metro": ["metro@0.84.5", "", { "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", "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.5", "metro-cache": "0.84.5", "metro-cache-key": "0.84.5", "metro-config": "0.84.5", "metro-core": "0.84.5", "metro-file-map": "0.84.5", "metro-resolver": "0.84.5", "metro-runtime": "0.84.5", "metro-source-map": "0.84.5", "metro-symbolicate": "0.84.5", "metro-transform-plugins": "0.84.5", "metro-transform-worker": "0.84.5", "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-r1liLkyFZMVSEMNjU1CJU5pRzs3NdkxHqXS60O25c0rCIqAR+cGk7rPydw/g0WAIKVXojIBIF45yYBPagJGcgw=="], @@ -1339,6 +1405,8 @@ "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.6", "", { "dependencies": { "flow-enums-runtime": "^0.0.6" } }, "sha512-+s+6zjd0X68hfAcn92NsEPXnSYOF3O7exw/Fj4UfRTB+UL+Tdjdkzu5/4WquXlzqgvNm8FWuuW6/0Yd8S2rYxw=="], @@ -1377,6 +1445,8 @@ "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="], + "p-try": ["p-try@2.2.0", "", {}, "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="], + "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], "parse-png": ["parse-png@2.1.0", "", { "dependencies": { "pngjs": "^3.3.0" } }, "sha512-Nt/a5SfCLiTnQAjx3fHlqp8hRgTL3z7kTQZzvIMS9uCAepnCyjpdEc6M/sz69WqMBdaDBw9sF1F1UaHROYzGkQ=="], @@ -1397,7 +1467,7 @@ "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=="], + "pngjs": ["pngjs@5.0.0", "", {}, "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw=="], "possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="], @@ -1409,6 +1479,8 @@ "prettier": ["prettier@3.9.10", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-skGHTH1Yb9QvaTC4hWnRTzEYtCpApF0UMBPz+t/0ZPzP8ihefo/btKd+QA7pUE0fEwA1SbS/NmhyEcstdXOIdA=="], + "prettier-linter-helpers": ["prettier-linter-helpers@1.0.1", "", { "dependencies": { "fast-diff": "^1.1.2" } }, "sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg=="], + "prettier-plugin-tailwindcss": ["prettier-plugin-tailwindcss@0.5.14", "", { "peerDependencies": { "@ianvs/prettier-plugin-sort-imports": "*", "@prettier/plugin-pug": "*", "@shopify/prettier-plugin-liquid": "*", "@trivago/prettier-plugin-sort-imports": "*", "@zackad/prettier-plugin-twig-melody": "*", "prettier": "^3.0", "prettier-plugin-astro": "*", "prettier-plugin-css-order": "*", "prettier-plugin-import-sort": "*", "prettier-plugin-jsdoc": "*", "prettier-plugin-marko": "*", "prettier-plugin-organize-attributes": "*", "prettier-plugin-organize-imports": "*", "prettier-plugin-sort-imports": "*", "prettier-plugin-style-order": "*", "prettier-plugin-svelte": "*" }, "optionalPeers": ["@ianvs/prettier-plugin-sort-imports", "@prettier/plugin-pug", "@shopify/prettier-plugin-liquid", "@trivago/prettier-plugin-sort-imports", "@zackad/prettier-plugin-twig-melody", "prettier-plugin-astro", "prettier-plugin-css-order", "prettier-plugin-import-sort", "prettier-plugin-jsdoc", "prettier-plugin-marko", "prettier-plugin-organize-attributes", "prettier-plugin-organize-imports", "prettier-plugin-sort-imports", "prettier-plugin-style-order", "prettier-plugin-svelte"] }, "sha512-Puaz+wPUAhFp8Lo9HuciYKM2Y2XExESjeT+9NQoVFXZsPPnc9VYss2SpxdQ6vbatmt8/4+SN0oe0I1cPDABg9Q=="], "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=="], @@ -1425,6 +1497,8 @@ "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], + "qrcode": ["qrcode@1.5.4", "", { "dependencies": { "dijkstrajs": "^1.0.1", "pngjs": "^5.0.0", "yargs": "^15.3.1" }, "bin": { "qrcode": "bin/qrcode" } }, "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg=="], + "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=="], "range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="], @@ -1445,22 +1519,32 @@ "react-native-css": ["react-native-css@3.1.0-rc.0", "", { "dependencies": { "@types/debug": "^4.1.12", "babel-plugin-react-compiler": "^19.1.0-rc.2", "colorjs.io": "0.7.0", "comment-json": "^4.2.5", "debug": "^4.4.1" }, "peerDependencies": { "@expo/metro-config": ">=54", "lightningcss": ">=1.27.0", "react": ">=19", "react-native": ">=0.81" } }, "sha512-/wfPJ8pXiPxvHUs0QcocN3ViV4QJdnXpKukNirZJcJ/MeZKrStSEHm2rBq+KuZm8/2XDl4GfeuaVvJctYGtdgA=="], + "react-native-device-info": ["react-native-device-info@15.0.2", "", { "peerDependencies": { "react-native": "*" } }, "sha512-dd71eXG2l3Cwp66IvKNadMTB8fhU3PEjyVddI97sYan+D4bgIAUmgGDhbSOFvHcGavksb2U17kiQYaDiK2WK2g=="], + "react-native-drawer-layout": ["react-native-drawer-layout@4.2.11", "", { "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-Aua+LAZJ6L3v7ESHsNtxN2sO+hFQKsSz3EDKOLIpWni6PdQEJGFT0Mc2UnEsvFdfV743aHfODTAaHxsJ2D0uFw=="], "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-get-random-values": ["react-native-get-random-values@1.11.0", "", { "dependencies": { "fast-base64-decode": "^1.0.0" }, "peerDependencies": { "react-native": ">=0.56" } }, "sha512-4BTbDbRmS7iPdhYLRcz3PGFIpFJBwNZg9g42iwa2P6FOv9vZj/xJc678RZXnLNZzd0qd7Q3CCF6Yd+CU2eoXKQ=="], + "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-mmkv": ["react-native-mmkv@4.3.2", "", { "peerDependencies": { "react": "*", "react-native": "*", "react-native-nitro-modules": "*" } }, "sha512-49OAyfkg0/TMWiWELZN6VuVQPZPhizwL4DTmp8b7B1md3dB/s3LH3mGfC3T+lp9W0y/rqxZMEnotLFTIbOAenQ=="], "react-native-nitro-modules": ["react-native-nitro-modules@0.37.1", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-KpW6EQVQ/bfegpCGxN9Be+ndvsfj56t4IESEvCASu9gWpJa/NDfHpIeIwCOvZQ3eXmLEj6YD4wCLqcC1FJPr2w=="], + "react-native-nitro-totp": ["react-native-nitro-totp@2.0.1", "", { "peerDependencies": { "react": "*", "react-native": "*", "react-native-nitro-modules": "^0.29.6" } }, "sha512-E/B/qsIMzwifiypR+bJZ8v6VMMH5n/1kHWTyPr+x/ne7XyPHPx/7KEH7RMPBqw/kWDf/KfwEbb66xVstOE9IkA=="], + + "react-native-qrcode-svg": ["react-native-qrcode-svg@6.3.26", "", { "dependencies": { "prop-types": "^15.8.0", "qrcode": "^1.5.4", "text-encoding": "^0.7.0" }, "peerDependencies": { "react": "*", "react-native": ">=0.63.4", "react-native-svg": ">=14.0.0" } }, "sha512-xhQywklf0qh5Z9ooy2rEuCrv6tRksVAeFUdYgv5y3fUkwQN53yp2Iu49QTgxj8QyjFgo0fYwee+knBBDzbNH+g=="], + "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-url-polyfill": ["react-native-url-polyfill@4.0.0", "", { "peerDependencies": { "react-native": "*" } }, "sha512-eqYM3wBAA0eL1sPYbBAoNfbES3+NkgcxUdelQ7QzmoVtqKB5qGG0U13MPTRUroAWK+y2EoJFS3MZUK0fwTf0pA=="], "react-native-web": ["react-native-web@0.21.4", "", { "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-77B6KlalB4osNIck91TNFixPkYPsTbuNEvw8P7IV+4v4/5wZSBRKZnw0Zhx6YjuauDTz71gc8IW+fVhcBMjr5A=="], @@ -1493,6 +1577,8 @@ "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], + "require-main-filename": ["require-main-filename@2.0.0", "", {}, "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="], + "resolve": ["resolve@2.0.0-next.7", "", { "dependencies": { "es-errors": "^1.3.0", "is-core-module": "^2.16.2", "node-exports-info": "^1.6.0", "object-keys": "^1.1.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ=="], "resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="], @@ -1527,6 +1613,8 @@ "server-only": ["server-only@0.0.1", "", {}, "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA=="], + "set-blocking": ["set-blocking@2.0.0", "", {}, "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="], + "set-function-length": ["set-function-length@1.2.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2" } }, "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg=="], "set-function-name": ["set-function-name@2.0.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", "has-property-descriptors": "^1.0.2" } }, "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ=="], @@ -1617,6 +1705,10 @@ "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], + "synckit": ["synckit@0.11.13", "", { "dependencies": { "@pkgr/core": "^0.3.6" } }, "sha512-eNRKgb3z66Yp3D2CixVujOUvXLFUTij/zVnV8KRyvFdQwpz7I5DS8UfRkTeLzb64u+dkzDSdelE24izu+zSSUg=="], + + "tagged-tag": ["tagged-tag@1.0.0", "", {}, "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng=="], + "tailwindcss": ["tailwindcss@4.1.12", "", {}, "sha512-DzFtxOi+7NsFf7DBtI3BJsynR+0Yp6etH+nRPTbpWnS2pZBaSksv/JGctNwSWzbFjp0vxSqknaUylseZqMDGrA=="], "tailwindcss-safe-area": ["tailwindcss-safe-area@1.3.0", "", { "peerDependencies": { "tailwindcss": "^4.0.0" } }, "sha512-RoxnW1zAjBWC3XK+row7Qj5toRMRlKNN/p3FLXb6fTGKxDGWT6JP/mcNX1yf09xRficQ308hbwiedgniepSp1Q=="], @@ -1629,6 +1721,8 @@ "terser": ["terser@5.51.2", "", { "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-bWnjSNscmuI+GJze6ZupnHP8G/cTcsJF+bXCeQknk2SHQsgbNJnLrqiH9jZ2W4STPVXH2mDKKRX3iwPhc9Cn/Q=="], + "text-encoding": ["text-encoding@0.7.0", "", {}, "sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA=="], + "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=="], @@ -1681,6 +1775,8 @@ "unicode-segmenter": ["unicode-segmenter@0.17.3", "", {}, "sha512-hKZwqBjJDmqNrq1+LjDxck1qLzJFcLLJM2Xq92ORRHOuau6GSHeELmn+uyk6zNH1CK9mogrUJGP9WJCJUQXMAw=="], + "unicorn-magic": ["unicorn-magic@0.3.0", "", {}, "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA=="], + "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="], "unrs-resolver": ["unrs-resolver@1.12.2", "", { "dependencies": { "napi-postinstall": "^0.3.4" }, "optionalDependencies": { "@unrs/resolver-binding-android-arm-eabi": "1.12.2", "@unrs/resolver-binding-android-arm64": "1.12.2", "@unrs/resolver-binding-darwin-arm64": "1.12.2", "@unrs/resolver-binding-darwin-x64": "1.12.2", "@unrs/resolver-binding-freebsd-x64": "1.12.2", "@unrs/resolver-binding-linux-arm-gnueabihf": "1.12.2", "@unrs/resolver-binding-linux-arm-musleabihf": "1.12.2", "@unrs/resolver-binding-linux-arm64-gnu": "1.12.2", "@unrs/resolver-binding-linux-arm64-musl": "1.12.2", "@unrs/resolver-binding-linux-loong64-gnu": "1.12.2", "@unrs/resolver-binding-linux-loong64-musl": "1.12.2", "@unrs/resolver-binding-linux-ppc64-gnu": "1.12.2", "@unrs/resolver-binding-linux-riscv64-gnu": "1.12.2", "@unrs/resolver-binding-linux-riscv64-musl": "1.12.2", "@unrs/resolver-binding-linux-s390x-gnu": "1.12.2", "@unrs/resolver-binding-linux-x64-gnu": "1.12.2", "@unrs/resolver-binding-linux-x64-musl": "1.12.2", "@unrs/resolver-binding-openharmony-arm64": "1.12.2", "@unrs/resolver-binding-wasm32-wasi": "1.12.2", "@unrs/resolver-binding-win32-arm64-msvc": "1.12.2", "@unrs/resolver-binding-win32-ia32-msvc": "1.12.2", "@unrs/resolver-binding-win32-x64-msvc": "1.12.2" } }, "sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ=="], @@ -1731,6 +1827,8 @@ "which-collection": ["which-collection@1.0.2", "", { "dependencies": { "is-map": "^2.0.3", "is-set": "^2.0.3", "is-weakmap": "^2.0.2", "is-weakset": "^2.0.3" } }, "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw=="], + "which-module": ["which-module@2.0.1", "", {}, "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ=="], + "which-typed-array": ["which-typed-array@1.1.24", "", { "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.9", "call-bound": "^1.0.4", "for-each": "^0.3.5", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" } }, "sha512-wk4Mf4pR5mRP7eYuuTBCIQ9d0ud2Fv2jRLQpfgnRjbOxAFHmjKFValgTpitVKzJJS8ajnYQV2Du1SZ8j6b/EUQ=="], "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="], @@ -1761,6 +1859,8 @@ "zod-validation-error": ["zod-validation-error@4.0.2", "", { "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" } }, "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ=="], + "zxing-wasm": ["zxing-wasm@3.1.3", "", { "dependencies": { "@types/emscripten": "^1.41.5", "type-fest": "^5.8.0" } }, "sha512-3lC9BJk4fR5ZJxcGjb0hVnDFOW7KpLXHIebiBmVd4FDRQZVeObztoTKxRUPxlWwSgxrMRONK0u50hBD1aTYEKg=="], + "@atproto-labs/simple-store-memory/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], "@atproto/lex-data/unicode-segmenter": ["unicode-segmenter@0.14.5", "", {}, "sha512-jHGmj2LUuqDcX3hqY12Ql+uhUTn8huuxNZGq7GvtF6bSybzH3aFgedYu/KTzQStEgt1Ra2F3HxadNXsNjb3m3g=="], @@ -1793,10 +1893,14 @@ "@expo/metro-config/hermes-parser": ["hermes-parser@0.36.1", "", { "dependencies": { "hermes-estree": "0.36.1" } }, "sha512-GApNk4zLHi2UWoWZZkx7LNCOSzLSc5lB55pZ/PhK7ycFeg7u5LcF88p/WbpIi1XUDtE0MpHE3uRR3u3KB7TjSQ=="], + "@expo/plist/@xmldom/xmldom": ["@xmldom/xmldom@0.8.15", "", {}, "sha512-/5NV/vDALVFDXgLmfsy9TRCBlKwO2LNBFzpzvb9iIj+jR+eSc6DLYYvVOdivT/jm7MtU6TebYuRmzEOI7w40UA=="], + "@expo/plist/xmlbuilder": ["xmlbuilder@15.1.1", "", {}, "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="], "@expo/ws-tunnel/ws": ["ws@8.22.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-Ydggc987+RO0AnWtZ/7Wq9FtNvcrL1b/RO0ud9mWjUPgDrsAAwQSF51sm2hm1XofbU/4jkpGEsLFsZZxU+1DOg=="], + "@react-native-vector-icons/common/find-up": ["find-up@8.0.0", "", { "dependencies": { "locate-path": "^8.0.0", "unicorn-magic": "^0.3.0" } }, "sha512-JGG8pvDi2C+JxidYdIwQDyS/CgcrIdh18cvgxcBge3wSHRQOrooMD3GlFBcmMJAN9M42SAZjDp5zv1dglJjwww=="], + "@react-native/babel-preset/@react-native/babel-plugin-codegen": ["@react-native/babel-plugin-codegen@0.87.1", "", { "dependencies": { "@babel/traverse": "^7.29.0", "@react-native/codegen": "0.87.1" } }, "sha512-DfnyLAHG7jH4pqeID7ib6AeD6gG8T+KvM3c/w/yEa5ONkfRcHvTC8JMIRdhUqs4ruA+8xbYcNVQzewYRCPm1Xw=="], "@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=="], @@ -1839,6 +1943,8 @@ "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=="], + "eslint-import-resolver-node/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="], "eslint-module-utils/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="], @@ -1851,6 +1957,8 @@ "eslint-plugin-react-hooks/hermes-parser": ["hermes-parser@0.25.1", "", { "dependencies": { "hermes-estree": "0.25.1" } }, "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA=="], + "expo/babel-preset-expo": ["babel-preset-expo@57.0.15", "", { "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.3", "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.24", "react-refresh": ">=0.14.0 <1.0.0" }, "optionalPeers": ["@babel/runtime", "expo", "expo-widgets"] }, "sha512-GIJZeeBlDAO753yBaslD5wkElbB1//D0oRanc7ncahXDD0cBizIznJDNm1cKgVxcMaVZFacdozSa8jFHV1YJfQ=="], + "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=="], @@ -1911,9 +2019,9 @@ "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.3", "", {}, "sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg=="], + "parse-png/pngjs": ["pngjs@3.4.0", "", {}, "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w=="], - "plist/@xmldom/xmldom": ["@xmldom/xmldom@0.9.12", "", {}, "sha512-5AXjrcMClTryPe9LgZrygpB1lj7s0S9E0+W+AHaVKAVyHanafK86iPSvG5xHVSp/jC+VH1UXu0TAEmY279xH7A=="], + "path-scurry/lru-cache": ["lru-cache@11.5.3", "", {}, "sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg=="], "plist/xmlbuilder": ["xmlbuilder@15.1.1", "", {}, "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="], @@ -1923,6 +2031,8 @@ "prop-types/react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="], + "qrcode/yargs": ["yargs@15.4.1", "", { "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", "find-up": "^4.1.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^18.1.2" } }, "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A=="], + "react-native-css/babel-plugin-react-compiler": ["babel-plugin-react-compiler@19.1.0-rc.1-rc-af1b7da-20250421", "", { "dependencies": { "@babel/types": "^7.26.0" } }, "sha512-E3kaokBhWDLf7ZD8fuYjYn0ZJHYZ+3EHtAWCdX2hl4lpu1z9S/Xr99sxhx2bTCVB41oIesz9FtM8f4INsrZaOw=="], "react-native-web/@react-native/normalize-colors": ["@react-native/normalize-colors@0.74.89", "", {}, "sha512-qoMMXddVKVhZ8PA1AbUCk83trpd6N+1nF2A6k1i6LsQObyS92fELuk8kU/lQs6M7BsMHwqyLCpQJ1uFgNvIQXg=="], @@ -1945,12 +2055,16 @@ "wrap-ansi/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + "zxing-wasm/type-fest": ["type-fest@5.10.0", "", { "dependencies": { "tagged-tag": "^1.0.0" } }, "sha512-NoSdpq/WEiAg5sjmBkmV/hfxv6HJH4NqPNrqjtSO5CwRmpsDfaf4begxW34KdJykH/l1yHtwBWQkCRdoXO8mPA=="], + "@expo/fingerprint/minimatch/brace-expansion": ["brace-expansion@5.0.12", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ=="], "@expo/metro-config/hermes-parser/hermes-estree": ["hermes-estree@0.36.1", "", {}, "sha512-guv1nQ6IJ7S83NRFPWc3SA7IBZrdNC9kapwOq6uXvF4wP+sDCgjzQbKPCoyYmoyZRzztF/n/c36l/rccCZSiCw=="], "@expo/metro/metro-source-map/ob1": ["ob1@0.84.5", "", { "dependencies": { "flow-enums-runtime": "^0.0.6" } }, "sha512-aH9RkoZc7w/90HBamFxTw8ZLFr05wXS+iOnvmrgo53Ep8Pyrm5FieQSaPIVROkfFVQISeD/zo92fes26TOwe+A=="], + "@react-native-vector-icons/common/find-up/locate-path": ["locate-path@8.0.0", "", { "dependencies": { "p-locate": "^6.0.0" } }, "sha512-XT9ewWAC43tiAV7xDAPflMkG0qOPn2QjHqlgX8FOqmWa/rxnyYDulF9T0F7tRy1u+TVTmK/M//6VIOye+2zDXg=="], + "@react-native/babel-preset/@react-native/babel-plugin-codegen/@react-native/codegen": ["@react-native/codegen@0.87.1", "", { "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-qbaqEdlUfj2vRgvWTpMoNgHnEqAhAYJLUrpGkb0WC9n0kdtqUvgigpz4bDktZwolM9BemXwgGFgyiAnbs3t0xw=="], "@react-native/babel-preset/babel-plugin-syntax-hermes-parser/hermes-parser": ["hermes-parser@0.36.1", "", { "dependencies": { "hermes-estree": "0.36.1" } }, "sha512-GApNk4zLHi2UWoWZZkx7LNCOSzLSc5lB55pZ/PhK7ycFeg7u5LcF88p/WbpIi1XUDtE0MpHE3uRR3u3KB7TjSQ=="], @@ -1971,6 +2085,8 @@ "eslint-plugin-react-hooks/hermes-parser/hermes-estree": ["hermes-estree@0.25.1", "", {}, "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw=="], + "expo/babel-preset-expo/babel-plugin-syntax-hermes-parser": ["babel-plugin-syntax-hermes-parser@0.36.1", "", { "dependencies": { "hermes-parser": "0.36.1" } }, "sha512-ycduwJbvdvIMmVvlAZqGggS+pm5Eu4Bk9pcV9Sm2Z4PJNRVsKkv0g7vHj+LeuC1gHTeF67sJXFOq61IlqCa2hA=="], + "finalhandler/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], "glob/minimatch/brace-expansion": ["brace-expansion@5.0.12", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ=="], @@ -2003,10 +2119,20 @@ "ora/chalk/supports-color": ["supports-color@5.5.0", "", { "dependencies": { "has-flag": "^3.0.0" } }, "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="], + "qrcode/yargs/cliui": ["cliui@6.0.0", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^6.2.0" } }, "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ=="], + + "qrcode/yargs/find-up": ["find-up@4.1.0", "", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="], + + "qrcode/yargs/y18n": ["y18n@4.0.3", "", {}, "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="], + + "qrcode/yargs/yargs-parser": ["yargs-parser@18.1.3", "", { "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" } }, "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ=="], + "send/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], "@expo/fingerprint/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + "@react-native-vector-icons/common/find-up/locate-path/p-locate": ["p-locate@6.0.0", "", { "dependencies": { "p-limit": "^4.0.0" } }, "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw=="], + "@react-native/babel-preset/@react-native/babel-plugin-codegen/@react-native/codegen/hermes-parser": ["hermes-parser@0.36.1", "", { "dependencies": { "hermes-estree": "0.36.1" } }, "sha512-GApNk4zLHi2UWoWZZkx7LNCOSzLSc5lB55pZ/PhK7ycFeg7u5LcF88p/WbpIi1XUDtE0MpHE3uRR3u3KB7TjSQ=="], "@react-native/babel-preset/babel-plugin-syntax-hermes-parser/hermes-parser/hermes-estree": ["hermes-estree@0.36.1", "", {}, "sha512-guv1nQ6IJ7S83NRFPWc3SA7IBZrdNC9kapwOq6uXvF4wP+sDCgjzQbKPCoyYmoyZRzztF/n/c36l/rccCZSiCw=="], @@ -2035,6 +2161,8 @@ "@typescript-eslint/typescript-estree/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + "expo/babel-preset-expo/babel-plugin-syntax-hermes-parser/hermes-parser": ["hermes-parser@0.36.1", "", { "dependencies": { "hermes-estree": "0.36.1" } }, "sha512-GApNk4zLHi2UWoWZZkx7LNCOSzLSc5lB55pZ/PhK7ycFeg7u5LcF88p/WbpIi1XUDtE0MpHE3uRR3u3KB7TjSQ=="], + "glob/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], "log-symbols/chalk/ansi-styles/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="], @@ -2045,6 +2173,16 @@ "ora/chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="], + "qrcode/yargs/cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "qrcode/yargs/cliui/wrap-ansi": ["wrap-ansi@6.2.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA=="], + + "qrcode/yargs/find-up/locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="], + + "qrcode/yargs/yargs-parser/camelcase": ["camelcase@5.3.1", "", {}, "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="], + + "@react-native-vector-icons/common/find-up/locate-path/p-locate/p-limit": ["p-limit@4.0.0", "", { "dependencies": { "yocto-queue": "^1.0.0" } }, "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ=="], + "@react-native/babel-preset/@react-native/babel-plugin-codegen/@react-native/codegen/hermes-parser/hermes-estree": ["hermes-estree@0.36.1", "", {}, "sha512-guv1nQ6IJ7S83NRFPWc3SA7IBZrdNC9kapwOq6uXvF4wP+sDCgjzQbKPCoyYmoyZRzztF/n/c36l/rccCZSiCw=="], "@react-native/metro-config/metro-config/metro/accepts/negotiator": ["negotiator@1.1.0", "", { "dependencies": { "content-type": "^2.1.0" } }, "sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg=="], @@ -2055,8 +2193,16 @@ "@react-native/metro-config/metro-config/metro/mime-types/mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], + "expo/babel-preset-expo/babel-plugin-syntax-hermes-parser/hermes-parser/hermes-estree": ["hermes-estree@0.36.1", "", {}, "sha512-guv1nQ6IJ7S83NRFPWc3SA7IBZrdNC9kapwOq6uXvF4wP+sDCgjzQbKPCoyYmoyZRzztF/n/c36l/rccCZSiCw=="], + "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=="], + + "qrcode/yargs/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="], + + "@react-native-vector-icons/common/find-up/locate-path/p-locate/p-limit/yocto-queue": ["yocto-queue@1.2.2", "", {}, "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ=="], + + "qrcode/yargs/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="], } } diff --git a/touchgrass.app/eslint.config.js b/touchgrass.app/eslint.config.js index 9d86e68..2ace5eb 100644 --- a/touchgrass.app/eslint.config.js +++ b/touchgrass.app/eslint.config.js @@ -1,10 +1,16 @@ // https://docs.expo.dev/guides/using-eslint/ -import { defineConfig } from 'eslint/config'; -import expoConfig from 'eslint-config-expo/flat.js'; +import expoConfig from "eslint-config-expo/flat.js"; +import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended"; +import { defineConfig } from "eslint/config"; export default defineConfig([ expoConfig, + eslintPluginPrettierRecommended, { - ignores: ["dist/*"], - } + ignores: [ + "dist/*", + // auto generated + "src/lexicons/*", + ], + }, ]); diff --git a/touchgrass.app/lex.config.ts b/touchgrass.app/lex.config.ts index f6bd4da..f15324a 100644 --- a/touchgrass.app/lex.config.ts +++ b/touchgrass.app/lex.config.ts @@ -1,12 +1,12 @@ -import { defineLexiconConfig } from '@atcute/lex-cli'; +import { defineLexiconConfig } from "@atcute/lex-cli"; export default defineLexiconConfig({ - generate: { - files: ['lexicons-src/**/*.ts'], - outdir: 'src/lexicons/', - }, - export: { - outdir: 'lexicons/', - clean: true, - }, -}); \ No newline at end of file + generate: { + files: ["lexicons-src/**/*.ts"], + outdir: "src/lexicons/", + }, + export: { + outdir: "lexicons/", + clean: true, + }, +}); diff --git a/touchgrass.app/lexicons-src/gay/lunarequest/pubkey.ts b/touchgrass.app/lexicons-src/gay/lunarequest/pubkey.ts index 64688f2..07d5287 100644 --- a/touchgrass.app/lexicons-src/gay/lunarequest/pubkey.ts +++ b/touchgrass.app/lexicons-src/gay/lunarequest/pubkey.ts @@ -1,17 +1,21 @@ -import { document, object, record, required, string } from '@atcute/lexicon-doc/builder'; +import { document, object, record, required, string } from "@atcute/lexicon-doc/builder"; export default document({ - id: "gay.lunarequest.touchgrass.pubkey", - defs: { - main: record({ - key: "any", - record: object({ - properties: { - PubKey: required(string({ description: "a pubkey used by the user" })), - ValidTill: required(string({ format: "datetime", description: "the expiry of the pub key" })), - CreatedAt: required(string({ format: "datetime", description: "when record was created", })) - } - }) - }) - } -}) \ No newline at end of file + id: "gay.lunarequest.touchgrass.pubkey", + defs: { + main: record({ + key: "any", + record: object({ + properties: { + PubKey: required(string({ description: "a pubkey used by the user" })), + ValidTill: required( + string({ format: "datetime", description: "the expiry of the pub key" }), + ), + CreatedAt: required( + string({ format: "datetime", description: "when record was created" }), + ), + }, + }), + }), + }, +}); diff --git a/touchgrass.app/lexicons-src/gay/lunarequest/touchedgrass.ts b/touchgrass.app/lexicons-src/gay/lunarequest/touchedgrass.ts index 6a404ca..30d63b3 100644 --- a/touchgrass.app/lexicons-src/gay/lunarequest/touchedgrass.ts +++ b/touchgrass.app/lexicons-src/gay/lunarequest/touchedgrass.ts @@ -1,17 +1,24 @@ -import { document, object, record, required, string } from '@atcute/lexicon-doc/builder'; +import { document, object, record, required, string } from "@atcute/lexicon-doc/builder"; export default document({ - id: "gay.lunarequest.touchgrass.touchedgrass", - defs: { - main: record({ - key: "any", - record: object({ - properties: { - Target: required(string({ format: "did", description: "target for irl meetup, did of the user being verified" })), - Payload: required(string({ description: "signed did of the person verifiying" })), - CreatedAt: required(string({ format: "datetime", description: "when record was created", })) - } - }) - }) - } -}) \ No newline at end of file + id: "gay.lunarequest.touchgrass.touchedgrass", + defs: { + main: record({ + key: "any", + record: object({ + properties: { + Target: required( + string({ + format: "did", + description: "target for irl meetup, did of the user being verified", + }), + ), + Payload: required(string({ description: "signed did of the person verifiying" })), + CreatedAt: required( + string({ format: "datetime", description: "when record was created" }), + ), + }, + }), + }), + }, +}); diff --git a/touchgrass.app/lexicons/gay/lunarequest/touchgrass/pubkey.json b/touchgrass.app/lexicons/gay/lunarequest/touchgrass/pubkey.json index 139ccaa..468cace 100644 --- a/touchgrass.app/lexicons/gay/lunarequest/touchgrass/pubkey.json +++ b/touchgrass.app/lexicons/gay/lunarequest/touchgrass/pubkey.json @@ -19,11 +19,7 @@ "format": "datetime" } }, - "required": [ - "PubKey", - "ValidTill", - "CreatedAt" - ], + "required": ["PubKey", "ValidTill", "CreatedAt"], "type": "object" }, "type": "record" @@ -31,4 +27,4 @@ }, "id": "gay.lunarequest.touchgrass.pubkey", "lexicon": 1 -} \ No newline at end of file +} diff --git a/touchgrass.app/lexicons/gay/lunarequest/touchgrass/touchedgrass.json b/touchgrass.app/lexicons/gay/lunarequest/touchgrass/touchedgrass.json index 2c0ac6a..6bb9a13 100644 --- a/touchgrass.app/lexicons/gay/lunarequest/touchgrass/touchedgrass.json +++ b/touchgrass.app/lexicons/gay/lunarequest/touchgrass/touchedgrass.json @@ -19,11 +19,7 @@ "format": "datetime" } }, - "required": [ - "Target", - "Payload", - "CreatedAt" - ], + "required": ["Target", "Payload", "CreatedAt"], "type": "object" }, "type": "record" @@ -31,4 +27,4 @@ }, "id": "gay.lunarequest.touchgrass.touchedgrass", "lexicon": 1 -} \ No newline at end of file +} diff --git a/touchgrass.app/metro.config.js b/touchgrass.app/metro.config.cjs similarity index 81% rename from touchgrass.app/metro.config.js rename to touchgrass.app/metro.config.cjs index cc0e83d..761bcb5 100644 --- a/touchgrass.app/metro.config.js +++ b/touchgrass.app/metro.config.cjs @@ -1,8 +1,7 @@ // Learn more https://docs.expo.io/guides/customizing-metro -const { getDefaultConfig } = require('expo/metro-config'); +const { getDefaultConfig } = require("expo/metro-config"); const { withNativewind } = require("nativewind/metro"); - /** @type {import('expo/metro-config').MetroConfig} */ const config = getDefaultConfig(__dirname); diff --git a/touchgrass.app/nativewind-env.d.ts b/touchgrass.app/nativewind-env.d.ts index 8197891..dde9c2c 100644 --- a/touchgrass.app/nativewind-env.d.ts +++ b/touchgrass.app/nativewind-env.d.ts @@ -1,5 +1,4 @@ /// /// - -// NOTE: This file should not be edited and should be committed with your source code. It is generated by react-native-css. If you need to move or disable this file, please see the documentation. \ No newline at end of file +// NOTE: This file should not be edited and should be committed with your source code. It is generated by react-native-css. If you need to move or disable this file, please see the documentation. diff --git a/touchgrass.app/package.json b/touchgrass.app/package.json index 406edec..4eedfda 100644 --- a/touchgrass.app/package.json +++ b/touchgrass.app/package.json @@ -4,29 +4,31 @@ "version": "1.0.0", "type": "module", "dependencies": { - "@atcute/atproto": "^4.0.4", - "@atcute/client": "^5.1.2", - "@atcute/identity": "^2", - "@atcute/identity-resolver": "^2", "@atcute/lex-cli": "^3.3.0", "@atcute/lexicons": "^2", "@atproto/api": "^0.24.3", + "@atproto/common-web": "^0.5.14", "@atproto/oauth-client-expo": "^0.2.6", - "@expo/ui": "~57.0.22", + "@expo/ui": "~57.0.23", + "@noble/post-quantum": "^0.7.1", + "@react-native-async-storage/async-storage": "2.2.0", + "@react-native-vector-icons/fontawesome6": "^13.1.5", "@react-native/typescript-config": "^0.87.1", "@types/node": "^26.6.4", "core-js": "^3.50.0", - "expo": "^57.0.27", + "expo": "~57.0.28", + "expo-blur": "~57.0.3", + "expo-camera": "~57.0.6", "expo-constants": "~57.0.21", - "expo-dev-client": "~57.0.19", + "expo-dev-client": "~57.0.20", "expo-device": "~57.0.2", "expo-font": "~57.0.4", "expo-glass-effect": "~57.0.4", "expo-image": "~57.0.5", "expo-linking": "~57.0.12", - "expo-router": "~57.0.25", + "expo-router": "~57.0.26", "expo-secure-store": "~57.0.4", - "expo-splash-screen": "~57.0.9", + "expo-splash-screen": "~57.0.10", "expo-status-bar": "~57.0.1", "expo-symbols": "~57.0.3", "expo-system-ui": "~57.0.4", @@ -36,12 +38,17 @@ "react-dom": "19.2.3", "react-native": "0.86.3", "react-native-css": "3.1.0-rc.0", + "react-native-device-info": "^15.0.2", "react-native-gesture-handler": "~2.32.0", + "react-native-get-random-values": "~1.11.0", "react-native-mmkv": "^4.3.2", "react-native-nitro-modules": "^0.37.1", + "react-native-nitro-totp": "^2.0.1", + "react-native-qrcode-svg": "^6.3.26", "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-url-polyfill": "^4.0.0", "react-native-web": "~0.21.0", "react-native-worklets": "0.10.1" @@ -53,8 +60,11 @@ "babel-preset-expo": "^57.0.14", "eslint": "^9", "eslint-config-expo": "~57.0.2", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-prettier": "^5.5.6", "lightningcss": "1.30.1", "postcss": "8.5.29", + "prettier": "^3.9.10", "prettier-plugin-tailwindcss": "^0.5.11", "tailwindcss": "4.1.12", "typescript": "~6.0.3" @@ -62,6 +72,7 @@ "scripts": { "start": "expo start", "android": "expo run:android", + "android:prod": "eas build --platform android --local", "ios": "expo run:ios", "web": "expo start --web", "lint": "expo lint", @@ -69,7 +80,8 @@ "lexicons:export": "lex-cli export", "lexicons:generate": "lex-cli generate", "oauth-metadata": "bun scripts/sync-oauth-client-metadata.ts", - "prebuild": "EXPO_NO_GIT_STATUS=1 expo prebuild --clean" + "prebuild": "EXPO_NO_GIT_STATUS=1 expo prebuild --clean", + "fmt": "prettier . --write" }, "private": true, "overrides": { diff --git a/touchgrass.app/postcss.config.mjs b/touchgrass.app/postcss.config.mjs index fe1e17e..c2ddf74 100644 --- a/touchgrass.app/postcss.config.mjs +++ b/touchgrass.app/postcss.config.mjs @@ -2,4 +2,4 @@ export default { plugins: { "@tailwindcss/postcss": {}, }, -}; \ No newline at end of file +}; diff --git a/touchgrass.app/src/app/(authenticated)/_layout.tsx b/touchgrass.app/src/app/(authenticated)/_layout.tsx deleted file mode 100644 index 7a0cd61..0000000 --- a/touchgrass.app/src/app/(authenticated)/_layout.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { Stack } from "expo-router"; - -export default function AuthenticatedLayout() { - return ( - - ); -} diff --git a/touchgrass.app/src/app/(authenticated)/home.tsx b/touchgrass.app/src/app/(authenticated)/home.tsx deleted file mode 100644 index 67fdf94..0000000 --- a/touchgrass.app/src/app/(authenticated)/home.tsx +++ /dev/null @@ -1,134 +0,0 @@ -import { useEffect, useState } from "react"; -import { - ActivityIndicator, - Pressable, - StyleSheet, - Text, - View, -} from "react-native"; - -import { useAuth } from "../../components/SessionProvider"; - -type SessionInfo = { - did: string; - handle: string; - active?: boolean; -}; - -export default function Home() { - const { agent, did, signOut } = useAuth(); - - const [info, setInfo] = useState(null); - const [error, setError] = useState(null); - - useEffect(() => { - if (!agent) return; - - let cancelled = false; - - agent.com.atproto.server - .getSession() - .then((response) => { - if (!cancelled) setInfo(response.data); - }) - .catch((err: unknown) => { - if (!cancelled) - setError(err instanceof Error ? err.message : String(err)); - }); - - return () => { - cancelled = true; - }; - }, [agent]); - - return ( - - signed in as - - {info ? `@${info.handle}` : (did ?? "…")} - - {did} - - {error ? ( - {error} - ) : info ? ( - com.atproto.server.getSession ok - ) : ( - - )} - - - - { - void signOut(); - }} - style={({ pressed }) => [ - styles.button, - pressed && styles.buttonPressed, - ]} - > - Sign out - - - ); -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: "center", - paddingHorizontal: 24, - }, - eyebrow: { - fontSize: 12, - letterSpacing: 1, - textTransform: "uppercase", - color: "#737373", - }, - handle: { - marginTop: 4, - fontSize: 28, - fontWeight: "700", - color: "#ffffff", - }, - meta: { - marginTop: 6, - fontSize: 12, - color: "#a3a3a3", - }, - ok: { - marginTop: 20, - fontSize: 13, - color: "#4ade80", - }, - error: { - marginTop: 20, - fontSize: 13, - color: "#f87171", - }, - spinner: { - marginTop: 20, - alignSelf: "flex-start", - }, - spacer: { - height: 32, - }, - button: { - borderWidth: 1, - borderColor: "#262626", - backgroundColor: "#171717", - borderRadius: 16, - paddingVertical: 16, - alignItems: "center", - }, - buttonPressed: { - opacity: 0.7, - }, - buttonLabel: { - fontSize: 16, - fontWeight: "600", - color: "#ffffff", - }, -}); diff --git a/touchgrass.app/src/app/(authenticated)/logout.tsx b/touchgrass.app/src/app/(authenticated)/logout.tsx new file mode 100644 index 0000000..68f9167 --- /dev/null +++ b/touchgrass.app/src/app/(authenticated)/logout.tsx @@ -0,0 +1,5 @@ +import { View } from "react-native"; + +export default function Logout() { + return ; +} diff --git a/touchgrass.app/src/app/(authenticated)/scan.tsx b/touchgrass.app/src/app/(authenticated)/scan.tsx new file mode 100644 index 0000000..e955c1c --- /dev/null +++ b/touchgrass.app/src/app/(authenticated)/scan.tsx @@ -0,0 +1,14 @@ +import { useAuth } from "#/components/SessionProvider"; +import { useRouter } from "expo-router"; +import { View } from "react-native"; + +export default function Scan() { + const router = useRouter(); + const { isAuthed } = useAuth(); + + if (!isAuthed) { + router.navigate("/sign-in"); + } + + return ; +} diff --git a/touchgrass.app/src/app/_layout.tsx b/touchgrass.app/src/app/_layout.tsx index 8535d76..590a4e5 100644 --- a/touchgrass.app/src/app/_layout.tsx +++ b/touchgrass.app/src/app/_layout.tsx @@ -14,15 +14,12 @@ export default function RootLayout() { } function RootNavigator() { - const { isLoading, isAuthed } = useAuth(); + const { isLoading } = useAuth(); useEffect(() => { - console.log(`loading: ${isLoading}`); if (!isLoading) void SplashScreen.hideAsync(); }, [isLoading]); - console.log(`authenticated ${isAuthed}`); - return ( - - - - - - - - + /> ); } diff --git a/touchgrass.app/src/app/about.tsx b/touchgrass.app/src/app/about.tsx new file mode 100644 index 0000000..9a39d28 --- /dev/null +++ b/touchgrass.app/src/app/about.tsx @@ -0,0 +1,33 @@ +import { View, Text, Linking } from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; + +export default function About() { + return ( + + + About + + + + + Touch Fluffy Tail originally started life as touchgrass. Unfortunately, the domains were + way too expensive, so it was renamed to Touch Fluffy Tail. The idea behind this app is a + way to "prove" that you met someone at a convention by having a record they have + attested to show you met them. Touch Fluffy Tail is mainly developed by 2 people{" "} + Linking.openURL("https://witchsky.app/profile/nullrequest.com")}> + Luna + {" "} + and{" "} + Linking.openURL("https://witchsky.app/profile/sakurakat.systems")}> + Kathryn + + . It is however opensource and we are always open to contributions. + + + + ); +} diff --git a/touchgrass.app/src/app/index.tsx b/touchgrass.app/src/app/index.tsx index 76d440c..443e576 100644 --- a/touchgrass.app/src/app/index.tsx +++ b/touchgrass.app/src/app/index.tsx @@ -1,11 +1,93 @@ -import { Redirect } from "expo-router"; -import { useAuth } from "../components/SessionProvider"; +import NavBar from "#/components/NavBar"; +import { AuthRequiredError, useAuth } from "#/components/SessionProvider"; +import { BlurTargetView, BlurView } from "expo-blur"; +import { router } from "expo-router"; +import { styled } from "nativewind"; +import { useRef, useState } from "react"; +import { Pressable, Text, View } from "react-native"; +import "react-native-get-random-values"; +import QRcode from "#/components/QRcode"; +import { SafeAreaView } from "react-native-safe-area-context"; import "./global.css"; -export default function Index() { - const { isLoading, isAuthed } = useAuth(); +type VerifiedSession = { + handle: string; + did: string; +}; - if (isLoading) return null; +export default function Home() { + const { did, status, isAuthed, hasSavedDid, requireSession } = useAuth(); - return ; + const [busy, setBusy] = useState<"session" | "sign-out" | null>(null); + const [verified, setVerified] = useState(null); + const [notice, setNotice] = useState(null); + const [error, setError] = useState(null); + + const qrTarget = useRef(null); + + function report(error: unknown) { + setError(error instanceof Error ? error.message : String(error)); + } + + async function handleCheckSession() { + if (busy) return; + + setBusy("session"); + setError(null); + setNotice(null); + + try { + const liveAgent = await requireSession(); + const { data } = await liveAgent.com.atproto.server.getSession(); + + setVerified({ handle: data.handle, did: data.did }); + setNotice("session verified"); + } catch (sessionError) { + if (sessionError instanceof AuthRequiredError && sessionError.reason === "no-session") { + router.push("/sign-in"); + return; + } + + report(sessionError); + } finally { + setBusy(null); + } + } + + return ( + + + + + + + + + + {!isAuthed ? ( + + + + router.push("/sign-in")} + className="items-center justify-center rounded-2xl border border-neutral-800 bg-neutral-900 px-8 py-4 active:opacity-70"> + sign in to get started + + + ) : null} + + + + + ); } + +const StyledBlurTargetView = styled(BlurTargetView); +const StyledBlurView = styled(BlurView); diff --git a/touchgrass.app/src/app/sign-in.tsx b/touchgrass.app/src/app/sign-in.tsx index dbd2a4d..bc6fb07 100644 --- a/touchgrass.app/src/app/sign-in.tsx +++ b/touchgrass.app/src/app/sign-in.tsx @@ -1,24 +1,17 @@ import OauthForm from "#/components/OAuthForm"; import { useAuth } from "#/components/SessionProvider"; -import { useState } from "react"; -import { Pressable, Text, View } from "react-native"; +import { mainSchema } from "#/lexicons/types/gay/lunarequest/touchgrass/pubkey"; +import { safeParse } from "@atcute/lexicons"; +import { Agent } from "@atproto/api"; +import { TID } from "@atproto/common-web"; +import { ml_dsa65 } from "@noble/post-quantum/ml-dsa.js"; +import { FontAwesome6 } from "@react-native-vector-icons/fontawesome6"; +import { router } from "expo-router"; +import { Text, View } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; -type LoginMode = "oauth" | "legacy"; - -type SignInProps = { - setError?: (v: string) => void; -}; - -export default function SignIn({ setError = () => {} }: SignInProps) { +export default function SignIn() { const { isLoading, signIn } = useAuth(); - const [mode, setMode] = useState("oauth"); - - const switchMode = (next: LoginMode) => { - if (next === mode) return; - setError(""); - setMode(next); - }; if (isLoading) return null; @@ -27,57 +20,56 @@ export default function SignIn({ setError = () => {} }: SignInProps) { - Sign In + {" "} + Sign In {" "} - - switchMode("oauth")} - className={`flex-1 items-center justify-center border-b-2 py-4 ${ - mode === "oauth" ? "border-b-emerald-500" : "border-b-transparent" - }`} - > - - OAuth - - - - switchMode("legacy")} - className={`flex-1 items-center justify-center border-b-2 py-4 ${ - mode === "legacy" - ? "border-b-emerald-500" - : "border-b-transparent" - }`} - > - - Legacy - - - + { + await generate_key_pair(handle, signIn); - {mode === "oauth" ? ( - - ) : ( - Place holder for legacy login - )} + if (router.canGoBack()) router.back(); + else router.replace("/"); + }} + /> ); } + +async function generate_key_pair( + handle: string, + signin: (handle: string, privateKey: Uint8Array) => Promise, +) { + const keys = ml_dsa65.keygen(); + const pubkey = keys.publicKey; + const privkey = keys.secretKey; + + const agent = await signin(handle, privkey); + const createdAt = new Date().toISOString(); + const validTill = new Date(createdAt); + validTill.setFullYear(validTill.getFullYear() + 1); + const tid = TID.nextStr(); + + const record = { + $type: "gay.lunarequest.touchgrass.pubkey", + CreatedAt: createdAt, + pubkey: Buffer.from(pubkey).toString("base64"), + ValidTill: validTill, + }; + + const result = safeParse(mainSchema, record); + if (!result.ok) { + throw new Error("How the fuck did we get here luna?"); + } + const resp = await agent.com.atproto.repo.putRecord({ + repo: agent.assertDid, + rkey: tid, + collection: "gay.lunarequest.touchgrass.pubkey", + record: record, + }); + if (!resp.success) { + throw new Error("once more i thought this was not possible"); + } +} diff --git a/touchgrass.app/src/components/BurgerMenu.tsx b/touchgrass.app/src/components/BurgerMenu.tsx new file mode 100644 index 0000000..9cd48d7 --- /dev/null +++ b/touchgrass.app/src/components/BurgerMenu.tsx @@ -0,0 +1,51 @@ +import { FontAwesome6 } from "@react-native-vector-icons/fontawesome6"; +import { useState } from "react"; +import { Pressable, Text, View } from "react-native"; + +export interface MenuItems { + title: string; + onpress: () => void; +} + +interface HamburgerMenuProps { + items: MenuItems[]; +} + +export default function HamburgerMenu({ items }: HamburgerMenuProps) { + const [menuVisible, setMenuVisible] = useState(false); + + return ( + + setMenuVisible((visible) => !visible)} + className="self-start" + accessibilityRole="button" + accessibilityLabel="Toggle menu" + accessibilityState={{ expanded: menuVisible }}> + + + + {menuVisible && ( + + {items.map((item) => ( + { + setMenuVisible(false); + item.onpress(); + }} + className="my-1 rounded-md px-2.5 py-1 active:bg-[#2a2a3b]"> + {item.title} + + ))} + + )} + + ); +} diff --git a/touchgrass.app/src/components/NavBar.tsx b/touchgrass.app/src/components/NavBar.tsx new file mode 100644 index 0000000..2f127fa --- /dev/null +++ b/touchgrass.app/src/components/NavBar.tsx @@ -0,0 +1,48 @@ +import { FontAwesome6 } from "@react-native-vector-icons/fontawesome6"; +import { useRouter } from "expo-router"; +import { Pressable, Text, View } from "react-native"; +import HamburgerMenu, { MenuItems } from "./BurgerMenu"; +import { useAuth } from "./SessionProvider"; + +export default function NavBar() { + const router = useRouter(); + const { isAuthed } = useAuth(); + + const items: MenuItems[] = [ + ...(isAuthed + ? [ + { + title: "Logout", + onpress: () => router.navigate("./(authenticated)/logout"), + }, + ] + : []), + { + title: "About", + onpress: () => router.navigate("./about"), + }, + ]; + + return ( + + Touch Fluffy Tail + + + router.navigate("./(authenticated)/scan")} + accessibilityRole="button" + accessibilityLabel="Switch camera view"> + + + + + + + ); +} diff --git a/touchgrass.app/src/components/OAuthForm.tsx b/touchgrass.app/src/components/OAuthForm.tsx index 873d8f0..2e53d14 100644 --- a/touchgrass.app/src/components/OAuthForm.tsx +++ b/touchgrass.app/src/components/OAuthForm.tsx @@ -1,26 +1,173 @@ -import { useState } from "react"; -import { Pressable, Text, TextInput, View } from "react-native"; +import { useEffect, useRef, useState } from "react"; +import { ActivityIndicator, Pressable, Text, TextInput, View } from "react-native"; +import { HandleResult } from "./common/types"; +import TypeAheadResults from "./TypeAheadResults"; + +const TYPEAHEAD_URL = "https://typeahead.waow.tech"; type OAuthFormProps = { - signIn?: (v: string) => Promise; + signIn: (v: string) => Promise; }; export default function OAuthForm({ signIn }: OAuthFormProps) { const [handle, setHandle] = useState(""); + const [results, setResults] = useState([]); + const [searching, setSearching] = useState(false); + const [showResults, setShowResults] = useState(false); + const [signingIn, setSigningIn] = useState(false); + const [error, setError] = useState(null); + + const inputRef = useRef(null); + const requestId = useRef(0); + + function handleQueryChange(value: string) { + setHandle(value); + + if (value.trim().length < 2) { + // Invalidate any pending request. + requestId.current += 1; + + setResults([]); + setShowResults(false); + setSearching(false); + } + } + + useEffect(() => { + const query = handle.trim(); + + if (query.length < 2) return; + + const currentRequestId = ++requestId.current; + + const timeout = setTimeout(async () => { + setSearching(true); + + try { + const response = await fetch( + `${TYPEAHEAD_URL}/xrpc/app.bsky.actor.searchActorsTypeahead?q=${encodeURIComponent(query)}&limit=10`, + { + headers: { "X-Client": "gay.lunrequest.touchgrass" }, + }, + ); + + if (!response.ok) { + throw new Error(`Typeahead request failed: ${response.status}`); + } + + const data = await response.json(); + + if (currentRequestId !== requestId.current) return; + + const actors: HandleResult[] = (data.actors ?? []).map( + (actor: { did: string; handle: string; displayName?: string; avatar?: string }) => ({ + did: actor.did, + handle: actor.handle, + display_name: actor.displayName ?? actor.handle, + avatar_url: actor.avatar ?? null, + }), + ); + + setResults(actors); + setShowResults(actors.length > 0); + } catch (error) { + if (currentRequestId === requestId.current) { + console.error("Handle search failed:", error); + setResults([]); + setShowResults(false); + } + } finally { + if (currentRequestId === requestId.current) { + setSearching(false); + } + } + }, 300); + + return () => clearTimeout(timeout); + }, [handle]); + + function selectHandle(result: HandleResult) { + requestId.current += 1; + + setHandle(result.handle); + setResults([]); + setShowResults(false); + setSearching(false); + inputRef.current?.blur(); + } + + async function handleLogin() { + const selectedHandle = handle.trim(); + + if (!selectedHandle || signingIn) return; + + setSigningIn(true); + setError(null); + + try { + await signIn(selectedHandle); + } catch (signInError) { + setError(signInError instanceof Error ? signInError.message : String(signInError)); + } finally { + setSigningIn(false); + } + } + return ( - - - @ - + + + + @ + + { + if (results.length > 0) setShowResults(true); + }} + onSubmitEditing={() => { + if (results.length === 1) { + selectHandle(results[0]); + } + }} + autoCapitalize="none" + autoCorrect={false} + spellCheck={false} + autoComplete="off" + returnKeyType="search" + accessibilityLabel="Search Bluesky handles" + /> + + {searching && } + + + {showResults && results.length > 0 && ( + + )} - - Login + + {error && ( + + {error} + + )} + + + + {signingIn ? "Logging in..." : "Login"} + ); diff --git a/touchgrass.app/src/components/QRcode.tsx b/touchgrass.app/src/components/QRcode.tsx new file mode 100644 index 0000000..4dcb94a --- /dev/null +++ b/touchgrass.app/src/components/QRcode.tsx @@ -0,0 +1,124 @@ +import { deviceName } from "expo-device"; +import { useEffect, useState } from "react"; +import { ActivityIndicator, Text, View } from "react-native"; +import { NitroTotp, parseSecretKey } from "react-native-nitro-totp"; +import QRCode from "react-native-qrcode-svg"; +import { useAuth } from "./SessionProvider"; + +const totp = new NitroTotp(); +const PERIOD = 30; + +type TotpResult = { + seed: string; + code: string; +}; + +export default function QRcode() { + const { seed } = useAuth(); + + const [totpResult, setTotpResult] = useState(null); + + const [remaining, setRemaining] = useState(PERIOD); + const [macId] = useState("Unavailable"); + const [error, setError] = useState(null); + + const code = seed && totpResult?.seed === seed ? totpResult.code : ""; + + useEffect(() => { + if (!seed) return; + + let active = true; + + const generate = () => { + try { + const secret = parseSecretKey(seed); + const nextCode = totp.generate(secret); + + if (active) { + setTotpResult({ seed, code: nextCode }); + setError(null); + } + } catch { + if (active) { + setError("Unable to generate TOTP. Check the seed."); + } + } + }; + + const updateTimer = () => { + const seconds = Math.floor(Date.now() / 1000); + const left = PERIOD - (seconds % PERIOD); + + if (active) { + setRemaining(left); + } + + if (left === PERIOD) { + generate(); + } + }; + + generate(); + updateTimer(); + + const timer = setInterval(updateTimer, 250); + + return () => { + active = false; + clearInterval(timer); + }; + }, [seed]); + + if (!seed) { + return ( + + No seed available. + + ); + } + + const qrValue = code + ? JSON.stringify({ + deviceName, + macId, + totp: code, + }) + : ""; + const progress = (PERIOD - remaining) / PERIOD; + + return ( + + + Verify Me :3 + + {error ? ( + {error} + ) : code ? ( + <> + Refreshes in {remaining}s + + + + + + + + + ) : ( + + )} + + + Device name + + + {deviceName ? deviceName : "Unknown device"} + + + + + ); +} diff --git a/touchgrass.app/src/components/SessionProvider.tsx b/touchgrass.app/src/components/SessionProvider.tsx index 799f390..3e999c4 100644 --- a/touchgrass.app/src/components/SessionProvider.tsx +++ b/touchgrass.app/src/components/SessionProvider.tsx @@ -1,101 +1,189 @@ import { oauthClient } from "#/lib/atproto"; import { Agent } from "@atproto/api"; +import { TokenRefreshError } from "@atproto/oauth-client-expo"; import { deleteItemAsync, getItemAsync, setItemAsync } from "expo-secure-store"; -import { - createContext, - ReactNode, - useCallback, - useContext, - useEffect, - useState, -} from "react"; +import { createContext, ReactNode, useCallback, useContext, useEffect, useState } from "react"; +import { NitroSecret, SecretSize } from "react-native-nitro-totp"; const DID_KEY = "gay.lunarequest.touchgrass.did"; +const PRIVATE_KEY = "gay.lunarequest.touchgrass.privkey"; +const SEED_KEY = "gay.lunarequest.touchgrass.otp_seed"; + +const nitroSecret = new NitroSecret(); + +export type AuthRequiredReason = "no-session" | "unavailable"; +export class AuthRequiredError extends Error { + readonly reason: AuthRequiredReason; + + constructor(reason: AuthRequiredReason, message: string, options?: ErrorOptions) { + super(message, options); + this.name = "AuthRequiredError"; + this.reason = reason; + } +} +export type AuthStatus = "loading" | "anonymous" | "saved" | "authenticated"; type AuthContextType = { agent: Agent | null; did: string | null; + status: AuthStatus; isLoading: boolean; isAuthed: boolean; - signIn: (handle: string) => Promise; + hasSavedDid: boolean; + seed: string | null; + privateKey: Uint8Array | null; + signIn: (handleOrDid: string, privateKey: Uint8Array) => Promise; signOut: () => Promise; + requireSession: () => Promise; }; const AuthContext = createContext(undefined); +function toAuthRequiredError(error: unknown): AuthRequiredError { + if (error instanceof TokenRefreshError && error.cause === undefined) { + return new AuthRequiredError("no-session", "No usable session is stored on this device.", { + cause: error, + }); + } + + return new AuthRequiredError( + "unavailable", + error instanceof Error ? error.message : String(error), + { cause: error }, + ); +} + export function AuthProvider({ children }: { children: ReactNode }) { const [agent, setAgent] = useState(null); const [did, setDid] = useState(null); const [isLoading, setIsLoading] = useState(true); - - const setSession = useCallback(async (session: any) => { - // i don't like using any but atproto can't do types right - const nextAgent = new Agent(session); - - // the return shouldn't be reachable but it makes typescript's linter happy - if (!session.did) { - return; - } - - await setItemAsync(DID_KEY, session.did); - setDid(session.did); - setAgent(nextAgent); - }, []); + const [seed, setSeed] = useState(null); + const [privateKey, setPrivateKey] = useState | null>(null); useEffect(() => { let active = true; - async function restoreSession() { + + const loadSavedData = async () => { try { const savedDid = await getItemAsync(DID_KEY); - if (!savedDid) return; - - const session = await oauthClient.restore(savedDid); - - if (active) { - setDid(session.did); - setAgent(new Agent(session)); + if (active && savedDid) setDid(savedDid); + if (active && savedDid) { + const privateKeyString = await getItemAsync(PRIVATE_KEY); + if (!privateKeyString) { + throw new Error("Unable to find privatekey"); + } + const pkey = new Uint8Array(Buffer.from(privateKeyString, "hex")); + setPrivateKey(pkey); } } catch (error) { - console.error("Failed to restore AT Protocol session:", error); - await deleteItemAsync(DID_KEY); + console.error("Failed to read the saved DID:", error); } finally { - if (active) setIsLoading(false); + const savedSeed = await getItemAsync(SEED_KEY); + if (active) { + if (savedSeed) { + setSeed(savedSeed); + } else { + let secret = nitroSecret.generate({ size: SecretSize.EXTENDED }); + await setItemAsync(SEED_KEY, secret); + } + } } - } - restoreSession(); + if (active) setIsLoading(false); + }; + void loadSavedData(); return () => { active = false; }; }, []); + const forgetIdentity = useCallback(async () => { + if (did) { + try { + await oauthClient.revoke(did); + } catch (error) { + console.warn("Failed to revoke the AT Protocol session:", error); + } + } + + await deleteItemAsync(DID_KEY); + await deleteItemAsync(PRIVATE_KEY); + await deleteItemAsync(SEED_KEY); + }, [did]); + + const requireSession = useCallback(async (): Promise => { + if (agent) return agent; + + if (!did) { + throw new AuthRequiredError("no-session", "No account is saved on this device."); + } + + try { + const session = await oauthClient.restore(did); + const nextAgent = new Agent(session); + + setAgent(nextAgent); + + return nextAgent; + } catch (error) { + console.error("Failed to restore the AT Protocol session:", error); + + throw toAuthRequiredError(error); + } + }, [agent, did]); + const signIn = useCallback( - async (handle: string) => { - const session = await oauthClient.signIn(handle); + async (handleOrDid: string, privateKey: Uint8Array): Promise => { + const session = await oauthClient.signIn(handleOrDid.trim()); + + if (did && did !== session.did) await forgetIdentity(); + + await setItemAsync(DID_KEY, session.did); + setDid(session.did); - await setSession(session); + const privateKeyString = Buffer.from(privateKey).toString("hex"); + await setItemAsync("PRIVATE_KEY", privateKeyString); + setPrivateKey(privateKey); + + const nextAgent = new Agent(session); + setAgent(nextAgent); + + return nextAgent; }, - [setSession], + [did, forgetIdentity], ); const signOut = useCallback(async () => { - await deleteItemAsync(DID_KEY); + await forgetIdentity(); setAgent(null); setDid(null); - }, []); + setPrivateKey(null); + }, [forgetIdentity]); + + const status: AuthStatus = isLoading + ? "loading" + : agent + ? "authenticated" + : did + ? "saved" + : "anonymous"; return ( + requireSession, + }}> {children} ); @@ -105,7 +193,7 @@ export function useAuth() { const context = useContext(AuthContext); if (!context) { - throw new Error("useAtprotoAuth must be used inside AtprotoProvider"); + throw new Error("useAuth must be used inside AuthProvider"); } return context; diff --git a/touchgrass.app/src/components/TypeAheadResults.tsx b/touchgrass.app/src/components/TypeAheadResults.tsx new file mode 100644 index 0000000..d506eed --- /dev/null +++ b/touchgrass.app/src/components/TypeAheadResults.tsx @@ -0,0 +1,50 @@ +import { FlatList, Image, Pressable, Text, View } from "react-native"; +import { HandleResult } from "./common/types"; +type Props = { + results: HandleResult[]; + selectHandle: (item: HandleResult) => void; +}; + +export default function TypeAheadResults({ results, selectHandle }: Props) { + return ( + + item.did} + renderItem={({ item, index }) => ( + selectHandle(item)} + className={`flex-row items-center gap-3 px-3 py-3 ${ + index !== results.length - 1 ? "border-b border-emerald-800" : "" + }`}> + {item.avatar_url ? ( + + ) : ( + + )} + + + + {item.display_name} + + + + @{item.handle} + + + + )} + nestedScrollEnabled={true} + scrollEnabled={true} + keyboardShouldPersistTaps="always" + showsVerticalScrollIndicator={true} + bounces={false} + style={{ maxHeight: 240, flexGrow: 0 }} + /> + + ); +} diff --git a/touchgrass.app/src/components/common/types.ts b/touchgrass.app/src/components/common/types.ts new file mode 100644 index 0000000..790f676 --- /dev/null +++ b/touchgrass.app/src/components/common/types.ts @@ -0,0 +1,8 @@ +interface HandleResult { + did: string; + handle: string; + display_name: string; + avatar_url: string | null; +} + +export type { HandleResult }; diff --git a/touchgrass.app/src/lexicons/types/gay/lunarequest/touchgrass/pubkey.ts b/touchgrass.app/src/lexicons/types/gay/lunarequest/touchgrass/pubkey.ts index 83c4950..debe655 100644 --- a/touchgrass.app/src/lexicons/types/gay/lunarequest/touchgrass/pubkey.ts +++ b/touchgrass.app/src/lexicons/types/gay/lunarequest/touchgrass/pubkey.ts @@ -1,26 +1,24 @@ -import type {} from '@atcute/lexicons'; -import * as v from '@atcute/lexicons/validations'; -import type {} from '@atcute/lexicons/ambient'; +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; const _mainSchema = /*#__PURE__*/ v.record( - /*#__PURE__*/ v.string(), - /*#__PURE__*/ v.object( - { - "$type": /*#__PURE__*/ v.literal("gay.lunarequest.touchgrass.pubkey"), - /** - * when record was created - */ - "CreatedAt": /*#__PURE__*/ v.datetimeString(), - /** - * a pubkey used by the user - */ - "PubKey": /*#__PURE__*/ v.string(), - /** - * the expiry of the pub key - */ - "ValidTill": /*#__PURE__*/ v.datetimeString(), - } - ) + /*#__PURE__*/ v.string(), + /*#__PURE__*/ v.object({ + $type: /*#__PURE__*/ v.literal("gay.lunarequest.touchgrass.pubkey"), + /** + * when record was created + */ + CreatedAt: /*#__PURE__*/ v.datetimeString(), + /** + * a pubkey used by the user + */ + PubKey: /*#__PURE__*/ v.string(), + /** + * the expiry of the pub key + */ + ValidTill: /*#__PURE__*/ v.datetimeString(), + }), ); type main$schematype = typeof _mainSchema; @@ -28,8 +26,8 @@ export interface mainSchema extends main$schematype {} export const mainSchema = _mainSchema as mainSchema; export interface Main extends v.InferInput {} -declare module '@atcute/lexicons/ambient' { - interface Records { - "gay.lunarequest.touchgrass.pubkey": mainSchema; - } +declare module "@atcute/lexicons/ambient" { + interface Records { + "gay.lunarequest.touchgrass.pubkey": mainSchema; + } } diff --git a/touchgrass.app/src/lexicons/types/gay/lunarequest/touchgrass/touchedgrass.ts b/touchgrass.app/src/lexicons/types/gay/lunarequest/touchgrass/touchedgrass.ts index 1155b7e..4942390 100644 --- a/touchgrass.app/src/lexicons/types/gay/lunarequest/touchgrass/touchedgrass.ts +++ b/touchgrass.app/src/lexicons/types/gay/lunarequest/touchgrass/touchedgrass.ts @@ -1,26 +1,24 @@ -import type {} from '@atcute/lexicons'; -import * as v from '@atcute/lexicons/validations'; -import type {} from '@atcute/lexicons/ambient'; +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; const _mainSchema = /*#__PURE__*/ v.record( - /*#__PURE__*/ v.string(), - /*#__PURE__*/ v.object( - { - "$type": /*#__PURE__*/ v.literal("gay.lunarequest.touchgrass.touchedgrass"), - /** - * when record was created - */ - "CreatedAt": /*#__PURE__*/ v.datetimeString(), - /** - * signed did of the person verifiying - */ - "Payload": /*#__PURE__*/ v.string(), - /** - * target for irl meetup, did of the user being verified - */ - "Target": /*#__PURE__*/ v.didString(), - } - ) + /*#__PURE__*/ v.string(), + /*#__PURE__*/ v.object({ + $type: /*#__PURE__*/ v.literal("gay.lunarequest.touchgrass.touchedgrass"), + /** + * when record was created + */ + CreatedAt: /*#__PURE__*/ v.datetimeString(), + /** + * signed did of the person verifiying + */ + Payload: /*#__PURE__*/ v.string(), + /** + * target for irl meetup, did of the user being verified + */ + Target: /*#__PURE__*/ v.didString(), + }), ); type main$schematype = typeof _mainSchema; @@ -28,8 +26,8 @@ export interface mainSchema extends main$schematype {} export const mainSchema = _mainSchema as mainSchema; export interface Main extends v.InferInput {} -declare module '@atcute/lexicons/ambient' { - interface Records { - "gay.lunarequest.touchgrass.touchedgrass": mainSchema; - } +declare module "@atcute/lexicons/ambient" { + interface Records { + "gay.lunarequest.touchgrass.touchedgrass": mainSchema; + } } diff --git a/touchgrass.app/src/lib/atproto.ts b/touchgrass.app/src/lib/atproto.ts index cc74a00..592d705 100644 --- a/touchgrass.app/src/lib/atproto.ts +++ b/touchgrass.app/src/lib/atproto.ts @@ -1,9 +1,8 @@ -import { ExpoOAuthClient } from '@atproto/oauth-client-expo'; +import { ExpoOAuthClient } from "@atproto/oauth-client-expo"; import clientMetadata from "../../assets/oauth-client-metadata.json"; - export const oauthClient = new ExpoOAuthClient({ - handleResolver: "https://bsky.social", // look into a alternative for this and let people choose maybe?, - // @ts-expect-error: TS2322 there's some weirdness with converting json to types - clientMetadata -}) \ No newline at end of file + handleResolver: "https://bsky.social", // look into a alternative for this and let people choose maybe?, + // @ts-expect-error: TS2322 there's some weirdness with converting json to types + clientMetadata, +}); diff --git a/touchgrass.app/tsconfig.json b/touchgrass.app/tsconfig.json index 121e6e5..ed60bab 100644 --- a/touchgrass.app/tsconfig.json +++ b/touchgrass.app/tsconfig.json @@ -3,51 +3,24 @@ "compilerOptions": { "jsx": "react-jsx", "module": "esnext", - "moduleSuffixes": [ - ".ios", - ".android", - ".native", - "" - ], - "lib": [ - "dom", - "esnext" - ], - "types": [ - "node" - ], + "moduleSuffixes": [".ios", ".android", ".native", ""], + "lib": ["dom", "esnext"], + "types": ["node"], "paths": { - "#/*": [ - "./src/*" - ], - "crypto": [ - "./src/platform/crypto.ts" - ], - "expo-file-system/build/*": [ - "./node_modules/expo-file-system/build/*" - ] + "#/*": ["./src/*"], + "crypto": ["./src/platform/crypto.ts"], + "expo-file-system/build/*": ["./node_modules/expo-file-system/build/*"] }, "plugins": [ { "name": "ts-plugin-sort-import-suggestions", - "moveUpPatterns": [ - "#/", - "@lingui/react/macro" - ], - "moveDownPatterns": [ - "react-native-reanimated/lib" - ] + "moveUpPatterns": ["#/", "@lingui/react/macro"], + "moveDownPatterns": ["react-native-reanimated/lib"] } ], - "customConditions": [ - "react-native" - ] + "customConditions": ["react-native"] }, - "exclude": [ - "bskyweb", - "bskyembed", - "web-build" - ], + "exclude": ["bskyweb", "bskyembed", "web-build"], "include": [ "**/*.ts", "**/*.tsx", @@ -56,4 +29,4 @@ "lex.config.mts", "nativewind-env.d.ts" ] -} \ No newline at end of file +} -- 2.54.0