@steveencues/starter-react-ui 1.0.2 → 1.0.3
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/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +15 -26
- package/dist/index.js.map +1 -1
- package/dist/libs/components/Button/Button.d.ts +23 -1
- package/dist/libs/components/Button/index.d.ts +1 -1
- package/dist/libs/components/index.d.ts +1 -1
- package/dist/libs/domain/interface/theme/core/theme.interface.d.ts +3 -9
- package/dist/libs/domain/interface/theme/effects/index.d.ts +0 -2
- package/dist/libs/domain/interface/theme/index.d.ts +0 -2
- package/dist/libs/domain/interface/theme/preferences/theme-context.interface.d.ts +0 -1
- package/package.json +1 -1
- package/dist/libs/components/Button/button.types.d.ts +0 -1
- package/dist/libs/domain/interface/theme/components/index.d.ts +0 -6
- package/dist/libs/domain/interface/theme/components/theme-button.interface.d.ts +0 -18
- package/dist/libs/domain/interface/theme/components/theme-card.interface.d.ts +0 -15
- package/dist/libs/domain/interface/theme/components/theme-components.interface.d.ts +0 -12
- package/dist/libs/domain/interface/theme/components/theme-input.interface.d.ts +0 -18
- package/dist/libs/domain/interface/theme/components/theme-interactive-colors.interface.d.ts +0 -16
- package/dist/libs/domain/interface/theme/components/theme-modal.interface.d.ts +0 -14
- package/dist/libs/domain/interface/theme/effects/theme-animations.interface.d.ts +0 -20
- package/dist/libs/domain/interface/theme/effects/theme-transitions.interface.d.ts +0 -18
- package/dist/libs/domain/interface/theme/layout/index.d.ts +0 -8
- package/dist/libs/domain/interface/theme/layout/theme-breakpoints.interface.d.ts +0 -13
- package/dist/libs/domain/interface/theme/layout/theme-dimensions.interface.d.ts +0 -15
- package/dist/libs/domain/interface/theme/layout/theme-layout.interface.d.ts +0 -14
- package/dist/libs/domain/interface/theme/layout/theme-radii.interface.d.ts +0 -16
- package/dist/libs/domain/interface/theme/layout/theme-shadow-colors.interface.d.ts +0 -13
- package/dist/libs/domain/interface/theme/layout/theme-shadows.interface.d.ts +0 -16
- package/dist/libs/domain/interface/theme/layout/theme-spacing.interface.d.ts +0 -20
- package/dist/libs/domain/interface/theme/layout/theme-z-index.interface.d.ts +0 -16
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["TranslateContext","createContext","ThemeContext","useLanguage","context","useContext","useTheme","saveEncryptedPreference","value","encryptionKey","storage","getLocalStorage","encryptedValue","encryptText","storageKey","loadEncryptedPreference","decryptText","LANGUAGE_PREFERENCE_STORAGE_KEY","saveLanguagePreference","language","loadLanguagePreference","savedLanguage","availableLanguages","THEME_PREFERENCE_STORAGE_KEY","saveThemePreference","themeName","loadThemePreference","savedTheme","themes","theme","createPreferenceState","configuration","matchesConfiguration","state","restoreSavedTheme","useRestoreThemePreference","isActive","defaultTheme","resolveInitialTheme","currentState","setPreferenceState","useSetThemePreference","useCallback","assertThemeExists","nextTheme","useThemePreference","inputConfiguration","useMemo","initialTheme","themeEncryptionKey","preferenceState","useState","isCurrentConfiguration","createLanguagePreferenceState","matchesLanguageConfiguration","restoreSavedLanguage","useRestoreLanguagePreference","defaultLanguage","resolveInitialLanguage","usePersistLanguagePreference","isLoaded","useSetLanguagePreference","assertLanguageExists","nextLanguage","useLanguagePreference","selectedLanguage","setLanguage","resolveActiveLanguage","TranslateProvider","languages","translations","initialLanguage","fallbackLanguage","languageEncryptionKey","preference","contextValue","useTranslationContext","currentDictionary","fallbackDictionary","t","translateMessage","key","params","ThemeProvider","resolveActiveTheme","isPreferenceLoaded","setTheme","setThemeName","themeVariables","createThemeVariables","TranslationRegex","GLOBAL_REGEX_FLAG","AES_GCM_ALGORITHM","AES_GCM_IV_LENGTH","SHA_256_ALGORITHM","RAW_KEY_FORMAT","STORAGE_VALUE_SEPARATOR","KEY_USAGES","ENCRYPTED_VALUE_PART_COUNT","ThemeCssVariable","THEME_FONT_WEIGHT","isLanguageAvailable","findFirstLanguage","firstLanguage","findTranslationValue","current","dictionary","segment","findTranslation","resolveInterpolationValue","placeholder","interpolateTranslation","placeholderRegex","message","resolveTranslationMessage","currentTranslation","findTheme","getFirstTheme","firstTheme","selectedTheme","createSurfaceVariables","colors","createTextVariables","createBrandVariables","createStateVariables","createBorderVariables","createShadowVariables","createEffectVariables","createTypographyVariables","getCryptoApi","encodeText","decodeText","encodeBase64","binary","byte","bytes","decodeBase64","index","deriveAesKey","cryptoApi","secret","digest","createInitializationVector","decodeInitializationVector","iv","hasExpectedEncryptedParts","parts","validateEncryptedParts","parseEncryptedPayload","encodedIv","encodedCiphertext","encryptPayload","requireCryptoApi","plaintext","decryptPayload","payload","ciphertext"],"sources":["../src/libs/aplicacion/contexts/translate.context.ts","../src/libs/aplicacion/contexts/theme.context.ts","../src/libs/aplicacion/hooks/use-language.ts","../src/libs/aplicacion/hooks/use-theme.ts","../src/libs/infraestructura/storage/encrypted-preference.storage.ts","../src/libs/infraestructura/storage/language-preference.storage.ts","../src/libs/infraestructura/storage/theme-preference.storage.ts","../src/libs/aplicacion/hooks/use-theme-preference.hook.ts","../src/libs/aplicacion/providers/translate.provider.tsx","../src/libs/aplicacion/providers/theme-provider.tsx","../src/libs/domain/enums/translation-regex.enum.ts","../src/libs/domain/constants/translation.constants.ts","../src/libs/domain/constants/encrypted-preference.constanst.ts","../src/libs/domain/constants/theme-css-variable.const.ts","../src/libs/domain/constants/theme-font-weight.const.ts","../src/libs/aplicacion/utils/translation.utils.ts","../src/libs/aplicacion/utils/theme.utils.ts","../src/libs/aplicacion/utils/crypto-api.util.ts","../src/libs/aplicacion/utils/storage-api.util.ts","../src/libs/aplicacion/utils/text-encoding.util.ts","../src/libs/aplicacion/utils/base64.util.ts","../src/libs/aplicacion/services/encryption.service.ts"],"sourcesContent":["import type { ILanguageContextValue } from \"@domain\";\nimport { createContext } from \"react\";\n\n/**\n * @description Contexto interno de traducciones de la libreria.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport const TranslateContext = createContext<ILanguageContextValue | null>(\n null,\n);\n","import type { IThemeContextValue } from \"@domain\";\nimport { createContext } from \"react\";\n\n/**\n * @description Contexto interno del sistema de temas.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport const ThemeContext = createContext<IThemeContextValue | null>(null);\n","import { TranslateContext } from \"@aplicacion\";\nimport type { ILanguageContextValue } from \"@domain\";\nimport { useContext } from \"react\";\n\n/**\n * @description Obtiene el idioma actual y la funcion de traduccion.\n * Requiere que el componente este dentro de TranslateProvider.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport function useLanguage(): ILanguageContextValue {\n const context = useContext(TranslateContext);\n\n if (context === null) {\n throw new Error(\"useLanguage must be used inside TranslateProvider.\");\n }\n\n return context;\n}\n","import { ThemeContext } from \"@aplicacion\";\nimport type { IThemeContextValue } from \"@domain\";\nimport { useContext } from \"react\";\n\n/**\n * @description Obtiene el tema activo, los temas disponibles y\n * la funcion para cambiar de tema.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport function useTheme(): IThemeContextValue {\n const context = useContext(ThemeContext);\n\n if (context === null) {\n throw new Error(\"useTheme must be used inside ThemeProvider.\");\n }\n\n return context;\n}\n","import { decryptText, encryptText, getLocalStorage } from \"@aplicacion\";\n\n/**\n * @description Encrypts and saves a preference in localStorage.\n * @param storageKey Storage key.\n * @param value Value to store.\n * @param encryptionKey Encryption secret.\n * @returns Promise resolved after the save attempt.\n * @author Steveen Cues\n * @version 3.0.0\n */\nexport async function saveEncryptedPreference(\n storageKey: string,\n value: string,\n encryptionKey: string,\n): Promise<void> {\n if (value.length === 0 || encryptionKey.length === 0) {\n return;\n }\n\n try {\n const storage = getLocalStorage();\n\n if (storage === undefined) {\n return;\n }\n\n const encryptedValue = await encryptText(value, encryptionKey);\n\n if (encryptedValue === undefined) {\n return;\n }\n\n storage.setItem(storageKey, encryptedValue);\n } catch {\n // Preference persistence must not interrupt application usage.\n }\n}\n\n/**\n * @description Loads and decrypts a preference from localStorage.\n * @param storageKey Storage key.\n * @param encryptionKey Encryption secret.\n * @returns Decrypted preference or undefined when unavailable.\n * @author Steveen Cues\n * @version 3.0.0\n */\nexport async function loadEncryptedPreference(\n storageKey: string,\n encryptionKey: string,\n): Promise<string | undefined> {\n if (encryptionKey.length === 0) {\n return undefined;\n }\n\n try {\n const storage = getLocalStorage();\n\n if (storage === undefined) {\n return undefined;\n }\n\n const encryptedValue = storage.getItem(storageKey);\n\n if (encryptedValue === null) {\n return undefined;\n }\n\n return await decryptText(encryptedValue, encryptionKey);\n } catch {\n return undefined;\n }\n}\n","import {\n loadEncryptedPreference,\n saveEncryptedPreference,\n} from \"./encrypted-preference.storage\";\n\nconst LANGUAGE_PREFERENCE_STORAGE_KEY =\n \"starter-react-ui:language-preference:v1\";\n\n/**\n * @description Guarda el idioma activo de forma cifrada.\n * @param language Codigo del idioma activo.\n * @param encryptionKey Clave de cifrado proporcionada por el consumidor.\n * @returns Promesa completada al finalizar el intento de guardado.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport function saveLanguagePreference(\n language: string,\n encryptionKey: string,\n): Promise<void> {\n return saveEncryptedPreference(\n LANGUAGE_PREFERENCE_STORAGE_KEY,\n language,\n encryptionKey,\n );\n}\n\n/**\n * @description Recupera el idioma guardado y verifica que siga disponible.\n * @param availableLanguages Idiomas admitidos por el proyecto.\n * @param encryptionKey Clave de cifrado proporcionada por el consumidor.\n * @returns Idioma recuperado o undefined si no existe o no es valido.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport async function loadLanguagePreference(\n availableLanguages: readonly string[],\n encryptionKey: string,\n): Promise<string | undefined> {\n const savedLanguage = await loadEncryptedPreference(\n LANGUAGE_PREFERENCE_STORAGE_KEY,\n encryptionKey,\n );\n\n if (\n savedLanguage === undefined ||\n !availableLanguages.includes(savedLanguage)\n ) {\n return undefined;\n }\n\n return savedLanguage;\n}\n","import type { AppTheme, ThemeName } from \"@domain\";\n\nimport {\n loadEncryptedPreference,\n saveEncryptedPreference,\n} from \"./encrypted-preference.storage\";\n\nconst THEME_PREFERENCE_STORAGE_KEY = \"starter-react-ui:theme-preference:v1\";\n\n/**\n * @description Guarda el nombre del tema activo de forma cifrada.\n * @param themeName Nombre del tema.\n * @param encryptionKey Clave de cifrado proporcionada por el consumidor.\n * @returns Promesa completada al finalizar el intento de guardado.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport function saveThemePreference(\n themeName: ThemeName,\n encryptionKey: string,\n): Promise<void> {\n return saveEncryptedPreference(\n THEME_PREFERENCE_STORAGE_KEY,\n themeName,\n encryptionKey,\n );\n}\n\n/**\n * @description Recupera el tema guardado si existe entre los temas admitidos.\n * @param themes Temas definidos por el proyecto consumidor.\n * @param encryptionKey Clave de cifrado proporcionada por el consumidor.\n * @returns Nombre del tema recuperado o undefined.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport async function loadThemePreference(\n themes: readonly AppTheme[],\n encryptionKey: string,\n): Promise<ThemeName | undefined> {\n const savedTheme = await loadEncryptedPreference(\n THEME_PREFERENCE_STORAGE_KEY,\n encryptionKey,\n );\n\n if (savedTheme === undefined) {\n return undefined;\n }\n\n const availableTheme = themes.find(\n (theme: AppTheme): boolean => theme.name === savedTheme,\n );\n\n return availableTheme?.name;\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\n\nimport type {\n SetThemePreferenceState,\n ThemeName,\n ThemePreferenceConfiguration,\n ThemePreferenceResult,\n ThemePreferenceState,\n} from \"@domain\";\n\nimport { loadThemePreference } from \"@infraestructura\";\n\nimport { assertThemeExists, resolveInitialTheme } from \"@aplicacion\";\n\n/**\n * @description Creates a preference state for the given configuration.\n * @author Steveen Cues\n * @version 3.0.0\n */\nfunction createPreferenceState(\n configuration: ThemePreferenceConfiguration,\n themeName: ThemeName,\n isLoaded: boolean,\n): ThemePreferenceState {\n return {\n ...configuration,\n themeName,\n isLoaded,\n };\n}\n\n/**\n * @description Checks whether a state belongs to the active configuration.\n * @author Steveen Cues\n * @version 3.0.0\n */\nfunction matchesConfiguration(\n state: ThemePreferenceState,\n configuration: ThemePreferenceConfiguration,\n): boolean {\n return (\n state.themes === configuration.themes &&\n state.initialTheme === configuration.initialTheme &&\n state.themeEncryptionKey === configuration.themeEncryptionKey\n );\n}\n\n/**\n * @description Loads the stored theme and safely handles restoration failures.\n * @author Steveen Cues\n * @version 3.0.0\n */\nasync function restoreSavedTheme(\n configuration: ThemePreferenceConfiguration,\n): Promise<ThemeName | undefined> {\n try {\n return await loadThemePreference(\n configuration.themes,\n configuration.themeEncryptionKey,\n );\n } catch {\n return undefined;\n }\n}\n\n/**\n * @description Restores the saved preference without overriding a user selection.\n * @author Steveen Cues\n * @version 3.0.0\n */\nfunction useRestoreThemePreference(\n configuration: ThemePreferenceConfiguration,\n setPreferenceState: SetThemePreferenceState,\n): void {\n useEffect((): (() => void) => {\n let isActive = true;\n\n const restorePreference = async (): Promise<void> => {\n const savedTheme = await restoreSavedTheme(configuration);\n\n if (!isActive) {\n return;\n }\n\n const defaultTheme = resolveInitialTheme(\n configuration.themes,\n configuration.initialTheme,\n );\n\n setPreferenceState(\n (currentState: ThemePreferenceState): ThemePreferenceState => {\n if (\n matchesConfiguration(currentState, configuration) &&\n currentState.isLoaded\n ) {\n return currentState;\n }\n\n return createPreferenceState(\n configuration,\n savedTheme ?? defaultTheme.name,\n true,\n );\n },\n );\n };\n\n void restorePreference();\n\n return (): void => {\n isActive = false;\n };\n }, [configuration, setPreferenceState]);\n}\n\n/**\n * @description Creates a validated theme selection handler.\n * @author Steveen Cues\n * @version 3.0.0\n */\nfunction useSetThemePreference(\n configuration: ThemePreferenceConfiguration,\n setPreferenceState: SetThemePreferenceState,\n): (nextTheme: ThemeName) => void {\n return useCallback(\n (nextTheme: ThemeName): void => {\n assertThemeExists(configuration.themes, nextTheme);\n\n setPreferenceState(createPreferenceState(configuration, nextTheme, true));\n },\n [configuration, setPreferenceState],\n );\n}\n\n/**\n * @description Manages the selected theme and its encrypted persistence lifecycle.\n * @author Steveen Cues\n * @version 3.0.0\n */\nexport function useThemePreference(\n inputConfiguration: ThemePreferenceConfiguration,\n): ThemePreferenceResult {\n const { themes, initialTheme, themeEncryptionKey } = inputConfiguration;\n\n const configuration = useMemo(\n (): ThemePreferenceConfiguration => ({\n themes,\n initialTheme,\n themeEncryptionKey,\n }),\n [themes, initialTheme, themeEncryptionKey],\n );\n\n const [preferenceState, setPreferenceState] = useState<ThemePreferenceState>(\n (): ThemePreferenceState =>\n createPreferenceState(\n configuration,\n resolveInitialTheme(themes, initialTheme).name,\n false,\n ),\n );\n\n useRestoreThemePreference(configuration, setPreferenceState);\n\n const isCurrentConfiguration = matchesConfiguration(\n preferenceState,\n configuration,\n );\n\n const themeName = isCurrentConfiguration\n ? preferenceState.themeName\n : resolveInitialTheme(themes, initialTheme).name;\n\n const isPreferenceLoaded = isCurrentConfiguration && preferenceState.isLoaded;\n\n const setThemeName = useSetThemePreference(configuration, setPreferenceState);\n\n return {\n themeName,\n isPreferenceLoaded,\n setThemeName,\n };\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\n\nimport type { JSX } from \"react\";\n\nimport type {\n ILanguageContextValue,\n ITranslateProviderProps,\n TranslationParams,\n TranslationDictionary,\n} from \"@domain\";\n\nimport { TranslateContext } from \"@aplicacion\";\n\nimport {\n loadLanguagePreference,\n saveLanguagePreference,\n} from \"@infraestructura\";\n\nimport {\n assertLanguageExists,\n resolveActiveLanguage,\n resolveInitialLanguage,\n translateMessage,\n} from \"@aplicacion\";\n\ninterface LanguagePreferenceConfiguration {\n readonly translations: ITranslateProviderProps[\"translations\"];\n readonly initialLanguage: ITranslateProviderProps[\"initialLanguage\"];\n readonly fallbackLanguage: string;\n readonly languageEncryptionKey: ITranslateProviderProps[\"languageEncryptionKey\"];\n readonly languages: readonly string[];\n}\n\ninterface LanguagePreferenceState extends LanguagePreferenceConfiguration {\n readonly selectedLanguage: string;\n readonly isLoaded: boolean;\n}\n\ninterface LanguagePreferenceResult {\n readonly language: string;\n readonly isLoaded: boolean;\n readonly setLanguage: (language: string) => void;\n}\n\ntype SetLanguagePreferenceState = React.Dispatch<\n React.SetStateAction<LanguagePreferenceState>\n>;\n\n/**\n * @description Creates the initial language preference state.\n * @author Steveen Cues\n * @version 4.0.0\n */\nfunction createLanguagePreferenceState(\n configuration: LanguagePreferenceConfiguration,\n selectedLanguage: string,\n isLoaded: boolean,\n): LanguagePreferenceState {\n return {\n ...configuration,\n selectedLanguage,\n isLoaded,\n };\n}\n\n/**\n * @description Checks whether a state matches the active configuration.\n * @author Steveen Cues\n * @version 4.0.0\n */\nfunction matchesLanguageConfiguration(\n state: LanguagePreferenceState,\n configuration: LanguagePreferenceConfiguration,\n): boolean {\n return (\n state.translations === configuration.translations &&\n state.initialLanguage === configuration.initialLanguage &&\n state.fallbackLanguage === configuration.fallbackLanguage &&\n state.languageEncryptionKey === configuration.languageEncryptionKey &&\n state.languages === configuration.languages\n );\n}\n\n/**\n * @description Restores the saved language and falls back when loading fails.\n * @author Steveen Cues\n * @version 4.0.0\n */\nasync function restoreSavedLanguage(\n configuration: LanguagePreferenceConfiguration,\n): Promise<string | undefined> {\n try {\n return await loadLanguagePreference(\n configuration.languages,\n configuration.languageEncryptionKey,\n );\n } catch {\n return undefined;\n }\n}\n\n/**\n * @description Restores the saved language for the active configuration.\n * @author Steveen Cues\n * @version 4.0.0\n */\nfunction useRestoreLanguagePreference(\n configuration: LanguagePreferenceConfiguration,\n setPreferenceState: SetLanguagePreferenceState,\n): void {\n useEffect((): (() => void) => {\n let isActive = true;\n\n const restorePreference = async (): Promise<void> => {\n const savedLanguage = await restoreSavedLanguage(configuration);\n\n if (!isActive) {\n return;\n }\n\n const defaultLanguage = resolveInitialLanguage(\n configuration.translations,\n configuration.initialLanguage,\n configuration.fallbackLanguage,\n );\n\n setPreferenceState(\n (currentState: LanguagePreferenceState): LanguagePreferenceState => {\n if (\n matchesLanguageConfiguration(currentState, configuration) &&\n currentState.isLoaded\n ) {\n return currentState;\n }\n\n return createLanguagePreferenceState(\n configuration,\n savedLanguage ?? defaultLanguage,\n true,\n );\n },\n );\n };\n\n void restorePreference();\n\n return (): void => {\n isActive = false;\n };\n }, [configuration, setPreferenceState]);\n}\n\n/**\n * @description Persists the active language after preference restoration.\n * @author Steveen Cues\n * @version 4.0.0\n */\nfunction usePersistLanguagePreference(\n configuration: LanguagePreferenceConfiguration,\n language: string,\n isLoaded: boolean,\n): void {\n useEffect((): void => {\n if (!isLoaded) {\n return;\n }\n\n void saveLanguagePreference(language, configuration.languageEncryptionKey);\n }, [configuration.languageEncryptionKey, language, isLoaded]);\n}\n\n/**\n * @description Creates a validated language selection handler.\n * @author Steveen Cues\n * @version 4.0.0\n */\nfunction useSetLanguagePreference(\n configuration: LanguagePreferenceConfiguration,\n setPreferenceState: SetLanguagePreferenceState,\n): (language: string) => void {\n return useCallback(\n (nextLanguage: string): void => {\n assertLanguageExists(configuration.translations, nextLanguage);\n\n setPreferenceState(\n createLanguagePreferenceState(configuration, nextLanguage, true),\n );\n },\n [configuration, setPreferenceState],\n );\n}\n\n/**\n * @description Manages language selection, restoration, and persistence.\n * @author Steveen Cues\n * @version 4.0.0\n */\nfunction useLanguagePreference(\n configuration: LanguagePreferenceConfiguration,\n): LanguagePreferenceResult {\n const [preferenceState, setPreferenceState] =\n useState<LanguagePreferenceState>((): LanguagePreferenceState =>\n createLanguagePreferenceState(\n configuration,\n configuration.initialLanguage,\n false,\n ),\n );\n\n useRestoreLanguagePreference(configuration, setPreferenceState);\n\n const isCurrentConfiguration = matchesLanguageConfiguration(\n preferenceState,\n configuration,\n );\n\n const selectedLanguage = isCurrentConfiguration\n ? preferenceState.selectedLanguage\n : configuration.initialLanguage;\n\n const isLoaded = isCurrentConfiguration && preferenceState.isLoaded;\n\n const setLanguage = useSetLanguagePreference(\n configuration,\n setPreferenceState,\n );\n\n return {\n language: resolveActiveLanguage(\n configuration.translations,\n selectedLanguage,\n configuration.initialLanguage,\n configuration.fallbackLanguage,\n ),\n isLoaded,\n setLanguage,\n };\n}\n\n/**\n * @description Provides the active language and translation functions.\n * @author Steveen Cues\n * @version 4.0.0\n */\nexport function TranslateProvider({\n translations,\n initialLanguage,\n fallbackLanguage = \"en\",\n languageEncryptionKey,\n children,\n}: ITranslateProviderProps): JSX.Element {\n const languages = useMemo(\n (): readonly string[] => Object.keys(translations),\n [translations],\n );\n\n const configuration = useMemo(\n (): LanguagePreferenceConfiguration => ({\n translations,\n initialLanguage,\n fallbackLanguage,\n languageEncryptionKey,\n languages,\n }),\n [\n translations,\n initialLanguage,\n fallbackLanguage,\n languageEncryptionKey,\n languages,\n ],\n );\n\n const preference = useLanguagePreference(configuration);\n\n usePersistLanguagePreference(\n configuration,\n preference.language,\n preference.isLoaded,\n );\n\n const contextValue = useTranslationContext(configuration, preference);\n\n return (\n <TranslateContext.Provider value={contextValue}>\n {children}\n </TranslateContext.Provider>\n );\n}\n\n/**\n * @description Creates the translation context value.\n * @author Steveen Cues\n * @version 4.0.0\n */\nfunction useTranslationContext(\n configuration: LanguagePreferenceConfiguration,\n preference: LanguagePreferenceResult,\n): ILanguageContextValue {\n const currentDictionary: TranslationDictionary =\n configuration.translations[preference.language];\n\n const fallbackDictionary: TranslationDictionary =\n configuration.translations[configuration.fallbackLanguage];\n\n const t = useCallback(\n (key: string, params?: TranslationParams): string =>\n translateMessage(currentDictionary, fallbackDictionary, key, params),\n [currentDictionary, fallbackDictionary],\n );\n\n return useMemo(\n (): ILanguageContextValue => ({\n language: preference.language,\n languages: configuration.languages,\n setLanguage: preference.setLanguage,\n t,\n }),\n [preference.language, preference.setLanguage, configuration.languages, t],\n );\n}\n","import { useCallback, useEffect, useMemo } from \"react\";\n\nimport type {\n IThemeContextValue,\n IThemeProviderProps,\n ThemeName,\n} from \"@domain\";\nimport type { JSX } from \"react\";\n\nimport { saveThemePreference } from \"@infraestructura\";\n\nimport {\n ThemeContext,\n createThemeVariables,\n resolveActiveTheme,\n useThemePreference,\n} from \"@aplicacion\";\n\n/**\n * @description Provides the active theme and allows theme changes.\n * Restores and persists the encrypted theme preference.\n * @author Steveen Cues\n * @version 4.0.0\n */\nexport function ThemeProvider({\n themes,\n initialTheme,\n themeEncryptionKey,\n children,\n}: IThemeProviderProps): JSX.Element {\n const { themeName, isPreferenceLoaded, setThemeName } = useThemePreference({\n themes,\n initialTheme,\n themeEncryptionKey,\n });\n\n const theme = resolveActiveTheme(themes, themeName, initialTheme);\n\n useEffect((): void => {\n if (!isPreferenceLoaded) {\n return;\n }\n\n void saveThemePreference(theme.name, themeEncryptionKey);\n }, [isPreferenceLoaded, theme.name, themeEncryptionKey]);\n\n const setTheme = useCallback(\n (nextTheme: ThemeName): void => setThemeName(nextTheme),\n [setThemeName],\n );\n\n const themeVariables = useMemo(() => createThemeVariables(theme), [theme]);\n\n const contextValue = useMemo<IThemeContextValue>(\n () => ({\n theme,\n themeName: theme.name,\n themes,\n setTheme,\n }),\n [theme, themes, setTheme],\n );\n\n return (\n <ThemeContext.Provider value={contextValue}>\n <div\n data-rui-theme={theme.name}\n style={{\n ...themeVariables,\n display: \"contents\",\n }}\n >\n {children}\n </div>\n </ThemeContext.Provider>\n );\n}\n","/**\n * @description Expresiones regulares reutilizables para traducciones.\n * @author Steveen Cues\n * @version 2.0.0\n */\nexport const TranslationRegex = Object.freeze({\n INTERPOLATION_PLACEHOLDER: String.raw`\\{\\{([a-zA-Z0-9_]+)\\}\\}`,\n});\n","export const GLOBAL_REGEX_FLAG = \"g\";\n","export const AES_GCM_ALGORITHM = \"AES-GCM\";\nexport const AES_GCM_IV_LENGTH = 12;\nexport const SHA_256_ALGORITHM = \"SHA-256\";\nexport const RAW_KEY_FORMAT = \"raw\";\nexport const STORAGE_VALUE_SEPARATOR = \".\";\nexport const KEY_USAGES: KeyUsage[] = [\"encrypt\", \"decrypt\"];\nexport const ENCRYPTED_VALUE_PART_COUNT = 2;\n","/**\n * @description Define los nombres de las variables CSS de la libreria.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport const ThemeCssVariable = {\n SURFACE_BACKGROUND: \"--rui-surface-background\",\n SURFACE_SURFACE: \"--rui-surface-surface\",\n SURFACE_SURFACE_ELEVATED: \"--rui-surface-surface-elevated\",\n SURFACE_SURFACE_HOVER: \"--rui-surface-surface-hover\",\n SURFACE_SURFACE_ACTIVE: \"--rui-surface-surface-active\",\n SURFACE_SURFACE_DISABLED: \"--rui-surface-surface-disabled\",\n\n TEXT_PRIMARY: \"--rui-text-primary\",\n TEXT_SECONDARY: \"--rui-text-secondary\",\n TEXT_MUTED: \"--rui-text-muted\",\n TEXT_DISABLED: \"--rui-text-disabled\",\n TEXT_INVERSE: \"--rui-text-inverse\",\n TEXT_LINK: \"--rui-text-link\",\n TEXT_LINK_HOVER: \"--rui-text-link-hover\",\n\n BRAND_PRIMARY: \"--rui-brand-primary\",\n BRAND_PRIMARY_HOVER: \"--rui-brand-primary-hover\",\n BRAND_PRIMARY_ACTIVE: \"--rui-brand-primary-active\",\n BRAND_PRIMARY_CONTRAST: \"--rui-brand-primary-contrast\",\n BRAND_SECONDARY: \"--rui-brand-secondary\",\n BRAND_SECONDARY_HOVER: \"--rui-brand-secondary-hover\",\n BRAND_SECONDARY_ACTIVE: \"--rui-brand-secondary-active\",\n BRAND_SECONDARY_CONTRAST: \"--rui-brand-secondary-contrast\",\n BRAND_ACCENT: \"--rui-brand-accent\",\n BRAND_ACCENT_HOVER: \"--rui-brand-accent-hover\",\n BRAND_ACCENT_CONTRAST: \"--rui-brand-accent-contrast\",\n\n STATE_SUCCESS: \"--rui-state-success\",\n STATE_SUCCESS_BACKGROUND: \"--rui-state-success-background\",\n STATE_WARNING: \"--rui-state-warning\",\n STATE_WARNING_BACKGROUND: \"--rui-state-warning-background\",\n STATE_ERROR: \"--rui-state-error\",\n STATE_ERROR_BACKGROUND: \"--rui-state-error-background\",\n STATE_INFO: \"--rui-state-info\",\n STATE_INFO_BACKGROUND: \"--rui-state-info-background\",\n\n BORDER_DEFAULT: \"--rui-border-default\",\n BORDER_SUBTLE: \"--rui-border-subtle\",\n BORDER_STRONG: \"--rui-border-strong\",\n BORDER_FOCUS: \"--rui-border-focus\",\n BORDER_HOVER: \"--rui-border-hover\",\n BORDER_ACTIVE: \"--rui-border-active\",\n BORDER_DISABLED: \"--rui-border-disabled\",\n\n SHADOW_COLOR: \"--rui-shadow-color\",\n SHADOW_SUBTLE: \"--rui-shadow-subtle\",\n SHADOW_SMALL: \"--rui-shadow-small\",\n SHADOW_MEDIUM: \"--rui-shadow-medium\",\n SHADOW_LARGE: \"--rui-shadow-large\",\n SHADOW_GLOW: \"--rui-shadow-glow\",\n\n EFFECTS_OVERLAY: \"--rui-effects-overlay\",\n EFFECTS_BACKDROP: \"--rui-effects-backdrop\",\n EFFECTS_BLUR: \"--rui-effects-blur\",\n EFFECTS_BLUR_STRONG: \"--rui-effects-blur-strong\",\n EFFECTS_GLASS_BACKGROUND: \"--rui-effects-glass-background\",\n EFFECTS_GLASS_BORDER: \"--rui-effects-glass-border\",\n\n TYPOGRAPHY_HEADING_PRIMARY: \"--rui-typography-heading-primary\",\n TYPOGRAPHY_HEADING_SECONDARY: \"--rui-typography-heading-secondary\",\n TYPOGRAPHY_HEADING_MUTED: \"--rui-typography-heading-muted\",\n TYPOGRAPHY_BODY_PRIMARY: \"--rui-typography-body-primary\",\n TYPOGRAPHY_BODY_SECONDARY: \"--rui-typography-body-secondary\",\n TYPOGRAPHY_BODY_MUTED: \"--rui-typography-body-muted\",\n TYPOGRAPHY_LABEL_PRIMARY: \"--rui-typography-label-primary\",\n TYPOGRAPHY_LABEL_SECONDARY: \"--rui-typography-label-secondary\",\n TYPOGRAPHY_LABEL_MUTED: \"--rui-typography-label-muted\",\n TYPOGRAPHY_BUTTON_PRIMARY: \"--rui-typography-button-primary\",\n TYPOGRAPHY_BUTTON_SECONDARY: \"--rui-typography-button-secondary\",\n} as const;\n","/**\n * @description Defines the standard typography weights.\n * @author Steveen Cues\n * @version 2.0.0\n */\nconst THEME_FONT_WEIGHT_THIN = 100;\nconst THEME_FONT_WEIGHT_EXTRA_LIGHT = 200;\nconst THEME_FONT_WEIGHT_LIGHT = 300;\nconst THEME_FONT_WEIGHT_REGULAR = 400;\nconst THEME_FONT_WEIGHT_MEDIUM = 500;\nconst THEME_FONT_WEIGHT_SEMI_BOLD = 600;\nconst THEME_FONT_WEIGHT_BOLD = 700;\nconst THEME_FONT_WEIGHT_EXTRA_BOLD = 800;\nconst THEME_FONT_WEIGHT_BLACK = 900;\n\n/**\n * @description Defines the available typography weights.\n * @author Steveen Cues\n * @version 2.0.0\n */\nexport const THEME_FONT_WEIGHT = {\n THIN: THEME_FONT_WEIGHT_THIN,\n EXTRA_LIGHT: THEME_FONT_WEIGHT_EXTRA_LIGHT,\n LIGHT: THEME_FONT_WEIGHT_LIGHT,\n REGULAR: THEME_FONT_WEIGHT_REGULAR,\n MEDIUM: THEME_FONT_WEIGHT_MEDIUM,\n SEMI_BOLD: THEME_FONT_WEIGHT_SEMI_BOLD,\n BOLD: THEME_FONT_WEIGHT_BOLD,\n EXTRA_BOLD: THEME_FONT_WEIGHT_EXTRA_BOLD,\n BLACK: THEME_FONT_WEIGHT_BLACK,\n} as const;\n","import {\n type TranslationCatalog,\n type TranslationDictionary,\n type TranslationParams,\n type TranslationValue,\n GLOBAL_REGEX_FLAG,\n TranslationRegex,\n} from \"@domain\";\n\n/**\n * @description Comprueba si un idioma existe en el catalogo.\n * @param translations Catalogo disponible.\n * @param language Codigo del idioma.\n * @returns Indica si el idioma esta registrado.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction isLanguageAvailable(\n translations: TranslationCatalog,\n language: string,\n): boolean {\n return Object.hasOwn(translations, language);\n}\n\n/**\n * @description Obtiene el primer idioma registrado en el catalogo.\n * @param translations Catalogo de traducciones.\n * @returns Codigo del primer idioma o undefined si esta vacio.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction findFirstLanguage(\n translations: TranslationCatalog,\n): string | undefined {\n const [firstLanguage] = Object.keys(translations);\n\n return firstLanguage;\n}\n\n/**\n * @description Obtiene el idioma inicial disponible, priorizando el\n * idioma solicitado, el idioma de respaldo y el primer idioma registrado.\n * @param translations Catalogo de traducciones.\n * @param initialLanguage Idioma solicitado inicialmente.\n * @param fallbackLanguage Idioma de respaldo.\n * @returns Codigo del idioma inicial disponible.\n * @throws Error cuando el catalogo esta vacio.\n * @author Steveen Cues\n * @version 2.0.0\n */\nexport function resolveInitialLanguage(\n translations: TranslationCatalog,\n initialLanguage: string,\n fallbackLanguage: string,\n): string {\n if (isLanguageAvailable(translations, initialLanguage)) {\n return initialLanguage;\n }\n\n if (isLanguageAvailable(translations, fallbackLanguage)) {\n return fallbackLanguage;\n }\n\n const firstLanguage = findFirstLanguage(translations);\n\n if (firstLanguage === undefined) {\n throw new Error(\n \"TranslateProvider requires at least one translation catalog.\",\n );\n }\n\n return firstLanguage;\n}\n\n/**\n * @description Resuelve el idioma seleccionado y utiliza el idioma\n * inicial, el respaldo o el primer idioma disponible si es necesario.\n * @param translations Catalogo de traducciones.\n * @param selectedLanguage Idioma seleccionado actualmente.\n * @param initialLanguage Idioma inicial configurado.\n * @param fallbackLanguage Idioma de respaldo.\n * @returns Codigo del idioma activo.\n * @author Steveen Cues\n * @version 2.0.0\n */\nexport function resolveActiveLanguage(\n translations: TranslationCatalog,\n selectedLanguage: string,\n initialLanguage: string,\n fallbackLanguage: string,\n): string {\n if (isLanguageAvailable(translations, selectedLanguage)) {\n return selectedLanguage;\n }\n\n return resolveInitialLanguage(\n translations,\n initialLanguage,\n fallbackLanguage,\n );\n}\n\n/**\n * @description Valida que un idioma este registrado en el catalogo.\n * @param translations Catalogo de traducciones.\n * @param language Codigo del idioma que se desea validar.\n * @returns No devuelve ningun valor.\n * @throws Error cuando el idioma no esta disponible.\n * @author Steveen Cues\n * @version 2.0.0\n */\nexport function assertLanguageExists(\n translations: TranslationCatalog,\n language: string,\n): void {\n if (isLanguageAvailable(translations, language)) {\n return;\n }\n\n throw new Error(\n `Language \"${language}\" is not available in the translation catalog.`,\n );\n}\n\n/**\n * @description Obtiene el valor anidado de una clave usando notacion\n * de puntos, por ejemplo \"navigation.contact\".\n * @param dictionary Diccionario donde se realiza la busqueda.\n * @param key Clave de traduccion.\n * @returns Valor encontrado o undefined si no existe.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction findTranslationValue(\n dictionary: TranslationDictionary,\n key: string,\n): TranslationValue | undefined {\n let current: TranslationValue = dictionary;\n\n for (const segment of key.split(\".\")) {\n if (typeof current === \"string\") {\n return undefined;\n }\n\n if (!Object.hasOwn(current, segment)) {\n return undefined;\n }\n\n current = current[segment];\n }\n\n return current;\n}\n\n/**\n * @description Busca una traduccion dentro de un diccionario.\n * @param dictionary Diccionario del idioma.\n * @param key Clave con notacion de puntos.\n * @returns Traduccion encontrada o undefined.\n * @author Steveen Cues\n * @version 2.0.0\n */\nexport function findTranslation(\n dictionary: TranslationDictionary | undefined,\n key: string,\n): string | undefined {\n if (dictionary === undefined || key === \"\") {\n return undefined;\n }\n\n const value = findTranslationValue(dictionary, key);\n\n return typeof value === \"string\" ? value : undefined;\n}\n\n/**\n * @description Resuelve el texto correspondiente a un marcador de\n * interpolacion sin eliminarlo cuando falta su parametro.\n * @param placeholder Marcador original, por ejemplo {{name}}.\n * @param key Nombre del parametro.\n * @param params Parametros disponibles.\n * @returns Valor interpolado o marcador original.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction resolveInterpolationValue(\n placeholder: string,\n key: string,\n params: TranslationParams | undefined,\n): string {\n const value = params?.[key];\n\n return value === undefined ? placeholder : String(value);\n}\n\n/**\n * @description Sustituye los marcadores {{name}} usando los parametros.\n * @param message Mensaje que se desea interpolar.\n * @param params Valores disponibles para la interpolacion.\n * @returns Mensaje con los parametros sustituidos.\n * @author Steveen Cues\n * @version 2.0.0\n */\nexport function interpolateTranslation(\n message: string,\n params?: TranslationParams,\n): string {\n const placeholderRegex = new RegExp(\n TranslationRegex.INTERPOLATION_PLACEHOLDER,\n GLOBAL_REGEX_FLAG,\n );\n\n return message.replace(\n placeholderRegex,\n (placeholder: string, key: string): string =>\n resolveInterpolationValue(placeholder, key, params),\n );\n}\n\n/**\n * @description Busca una traduccion en el idioma activo y utiliza el\n * idioma de respaldo cuando la clave no esta disponible.\n * @param currentDictionary Diccionario del idioma activo.\n * @param fallbackDictionary Diccionario del idioma de respaldo.\n * @param key Clave de traduccion.\n * @returns Traduccion encontrada o clave original.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction resolveTranslationMessage(\n currentDictionary: TranslationDictionary | undefined,\n fallbackDictionary: TranslationDictionary | undefined,\n key: string,\n): string {\n const currentTranslation = findTranslation(currentDictionary, key);\n\n if (currentTranslation !== undefined) {\n return currentTranslation;\n }\n\n const fallbackTranslation = findTranslation(fallbackDictionary, key);\n\n return fallbackTranslation ?? key;\n}\n\n/**\n * @description Traduce un mensaje aplicando respaldo e interpolacion.\n * @param currentDictionary Diccionario del idioma activo.\n * @param fallbackDictionary Diccionario del idioma de respaldo.\n * @param key Clave de traduccion.\n * @param params Parametros de interpolacion.\n * @returns Mensaje final traducido e interpolado.\n * @author Steveen Cues\n * @version 2.0.0\n */\nexport function translateMessage(\n currentDictionary: TranslationDictionary | undefined,\n fallbackDictionary: TranslationDictionary | undefined,\n key: string,\n params?: TranslationParams,\n): string {\n const message = resolveTranslationMessage(\n currentDictionary,\n fallbackDictionary,\n key,\n );\n\n return interpolateTranslation(message, params);\n}\n","import {\n ThemeCssVariable,\n type AppTheme,\n type BorderVariables,\n type BrandVariables,\n type EffectVariables,\n type ShadowVariables,\n type StateVariables,\n type SurfaceVariables,\n type TextVariables,\n type ThemeCssVariables,\n type ThemeName,\n type TypographyVariables,\n} from \"@domain\";\n\n/**\n * @description Busca un tema por su nombre.\n * @author Steveen Cues\n * @version 1.0.0\n */\nfunction findTheme(\n themes: readonly AppTheme[],\n themeName: ThemeName,\n): AppTheme | undefined {\n return themes.find((theme) => theme.name === themeName);\n}\n\n/**\n * @description Obtiene el primer tema registrado.\n * @throws {Error} Cuando no hay temas registrados.\n * @author Steveen Cues\n * @version 1.0.0\n */\n/**\n * @description Obtiene el primer tema registrado.\n * @author Steveen Cues\n * @version 2.1.0\n */\n/**\n * @description Obtiene el primer tema registrado.\n * @author Steveen Cues\n * @version 2.1.0\n */\n/**\n * @description Obtiene el primer tema registrado.\n * @author Steveen Cues\n * @version 2.2.0\n */\nfunction getFirstTheme(themes: readonly AppTheme[]): AppTheme {\n const firstTheme = themes.at(0);\n\n if (firstTheme === undefined) {\n throw new Error(\"ThemeProvider requires at least one registered theme.\");\n }\n\n return firstTheme;\n}\n\n/**\n * @description Resuelve el tema inicial solicitado o utiliza el primero registrado.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport function resolveInitialTheme(\n themes: readonly AppTheme[],\n initialTheme: ThemeName,\n): AppTheme {\n return findTheme(themes, initialTheme) ?? getFirstTheme(themes);\n}\n\n/**\n * @description Resuelve el tema activo o recupera uno disponible.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport function resolveActiveTheme(\n themes: readonly AppTheme[],\n selectedTheme: ThemeName,\n initialTheme: ThemeName,\n): AppTheme {\n return (\n findTheme(themes, selectedTheme) ??\n resolveInitialTheme(themes, initialTheme)\n );\n}\n\n/**\n * @description Valida que el tema solicitado este registrado.\n * @throws {Error} Cuando el tema no esta registrado.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport function assertThemeExists(\n themes: readonly AppTheme[],\n themeName: ThemeName,\n): void {\n if (findTheme(themes, themeName) === undefined) {\n throw new Error(`Theme \"${themeName}\" is not registered in ThemeProvider.`);\n }\n}\n\n/**\n * @description Crea variables CSS para los colores de superficie.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction createSurfaceVariables(colors: AppTheme[\"themes\"]): SurfaceVariables {\n return {\n [ThemeCssVariable.SURFACE_BACKGROUND]: colors.surface.background,\n [ThemeCssVariable.SURFACE_SURFACE]: colors.surface.surface,\n [ThemeCssVariable.SURFACE_SURFACE_ELEVATED]: colors.surface.surfaceElevated,\n [ThemeCssVariable.SURFACE_SURFACE_HOVER]: colors.surface.surfaceHover,\n [ThemeCssVariable.SURFACE_SURFACE_ACTIVE]: colors.surface.surfaceActive,\n [ThemeCssVariable.SURFACE_SURFACE_DISABLED]: colors.surface.surfaceDisabled,\n };\n}\n\n/**\n * @description Crea variables CSS para los colores de texto.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction createTextVariables(colors: AppTheme[\"themes\"]): TextVariables {\n return {\n [ThemeCssVariable.TEXT_PRIMARY]: colors.text.primary,\n [ThemeCssVariable.TEXT_SECONDARY]: colors.text.secondary,\n [ThemeCssVariable.TEXT_MUTED]: colors.text.muted,\n [ThemeCssVariable.TEXT_DISABLED]: colors.text.disabled,\n [ThemeCssVariable.TEXT_INVERSE]: colors.text.inverse,\n [ThemeCssVariable.TEXT_LINK]: colors.text.link,\n [ThemeCssVariable.TEXT_LINK_HOVER]: colors.text.linkHover,\n };\n}\n\n/**\n * @description Crea variables CSS para los colores de marca.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction createBrandVariables(colors: AppTheme[\"themes\"]): BrandVariables {\n return {\n [ThemeCssVariable.BRAND_PRIMARY]: colors.brand.primary,\n [ThemeCssVariable.BRAND_PRIMARY_HOVER]: colors.brand.primaryHover,\n [ThemeCssVariable.BRAND_PRIMARY_ACTIVE]: colors.brand.primaryActive,\n [ThemeCssVariable.BRAND_PRIMARY_CONTRAST]: colors.brand.primaryContrast,\n [ThemeCssVariable.BRAND_SECONDARY]: colors.brand.secondary,\n [ThemeCssVariable.BRAND_SECONDARY_HOVER]: colors.brand.secondaryHover,\n [ThemeCssVariable.BRAND_SECONDARY_ACTIVE]: colors.brand.secondaryActive,\n [ThemeCssVariable.BRAND_SECONDARY_CONTRAST]: colors.brand.secondaryContrast,\n [ThemeCssVariable.BRAND_ACCENT]: colors.brand.accent,\n [ThemeCssVariable.BRAND_ACCENT_HOVER]: colors.brand.accentHover,\n [ThemeCssVariable.BRAND_ACCENT_CONTRAST]: colors.brand.accentContrast,\n };\n}\n\n/**\n * @description Crea variables CSS para los estados.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction createStateVariables(colors: AppTheme[\"themes\"]): StateVariables {\n return {\n [ThemeCssVariable.STATE_SUCCESS]: colors.state.success,\n [ThemeCssVariable.STATE_SUCCESS_BACKGROUND]: colors.state.successBackground,\n [ThemeCssVariable.STATE_WARNING]: colors.state.warning,\n [ThemeCssVariable.STATE_WARNING_BACKGROUND]: colors.state.warningBackground,\n [ThemeCssVariable.STATE_ERROR]: colors.state.error,\n [ThemeCssVariable.STATE_ERROR_BACKGROUND]: colors.state.errorBackground,\n [ThemeCssVariable.STATE_INFO]: colors.state.info,\n [ThemeCssVariable.STATE_INFO_BACKGROUND]: colors.state.infoBackground,\n };\n}\n\n/**\n * @description Crea variables CSS para los bordes.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction createBorderVariables(colors: AppTheme[\"themes\"]): BorderVariables {\n return {\n [ThemeCssVariable.BORDER_DEFAULT]: colors.border.default,\n [ThemeCssVariable.BORDER_SUBTLE]: colors.border.subtle,\n [ThemeCssVariable.BORDER_STRONG]: colors.border.strong,\n [ThemeCssVariable.BORDER_FOCUS]: colors.border.focus,\n [ThemeCssVariable.BORDER_HOVER]: colors.border.hover,\n [ThemeCssVariable.BORDER_ACTIVE]: colors.border.active,\n [ThemeCssVariable.BORDER_DISABLED]: colors.border.disabled,\n };\n}\n\n/**\n * @description Crea variables CSS para las sombras.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction createShadowVariables(colors: AppTheme[\"themes\"]): ShadowVariables {\n return {\n [ThemeCssVariable.SHADOW_COLOR]: colors.shadowColors.color,\n [ThemeCssVariable.SHADOW_SUBTLE]: colors.shadowColors.subtle,\n [ThemeCssVariable.SHADOW_SMALL]: colors.shadowColors.small,\n [ThemeCssVariable.SHADOW_MEDIUM]: colors.shadowColors.medium,\n [ThemeCssVariable.SHADOW_LARGE]: colors.shadowColors.large,\n [ThemeCssVariable.SHADOW_GLOW]: colors.shadowColors.glow,\n };\n}\n\n/**\n * @description Crea variables CSS para los efectos visuales.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction createEffectVariables(colors: AppTheme[\"themes\"]): EffectVariables {\n return {\n [ThemeCssVariable.EFFECTS_OVERLAY]: colors.effects.overlay,\n [ThemeCssVariable.EFFECTS_BACKDROP]: colors.effects.backdrop,\n [ThemeCssVariable.EFFECTS_BLUR]: colors.effects.blur,\n [ThemeCssVariable.EFFECTS_BLUR_STRONG]: colors.effects.blurStrong,\n [ThemeCssVariable.EFFECTS_GLASS_BACKGROUND]: colors.effects.glassBackground,\n [ThemeCssVariable.EFFECTS_GLASS_BORDER]: colors.effects.glassBorder,\n };\n}\n\n/**\n * @description Crea variables CSS para la tipografia.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction createTypographyVariables(\n colors: AppTheme[\"themes\"],\n): TypographyVariables {\n return {\n [ThemeCssVariable.TYPOGRAPHY_HEADING_PRIMARY]:\n colors.typography.heading.h1.color,\n [ThemeCssVariable.TYPOGRAPHY_HEADING_SECONDARY]:\n colors.typography.heading.h2.color,\n [ThemeCssVariable.TYPOGRAPHY_HEADING_MUTED]:\n colors.typography.body.muted.color,\n [ThemeCssVariable.TYPOGRAPHY_BODY_PRIMARY]:\n colors.typography.body.primary.color,\n [ThemeCssVariable.TYPOGRAPHY_BODY_SECONDARY]:\n colors.typography.body.secondary.color,\n [ThemeCssVariable.TYPOGRAPHY_BODY_MUTED]:\n colors.typography.body.muted.color,\n [ThemeCssVariable.TYPOGRAPHY_LABEL_PRIMARY]:\n colors.typography.label.primary.color,\n [ThemeCssVariable.TYPOGRAPHY_LABEL_SECONDARY]:\n colors.typography.label.secondary.color,\n [ThemeCssVariable.TYPOGRAPHY_LABEL_MUTED]:\n colors.typography.label.muted.color,\n [ThemeCssVariable.TYPOGRAPHY_BUTTON_PRIMARY]:\n colors.typography.button.primary.color,\n [ThemeCssVariable.TYPOGRAPHY_BUTTON_SECONDARY]:\n colors.typography.button.secondary.color,\n };\n}\n\n/**\n * @description Genera todas las variables CSS a partir de los tokens del tema.\n * @author Steveen Cues\n * @version 2.0.0\n */\nexport function createThemeVariables(theme: AppTheme): ThemeCssVariables {\n const { themes: colors } = theme;\n\n return {\n ...createSurfaceVariables(colors),\n ...createTextVariables(colors),\n ...createBrandVariables(colors),\n ...createStateVariables(colors),\n ...createBorderVariables(colors),\n ...createShadowVariables(colors),\n ...createEffectVariables(colors),\n ...createTypographyVariables(colors),\n };\n}\n","/**\n * @description Obtains the cryptographic API when available.\n * @returns Cryptographic API or undefined if unavailable.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport function getCryptoApi(): Crypto | undefined {\n try {\n return globalThis.crypto;\n } catch {\n return undefined;\n }\n}\n","/**\n * @description Obtains localStorage when available.\n * @returns Browser storage or undefined if unavailable.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport function getLocalStorage(): Storage | undefined {\n try {\n return globalThis.localStorage;\n } catch {\n return undefined;\n }\n}\n","/**\n * @description Encodes text into UTF-8 bytes.\n * @param value Text to encode.\n * @returns Encoded bytes.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport function encodeText(value: string): Uint8Array<ArrayBuffer> {\n return new TextEncoder().encode(value);\n}\n\n/**\n * @description Decodes UTF-8 bytes into text.\n * @param value Encoded bytes.\n * @returns Decoded text.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport function decodeText(value: ArrayBuffer): string {\n return new TextDecoder().decode(value);\n}\n","/**\n * @description Encodes bytes into Base64.\n * @param bytes Bytes to encode.\n * @returns Base64 string.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport function encodeBase64(bytes: Uint8Array): string {\n let binary = \"\";\n\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n\n return btoa(binary);\n}\n\n/**\n * @description Decodes Base64 into bytes.\n * @param value Base64 string.\n * @returns Decoded bytes.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport function decodeBase64(value: string): Uint8Array<ArrayBuffer> {\n const binary = atob(value);\n const bytes = new Uint8Array(binary.length);\n\n for (let index = 0; index < binary.length; index += 1) {\n bytes[index] = binary.charCodeAt(index);\n }\n\n return bytes;\n}\n","import {\n AES_GCM_ALGORITHM,\n AES_GCM_IV_LENGTH,\n ENCRYPTED_VALUE_PART_COUNT,\n KEY_USAGES,\n RAW_KEY_FORMAT,\n SHA_256_ALGORITHM,\n STORAGE_VALUE_SEPARATOR,\n} from \"@domain\";\n\nimport {\n decodeBase64,\n encodeBase64,\n getCryptoApi,\n decodeText,\n encodeText,\n} from \"@aplicacion\";\n\n/**\n * @description Represents validated encrypted data.\n * @author Steveen Cues\n * @version 2.0.0\n */\ninterface EncryptedPayload {\n iv: Uint8Array<ArrayBuffer>;\n ciphertext: Uint8Array<ArrayBuffer>;\n}\n\n/**\n * @description Derives an AES-GCM key from a configured secret.\n * @param secret Encryption secret.\n * @returns Crypto key or undefined when unavailable.\n * @author Steveen Cues\n * @version 2.0.0\n */\nasync function deriveAesKey(secret: string): Promise<CryptoKey | undefined> {\n const cryptoApi = getCryptoApi();\n\n if (cryptoApi === undefined || secret.length === 0) {\n return undefined;\n }\n\n const digest = await cryptoApi.subtle.digest(\n SHA_256_ALGORITHM,\n encodeText(secret),\n );\n\n return cryptoApi.subtle.importKey(\n RAW_KEY_FORMAT,\n digest,\n { name: AES_GCM_ALGORITHM },\n false,\n KEY_USAGES,\n );\n}\n\n/**\n * @description Creates a cryptographically random initialization vector.\n * @returns Initialization vector.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction createInitializationVector(): Uint8Array<ArrayBuffer> {\n const cryptoApi = getCryptoApi();\n\n if (cryptoApi === undefined) {\n throw new Error(\"Cryptographic API is unavailable.\");\n }\n\n return cryptoApi.getRandomValues(new Uint8Array(AES_GCM_IV_LENGTH));\n}\n\n/**\n * @description Validates and decodes an initialization vector.\n * @param value Base64-encoded initialization vector.\n * @returns Valid vector or undefined.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction decodeInitializationVector(\n value: string,\n): Uint8Array<ArrayBuffer> | undefined {\n try {\n const iv = decodeBase64(value);\n\n return iv.length === AES_GCM_IV_LENGTH ? iv : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * @description Checks whether the encrypted value has the expected segments.\n * @param parts Encrypted value segments.\n * @returns Whether the segments contain an IV and ciphertext.\n * @author Steveen Cues\n * @version 2.2.0\n */\nfunction hasExpectedEncryptedParts(parts: string[]): parts is [string, string] {\n return parts.length === ENCRYPTED_VALUE_PART_COUNT;\n}\n\n/**\n * @description Validates the encrypted value segments.\n * @param parts Encrypted value segments.\n * @returns Validated segments or undefined.\n * @author Steveen Cues\n * @version 2.2.0\n */\nfunction validateEncryptedParts(parts: string[]): [string, string] | undefined {\n if (!hasExpectedEncryptedParts(parts)) {\n return undefined;\n }\n\n return [parts[0], parts[1]];\n}\n\n/**\n * @description Splits and validates an encrypted value.\n * @param value Encoded initialization vector and ciphertext.\n * @returns Validated payload or undefined.\n * @author Steveen Cues\n * @version 2.1.0\n */\nfunction parseEncryptedPayload(value: string): EncryptedPayload | undefined {\n const parts = validateEncryptedParts(value.split(STORAGE_VALUE_SEPARATOR));\n\n if (parts === undefined) {\n return undefined;\n }\n\n const [encodedIv, encodedCiphertext] = parts;\n const iv = decodeInitializationVector(encodedIv);\n\n if (iv === undefined) {\n return undefined;\n }\n\n try {\n return {\n iv,\n ciphertext: decodeBase64(encodedCiphertext),\n };\n } catch {\n return undefined;\n }\n}\n\n/**\n * @description Encrypts bytes using AES-GCM.\n * @param plaintext Plaintext bytes.\n * @param key Encryption key.\n * @param iv Initialization vector.\n * @returns Encrypted bytes.\n * @author Steveen Cues\n * @version 2.1.0\n */\nasync function encryptPayload(\n plaintext: Uint8Array<ArrayBuffer>,\n key: CryptoKey,\n iv: Uint8Array<ArrayBuffer>,\n): Promise<ArrayBuffer> {\n const cryptoApi = requireCryptoApi();\n\n return cryptoApi.subtle.encrypt(\n { name: AES_GCM_ALGORITHM, iv },\n key,\n plaintext,\n );\n}\n\n/**\n * @description Decrypts bytes using AES-GCM.\n * @param payload Validated encrypted payload.\n * @param key Decryption key.\n * @returns Decrypted bytes.\n * @author Steveen Cues\n * @version 2.1.0\n */\nasync function decryptPayload(\n payload: EncryptedPayload,\n key: CryptoKey,\n): Promise<ArrayBuffer> {\n const cryptoApi = requireCryptoApi();\n\n return cryptoApi.subtle.decrypt(\n {\n name: AES_GCM_ALGORITHM,\n iv: payload.iv,\n },\n key,\n payload.ciphertext,\n );\n}\n\n/**\n * @description Obtains the cryptographic API or throws when unavailable.\n * @returns Available cryptographic API.\n * @author Steveen Cues\n * @version 2.2.0\n */\nfunction requireCryptoApi(): Crypto {\n const cryptoApi = getCryptoApi();\n\n if (cryptoApi === undefined) {\n throw new Error(\"Cryptographic API is unavailable.\");\n }\n\n return cryptoApi;\n}\n\n/**\n * @description Encrypts text using AES-GCM.\n * @param value Text to encrypt.\n * @param secret Encryption secret.\n * @returns Encoded encrypted value or undefined when unavailable.\n * @author Steveen Cues\n * @version 2.0.0\n */\nexport async function encryptText(\n value: string,\n secret: string,\n): Promise<string | undefined> {\n try {\n const key = await deriveAesKey(secret);\n\n if (key === undefined) {\n return undefined;\n }\n\n const iv = createInitializationVector();\n const ciphertext = await encryptPayload(encodeText(value), key, iv);\n\n return [encodeBase64(iv), encodeBase64(new Uint8Array(ciphertext))].join(\n STORAGE_VALUE_SEPARATOR,\n );\n } catch {\n return undefined;\n }\n}\n\n/**\n * @description Decrypts an AES-GCM encrypted value.\n * @param value Encoded initialization vector and ciphertext.\n * @param secret Encryption secret.\n * @returns Original text or undefined if decryption fails.\n * @author Steveen Cues\n * @version 2.0.0\n */\nexport async function decryptText(\n value: string,\n secret: string,\n): Promise<string | undefined> {\n try {\n const payload = parseEncryptedPayload(value);\n\n if (payload === undefined) {\n return undefined;\n }\n\n const key = await deriveAesKey(secret);\n\n if (key === undefined) {\n return undefined;\n }\n\n const plaintext = await decryptPayload(payload, key);\n\n return decodeText(plaintext);\n } catch {\n return undefined;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["TranslateContext","createContext","ThemeContext","useLanguage","context","useContext","useTheme","saveEncryptedPreference","value","encryptionKey","storage","getLocalStorage","encryptedValue","encryptText","storageKey","loadEncryptedPreference","decryptText","LANGUAGE_PREFERENCE_STORAGE_KEY","saveLanguagePreference","language","loadLanguagePreference","savedLanguage","availableLanguages","THEME_PREFERENCE_STORAGE_KEY","saveThemePreference","themeName","loadThemePreference","savedTheme","themes","theme","createPreferenceState","configuration","matchesConfiguration","state","restoreSavedTheme","useRestoreThemePreference","isActive","defaultTheme","resolveInitialTheme","currentState","setPreferenceState","useSetThemePreference","useCallback","assertThemeExists","nextTheme","useThemePreference","inputConfiguration","useMemo","initialTheme","themeEncryptionKey","preferenceState","useState","isCurrentConfiguration","createLanguagePreferenceState","matchesLanguageConfiguration","restoreSavedLanguage","useRestoreLanguagePreference","defaultLanguage","resolveInitialLanguage","usePersistLanguagePreference","isLoaded","useSetLanguagePreference","assertLanguageExists","nextLanguage","useLanguagePreference","selectedLanguage","setLanguage","resolveActiveLanguage","TranslateProvider","languages","translations","initialLanguage","fallbackLanguage","languageEncryptionKey","preference","contextValue","useTranslationContext","currentDictionary","fallbackDictionary","t","translateMessage","key","params","ThemeProvider","resolveActiveTheme","isPreferenceLoaded","setTheme","setThemeName","themeVariables","createThemeVariables","TranslationRegex","GLOBAL_REGEX_FLAG","AES_GCM_ALGORITHM","AES_GCM_IV_LENGTH","SHA_256_ALGORITHM","RAW_KEY_FORMAT","STORAGE_VALUE_SEPARATOR","KEY_USAGES","ENCRYPTED_VALUE_PART_COUNT","ThemeCssVariable","THEME_FONT_WEIGHT","isLanguageAvailable","findFirstLanguage","firstLanguage","findTranslationValue","current","dictionary","segment","findTranslation","resolveInterpolationValue","placeholder","interpolateTranslation","placeholderRegex","message","resolveTranslationMessage","currentTranslation","findTheme","getFirstTheme","firstTheme","selectedTheme","createSurfaceVariables","colors","createTextVariables","createBrandVariables","createStateVariables","createBorderVariables","createEffectVariables","createTypographyVariables","getCryptoApi","encodeText","decodeText","encodeBase64","binary","byte","bytes","decodeBase64","index","deriveAesKey","cryptoApi","secret","digest","createInitializationVector","decodeInitializationVector","iv","hasExpectedEncryptedParts","parts","validateEncryptedParts","parseEncryptedPayload","encodedIv","encodedCiphertext","encryptPayload","requireCryptoApi","plaintext","decryptPayload","payload","ciphertext"],"sources":["../src/libs/aplicacion/contexts/translate.context.ts","../src/libs/aplicacion/contexts/theme.context.ts","../src/libs/aplicacion/hooks/use-language.ts","../src/libs/aplicacion/hooks/use-theme.ts","../src/libs/infraestructura/storage/encrypted-preference.storage.ts","../src/libs/infraestructura/storage/language-preference.storage.ts","../src/libs/infraestructura/storage/theme-preference.storage.ts","../src/libs/aplicacion/hooks/use-theme-preference.hook.ts","../src/libs/aplicacion/providers/translate.provider.tsx","../src/libs/aplicacion/providers/theme-provider.tsx","../src/libs/domain/enums/translation-regex.enum.ts","../src/libs/domain/constants/translation.constants.ts","../src/libs/domain/constants/encrypted-preference.constanst.ts","../src/libs/domain/constants/theme-css-variable.const.ts","../src/libs/domain/constants/theme-font-weight.const.ts","../src/libs/aplicacion/utils/translation.utils.ts","../src/libs/aplicacion/utils/theme.utils.ts","../src/libs/aplicacion/utils/crypto-api.util.ts","../src/libs/aplicacion/utils/storage-api.util.ts","../src/libs/aplicacion/utils/text-encoding.util.ts","../src/libs/aplicacion/utils/base64.util.ts","../src/libs/aplicacion/services/encryption.service.ts"],"sourcesContent":["import type { ILanguageContextValue } from \"@domain\";\nimport { createContext } from \"react\";\n\n/**\n * @description Contexto interno de traducciones de la libreria.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport const TranslateContext = createContext<ILanguageContextValue | null>(\n null,\n);\n","import type { IThemeContextValue } from \"@domain\";\nimport { createContext } from \"react\";\n\n/**\n * @description Contexto interno del sistema de temas.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport const ThemeContext = createContext<IThemeContextValue | null>(null);\n","import { TranslateContext } from \"@aplicacion\";\nimport type { ILanguageContextValue } from \"@domain\";\nimport { useContext } from \"react\";\n\n/**\n * @description Obtiene el idioma actual y la funcion de traduccion.\n * Requiere que el componente este dentro de TranslateProvider.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport function useLanguage(): ILanguageContextValue {\n const context = useContext(TranslateContext);\n\n if (context === null) {\n throw new Error(\"useLanguage must be used inside TranslateProvider.\");\n }\n\n return context;\n}\n","import { ThemeContext } from \"@aplicacion\";\nimport type { IThemeContextValue } from \"@domain\";\nimport { useContext } from \"react\";\n\n/**\n * @description Obtiene el tema activo, los temas disponibles y\n * la funcion para cambiar de tema.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport function useTheme(): IThemeContextValue {\n const context = useContext(ThemeContext);\n\n if (context === null) {\n throw new Error(\"useTheme must be used inside ThemeProvider.\");\n }\n\n return context;\n}\n","import { decryptText, encryptText, getLocalStorage } from \"@aplicacion\";\n\n/**\n * @description Encrypts and saves a preference in localStorage.\n * @param storageKey Storage key.\n * @param value Value to store.\n * @param encryptionKey Encryption secret.\n * @returns Promise resolved after the save attempt.\n * @author Steveen Cues\n * @version 3.0.0\n */\nexport async function saveEncryptedPreference(\n storageKey: string,\n value: string,\n encryptionKey: string,\n): Promise<void> {\n if (value.length === 0 || encryptionKey.length === 0) {\n return;\n }\n\n try {\n const storage = getLocalStorage();\n\n if (storage === undefined) {\n return;\n }\n\n const encryptedValue = await encryptText(value, encryptionKey);\n\n if (encryptedValue === undefined) {\n return;\n }\n\n storage.setItem(storageKey, encryptedValue);\n } catch {\n // Preference persistence must not interrupt application usage.\n }\n}\n\n/**\n * @description Loads and decrypts a preference from localStorage.\n * @param storageKey Storage key.\n * @param encryptionKey Encryption secret.\n * @returns Decrypted preference or undefined when unavailable.\n * @author Steveen Cues\n * @version 3.0.0\n */\nexport async function loadEncryptedPreference(\n storageKey: string,\n encryptionKey: string,\n): Promise<string | undefined> {\n if (encryptionKey.length === 0) {\n return undefined;\n }\n\n try {\n const storage = getLocalStorage();\n\n if (storage === undefined) {\n return undefined;\n }\n\n const encryptedValue = storage.getItem(storageKey);\n\n if (encryptedValue === null) {\n return undefined;\n }\n\n return await decryptText(encryptedValue, encryptionKey);\n } catch {\n return undefined;\n }\n}\n","import {\n loadEncryptedPreference,\n saveEncryptedPreference,\n} from \"./encrypted-preference.storage\";\n\nconst LANGUAGE_PREFERENCE_STORAGE_KEY =\n \"starter-react-ui:language-preference:v1\";\n\n/**\n * @description Guarda el idioma activo de forma cifrada.\n * @param language Codigo del idioma activo.\n * @param encryptionKey Clave de cifrado proporcionada por el consumidor.\n * @returns Promesa completada al finalizar el intento de guardado.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport function saveLanguagePreference(\n language: string,\n encryptionKey: string,\n): Promise<void> {\n return saveEncryptedPreference(\n LANGUAGE_PREFERENCE_STORAGE_KEY,\n language,\n encryptionKey,\n );\n}\n\n/**\n * @description Recupera el idioma guardado y verifica que siga disponible.\n * @param availableLanguages Idiomas admitidos por el proyecto.\n * @param encryptionKey Clave de cifrado proporcionada por el consumidor.\n * @returns Idioma recuperado o undefined si no existe o no es valido.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport async function loadLanguagePreference(\n availableLanguages: readonly string[],\n encryptionKey: string,\n): Promise<string | undefined> {\n const savedLanguage = await loadEncryptedPreference(\n LANGUAGE_PREFERENCE_STORAGE_KEY,\n encryptionKey,\n );\n\n if (\n savedLanguage === undefined ||\n !availableLanguages.includes(savedLanguage)\n ) {\n return undefined;\n }\n\n return savedLanguage;\n}\n","import type { AppTheme, ThemeName } from \"@domain\";\n\nimport {\n loadEncryptedPreference,\n saveEncryptedPreference,\n} from \"./encrypted-preference.storage\";\n\nconst THEME_PREFERENCE_STORAGE_KEY = \"starter-react-ui:theme-preference:v1\";\n\n/**\n * @description Guarda el nombre del tema activo de forma cifrada.\n * @param themeName Nombre del tema.\n * @param encryptionKey Clave de cifrado proporcionada por el consumidor.\n * @returns Promesa completada al finalizar el intento de guardado.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport function saveThemePreference(\n themeName: ThemeName,\n encryptionKey: string,\n): Promise<void> {\n return saveEncryptedPreference(\n THEME_PREFERENCE_STORAGE_KEY,\n themeName,\n encryptionKey,\n );\n}\n\n/**\n * @description Recupera el tema guardado si existe entre los temas admitidos.\n * @param themes Temas definidos por el proyecto consumidor.\n * @param encryptionKey Clave de cifrado proporcionada por el consumidor.\n * @returns Nombre del tema recuperado o undefined.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport async function loadThemePreference(\n themes: readonly AppTheme[],\n encryptionKey: string,\n): Promise<ThemeName | undefined> {\n const savedTheme = await loadEncryptedPreference(\n THEME_PREFERENCE_STORAGE_KEY,\n encryptionKey,\n );\n\n if (savedTheme === undefined) {\n return undefined;\n }\n\n const availableTheme = themes.find(\n (theme: AppTheme): boolean => theme.name === savedTheme,\n );\n\n return availableTheme?.name;\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\n\nimport type {\n SetThemePreferenceState,\n ThemeName,\n ThemePreferenceConfiguration,\n ThemePreferenceResult,\n ThemePreferenceState,\n} from \"@domain\";\n\nimport { loadThemePreference } from \"@infraestructura\";\n\nimport { assertThemeExists, resolveInitialTheme } from \"@aplicacion\";\n\n/**\n * @description Creates a preference state for the given configuration.\n * @author Steveen Cues\n * @version 3.0.0\n */\nfunction createPreferenceState(\n configuration: ThemePreferenceConfiguration,\n themeName: ThemeName,\n isLoaded: boolean,\n): ThemePreferenceState {\n return {\n ...configuration,\n themeName,\n isLoaded,\n };\n}\n\n/**\n * @description Checks whether a state belongs to the active configuration.\n * @author Steveen Cues\n * @version 3.0.0\n */\nfunction matchesConfiguration(\n state: ThemePreferenceState,\n configuration: ThemePreferenceConfiguration,\n): boolean {\n return (\n state.themes === configuration.themes &&\n state.initialTheme === configuration.initialTheme &&\n state.themeEncryptionKey === configuration.themeEncryptionKey\n );\n}\n\n/**\n * @description Loads the stored theme and safely handles restoration failures.\n * @author Steveen Cues\n * @version 3.0.0\n */\nasync function restoreSavedTheme(\n configuration: ThemePreferenceConfiguration,\n): Promise<ThemeName | undefined> {\n try {\n return await loadThemePreference(\n configuration.themes,\n configuration.themeEncryptionKey,\n );\n } catch {\n return undefined;\n }\n}\n\n/**\n * @description Restores the saved preference without overriding a user selection.\n * @author Steveen Cues\n * @version 3.0.0\n */\nfunction useRestoreThemePreference(\n configuration: ThemePreferenceConfiguration,\n setPreferenceState: SetThemePreferenceState,\n): void {\n useEffect((): (() => void) => {\n let isActive = true;\n\n const restorePreference = async (): Promise<void> => {\n const savedTheme = await restoreSavedTheme(configuration);\n\n if (!isActive) {\n return;\n }\n\n const defaultTheme = resolveInitialTheme(\n configuration.themes,\n configuration.initialTheme,\n );\n\n setPreferenceState(\n (currentState: ThemePreferenceState): ThemePreferenceState => {\n if (\n matchesConfiguration(currentState, configuration) &&\n currentState.isLoaded\n ) {\n return currentState;\n }\n\n return createPreferenceState(\n configuration,\n savedTheme ?? defaultTheme.name,\n true,\n );\n },\n );\n };\n\n void restorePreference();\n\n return (): void => {\n isActive = false;\n };\n }, [configuration, setPreferenceState]);\n}\n\n/**\n * @description Creates a validated theme selection handler.\n * @author Steveen Cues\n * @version 3.0.0\n */\nfunction useSetThemePreference(\n configuration: ThemePreferenceConfiguration,\n setPreferenceState: SetThemePreferenceState,\n): (nextTheme: ThemeName) => void {\n return useCallback(\n (nextTheme: ThemeName): void => {\n assertThemeExists(configuration.themes, nextTheme);\n\n setPreferenceState(createPreferenceState(configuration, nextTheme, true));\n },\n [configuration, setPreferenceState],\n );\n}\n\n/**\n * @description Manages the selected theme and its encrypted persistence lifecycle.\n * @author Steveen Cues\n * @version 3.0.0\n */\nexport function useThemePreference(\n inputConfiguration: ThemePreferenceConfiguration,\n): ThemePreferenceResult {\n const { themes, initialTheme, themeEncryptionKey } = inputConfiguration;\n\n const configuration = useMemo(\n (): ThemePreferenceConfiguration => ({\n themes,\n initialTheme,\n themeEncryptionKey,\n }),\n [themes, initialTheme, themeEncryptionKey],\n );\n\n const [preferenceState, setPreferenceState] = useState<ThemePreferenceState>(\n (): ThemePreferenceState =>\n createPreferenceState(\n configuration,\n resolveInitialTheme(themes, initialTheme).name,\n false,\n ),\n );\n\n useRestoreThemePreference(configuration, setPreferenceState);\n\n const isCurrentConfiguration = matchesConfiguration(\n preferenceState,\n configuration,\n );\n\n const themeName = isCurrentConfiguration\n ? preferenceState.themeName\n : resolveInitialTheme(themes, initialTheme).name;\n\n const isPreferenceLoaded = isCurrentConfiguration && preferenceState.isLoaded;\n\n const setThemeName = useSetThemePreference(configuration, setPreferenceState);\n\n return {\n themeName,\n isPreferenceLoaded,\n setThemeName,\n };\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\n\nimport type { JSX } from \"react\";\n\nimport type {\n ILanguageContextValue,\n ITranslateProviderProps,\n TranslationParams,\n TranslationDictionary,\n} from \"@domain\";\n\nimport { TranslateContext } from \"@aplicacion\";\n\nimport {\n loadLanguagePreference,\n saveLanguagePreference,\n} from \"@infraestructura\";\n\nimport {\n assertLanguageExists,\n resolveActiveLanguage,\n resolveInitialLanguage,\n translateMessage,\n} from \"@aplicacion\";\n\ninterface LanguagePreferenceConfiguration {\n readonly translations: ITranslateProviderProps[\"translations\"];\n readonly initialLanguage: ITranslateProviderProps[\"initialLanguage\"];\n readonly fallbackLanguage: string;\n readonly languageEncryptionKey: ITranslateProviderProps[\"languageEncryptionKey\"];\n readonly languages: readonly string[];\n}\n\ninterface LanguagePreferenceState extends LanguagePreferenceConfiguration {\n readonly selectedLanguage: string;\n readonly isLoaded: boolean;\n}\n\ninterface LanguagePreferenceResult {\n readonly language: string;\n readonly isLoaded: boolean;\n readonly setLanguage: (language: string) => void;\n}\n\ntype SetLanguagePreferenceState = React.Dispatch<\n React.SetStateAction<LanguagePreferenceState>\n>;\n\n/**\n * @description Creates the initial language preference state.\n * @author Steveen Cues\n * @version 4.0.0\n */\nfunction createLanguagePreferenceState(\n configuration: LanguagePreferenceConfiguration,\n selectedLanguage: string,\n isLoaded: boolean,\n): LanguagePreferenceState {\n return {\n ...configuration,\n selectedLanguage,\n isLoaded,\n };\n}\n\n/**\n * @description Checks whether a state matches the active configuration.\n * @author Steveen Cues\n * @version 4.0.0\n */\nfunction matchesLanguageConfiguration(\n state: LanguagePreferenceState,\n configuration: LanguagePreferenceConfiguration,\n): boolean {\n return (\n state.translations === configuration.translations &&\n state.initialLanguage === configuration.initialLanguage &&\n state.fallbackLanguage === configuration.fallbackLanguage &&\n state.languageEncryptionKey === configuration.languageEncryptionKey &&\n state.languages === configuration.languages\n );\n}\n\n/**\n * @description Restores the saved language and falls back when loading fails.\n * @author Steveen Cues\n * @version 4.0.0\n */\nasync function restoreSavedLanguage(\n configuration: LanguagePreferenceConfiguration,\n): Promise<string | undefined> {\n try {\n return await loadLanguagePreference(\n configuration.languages,\n configuration.languageEncryptionKey,\n );\n } catch {\n return undefined;\n }\n}\n\n/**\n * @description Restores the saved language for the active configuration.\n * @author Steveen Cues\n * @version 4.0.0\n */\nfunction useRestoreLanguagePreference(\n configuration: LanguagePreferenceConfiguration,\n setPreferenceState: SetLanguagePreferenceState,\n): void {\n useEffect((): (() => void) => {\n let isActive = true;\n\n const restorePreference = async (): Promise<void> => {\n const savedLanguage = await restoreSavedLanguage(configuration);\n\n if (!isActive) {\n return;\n }\n\n const defaultLanguage = resolveInitialLanguage(\n configuration.translations,\n configuration.initialLanguage,\n configuration.fallbackLanguage,\n );\n\n setPreferenceState(\n (currentState: LanguagePreferenceState): LanguagePreferenceState => {\n if (\n matchesLanguageConfiguration(currentState, configuration) &&\n currentState.isLoaded\n ) {\n return currentState;\n }\n\n return createLanguagePreferenceState(\n configuration,\n savedLanguage ?? defaultLanguage,\n true,\n );\n },\n );\n };\n\n void restorePreference();\n\n return (): void => {\n isActive = false;\n };\n }, [configuration, setPreferenceState]);\n}\n\n/**\n * @description Persists the active language after preference restoration.\n * @author Steveen Cues\n * @version 4.0.0\n */\nfunction usePersistLanguagePreference(\n configuration: LanguagePreferenceConfiguration,\n language: string,\n isLoaded: boolean,\n): void {\n useEffect((): void => {\n if (!isLoaded) {\n return;\n }\n\n void saveLanguagePreference(language, configuration.languageEncryptionKey);\n }, [configuration.languageEncryptionKey, language, isLoaded]);\n}\n\n/**\n * @description Creates a validated language selection handler.\n * @author Steveen Cues\n * @version 4.0.0\n */\nfunction useSetLanguagePreference(\n configuration: LanguagePreferenceConfiguration,\n setPreferenceState: SetLanguagePreferenceState,\n): (language: string) => void {\n return useCallback(\n (nextLanguage: string): void => {\n assertLanguageExists(configuration.translations, nextLanguage);\n\n setPreferenceState(\n createLanguagePreferenceState(configuration, nextLanguage, true),\n );\n },\n [configuration, setPreferenceState],\n );\n}\n\n/**\n * @description Manages language selection, restoration, and persistence.\n * @author Steveen Cues\n * @version 4.0.0\n */\nfunction useLanguagePreference(\n configuration: LanguagePreferenceConfiguration,\n): LanguagePreferenceResult {\n const [preferenceState, setPreferenceState] =\n useState<LanguagePreferenceState>((): LanguagePreferenceState =>\n createLanguagePreferenceState(\n configuration,\n configuration.initialLanguage,\n false,\n ),\n );\n\n useRestoreLanguagePreference(configuration, setPreferenceState);\n\n const isCurrentConfiguration = matchesLanguageConfiguration(\n preferenceState,\n configuration,\n );\n\n const selectedLanguage = isCurrentConfiguration\n ? preferenceState.selectedLanguage\n : configuration.initialLanguage;\n\n const isLoaded = isCurrentConfiguration && preferenceState.isLoaded;\n\n const setLanguage = useSetLanguagePreference(\n configuration,\n setPreferenceState,\n );\n\n return {\n language: resolveActiveLanguage(\n configuration.translations,\n selectedLanguage,\n configuration.initialLanguage,\n configuration.fallbackLanguage,\n ),\n isLoaded,\n setLanguage,\n };\n}\n\n/**\n * @description Provides the active language and translation functions.\n * @author Steveen Cues\n * @version 4.0.0\n */\nexport function TranslateProvider({\n translations,\n initialLanguage,\n fallbackLanguage = \"en\",\n languageEncryptionKey,\n children,\n}: ITranslateProviderProps): JSX.Element {\n const languages = useMemo(\n (): readonly string[] => Object.keys(translations),\n [translations],\n );\n\n const configuration = useMemo(\n (): LanguagePreferenceConfiguration => ({\n translations,\n initialLanguage,\n fallbackLanguage,\n languageEncryptionKey,\n languages,\n }),\n [\n translations,\n initialLanguage,\n fallbackLanguage,\n languageEncryptionKey,\n languages,\n ],\n );\n\n const preference = useLanguagePreference(configuration);\n\n usePersistLanguagePreference(\n configuration,\n preference.language,\n preference.isLoaded,\n );\n\n const contextValue = useTranslationContext(configuration, preference);\n\n return (\n <TranslateContext.Provider value={contextValue}>\n {children}\n </TranslateContext.Provider>\n );\n}\n\n/**\n * @description Creates the translation context value.\n * @author Steveen Cues\n * @version 4.0.0\n */\nfunction useTranslationContext(\n configuration: LanguagePreferenceConfiguration,\n preference: LanguagePreferenceResult,\n): ILanguageContextValue {\n const currentDictionary: TranslationDictionary =\n configuration.translations[preference.language];\n\n const fallbackDictionary: TranslationDictionary =\n configuration.translations[configuration.fallbackLanguage];\n\n const t = useCallback(\n (key: string, params?: TranslationParams): string =>\n translateMessage(currentDictionary, fallbackDictionary, key, params),\n [currentDictionary, fallbackDictionary],\n );\n\n return useMemo(\n (): ILanguageContextValue => ({\n language: preference.language,\n languages: configuration.languages,\n setLanguage: preference.setLanguage,\n t,\n }),\n [preference.language, preference.setLanguage, configuration.languages, t],\n );\n}\n","import { useCallback, useEffect, useMemo } from \"react\";\n\nimport type {\n IThemeContextValue,\n IThemeProviderProps,\n ThemeName,\n} from \"@domain\";\nimport type { JSX } from \"react\";\n\nimport { saveThemePreference } from \"@infraestructura\";\n\nimport {\n ThemeContext,\n createThemeVariables,\n resolveActiveTheme,\n useThemePreference,\n} from \"@aplicacion\";\n\n/**\n * @description Provides the active theme and allows theme changes.\n * Restores and persists the encrypted theme preference.\n * @author Steveen Cues\n * @version 4.0.0\n */\nexport function ThemeProvider({\n themes,\n initialTheme,\n themeEncryptionKey,\n children,\n}: IThemeProviderProps): JSX.Element {\n const { themeName, isPreferenceLoaded, setThemeName } = useThemePreference({\n themes,\n initialTheme,\n themeEncryptionKey,\n });\n\n const theme = resolveActiveTheme(themes, themeName, initialTheme);\n\n useEffect((): void => {\n if (!isPreferenceLoaded) {\n return;\n }\n\n void saveThemePreference(theme.name, themeEncryptionKey);\n }, [isPreferenceLoaded, theme.name, themeEncryptionKey]);\n\n const setTheme = useCallback(\n (nextTheme: ThemeName): void => setThemeName(nextTheme),\n [setThemeName],\n );\n\n const themeVariables = useMemo(() => createThemeVariables(theme), [theme]);\n\n const contextValue = useMemo<IThemeContextValue>(\n () => ({\n theme,\n themeName: theme.name,\n themes,\n setTheme,\n }),\n [theme, themes, setTheme],\n );\n\n return (\n <ThemeContext.Provider value={contextValue}>\n <div\n data-rui-theme={theme.name}\n style={{\n ...themeVariables,\n display: \"contents\",\n }}\n >\n {children}\n </div>\n </ThemeContext.Provider>\n );\n}\n","/**\n * @description Expresiones regulares reutilizables para traducciones.\n * @author Steveen Cues\n * @version 2.0.0\n */\nexport const TranslationRegex = Object.freeze({\n INTERPOLATION_PLACEHOLDER: String.raw`\\{\\{([a-zA-Z0-9_]+)\\}\\}`,\n});\n","export const GLOBAL_REGEX_FLAG = \"g\";\n","export const AES_GCM_ALGORITHM = \"AES-GCM\";\nexport const AES_GCM_IV_LENGTH = 12;\nexport const SHA_256_ALGORITHM = \"SHA-256\";\nexport const RAW_KEY_FORMAT = \"raw\";\nexport const STORAGE_VALUE_SEPARATOR = \".\";\nexport const KEY_USAGES: KeyUsage[] = [\"encrypt\", \"decrypt\"];\nexport const ENCRYPTED_VALUE_PART_COUNT = 2;\n","/**\n * @description Define los nombres de las variables CSS de la libreria.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport const ThemeCssVariable = {\n SURFACE_BACKGROUND: \"--rui-surface-background\",\n SURFACE_SURFACE: \"--rui-surface-surface\",\n SURFACE_SURFACE_ELEVATED: \"--rui-surface-surface-elevated\",\n SURFACE_SURFACE_HOVER: \"--rui-surface-surface-hover\",\n SURFACE_SURFACE_ACTIVE: \"--rui-surface-surface-active\",\n SURFACE_SURFACE_DISABLED: \"--rui-surface-surface-disabled\",\n\n TEXT_PRIMARY: \"--rui-text-primary\",\n TEXT_SECONDARY: \"--rui-text-secondary\",\n TEXT_MUTED: \"--rui-text-muted\",\n TEXT_DISABLED: \"--rui-text-disabled\",\n TEXT_INVERSE: \"--rui-text-inverse\",\n TEXT_LINK: \"--rui-text-link\",\n TEXT_LINK_HOVER: \"--rui-text-link-hover\",\n\n BRAND_PRIMARY: \"--rui-brand-primary\",\n BRAND_PRIMARY_HOVER: \"--rui-brand-primary-hover\",\n BRAND_PRIMARY_ACTIVE: \"--rui-brand-primary-active\",\n BRAND_PRIMARY_CONTRAST: \"--rui-brand-primary-contrast\",\n BRAND_SECONDARY: \"--rui-brand-secondary\",\n BRAND_SECONDARY_HOVER: \"--rui-brand-secondary-hover\",\n BRAND_SECONDARY_ACTIVE: \"--rui-brand-secondary-active\",\n BRAND_SECONDARY_CONTRAST: \"--rui-brand-secondary-contrast\",\n BRAND_ACCENT: \"--rui-brand-accent\",\n BRAND_ACCENT_HOVER: \"--rui-brand-accent-hover\",\n BRAND_ACCENT_CONTRAST: \"--rui-brand-accent-contrast\",\n\n STATE_SUCCESS: \"--rui-state-success\",\n STATE_SUCCESS_BACKGROUND: \"--rui-state-success-background\",\n STATE_WARNING: \"--rui-state-warning\",\n STATE_WARNING_BACKGROUND: \"--rui-state-warning-background\",\n STATE_ERROR: \"--rui-state-error\",\n STATE_ERROR_BACKGROUND: \"--rui-state-error-background\",\n STATE_INFO: \"--rui-state-info\",\n STATE_INFO_BACKGROUND: \"--rui-state-info-background\",\n\n BORDER_DEFAULT: \"--rui-border-default\",\n BORDER_SUBTLE: \"--rui-border-subtle\",\n BORDER_STRONG: \"--rui-border-strong\",\n BORDER_FOCUS: \"--rui-border-focus\",\n BORDER_HOVER: \"--rui-border-hover\",\n BORDER_ACTIVE: \"--rui-border-active\",\n BORDER_DISABLED: \"--rui-border-disabled\",\n\n SHADOW_COLOR: \"--rui-shadow-color\",\n SHADOW_SUBTLE: \"--rui-shadow-subtle\",\n SHADOW_SMALL: \"--rui-shadow-small\",\n SHADOW_MEDIUM: \"--rui-shadow-medium\",\n SHADOW_LARGE: \"--rui-shadow-large\",\n SHADOW_GLOW: \"--rui-shadow-glow\",\n\n EFFECTS_OVERLAY: \"--rui-effects-overlay\",\n EFFECTS_BACKDROP: \"--rui-effects-backdrop\",\n EFFECTS_BLUR: \"--rui-effects-blur\",\n EFFECTS_BLUR_STRONG: \"--rui-effects-blur-strong\",\n EFFECTS_GLASS_BACKGROUND: \"--rui-effects-glass-background\",\n EFFECTS_GLASS_BORDER: \"--rui-effects-glass-border\",\n\n TYPOGRAPHY_HEADING_PRIMARY: \"--rui-typography-heading-primary\",\n TYPOGRAPHY_HEADING_SECONDARY: \"--rui-typography-heading-secondary\",\n TYPOGRAPHY_HEADING_MUTED: \"--rui-typography-heading-muted\",\n TYPOGRAPHY_BODY_PRIMARY: \"--rui-typography-body-primary\",\n TYPOGRAPHY_BODY_SECONDARY: \"--rui-typography-body-secondary\",\n TYPOGRAPHY_BODY_MUTED: \"--rui-typography-body-muted\",\n TYPOGRAPHY_LABEL_PRIMARY: \"--rui-typography-label-primary\",\n TYPOGRAPHY_LABEL_SECONDARY: \"--rui-typography-label-secondary\",\n TYPOGRAPHY_LABEL_MUTED: \"--rui-typography-label-muted\",\n TYPOGRAPHY_BUTTON_PRIMARY: \"--rui-typography-button-primary\",\n TYPOGRAPHY_BUTTON_SECONDARY: \"--rui-typography-button-secondary\",\n} as const;\n","/**\n * @description Defines the standard typography weights.\n * @author Steveen Cues\n * @version 2.0.0\n */\nconst THEME_FONT_WEIGHT_THIN = 100;\nconst THEME_FONT_WEIGHT_EXTRA_LIGHT = 200;\nconst THEME_FONT_WEIGHT_LIGHT = 300;\nconst THEME_FONT_WEIGHT_REGULAR = 400;\nconst THEME_FONT_WEIGHT_MEDIUM = 500;\nconst THEME_FONT_WEIGHT_SEMI_BOLD = 600;\nconst THEME_FONT_WEIGHT_BOLD = 700;\nconst THEME_FONT_WEIGHT_EXTRA_BOLD = 800;\nconst THEME_FONT_WEIGHT_BLACK = 900;\n\n/**\n * @description Defines the available typography weights.\n * @author Steveen Cues\n * @version 2.0.0\n */\nexport const THEME_FONT_WEIGHT = {\n THIN: THEME_FONT_WEIGHT_THIN,\n EXTRA_LIGHT: THEME_FONT_WEIGHT_EXTRA_LIGHT,\n LIGHT: THEME_FONT_WEIGHT_LIGHT,\n REGULAR: THEME_FONT_WEIGHT_REGULAR,\n MEDIUM: THEME_FONT_WEIGHT_MEDIUM,\n SEMI_BOLD: THEME_FONT_WEIGHT_SEMI_BOLD,\n BOLD: THEME_FONT_WEIGHT_BOLD,\n EXTRA_BOLD: THEME_FONT_WEIGHT_EXTRA_BOLD,\n BLACK: THEME_FONT_WEIGHT_BLACK,\n} as const;\n","import {\n type TranslationCatalog,\n type TranslationDictionary,\n type TranslationParams,\n type TranslationValue,\n GLOBAL_REGEX_FLAG,\n TranslationRegex,\n} from \"@domain\";\n\n/**\n * @description Comprueba si un idioma existe en el catalogo.\n * @param translations Catalogo disponible.\n * @param language Codigo del idioma.\n * @returns Indica si el idioma esta registrado.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction isLanguageAvailable(\n translations: TranslationCatalog,\n language: string,\n): boolean {\n return Object.hasOwn(translations, language);\n}\n\n/**\n * @description Obtiene el primer idioma registrado en el catalogo.\n * @param translations Catalogo de traducciones.\n * @returns Codigo del primer idioma o undefined si esta vacio.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction findFirstLanguage(\n translations: TranslationCatalog,\n): string | undefined {\n const [firstLanguage] = Object.keys(translations);\n\n return firstLanguage;\n}\n\n/**\n * @description Obtiene el idioma inicial disponible, priorizando el\n * idioma solicitado, el idioma de respaldo y el primer idioma registrado.\n * @param translations Catalogo de traducciones.\n * @param initialLanguage Idioma solicitado inicialmente.\n * @param fallbackLanguage Idioma de respaldo.\n * @returns Codigo del idioma inicial disponible.\n * @throws Error cuando el catalogo esta vacio.\n * @author Steveen Cues\n * @version 2.0.0\n */\nexport function resolveInitialLanguage(\n translations: TranslationCatalog,\n initialLanguage: string,\n fallbackLanguage: string,\n): string {\n if (isLanguageAvailable(translations, initialLanguage)) {\n return initialLanguage;\n }\n\n if (isLanguageAvailable(translations, fallbackLanguage)) {\n return fallbackLanguage;\n }\n\n const firstLanguage = findFirstLanguage(translations);\n\n if (firstLanguage === undefined) {\n throw new Error(\n \"TranslateProvider requires at least one translation catalog.\",\n );\n }\n\n return firstLanguage;\n}\n\n/**\n * @description Resuelve el idioma seleccionado y utiliza el idioma\n * inicial, el respaldo o el primer idioma disponible si es necesario.\n * @param translations Catalogo de traducciones.\n * @param selectedLanguage Idioma seleccionado actualmente.\n * @param initialLanguage Idioma inicial configurado.\n * @param fallbackLanguage Idioma de respaldo.\n * @returns Codigo del idioma activo.\n * @author Steveen Cues\n * @version 2.0.0\n */\nexport function resolveActiveLanguage(\n translations: TranslationCatalog,\n selectedLanguage: string,\n initialLanguage: string,\n fallbackLanguage: string,\n): string {\n if (isLanguageAvailable(translations, selectedLanguage)) {\n return selectedLanguage;\n }\n\n return resolveInitialLanguage(\n translations,\n initialLanguage,\n fallbackLanguage,\n );\n}\n\n/**\n * @description Valida que un idioma este registrado en el catalogo.\n * @param translations Catalogo de traducciones.\n * @param language Codigo del idioma que se desea validar.\n * @returns No devuelve ningun valor.\n * @throws Error cuando el idioma no esta disponible.\n * @author Steveen Cues\n * @version 2.0.0\n */\nexport function assertLanguageExists(\n translations: TranslationCatalog,\n language: string,\n): void {\n if (isLanguageAvailable(translations, language)) {\n return;\n }\n\n throw new Error(\n `Language \"${language}\" is not available in the translation catalog.`,\n );\n}\n\n/**\n * @description Obtiene el valor anidado de una clave usando notacion\n * de puntos, por ejemplo \"navigation.contact\".\n * @param dictionary Diccionario donde se realiza la busqueda.\n * @param key Clave de traduccion.\n * @returns Valor encontrado o undefined si no existe.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction findTranslationValue(\n dictionary: TranslationDictionary,\n key: string,\n): TranslationValue | undefined {\n let current: TranslationValue = dictionary;\n\n for (const segment of key.split(\".\")) {\n if (typeof current === \"string\") {\n return undefined;\n }\n\n if (!Object.hasOwn(current, segment)) {\n return undefined;\n }\n\n current = current[segment];\n }\n\n return current;\n}\n\n/**\n * @description Busca una traduccion dentro de un diccionario.\n * @param dictionary Diccionario del idioma.\n * @param key Clave con notacion de puntos.\n * @returns Traduccion encontrada o undefined.\n * @author Steveen Cues\n * @version 2.0.0\n */\nexport function findTranslation(\n dictionary: TranslationDictionary | undefined,\n key: string,\n): string | undefined {\n if (dictionary === undefined || key === \"\") {\n return undefined;\n }\n\n const value = findTranslationValue(dictionary, key);\n\n return typeof value === \"string\" ? value : undefined;\n}\n\n/**\n * @description Resuelve el texto correspondiente a un marcador de\n * interpolacion sin eliminarlo cuando falta su parametro.\n * @param placeholder Marcador original, por ejemplo {{name}}.\n * @param key Nombre del parametro.\n * @param params Parametros disponibles.\n * @returns Valor interpolado o marcador original.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction resolveInterpolationValue(\n placeholder: string,\n key: string,\n params: TranslationParams | undefined,\n): string {\n const value = params?.[key];\n\n return value === undefined ? placeholder : String(value);\n}\n\n/**\n * @description Sustituye los marcadores {{name}} usando los parametros.\n * @param message Mensaje que se desea interpolar.\n * @param params Valores disponibles para la interpolacion.\n * @returns Mensaje con los parametros sustituidos.\n * @author Steveen Cues\n * @version 2.0.0\n */\nexport function interpolateTranslation(\n message: string,\n params?: TranslationParams,\n): string {\n const placeholderRegex = new RegExp(\n TranslationRegex.INTERPOLATION_PLACEHOLDER,\n GLOBAL_REGEX_FLAG,\n );\n\n return message.replace(\n placeholderRegex,\n (placeholder: string, key: string): string =>\n resolveInterpolationValue(placeholder, key, params),\n );\n}\n\n/**\n * @description Busca una traduccion en el idioma activo y utiliza el\n * idioma de respaldo cuando la clave no esta disponible.\n * @param currentDictionary Diccionario del idioma activo.\n * @param fallbackDictionary Diccionario del idioma de respaldo.\n * @param key Clave de traduccion.\n * @returns Traduccion encontrada o clave original.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction resolveTranslationMessage(\n currentDictionary: TranslationDictionary | undefined,\n fallbackDictionary: TranslationDictionary | undefined,\n key: string,\n): string {\n const currentTranslation = findTranslation(currentDictionary, key);\n\n if (currentTranslation !== undefined) {\n return currentTranslation;\n }\n\n const fallbackTranslation = findTranslation(fallbackDictionary, key);\n\n return fallbackTranslation ?? key;\n}\n\n/**\n * @description Traduce un mensaje aplicando respaldo e interpolacion.\n * @param currentDictionary Diccionario del idioma activo.\n * @param fallbackDictionary Diccionario del idioma de respaldo.\n * @param key Clave de traduccion.\n * @param params Parametros de interpolacion.\n * @returns Mensaje final traducido e interpolado.\n * @author Steveen Cues\n * @version 2.0.0\n */\nexport function translateMessage(\n currentDictionary: TranslationDictionary | undefined,\n fallbackDictionary: TranslationDictionary | undefined,\n key: string,\n params?: TranslationParams,\n): string {\n const message = resolveTranslationMessage(\n currentDictionary,\n fallbackDictionary,\n key,\n );\n\n return interpolateTranslation(message, params);\n}\n","import {\n ThemeCssVariable,\n type AppTheme,\n type BorderVariables,\n type BrandVariables,\n type EffectVariables,\n type StateVariables,\n type SurfaceVariables,\n type TextVariables,\n type ThemeCssVariables,\n type ThemeName,\n type TypographyVariables,\n} from \"@domain\";\n\n/**\n * @description Busca un tema por su nombre.\n * @author Steveen Cues\n * @version 1.0.0\n */\nfunction findTheme(\n themes: readonly AppTheme[],\n themeName: ThemeName,\n): AppTheme | undefined {\n return themes.find((theme) => theme.name === themeName);\n}\n\n/**\n * @description Obtiene el primer tema registrado.\n * @throws {Error} Cuando no hay temas registrados.\n * @author Steveen Cues\n * @version 1.0.0\n */\n/**\n * @description Obtiene el primer tema registrado.\n * @author Steveen Cues\n * @version 2.1.0\n */\n/**\n * @description Obtiene el primer tema registrado.\n * @author Steveen Cues\n * @version 2.1.0\n */\n/**\n * @description Obtiene el primer tema registrado.\n * @author Steveen Cues\n * @version 2.2.0\n */\nfunction getFirstTheme(themes: readonly AppTheme[]): AppTheme {\n const firstTheme = themes.at(0);\n\n if (firstTheme === undefined) {\n throw new Error(\"ThemeProvider requires at least one registered theme.\");\n }\n\n return firstTheme;\n}\n\n/**\n * @description Resuelve el tema inicial solicitado o utiliza el primero registrado.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport function resolveInitialTheme(\n themes: readonly AppTheme[],\n initialTheme: ThemeName,\n): AppTheme {\n return findTheme(themes, initialTheme) ?? getFirstTheme(themes);\n}\n\n/**\n * @description Resuelve el tema activo o recupera uno disponible.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport function resolveActiveTheme(\n themes: readonly AppTheme[],\n selectedTheme: ThemeName,\n initialTheme: ThemeName,\n): AppTheme {\n return (\n findTheme(themes, selectedTheme) ??\n resolveInitialTheme(themes, initialTheme)\n );\n}\n\n/**\n * @description Valida que el tema solicitado este registrado.\n * @throws {Error} Cuando el tema no esta registrado.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport function assertThemeExists(\n themes: readonly AppTheme[],\n themeName: ThemeName,\n): void {\n if (findTheme(themes, themeName) === undefined) {\n throw new Error(`Theme \"${themeName}\" is not registered in ThemeProvider.`);\n }\n}\n\n/**\n * @description Crea variables CSS para los colores de superficie.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction createSurfaceVariables(colors: AppTheme[\"themes\"]): SurfaceVariables {\n return {\n [ThemeCssVariable.SURFACE_BACKGROUND]: colors.surface.background,\n [ThemeCssVariable.SURFACE_SURFACE]: colors.surface.surface,\n [ThemeCssVariable.SURFACE_SURFACE_ELEVATED]: colors.surface.surfaceElevated,\n [ThemeCssVariable.SURFACE_SURFACE_HOVER]: colors.surface.surfaceHover,\n [ThemeCssVariable.SURFACE_SURFACE_ACTIVE]: colors.surface.surfaceActive,\n [ThemeCssVariable.SURFACE_SURFACE_DISABLED]: colors.surface.surfaceDisabled,\n };\n}\n\n/**\n * @description Crea variables CSS para los colores de texto.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction createTextVariables(colors: AppTheme[\"themes\"]): TextVariables {\n return {\n [ThemeCssVariable.TEXT_PRIMARY]: colors.text.primary,\n [ThemeCssVariable.TEXT_SECONDARY]: colors.text.secondary,\n [ThemeCssVariable.TEXT_MUTED]: colors.text.muted,\n [ThemeCssVariable.TEXT_DISABLED]: colors.text.disabled,\n [ThemeCssVariable.TEXT_INVERSE]: colors.text.inverse,\n [ThemeCssVariable.TEXT_LINK]: colors.text.link,\n [ThemeCssVariable.TEXT_LINK_HOVER]: colors.text.linkHover,\n };\n}\n\n/**\n * @description Crea variables CSS para los colores de marca.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction createBrandVariables(colors: AppTheme[\"themes\"]): BrandVariables {\n return {\n [ThemeCssVariable.BRAND_PRIMARY]: colors.brand.primary,\n [ThemeCssVariable.BRAND_PRIMARY_HOVER]: colors.brand.primaryHover,\n [ThemeCssVariable.BRAND_PRIMARY_ACTIVE]: colors.brand.primaryActive,\n [ThemeCssVariable.BRAND_PRIMARY_CONTRAST]: colors.brand.primaryContrast,\n [ThemeCssVariable.BRAND_SECONDARY]: colors.brand.secondary,\n [ThemeCssVariable.BRAND_SECONDARY_HOVER]: colors.brand.secondaryHover,\n [ThemeCssVariable.BRAND_SECONDARY_ACTIVE]: colors.brand.secondaryActive,\n [ThemeCssVariable.BRAND_SECONDARY_CONTRAST]: colors.brand.secondaryContrast,\n [ThemeCssVariable.BRAND_ACCENT]: colors.brand.accent,\n [ThemeCssVariable.BRAND_ACCENT_HOVER]: colors.brand.accentHover,\n [ThemeCssVariable.BRAND_ACCENT_CONTRAST]: colors.brand.accentContrast,\n };\n}\n\n/**\n * @description Crea variables CSS para los estados.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction createStateVariables(colors: AppTheme[\"themes\"]): StateVariables {\n return {\n [ThemeCssVariable.STATE_SUCCESS]: colors.state.success,\n [ThemeCssVariable.STATE_SUCCESS_BACKGROUND]: colors.state.successBackground,\n [ThemeCssVariable.STATE_WARNING]: colors.state.warning,\n [ThemeCssVariable.STATE_WARNING_BACKGROUND]: colors.state.warningBackground,\n [ThemeCssVariable.STATE_ERROR]: colors.state.error,\n [ThemeCssVariable.STATE_ERROR_BACKGROUND]: colors.state.errorBackground,\n [ThemeCssVariable.STATE_INFO]: colors.state.info,\n [ThemeCssVariable.STATE_INFO_BACKGROUND]: colors.state.infoBackground,\n };\n}\n\n/**\n * @description Crea variables CSS para los bordes.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction createBorderVariables(colors: AppTheme[\"themes\"]): BorderVariables {\n return {\n [ThemeCssVariable.BORDER_DEFAULT]: colors.border.default,\n [ThemeCssVariable.BORDER_SUBTLE]: colors.border.subtle,\n [ThemeCssVariable.BORDER_STRONG]: colors.border.strong,\n [ThemeCssVariable.BORDER_FOCUS]: colors.border.focus,\n [ThemeCssVariable.BORDER_HOVER]: colors.border.hover,\n [ThemeCssVariable.BORDER_ACTIVE]: colors.border.active,\n [ThemeCssVariable.BORDER_DISABLED]: colors.border.disabled,\n };\n}\n\n/**\n * @description Crea variables CSS para los efectos visuales.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction createEffectVariables(colors: AppTheme[\"themes\"]): EffectVariables {\n return {\n [ThemeCssVariable.EFFECTS_OVERLAY]: colors.effects.overlay,\n [ThemeCssVariable.EFFECTS_BACKDROP]: colors.effects.backdrop,\n [ThemeCssVariable.EFFECTS_BLUR]: colors.effects.blur,\n [ThemeCssVariable.EFFECTS_BLUR_STRONG]: colors.effects.blurStrong,\n [ThemeCssVariable.EFFECTS_GLASS_BACKGROUND]: colors.effects.glassBackground,\n [ThemeCssVariable.EFFECTS_GLASS_BORDER]: colors.effects.glassBorder,\n };\n}\n\n/**\n * @description Crea variables CSS para la tipografia.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction createTypographyVariables(\n colors: AppTheme[\"themes\"],\n): TypographyVariables {\n return {\n [ThemeCssVariable.TYPOGRAPHY_HEADING_PRIMARY]:\n colors.typography.heading.h1.color,\n [ThemeCssVariable.TYPOGRAPHY_HEADING_SECONDARY]:\n colors.typography.heading.h2.color,\n [ThemeCssVariable.TYPOGRAPHY_HEADING_MUTED]:\n colors.typography.body.muted.color,\n [ThemeCssVariable.TYPOGRAPHY_BODY_PRIMARY]:\n colors.typography.body.primary.color,\n [ThemeCssVariable.TYPOGRAPHY_BODY_SECONDARY]:\n colors.typography.body.secondary.color,\n [ThemeCssVariable.TYPOGRAPHY_BODY_MUTED]:\n colors.typography.body.muted.color,\n [ThemeCssVariable.TYPOGRAPHY_LABEL_PRIMARY]:\n colors.typography.label.primary.color,\n [ThemeCssVariable.TYPOGRAPHY_LABEL_SECONDARY]:\n colors.typography.label.secondary.color,\n [ThemeCssVariable.TYPOGRAPHY_LABEL_MUTED]:\n colors.typography.label.muted.color,\n [ThemeCssVariable.TYPOGRAPHY_BUTTON_PRIMARY]:\n colors.typography.button.primary.color,\n [ThemeCssVariable.TYPOGRAPHY_BUTTON_SECONDARY]:\n colors.typography.button.secondary.color,\n };\n}\n\n/**\n * @description Genera todas las variables CSS a partir de los tokens del tema.\n * @author Steveen Cues\n * @version 2.0.0\n */\nexport function createThemeVariables(theme: AppTheme): ThemeCssVariables {\n const { themes: colors } = theme;\n\n return {\n ...createSurfaceVariables(colors),\n ...createTextVariables(colors),\n ...createBrandVariables(colors),\n ...createStateVariables(colors),\n ...createBorderVariables(colors),\n ...createEffectVariables(colors),\n ...createTypographyVariables(colors),\n };\n}\n","/**\n * @description Obtains the cryptographic API when available.\n * @returns Cryptographic API or undefined if unavailable.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport function getCryptoApi(): Crypto | undefined {\n try {\n return globalThis.crypto;\n } catch {\n return undefined;\n }\n}\n","/**\n * @description Obtains localStorage when available.\n * @returns Browser storage or undefined if unavailable.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport function getLocalStorage(): Storage | undefined {\n try {\n return globalThis.localStorage;\n } catch {\n return undefined;\n }\n}\n","/**\n * @description Encodes text into UTF-8 bytes.\n * @param value Text to encode.\n * @returns Encoded bytes.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport function encodeText(value: string): Uint8Array<ArrayBuffer> {\n return new TextEncoder().encode(value);\n}\n\n/**\n * @description Decodes UTF-8 bytes into text.\n * @param value Encoded bytes.\n * @returns Decoded text.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport function decodeText(value: ArrayBuffer): string {\n return new TextDecoder().decode(value);\n}\n","/**\n * @description Encodes bytes into Base64.\n * @param bytes Bytes to encode.\n * @returns Base64 string.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport function encodeBase64(bytes: Uint8Array): string {\n let binary = \"\";\n\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n\n return btoa(binary);\n}\n\n/**\n * @description Decodes Base64 into bytes.\n * @param value Base64 string.\n * @returns Decoded bytes.\n * @author Steveen Cues\n * @version 1.0.0\n */\nexport function decodeBase64(value: string): Uint8Array<ArrayBuffer> {\n const binary = atob(value);\n const bytes = new Uint8Array(binary.length);\n\n for (let index = 0; index < binary.length; index += 1) {\n bytes[index] = binary.charCodeAt(index);\n }\n\n return bytes;\n}\n","import {\n AES_GCM_ALGORITHM,\n AES_GCM_IV_LENGTH,\n ENCRYPTED_VALUE_PART_COUNT,\n KEY_USAGES,\n RAW_KEY_FORMAT,\n SHA_256_ALGORITHM,\n STORAGE_VALUE_SEPARATOR,\n} from \"@domain\";\n\nimport {\n decodeBase64,\n encodeBase64,\n getCryptoApi,\n decodeText,\n encodeText,\n} from \"@aplicacion\";\n\n/**\n * @description Represents validated encrypted data.\n * @author Steveen Cues\n * @version 2.0.0\n */\ninterface EncryptedPayload {\n iv: Uint8Array<ArrayBuffer>;\n ciphertext: Uint8Array<ArrayBuffer>;\n}\n\n/**\n * @description Derives an AES-GCM key from a configured secret.\n * @param secret Encryption secret.\n * @returns Crypto key or undefined when unavailable.\n * @author Steveen Cues\n * @version 2.0.0\n */\nasync function deriveAesKey(secret: string): Promise<CryptoKey | undefined> {\n const cryptoApi = getCryptoApi();\n\n if (cryptoApi === undefined || secret.length === 0) {\n return undefined;\n }\n\n const digest = await cryptoApi.subtle.digest(\n SHA_256_ALGORITHM,\n encodeText(secret),\n );\n\n return cryptoApi.subtle.importKey(\n RAW_KEY_FORMAT,\n digest,\n { name: AES_GCM_ALGORITHM },\n false,\n KEY_USAGES,\n );\n}\n\n/**\n * @description Creates a cryptographically random initialization vector.\n * @returns Initialization vector.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction createInitializationVector(): Uint8Array<ArrayBuffer> {\n const cryptoApi = getCryptoApi();\n\n if (cryptoApi === undefined) {\n throw new Error(\"Cryptographic API is unavailable.\");\n }\n\n return cryptoApi.getRandomValues(new Uint8Array(AES_GCM_IV_LENGTH));\n}\n\n/**\n * @description Validates and decodes an initialization vector.\n * @param value Base64-encoded initialization vector.\n * @returns Valid vector or undefined.\n * @author Steveen Cues\n * @version 2.0.0\n */\nfunction decodeInitializationVector(\n value: string,\n): Uint8Array<ArrayBuffer> | undefined {\n try {\n const iv = decodeBase64(value);\n\n return iv.length === AES_GCM_IV_LENGTH ? iv : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * @description Checks whether the encrypted value has the expected segments.\n * @param parts Encrypted value segments.\n * @returns Whether the segments contain an IV and ciphertext.\n * @author Steveen Cues\n * @version 2.2.0\n */\nfunction hasExpectedEncryptedParts(parts: string[]): parts is [string, string] {\n return parts.length === ENCRYPTED_VALUE_PART_COUNT;\n}\n\n/**\n * @description Validates the encrypted value segments.\n * @param parts Encrypted value segments.\n * @returns Validated segments or undefined.\n * @author Steveen Cues\n * @version 2.2.0\n */\nfunction validateEncryptedParts(parts: string[]): [string, string] | undefined {\n if (!hasExpectedEncryptedParts(parts)) {\n return undefined;\n }\n\n return [parts[0], parts[1]];\n}\n\n/**\n * @description Splits and validates an encrypted value.\n * @param value Encoded initialization vector and ciphertext.\n * @returns Validated payload or undefined.\n * @author Steveen Cues\n * @version 2.1.0\n */\nfunction parseEncryptedPayload(value: string): EncryptedPayload | undefined {\n const parts = validateEncryptedParts(value.split(STORAGE_VALUE_SEPARATOR));\n\n if (parts === undefined) {\n return undefined;\n }\n\n const [encodedIv, encodedCiphertext] = parts;\n const iv = decodeInitializationVector(encodedIv);\n\n if (iv === undefined) {\n return undefined;\n }\n\n try {\n return {\n iv,\n ciphertext: decodeBase64(encodedCiphertext),\n };\n } catch {\n return undefined;\n }\n}\n\n/**\n * @description Encrypts bytes using AES-GCM.\n * @param plaintext Plaintext bytes.\n * @param key Encryption key.\n * @param iv Initialization vector.\n * @returns Encrypted bytes.\n * @author Steveen Cues\n * @version 2.1.0\n */\nasync function encryptPayload(\n plaintext: Uint8Array<ArrayBuffer>,\n key: CryptoKey,\n iv: Uint8Array<ArrayBuffer>,\n): Promise<ArrayBuffer> {\n const cryptoApi = requireCryptoApi();\n\n return cryptoApi.subtle.encrypt(\n { name: AES_GCM_ALGORITHM, iv },\n key,\n plaintext,\n );\n}\n\n/**\n * @description Decrypts bytes using AES-GCM.\n * @param payload Validated encrypted payload.\n * @param key Decryption key.\n * @returns Decrypted bytes.\n * @author Steveen Cues\n * @version 2.1.0\n */\nasync function decryptPayload(\n payload: EncryptedPayload,\n key: CryptoKey,\n): Promise<ArrayBuffer> {\n const cryptoApi = requireCryptoApi();\n\n return cryptoApi.subtle.decrypt(\n {\n name: AES_GCM_ALGORITHM,\n iv: payload.iv,\n },\n key,\n payload.ciphertext,\n );\n}\n\n/**\n * @description Obtains the cryptographic API or throws when unavailable.\n * @returns Available cryptographic API.\n * @author Steveen Cues\n * @version 2.2.0\n */\nfunction requireCryptoApi(): Crypto {\n const cryptoApi = getCryptoApi();\n\n if (cryptoApi === undefined) {\n throw new Error(\"Cryptographic API is unavailable.\");\n }\n\n return cryptoApi;\n}\n\n/**\n * @description Encrypts text using AES-GCM.\n * @param value Text to encrypt.\n * @param secret Encryption secret.\n * @returns Encoded encrypted value or undefined when unavailable.\n * @author Steveen Cues\n * @version 2.0.0\n */\nexport async function encryptText(\n value: string,\n secret: string,\n): Promise<string | undefined> {\n try {\n const key = await deriveAesKey(secret);\n\n if (key === undefined) {\n return undefined;\n }\n\n const iv = createInitializationVector();\n const ciphertext = await encryptPayload(encodeText(value), key, iv);\n\n return [encodeBase64(iv), encodeBase64(new Uint8Array(ciphertext))].join(\n STORAGE_VALUE_SEPARATOR,\n );\n } catch {\n return undefined;\n }\n}\n\n/**\n * @description Decrypts an AES-GCM encrypted value.\n * @param value Encoded initialization vector and ciphertext.\n * @param secret Encryption secret.\n * @returns Original text or undefined if decryption fails.\n * @author Steveen Cues\n * @version 2.0.0\n */\nexport async function decryptText(\n value: string,\n secret: string,\n): Promise<string | undefined> {\n try {\n const payload = parseEncryptedPayload(value);\n\n if (payload === undefined) {\n return undefined;\n }\n\n const key = await deriveAesKey(secret);\n\n if (key === undefined) {\n return undefined;\n }\n\n const plaintext = await decryptPayload(payload, key);\n\n return decodeText(plaintext);\n } catch {\n return undefined;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1,23 @@
|
|
|
1
|
-
|
|
1
|
+
import { FC, ButtonHTMLAttributes } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* @description Variantes visuales del boton.
|
|
4
|
+
* @author Steveen Cues
|
|
5
|
+
* @version 1.0.0
|
|
6
|
+
*/
|
|
7
|
+
export type ButtonVariant = "solid" | "outline" | "ghost";
|
|
8
|
+
/**
|
|
9
|
+
* @description Propiedades del componente Button.
|
|
10
|
+
* @author Steveen Cues
|
|
11
|
+
* @version 1.0.0
|
|
12
|
+
*/
|
|
13
|
+
export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
14
|
+
readonly titulo: string;
|
|
15
|
+
readonly variant?: ButtonVariant;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* @description Renderiza un boton accesible adaptado al tema activo.
|
|
19
|
+
* @author Steveen Cues
|
|
20
|
+
* @version 1.0.0
|
|
21
|
+
*/
|
|
22
|
+
declare const Button: FC<ButtonProps>;
|
|
23
|
+
export default Button;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export * from './Button';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export * from './Button';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ThemeBrandColors, ThemeBorderColors, ThemeColorPalette, ThemeDataColors, ThemeOverlayColors, ThemeStateColors, ThemeSurfaceColors, ThemeTextColors, ThemeAccessibility,
|
|
1
|
+
import { ThemeBrandColors, ThemeBorderColors, ThemeColorPalette, ThemeDataColors, ThemeOverlayColors, ThemeStateColors, ThemeSurfaceColors, ThemeTextColors, ThemeAccessibility, ThemeEffects, ThemeGradients, ThemeTypography } from '../../..';
|
|
2
2
|
/**
|
|
3
|
-
* @description Define
|
|
3
|
+
* @description Define los tokens visuales que dependen del tema activo.
|
|
4
4
|
* @author Steveen Cues
|
|
5
|
-
* @version 2.
|
|
5
|
+
* @version 2.1.0
|
|
6
6
|
*/
|
|
7
7
|
export interface Theme {
|
|
8
8
|
readonly palette: ThemeColorPalette;
|
|
@@ -15,12 +15,6 @@ export interface Theme {
|
|
|
15
15
|
readonly data: ThemeDataColors;
|
|
16
16
|
readonly typography: ThemeTypography;
|
|
17
17
|
readonly gradients: ThemeGradients;
|
|
18
|
-
readonly shadows: ThemeShadows;
|
|
19
|
-
readonly shadowColors: ThemeShadowColors;
|
|
20
18
|
readonly effects: ThemeEffects;
|
|
21
|
-
readonly transitions: ThemeTransitions;
|
|
22
|
-
readonly animations: ThemeAnimations;
|
|
23
|
-
readonly layout: ThemeLayout;
|
|
24
|
-
readonly components: ThemeComponents;
|
|
25
19
|
readonly accessibility: ThemeAccessibility;
|
|
26
20
|
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
export * from './theme-animation.interface';
|
|
2
|
-
export * from './theme-animations.interface';
|
|
3
2
|
export * from './theme-effects.interface';
|
|
4
3
|
export * from './theme-gradient-stop.interface';
|
|
5
4
|
export * from './theme-gradient.interface';
|
|
6
5
|
export * from './theme-gradients.interface';
|
|
7
|
-
export * from './theme-transitions.interface';
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export * from './theme-button.interface';
|
|
2
|
-
export * from './theme-card.interface';
|
|
3
|
-
export * from './theme-components.interface';
|
|
4
|
-
export * from './theme-input.interface';
|
|
5
|
-
export * from './theme-interactive-colors.interface';
|
|
6
|
-
export * from './theme-modal.interface';
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { ThemeFontWeight, ThemeInteractiveColors } from '../../..';
|
|
2
|
-
/**
|
|
3
|
-
* @description Define los tokens de un boton.
|
|
4
|
-
* @author Steveen Cues
|
|
5
|
-
* @version 2.0.0
|
|
6
|
-
*/
|
|
7
|
-
export interface ThemeButton {
|
|
8
|
-
readonly primary: ThemeInteractiveColors;
|
|
9
|
-
readonly secondary: ThemeInteractiveColors;
|
|
10
|
-
readonly outline: ThemeInteractiveColors;
|
|
11
|
-
readonly ghost: ThemeInteractiveColors;
|
|
12
|
-
readonly danger: ThemeInteractiveColors;
|
|
13
|
-
readonly radius: string;
|
|
14
|
-
readonly fontWeight: ThemeFontWeight;
|
|
15
|
-
readonly height: string;
|
|
16
|
-
readonly paddingInline: string;
|
|
17
|
-
readonly transition: string;
|
|
18
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @description Define los tokens de una tarjeta.
|
|
3
|
-
* @author Steveen Cues
|
|
4
|
-
* @version 2.0.0
|
|
5
|
-
*/
|
|
6
|
-
export interface ThemeCard {
|
|
7
|
-
readonly background: string;
|
|
8
|
-
readonly foreground: string;
|
|
9
|
-
readonly border: string;
|
|
10
|
-
readonly radius: string;
|
|
11
|
-
readonly shadow: string;
|
|
12
|
-
readonly padding: string;
|
|
13
|
-
readonly hoverTransform: string;
|
|
14
|
-
readonly transition: string;
|
|
15
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { ThemeButton, ThemeCard, ThemeInput, ThemeModal } from '../../..';
|
|
2
|
-
/**
|
|
3
|
-
* @description Define las propiedades visuales de los componentes.
|
|
4
|
-
* @author Steveen Cues
|
|
5
|
-
* @version 2.0.0
|
|
6
|
-
*/
|
|
7
|
-
export interface ThemeComponents {
|
|
8
|
-
readonly button: ThemeButton;
|
|
9
|
-
readonly input: ThemeInput;
|
|
10
|
-
readonly card: ThemeCard;
|
|
11
|
-
readonly modal: ThemeModal;
|
|
12
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @description Define los tokens de un campo de entrada.
|
|
3
|
-
* @author Steveen Cues
|
|
4
|
-
* @version 2.0.0
|
|
5
|
-
*/
|
|
6
|
-
export interface ThemeInput {
|
|
7
|
-
readonly background: string;
|
|
8
|
-
readonly foreground: string;
|
|
9
|
-
readonly placeholder: string;
|
|
10
|
-
readonly border: string;
|
|
11
|
-
readonly borderHover: string;
|
|
12
|
-
readonly borderFocus: string;
|
|
13
|
-
readonly borderError: string;
|
|
14
|
-
readonly radius: string;
|
|
15
|
-
readonly height: string;
|
|
16
|
-
readonly paddingInline: string;
|
|
17
|
-
readonly shadowFocus: string;
|
|
18
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @description Define los colores de los componentes interactivos.
|
|
3
|
-
* @author Steveen Cues
|
|
4
|
-
* @version 2.0.0
|
|
5
|
-
*/
|
|
6
|
-
export interface ThemeInteractiveColors {
|
|
7
|
-
readonly background: string;
|
|
8
|
-
readonly backgroundHover: string;
|
|
9
|
-
readonly backgroundActive: string;
|
|
10
|
-
readonly backgroundDisabled: string;
|
|
11
|
-
readonly foreground: string;
|
|
12
|
-
readonly foregroundHover: string;
|
|
13
|
-
readonly border: string;
|
|
14
|
-
readonly borderHover: string;
|
|
15
|
-
readonly borderFocus: string;
|
|
16
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @description Define los tokens de un modal.
|
|
3
|
-
* @author Steveen Cues
|
|
4
|
-
* @version 2.0.0
|
|
5
|
-
*/
|
|
6
|
-
export interface ThemeModal {
|
|
7
|
-
readonly background: string;
|
|
8
|
-
readonly foreground: string;
|
|
9
|
-
readonly border: string;
|
|
10
|
-
readonly radius: string;
|
|
11
|
-
readonly shadow: string;
|
|
12
|
-
readonly backdrop: string;
|
|
13
|
-
readonly maxWidth: string;
|
|
14
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { ThemeAnimation } from '../../..';
|
|
2
|
-
/**
|
|
3
|
-
* @description Define las animaciones disponibles.
|
|
4
|
-
* @author Steveen Cues
|
|
5
|
-
* @version 2.0.0
|
|
6
|
-
*/
|
|
7
|
-
export interface ThemeAnimations {
|
|
8
|
-
readonly fadeIn: ThemeAnimation;
|
|
9
|
-
readonly fadeOut: ThemeAnimation;
|
|
10
|
-
readonly slideIn: ThemeAnimation;
|
|
11
|
-
readonly slideOut: ThemeAnimation;
|
|
12
|
-
readonly scaleIn: ThemeAnimation;
|
|
13
|
-
readonly scaleOut: ThemeAnimation;
|
|
14
|
-
readonly pulse: ThemeAnimation;
|
|
15
|
-
readonly shimmer: ThemeAnimation;
|
|
16
|
-
readonly gradient: ThemeAnimation;
|
|
17
|
-
readonly glow: ThemeAnimation;
|
|
18
|
-
readonly float: ThemeAnimation;
|
|
19
|
-
readonly spin: ThemeAnimation;
|
|
20
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @description Define las duraciones y curvas de las transiciones.
|
|
3
|
-
* @author Steveen Cues
|
|
4
|
-
* @version 2.0.0
|
|
5
|
-
*/
|
|
6
|
-
export interface ThemeTransitions {
|
|
7
|
-
readonly instant: string;
|
|
8
|
-
readonly fast: string;
|
|
9
|
-
readonly normal: string;
|
|
10
|
-
readonly slow: string;
|
|
11
|
-
readonly easing: {
|
|
12
|
-
readonly standard: string;
|
|
13
|
-
readonly emphasized: string;
|
|
14
|
-
readonly decelerate: string;
|
|
15
|
-
readonly accelerate: string;
|
|
16
|
-
readonly spring: string;
|
|
17
|
-
};
|
|
18
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export * from './theme-breakpoints.interface';
|
|
2
|
-
export * from './theme-dimensions.interface';
|
|
3
|
-
export * from './theme-layout.interface';
|
|
4
|
-
export * from './theme-radii.interface';
|
|
5
|
-
export * from './theme-shadow-colors.interface';
|
|
6
|
-
export * from './theme-shadows.interface';
|
|
7
|
-
export * from './theme-spacing.interface';
|
|
8
|
-
export * from './theme-z-index.interface';
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @description Define los puntos de parada para el diseno adaptable.
|
|
3
|
-
* @author Steveen Cues
|
|
4
|
-
* @version 2.0.0
|
|
5
|
-
*/
|
|
6
|
-
export interface ThemeBreakpoints {
|
|
7
|
-
readonly xs: string;
|
|
8
|
-
readonly sm: string;
|
|
9
|
-
readonly md: string;
|
|
10
|
-
readonly lg: string;
|
|
11
|
-
readonly xl: string;
|
|
12
|
-
readonly "2xl": string;
|
|
13
|
-
}
|