From 78b234109129df726801e02884fd46abe7aa32e7 Mon Sep 17 00:00:00 2001 From: turnoffthiscomputer <98749896+remicolin@users.noreply.github.com> Date: Tue, 9 Sep 2025 01:42:33 +0200 Subject: [PATCH] add new home screen (#1019) * add new home screen * fix typing issue * yarn nice --- app/ios/Podfile.lock | 25 + app/package.json | 1 + app/src/components/NavBar/HomeNavBar.tsx | 57 +- app/src/components/NavBar/IdDetailsNavBar.tsx | 56 ++ app/src/components/NavBar/index.ts | 1 + app/src/components/homeScreen/idCard.tsx | 578 ++++++++++++++++++ app/src/images/icons/checkmark_gray.svg | 3 + app/src/images/icons/epassport.svg | 1 + app/src/images/logo_gray.svg | 12 + app/src/navigation/home.ts | 11 +- app/src/navigation/index.tsx | 1 + app/src/screens/home/HomeScreen.tsx | 156 +++-- app/src/screens/home/IdDetailsScreen.tsx | 173 ++++++ app/src/screens/home/ProofHistoryList.tsx | 420 +++++++++++++ app/src/screens/prove/ProveScreen.tsx | 39 +- app/src/stores/database.ts | 85 ++- app/src/stores/proof-types.ts | 1 + app/src/stores/proofHistoryStore.ts | 1 + app/src/stores/userStore.ts | 6 + app/src/utils/colors.ts | 4 +- app/src/utils/fonts.ts | 5 +- yarn.lock | 469 +++++++++++++- 22 files changed, 1979 insertions(+), 126 deletions(-) create mode 100644 app/src/components/NavBar/IdDetailsNavBar.tsx create mode 100644 app/src/components/homeScreen/idCard.tsx create mode 100644 app/src/images/icons/checkmark_gray.svg create mode 100644 app/src/images/icons/epassport.svg create mode 100644 app/src/images/logo_gray.svg create mode 100644 app/src/screens/home/IdDetailsScreen.tsx create mode 100644 app/src/screens/home/ProofHistoryList.tsx diff --git a/app/ios/Podfile.lock b/app/ios/Podfile.lock index a664acfb3..15807c4df 100644 --- a/app/ios/Podfile.lock +++ b/app/ios/Podfile.lock @@ -1474,6 +1474,27 @@ PODS: - React-Core - react-native-biometrics (3.0.1): - React-Core + - react-native-blur (4.4.1): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2024.10.14.00) + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-NativeModulesApple + - React-RCTFabric + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - Yoga - react-native-cloud-storage (2.3.0): - DoubleConversion - glog @@ -2155,6 +2176,7 @@ DEPENDENCIES: - React-microtasksnativemodule (from `../../node_modules/react-native/ReactCommon/react/nativemodule/microtasks`) - react-native-app-auth (from `../../node_modules/react-native-app-auth`) - react-native-biometrics (from `../../node_modules/react-native-biometrics`) + - "react-native-blur (from `../../node_modules/@react-native-community/blur`)" - react-native-cloud-storage (from `../../node_modules/react-native-cloud-storage`) - react-native-get-random-values (from `../../node_modules/react-native-get-random-values`) - "react-native-netinfo (from `../../node_modules/@react-native-community/netinfo`)" @@ -2319,6 +2341,8 @@ EXTERNAL SOURCES: :path: "../../node_modules/react-native-app-auth" react-native-biometrics: :path: "../../node_modules/react-native-biometrics" + react-native-blur: + :path: "../../node_modules/@react-native-community/blur" react-native-cloud-storage: :path: "../../node_modules/react-native-cloud-storage" react-native-get-random-values: @@ -2492,6 +2516,7 @@ SPEC CHECKSUMS: React-microtasksnativemodule: c7cafd8f4470cf8a4578ee605daa4c74d3278bf8 react-native-app-auth: eb42594042a25455119a8c57194b4fd25b9352f4 react-native-biometrics: 43ed5b828646a7862dbc7945556446be00798e7d + react-native-blur: 6334d934a9b5e67718b8f5725c44cc0a12946009 react-native-cloud-storage: 8d89f2bc574cf11068dfd90933905974087fb9e9 react-native-get-random-values: d16467cf726c618e9c7a8c3c39c31faa2244bbba react-native-netinfo: cec9c4e86083cb5b6aba0e0711f563e2fbbff187 diff --git a/app/package.json b/app/package.json index 59ca4ac44..40c552421 100644 --- a/app/package.json +++ b/app/package.json @@ -76,6 +76,7 @@ "@openpassport/zk-kit-smt": "^0.0.1", "@react-native-async-storage/async-storage": "^2.2.0", "@react-native-clipboard/clipboard": "1.16.3", + "@react-native-community/blur": "^4.4.1", "@react-native-community/netinfo": "^11.4.1", "@react-native-firebase/app": "^19.0.1", "@react-native-firebase/messaging": "^19.0.1", diff --git a/app/src/components/NavBar/HomeNavBar.tsx b/app/src/components/NavBar/HomeNavBar.tsx index 345e3f0da..057189e76 100644 --- a/app/src/components/NavBar/HomeNavBar.tsx +++ b/app/src/components/NavBar/HomeNavBar.tsx @@ -13,9 +13,10 @@ import type { SelfApp } from '@selfxyz/common/utils/appType'; import { NavBar } from '@/components/NavBar/BaseNavBar'; import ActivityIcon from '@/images/icons/activity.svg'; +import ScanIcon from '@/images/icons/qr_scan.svg'; import SettingsIcon from '@/images/icons/settings.svg'; import { useSelfAppStore } from '@/stores/selfAppStore'; -import { black, neutral400, white } from '@/utils/colors'; +import { black, charcoal, neutral400, slate50, white } from '@/utils/colors'; import { extraYPadding } from '@/utils/constants'; import { buttonTap } from '@/utils/haptic'; @@ -70,44 +71,56 @@ export const HomeNavBar = (props: NativeStackHeaderProps) => { }; return ( - } - /> + + + } + /> + + {props.options.title} + + + } + /> + + ); +}; diff --git a/app/src/components/NavBar/index.ts b/app/src/components/NavBar/index.ts index 1aa4ff527..a06a14949 100644 --- a/app/src/components/NavBar/index.ts +++ b/app/src/components/NavBar/index.ts @@ -4,4 +4,5 @@ export { DefaultNavBar } from '@/components/NavBar/DefaultNavBar'; export { HomeNavBar } from '@/components/NavBar/HomeNavBar'; +export { IdDetailsNavBar } from '@/components/NavBar/IdDetailsNavBar'; export { ProgressNavBar } from '@/components/NavBar/ProgressNavBar'; diff --git a/app/src/components/homeScreen/idCard.tsx b/app/src/components/homeScreen/idCard.tsx new file mode 100644 index 000000000..706d64d59 --- /dev/null +++ b/app/src/components/homeScreen/idCard.tsx @@ -0,0 +1,578 @@ +// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc. +// SPDX-License-Identifier: BUSL-1.1 +// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE. + +import React, { useCallback, useState } from 'react'; +import { Dimensions, Pressable } from 'react-native'; +import { SvgXml } from 'react-native-svg'; +import { Button, Image, Separator, Text, XStack, YStack } from 'tamagui'; +import { useFocusEffect } from '@react-navigation/native'; + +import { + attributeToPosition, + attributeToPosition_ID, + formatMrz, + PassportData, +} from '@selfxyz/common/dist/esm'; +import { pad } from '@selfxyz/common/dist/esm/src/utils/passports/passport'; + +import EPassport from '@/images/icons/epassport.svg'; +import LogoGray from '@/images/logo_gray.svg'; +import LogoInversed from '@/images/logo_inversed.svg'; +import { usePassport } from '@/providers/passportDataProvider'; +import { + black, + blue600, + green500, + red500, + slate50, + slate100, + slate300, + slate400, + slate500, + white, +} from '@/utils/colors'; +import { dinot, plexMono } from '@/utils/fonts'; + +// Import the logo SVG as a string +const logoSvg = ` + + + +`; + +interface IdCardLayoutAttributes { + idDocument: PassportData; + selected: boolean; + hidden: boolean; +} + +// This layout should be fully adaptative. I should perfectly fit in any screen size. +// the font size should adapt according to the size available to fit perfectly. +// only svg are allowed. +// each element size should be determined as % of the screen or the parent element +// the border radius should be adaptative too, as well as the padding +// this is the v0 of this component so we should only use placholders for now, no need to pass the real passport data as parameters. +const IdCardLayout: React.FC = ({ + idDocument, + selected, + hidden, +}) => { + // Function to mask MRZ characters except '<' and spaces + const maskMrzValue = (text: string): string => { + return text.replace(/./g, 'X'); + }; + + // Get screen dimensions for adaptive sizing + const { width: screenWidth, height: screenHeight } = Dimensions.get('window'); + + // Calculate adaptive sizes based on screen dimensions + // Reduce width slightly to account for horizontal margins (8px each side = 16px total) + const cardWidth = screenWidth * 0.95 - 16; // 90% of screen width minus margin space + const cardHeight = selected ? cardWidth * 0.645 : cardWidth * 0.645 * 0.3; // ID card aspect ratio (roughly 1.6:1) + const borderRadius = cardWidth * 0.04; // 4% of card width + const padding = cardWidth * 0.035; // 4% of card width + const fontSize = { + large: cardWidth * 0.045, + medium: cardWidth * 0.032, + small: cardWidth * 0.028, + xsmall: cardWidth * 0.022, + }; + + // Image dimensions (standard ID photo ratio) + const imageSize = { + width: cardWidth * 0.2, // 25% of card width + height: cardWidth * 0.29, // ID photo aspect ratio + }; + + // Shared left offset for content that should align with the start of the attributes block + const contentLeftOffset = imageSize.width + padding; + + return ( + // Container wrapper to handle shadow space properly + + + {/* Header Section */} + + + + + + {idDocument.documentCategory === 'passport' + ? 'Passport' + : 'ID Card'} + + + Verified{' '} + {idDocument.documentCategory === 'passport' + ? 'Biometric Passport' + : ' Biometric ID Card'} + + + + + {idDocument.mock && ( + + + DEVELOPER + + + )} + + + + {selected && ( + + )} + + {/* Main Content Section */} + {selected && ( + + {/* Person Image */} + + + + + {/* ID Attributes */} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + )} + + {/* Footer Section - MRZ */} + {selected && ( + + {/* Fixed-width spacer to align MRZ content with the attributes block */} + + + + + + {idDocument.documentCategory === 'passport' ? ( + // Passport: 2 lines, 88 chars total (44 chars each) + <> + + {hidden + ? maskMrzValue(idDocument.mrz.slice(0, 44)) + : idDocument.mrz.slice(0, 44)} + + + {hidden + ? maskMrzValue(idDocument.mrz.slice(44, 88)) + : idDocument.mrz.slice(44, 88)} + + + ) : ( + // ID Card: 3 lines, 90 chars total (30 chars each) + <> + + {hidden + ? maskMrzValue(idDocument.mrz.slice(0, 30)) + : idDocument.mrz.slice(0, 30)} + + + {hidden + ? maskMrzValue(idDocument.mrz.slice(30, 60)) + : idDocument.mrz.slice(30, 60)} + + + {hidden + ? maskMrzValue(idDocument.mrz.slice(60, 90)) + : idDocument.mrz.slice(60, 90)} + + + )} + + + )} + + + ); +}; + +// Interface for IdAttribute props +interface IdAttributeProps { + name: string; + value: string; + maskValue: string; + hidden?: boolean; +} + +// This layout should be fully adaptative. I should perfectly fit in any screen size. +// the font size should adapt according to the size available to fit perfectly. +// only svg are allowed. +// each element size should be determined as % of the screen or the parent element +const IdAttribute: React.FC = ({ + name, + value, + maskValue, + hidden = false, +}) => { + const { width: screenWidth } = Dimensions.get('window'); + const fontSize = { + label: screenWidth * 0.024, + value: screenWidth * 0.02, + }; + + const displayValue = hidden ? maskValue : value; + + return ( + + + {name} + + + {displayValue} + + + ); +}; + +export default IdCardLayout; + +function getPassportAttributes(mrz: string, documentCategory: string) { + const isPassportType = documentCategory === 'passport'; + const attributePositions = isPassportType + ? attributeToPosition + : attributeToPosition_ID; + + const nameSlice = mrz.slice( + attributePositions.name[0], + attributePositions.name[1], + ); + const dobSlice = mrz.slice( + attributePositions.date_of_birth[0], + attributePositions.date_of_birth[1] + 1, + ); + const yobSlice = mrz.slice( + attributePositions.date_of_birth[0], + attributePositions.date_of_birth[0] + 1, + ); + const issuingStateSlice = mrz.slice( + attributePositions.issuing_state[0], + attributePositions.issuing_state[1] + 1, + ); + const nationalitySlice = mrz.slice( + attributePositions.nationality[0], + attributePositions.nationality[1] + 1, + ); + const passNoSlice = mrz.slice( + attributePositions.passport_number[0], + attributePositions.passport_number[1] + 1, + ); + const sexSlice = mrz.slice( + attributePositions.gender[0], + attributePositions.gender[1] + 1, + ); + const expiryDateSlice = mrz.slice( + attributePositions.expiry_date[0], + attributePositions.expiry_date[1] + 1, + ); + return { + nameSlice, + dobSlice, + yobSlice, + issuingStateSlice, + nationalitySlice, + passNoSlice, + sexSlice, + expiryDateSlice, + isPassportType, + }; +} + +function getNameAndSurname(nameSlice: string) { + // Split by double << to separate surname from names + const parts = nameSlice.split('<<'); + if (parts.length < 2) { + return { surname: [], names: [] }; + } + + // First part is surname, second part contains names separated by single < + const surname = parts[0].replace(/ name.length > 0); + + return { + surname: surname ? [surname] : [], + names: names[0] ? [names[0]] : [], + }; +} + +function formatDateFromYYMMDD( + dateString: string, + isExpiry: boolean = false, +): string { + if (dateString.length !== 6) { + return dateString; + } + + const yy = parseInt(dateString.substring(0, 2), 10); + const mm = dateString.substring(2, 4); + const dd = dateString.substring(4, 6); + + const currentYear = new Date().getFullYear(); + const century = Math.floor(currentYear / 100) * 100; + let year = century + yy; + + if (isExpiry) { + // For expiry: if year is in the past, assume next century + if (year < currentYear) { + year += 100; + } + } else { + // For birth: if year is in the future, assume previous century + if (year > currentYear) { + year -= 100; + } + } + + return `${dd}/${mm}/${year}`; +} diff --git a/app/src/images/icons/checkmark_gray.svg b/app/src/images/icons/checkmark_gray.svg new file mode 100644 index 000000000..20f0b65c8 --- /dev/null +++ b/app/src/images/icons/checkmark_gray.svg @@ -0,0 +1,3 @@ + + + diff --git a/app/src/images/icons/epassport.svg b/app/src/images/icons/epassport.svg new file mode 100644 index 000000000..3c4c0073d --- /dev/null +++ b/app/src/images/icons/epassport.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/src/images/logo_gray.svg b/app/src/images/logo_gray.svg new file mode 100644 index 000000000..3fef120ad --- /dev/null +++ b/app/src/images/logo_gray.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/app/src/navigation/home.ts b/app/src/navigation/home.ts index 2a76c99b1..e53d2b79f 100644 --- a/app/src/navigation/home.ts +++ b/app/src/navigation/home.ts @@ -5,7 +5,7 @@ import { lazy } from 'react'; import type { NativeStackNavigationOptions } from '@react-navigation/native-stack'; -import { HomeNavBar } from '@/components/NavBar'; +import { HomeNavBar, IdDetailsNavBar } from '@/components/NavBar'; const DisclaimerScreen = lazy(() => import('@/screens/home/DisclaimerScreen')); const HomeScreen = lazy(() => import('@/screens/home/HomeScreen')); @@ -15,6 +15,7 @@ const ProofHistoryDetailScreen = lazy( const ProofHistoryScreen = lazy( () => import('@/screens/home/ProofHistoryScreen'), ); +const IdDetailsScreen = lazy(() => import('@/screens/home/IdDetailsScreen')); const homeScreens = { Disclaimer: { screen: DisclaimerScreen, @@ -44,6 +45,14 @@ const homeScreens = { title: 'Approval', }, }, + IdDetails: { + screen: IdDetailsScreen, + options: { + title: '', + header: IdDetailsNavBar, // Use custom header + headerBackVisible: false, // Hide default back button + }, + }, }; export default homeScreens; diff --git a/app/src/navigation/index.tsx b/app/src/navigation/index.tsx index 15f879b0f..c9bfaa7f6 100644 --- a/app/src/navigation/index.tsx +++ b/app/src/navigation/index.tsx @@ -23,6 +23,7 @@ import proveScreens from '@/navigation/prove'; import recoveryScreens from '@/navigation/recovery'; import settingsScreens from '@/navigation/settings'; import systemScreens from '@/navigation/system'; +import type { ProofHistory } from '@/stores/proof-types'; import analytics from '@/utils/analytics'; import { setupUniversalLinkListenerInNavigation } from '@/utils/deeplinks'; diff --git a/app/src/screens/home/HomeScreen.tsx b/app/src/screens/home/HomeScreen.tsx index 47e8d468b..73823c95d 100644 --- a/app/src/screens/home/HomeScreen.tsx +++ b/app/src/screens/home/HomeScreen.tsx @@ -2,30 +2,32 @@ // SPDX-License-Identifier: BUSL-1.1 // NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE. -import React, { useCallback } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; +import { Pressable } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; -import { Button, styled, YStack } from 'tamagui'; +import { Button, ScrollView, styled, Text, YStack } from 'tamagui'; import { useFocusEffect, useNavigation, usePreventRemove, } from '@react-navigation/native'; -import { useSelfClient } from '@selfxyz/mobile-sdk-alpha'; +import { PassportData } from '@selfxyz/common/dist/esm'; +import { DocumentCatalog } from '@selfxyz/common/dist/esm/src/utils/types'; +import { DocumentMetadata, useSelfClient } from '@selfxyz/mobile-sdk-alpha'; import { ProofEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics'; import { pressedStyle } from '@/components/buttons/pressedStyle'; +import IdCardLayout from '@/components/homeScreen/idCard'; import { BodyText } from '@/components/typography/BodyText'; -import { Caption } from '@/components/typography/Caption'; import { useAppUpdates } from '@/hooks/useAppUpdates'; import useConnectionModal from '@/hooks/useConnectionModal'; import useHapticNavigation from '@/hooks/useHapticNavigation'; -import SelfCard from '@/images/card-style-1.svg'; -import ScanIcon from '@/images/icons/qr_scan.svg'; import WarnIcon from '@/images/icons/warning.svg'; import { usePassport } from '@/providers/passportDataProvider'; import { useSettingStore } from '@/stores/settingStore'; -import { amber500, black, neutral700, slate800, white } from '@/utils/colors'; +import useUserStore from '@/stores/userStore'; +import { neutral700, slate50, slate800, white } from '@/utils/colors'; import { extraYPadding } from '@/utils/constants'; const ScanButton = styled(Button, { @@ -43,9 +45,43 @@ const HomeScreen: React.FC = () => { const selfClient = useSelfClient(); useConnectionModal(); const navigation = useNavigation(); - const { getAllDocuments } = usePassport(); + const { setIdDetailsDocumentId } = useUserStore(); + const { getAllDocuments, loadDocumentCatalog, setSelectedDocument } = + usePassport(); const [isNewVersionAvailable, showAppUpdateModal, isModalDismissed] = useAppUpdates(); + const [documentCatalog, setDocumentCatalog] = useState({ + documents: [], + }); + const [allDocuments, setAllDocuments] = useState< + Record + >({}); + const [loading, setLoading] = useState(true); + + const loadDocuments = useCallback(async () => { + setLoading(true); + try { + const catalog = await loadDocumentCatalog(); + const docs = await getAllDocuments(); + + setDocumentCatalog(catalog); + setAllDocuments(docs); + + if (catalog.documents.length === 0) { + navigation.navigate('Launch' as never); + } + } catch (error) { + console.warn('Failed to load documents:', error); + navigation.navigate('Launch' as never); + } + setLoading(false); + }, [loadDocumentCatalog, getAllDocuments, navigation]); + + useFocusEffect( + useCallback(() => { + loadDocuments(); + }, [loadDocuments]), + ); useFocusEffect(() => { if (isNewVersionAvailable && !isModalDismissed) { @@ -53,22 +89,12 @@ const HomeScreen: React.FC = () => { } }); - useFocusEffect( - useCallback(() => { - async function checkDocs() { - try { - const docs = await getAllDocuments(); - if (Object.keys(docs).length === 0) { - navigation.navigate('Launch' as never); - } - } catch { - // ignore errors - } - } - - checkDocs(); - }, [getAllDocuments, navigation]), - ); + const handleDocumentSelection = async (documentId: string) => { + await setSelectedDocument(documentId); + // Reload catalog to update selected state + const updatedCatalog = await loadDocumentCatalog(); + setDocumentCatalog(updatedCatalog); + }; const goToQRCodeViewFinder = useHapticNavigation('QRCodeViewFinder'); const onScanButtonPress = useCallback(() => { @@ -82,40 +108,64 @@ const HomeScreen: React.FC = () => { // Prevents back navigation usePreventRemove(true, () => {}); const { bottom } = useSafeAreaInsets(); + + if (loading) { + return ( + + Loading documents... + + ); + } + return ( - - - - Only visible to you - - - - - - - - - Prove your SELF - - + + {documentCatalog.documents.map((metadata: DocumentMetadata) => { + const documentData = allDocuments[metadata.id]; + const isSelected = documentCatalog.selectedDocumentId === metadata.id; + + if (!documentData) { + return null; + } + + return ( + { + setIdDetailsDocumentId(metadata.id); + navigation.navigate('IdDetails'); + }} + > + + ); + })} + ); }; diff --git a/app/src/screens/home/IdDetailsScreen.tsx b/app/src/screens/home/IdDetailsScreen.tsx new file mode 100644 index 000000000..811f6adfe --- /dev/null +++ b/app/src/screens/home/IdDetailsScreen.tsx @@ -0,0 +1,173 @@ +// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc. +// SPDX-License-Identifier: BUSL-1.1 +// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE. + +import React, { useEffect, useState } from 'react'; +import { ScrollView } from 'react-native'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; +import { Button, Text, XStack, YStack, ZStack } from 'tamagui'; +import { BlurView } from '@react-native-community/blur'; +import { useNavigation, useRoute } from '@react-navigation/native'; + +import { DocumentCatalog } from '@selfxyz/common/dist/esm/src/utils/types'; +import { PassportData } from '@selfxyz/common/types'; + +import IdCardLayout from '@/components/homeScreen/idCard'; +import { usePassport } from '@/providers/passportDataProvider'; +import ProofHistoryList from '@/screens/home/ProofHistoryList'; +import useUserStore from '@/stores/userStore'; +import { + black, + slate50, + slate100, + slate300, + slate500, + white, +} from '@/utils/colors'; + +const IdDetailsScreen: React.FC = () => { + const { idDetailsDocumentId } = useUserStore(); + const documentId = idDetailsDocumentId; + const { getAllDocuments, loadDocumentCatalog, setSelectedDocument } = + usePassport(); + const [document, setDocument] = useState(null); + const [documentCatalog, setDocumentCatalog] = useState({ + documents: [], + }); + const [isHidden, setIsHidden] = useState(true); + const navigation = useNavigation(); + const { bottom } = useSafeAreaInsets(); + + useEffect(() => { + const loadDocumentAndCatalog = async () => { + const allDocs = await getAllDocuments(); + const catalog = await loadDocumentCatalog(); + const docEntry = Object.entries(allDocs).find( + ([id]) => id === documentId, + ); + setDocument(docEntry ? docEntry[1].data : null); + setDocumentCatalog(catalog); + }; + loadDocumentAndCatalog(); + }, [documentId, getAllDocuments, loadDocumentCatalog]); + + const isConnected = documentCatalog.selectedDocumentId === documentId; + + const handleConnectId = async () => { + if (!isConnected) { + await setSelectedDocument(documentId!); + const updatedCatalog = await loadDocumentCatalog(); + setDocumentCatalog(updatedCatalog); + } + }; + + if (!documentId) { + return ( + + No document selected + + ); + } + + if (!document) { + return ( + + Loading... + + ); + } + + const ListHeader = ( + + + ); + + return ( + + {ListHeader} + + + + + + + + + ); +}; + +export default IdDetailsScreen; diff --git a/app/src/screens/home/ProofHistoryList.tsx b/app/src/screens/home/ProofHistoryList.tsx new file mode 100644 index 000000000..863e10efd --- /dev/null +++ b/app/src/screens/home/ProofHistoryList.tsx @@ -0,0 +1,420 @@ +// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc. +// SPDX-License-Identifier: BUSL-1.1 +// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE. + +import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import { + ActivityIndicator, + RefreshControl, + SectionList, + StyleSheet, +} from 'react-native'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; +import { Card, Image, Text, View, XStack, YStack } from 'tamagui'; +import { useNavigation } from '@react-navigation/native'; +import { CheckSquare2, Wallet, XCircle } from '@tamagui/lucide-icons'; + +import { BodyText } from '@/components/typography/BodyText'; +import type { ProofHistory } from '@/stores/proof-types'; +import { ProofStatus } from '@/stores/proof-types'; +import { useProofHistoryStore } from '@/stores/proofHistoryStore'; +import { + black, + blue100, + blue600, + red500, + slate50, + slate200, + slate300, + slate400, + slate500, + white, +} from '@/utils/colors'; +import { dinot, plexMono } from '@/utils/fonts'; + +type Section = { + title: string; + data: ProofHistory[]; +}; + +const TIME_PERIODS = { + TODAY: 'TODAY', + THIS_WEEK: 'THIS WEEK', + THIS_MONTH: 'THIS MONTH', + MONTH_NAME: (date: Date): string => { + return date.toLocaleString('default', { month: 'long' }).toUpperCase(); + }, + OLDER: 'OLDER', +}; + +interface ProofHistoryListProps { + documentId: string; +} + +export const ProofHistoryList: React.FC = ({ + documentId, +}) => { + const { + proofHistory, + isLoading, + loadMoreHistory, + resetHistory, + initDatabase, + hasMore, + } = useProofHistoryStore(); + const [refreshing, setRefreshing] = useState(false); + const navigation = useNavigation(); + const { bottom } = useSafeAreaInsets(); + + useEffect(() => { + initDatabase(); + }, [initDatabase]); + + useEffect(() => { + if (!isLoading && refreshing) { + setRefreshing(false); + } + }, [isLoading, refreshing]); + + const formatDate = (timestamp: number) => { + return new Date(timestamp).toLocaleTimeString([], { + hour: '2-digit', + minute: '2-digit', + }); + }; + + const getTimePeriod = useCallback((timestamp: number): string => { + const now = new Date(); + const proofDate = new Date(timestamp); + const startOfToday = new Date( + now.getFullYear(), + now.getMonth(), + now.getDate(), + ); + const startOfThisWeek = new Date(startOfToday); + startOfThisWeek.setDate(startOfToday.getDate() - startOfToday.getDay()); + const startOfThisMonth = new Date(now.getFullYear(), now.getMonth(), 1); + const startOfLastMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1); + + if (proofDate >= startOfToday) { + return TIME_PERIODS.TODAY; + } else if (proofDate >= startOfThisWeek) { + return TIME_PERIODS.THIS_WEEK; + } else if (proofDate >= startOfThisMonth) { + return TIME_PERIODS.THIS_MONTH; + } else if (proofDate >= startOfLastMonth) { + return TIME_PERIODS.MONTH_NAME(proofDate); + } else { + return TIME_PERIODS.OLDER; + } + }, []); + + const groupedProofs = useMemo(() => { + const filteredProofs = proofHistory.filter( + proof => proof.documentId === documentId, + ); + const groups: Record = {}; + + [ + TIME_PERIODS.TODAY, + TIME_PERIODS.THIS_WEEK, + TIME_PERIODS.THIS_MONTH, + TIME_PERIODS.OLDER, + ].forEach(period => { + groups[period] = []; + }); + + const monthGroups = new Set(); + + filteredProofs.forEach(proof => { + const period = getTimePeriod(proof.timestamp); + if ( + period !== TIME_PERIODS.TODAY && + period !== TIME_PERIODS.THIS_WEEK && + period !== TIME_PERIODS.THIS_MONTH && + period !== TIME_PERIODS.OLDER + ) { + monthGroups.add(period); + if (!groups[period]) { + groups[period] = []; + } + } + groups[period].push(proof); + }); + + const sections: Section[] = []; + [ + TIME_PERIODS.TODAY, + TIME_PERIODS.THIS_WEEK, + TIME_PERIODS.THIS_MONTH, + ].forEach(period => { + if (groups[period] && groups[period].length > 0) { + sections.push({ title: period, data: groups[period] }); + } + }); + + Array.from(monthGroups) + .sort( + (a, b) => + new Date(groups[b][0].timestamp).getMonth() - + new Date(groups[a][0].timestamp).getMonth(), + ) + .forEach(month => { + sections.push({ title: month, data: groups[month] }); + }); + + if (groups[TIME_PERIODS.OLDER] && groups[TIME_PERIODS.OLDER].length > 0) { + sections.push({ + title: TIME_PERIODS.OLDER, + data: groups[TIME_PERIODS.OLDER], + }); + } + + return sections; + }, [proofHistory, documentId, getTimePeriod]); + + const renderItem = useCallback( + ({ + item, + index, + section, + }: { + item: ProofHistory; + index: number; + section: Section; + }) => { + try { + const disclosures = JSON.parse(item.disclosures); + const logoSource = item.logoBase64 + ? { + uri: + item.logoBase64.startsWith('data:') || + item.logoBase64.startsWith('http') + ? item.logoBase64 + : `data:image/png;base64,${item.logoBase64}`, + } + : null; + const disclosureCount = Object.values(disclosures).filter( + value => value, + ).length; + const borderRadiusSize = 16; + const isFirstItem = index === 0; + const isLastItem = index === section.data.length - 1; + + return ( + + + + navigation.navigate('ProofHistoryDetail', { data: item }) + } + > + + {logoSource && ( + + )} + + + {item.appName} + + + {formatDate(item.timestamp)} + + + {(item.endpointType === 'staging_celo' || + item.endpointType === 'celo') && ( + + + + )} + {item.status === ProofStatus.FAILURE ? ( + + + FAIL + + + + ) : ( + + + {disclosureCount} + + + + )} + + + + + ); + } catch (e) { + console.error('Error rendering item:', e, item); + return null; + } + }, + [navigation], + ); + + const renderSectionHeader = useCallback( + ({ section }: { section: Section }) => { + return ( + + + {section.title.toUpperCase()} + + + ); + }, + [], + ); + + const onRefresh = useCallback(() => { + setRefreshing(true); + resetHistory(); + loadMoreHistory(); + }, [resetHistory, loadMoreHistory]); + + const keyExtractor = useCallback((item: ProofHistory) => item.sessionId, []); + + const handleEndReached = useCallback(() => { + if (!isLoading && hasMore) { + loadMoreHistory(); + } + }, [isLoading, hasMore, loadMoreHistory]); + + const renderEmptyComponent = useCallback(() => { + if (isLoading) { + return ( + + + + Loading history... + + + ); + } + return ( + + No proof history available for this ID. + + ); + }, [isLoading]); + + const renderFooter = useCallback(() => { + if (!isLoading || refreshing) return null; + return ( + + + + ); + }, [isLoading, refreshing]); + + return ( + + } + contentContainerStyle={[ + styles.listContent, + groupedProofs.length === 0 && styles.emptyList, + ]} + showsVerticalScrollIndicator={false} + stickySectionHeadersEnabled={false} + ListEmptyComponent={renderEmptyComponent} + ListFooterComponent={renderFooter} + initialNumToRender={10} + maxToRenderPerBatch={10} + windowSize={10} + removeClippedSubviews={true} + style={{ marginHorizontal: 15 }} + /> + ); +}; + +const styles = StyleSheet.create({ + listContent: { + paddingBottom: 100, // Add space for the floating Connect ID button + }, + emptyList: { + flexGrow: 1, + }, + emptyContainer: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + }, + footerContainer: { + alignItems: 'center', + }, +}); + +export default ProofHistoryList; diff --git a/app/src/screens/prove/ProveScreen.tsx b/app/src/screens/prove/ProveScreen.tsx index 41693349e..1d505f98d 100644 --- a/app/src/screens/prove/ProveScreen.tsx +++ b/app/src/screens/prove/ProveScreen.tsx @@ -31,7 +31,10 @@ import Disclosures from '@/components/Disclosures'; import { BodyText } from '@/components/typography/BodyText'; import { Caption } from '@/components/typography/Caption'; import { ExpandableBottomLayout } from '@/layouts/ExpandableBottomLayout'; -import { setDefaultDocumentTypeIfNeeded } from '@/providers/passportDataProvider'; +import { + setDefaultDocumentTypeIfNeeded, + usePassport, +} from '@/providers/passportDataProvider'; import { ProofStatus } from '@/stores/proof-types'; import { useProofHistoryStore } from '@/stores/proofHistoryStore'; import { useSelfAppStore } from '@/stores/selfAppStore'; @@ -63,21 +66,29 @@ const ProveScreen: React.FC = () => { const isReadyToProve = currentState === 'ready_to_prove'; const { addProofHistory } = useProofHistoryStore(); + const { loadDocumentCatalog } = usePassport(); useEffect(() => { - if (provingStore.uuid && selectedApp) { - addProofHistory({ - appName: selectedApp.appName, - sessionId: provingStore.uuid!, - userId: selectedApp.userId, - userIdType: selectedApp.userIdType, - endpointType: selectedApp.endpointType, - status: ProofStatus.PENDING, - logoBase64: selectedApp.logoBase64, - disclosures: JSON.stringify(selectedApp.disclosures), - }); - } - }, [addProofHistory, provingStore.uuid, selectedApp]); + const addHistory = async () => { + if (provingStore.uuid && selectedApp) { + const catalog = await loadDocumentCatalog(); + const selectedDocumentId = catalog.selectedDocumentId; + + addProofHistory({ + appName: selectedApp.appName, + sessionId: provingStore.uuid!, + userId: selectedApp.userId, + userIdType: selectedApp.userIdType, + endpointType: selectedApp.endpointType, + status: ProofStatus.PENDING, + logoBase64: selectedApp.logoBase64, + disclosures: JSON.stringify(selectedApp.disclosures), + documentId: selectedDocumentId || '', // Fallback to empty if none selected + }); + } + }; + addHistory(); + }, [addProofHistory, provingStore.uuid, selectedApp, loadDocumentCatalog]); useEffect(() => { if (isContentShorterThanScrollView) { diff --git a/app/src/stores/database.ts b/app/src/stores/database.ts index 2a64e19c9..e782fc7d1 100644 --- a/app/src/stores/database.ts +++ b/app/src/stores/database.ts @@ -97,7 +97,8 @@ export const database: ProofDB = { errorReason TEXT, timestamp INTEGER NOT NULL, disclosures TEXT NOT NULL, - logoBase64 TEXT + logoBase64 TEXT, + documentId TEXT NOT NULL ) `); @@ -109,28 +110,61 @@ export const database: ProofDB = { const db = await openDatabase(); const timestamp = Date.now(); - const [insertResult] = await db.executeSql( - `INSERT OR IGNORE INTO ${TABLE_NAME} (appName, endpointType, status, errorCode, errorReason, timestamp, disclosures, logoBase64, userId, userIdType, sessionId) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, - [ - proof.appName, - proof.endpointType, - proof.status, - proof.errorCode || null, - proof.errorReason || null, + try { + const [insertResult] = await db.executeSql( + `INSERT OR IGNORE INTO ${TABLE_NAME} (appName, endpointType, status, errorCode, errorReason, timestamp, disclosures, logoBase64, userId, userIdType, sessionId, documentId) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, + [ + proof.appName, + proof.endpointType, + proof.status, + proof.errorCode || null, + proof.errorReason || null, + timestamp, + proof.disclosures, + proof.logoBase64 || null, + proof.userId, + proof.userIdType, + proof.sessionId, + proof.documentId, + ], + ); + return { + id: insertResult.insertId.toString(), timestamp, - proof.disclosures, - proof.logoBase64 || null, - proof.userId, - proof.userIdType, - proof.sessionId, - ], - ); - return { - id: insertResult.insertId.toString(), - timestamp, - rowsAffected: insertResult.rowsAffected, - }; + rowsAffected: insertResult.rowsAffected, + }; + } catch (error) { + if ((error as Error).message.includes('no column named documentId')) { + await addDocumentIdColumn(); + // Then retry the insert (copy the executeSql call here) + const [insertResult] = await db.executeSql( + `INSERT OR IGNORE INTO ${TABLE_NAME} (appName, endpointType, status, errorCode, errorReason, timestamp, disclosures, logoBase64, userId, userIdType, sessionId, documentId) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, + [ + proof.appName, + proof.endpointType, + proof.status, + proof.errorCode || null, + proof.errorReason || null, + timestamp, + proof.disclosures, + proof.logoBase64 || null, + proof.userId, + proof.userIdType, + proof.sessionId, + proof.documentId, + ], + ); + return { + id: insertResult.insertId.toString(), + timestamp, + rowsAffected: insertResult.rowsAffected, + }; + } else { + throw error; + } + } }, async updateProofStatus( status: ProofStatus, @@ -147,3 +181,10 @@ export const database: ProofDB = { ); }, }; + +async function addDocumentIdColumn() { + const db = await openDatabase(); + await db.executeSql( + `ALTER TABLE ${TABLE_NAME} ADD COLUMN documentId TEXT NOT NULL DEFAULT ''`, + ); +} diff --git a/app/src/stores/proof-types.ts b/app/src/stores/proof-types.ts index d291bfa9b..41c61fe21 100644 --- a/app/src/stores/proof-types.ts +++ b/app/src/stores/proof-types.ts @@ -42,6 +42,7 @@ export interface ProofHistory { timestamp: number; disclosures: string; logoBase64?: string; + documentId: string; } export enum ProofStatus { diff --git a/app/src/stores/proofHistoryStore.ts b/app/src/stores/proofHistoryStore.ts index 0c64be17c..89ea31d11 100644 --- a/app/src/stores/proofHistoryStore.ts +++ b/app/src/stores/proofHistoryStore.ts @@ -183,6 +183,7 @@ export const useProofHistoryStore = create()((set, get) => { logoBase64: row.logoBase64, userId: row.userId, userIdType: row.userIdType, + documentId: row.documentId, }); } diff --git a/app/src/stores/userStore.ts b/app/src/stores/userStore.ts index 4281d9d35..c1b6398f0 100644 --- a/app/src/stores/userStore.ts +++ b/app/src/stores/userStore.ts @@ -18,8 +18,10 @@ interface UserState { deepLinkNationality?: IdDocInput['nationality']; deepLinkBirthDate?: string; deepLinkGender?: string; + idDetailsDocumentId?: string; update: (patch: Partial) => void; deleteMrzFields: () => void; + setIdDetailsDocumentId: (documentId: string) => void; setDeepLinkUserDetails: (details: { name?: string; surname?: string; @@ -41,6 +43,7 @@ const useUserStore = create((set, _get) => ({ deepLinkNationality: undefined, deepLinkBirthDate: undefined, deepLinkGender: undefined, + idDetailsDocumentId: undefined, update: patch => { set(state => ({ ...state, ...patch })); @@ -64,6 +67,9 @@ const useUserStore = create((set, _get) => ({ deepLinkGender: details.gender, }), + setIdDetailsDocumentId: (documentId: string) => + set({ idDetailsDocumentId: documentId }), + clearDeepLinkUserDetails: () => set({ deepLinkName: undefined, diff --git a/app/src/utils/colors.ts b/app/src/utils/colors.ts index 8dd5a1b44..dbb2062ad 100644 --- a/app/src/utils/colors.ts +++ b/app/src/utils/colors.ts @@ -12,6 +12,8 @@ export const blue700 = '#1D4ED8'; // OLD export const borderColor = '#343434'; +export const charcoal = '#485469'; + export const cyan300 = '#67E8F9'; export const emerald500 = '#10B981'; @@ -28,7 +30,7 @@ export const separatorColor = '#E0E0E0'; export const sky500 = '#0EA5E9'; -export const slate100 = '#F1F5F9'; +export const slate100 = '#F8FAFC'; export const slate200 = '#E2E8F0'; diff --git a/app/src/utils/fonts.ts b/app/src/utils/fonts.ts index 7e570f97b..7cd6e38a9 100644 --- a/app/src/utils/fonts.ts +++ b/app/src/utils/fonts.ts @@ -2,6 +2,9 @@ // SPDX-License-Identifier: BUSL-1.1 // NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE. +import { Platform } from 'react-native'; + export const advercase = 'Advercase-Regular'; export const dinot = 'DINOT-Medium'; -export const plexMono = 'IBM Plex Mono'; +export const plexMono = + Platform.OS === 'ios' ? 'IBM Plex Mono' : 'IBMPlexMono-Regular'; diff --git a/yarn.lock b/yarn.lock index c0825110a..f77170a10 100644 --- a/yarn.lock +++ b/yarn.lock @@ -52,13 +52,20 @@ __metadata: languageName: node linkType: hard -"@babel/compat-data@npm:^7.20.5, @babel/compat-data@npm:^7.27.2, @babel/compat-data@npm:^7.27.7": +"@babel/compat-data@npm:^7.20.5, @babel/compat-data@npm:^7.27.7": version: 7.28.4 resolution: "@babel/compat-data@npm:7.28.4" checksum: 10c0/9d346471e0a016641df9a325f42ad1e8324bbdc0243ce4af4dd2b10b974128590da9eb179eea2c36647b9bb987343119105e96773c1f6981732cd4f87e5a03b9 languageName: node linkType: hard +"@babel/compat-data@npm:^7.27.2": + version: 7.27.5 + resolution: "@babel/compat-data@npm:7.27.5" + checksum: 10c0/da2751fcd0b58eea958f2b2f7ff7d6de1280712b709fa1ad054b73dc7d31f589e353bb50479b9dc96007935f3ed3cada68ac5b45ce93086b7122ddc32e60dc00 + languageName: node + linkType: hard + "@babel/core@npm:^7.28.3": version: 7.28.4 resolution: "@babel/core@npm:7.28.4" @@ -739,7 +746,18 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-destructuring@npm:^7.20.0, @babel/plugin-transform-destructuring@npm:^7.24.8, @babel/plugin-transform-destructuring@npm:^7.28.0": +"@babel/plugin-transform-destructuring@npm:^7.20.0": + version: 7.27.3 + resolution: "@babel/plugin-transform-destructuring@npm:7.27.3" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/f8ac96deef6f9a4cb1dff148dfa2a43116ca1c48434bba433964498c4ef5cef5557693b47463e64a71ffaaf10191c7fab0270844e8dbdc47dc4d120435025df5 + languageName: node + linkType: hard + +"@babel/plugin-transform-destructuring@npm:^7.24.8, @babel/plugin-transform-destructuring@npm:^7.28.0": version: 7.28.0 resolution: "@babel/plugin-transform-destructuring@npm:7.28.0" dependencies: @@ -894,7 +912,18 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-parameters@npm:^7.0.0, @babel/plugin-transform-parameters@npm:^7.20.7, @babel/plugin-transform-parameters@npm:^7.24.7, @babel/plugin-transform-parameters@npm:^7.27.7": +"@babel/plugin-transform-parameters@npm:^7.0.0": + version: 7.27.1 + resolution: "@babel/plugin-transform-parameters@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/453a9618735eeff5551d4c7f02c250606586fe1dd210ec9f69a4f15629ace180cd944339ebff2b0f11e1a40567d83a229ba1c567620e70b2ebedea576e12196a + languageName: node + linkType: hard + +"@babel/plugin-transform-parameters@npm:^7.20.7, @babel/plugin-transform-parameters@npm:^7.24.7, @babel/plugin-transform-parameters@npm:^7.27.7": version: 7.27.7 resolution: "@babel/plugin-transform-parameters@npm:7.27.7" dependencies: @@ -1039,7 +1068,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-typescript@npm:^7.25.2, @babel/plugin-transform-typescript@npm:^7.27.1, @babel/plugin-transform-typescript@npm:^7.5.0": +"@babel/plugin-transform-typescript@npm:^7.25.2": version: 7.28.0 resolution: "@babel/plugin-transform-typescript@npm:7.28.0" dependencies: @@ -1054,6 +1083,21 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-typescript@npm:^7.27.1, @babel/plugin-transform-typescript@npm:^7.5.0": + version: 7.27.1 + resolution: "@babel/plugin-transform-typescript@npm:7.27.1" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.27.1" + "@babel/helper-create-class-features-plugin": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.27.1" + "@babel/plugin-syntax-typescript": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/48f1db5de17a0f9fc365ff4fb046010aedc7aad813a7aa42fb73fcdab6442f9e700dde2cc0481086e01b0dae662ae4d3e965a52cde154f0f146d243a8ac68e93 + languageName: node + linkType: hard + "@babel/plugin-transform-unicode-regex@npm:^7.0.0, @babel/plugin-transform-unicode-regex@npm:^7.24.7": version: 7.27.1 resolution: "@babel/plugin-transform-unicode-regex@npm:7.27.1" @@ -2637,7 +2681,7 @@ __metadata: languageName: node linkType: hard -"@jridgewell/gen-mapping@npm:^0.3.12, @jridgewell/gen-mapping@npm:^0.3.2, @jridgewell/gen-mapping@npm:^0.3.5": +"@jridgewell/gen-mapping@npm:^0.3.12": version: 0.3.13 resolution: "@jridgewell/gen-mapping@npm:0.3.13" dependencies: @@ -2647,6 +2691,17 @@ __metadata: languageName: node linkType: hard +"@jridgewell/gen-mapping@npm:^0.3.2, @jridgewell/gen-mapping@npm:^0.3.5": + version: 0.3.8 + resolution: "@jridgewell/gen-mapping@npm:0.3.8" + dependencies: + "@jridgewell/set-array": "npm:^1.2.1" + "@jridgewell/sourcemap-codec": "npm:^1.4.10" + "@jridgewell/trace-mapping": "npm:^0.3.24" + checksum: 10c0/c668feaf86c501d7c804904a61c23c67447b2137b813b9ce03eca82cb9d65ac7006d766c218685d76e3d72828279b6ee26c347aa1119dab23fbaf36aed51585a + languageName: node + linkType: hard + "@jridgewell/remapping@npm:^2.3.5": version: 2.3.5 resolution: "@jridgewell/remapping@npm:2.3.5" @@ -2664,6 +2719,13 @@ __metadata: languageName: node linkType: hard +"@jridgewell/set-array@npm:^1.2.1": + version: 1.2.1 + resolution: "@jridgewell/set-array@npm:1.2.1" + checksum: 10c0/2a5aa7b4b5c3464c895c802d8ae3f3d2b92fcbe84ad12f8d0bfbb1f5ad006717e7577ee1fd2eac00c088abe486c7adb27976f45d2941ff6b0b92b2c3302c60f4 + languageName: node + linkType: hard + "@jridgewell/source-map@npm:^0.3.3": version: 0.3.11 resolution: "@jridgewell/source-map@npm:0.3.11" @@ -3720,6 +3782,16 @@ __metadata: languageName: node linkType: hard +"@react-native-community/blur@npm:^4.4.1": + version: 4.4.1 + resolution: "@react-native-community/blur@npm:4.4.1" + peerDependencies: + react: "*" + react-native: "*" + checksum: 10c0/f8f3b2e0dc630d93219c5db822a5d283754beedf31b8e481c17bca6f8b2a29d0e24cad4c5013f692f120a3336490dc5b1b3990a68c714c3308151adf92686ad7 + languageName: node + linkType: hard + "@react-native-community/cli-clean@npm:16.0.3": version: 16.0.3 resolution: "@react-native-community/cli-clean@npm:16.0.3" @@ -4335,6 +4407,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-android-arm-eabi@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.44.0" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@rollup/rollup-android-arm-eabi@npm:4.50.0": version: 4.50.0 resolution: "@rollup/rollup-android-arm-eabi@npm:4.50.0" @@ -4342,6 +4421,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-android-arm64@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-android-arm64@npm:4.44.0" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-android-arm64@npm:4.50.0": version: 4.50.0 resolution: "@rollup/rollup-android-arm64@npm:4.50.0" @@ -4349,6 +4435,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-darwin-arm64@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-darwin-arm64@npm:4.44.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-darwin-arm64@npm:4.50.0": version: 4.50.0 resolution: "@rollup/rollup-darwin-arm64@npm:4.50.0" @@ -4356,6 +4449,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-darwin-x64@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-darwin-x64@npm:4.44.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@rollup/rollup-darwin-x64@npm:4.50.0": version: 4.50.0 resolution: "@rollup/rollup-darwin-x64@npm:4.50.0" @@ -4363,6 +4463,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-freebsd-arm64@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.44.0" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-freebsd-arm64@npm:4.50.0": version: 4.50.0 resolution: "@rollup/rollup-freebsd-arm64@npm:4.50.0" @@ -4370,6 +4477,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-freebsd-x64@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-freebsd-x64@npm:4.44.0" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "@rollup/rollup-freebsd-x64@npm:4.50.0": version: 4.50.0 resolution: "@rollup/rollup-freebsd-x64@npm:4.50.0" @@ -4377,6 +4491,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm-gnueabihf@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.44.0" + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-arm-gnueabihf@npm:4.50.0": version: 4.50.0 resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.50.0" @@ -4384,6 +4505,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm-musleabihf@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.44.0" + conditions: os=linux & cpu=arm & libc=musl + languageName: node + linkType: hard + "@rollup/rollup-linux-arm-musleabihf@npm:4.50.0": version: 4.50.0 resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.50.0" @@ -4391,6 +4519,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm64-gnu@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.44.0" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-arm64-gnu@npm:4.50.0": version: 4.50.0 resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.50.0" @@ -4398,6 +4533,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm64-musl@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.44.0" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + "@rollup/rollup-linux-arm64-musl@npm:4.50.0": version: 4.50.0 resolution: "@rollup/rollup-linux-arm64-musl@npm:4.50.0" @@ -4405,6 +4547,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-loongarch64-gnu@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.44.0" + conditions: os=linux & cpu=loong64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-loongarch64-gnu@npm:4.50.0": version: 4.50.0 resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.50.0" @@ -4412,6 +4561,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-powerpc64le-gnu@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.44.0" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-ppc64-gnu@npm:4.50.0": version: 4.50.0 resolution: "@rollup/rollup-linux-ppc64-gnu@npm:4.50.0" @@ -4419,6 +4575,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-riscv64-gnu@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.44.0" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-riscv64-gnu@npm:4.50.0": version: 4.50.0 resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.50.0" @@ -4426,6 +4589,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-riscv64-musl@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.44.0" + conditions: os=linux & cpu=riscv64 & libc=musl + languageName: node + linkType: hard + "@rollup/rollup-linux-riscv64-musl@npm:4.50.0": version: 4.50.0 resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.50.0" @@ -4433,6 +4603,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-s390x-gnu@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.44.0" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-s390x-gnu@npm:4.50.0": version: 4.50.0 resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.50.0" @@ -4440,6 +4617,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-x64-gnu@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.44.0" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-x64-gnu@npm:4.50.0": version: 4.50.0 resolution: "@rollup/rollup-linux-x64-gnu@npm:4.50.0" @@ -4447,6 +4631,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-x64-musl@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.44.0" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + "@rollup/rollup-linux-x64-musl@npm:4.50.0": version: 4.50.0 resolution: "@rollup/rollup-linux-x64-musl@npm:4.50.0" @@ -4461,6 +4652,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-arm64-msvc@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.44.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-win32-arm64-msvc@npm:4.50.0": version: 4.50.0 resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.50.0" @@ -4468,6 +4666,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-ia32-msvc@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.44.0" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@rollup/rollup-win32-ia32-msvc@npm:4.50.0": version: 4.50.0 resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.50.0" @@ -4475,6 +4680,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-x64-msvc@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.44.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@rollup/rollup-win32-x64-msvc@npm:4.50.0": version: 4.50.0 resolution: "@rollup/rollup-win32-x64-msvc@npm:4.50.0" @@ -4802,6 +5014,7 @@ __metadata: "@openpassport/zk-kit-smt": "npm:^0.0.1" "@react-native-async-storage/async-storage": "npm:^2.2.0" "@react-native-clipboard/clipboard": "npm:1.16.3" + "@react-native-community/blur": "npm:^4.4.1" "@react-native-community/cli": "npm:^16.0.3" "@react-native-community/netinfo": "npm:^11.4.1" "@react-native-firebase/app": "npm:^19.0.1" @@ -9525,7 +9738,16 @@ __metadata: languageName: node linkType: hard -"@types/node-forge@npm:^1, @types/node-forge@npm:^1.3.0, @types/node-forge@npm:^1.3.10, @types/node-forge@npm:^1.3.14, @types/node-forge@npm:^1.3.5": +"@types/node-forge@npm:^1, @types/node-forge@npm:^1.3.0, @types/node-forge@npm:^1.3.10, @types/node-forge@npm:^1.3.5": + version: 1.3.11 + resolution: "@types/node-forge@npm:1.3.11" + dependencies: + "@types/node": "npm:*" + checksum: 10c0/3d7d23ca0ba38ac0cf74028393bd70f31169ab9aba43f21deb787840170d307d662644bac07287495effe2812ddd7ac8a14dbd43f16c2936bbb06312e96fc3b9 + languageName: node + linkType: hard + +"@types/node-forge@npm:^1.3.14": version: 1.3.14 resolution: "@types/node-forge@npm:1.3.14" dependencies: @@ -9790,6 +10012,19 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/project-service@npm:8.34.1": + version: 8.34.1 + resolution: "@typescript-eslint/project-service@npm:8.34.1" + dependencies: + "@typescript-eslint/tsconfig-utils": "npm:^8.34.1" + "@typescript-eslint/types": "npm:^8.34.1" + debug: "npm:^4.3.4" + peerDependencies: + typescript: ">=4.8.4 <5.9.0" + checksum: 10c0/9333a890625f6777054db17a6b299281ae7502bb7615261d15b885a75b8cf65fc91591389c93b37ecd14b651d8e94851dac8718e5dcc8ed0600533535dae855c + languageName: node + linkType: hard + "@typescript-eslint/project-service@npm:8.42.0": version: 8.42.0 resolution: "@typescript-eslint/project-service@npm:8.42.0" @@ -9813,6 +10048,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/scope-manager@npm:8.34.1": + version: 8.34.1 + resolution: "@typescript-eslint/scope-manager@npm:8.34.1" + dependencies: + "@typescript-eslint/types": "npm:8.34.1" + "@typescript-eslint/visitor-keys": "npm:8.34.1" + checksum: 10c0/2af608fa3900f4726322e33bf4f3a376fdace3ac0f310cf7d9256bbc2905c3896138176a47dd195d2c2229f27fe43f5deb4bc7729db2eb18389926dedea78077 + languageName: node + linkType: hard + "@typescript-eslint/scope-manager@npm:8.42.0": version: 8.42.0 resolution: "@typescript-eslint/scope-manager@npm:8.42.0" @@ -9823,6 +10068,15 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/tsconfig-utils@npm:8.34.1, @typescript-eslint/tsconfig-utils@npm:^8.34.1": + version: 8.34.1 + resolution: "@typescript-eslint/tsconfig-utils@npm:8.34.1" + peerDependencies: + typescript: ">=4.8.4 <5.9.0" + checksum: 10c0/8d1ead8b7c279b48e2ed96f083ec119a9aeea1ca9cdd40576ec271b996b9fd8cfa0ddb0aafbb4e14bc27fc62c69c5be66d39b1de68eab9ddd7f1861da267423d + languageName: node + linkType: hard + "@typescript-eslint/tsconfig-utils@npm:8.42.0, @typescript-eslint/tsconfig-utils@npm:^8.42.0": version: 8.42.0 resolution: "@typescript-eslint/tsconfig-utils@npm:8.42.0" @@ -9855,6 +10109,13 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/types@npm:8.34.1, @typescript-eslint/types@npm:^8.34.1": + version: 8.34.1 + resolution: "@typescript-eslint/types@npm:8.34.1" + checksum: 10c0/db1b3dce6a70b28ddb13c76fbb5983240d9395656df5f7cbd99bfd9905e39c0dab2132870f01dbc406b48739c437f7d344a879a824cedaba81b91a53110dc23a + languageName: node + linkType: hard + "@typescript-eslint/types@npm:8.42.0, @typescript-eslint/types@npm:^8.42.0": version: 8.42.0 resolution: "@typescript-eslint/types@npm:8.42.0" @@ -9880,6 +10141,26 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/typescript-estree@npm:8.34.1": + version: 8.34.1 + resolution: "@typescript-eslint/typescript-estree@npm:8.34.1" + dependencies: + "@typescript-eslint/project-service": "npm:8.34.1" + "@typescript-eslint/tsconfig-utils": "npm:8.34.1" + "@typescript-eslint/types": "npm:8.34.1" + "@typescript-eslint/visitor-keys": "npm:8.34.1" + debug: "npm:^4.3.4" + fast-glob: "npm:^3.3.2" + is-glob: "npm:^4.0.3" + minimatch: "npm:^9.0.4" + semver: "npm:^7.6.0" + ts-api-utils: "npm:^2.1.0" + peerDependencies: + typescript: ">=4.8.4 <5.9.0" + checksum: 10c0/4ee7249db91b9840361f34f80b7b6d646a3af159c7298d79a33d8a11c98792fd3a395343e5e17e0fa29529e8f0113bac8baadcef90d1e140bd736a48f0485042 + languageName: node + linkType: hard + "@typescript-eslint/typescript-estree@npm:8.42.0": version: 8.42.0 resolution: "@typescript-eslint/typescript-estree@npm:8.42.0" @@ -9900,7 +10181,7 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/utils@npm:8.42.0, @typescript-eslint/utils@npm:^6.0.0 || ^7.0.0 || ^8.0.0": +"@typescript-eslint/utils@npm:8.42.0": version: 8.42.0 resolution: "@typescript-eslint/utils@npm:8.42.0" dependencies: @@ -9933,6 +10214,21 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/utils@npm:^6.0.0 || ^7.0.0 || ^8.0.0": + version: 8.34.1 + resolution: "@typescript-eslint/utils@npm:8.34.1" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.7.0" + "@typescript-eslint/scope-manager": "npm:8.34.1" + "@typescript-eslint/types": "npm:8.34.1" + "@typescript-eslint/typescript-estree": "npm:8.34.1" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <5.9.0" + checksum: 10c0/e3085877f7940c02a37653e6bc52ac6cde115e755b1f788fe4331202f371b3421cc4d0878c7d3eb054e14e9b3a064496a707a73eac471cb2b73593b9e9d4b998 + languageName: node + linkType: hard + "@typescript-eslint/visitor-keys@npm:5.62.0": version: 5.62.0 resolution: "@typescript-eslint/visitor-keys@npm:5.62.0" @@ -9943,6 +10239,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/visitor-keys@npm:8.34.1": + version: 8.34.1 + resolution: "@typescript-eslint/visitor-keys@npm:8.34.1" + dependencies: + "@typescript-eslint/types": "npm:8.34.1" + eslint-visitor-keys: "npm:^4.2.1" + checksum: 10c0/0e5a9b3d93905d16d3cf8cb5fb346dcc6f760482eb7d0ac209aefc09a32f78ef28a687634df6ad08e81fb3e1083e8805f34472de6bbc501c0105ad654d518f40 + languageName: node + linkType: hard + "@typescript-eslint/visitor-keys@npm:8.42.0": version: 8.42.0 resolution: "@typescript-eslint/visitor-keys@npm:8.42.0" @@ -11845,7 +12151,7 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.22.2, browserslist@npm:^4.24.0, browserslist@npm:^4.25.3": +"browserslist@npm:^4.22.2, browserslist@npm:^4.25.3": version: 4.25.4 resolution: "browserslist@npm:4.25.4" dependencies: @@ -11859,6 +12165,20 @@ __metadata: languageName: node linkType: hard +"browserslist@npm:^4.24.0": + version: 4.25.0 + resolution: "browserslist@npm:4.25.0" + dependencies: + caniuse-lite: "npm:^1.0.30001718" + electron-to-chromium: "npm:^1.5.160" + node-releases: "npm:^2.0.19" + update-browserslist-db: "npm:^1.1.3" + bin: + browserslist: cli.js + checksum: 10c0/cc16c55b4468b18684a0e1ca303592b38635b1155d6724f172407192737a2f405b8030d87a05813729592793445b3d15e737b0055f901cdecccb29b1e580a1c5 + languageName: node + linkType: hard + "bs58@npm:^4.0.0": version: 4.0.1 resolution: "bs58@npm:4.0.1" @@ -12088,6 +12408,13 @@ __metadata: languageName: node linkType: hard +"caniuse-lite@npm:^1.0.30001718": + version: 1.0.30001724 + resolution: "caniuse-lite@npm:1.0.30001724" + checksum: 10c0/ed9ec0bcf619f0e7ef2d33aac74d2346d1faf52060dfded1fb9c32d87854de5c2988b3ba338c281034c88bf797d6b55468a804ce8396a7e16a48cb0d481d4bfe + languageName: node + linkType: hard + "caniuse-lite@npm:^1.0.30001737": version: 1.0.30001741 resolution: "caniuse-lite@npm:1.0.30001741" @@ -13734,6 +14061,13 @@ __metadata: languageName: node linkType: hard +"electron-to-chromium@npm:^1.5.160": + version: 1.5.171 + resolution: "electron-to-chromium@npm:1.5.171" + checksum: 10c0/e9d7e70d5fe829951c955287877155889a752336e48c715e373c6919f8e438bb686b7278511013aa8456c329c55895059a1d9e4b799217483f28dbae60c198d8 + languageName: node + linkType: hard + "electron-to-chromium@npm:^1.5.211": version: 1.5.214 resolution: "electron-to-chromium@npm:1.5.214" @@ -14637,7 +14971,7 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-prettier@npm:^5.1.3, eslint-plugin-prettier@npm:^5.2.6, eslint-plugin-prettier@npm:^5.5.4": +"eslint-plugin-prettier@npm:^5.1.3, eslint-plugin-prettier@npm:^5.5.4": version: 5.5.4 resolution: "eslint-plugin-prettier@npm:5.5.4" dependencies: @@ -14657,6 +14991,26 @@ __metadata: languageName: node linkType: hard +"eslint-plugin-prettier@npm:^5.2.6": + version: 5.5.0 + resolution: "eslint-plugin-prettier@npm:5.5.0" + dependencies: + prettier-linter-helpers: "npm:^1.0.0" + synckit: "npm:^0.11.7" + 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" + peerDependenciesMeta: + "@types/eslint": + optional: true + eslint-config-prettier: + optional: true + checksum: 10c0/d739940d5f5ea9b4c3a52836b24907b273a46909cdd1def5526f8934e54082fe5aac13512eb2c27d538ca79e16916ca54c651e3372aa53b7d4297afb4c156d47 + languageName: node + linkType: hard + "eslint-plugin-react-hooks@npm:^4.6.0": version: 4.6.2 resolution: "eslint-plugin-react-hooks@npm:4.6.2" @@ -18959,7 +19313,7 @@ __metadata: languageName: node linkType: hard -"magic-string@npm:^0.30.12, magic-string@npm:^0.30.17, magic-string@npm:^0.30.5": +"magic-string@npm:^0.30.12": version: 0.30.18 resolution: "magic-string@npm:0.30.18" dependencies: @@ -18968,6 +19322,15 @@ __metadata: languageName: node linkType: hard +"magic-string@npm:^0.30.17, magic-string@npm:^0.30.5": + version: 0.30.17 + resolution: "magic-string@npm:0.30.17" + dependencies: + "@jridgewell/sourcemap-codec": "npm:^1.5.0" + checksum: 10c0/16826e415d04b88378f200fe022b53e638e3838b9e496edda6c0e086d7753a44a6ed187adc72d19f3623810589bf139af1a315541cd6a26ae0771a0193eaf7b8 + languageName: node + linkType: hard + "make-dir@npm:^2.0.0, make-dir@npm:^2.1.0": version: 2.1.0 resolution: "make-dir@npm:2.1.0" @@ -20948,13 +21311,20 @@ __metadata: languageName: node linkType: hard -"picomatch@npm:^4.0.1, picomatch@npm:^4.0.2, picomatch@npm:^4.0.3": +"picomatch@npm:^4.0.1, picomatch@npm:^4.0.3": version: 4.0.3 resolution: "picomatch@npm:4.0.3" checksum: 10c0/9582c951e95eebee5434f59e426cddd228a7b97a0161a375aed4be244bd3fe8e3a31b846808ea14ef2c8a2527a6eeab7b3946a67d5979e81694654f939473ae2 languageName: node linkType: hard +"picomatch@npm:^4.0.2": + version: 4.0.2 + resolution: "picomatch@npm:4.0.2" + checksum: 10c0/7c51f3ad2bb42c776f49ebf964c644958158be30d0a510efd5a395e8d49cb5acfed5b82c0c5b365523ce18e6ab85013c9ebe574f60305892ec3fa8eee8304ccc + languageName: node + linkType: hard + "pify@npm:^4.0.1": version: 4.0.1 resolution: "pify@npm:4.0.1" @@ -22589,7 +22959,7 @@ __metadata: languageName: node linkType: hard -"rollup@npm:^4.20.0, rollup@npm:^4.34.8, rollup@npm:^4.43.0": +"rollup@npm:^4.20.0, rollup@npm:^4.43.0": version: 4.50.0 resolution: "rollup@npm:4.50.0" dependencies: @@ -22667,6 +23037,81 @@ __metadata: languageName: node linkType: hard +"rollup@npm:^4.34.8": + version: 4.44.0 + resolution: "rollup@npm:4.44.0" + dependencies: + "@rollup/rollup-android-arm-eabi": "npm:4.44.0" + "@rollup/rollup-android-arm64": "npm:4.44.0" + "@rollup/rollup-darwin-arm64": "npm:4.44.0" + "@rollup/rollup-darwin-x64": "npm:4.44.0" + "@rollup/rollup-freebsd-arm64": "npm:4.44.0" + "@rollup/rollup-freebsd-x64": "npm:4.44.0" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.44.0" + "@rollup/rollup-linux-arm-musleabihf": "npm:4.44.0" + "@rollup/rollup-linux-arm64-gnu": "npm:4.44.0" + "@rollup/rollup-linux-arm64-musl": "npm:4.44.0" + "@rollup/rollup-linux-loongarch64-gnu": "npm:4.44.0" + "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.44.0" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.44.0" + "@rollup/rollup-linux-riscv64-musl": "npm:4.44.0" + "@rollup/rollup-linux-s390x-gnu": "npm:4.44.0" + "@rollup/rollup-linux-x64-gnu": "npm:4.44.0" + "@rollup/rollup-linux-x64-musl": "npm:4.44.0" + "@rollup/rollup-win32-arm64-msvc": "npm:4.44.0" + "@rollup/rollup-win32-ia32-msvc": "npm:4.44.0" + "@rollup/rollup-win32-x64-msvc": "npm:4.44.0" + "@types/estree": "npm:1.0.8" + fsevents: "npm:~2.3.2" + dependenciesMeta: + "@rollup/rollup-android-arm-eabi": + optional: true + "@rollup/rollup-android-arm64": + optional: true + "@rollup/rollup-darwin-arm64": + optional: true + "@rollup/rollup-darwin-x64": + optional: true + "@rollup/rollup-freebsd-arm64": + optional: true + "@rollup/rollup-freebsd-x64": + optional: true + "@rollup/rollup-linux-arm-gnueabihf": + optional: true + "@rollup/rollup-linux-arm-musleabihf": + optional: true + "@rollup/rollup-linux-arm64-gnu": + optional: true + "@rollup/rollup-linux-arm64-musl": + optional: true + "@rollup/rollup-linux-loongarch64-gnu": + optional: true + "@rollup/rollup-linux-powerpc64le-gnu": + optional: true + "@rollup/rollup-linux-riscv64-gnu": + optional: true + "@rollup/rollup-linux-riscv64-musl": + optional: true + "@rollup/rollup-linux-s390x-gnu": + optional: true + "@rollup/rollup-linux-x64-gnu": + optional: true + "@rollup/rollup-linux-x64-musl": + optional: true + "@rollup/rollup-win32-arm64-msvc": + optional: true + "@rollup/rollup-win32-ia32-msvc": + optional: true + "@rollup/rollup-win32-x64-msvc": + optional: true + fsevents: + optional: true + bin: + rollup: dist/bin/rollup + checksum: 10c0/ff3e0741f2fc7b7b183079628cf50fcfc9163bef86ecfbc9f4e4023adfdee375b7075940963514e2bc4969764688d38d67095bce038b0ad5d572207f114afff5 + languageName: node + linkType: hard + "rrweb-cssom@npm:^0.7.1": version: 0.7.1 resolution: "rrweb-cssom@npm:0.7.1"