@entropy-softworks/ui 2026.7.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +96 -0
- package/LICENSE +21 -0
- package/README.md +115 -0
- package/lib/components/auth/LockOverlay.d.ts +22 -0
- package/lib/components/auth/LockOverlay.d.ts.map +1 -0
- package/lib/components/auth/LockOverlay.jsx +82 -0
- package/lib/components/auth/LockOverlay.jsx.map +1 -0
- package/lib/components/auth/PasswordStrengthMeter.d.ts +12 -0
- package/lib/components/auth/PasswordStrengthMeter.d.ts.map +1 -0
- package/lib/components/auth/PasswordStrengthMeter.jsx +81 -0
- package/lib/components/auth/PasswordStrengthMeter.jsx.map +1 -0
- package/lib/components/auth/ProtectedRoute.d.ts +24 -0
- package/lib/components/auth/ProtectedRoute.d.ts.map +1 -0
- package/lib/components/auth/ProtectedRoute.jsx +56 -0
- package/lib/components/auth/ProtectedRoute.jsx.map +1 -0
- package/lib/components/auth/PwnedPasswordWarning.d.ts +13 -0
- package/lib/components/auth/PwnedPasswordWarning.d.ts.map +1 -0
- package/lib/components/auth/PwnedPasswordWarning.jsx +29 -0
- package/lib/components/auth/PwnedPasswordWarning.jsx.map +1 -0
- package/lib/components/auth/index.d.ts +5 -0
- package/lib/components/auth/index.d.ts.map +1 -0
- package/lib/components/auth/index.js +5 -0
- package/lib/components/auth/index.js.map +1 -0
- package/lib/components/bottom-nav.d.ts +25 -0
- package/lib/components/bottom-nav.d.ts.map +1 -0
- package/lib/components/bottom-nav.jsx +51 -0
- package/lib/components/bottom-nav.jsx.map +1 -0
- package/lib/components/button.d.ts +16 -0
- package/lib/components/button.d.ts.map +1 -0
- package/lib/components/button.jsx +73 -0
- package/lib/components/button.jsx.map +1 -0
- package/lib/components/card.d.ts +22 -0
- package/lib/components/card.d.ts.map +1 -0
- package/lib/components/card.jsx +36 -0
- package/lib/components/card.jsx.map +1 -0
- package/lib/components/checkbox.d.ts +12 -0
- package/lib/components/checkbox.d.ts.map +1 -0
- package/lib/components/checkbox.jsx +16 -0
- package/lib/components/checkbox.jsx.map +1 -0
- package/lib/components/connection-settings.d.ts +41 -0
- package/lib/components/connection-settings.d.ts.map +1 -0
- package/lib/components/connection-settings.jsx +354 -0
- package/lib/components/connection-settings.jsx.map +1 -0
- package/lib/components/context-menu.d.ts +52 -0
- package/lib/components/context-menu.d.ts.map +1 -0
- package/lib/components/context-menu.jsx +24 -0
- package/lib/components/context-menu.jsx.map +1 -0
- package/lib/components/data-table.d.ts +59 -0
- package/lib/components/data-table.d.ts.map +1 -0
- package/lib/components/data-table.jsx +101 -0
- package/lib/components/data-table.jsx.map +1 -0
- package/lib/components/dialog.d.ts +58 -0
- package/lib/components/dialog.d.ts.map +1 -0
- package/lib/components/dialog.jsx +197 -0
- package/lib/components/dialog.jsx.map +1 -0
- package/lib/components/dropdown-menu.d.ts +55 -0
- package/lib/components/dropdown-menu.d.ts.map +1 -0
- package/lib/components/dropdown-menu.jsx +38 -0
- package/lib/components/dropdown-menu.jsx.map +1 -0
- package/lib/components/entropy-boot-splash.d.ts +24 -0
- package/lib/components/entropy-boot-splash.d.ts.map +1 -0
- package/lib/components/entropy-boot-splash.jsx +83 -0
- package/lib/components/entropy-boot-splash.jsx.map +1 -0
- package/lib/components/entropy-mark-animated.d.ts +20 -0
- package/lib/components/entropy-mark-animated.d.ts.map +1 -0
- package/lib/components/entropy-mark-animated.jsx +148 -0
- package/lib/components/entropy-mark-animated.jsx.map +1 -0
- package/lib/components/entropy-mark-geometry.d.ts +8 -0
- package/lib/components/entropy-mark-geometry.d.ts.map +1 -0
- package/lib/components/entropy-mark-geometry.js +10 -0
- package/lib/components/entropy-mark-geometry.js.map +1 -0
- package/lib/components/entropy-mark-sequential.d.ts +12 -0
- package/lib/components/entropy-mark-sequential.d.ts.map +1 -0
- package/lib/components/entropy-mark-sequential.jsx +53 -0
- package/lib/components/entropy-mark-sequential.jsx.map +1 -0
- package/lib/components/entropy-mark.d.ts +29 -0
- package/lib/components/entropy-mark.d.ts.map +1 -0
- package/lib/components/entropy-mark.jsx +66 -0
- package/lib/components/entropy-mark.jsx.map +1 -0
- package/lib/components/error-boundary.d.ts +31 -0
- package/lib/components/error-boundary.d.ts.map +1 -0
- package/lib/components/error-boundary.jsx +40 -0
- package/lib/components/error-boundary.jsx.map +1 -0
- package/lib/components/index.d.ts +41 -0
- package/lib/components/index.d.ts.map +1 -0
- package/lib/components/index.js +43 -0
- package/lib/components/index.js.map +1 -0
- package/lib/components/input.d.ts +26 -0
- package/lib/components/input.d.ts.map +1 -0
- package/lib/components/input.jsx +95 -0
- package/lib/components/input.jsx.map +1 -0
- package/lib/components/item-icon.d.ts +32 -0
- package/lib/components/item-icon.d.ts.map +1 -0
- package/lib/components/item-icon.jsx +54 -0
- package/lib/components/item-icon.jsx.map +1 -0
- package/lib/components/label.d.ts +13 -0
- package/lib/components/label.d.ts.map +1 -0
- package/lib/components/label.jsx +9 -0
- package/lib/components/label.jsx.map +1 -0
- package/lib/components/legal-dialog.d.ts +18 -0
- package/lib/components/legal-dialog.d.ts.map +1 -0
- package/lib/components/legal-dialog.jsx +31 -0
- package/lib/components/legal-dialog.jsx.map +1 -0
- package/lib/components/license-gate.d.ts +17 -0
- package/lib/components/license-gate.d.ts.map +1 -0
- package/lib/components/license-gate.jsx +21 -0
- package/lib/components/license-gate.jsx.map +1 -0
- package/lib/components/logo.d.ts +15 -0
- package/lib/components/logo.d.ts.map +1 -0
- package/lib/components/logo.jsx +20 -0
- package/lib/components/logo.jsx.map +1 -0
- package/lib/components/onboarding-wizard.d.ts +89 -0
- package/lib/components/onboarding-wizard.d.ts.map +1 -0
- package/lib/components/onboarding-wizard.jsx +185 -0
- package/lib/components/onboarding-wizard.jsx.map +1 -0
- package/lib/components/pagination.d.ts +43 -0
- package/lib/components/pagination.d.ts.map +1 -0
- package/lib/components/pagination.jsx +72 -0
- package/lib/components/pagination.jsx.map +1 -0
- package/lib/components/password-generator.d.ts +15 -0
- package/lib/components/password-generator.d.ts.map +1 -0
- package/lib/components/password-generator.jsx +273 -0
- package/lib/components/password-generator.jsx.map +1 -0
- package/lib/components/pin-pad.d.ts +20 -0
- package/lib/components/pin-pad.d.ts.map +1 -0
- package/lib/components/pin-pad.jsx +93 -0
- package/lib/components/pin-pad.jsx.map +1 -0
- package/lib/components/popover.d.ts +27 -0
- package/lib/components/popover.d.ts.map +1 -0
- package/lib/components/popover.jsx +18 -0
- package/lib/components/popover.jsx.map +1 -0
- package/lib/components/profile/ProfileDialog.d.ts +25 -0
- package/lib/components/profile/ProfileDialog.d.ts.map +1 -0
- package/lib/components/profile/ProfileDialog.jsx +71 -0
- package/lib/components/profile/ProfileDialog.jsx.map +1 -0
- package/lib/components/profile/ProfileTab.d.ts +12 -0
- package/lib/components/profile/ProfileTab.d.ts.map +1 -0
- package/lib/components/profile/ProfileTab.jsx +112 -0
- package/lib/components/profile/ProfileTab.jsx.map +1 -0
- package/lib/components/profile/SecurityTab.d.ts +32 -0
- package/lib/components/profile/SecurityTab.d.ts.map +1 -0
- package/lib/components/profile/SecurityTab.jsx +145 -0
- package/lib/components/profile/SecurityTab.jsx.map +1 -0
- package/lib/components/profile/index.d.ts +4 -0
- package/lib/components/profile/index.d.ts.map +1 -0
- package/lib/components/profile/index.js +4 -0
- package/lib/components/profile/index.js.map +1 -0
- package/lib/components/segmented-toggle.d.ts +28 -0
- package/lib/components/segmented-toggle.d.ts.map +1 -0
- package/lib/components/segmented-toggle.jsx +64 -0
- package/lib/components/segmented-toggle.jsx.map +1 -0
- package/lib/components/separator.d.ts +13 -0
- package/lib/components/separator.d.ts.map +1 -0
- package/lib/components/separator.jsx +16 -0
- package/lib/components/separator.jsx.map +1 -0
- package/lib/components/server-settings.d.ts +27 -0
- package/lib/components/server-settings.d.ts.map +1 -0
- package/lib/components/server-settings.jsx +307 -0
- package/lib/components/server-settings.jsx.map +1 -0
- package/lib/components/settings/AccountSection.d.ts +26 -0
- package/lib/components/settings/AccountSection.d.ts.map +1 -0
- package/lib/components/settings/AccountSection.jsx +32 -0
- package/lib/components/settings/AccountSection.jsx.map +1 -0
- package/lib/components/settings/DangerZoneSection.d.ts +13 -0
- package/lib/components/settings/DangerZoneSection.d.ts.map +1 -0
- package/lib/components/settings/DangerZoneSection.jsx +16 -0
- package/lib/components/settings/DangerZoneSection.jsx.map +1 -0
- package/lib/components/settings/GeneralSection.d.ts +11 -0
- package/lib/components/settings/GeneralSection.d.ts.map +1 -0
- package/lib/components/settings/GeneralSection.jsx +12 -0
- package/lib/components/settings/GeneralSection.jsx.map +1 -0
- package/lib/components/settings/SupportSection.d.ts +11 -0
- package/lib/components/settings/SupportSection.d.ts.map +1 -0
- package/lib/components/settings/SupportSection.jsx +22 -0
- package/lib/components/settings/SupportSection.jsx.map +1 -0
- package/lib/components/settings/index.d.ts +5 -0
- package/lib/components/settings/index.d.ts.map +1 -0
- package/lib/components/settings/index.js +5 -0
- package/lib/components/settings/index.js.map +1 -0
- package/lib/components/settings-row.d.ts +28 -0
- package/lib/components/settings-row.d.ts.map +1 -0
- package/lib/components/settings-row.jsx +68 -0
- package/lib/components/settings-row.jsx.map +1 -0
- package/lib/components/skeleton.d.ts +8 -0
- package/lib/components/skeleton.d.ts.map +1 -0
- package/lib/components/skeleton.jsx +24 -0
- package/lib/components/skeleton.jsx.map +1 -0
- package/lib/components/social-connections.d.ts +15 -0
- package/lib/components/social-connections.d.ts.map +1 -0
- package/lib/components/social-connections.jsx +31 -0
- package/lib/components/social-connections.jsx.map +1 -0
- package/lib/components/stat-card.d.ts +29 -0
- package/lib/components/stat-card.d.ts.map +1 -0
- package/lib/components/stat-card.jsx +36 -0
- package/lib/components/stat-card.jsx.map +1 -0
- package/lib/components/tag-chip.d.ts +18 -0
- package/lib/components/tag-chip.d.ts.map +1 -0
- package/lib/components/tag-chip.jsx +54 -0
- package/lib/components/tag-chip.jsx.map +1 -0
- package/lib/components/tag-multi-select.d.ts +27 -0
- package/lib/components/tag-multi-select.d.ts.map +1 -0
- package/lib/components/tag-multi-select.jsx +65 -0
- package/lib/components/tag-multi-select.jsx.map +1 -0
- package/lib/components/text.d.ts +22 -0
- package/lib/components/text.d.ts.map +1 -0
- package/lib/components/text.jsx +43 -0
- package/lib/components/text.jsx.map +1 -0
- package/lib/components/toast/ToastPortal.d.ts +11 -0
- package/lib/components/toast/ToastPortal.d.ts.map +1 -0
- package/lib/components/toast/ToastPortal.jsx +15 -0
- package/lib/components/toast/ToastPortal.jsx.map +1 -0
- package/lib/components/toast/ToastPortal.web.d.ts +14 -0
- package/lib/components/toast/ToastPortal.web.d.ts.map +1 -0
- package/lib/components/toast/ToastPortal.web.jsx +39 -0
- package/lib/components/toast/ToastPortal.web.jsx.map +1 -0
- package/lib/components/toast/index.d.ts +3 -0
- package/lib/components/toast/index.d.ts.map +1 -0
- package/lib/components/toast/index.js +3 -0
- package/lib/components/toast/index.js.map +1 -0
- package/lib/components/toast/toast-config.d.ts +14 -0
- package/lib/components/toast/toast-config.d.ts.map +1 -0
- package/lib/components/toast/toast-config.jsx +24 -0
- package/lib/components/toast/toast-config.jsx.map +1 -0
- package/lib/components/tooltip.d.ts +30 -0
- package/lib/components/tooltip.d.ts.map +1 -0
- package/lib/components/tooltip.jsx +14 -0
- package/lib/components/tooltip.jsx.map +1 -0
- package/lib/components/totp-display.d.ts +23 -0
- package/lib/components/totp-display.d.ts.map +1 -0
- package/lib/components/totp-display.jsx +132 -0
- package/lib/components/totp-display.jsx.map +1 -0
- package/lib/components/user-avatar.d.ts +18 -0
- package/lib/components/user-avatar.d.ts.map +1 -0
- package/lib/components/user-avatar.jsx +25 -0
- package/lib/components/user-avatar.jsx.map +1 -0
- package/lib/context/AppConfigContext.d.ts +56 -0
- package/lib/context/AppConfigContext.d.ts.map +1 -0
- package/lib/context/AppConfigContext.jsx +14 -0
- package/lib/context/AppConfigContext.jsx.map +1 -0
- package/lib/context/NavigationContext.d.ts +42 -0
- package/lib/context/NavigationContext.d.ts.map +1 -0
- package/lib/context/NavigationContext.jsx +53 -0
- package/lib/context/NavigationContext.jsx.map +1 -0
- package/lib/context/NotificationContext.d.ts +32 -0
- package/lib/context/NotificationContext.d.ts.map +1 -0
- package/lib/context/NotificationContext.jsx +49 -0
- package/lib/context/NotificationContext.jsx.map +1 -0
- package/lib/context/ThemeContext.d.ts +12 -0
- package/lib/context/ThemeContext.d.ts.map +1 -0
- package/lib/context/ThemeContext.jsx +66 -0
- package/lib/context/ThemeContext.jsx.map +1 -0
- package/lib/context/index.d.ts +5 -0
- package/lib/context/index.d.ts.map +1 -0
- package/lib/context/index.js +5 -0
- package/lib/context/index.js.map +1 -0
- package/lib/flags.d.ts +9 -0
- package/lib/flags.d.ts.map +1 -0
- package/lib/flags.js +37 -0
- package/lib/flags.js.map +1 -0
- package/lib/forms/form-error.d.ts +12 -0
- package/lib/forms/form-error.d.ts.map +1 -0
- package/lib/forms/form-error.jsx +14 -0
- package/lib/forms/form-error.jsx.map +1 -0
- package/lib/forms/index.d.ts +3 -0
- package/lib/forms/index.d.ts.map +1 -0
- package/lib/forms/index.js +3 -0
- package/lib/forms/index.js.map +1 -0
- package/lib/forms/shake-field.d.ts +18 -0
- package/lib/forms/shake-field.d.ts.map +1 -0
- package/lib/forms/shake-field.jsx +30 -0
- package/lib/forms/shake-field.jsx.map +1 -0
- package/lib/hooks/index.d.ts +6 -0
- package/lib/hooks/index.d.ts.map +1 -0
- package/lib/hooks/index.js +6 -0
- package/lib/hooks/index.js.map +1 -0
- package/lib/hooks/useAuth.d.ts +109 -0
- package/lib/hooks/useAuth.d.ts.map +1 -0
- package/lib/hooks/useAuth.jsx +404 -0
- package/lib/hooks/useAuth.jsx.map +1 -0
- package/lib/hooks/useAutoLock.d.ts +22 -0
- package/lib/hooks/useAutoLock.d.ts.map +1 -0
- package/lib/hooks/useAutoLock.js +85 -0
- package/lib/hooks/useAutoLock.js.map +1 -0
- package/lib/hooks/useDebouncedValue.d.ts +19 -0
- package/lib/hooks/useDebouncedValue.d.ts.map +1 -0
- package/lib/hooks/useDebouncedValue.js +29 -0
- package/lib/hooks/useDebouncedValue.js.map +1 -0
- package/lib/hooks/useShakeAnimation.d.ts +17 -0
- package/lib/hooks/useShakeAnimation.d.ts.map +1 -0
- package/lib/hooks/useShakeAnimation.js +22 -0
- package/lib/hooks/useShakeAnimation.js.map +1 -0
- package/lib/hooks/useUploadBlobUrl.d.ts +13 -0
- package/lib/hooks/useUploadBlobUrl.d.ts.map +1 -0
- package/lib/hooks/useUploadBlobUrl.js +60 -0
- package/lib/hooks/useUploadBlobUrl.js.map +1 -0
- package/lib/index.d.ts +10 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +47 -0
- package/lib/index.js.map +1 -0
- package/lib/screens/auth/AccountPickerScreen.d.ts +24 -0
- package/lib/screens/auth/AccountPickerScreen.d.ts.map +1 -0
- package/lib/screens/auth/AccountPickerScreen.jsx +47 -0
- package/lib/screens/auth/AccountPickerScreen.jsx.map +1 -0
- package/lib/screens/auth/AuthScreen.d.ts +59 -0
- package/lib/screens/auth/AuthScreen.d.ts.map +1 -0
- package/lib/screens/auth/AuthScreen.jsx +594 -0
- package/lib/screens/auth/AuthScreen.jsx.map +1 -0
- package/lib/screens/auth/ConsentScreen.d.ts +27 -0
- package/lib/screens/auth/ConsentScreen.d.ts.map +1 -0
- package/lib/screens/auth/ConsentScreen.jsx +55 -0
- package/lib/screens/auth/ConsentScreen.jsx.map +1 -0
- package/lib/screens/auth/ErrorScreen.d.ts +20 -0
- package/lib/screens/auth/ErrorScreen.d.ts.map +1 -0
- package/lib/screens/auth/ErrorScreen.jsx +43 -0
- package/lib/screens/auth/ErrorScreen.jsx.map +1 -0
- package/lib/screens/auth/ExpiredLinkScreen.d.ts +19 -0
- package/lib/screens/auth/ExpiredLinkScreen.d.ts.map +1 -0
- package/lib/screens/auth/ExpiredLinkScreen.jsx +38 -0
- package/lib/screens/auth/ExpiredLinkScreen.jsx.map +1 -0
- package/lib/screens/auth/ForgotPasswordScreen.d.ts +4 -0
- package/lib/screens/auth/ForgotPasswordScreen.d.ts.map +1 -0
- package/lib/screens/auth/ForgotPasswordScreen.jsx +123 -0
- package/lib/screens/auth/ForgotPasswordScreen.jsx.map +1 -0
- package/lib/screens/auth/ImportDataScreen.d.ts +17 -0
- package/lib/screens/auth/ImportDataScreen.d.ts.map +1 -0
- package/lib/screens/auth/ImportDataScreen.jsx +73 -0
- package/lib/screens/auth/ImportDataScreen.jsx.map +1 -0
- package/lib/screens/auth/LoginScreen.d.ts +38 -0
- package/lib/screens/auth/LoginScreen.d.ts.map +1 -0
- package/lib/screens/auth/LoginScreen.jsx +326 -0
- package/lib/screens/auth/LoginScreen.jsx.map +1 -0
- package/lib/screens/auth/MfaChallengeScreen.d.ts +4 -0
- package/lib/screens/auth/MfaChallengeScreen.d.ts.map +1 -0
- package/lib/screens/auth/MfaChallengeScreen.jsx +139 -0
- package/lib/screens/auth/MfaChallengeScreen.jsx.map +1 -0
- package/lib/screens/auth/MfaEnrollScreen.d.ts +12 -0
- package/lib/screens/auth/MfaEnrollScreen.d.ts.map +1 -0
- package/lib/screens/auth/MfaEnrollScreen.jsx +267 -0
- package/lib/screens/auth/MfaEnrollScreen.jsx.map +1 -0
- package/lib/screens/auth/PasskeyEnrollScreen.d.ts +18 -0
- package/lib/screens/auth/PasskeyEnrollScreen.d.ts.map +1 -0
- package/lib/screens/auth/PasskeyEnrollScreen.jsx +51 -0
- package/lib/screens/auth/PasskeyEnrollScreen.jsx.map +1 -0
- package/lib/screens/auth/PrivacyPolicyScreen.d.ts +19 -0
- package/lib/screens/auth/PrivacyPolicyScreen.d.ts.map +1 -0
- package/lib/screens/auth/PrivacyPolicyScreen.jsx +143 -0
- package/lib/screens/auth/PrivacyPolicyScreen.jsx.map +1 -0
- package/lib/screens/auth/RegisterScreen.d.ts +14 -0
- package/lib/screens/auth/RegisterScreen.d.ts.map +1 -0
- package/lib/screens/auth/RegisterScreen.jsx +296 -0
- package/lib/screens/auth/RegisterScreen.jsx.map +1 -0
- package/lib/screens/auth/ResetPasswordScreen.d.ts +12 -0
- package/lib/screens/auth/ResetPasswordScreen.d.ts.map +1 -0
- package/lib/screens/auth/ResetPasswordScreen.jsx +276 -0
- package/lib/screens/auth/ResetPasswordScreen.jsx.map +1 -0
- package/lib/screens/auth/ServerConfigScreen.d.ts +18 -0
- package/lib/screens/auth/ServerConfigScreen.d.ts.map +1 -0
- package/lib/screens/auth/ServerConfigScreen.jsx +259 -0
- package/lib/screens/auth/ServerConfigScreen.jsx.map +1 -0
- package/lib/screens/auth/TermsOfServiceScreen.d.ts +30 -0
- package/lib/screens/auth/TermsOfServiceScreen.d.ts.map +1 -0
- package/lib/screens/auth/TermsOfServiceScreen.jsx +130 -0
- package/lib/screens/auth/TermsOfServiceScreen.jsx.map +1 -0
- package/lib/screens/auth/VerifyEmailScreen.d.ts +4 -0
- package/lib/screens/auth/VerifyEmailScreen.d.ts.map +1 -0
- package/lib/screens/auth/VerifyEmailScreen.jsx +249 -0
- package/lib/screens/auth/VerifyEmailScreen.jsx.map +1 -0
- package/lib/screens/auth/WelcomeScreen.d.ts +17 -0
- package/lib/screens/auth/WelcomeScreen.d.ts.map +1 -0
- package/lib/screens/auth/WelcomeScreen.jsx +58 -0
- package/lib/screens/auth/WelcomeScreen.jsx.map +1 -0
- package/lib/screens/auth/index.d.ts +19 -0
- package/lib/screens/auth/index.d.ts.map +1 -0
- package/lib/screens/auth/index.js +19 -0
- package/lib/screens/auth/index.js.map +1 -0
- package/lib/screens/index.d.ts +2 -0
- package/lib/screens/index.d.ts.map +1 -0
- package/lib/screens/index.js +2 -0
- package/lib/screens/index.js.map +1 -0
- package/lib/services/api-config.d.ts +87 -0
- package/lib/services/api-config.d.ts.map +1 -0
- package/lib/services/api-config.js +202 -0
- package/lib/services/api-config.js.map +1 -0
- package/lib/services/auth.service.d.ts +140 -0
- package/lib/services/auth.service.d.ts.map +1 -0
- package/lib/services/auth.service.js +376 -0
- package/lib/services/auth.service.js.map +1 -0
- package/lib/services/favicon.d.ts +46 -0
- package/lib/services/favicon.d.ts.map +1 -0
- package/lib/services/favicon.js +84 -0
- package/lib/services/favicon.js.map +1 -0
- package/lib/services/hibp-cache.d.ts +23 -0
- package/lib/services/hibp-cache.d.ts.map +1 -0
- package/lib/services/hibp-cache.js +56 -0
- package/lib/services/hibp-cache.js.map +1 -0
- package/lib/services/hibp.d.ts +28 -0
- package/lib/services/hibp.d.ts.map +1 -0
- package/lib/services/hibp.js +92 -0
- package/lib/services/hibp.js.map +1 -0
- package/lib/services/index.d.ts +8 -0
- package/lib/services/index.d.ts.map +1 -0
- package/lib/services/index.js +7 -0
- package/lib/services/index.js.map +1 -0
- package/lib/services/passkey.d.ts +10 -0
- package/lib/services/passkey.d.ts.map +1 -0
- package/lib/services/passkey.js +192 -0
- package/lib/services/passkey.js.map +1 -0
- package/lib/utils/api-fetch.d.ts +11 -0
- package/lib/utils/api-fetch.d.ts.map +1 -0
- package/lib/utils/api-fetch.js +52 -0
- package/lib/utils/api-fetch.js.map +1 -0
- package/lib/utils/clipboard.d.ts +31 -0
- package/lib/utils/clipboard.d.ts.map +1 -0
- package/lib/utils/clipboard.js +66 -0
- package/lib/utils/clipboard.js.map +1 -0
- package/lib/utils/cn.d.ts +9 -0
- package/lib/utils/cn.d.ts.map +1 -0
- package/lib/utils/cn.js +12 -0
- package/lib/utils/cn.js.map +1 -0
- package/lib/utils/debounce.d.ts +13 -0
- package/lib/utils/debounce.d.ts.map +1 -0
- package/lib/utils/debounce.js +28 -0
- package/lib/utils/debounce.js.map +1 -0
- package/lib/utils/error.d.ts +9 -0
- package/lib/utils/error.d.ts.map +1 -0
- package/lib/utils/error.js +11 -0
- package/lib/utils/error.js.map +1 -0
- package/lib/utils/fetch.d.ts +17 -0
- package/lib/utils/fetch.d.ts.map +1 -0
- package/lib/utils/fetch.js +29 -0
- package/lib/utils/fetch.js.map +1 -0
- package/lib/utils/http-error.d.ts +41 -0
- package/lib/utils/http-error.d.ts.map +1 -0
- package/lib/utils/http-error.js +63 -0
- package/lib/utils/http-error.js.map +1 -0
- package/lib/utils/index.d.ts +11 -0
- package/lib/utils/index.d.ts.map +1 -0
- package/lib/utils/index.js +11 -0
- package/lib/utils/index.js.map +1 -0
- package/lib/utils/palette.d.ts +46 -0
- package/lib/utils/palette.d.ts.map +1 -0
- package/lib/utils/palette.js +75 -0
- package/lib/utils/palette.js.map +1 -0
- package/lib/utils/password.d.ts +20 -0
- package/lib/utils/password.d.ts.map +1 -0
- package/lib/utils/password.js +51 -0
- package/lib/utils/password.js.map +1 -0
- package/lib/utils/settings-storage.d.ts +3 -0
- package/lib/utils/settings-storage.d.ts.map +1 -0
- package/lib/utils/settings-storage.js +62 -0
- package/lib/utils/settings-storage.js.map +1 -0
- package/lib/utils/validation.d.ts +29 -0
- package/lib/utils/validation.d.ts.map +1 -0
- package/lib/utils/validation.js +58 -0
- package/lib/utils/validation.js.map +1 -0
- package/package.json +204 -0
- package/src/components/__tests__/data-table.test.ts +94 -0
- package/src/components/__tests__/pagination.test.ts +73 -0
- package/src/components/__tests__/stat-card.test.ts +21 -0
- package/src/components/auth/LockOverlay.tsx +122 -0
- package/src/components/auth/PasswordStrengthMeter.tsx +96 -0
- package/src/components/auth/ProtectedRoute.tsx +91 -0
- package/src/components/auth/PwnedPasswordWarning.tsx +54 -0
- package/src/components/auth/index.ts +10 -0
- package/src/components/bottom-nav.tsx +99 -0
- package/src/components/button.tsx +144 -0
- package/src/components/card.tsx +82 -0
- package/src/components/checkbox.tsx +48 -0
- package/src/components/connection-settings.tsx +583 -0
- package/src/components/context-menu.tsx +95 -0
- package/src/components/data-table.tsx +223 -0
- package/src/components/dialog.tsx +376 -0
- package/src/components/dropdown-menu.tsx +120 -0
- package/src/components/entropy-boot-splash.tsx +114 -0
- package/src/components/entropy-mark-animated.tsx +260 -0
- package/src/components/entropy-mark-geometry.ts +11 -0
- package/src/components/entropy-mark-sequential.tsx +132 -0
- package/src/components/entropy-mark.tsx +135 -0
- package/src/components/error-boundary.tsx +70 -0
- package/src/components/index.ts +156 -0
- package/src/components/input.tsx +246 -0
- package/src/components/item-icon.tsx +111 -0
- package/src/components/label.tsx +25 -0
- package/src/components/legal-dialog.tsx +47 -0
- package/src/components/license-gate.tsx +28 -0
- package/src/components/logo.tsx +34 -0
- package/src/components/onboarding-wizard.tsx +353 -0
- package/src/components/pagination.tsx +154 -0
- package/src/components/password-generator.tsx +393 -0
- package/src/components/pin-pad.tsx +156 -0
- package/src/components/popover.tsx +38 -0
- package/src/components/profile/ProfileDialog.tsx +129 -0
- package/src/components/profile/ProfileTab.tsx +151 -0
- package/src/components/profile/SecurityTab.tsx +229 -0
- package/src/components/profile/index.ts +3 -0
- package/src/components/segmented-toggle.tsx +119 -0
- package/src/components/separator.tsx +41 -0
- package/src/components/server-settings.tsx +442 -0
- package/src/components/settings/AccountSection.tsx +76 -0
- package/src/components/settings/DangerZoneSection.tsx +37 -0
- package/src/components/settings/GeneralSection.tsx +39 -0
- package/src/components/settings/SupportSection.tsx +53 -0
- package/src/components/settings/index.ts +4 -0
- package/src/components/settings-row.tsx +126 -0
- package/src/components/skeleton.tsx +48 -0
- package/src/components/social-connections.tsx +55 -0
- package/src/components/stat-card.tsx +64 -0
- package/src/components/tag-chip.tsx +78 -0
- package/src/components/tag-multi-select.tsx +136 -0
- package/src/components/text.tsx +77 -0
- package/src/components/toast/ToastPortal.tsx +16 -0
- package/src/components/toast/ToastPortal.web.tsx +47 -0
- package/src/components/toast/index.ts +2 -0
- package/src/components/toast/toast-config.tsx +31 -0
- package/src/components/tooltip.tsx +30 -0
- package/src/components/totp-display.tsx +207 -0
- package/src/components/user-avatar.tsx +46 -0
- package/src/context/AppConfigContext.tsx +76 -0
- package/src/context/NavigationContext.tsx +75 -0
- package/src/context/NotificationContext.tsx +69 -0
- package/src/context/ThemeContext.tsx +83 -0
- package/src/context/__tests__/NavigationContext.test.tsx +53 -0
- package/src/context/index.ts +24 -0
- package/src/flags.ts +44 -0
- package/src/forms/form-error.tsx +20 -0
- package/src/forms/index.ts +2 -0
- package/src/forms/shake-field.tsx +52 -0
- package/src/hooks/__tests__/useUploadBlobUrl.test.tsx +77 -0
- package/src/hooks/index.ts +18 -0
- package/src/hooks/useAuth.tsx +567 -0
- package/src/hooks/useAutoLock.ts +110 -0
- package/src/hooks/useDebouncedValue.ts +32 -0
- package/src/hooks/useShakeAnimation.ts +42 -0
- package/src/hooks/useUploadBlobUrl.ts +75 -0
- package/src/index.ts +48 -0
- package/src/screens/auth/AccountPickerScreen.tsx +103 -0
- package/src/screens/auth/AuthScreen.tsx +941 -0
- package/src/screens/auth/ConsentScreen.tsx +118 -0
- package/src/screens/auth/ErrorScreen.tsx +96 -0
- package/src/screens/auth/ExpiredLinkScreen.tsx +87 -0
- package/src/screens/auth/ForgotPasswordScreen.tsx +182 -0
- package/src/screens/auth/ImportDataScreen.tsx +112 -0
- package/src/screens/auth/LoginScreen.tsx +484 -0
- package/src/screens/auth/MfaChallengeScreen.tsx +216 -0
- package/src/screens/auth/MfaEnrollScreen.tsx +388 -0
- package/src/screens/auth/PasskeyEnrollScreen.tsx +96 -0
- package/src/screens/auth/PrivacyPolicyScreen.tsx +249 -0
- package/src/screens/auth/RegisterScreen.tsx +430 -0
- package/src/screens/auth/ResetPasswordScreen.tsx +377 -0
- package/src/screens/auth/ServerConfigScreen.tsx +388 -0
- package/src/screens/auth/TermsOfServiceScreen.tsx +236 -0
- package/src/screens/auth/VerifyEmailScreen.tsx +310 -0
- package/src/screens/auth/WelcomeScreen.tsx +78 -0
- package/src/screens/auth/index.ts +36 -0
- package/src/screens/index.ts +1 -0
- package/src/services/__tests__/api-config.test.ts +67 -0
- package/src/services/__tests__/favicon.test.ts +88 -0
- package/src/services/__tests__/hibp-cache.test.ts +37 -0
- package/src/services/__tests__/hibp.test.ts +39 -0
- package/src/services/api-config.ts +260 -0
- package/src/services/auth.service.ts +498 -0
- package/src/services/favicon.ts +102 -0
- package/src/services/hibp-cache.ts +71 -0
- package/src/services/hibp.ts +120 -0
- package/src/services/index.ts +52 -0
- package/src/services/passkey.ts +213 -0
- package/src/types/external.d.ts +24 -0
- package/src/utils/__tests__/clipboard.test.ts +59 -0
- package/src/utils/__tests__/cn.test.ts +24 -0
- package/src/utils/__tests__/debounce.test.ts +42 -0
- package/src/utils/__tests__/error.test.ts +18 -0
- package/src/utils/__tests__/http-error.test.ts +33 -0
- package/src/utils/__tests__/palette.test.ts +22 -0
- package/src/utils/__tests__/password.test.ts +55 -0
- package/src/utils/__tests__/settings-storage.test.ts +15 -0
- package/src/utils/__tests__/validation.test.ts +52 -0
- package/src/utils/api-fetch.ts +61 -0
- package/src/utils/clipboard.ts +69 -0
- package/src/utils/cn.ts +12 -0
- package/src/utils/debounce.ts +33 -0
- package/src/utils/error.ts +10 -0
- package/src/utils/fetch.ts +33 -0
- package/src/utils/http-error.ts +81 -0
- package/src/utils/index.ts +23 -0
- package/src/utils/palette.ts +105 -0
- package/src/utils/password.ts +64 -0
- package/src/utils/settings-storage.ts +68 -0
- package/src/utils/validation.ts +71 -0
- package/styles/globals.css +262 -0
- package/tailwind-preset.js +163 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `fetch` with a timeout abort signal merged onto the caller's own signal.
|
|
3
|
+
* The default timeout is 15s. Pass `Infinity` to disable the timeout
|
|
4
|
+
* (the caller's own `signal` still applies). Passing `0` aborts
|
|
5
|
+
* immediately — almost never what you want — so we treat any
|
|
6
|
+
* non-positive value as "no timeout" to avoid the footgun.
|
|
7
|
+
*
|
|
8
|
+
* **Lockstep duplicate** of `vault/clients/shared/src/utils/fetch.ts`.
|
|
9
|
+
* `@vault/shared` is the vault-specific lower layer; `@entropy-softworks/ui`
|
|
10
|
+
* is the cross-portfolio UI package. Neither can depend on the other
|
|
11
|
+
* (shared → ui would invert layering; ui → shared would chain every
|
|
12
|
+
* downstream Entropy Softworks app to vault). The function is small,
|
|
13
|
+
* pure, and stable; keep both copies byte-identical and update both
|
|
14
|
+
* when changing.
|
|
15
|
+
*/
|
|
16
|
+
export declare function fetchWithTimeout(url: string, options?: RequestInit, timeoutMs?: number): Promise<Response>;
|
|
17
|
+
//# sourceMappingURL=fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/utils/fetch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,WAAgB,EACzB,SAAS,SAAQ,GAChB,OAAO,CAAC,QAAQ,CAAC,CAanB"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `fetch` with a timeout abort signal merged onto the caller's own signal.
|
|
3
|
+
* The default timeout is 15s. Pass `Infinity` to disable the timeout
|
|
4
|
+
* (the caller's own `signal` still applies). Passing `0` aborts
|
|
5
|
+
* immediately — almost never what you want — so we treat any
|
|
6
|
+
* non-positive value as "no timeout" to avoid the footgun.
|
|
7
|
+
*
|
|
8
|
+
* **Lockstep duplicate** of `vault/clients/shared/src/utils/fetch.ts`.
|
|
9
|
+
* `@vault/shared` is the vault-specific lower layer; `@entropy-softworks/ui`
|
|
10
|
+
* is the cross-portfolio UI package. Neither can depend on the other
|
|
11
|
+
* (shared → ui would invert layering; ui → shared would chain every
|
|
12
|
+
* downstream Entropy Softworks app to vault). The function is small,
|
|
13
|
+
* pure, and stable; keep both copies byte-identical and update both
|
|
14
|
+
* when changing.
|
|
15
|
+
*/
|
|
16
|
+
export function fetchWithTimeout(url, options = {}, timeoutMs = 15000) {
|
|
17
|
+
const controller = new AbortController();
|
|
18
|
+
const id = timeoutMs > 0 && Number.isFinite(timeoutMs)
|
|
19
|
+
? setTimeout(() => controller.abort(), timeoutMs)
|
|
20
|
+
: null;
|
|
21
|
+
const signals = [controller.signal, options.signal].filter((s) => s != null);
|
|
22
|
+
const combinedSignal = signals.length > 1 ? AbortSignal.any(signals) : controller.signal;
|
|
23
|
+
return fetch(url, { ...options, signal: combinedSignal }).finally(() => {
|
|
24
|
+
if (id !== null) {
|
|
25
|
+
clearTimeout(id);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=fetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/utils/fetch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,gBAAgB,CAC9B,GAAW,EACX,UAAuB,EAAE,EACzB,SAAS,GAAG,KAAK;IAEjB,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,EAAE,GACN,SAAS,GAAG,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC;QACzC,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC;QACjD,CAAC,CAAC,IAAI,CAAC;IACX,MAAM,OAAO,GAAG,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAoB,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC;IAC/F,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC;IACzF,OAAO,KAAK,CAAC,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE;QACrE,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;YAChB,YAAY,CAAC,EAAE,CAAC,CAAC;QACnB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse an Entropy Softworks server error response into a single user-
|
|
3
|
+
* facing string. Falls back to `fallback` when the body isn't valid
|
|
4
|
+
* JSON or doesn't follow the expected `{ error: { message, details? } }`
|
|
5
|
+
* shape. Detail arrays longer than `MAX_DETAILS` are truncated so a
|
|
6
|
+
* runaway server response can't produce an unreadable toast.
|
|
7
|
+
*/
|
|
8
|
+
export interface ServerErrorBody {
|
|
9
|
+
error: {
|
|
10
|
+
message: string;
|
|
11
|
+
details?: string[];
|
|
12
|
+
code?: string;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Error subclass that carries the server's machine-readable
|
|
17
|
+
* `error.code` and HTTP `status` alongside the human-readable
|
|
18
|
+
* message. UI code can branch on `code` (e.g. `INVALID_CREDENTIALS`,
|
|
19
|
+
* `ACCOUNT_LOCKED`, `EMAIL_NOT_VERIFIED`) instead of substring-
|
|
20
|
+
* matching against an English message that breaks under i18n.
|
|
21
|
+
*/
|
|
22
|
+
export declare class ApiError extends Error {
|
|
23
|
+
readonly code: string | undefined;
|
|
24
|
+
readonly status: number;
|
|
25
|
+
readonly details: readonly string[] | undefined;
|
|
26
|
+
constructor(message: string, options: {
|
|
27
|
+
code?: string;
|
|
28
|
+
status: number;
|
|
29
|
+
details?: readonly string[];
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
export declare function extractErrorMessage(response: Response, fallback: string): Promise<string>;
|
|
33
|
+
/**
|
|
34
|
+
* Like `extractErrorMessage` but returns a structured `ApiError` so
|
|
35
|
+
* callers can branch on `code` / `status`. Use this when the caller
|
|
36
|
+
* is throwing and downstream consumers need machine-readable
|
|
37
|
+
* classification; use `extractErrorMessage` when all you need is a
|
|
38
|
+
* toast string.
|
|
39
|
+
*/
|
|
40
|
+
export declare function extractApiError(response: Response, fallback: string): Promise<ApiError>;
|
|
41
|
+
//# sourceMappingURL=http-error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-error.d.ts","sourceRoot":"","sources":["../../src/utils/http-error.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE;QACL,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAID;;;;;;GAMG;AACH,qBAAa,QAAS,SAAQ,KAAK;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;gBAG9C,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE;CAQ1E;AAED,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAY/F;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAkB7F"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
const MAX_DETAILS = 5;
|
|
2
|
+
/**
|
|
3
|
+
* Error subclass that carries the server's machine-readable
|
|
4
|
+
* `error.code` and HTTP `status` alongside the human-readable
|
|
5
|
+
* message. UI code can branch on `code` (e.g. `INVALID_CREDENTIALS`,
|
|
6
|
+
* `ACCOUNT_LOCKED`, `EMAIL_NOT_VERIFIED`) instead of substring-
|
|
7
|
+
* matching against an English message that breaks under i18n.
|
|
8
|
+
*/
|
|
9
|
+
export class ApiError extends Error {
|
|
10
|
+
code;
|
|
11
|
+
status;
|
|
12
|
+
details;
|
|
13
|
+
constructor(message, options) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.name = "ApiError";
|
|
16
|
+
this.code = options.code;
|
|
17
|
+
this.status = options.status;
|
|
18
|
+
this.details = options.details;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export async function extractErrorMessage(response, fallback) {
|
|
22
|
+
try {
|
|
23
|
+
const error = await response.json();
|
|
24
|
+
const details = error.error.details;
|
|
25
|
+
if (details && details.length > 0) {
|
|
26
|
+
const shown = details.slice(0, MAX_DETAILS).join(", ");
|
|
27
|
+
return details.length > MAX_DETAILS ? `${shown}, …` : shown;
|
|
28
|
+
}
|
|
29
|
+
return error.error.message || fallback;
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return fallback;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Like `extractErrorMessage` but returns a structured `ApiError` so
|
|
37
|
+
* callers can branch on `code` / `status`. Use this when the caller
|
|
38
|
+
* is throwing and downstream consumers need machine-readable
|
|
39
|
+
* classification; use `extractErrorMessage` when all you need is a
|
|
40
|
+
* toast string.
|
|
41
|
+
*/
|
|
42
|
+
export async function extractApiError(response, fallback) {
|
|
43
|
+
let message = fallback;
|
|
44
|
+
let code;
|
|
45
|
+
let details;
|
|
46
|
+
try {
|
|
47
|
+
const error = await response.json();
|
|
48
|
+
if (error.error.details && error.error.details.length > 0) {
|
|
49
|
+
details = error.error.details.slice(0, MAX_DETAILS);
|
|
50
|
+
const shown = details.join(", ");
|
|
51
|
+
message = error.error.details.length > MAX_DETAILS ? `${shown}, …` : shown;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
message = error.error.message || fallback;
|
|
55
|
+
}
|
|
56
|
+
code = error.error.code;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// Non-JSON body — keep fallback message, no code.
|
|
60
|
+
}
|
|
61
|
+
return new ApiError(message, { code, status: response.status, details });
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=http-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-error.js","sourceRoot":"","sources":["../../src/utils/http-error.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,GAAG,CAAC,CAAC;AAEtB;;;;;;GAMG;AACH,MAAM,OAAO,QAAS,SAAQ,KAAK;IACxB,IAAI,CAAqB;IACzB,MAAM,CAAS;IACf,OAAO,CAAgC;IAEhD,YACE,OAAe,EACf,OAAuE;QAEvE,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IACjC,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,QAAkB,EAAE,QAAgB;IAC5E,IAAI,CAAC;QACH,MAAM,KAAK,GAAoB,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrD,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC;QACpC,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvD,OAAO,OAAO,CAAC,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;QAC9D,CAAC;QACD,OAAO,KAAK,CAAC,KAAK,CAAC,OAAO,IAAI,QAAQ,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,QAAkB,EAAE,QAAgB;IACxE,IAAI,OAAO,GAAG,QAAQ,CAAC;IACvB,IAAI,IAAwB,CAAC;IAC7B,IAAI,OAA6B,CAAC;IAClC,IAAI,CAAC;QACH,MAAM,KAAK,GAAoB,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrD,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1D,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;YACpD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjC,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;QAC7E,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,IAAI,QAAQ,CAAC;QAC5C,CAAC;QACD,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,kDAAkD;IACpD,CAAC;IACD,OAAO,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;AAC3E,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { apiFetch } from "./api-fetch";
|
|
2
|
+
export { cn } from "./cn";
|
|
3
|
+
export { getErrorMessage } from "./error";
|
|
4
|
+
export { darkPalette, getPalette, lightPalette, usePalette, type ColorScheme, type Palette, } from "./palette";
|
|
5
|
+
export { clearClipboardNow, copyToClipboard } from "./clipboard";
|
|
6
|
+
export { loadSetting, saveSetting } from "./settings-storage";
|
|
7
|
+
export { debounce } from "./debounce";
|
|
8
|
+
export { ApiError, extractApiError, extractErrorMessage } from "./http-error";
|
|
9
|
+
export { generatePassword, type GeneratePasswordOptions } from "./password";
|
|
10
|
+
export { validateEmail, validatePassword, validateUsername, type PasswordValidation, type UsernameValidation, } from "./validation";
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EACL,WAAW,EACX,UAAU,EACV,YAAY,EACZ,UAAU,EACV,KAAK,WAAW,EAChB,KAAK,OAAO,GACb,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,GACxB,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { apiFetch } from "./api-fetch";
|
|
2
|
+
export { cn } from "./cn";
|
|
3
|
+
export { getErrorMessage } from "./error";
|
|
4
|
+
export { darkPalette, getPalette, lightPalette, usePalette, } from "./palette";
|
|
5
|
+
export { clearClipboardNow, copyToClipboard } from "./clipboard";
|
|
6
|
+
export { loadSetting, saveSetting } from "./settings-storage";
|
|
7
|
+
export { debounce } from "./debounce";
|
|
8
|
+
export { ApiError, extractApiError, extractErrorMessage } from "./http-error";
|
|
9
|
+
export { generatePassword } from "./password";
|
|
10
|
+
export { validateEmail, validatePassword, validateUsername, } from "./validation";
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EACL,WAAW,EACX,UAAU,EACV,YAAY,EACZ,UAAU,GAGX,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EAAE,gBAAgB,EAAgC,MAAM,YAAY,CAAC;AAC5E,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,gBAAgB,GAGjB,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JavaScript-side representation of the same color tokens NativeWind
|
|
3
|
+
* exposes as CSS variables in `styles/globals.css`. Components that need
|
|
4
|
+
* a palette object (RN-Web inline styles, SVG `stroke`, etc.) consume
|
|
5
|
+
* this so the values stay in lockstep with the className-based theming.
|
|
6
|
+
*
|
|
7
|
+
* Always read via `usePalette()` (or `getPalette(scheme)` for non-hook
|
|
8
|
+
* call sites) — the table mirrors `:root` for light and `.dark` for
|
|
9
|
+
* dark.
|
|
10
|
+
*/
|
|
11
|
+
export interface Palette {
|
|
12
|
+
background: string;
|
|
13
|
+
foreground: string;
|
|
14
|
+
card: string;
|
|
15
|
+
cardForeground: string;
|
|
16
|
+
popover: string;
|
|
17
|
+
popoverForeground: string;
|
|
18
|
+
primary: string;
|
|
19
|
+
primaryForeground: string;
|
|
20
|
+
secondary: string;
|
|
21
|
+
secondaryForeground: string;
|
|
22
|
+
muted: string;
|
|
23
|
+
mutedForeground: string;
|
|
24
|
+
accent: string;
|
|
25
|
+
accentForeground: string;
|
|
26
|
+
destructive: string;
|
|
27
|
+
destructiveForeground: string;
|
|
28
|
+
border: string;
|
|
29
|
+
input: string;
|
|
30
|
+
inputBorder: string;
|
|
31
|
+
ring: string;
|
|
32
|
+
placeholder: string;
|
|
33
|
+
}
|
|
34
|
+
export declare const lightPalette: Palette;
|
|
35
|
+
export declare const darkPalette: Palette;
|
|
36
|
+
export type ColorScheme = "light" | "dark";
|
|
37
|
+
export declare function getPalette(scheme: ColorScheme): Palette;
|
|
38
|
+
/**
|
|
39
|
+
* Returns the active palette + scheme. Re-renders the caller when the
|
|
40
|
+
* OS / class-toggled theme flips.
|
|
41
|
+
*/
|
|
42
|
+
export declare function usePalette(): {
|
|
43
|
+
scheme: ColorScheme;
|
|
44
|
+
palette: Palette;
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=palette.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"palette.d.ts","sourceRoot":"","sources":["../../src/utils/palette.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,MAAM,WAAW,OAAO;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,YAAY,EAAE,OAsB1B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,OAsBzB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3C,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAEvD;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAQtE"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JavaScript-side representation of the same color tokens NativeWind
|
|
3
|
+
* exposes as CSS variables in `styles/globals.css`. Components that need
|
|
4
|
+
* a palette object (RN-Web inline styles, SVG `stroke`, etc.) consume
|
|
5
|
+
* this so the values stay in lockstep with the className-based theming.
|
|
6
|
+
*
|
|
7
|
+
* Always read via `usePalette()` (or `getPalette(scheme)` for non-hook
|
|
8
|
+
* call sites) — the table mirrors `:root` for light and `.dark` for
|
|
9
|
+
* dark.
|
|
10
|
+
*/
|
|
11
|
+
import { useMemo } from "react";
|
|
12
|
+
import { useColorScheme } from "nativewind";
|
|
13
|
+
export const lightPalette = {
|
|
14
|
+
background: "rgb(255, 255, 255)",
|
|
15
|
+
foreground: "rgb(0, 0, 0)",
|
|
16
|
+
card: "rgb(255, 255, 255)",
|
|
17
|
+
cardForeground: "rgb(0, 0, 0)",
|
|
18
|
+
popover: "rgb(255, 255, 255)",
|
|
19
|
+
popoverForeground: "rgb(0, 0, 0)",
|
|
20
|
+
primary: "rgb(0, 0, 0)",
|
|
21
|
+
primaryForeground: "rgb(255, 255, 255)",
|
|
22
|
+
secondary: "rgb(245, 245, 245)",
|
|
23
|
+
secondaryForeground: "rgb(0, 0, 0)",
|
|
24
|
+
muted: "rgb(245, 245, 245)",
|
|
25
|
+
mutedForeground: "rgb(115, 115, 115)",
|
|
26
|
+
accent: "rgb(245, 245, 245)",
|
|
27
|
+
accentForeground: "rgb(0, 0, 0)",
|
|
28
|
+
destructive: "rgb(239, 68, 68)",
|
|
29
|
+
destructiveForeground: "rgb(255, 255, 255)",
|
|
30
|
+
border: "rgb(229, 229, 229)",
|
|
31
|
+
input: "rgb(255, 255, 255)",
|
|
32
|
+
inputBorder: "rgb(229, 229, 229)",
|
|
33
|
+
ring: "rgb(0, 0, 0)",
|
|
34
|
+
placeholder: "rgb(163, 163, 163)",
|
|
35
|
+
};
|
|
36
|
+
export const darkPalette = {
|
|
37
|
+
background: "rgb(0, 0, 0)",
|
|
38
|
+
foreground: "rgb(255, 255, 255)",
|
|
39
|
+
card: "rgb(0, 0, 0)",
|
|
40
|
+
cardForeground: "rgb(255, 255, 255)",
|
|
41
|
+
popover: "rgb(0, 0, 0)",
|
|
42
|
+
popoverForeground: "rgb(255, 255, 255)",
|
|
43
|
+
primary: "rgb(255, 255, 255)",
|
|
44
|
+
primaryForeground: "rgb(0, 0, 0)",
|
|
45
|
+
secondary: "rgb(38, 38, 38)",
|
|
46
|
+
secondaryForeground: "rgb(255, 255, 255)",
|
|
47
|
+
muted: "rgb(38, 38, 38)",
|
|
48
|
+
mutedForeground: "rgb(163, 163, 163)",
|
|
49
|
+
accent: "rgb(38, 38, 38)",
|
|
50
|
+
accentForeground: "rgb(255, 255, 255)",
|
|
51
|
+
destructive: "rgb(127, 29, 29)",
|
|
52
|
+
destructiveForeground: "rgb(255, 255, 255)",
|
|
53
|
+
border: "rgb(38, 38, 38)",
|
|
54
|
+
input: "rgb(0, 0, 0)",
|
|
55
|
+
inputBorder: "rgb(38, 38, 38)",
|
|
56
|
+
ring: "rgb(255, 255, 255)",
|
|
57
|
+
placeholder: "rgb(115, 115, 115)",
|
|
58
|
+
};
|
|
59
|
+
export function getPalette(scheme) {
|
|
60
|
+
return scheme === "dark" ? darkPalette : lightPalette;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Returns the active palette + scheme. Re-renders the caller when the
|
|
64
|
+
* OS / class-toggled theme flips.
|
|
65
|
+
*/
|
|
66
|
+
export function usePalette() {
|
|
67
|
+
const { colorScheme } = useColorScheme();
|
|
68
|
+
const scheme = colorScheme === "dark" ? "dark" : "light";
|
|
69
|
+
// Memoize the wrapper so callers using the result as a useMemo /
|
|
70
|
+
// useCallback dep see a stable reference until the scheme actually
|
|
71
|
+
// changes. The contained `palette` is already a module-level cached
|
|
72
|
+
// singleton; only the wrapper object was being re-created.
|
|
73
|
+
return useMemo(() => ({ scheme, palette: getPalette(scheme) }), [scheme]);
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=palette.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"palette.js","sourceRoot":"","sources":["../../src/utils/palette.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AA0B5C,MAAM,CAAC,MAAM,YAAY,GAAY;IACnC,UAAU,EAAE,oBAAoB;IAChC,UAAU,EAAE,cAAc;IAC1B,IAAI,EAAE,oBAAoB;IAC1B,cAAc,EAAE,cAAc;IAC9B,OAAO,EAAE,oBAAoB;IAC7B,iBAAiB,EAAE,cAAc;IACjC,OAAO,EAAE,cAAc;IACvB,iBAAiB,EAAE,oBAAoB;IACvC,SAAS,EAAE,oBAAoB;IAC/B,mBAAmB,EAAE,cAAc;IACnC,KAAK,EAAE,oBAAoB;IAC3B,eAAe,EAAE,oBAAoB;IACrC,MAAM,EAAE,oBAAoB;IAC5B,gBAAgB,EAAE,cAAc;IAChC,WAAW,EAAE,kBAAkB;IAC/B,qBAAqB,EAAE,oBAAoB;IAC3C,MAAM,EAAE,oBAAoB;IAC5B,KAAK,EAAE,oBAAoB;IAC3B,WAAW,EAAE,oBAAoB;IACjC,IAAI,EAAE,cAAc;IACpB,WAAW,EAAE,oBAAoB;CAClC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAY;IAClC,UAAU,EAAE,cAAc;IAC1B,UAAU,EAAE,oBAAoB;IAChC,IAAI,EAAE,cAAc;IACpB,cAAc,EAAE,oBAAoB;IACpC,OAAO,EAAE,cAAc;IACvB,iBAAiB,EAAE,oBAAoB;IACvC,OAAO,EAAE,oBAAoB;IAC7B,iBAAiB,EAAE,cAAc;IACjC,SAAS,EAAE,iBAAiB;IAC5B,mBAAmB,EAAE,oBAAoB;IACzC,KAAK,EAAE,iBAAiB;IACxB,eAAe,EAAE,oBAAoB;IACrC,MAAM,EAAE,iBAAiB;IACzB,gBAAgB,EAAE,oBAAoB;IACtC,WAAW,EAAE,kBAAkB;IAC/B,qBAAqB,EAAE,oBAAoB;IAC3C,MAAM,EAAE,iBAAiB;IACzB,KAAK,EAAE,cAAc;IACrB,WAAW,EAAE,iBAAiB;IAC9B,IAAI,EAAE,oBAAoB;IAC1B,WAAW,EAAE,oBAAoB;CAClC,CAAC;AAIF,MAAM,UAAU,UAAU,CAAC,MAAmB;IAC5C,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC;AACxD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,EAAE,WAAW,EAAE,GAAG,cAAc,EAAE,CAAC;IACzC,MAAM,MAAM,GAAgB,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;IACtE,iEAAiE;IACjE,mEAAmE;IACnE,oEAAoE;IACpE,2DAA2D;IAC3D,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;AAC5E,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface GeneratePasswordOptions {
|
|
2
|
+
/** Output length in characters. */
|
|
3
|
+
length: number;
|
|
4
|
+
includeUppercase?: boolean;
|
|
5
|
+
includeLowercase?: boolean;
|
|
6
|
+
includeNumbers?: boolean;
|
|
7
|
+
includeSymbols?: boolean;
|
|
8
|
+
/** Drop ambiguous glyphs (`i l 1 L o 0 O`). */
|
|
9
|
+
excludeSimilar?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Generate a random password using CSPRNG bytes (`@noble/ciphers`) with
|
|
13
|
+
* rejection sampling so the output distribution stays uniform across
|
|
14
|
+
* the chosen character set — `b % len` modulo-bias is rejected by
|
|
15
|
+
* trimming the byte range to a multiple of `len`.
|
|
16
|
+
*
|
|
17
|
+
* Throws when every character class is disabled (no charset).
|
|
18
|
+
*/
|
|
19
|
+
export declare function generatePassword(opts: GeneratePasswordOptions): string;
|
|
20
|
+
//# sourceMappingURL=password.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../../src/utils/password.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,uBAAuB;IACtC,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,+CAA+C;IAC/C,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,uBAAuB,GAAG,MAAM,CAoCtE"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { randomBytes } from "@noble/ciphers/utils.js";
|
|
2
|
+
const UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
3
|
+
const LOWERCASE = "abcdefghijklmnopqrstuvwxyz";
|
|
4
|
+
const NUMBERS = "0123456789";
|
|
5
|
+
const SYMBOLS = "!@#$%^&*()_+-=[]{}|;:,.<>?";
|
|
6
|
+
const SIMILAR = "il1Lo0O";
|
|
7
|
+
/**
|
|
8
|
+
* Generate a random password using CSPRNG bytes (`@noble/ciphers`) with
|
|
9
|
+
* rejection sampling so the output distribution stays uniform across
|
|
10
|
+
* the chosen character set — `b % len` modulo-bias is rejected by
|
|
11
|
+
* trimming the byte range to a multiple of `len`.
|
|
12
|
+
*
|
|
13
|
+
* Throws when every character class is disabled (no charset).
|
|
14
|
+
*/
|
|
15
|
+
export function generatePassword(opts) {
|
|
16
|
+
let charset = "";
|
|
17
|
+
if (opts.includeUppercase ?? true) {
|
|
18
|
+
charset += UPPERCASE;
|
|
19
|
+
}
|
|
20
|
+
if (opts.includeLowercase ?? true) {
|
|
21
|
+
charset += LOWERCASE;
|
|
22
|
+
}
|
|
23
|
+
if (opts.includeNumbers ?? true) {
|
|
24
|
+
charset += NUMBERS;
|
|
25
|
+
}
|
|
26
|
+
if (opts.includeSymbols ?? true) {
|
|
27
|
+
charset += SYMBOLS;
|
|
28
|
+
}
|
|
29
|
+
if (opts.excludeSimilar) {
|
|
30
|
+
charset = charset
|
|
31
|
+
.split("")
|
|
32
|
+
.filter((c) => !SIMILAR.includes(c))
|
|
33
|
+
.join("");
|
|
34
|
+
}
|
|
35
|
+
if (charset.length === 0) {
|
|
36
|
+
throw new Error("generatePassword: at least one character class must be enabled");
|
|
37
|
+
}
|
|
38
|
+
const limit = Math.floor(256 / charset.length) * charset.length;
|
|
39
|
+
let out = "";
|
|
40
|
+
while (out.length < opts.length) {
|
|
41
|
+
const bytes = randomBytes(opts.length - out.length + 16);
|
|
42
|
+
for (let i = 0; i < bytes.length && out.length < opts.length; i++) {
|
|
43
|
+
const b = bytes[i] ?? 0;
|
|
44
|
+
if (b < limit) {
|
|
45
|
+
out += charset.charAt(b % charset.length);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return out;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=password.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password.js","sourceRoot":"","sources":["../../src/utils/password.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,MAAM,SAAS,GAAG,4BAA4B,CAAC;AAC/C,MAAM,SAAS,GAAG,4BAA4B,CAAC;AAC/C,MAAM,OAAO,GAAG,YAAY,CAAC;AAC7B,MAAM,OAAO,GAAG,4BAA4B,CAAC;AAC7C,MAAM,OAAO,GAAG,SAAS,CAAC;AAa1B;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAA6B;IAC5D,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,IAAI,CAAC,gBAAgB,IAAI,IAAI,EAAE,CAAC;QAClC,OAAO,IAAI,SAAS,CAAC;IACvB,CAAC;IACD,IAAI,IAAI,CAAC,gBAAgB,IAAI,IAAI,EAAE,CAAC;QAClC,OAAO,IAAI,SAAS,CAAC;IACvB,CAAC;IACD,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,EAAE,CAAC;QAChC,OAAO,IAAI,OAAO,CAAC;IACrB,CAAC;IACD,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,EAAE,CAAC;QAChC,OAAO,IAAI,OAAO,CAAC;IACrB,CAAC;IACD,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;QACxB,OAAO,GAAG,OAAO;aACd,KAAK,CAAC,EAAE,CAAC;aACT,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;aACnC,IAAI,CAAC,EAAE,CAAC,CAAC;IACd,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;IACpF,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAChE,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,OAAO,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAChC,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;QACzD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAClE,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACxB,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC;gBACd,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings-storage.d.ts","sourceRoot":"","sources":["../../src/utils/settings-storage.ts"],"names":[],"mappings":"AA+BA,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAkBlF;AAED,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB5E"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Platform } from "react-native";
|
|
2
|
+
import * as SecureStore from "expo-secure-store";
|
|
3
|
+
/**
|
|
4
|
+
* Boolean preference storage shared across platforms.
|
|
5
|
+
*
|
|
6
|
+
* Web persists via `localStorage` so behaviour matches the native
|
|
7
|
+
* SecureStore path (also persistent). The web tier is origin-isolated
|
|
8
|
+
* but not encrypted at rest — don't use this for secrets, only for UX
|
|
9
|
+
* preferences whose disclosure is acceptable. Security-sensitive policy
|
|
10
|
+
* (e.g. enforced auto-lock) belongs server-side.
|
|
11
|
+
*/
|
|
12
|
+
const WEB_STORAGE_AVAILABLE = Platform.OS === "web" && typeof window !== "undefined" && !!window.localStorage;
|
|
13
|
+
let warnedNoStorage = false;
|
|
14
|
+
function warnNoStorage(action) {
|
|
15
|
+
if (warnedNoStorage) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
warnedNoStorage = true;
|
|
19
|
+
if (!__DEV__) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
console.warn(`[settings-storage] ${action} failed: localStorage unavailable; using fallbacks for this session.`);
|
|
23
|
+
}
|
|
24
|
+
export async function loadSetting(key, fallback) {
|
|
25
|
+
try {
|
|
26
|
+
if (Platform.OS === "web") {
|
|
27
|
+
if (!WEB_STORAGE_AVAILABLE) {
|
|
28
|
+
warnNoStorage("load");
|
|
29
|
+
return fallback;
|
|
30
|
+
}
|
|
31
|
+
const v = window.localStorage.getItem(key);
|
|
32
|
+
return v !== null ? v === "true" : fallback;
|
|
33
|
+
}
|
|
34
|
+
const v = await SecureStore.getItemAsync(key);
|
|
35
|
+
return v !== null ? v === "true" : fallback;
|
|
36
|
+
}
|
|
37
|
+
catch (e) {
|
|
38
|
+
if (__DEV__) {
|
|
39
|
+
console.warn(`[settings-storage] load(${key}) threw:`, e);
|
|
40
|
+
}
|
|
41
|
+
return fallback;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export async function saveSetting(key, value) {
|
|
45
|
+
try {
|
|
46
|
+
if (Platform.OS === "web") {
|
|
47
|
+
if (!WEB_STORAGE_AVAILABLE) {
|
|
48
|
+
warnNoStorage("save");
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
window.localStorage.setItem(key, String(value));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
await SecureStore.setItemAsync(key, String(value));
|
|
55
|
+
}
|
|
56
|
+
catch (e) {
|
|
57
|
+
if (__DEV__) {
|
|
58
|
+
console.warn(`[settings-storage] save(${key}) threw:`, e);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=settings-storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings-storage.js","sourceRoot":"","sources":["../../src/utils/settings-storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAC;AAEjD;;;;;;;;GAQG;AAEH,MAAM,qBAAqB,GACzB,QAAQ,CAAC,EAAE,KAAK,KAAK,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC;AAElF,IAAI,eAAe,GAAG,KAAK,CAAC;AAC5B,SAAS,aAAa,CAAC,MAAuB;IAC5C,IAAI,eAAe,EAAE,CAAC;QACpB,OAAO;IACT,CAAC;IACD,eAAe,GAAG,IAAI,CAAC;IACvB,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;IACT,CAAC;IAED,OAAO,CAAC,IAAI,CACV,sBAAsB,MAAM,sEAAsE,CACnG,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAW,EAAE,QAAiB;IAC9D,IAAI,CAAC;QACH,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;YAC1B,IAAI,CAAC,qBAAqB,EAAE,CAAC;gBAC3B,aAAa,CAAC,MAAM,CAAC,CAAC;gBACtB,OAAO,QAAQ,CAAC;YAClB,CAAC;YACD,MAAM,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC3C,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC9C,CAAC;QACD,MAAM,CAAC,GAAG,MAAM,WAAW,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QAC9C,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC9C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,2BAA2B,GAAG,UAAU,EAAE,CAAC,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAW,EAAE,KAAc;IAC3D,IAAI,CAAC;QACH,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;YAC1B,IAAI,CAAC,qBAAqB,EAAE,CAAC;gBAC3B,aAAa,CAAC,MAAM,CAAC,CAAC;gBACtB,OAAO;YACT,CAAC;YACD,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAChD,OAAO;QACT,CAAC;QACD,MAAM,WAAW,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACrD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,2BAA2B,GAAG,UAAU,EAAE,CAAC,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input validators used by the UI to surface preview feedback before
|
|
3
|
+
* the user hits the server. The Entropy Softworks application servers
|
|
4
|
+
* enforce these same rules authoritatively (see `entropy-auth`'s
|
|
5
|
+
* `password::policy` / `Validation`); these implementations are kept
|
|
6
|
+
* deliberately strict to avoid false positives on the client.
|
|
7
|
+
*
|
|
8
|
+
* Email: a permissive `local@host.tld` shape — anything stricter risks
|
|
9
|
+
* rejecting valid addresses, and the server validates anyway.
|
|
10
|
+
*
|
|
11
|
+
* Password: matches the default `entropy-auth` policy (≥8 chars, mixed
|
|
12
|
+
* case, digit, symbol). Apps that opt their server into a different
|
|
13
|
+
* policy can ignore the `valid` result and let the server be the source
|
|
14
|
+
* of truth.
|
|
15
|
+
*
|
|
16
|
+
* Username: 3–30 chars, ASCII alnum + underscore.
|
|
17
|
+
*/
|
|
18
|
+
export interface PasswordValidation {
|
|
19
|
+
valid: boolean;
|
|
20
|
+
errors: string[];
|
|
21
|
+
}
|
|
22
|
+
export interface UsernameValidation {
|
|
23
|
+
valid: boolean;
|
|
24
|
+
error?: string;
|
|
25
|
+
}
|
|
26
|
+
export declare function validateEmail(email: string): boolean;
|
|
27
|
+
export declare function validatePassword(password: string): PasswordValidation;
|
|
28
|
+
export declare function validateUsername(username: string): UsernameValidation;
|
|
29
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AASD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,CAkBrE;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,CAWrE"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input validators used by the UI to surface preview feedback before
|
|
3
|
+
* the user hits the server. The Entropy Softworks application servers
|
|
4
|
+
* enforce these same rules authoritatively (see `entropy-auth`'s
|
|
5
|
+
* `password::policy` / `Validation`); these implementations are kept
|
|
6
|
+
* deliberately strict to avoid false positives on the client.
|
|
7
|
+
*
|
|
8
|
+
* Email: a permissive `local@host.tld` shape — anything stricter risks
|
|
9
|
+
* rejecting valid addresses, and the server validates anyway.
|
|
10
|
+
*
|
|
11
|
+
* Password: matches the default `entropy-auth` policy (≥8 chars, mixed
|
|
12
|
+
* case, digit, symbol). Apps that opt their server into a different
|
|
13
|
+
* policy can ignore the `valid` result and let the server be the source
|
|
14
|
+
* of truth.
|
|
15
|
+
*
|
|
16
|
+
* Username: 3–30 chars, ASCII alnum + underscore.
|
|
17
|
+
*/
|
|
18
|
+
const EMAIL = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/;
|
|
19
|
+
const UPPER = /[A-Z]/;
|
|
20
|
+
const LOWER = /[a-z]/;
|
|
21
|
+
const DIGIT = /[0-9]/;
|
|
22
|
+
const SYMBOL = /[!@#$%^&*()_+\-=[\]{}|;:,.<>?]/;
|
|
23
|
+
const USERNAME = /^[a-zA-Z0-9_]+$/;
|
|
24
|
+
export function validateEmail(email) {
|
|
25
|
+
return EMAIL.test(email);
|
|
26
|
+
}
|
|
27
|
+
export function validatePassword(password) {
|
|
28
|
+
const errors = [];
|
|
29
|
+
if (password.length < 8) {
|
|
30
|
+
errors.push("Password must be at least 8 characters");
|
|
31
|
+
}
|
|
32
|
+
if (!UPPER.test(password)) {
|
|
33
|
+
errors.push("Password must contain at least one uppercase letter");
|
|
34
|
+
}
|
|
35
|
+
if (!LOWER.test(password)) {
|
|
36
|
+
errors.push("Password must contain at least one lowercase letter");
|
|
37
|
+
}
|
|
38
|
+
if (!DIGIT.test(password)) {
|
|
39
|
+
errors.push("Password must contain at least one number");
|
|
40
|
+
}
|
|
41
|
+
if (!SYMBOL.test(password)) {
|
|
42
|
+
errors.push("Password must contain at least one special character");
|
|
43
|
+
}
|
|
44
|
+
return { valid: errors.length === 0, errors };
|
|
45
|
+
}
|
|
46
|
+
export function validateUsername(username) {
|
|
47
|
+
if (username.length < 3 || username.length > 30) {
|
|
48
|
+
return { valid: false, error: "Username must be between 3 and 30 characters" };
|
|
49
|
+
}
|
|
50
|
+
if (!USERNAME.test(username)) {
|
|
51
|
+
return {
|
|
52
|
+
valid: false,
|
|
53
|
+
error: "Username can only contain letters, numbers, and underscores",
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return { valid: true };
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAYH,MAAM,KAAK,GAAG,+BAA+B,CAAC;AAC9C,MAAM,KAAK,GAAG,OAAO,CAAC;AACtB,MAAM,KAAK,GAAG,OAAO,CAAC;AACtB,MAAM,KAAK,GAAG,OAAO,CAAC;AACtB,MAAM,MAAM,GAAG,gCAAgC,CAAC;AAChD,MAAM,QAAQ,GAAG,iBAAiB,CAAC;AAEnC,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;IACxD,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC;IACrE,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC;IACrE,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3B,MAAM,CAAC,IAAI,CAAC,sDAAsD,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,QAAQ,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QAChD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,8CAA8C,EAAE,CAAC;IACjF,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,6DAA6D;SACrE,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzB,CAAC"}
|