{"version":3,"file":"i18n.cjs","names":["createContext","resolveLocale","matchLocale","useContext","useMemo","useSyncExternalStore","setupI18n","serializeLocaleCookie","useCallback","I18nProvider","useLingui"],"sources":["../../src/ui/i18n.tsx"],"sourcesContent":["import { type Messages, setupI18n } from \"@lingui/core\";\nimport { I18nProvider, useLingui } from \"@lingui/react\";\nimport {\n  createContext,\n  type ReactNode,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useSyncExternalStore,\n} from \"react\";\nimport { matchLocale, resolveLocale, serializeLocaleCookie } from \"./locale\";\n\nexport { Trans } from \"@lingui/react\";\nexport type { LocaleOptions } from \"./locale\";\nexport {\n  matchLocale,\n  readAcceptLanguage,\n  readLocaleCookie,\n  resolveLocale,\n  serializeLocaleCookie,\n} from \"./locale\";\nexport { createMessageCatalogs } from \"./message-catalogs\";\n\ntype SharedLocaleState = {\n  cookieName: string;\n  locale: string;\n  selectLocale: (locale: string) => Promise<void>;\n};\n\nconst SharedLocaleContext = createContext<SharedLocaleState | null>(null);\n\ntype LocaleStore = {\n  get: () => string;\n  set: (locale: string) => void;\n  subscribe: (listener: () => void) => () => void;\n};\n\nconst browserStores = new Map<string, LocaleStore>();\n\nfunction createLocaleStore(initialLocale: string): LocaleStore {\n  let locale = initialLocale;\n  const listeners = new Set<() => void>();\n  return {\n    get: () => locale,\n    set: (nextLocale) => {\n      if (nextLocale === locale) return;\n      locale = nextLocale;\n      for (const listener of listeners) listener();\n    },\n    subscribe: (listener) => {\n      listeners.add(listener);\n      return () => listeners.delete(listener);\n    },\n  };\n}\n\nexport function createLocaleRuntime<const Locale extends string>({\n  locales,\n  defaultLocale,\n  cookieName,\n}: {\n  locales: readonly Locale[];\n  defaultLocale: Locale;\n  cookieName: string;\n}) {\n  type ContextValue = {\n    locale: Locale;\n    selectLocale: (locale: Locale) => Promise<void>;\n  };\n\n  const LocaleContext = createContext<ContextValue | null>(null);\n\n  const getBrowserLocales = (): readonly string[] => {\n    if (typeof navigator === \"undefined\") return [];\n    if (Array.isArray(navigator.languages)) return navigator.languages;\n    return navigator.language ? [navigator.language] : [];\n  };\n\n  const detectLocale = (preferredLocale?: string | null): Locale =>\n    resolveLocale({\n      preferredLocale,\n      cookie: typeof document === \"undefined\" ? \"\" : document.cookie,\n      browserLocales: getBrowserLocales(),\n      locales,\n      defaultLocale,\n      cookieName,\n    });\n\n  const getStore = (initialLocale?: string | null) => {\n    const initial = matchLocale(initialLocale, locales) ?? detectLocale();\n    if (typeof window === \"undefined\") return createLocaleStore(initial);\n    const existing = browserStores.get(cookieName);\n    if (existing) return existing;\n    const store = createLocaleStore(initial);\n    browserStores.set(cookieName, store);\n    return store;\n  };\n\n  function LocaleProvider({\n    children,\n    messages,\n    initialLocale,\n    preferredLocale,\n    onLocaleChange,\n  }: {\n    children: ReactNode;\n    messages: (locale: Locale) => Messages;\n    initialLocale?: string | null;\n    preferredLocale?: string | null;\n    onLocaleChange?: (locale: Locale) => void | Promise<void>;\n  }) {\n    const parent = useContext(SharedLocaleContext);\n    const sharedParent = parent?.cookieName === cookieName ? parent : null;\n    const resolvedInitial =\n      matchLocale(preferredLocale, locales) ??\n      matchLocale(initialLocale, locales) ??\n      matchLocale(sharedParent?.locale, locales);\n    const serverLocale = resolvedInitial ?? defaultLocale;\n    const store = useMemo(() => getStore(resolvedInitial), []);\n    const locale = useSyncExternalStore(store.subscribe, store.get, () => serverLocale) as Locale;\n    const i18n = useMemo(\n      () => setupI18n({ locale, messages: { [locale]: messages(locale) } }),\n      [locale, messages],\n    );\n\n    useEffect(() => {\n      if (sharedParent) return;\n      const resolved = matchLocale(preferredLocale, locales);\n      if (resolved) {\n        Reflect.set(\n          document,\n          \"cookie\",\n          serializeLocaleCookie(cookieName, resolved, window.location.protocol === \"https:\"),\n        );\n        store.set(resolved);\n      }\n    }, [preferredLocale, sharedParent, store]);\n\n    useEffect(() => {\n      if (sharedParent) return;\n      const previousLocale = document.documentElement.lang;\n      document.documentElement.lang = locale;\n      return () => {\n        document.documentElement.lang = previousLocale;\n      };\n    }, [locale, sharedParent]);\n\n    const selectLocale = useCallback(\n      async (nextLocale: Locale) => {\n        if (!locales.includes(nextLocale)) return;\n        if (sharedParent && !onLocaleChange) {\n          await sharedParent.selectLocale(nextLocale);\n          return;\n        }\n        if (onLocaleChange) await onLocaleChange(nextLocale);\n        if (typeof document !== \"undefined\") {\n          Reflect.set(\n            document,\n            \"cookie\",\n            serializeLocaleCookie(\n              cookieName,\n              nextLocale,\n              typeof window !== \"undefined\" && window.location.protocol === \"https:\",\n            ),\n          );\n        }\n        store.set(nextLocale);\n      },\n      [onLocaleChange, sharedParent, store],\n    );\n\n    const value = useMemo(() => ({ locale, selectLocale }), [locale, selectLocale]);\n    const sharedValue = useMemo(\n      () => ({\n        cookieName,\n        locale,\n        selectLocale: async (next: string) => {\n          const matched = matchLocale(next, locales);\n          if (matched) await selectLocale(matched);\n        },\n      }),\n      [locale, selectLocale],\n    );\n    return (\n      <SharedLocaleContext.Provider value={sharedValue}>\n        <LocaleContext.Provider value={value}>\n          <I18nProvider i18n={i18n}>{children}</I18nProvider>\n        </LocaleContext.Provider>\n      </SharedLocaleContext.Provider>\n    );\n  }\n\n  function useLocale(): ContextValue {\n    const value = useContext(LocaleContext);\n    if (!value) throw new Error(\"useLocale must be used within LocaleProvider\");\n    return value;\n  }\n\n  function useTranslation<MessageId extends string>() {\n    const { _ } = useLingui();\n    return useCallback(\n      (id: MessageId, values?: Record<string, string | number>) => _(id, values),\n      [_],\n    );\n  }\n\n  const getLocale = (): Locale =>\n    matchLocale(browserStores.get(cookieName)?.get(), locales) ?? detectLocale();\n\n  return { LocaleProvider, useLocale, useTranslation, detectLocale, getLocale };\n}\n"],"mappings":"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"}