{
  "version": 3,
  "sources": ["../../src/translations/translations.ts"],
  "sourcesContent": ["import { LANGUAGES } from './languages'\n\n/** @public */\nexport { LANGUAGES }\n\n/**\n * A language definition object representing a supported localization in tldraw.\n *\n * Derived from the LANGUAGES array, this type represents a single language entry\n * containing a locale identifier and human-readable label. The locale follows\n * BCP 47 standards (e.g., 'en', 'fr', 'zh-CN') and the label is in the native language.\n *\n * @example\n * ```ts\n * import { TLLanguage } from '@tldraw/tlschema'\n *\n * // Using TLLanguage type\n * const currentLanguage: TLLanguage = { locale: 'fr', label: 'Fran\u00E7ais' }\n *\n * // Access locale and label\n * console.log(currentLanguage.locale) // \"fr\"\n * console.log(currentLanguage.label)  // \"Fran\u00E7ais\"\n * ```\n *\n * @public\n */\nexport type TLLanguage = (typeof LANGUAGES)[number]\n\n/**\n * Gets the default translation locale based on the user's browser language preferences.\n *\n * This function determines the best matching locale from the user's browser language\n * settings, falling back to English if no suitable match is found. It works in both\n * browser and server-side environments, defaulting to English on the server.\n *\n * The function prioritizes exact matches first, then falls back to language-only\n * matches, and finally uses predefined regional defaults for languages like Chinese,\n * Portuguese, Korean, and Hindi.\n *\n * @returns The locale identifier (e.g., 'en', 'fr', 'zh-cn') that best matches the user's preferences\n *\n * @example\n * ```ts\n * import { getDefaultTranslationLocale } from '@tldraw/tlschema'\n *\n * // Get the user's preferred locale\n * const locale = getDefaultTranslationLocale()\n * console.log(locale) // e.g., \"fr\" or \"en\" or \"zh-cn\"\n *\n * // Use in localization setup\n * const i18n = new I18n({\n *   locale,\n *   // ... other config\n * })\n * ```\n *\n * @example\n * ```ts\n * // Browser with languages: ['fr-CA', 'en-US']\n * const locale = getDefaultTranslationLocale()\n * console.log(locale) // \"fr\" (if French is supported)\n *\n * // Browser with languages: ['zh']\n * const locale = getDefaultTranslationLocale()\n * console.log(locale) // \"zh-cn\" (default region for Chinese)\n * ```\n *\n * @public\n */\nexport function getDefaultTranslationLocale(): TLLanguage['locale'] {\n\tconst locales =\n\t\ttypeof window !== 'undefined' && window.navigator\n\t\t\t? (window.navigator.languages ?? ['en'])\n\t\t\t: ['en']\n\treturn _getDefaultTranslationLocale(locales)\n}\n\n/**\n * Internal function that determines the default translation locale from a list of locale preferences.\n *\n * This function is the core logic for locale resolution, separated from browser-specific code\n * for easier testing and reuse. It iterates through the provided locales in priority order\n * and returns the first supported locale found, or 'en' as the ultimate fallback.\n *\n * @param locales - Array of locale identifiers in preference order (e.g., from navigator.languages)\n * @returns The best matching supported locale identifier\n *\n * @example\n * ```ts\n *\n * // Test locale resolution\n * const locale = _getDefaultTranslationLocale(['fr-CA', 'en-US', 'es'])\n * console.log(locale) // \"fr\" (if French is supported)\n *\n * // No supported locales\n * const fallback = _getDefaultTranslationLocale(['xx-YY', 'zz-AA'])\n * console.log(fallback) // \"en\"\n * ```\n *\n * @internal\n */\nexport function _getDefaultTranslationLocale(locales: readonly string[]): TLLanguage['locale'] {\n\tfor (const locale of locales) {\n\t\tconst supportedLocale = getSupportedLocale(locale)\n\t\tif (supportedLocale) {\n\t\t\treturn supportedLocale\n\t\t}\n\t}\n\treturn 'en'\n}\n\n/**\n * Default regional variants for languages that have multiple regional versions.\n *\n * When a user's locale contains only a language code (e.g., 'zh', 'pt') but tldraw\n * only supports region-specific variants, this mapping determines which regional\n * variant to use as the default. This ensures users get the most appropriate\n * localization even when their preference doesn't specify a region.\n *\n *\n * @example\n * ```ts\n * // User has locale preference \"zh\" but we only support \"zh-cn\" and \"zh-tw\"\n * const defaultRegion = DEFAULT_LOCALE_REGIONS['zh']\n * console.log(defaultRegion) // \"zh-cn\"\n *\n * // User has locale preference \"pt\" but we support \"pt-br\" and \"pt-pt\"\n * const defaultRegion = DEFAULT_LOCALE_REGIONS['pt']\n * console.log(defaultRegion) // \"pt-br\"\n * ```\n *\n * @public\n */\nconst DEFAULT_LOCALE_REGIONS: { [locale: string]: TLLanguage['locale'] } = {\n\tzh: 'zh-cn',\n\tpt: 'pt-br',\n\tko: 'ko-kr',\n\thi: 'hi-in',\n}\n\n/**\n * Finds a supported locale that matches the given locale identifier.\n *\n * This function implements a flexible locale matching algorithm that tries multiple\n * strategies to find the best available translation:\n *\n * 1. **Exact match**: Looks for an exact locale match (case-insensitive)\n * 2. **Language-only match**: If the input has a region, tries matching just the language\n * 3. **Default region**: If the input lacks a region, uses the default region for that language\n * 4. **No match**: Returns null if no suitable locale is found\n *\n * @param locale - The locale identifier to match (e.g., 'fr-CA', 'pt', 'zh-TW')\n * @returns The matching supported locale identifier, or null if no match is found\n *\n * @example\n * ```ts\n * // Exact matches\n * getSupportedLocale('fr') // \"fr\" (if supported)\n * getSupportedLocale('PT-BR') // \"pt-br\" (case insensitive)\n *\n * // Language-only fallback\n * getSupportedLocale('fr-CA') // \"fr\" (if we only support generic French)\n *\n * // Default region assignment\n * getSupportedLocale('zh') // \"zh-cn\" (default Chinese region)\n *\n * // No match\n * getSupportedLocale('xyz') // null\n * ```\n *\n * @example\n * ```ts\n * // Usage in locale resolution\n * const userLocales = ['es-MX', 'en-US']\n * for (const userLocale of userLocales) {\n *   const supported = getSupportedLocale(userLocale)\n *   if (supported) {\n *     console.log(`Using locale: ${supported}`)\n *     break\n *   }\n * }\n * ```\n *\n * @public\n */\nfunction getSupportedLocale(locale: string): TLLanguage['locale'] | null {\n\t// If we have an exact match, return it!\n\t// (e.g. if the user has 'fr' and we have 'fr')\n\t// (or if the user has 'pt-BR' and we have 'pt-br')\n\tconst exactMatch = LANGUAGES.find((t) => t.locale === locale.toLowerCase())\n\tif (exactMatch) {\n\t\treturn exactMatch.locale\n\t}\n\n\t// Otherwise, we need to be more flexible...\n\tconst [language, region] = locale.split(/[-_]/).map((s) => s.toLowerCase())\n\n\t// If the user's language has a region...\n\t// let's try to find non-region-specific locale for them\n\t// (e.g. if they have 'fr-CA' but we only have 'fr')\n\tif (region) {\n\t\tconst languageMatch = LANGUAGES.find((t) => t.locale === language)\n\t\tif (languageMatch) {\n\t\t\treturn languageMatch.locale\n\t\t}\n\t}\n\n\t// If the user's language doesn't have a region...\n\t// let's try to find a region-specific locale for them\n\t// (e.g. if they have 'pt' but we only have 'pt-pt' or 'pt-br')\n\t//\n\t// In this case, we choose the hard-coded default region for that language\n\tif (language in DEFAULT_LOCALE_REGIONS) {\n\t\treturn DEFAULT_LOCALE_REGIONS[language]\n\t}\n\n\t// Oh no! We don't have a translation for this language!\n\t// Let's give up...\n\treturn null\n}\n"],
  "mappings": "AAAA,SAAS,iBAAiB;AAqEnB,SAAS,8BAAoD;AACnE,QAAM,UACL,OAAO,WAAW,eAAe,OAAO,YACpC,OAAO,UAAU,aAAa,CAAC,IAAI,IACpC,CAAC,IAAI;AACT,SAAO,6BAA6B,OAAO;AAC5C;AA0BO,SAAS,6BAA6B,SAAkD;AAC9F,aAAW,UAAU,SAAS;AAC7B,UAAM,kBAAkB,mBAAmB,MAAM;AACjD,QAAI,iBAAiB;AACpB,aAAO;AAAA,IACR;AAAA,EACD;AACA,SAAO;AACR;AAwBA,MAAM,yBAAqE;AAAA,EAC1E,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACL;AA+CA,SAAS,mBAAmB,QAA6C;AAIxE,QAAM,aAAa,UAAU,KAAK,CAAC,MAAM,EAAE,WAAW,OAAO,YAAY,CAAC;AAC1E,MAAI,YAAY;AACf,WAAO,WAAW;AAAA,EACnB;AAGA,QAAM,CAAC,UAAU,MAAM,IAAI,OAAO,MAAM,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC;AAK1E,MAAI,QAAQ;AACX,UAAM,gBAAgB,UAAU,KAAK,CAAC,MAAM,EAAE,WAAW,QAAQ;AACjE,QAAI,eAAe;AAClB,aAAO,cAAc;AAAA,IACtB;AAAA,EACD;AAOA,MAAI,YAAY,wBAAwB;AACvC,WAAO,uBAAuB,QAAQ;AAAA,EACvC;AAIA,SAAO;AACR;",
  "names": []
}
