{"version":3,"sources":["../src/utils/languages.ts","../src/utils/formatting.ts","../src/utils/plurals.ts"],"sourcesContent":["// FILE: packages/sdk/src/utils/languages.ts\r\n//\r\n// This file is a KEY DIFFERENTIATOR of BhashaJS.\r\n//\r\n// Other i18n libraries like i18next treat every language the same —\r\n// they just swap strings. They don't know that Urdu is right-to-left,\r\n// that Hindi needs a specific font to render conjuncts properly, or\r\n// that Nepali should fall back to Hindi before falling back to English.\r\n//\r\n// BhashaJS ships with this knowledge built in. When a developer adds\r\n// Urdu support, we automatically handle RTL. When they add Bengali,\r\n// we know which font to load and which numbering system to use.\r\n//\r\n// This is what makes us purpose-built for South Asian languages.\r\n\r\nimport { LangInfo } from \"../types\";\r\n\r\n/**\r\n * Built-in language database — 14 entries covering 13 languages.\r\n * (Punjabi has two entries: Gurmukhi for India, Shahmukhi for Pakistan)\r\n *\r\n * Every South Asian language we support has:\r\n * - Its name in its own script (so the switcher shows हिन्दी not \"Hindi\")\r\n * - Text direction (RTL for Urdu/Shahmukhi Punjabi)\r\n * - A recommended Google Font that properly renders the script\r\n * - Default region, locale, currency, and numbering system for formatting\r\n */\r\nexport const LANGUAGES: Record<string, LangInfo> = {\r\n  en: {\r\n    code: \"en\",\r\n    name: \"English\",\r\n    englishName: \"English\",\r\n    dir: \"ltr\",\r\n    font: \"Inter, sans-serif\",\r\n    script: \"Latin\",\r\n    defaultRegion: \"IN\",\r\n    intlLocale: \"en-IN\",\r\n    numberingSystem: \"latn\",\r\n    defaultCurrency: \"INR\",\r\n  },\r\n  hi: {\r\n    code: \"hi\",\r\n    name: \"हिन्दी\",\r\n    englishName: \"Hindi\",\r\n    dir: \"ltr\",\r\n    font: \"Noto Sans Devanagari, sans-serif\",\r\n    script: \"Devanagari\",\r\n    defaultRegion: \"IN\",\r\n    intlLocale: \"hi-IN\",\r\n    numberingSystem: \"deva\",\r\n    defaultCurrency: \"INR\",\r\n  },\r\n  bn: {\r\n    code: \"bn\",\r\n    name: \"বাংলা\",\r\n    englishName: \"Bengali\",\r\n    dir: \"ltr\",\r\n    font: \"Noto Sans Bengali, sans-serif\",\r\n    script: \"Bengali\",\r\n    defaultRegion: \"BD\",\r\n    intlLocale: \"bn-BD\",\r\n    numberingSystem: \"beng\",\r\n    defaultCurrency: \"BDT\",\r\n  },\r\n  ur: {\r\n    code: \"ur\",\r\n    name: \"اردو\",\r\n    englishName: \"Urdu\",\r\n    dir: \"rtl\",\r\n    font: \"Noto Nastaliq Urdu, serif\",\r\n    script: \"Nastaliq\",\r\n    defaultRegion: \"PK\",\r\n    intlLocale: \"ur-PK\",\r\n    numberingSystem: \"arabext\",\r\n    defaultCurrency: \"PKR\",\r\n  },\r\n  ta: {\r\n    code: \"ta\",\r\n    name: \"தமிழ்\",\r\n    englishName: \"Tamil\",\r\n    dir: \"ltr\",\r\n    font: \"Noto Sans Tamil, sans-serif\",\r\n    script: \"Tamil\",\r\n    defaultRegion: \"IN\",\r\n    intlLocale: \"ta-IN\",\r\n    numberingSystem: \"tamldec\",\r\n    defaultCurrency: \"INR\",\r\n  },\r\n  te: {\r\n    code: \"te\",\r\n    name: \"తెలుగు\",\r\n    englishName: \"Telugu\",\r\n    dir: \"ltr\",\r\n    font: \"Noto Sans Telugu, sans-serif\",\r\n    script: \"Telugu\",\r\n    defaultRegion: \"IN\",\r\n    intlLocale: \"te-IN\",\r\n    numberingSystem: \"telu\",\r\n    defaultCurrency: \"INR\",\r\n  },\r\n  mr: {\r\n    code: \"mr\",\r\n    name: \"मराठी\",\r\n    englishName: \"Marathi\",\r\n    dir: \"ltr\",\r\n    font: \"Noto Sans Devanagari, sans-serif\",\r\n    script: \"Devanagari\",\r\n    defaultRegion: \"IN\",\r\n    intlLocale: \"mr-IN\",\r\n    numberingSystem: \"deva\",\r\n    defaultCurrency: \"INR\",\r\n  },\r\n  ne: {\r\n    code: \"ne\",\r\n    name: \"नेपाली\",\r\n    englishName: \"Nepali\",\r\n    dir: \"ltr\",\r\n    font: \"Noto Sans Devanagari, sans-serif\",\r\n    script: \"Devanagari\",\r\n    defaultRegion: \"NP\",\r\n    intlLocale: \"ne-NP\",\r\n    numberingSystem: \"deva\",\r\n    defaultCurrency: \"NPR\",\r\n  },\r\n  pa: {\r\n    code: \"pa\",\r\n    name: \"ਪੰਜਾਬੀ\",\r\n    englishName: \"Punjabi\",\r\n    dir: \"ltr\",\r\n    font: \"Noto Sans Gurmukhi, sans-serif\",\r\n    script: \"Gurmukhi\",\r\n    defaultRegion: \"IN\",\r\n    intlLocale: \"pa-IN\",\r\n    numberingSystem: \"guru\",\r\n    defaultCurrency: \"INR\",\r\n  },\r\n  \"pa-PK\": {\r\n    code: \"pa-PK\",\r\n    name: \"پنجابی\",\r\n    englishName: \"Punjabi (Shahmukhi)\",\r\n    dir: \"rtl\",\r\n    font: \"Noto Nastaliq Urdu, serif\",\r\n    script: \"Shahmukhi\",\r\n    defaultRegion: \"PK\",\r\n    intlLocale: \"pa-Arab-PK\",\r\n    numberingSystem: \"arabext\",\r\n    defaultCurrency: \"PKR\",\r\n  },\r\n  gu: {\r\n    code: \"gu\",\r\n    name: \"ગુજરાતી\",\r\n    englishName: \"Gujarati\",\r\n    dir: \"ltr\",\r\n    font: \"Noto Sans Gujarati, sans-serif\",\r\n    script: \"Gujarati\",\r\n    defaultRegion: \"IN\",\r\n    intlLocale: \"gu-IN\",\r\n    numberingSystem: \"gujr\",\r\n    defaultCurrency: \"INR\",\r\n  },\r\n  kn: {\r\n    code: \"kn\",\r\n    name: \"ಕನ್ನಡ\",\r\n    englishName: \"Kannada\",\r\n    dir: \"ltr\",\r\n    font: \"Noto Sans Kannada, sans-serif\",\r\n    script: \"Kannada\",\r\n    defaultRegion: \"IN\",\r\n    intlLocale: \"kn-IN\",\r\n    numberingSystem: \"knda\",\r\n    defaultCurrency: \"INR\",\r\n  },\r\n  ml: {\r\n    code: \"ml\",\r\n    name: \"മലയാളം\",\r\n    englishName: \"Malayalam\",\r\n    dir: \"ltr\",\r\n    font: \"Noto Sans Malayalam, sans-serif\",\r\n    script: \"Malayalam\",\r\n    defaultRegion: \"IN\",\r\n    intlLocale: \"ml-IN\",\r\n    numberingSystem: \"mlym\",\r\n    defaultCurrency: \"INR\",\r\n  },\r\n  si: {\r\n    code: \"si\",\r\n    name: \"සිංහල\",\r\n    englishName: \"Sinhala\",\r\n    dir: \"ltr\",\r\n    font: \"Noto Sans Sinhala, sans-serif\",\r\n    script: \"Sinhala\",\r\n    defaultRegion: \"LK\",\r\n    intlLocale: \"si-LK\",\r\n    numberingSystem: \"sinh\",\r\n    defaultCurrency: \"LKR\",\r\n  },\r\n\r\n  // ─── Latin-script (Romanized) variants — first-class locales ──────────\r\n  //\r\n  // These are NOT \"broken\" Hindi/Urdu/etc. — they're how Gen-Z South Asians\r\n  // actually type. WhatsApp, Twitter, Discord, dating apps, casual product\r\n  // copy: Latin script dominates. Treating them as their own locales (with\r\n  // their own translation memory, plural rules, fallback chains) is the\r\n  // unique edge no generic i18n tool offers.\r\n  //\r\n  // Naming follows the BCP 47 convention `<lang>-Latn`. The native `name`\r\n  // uses the colloquial term Gen-Z users recognize (\"Hinglish\", \"Banglish\").\r\n\r\n  \"hi-Latn\": {\r\n    code: \"hi-Latn\",\r\n    name: \"Hinglish\",\r\n    englishName: \"Hindi (Roman)\",\r\n    dir: \"ltr\",\r\n    font: \"Inter, sans-serif\",\r\n    script: \"Latin\",\r\n    defaultRegion: \"IN\",\r\n    intlLocale: \"hi-Latn-IN\",\r\n    numberingSystem: \"latn\",\r\n    defaultCurrency: \"INR\",\r\n  },\r\n  \"ne-Latn\": {\r\n    code: \"ne-Latn\",\r\n    name: \"Roman Nepali\",\r\n    englishName: \"Nepali (Roman)\",\r\n    dir: \"ltr\",\r\n    font: \"Inter, sans-serif\",\r\n    script: \"Latin\",\r\n    defaultRegion: \"NP\",\r\n    intlLocale: \"ne-Latn-NP\",\r\n    numberingSystem: \"latn\",\r\n    defaultCurrency: \"NPR\",\r\n  },\r\n  \"ur-Latn\": {\r\n    code: \"ur-Latn\",\r\n    name: \"Roman Urdu\",\r\n    englishName: \"Urdu (Roman)\",\r\n    dir: \"ltr\",\r\n    font: \"Inter, sans-serif\",\r\n    script: \"Latin\",\r\n    defaultRegion: \"PK\",\r\n    intlLocale: \"ur-Latn-PK\",\r\n    numberingSystem: \"latn\",\r\n    defaultCurrency: \"PKR\",\r\n  },\r\n  \"bn-Latn\": {\r\n    code: \"bn-Latn\",\r\n    name: \"Banglish\",\r\n    englishName: \"Bengali (Roman)\",\r\n    dir: \"ltr\",\r\n    font: \"Inter, sans-serif\",\r\n    script: \"Latin\",\r\n    defaultRegion: \"BD\",\r\n    intlLocale: \"bn-Latn-BD\",\r\n    numberingSystem: \"latn\",\r\n    defaultCurrency: \"BDT\",\r\n  },\r\n  \"pa-Latn\": {\r\n    code: \"pa-Latn\",\r\n    name: \"Roman Punjabi\",\r\n    englishName: \"Punjabi (Roman)\",\r\n    dir: \"ltr\",\r\n    font: \"Inter, sans-serif\",\r\n    script: \"Latin\",\r\n    defaultRegion: \"IN\",\r\n    intlLocale: \"pa-Latn-IN\",\r\n    numberingSystem: \"latn\",\r\n    defaultCurrency: \"INR\",\r\n  },\r\n};\r\n\r\n/**\r\n * Culturally-aware fallback chains.\r\n *\r\n * WHY THIS MATTERS:\r\n * If a Bengali translation is missing, what should we show?\r\n * Most i18n tools fall back to English. But a Bengali speaker\r\n * is more likely to understand Hindi than English. So we fall\r\n * back to Hindi first, then English.\r\n *\r\n * IMPORTANT: Dravidian languages (Tamil, Telugu, Kannada, Malayalam)\r\n * do NOT fall back to Hindi. They're from a completely different\r\n * language family. A Tamil speaker is NOT more likely to understand\r\n * Hindi than English.\r\n *\r\n * Developers can override these in the config if they want.\r\n */\r\nexport const FALLBACK_CHAINS: Record<string, string[]> = {\r\n  en: [\"en\"],\r\n  hi: [\"hi\", \"en\"],\r\n  bn: [\"bn\", \"hi\", \"en\"],        // Bengali → Hindi → English\r\n  ur: [\"ur\", \"hi\", \"en\"],        // Urdu → Hindi → English (mutually intelligible spoken)\r\n  ta: [\"ta\", \"en\"],              // Tamil → English (Dravidian — NO Hindi fallback)\r\n  te: [\"te\", \"en\"],              // Telugu → English (Dravidian — NO Hindi fallback)\r\n  mr: [\"mr\", \"hi\", \"en\"],        // Marathi → Hindi → English (both Devanagari)\r\n  ne: [\"ne\", \"hi\", \"en\"],        // Nepali → Hindi → English (very close to Hindi)\r\n  pa: [\"pa\", \"hi\", \"en\"],        // Punjabi (India) → Hindi → English\r\n  \"pa-PK\": [\"pa-PK\", \"ur\", \"en\"],// Punjabi (Pakistan) → Urdu → English\r\n  gu: [\"gu\", \"hi\", \"en\"],        // Gujarati → Hindi → English\r\n  kn: [\"kn\", \"en\"],              // Kannada → English (Dravidian — NO Hindi fallback)\r\n  ml: [\"ml\", \"en\"],              // Malayalam → English (Dravidian — NO Hindi fallback)\r\n  si: [\"si\", \"en\"],              // Sinhala → English\r\n\r\n  // Latin-script chains. Key insight: script bridges harder than language\r\n  // family does. A Roman-Hindi reader prefers English over Devanagari Hindi\r\n  // because the script flip is a worse experience than the language gap.\r\n  \"hi-Latn\": [\"hi-Latn\", \"en\"],                    // Hinglish → English\r\n  \"ne-Latn\": [\"ne-Latn\", \"hi-Latn\", \"en\"],         // Roman Nepali → Hinglish → English (same script + close lang)\r\n  \"ur-Latn\": [\"ur-Latn\", \"hi-Latn\", \"en\"],         // Roman Urdu → Hinglish → English (mutually intelligible)\r\n  \"bn-Latn\": [\"bn-Latn\", \"en\"],                    // Banglish → English (Bengali doesn't bridge to Hindi well in Latin)\r\n  \"pa-Latn\": [\"pa-Latn\", \"hi-Latn\", \"en\"],         // Roman Punjabi → Hinglish → English\r\n};\r\n\r\n/**\r\n * Region overrides for languages that span multiple countries.\r\n *\r\n * Some languages are spoken across borders with different currencies:\r\n * - Bengali: Bangladesh (৳ Taka) vs India (₹ Rupee)\r\n * - Tamil: India (₹ Rupee) vs Sri Lanka (Rs)\r\n * - Urdu: Pakistan (Rs) vs India (₹ Rupee)\r\n *\r\n * Developers pass region=\"IN\" to <I18nProvider> to override defaults.\r\n * The key format is \"{langCode}-{regionCode}\".\r\n */\r\nexport const REGION_OVERRIDES: Record<string, { currency: string; intlLocale: string }> = {\r\n  \"bn-IN\": { currency: \"INR\", intlLocale: \"bn-IN\" },\r\n  \"ta-LK\": { currency: \"LKR\", intlLocale: \"ta-LK\" },\r\n  \"ur-IN\": { currency: \"INR\", intlLocale: \"ur-IN\" },\r\n  \"si-IN\": { currency: \"INR\", intlLocale: \"si-IN\" },\r\n  \"ne-IN\": { currency: \"INR\", intlLocale: \"ne-IN\" },\r\n};\r\n\r\n/**\r\n * Get language info. Returns a default for unknown languages\r\n * so the SDK never crashes on an unrecognized code.\r\n */\r\nexport function getLangInfo(code: string): LangInfo {\r\n  if (LANGUAGES[code]) return LANGUAGES[code];\r\n\r\n  // Unknown code — infer direction so we never render an RTL language\r\n  // left-to-right (the exact South-Asian RTL audience we target). RTL if the\r\n  // base is a known RTL language or the code carries an Arabic-script subtag\r\n  // (e.g. \"ur-IN\", \"pa-Arab\"); a \"-Latn\" romanized variant is always LTR.\r\n  const lower = code.toLowerCase();\r\n  const isLatn = /-latn(-|$)/.test(lower);\r\n  const rtl =\r\n    !isLatn &&\r\n    (/^(ur|ar|fa|ps|sd|ks)(-|$)/.test(lower) || /-arab(-|$)/.test(lower));\r\n  return {\r\n    code,\r\n    name: code,\r\n    englishName: code,\r\n    dir: rtl ? (\"rtl\" as const) : (\"ltr\" as const),\r\n    font: \"sans-serif\",\r\n    script: rtl ? \"Arabic\" : isLatn ? \"Latin\" : \"Unknown\",\r\n    defaultRegion: \"IN\",\r\n    intlLocale: code,\r\n    numberingSystem: \"latn\",\r\n    defaultCurrency: \"INR\",\r\n  };\r\n}\r\n\r\n/**\r\n * Get the fallback chain for a language.\r\n * If no custom chain exists, defaults to [lang, \"en\"].\r\n */\r\nexport function getFallbackChain(lang: string): string[] {\r\n  return FALLBACK_CHAINS[lang] || [lang, \"en\"];\r\n}\r\n\r\n/**\r\n * Resolve the effective locale and currency for a language + optional region.\r\n * Checks REGION_OVERRIDES first, then falls back to the language's defaults.\r\n */\r\nexport function resolveRegion(\r\n  lang: string,\r\n  region?: string\r\n): { intlLocale: string; currency: string } {\r\n  const langInfo = getLangInfo(lang);\r\n\r\n  if (region) {\r\n    const overrideKey = `${lang}-${region}`;\r\n    const override = REGION_OVERRIDES[overrideKey];\r\n    if (override) {\r\n      return { intlLocale: override.intlLocale, currency: override.currency };\r\n    }\r\n    // If no specific override, just swap the region in the locale\r\n    return {\r\n      intlLocale: `${lang}-${region}`,\r\n      currency: langInfo.defaultCurrency,\r\n    };\r\n  }\r\n\r\n  return {\r\n    intlLocale: langInfo.intlLocale,\r\n    currency: langInfo.defaultCurrency,\r\n  };\r\n}\r\n\r\n/**\r\n * Google Fonts CSS URLs for each script.\r\n * We only load the fonts that are actually needed.\r\n */\r\nexport const FONT_URLS: Record<string, string> = {\r\n  \"Noto Sans Devanagari\":\r\n    \"https://fonts.googleapis.com/css2?family=Noto+Sans+Devanagari:wght@400;500;600;700&display=swap\",\r\n  \"Noto Sans Bengali\":\r\n    \"https://fonts.googleapis.com/css2?family=Noto+Sans+Bengali:wght@400;500;600;700&display=swap\",\r\n  \"Noto Nastaliq Urdu\":\r\n    \"https://fonts.googleapis.com/css2?family=Noto+Nastaliq+Urdu:wght@400;500;600;700&display=swap\",\r\n  \"Noto Sans Tamil\":\r\n    \"https://fonts.googleapis.com/css2?family=Noto+Sans+Tamil:wght@400;500;600;700&display=swap\",\r\n  \"Noto Sans Telugu\":\r\n    \"https://fonts.googleapis.com/css2?family=Noto+Sans+Telugu:wght@400;500;600;700&display=swap\",\r\n  \"Noto Sans Gurmukhi\":\r\n    \"https://fonts.googleapis.com/css2?family=Noto+Sans+Gurmukhi:wght@400;500;600;700&display=swap\",\r\n  \"Noto Sans Gujarati\":\r\n    \"https://fonts.googleapis.com/css2?family=Noto+Sans+Gujarati:wght@400;500;600;700&display=swap\",\r\n  \"Noto Sans Kannada\":\r\n    \"https://fonts.googleapis.com/css2?family=Noto+Sans+Kannada:wght@400;500;600;700&display=swap\",\r\n  \"Noto Sans Malayalam\":\r\n    \"https://fonts.googleapis.com/css2?family=Noto+Sans+Malayalam:wght@400;500;600;700&display=swap\",\r\n  \"Noto Sans Sinhala\":\r\n    \"https://fonts.googleapis.com/css2?family=Noto+Sans+Sinhala:wght@400;500;600;700&display=swap\",\r\n};\r\n","// FILE: packages/sdk/src/utils/formatting.ts\r\n//\r\n// South Asian number, currency, and date formatting.\r\n//\r\n// WHY THIS EXISTS:\r\n// South Asia uses a different number grouping system than the West:\r\n//   Western:     1,234,567     (groups of 3)\r\n//   South Asian: 12,34,567     (first group of 3, then groups of 2)\r\n//\r\n// This is called the lakh/crore system:\r\n//   1,00,000 = 1 lakh (100 thousand)\r\n//   1,00,00,000 = 1 crore (10 million)\r\n//\r\n// Additionally, many South Asian scripts have their own digit glyphs:\r\n//   Hindi: ०१२३४५६७८९  Bengali: ০১২৩৪৫৬৭৮৯  Tamil: ௦௧௨௩௪௫௬௭௮௯\r\n//\r\n// The Intl.NumberFormat API supports both lakh/crore grouping and\r\n// native digits via locale extensions (-u-nu-deva for Devanagari).\r\n// We wrap it with a clean API that auto-detects the right settings.\r\n\r\nimport { NumberFormatOptions, CurrencyFormatOptions, DateFormatOptions } from \"../types\";\r\nimport { getLangInfo, resolveRegion } from \"./languages\";\r\n\r\n// ─── South Asian (lakh/crore) grouping ──────────────────────────────\r\n//\r\n// Intl groups hi-IN, bn-BD, ta-IN, en-IN, ne-NP correctly as 12,34,567,\r\n// but some South Asian locales (notably ur-PK for PKR and si-LK for LKR)\r\n// fall back to Western 3-digit grouping. Rather than trust each locale's\r\n// CLDR grouping, we reassemble the integer with explicit 2,2,3 grouping for\r\n// every supported South Asian locale. This is idempotent for the locales\r\n// Intl already gets right (it produces the identical string), so the result\r\n// is consistent across the whole language set.\r\n\r\nconst SOUTH_ASIAN_LANGS = new Set([\r\n  \"en\", \"hi\", \"bn\", \"ur\", \"ta\", \"te\", \"mr\", \"ne\", \"pa\", \"pa-PK\",\r\n  \"gu\", \"kn\", \"ml\", \"si\",\r\n  \"hi-Latn\", \"ne-Latn\", \"ur-Latn\", \"bn-Latn\", \"pa-Latn\",\r\n]);\r\n\r\nfunction needsSouthAsianGrouping(lang: string): boolean {\r\n  if (SOUTH_ASIAN_LANGS.has(lang)) return true;\r\n  return SOUTH_ASIAN_LANGS.has(lang.split(\"-\")[0]);\r\n}\r\n\r\n/** Regroup a bare digit string into South Asian 2,2,3 grouping. Operates on\r\n *  whatever digit glyphs are passed in (Latin or native), so it composes with\r\n *  the `-u-nu-<system>` locale extension. */\r\nfunction groupSouthAsian(digits: string, sep: string): string {\r\n  if (digits.length <= 3) return digits;\r\n  const last3 = digits.slice(-3);\r\n  let rest = digits.slice(0, -3);\r\n  const groups: string[] = [];\r\n  while (rest.length > 2) {\r\n    groups.unshift(rest.slice(-2));\r\n    rest = rest.slice(0, -2);\r\n  }\r\n  if (rest.length) groups.unshift(rest);\r\n  return groups.join(sep) + sep + last3;\r\n}\r\n\r\n/** Rebuild an Intl.NumberFormat parts array with South Asian integer grouping,\r\n *  preserving sign, currency symbol, decimals, and the original digit glyphs. */\r\nfunction reassembleSouthAsianGrouping(parts: Intl.NumberFormatPart[]): string {\r\n  let sep = \",\";\r\n  let intDigits = \"\";\r\n  for (const p of parts) {\r\n    if (p.type === \"integer\") intDigits += p.value;\r\n    else if (p.type === \"group\") sep = p.value;\r\n  }\r\n  const grouped = groupSouthAsian(intDigits, sep);\r\n\r\n  let out = \"\";\r\n  let mergedInteger = false;\r\n  for (const p of parts) {\r\n    if (p.type === \"integer\") {\r\n      if (!mergedInteger) {\r\n        out += grouped;\r\n        mergedInteger = true;\r\n      }\r\n      // subsequent integer parts are already folded into `grouped`\r\n    } else if (p.type === \"group\") {\r\n      // grouping handled above\r\n    } else {\r\n      out += p.value;\r\n    }\r\n  }\r\n  return out;\r\n}\r\n\r\n/**\r\n * Format a number using South Asian conventions.\r\n *\r\n * Uses lakh/crore grouping automatically for South Asian locales.\r\n * Supports native digit rendering and compact notation.\r\n *\r\n * @param value   - The number to format\r\n * @param lang    - Language code (e.g. \"hi\", \"bn\")\r\n * @param region  - Optional region override (e.g. \"IN\", \"BD\")\r\n * @param options - Formatting options\r\n *\r\n * @example\r\n * formatNumber(1234567, \"hi\")                          // → \"12,34,567\"\r\n * formatNumber(1234567, \"hi\", undefined, { useNativeDigits: true })  // → \"१२,३४,५६७\"\r\n * formatNumber(1234567, \"en\")                          // → \"12,34,567\" (en-IN uses lakh/crore)\r\n * formatNumber(1500000, \"hi\", undefined, { compact: true })          // → \"15 लाख\"\r\n */\r\nexport function formatNumber(\r\n  value: number,\r\n  lang: string,\r\n  region?: string,\r\n  options?: NumberFormatOptions\r\n): string {\r\n  const langInfo = getLangInfo(lang);\r\n  const { intlLocale } = resolveRegion(lang, region);\r\n\r\n  // Build the locale string. Force Latin digits unless the caller explicitly\r\n  // opts in via useNativeDigits — otherwise some locales (bn-BD, ta-IN) silently\r\n  // emit native digits even when the developer passed nothing about digits.\r\n  let locale = intlLocale;\r\n  if (options?.useNativeDigits && langInfo.numberingSystem !== \"latn\") {\r\n    locale = `${intlLocale}-u-nu-${langInfo.numberingSystem}`;\r\n  } else {\r\n    locale = `${intlLocale}-u-nu-latn`;\r\n  }\r\n\r\n  const intlOptions: Intl.NumberFormatOptions = {};\r\n\r\n  if (options?.compact) {\r\n    intlOptions.notation = \"compact\";\r\n    intlOptions.compactDisplay = \"long\";\r\n  }\r\n\r\n  try {\r\n    const nf = new Intl.NumberFormat(locale, intlOptions);\r\n    // Compact notation has no thousands grouping, so skip the reassembly.\r\n    if (!options?.compact && needsSouthAsianGrouping(lang)) {\r\n      return reassembleSouthAsianGrouping(nf.formatToParts(value));\r\n    }\r\n    return nf.format(value);\r\n  } catch {\r\n    // Fallback to basic formatting if Intl doesn't support the locale\r\n    return value.toLocaleString();\r\n  }\r\n}\r\n\r\n/**\r\n * Format a currency value with region-aware symbol and lakh/crore grouping.\r\n *\r\n * Auto-detects the correct currency from the language and region:\r\n * - Hindi (IN) → ₹   Bengali (BD) → ৳   Urdu (PK) → Rs\r\n * - Bengali (IN) → ₹  (with region override)\r\n *\r\n * @param value   - The amount to format\r\n * @param lang    - Language code (e.g. \"hi\", \"bn\")\r\n * @param region  - Optional region override\r\n * @param options - Formatting options\r\n *\r\n * @example\r\n * formatCurrency(1234567, \"hi\")                           // → \"₹12,34,567.00\"\r\n * formatCurrency(1234567, \"bn\")                           // → \"৳12,34,567.00\" (Bangladesh default)\r\n * formatCurrency(1234567, \"bn\", \"IN\")                     // → \"₹12,34,567.00\" (India override)\r\n * formatCurrency(1234567, \"hi\", undefined, { display: \"code\" })  // → \"INR 12,34,567.00\"\r\n */\r\nexport function formatCurrency(\r\n  value: number,\r\n  lang: string,\r\n  region?: string,\r\n  options?: CurrencyFormatOptions\r\n): string {\r\n  const langInfo = getLangInfo(lang);\r\n  const resolved = resolveRegion(lang, region);\r\n\r\n  // Use explicit currency or auto-detect from language + region\r\n  const currencyCode = options?.currency || resolved.currency;\r\n\r\n  // Build locale with optional native digits (default to latn for consistency).\r\n  let locale = resolved.intlLocale;\r\n  if (options?.useNativeDigits && langInfo.numberingSystem !== \"latn\") {\r\n    locale = `${resolved.intlLocale}-u-nu-${langInfo.numberingSystem}`;\r\n  } else {\r\n    locale = `${resolved.intlLocale}-u-nu-latn`;\r\n  }\r\n\r\n  const intlOptions: Intl.NumberFormatOptions = {\r\n    style: \"currency\",\r\n    currency: currencyCode,\r\n    currencyDisplay: options?.display || \"symbol\",\r\n  };\r\n\r\n  try {\r\n    const nf = new Intl.NumberFormat(locale, intlOptions);\r\n    if (needsSouthAsianGrouping(lang)) {\r\n      return reassembleSouthAsianGrouping(nf.formatToParts(value));\r\n    }\r\n    return nf.format(value);\r\n  } catch {\r\n    // Fallback: basic format with currency code\r\n    return `${currencyCode} ${value.toLocaleString()}`;\r\n  }\r\n}\r\n\r\n/**\r\n * Format a date using South Asian conventions.\r\n *\r\n * Defaults to DD/MM/YYYY (not the American MM/DD/YYYY).\r\n * Supports four presets and native digit rendering.\r\n *\r\n * @param date    - Date to format (Date object, ISO string, or timestamp)\r\n * @param lang    - Language code\r\n * @param region  - Optional region override\r\n * @param options - Formatting options\r\n *\r\n * @example\r\n * formatDate(new Date(\"2026-03-19\"), \"hi\")                        // → \"19 मार्च 2026\"\r\n * formatDate(new Date(\"2026-03-19\"), \"hi\", undefined, { preset: \"short\" })  // → \"19/3/26\"\r\n * formatDate(new Date(\"2026-03-19\"), \"hi\", undefined, { preset: \"full\" })   // → \"गुरुवार, 19 मार्च 2026\"\r\n * formatDate(new Date(\"2026-03-19\"), \"hi\", undefined, { useNativeDigits: true }) // → \"१९ मार्च २०२६\"\r\n */\r\nexport function formatDate(\r\n  date: Date | string | number,\r\n  lang: string,\r\n  region?: string,\r\n  options?: DateFormatOptions\r\n): string {\r\n  const langInfo = getLangInfo(lang);\r\n  const { intlLocale } = resolveRegion(lang, region);\r\n\r\n  // Normalize the date input\r\n  const dateObj = date instanceof Date ? date : new Date(date);\r\n\r\n  // Guard against invalid input. Without this, Intl renders the literal\r\n  // English string \"Invalid Date\" into every locale's UI — a jarring,\r\n  // untranslated failure. Return an empty string so the caller decides.\r\n  if (isNaN(dateObj.getTime())) {\r\n    return \"\";\r\n  }\r\n\r\n  // Build locale with optional native digits (default to latn for consistency).\r\n  let locale = intlLocale;\r\n  if (options?.useNativeDigits && langInfo.numberingSystem !== \"latn\") {\r\n    locale = `${intlLocale}-u-nu-${langInfo.numberingSystem}`;\r\n  } else {\r\n    locale = `${intlLocale}-u-nu-latn`;\r\n  }\r\n\r\n  // Map presets to Intl.DateTimeFormat options\r\n  const preset = options?.preset || \"medium\";\r\n  const intlOptions = DATE_PRESETS[preset];\r\n\r\n  try {\r\n    return new Intl.DateTimeFormat(locale, intlOptions).format(dateObj);\r\n  } catch {\r\n    // Fallback to ISO date\r\n    return dateObj.toLocaleDateString();\r\n  }\r\n}\r\n\r\n/**\r\n * Date format presets mapped to Intl.DateTimeFormat options.\r\n *\r\n * short:  19/03/26\r\n * medium: 19 Mar 2026\r\n * long:   19 March 2026\r\n * full:   Thursday, 19 March 2026\r\n */\r\nconst DATE_PRESETS: Record<string, Intl.DateTimeFormatOptions> = {\r\n  short: {\r\n    day: \"numeric\",\r\n    month: \"numeric\",\r\n    year: \"2-digit\",\r\n  },\r\n  medium: {\r\n    day: \"numeric\",\r\n    month: \"short\",\r\n    year: \"numeric\",\r\n  },\r\n  long: {\r\n    day: \"numeric\",\r\n    month: \"long\",\r\n    year: \"numeric\",\r\n  },\r\n  full: {\r\n    weekday: \"long\",\r\n    day: \"numeric\",\r\n    month: \"long\",\r\n    year: \"numeric\",\r\n  },\r\n};\r\n","// FILE: packages/sdk/src/utils/plurals.ts\r\n//\r\n// CLDR-compliant pluralization for South Asian languages.\r\n//\r\n// WHY THIS IS CRITICAL:\r\n// Hindi treats 0 as singular: \"0 आइटम\" (not \"0 आइटमें\")\r\n// English treats 0 as plural: \"0 items\" (not \"0 item\")\r\n//\r\n// Most i18n tools apply English rules globally. This means Hindi\r\n// pluralization is WRONG in every app using i18next without custom\r\n// configuration. BhashaJS handles this correctly out of the box.\r\n//\r\n// CLDR PLURAL RULES (simplified for South Asian languages):\r\n// We only need \"one\" and \"other\" categories. More complex languages\r\n// (like Arabic with dual/few) are not in our scope.\r\n//\r\n// Group A — 0 AND 1 are \"one\" (singular):\r\n//   Hindi, Bengali, Marathi, Gujarati, Kannada, Sinhala, Punjabi\r\n//   Rule: n is 0 or n is 1 → \"one\"\r\n//\r\n// Group B — Only 1 is \"one\" (singular):\r\n//   English, Urdu, Tamil, Telugu, Malayalam, Nepali\r\n//   Rule: n is 1 → \"one\"\r\n//\r\n// Source: Unicode CLDR plural rules\r\n// https://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html\r\n\r\n/**\r\n * Languages where BOTH 0 and 1 are treated as singular (\"one\").\r\n * This is the South Asian plural rule that most tools get wrong.\r\n *\r\n * Latin-script variants (hi-Latn, bn-Latn, pa-Latn) inherit from their base\r\n * language — switching scripts doesn't change grammatical number rules. The\r\n * `getPluralCategory` function strips the `-Latn` suffix before lookup.\r\n */\r\nconst ZERO_AND_ONE_SINGULAR = new Set([\r\n  \"hi\",     // Hindi\r\n  \"bn\",     // Bengali\r\n  \"mr\",     // Marathi\r\n  \"gu\",     // Gujarati\r\n  \"kn\",     // Kannada\r\n  \"si\",     // Sinhala\r\n  \"pa\",     // Punjabi (Gurmukhi)\r\n  \"pa-PK\",  // Punjabi (Shahmukhi)\r\n]);\r\n\r\n/**\r\n * Map a locale code to its base language for plural-rule lookup.\r\n * `hi-Latn` → `hi`. `pa-PK` is intentionally NOT stripped because it's a\r\n * full locale (different script), not a romanization.\r\n */\r\nfunction baseLangForPlurals(lang: string): string {\r\n  return lang.endsWith(\"-Latn\") ? lang.slice(0, -5) : lang;\r\n}\r\n\r\n/**\r\n * Get the CLDR plural category for a number in a given language.\r\n *\r\n * @param count - The number to pluralize (e.g. 0, 1, 5)\r\n * @param lang  - The language code (e.g. \"hi\", \"en\")\r\n * @returns \"one\" (singular) or \"other\" (plural)\r\n *\r\n * @example\r\n * getPluralCategory(0, \"en\")  // → \"other\"  (English: \"0 items\")\r\n * getPluralCategory(0, \"hi\")  // → \"one\"    (Hindi: \"0 आइटम\")\r\n * getPluralCategory(1, \"en\")  // → \"one\"    (English: \"1 item\")\r\n * getPluralCategory(1, \"hi\")  // → \"one\"    (Hindi: \"1 आइटम\")\r\n * getPluralCategory(5, \"en\")  // → \"other\"  (English: \"5 items\")\r\n * getPluralCategory(5, \"hi\")  // → \"other\"  (Hindi: \"5 आइटमें\")\r\n */\r\nexport function getPluralCategory(\r\n  count: number,\r\n  lang: string\r\n): \"one\" | \"other\" {\r\n  // Use the absolute value for negative numbers\r\n  const n = Math.abs(count);\r\n  const base = baseLangForPlurals(lang);\r\n\r\n  // DELIBERATE MOAT OVERRIDE — South Asian \"0-as-singular\".\r\n  // For the Group-A languages, 0 is grammatically singular (\"0 आइटम\"),\r\n  // even where CLDR/Intl classifies it \"other\" (e.g. Marathi). This is the\r\n  // one intentional divergence from Intl.PluralRules and is allow-listed in\r\n  // cldr-plural.test.ts. It only applies to an EXACT zero — non-zero counts\r\n  // (including decimals like 0.5) defer to CLDR below.\r\n  if (ZERO_AND_ONE_SINGULAR.has(base) && n === 0) {\r\n    return \"one\";\r\n  }\r\n\r\n  // Everything else defers to the platform's CLDR data via Intl.PluralRules,\r\n  // which is correct for decimals (e.g. Sinhala/Punjabi 0.5 → \"other\",\r\n  // Marathi 0.5 → \"other\") where the old hand-rolled table diverged. The SDK\r\n  // only models \"one\"/\"other\", so we collapse Intl's category accordingly\r\n  // (Intl \"one\" → \"one\"; \"zero\"/\"two\"/\"few\"/\"many\"/\"other\" → \"other\").\r\n  try {\r\n    return new Intl.PluralRules(base).select(n) === \"one\" ? \"one\" : \"other\";\r\n  } catch {\r\n    // Unknown/unsupported locale — fall back to the old hand rule. Group-A\r\n    // bases already returned above for n === 0, so here Group A keeps 1 as\r\n    // singular and Group B keeps only 1 as singular.\r\n    if (ZERO_AND_ONE_SINGULAR.has(base)) {\r\n      return n <= 1 ? \"one\" : \"other\";\r\n    }\r\n    return n === 1 ? \"one\" : \"other\";\r\n  }\r\n}\r\n"],"mappings":"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","names":[]}