{"version":3,"sources":["../../src/core/constants.ts","../../src/react/DirhamSymbol.tsx","../../src/react/DirhamIcon.tsx","../../src/core/format.ts","../../src/react/DirhamPrice.tsx","../../src/react/DirhamInput.tsx","../../src/react/AnimatedDirhamPrice.tsx","../../src/core/conversion.ts","../../src/react/useDirhamRate.ts"],"names":["forwardRef","jsx","memo","useMemo","jsxs","Fragment","_fmtCache","useState","useRef","useCallback","useEffect"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * UAE Dirham currency symbol constants.\n *\n * This package maps the Dirham glyph to the official Unicode codepoint U+20C3\n * (UAE DIRHAM SIGN) via a custom web font. The codepoint was accepted by the\n * Unicode Technical Committee for Unicode 18.0 (expected September 2026).\n *\n * Until system fonts ship native U+20C3 glyphs, the bundled web font provides\n * the rendering. When OS/font support lands, the web font becomes optional;\n * zero migration required.\n *\n * @module dirham\n * @see https://www.unicode.org/alloc/Pipeline.html\n */\n\n/** Unicode character for the Dirham symbol (U+20C3, requires Dirham web font until system fonts support it) */\nexport const DIRHAM_UNICODE = \"\\u20C3\";\n\n/** HTML entity for the Dirham symbol */\nexport const DIRHAM_HTML_ENTITY = \"&#x20C3;\";\n\n/** CSS content value for use in `::before` / `::after` pseudo-elements */\nexport const DIRHAM_CSS_CONTENT = \"\\\\20C3\";\n\n/** ISO 4217 currency code for UAE Dirham */\nexport const DIRHAM_CURRENCY_CODE = \"AED\";\n\n/** Arabic text representation of the Dirham symbol (د.إ) */\nexport const DIRHAM_SYMBOL_TEXT = \"د.إ\";\n\n/** The font family name used for the Dirham web font */\nexport const DIRHAM_FONT_FAMILY = \"Dirham\";\n\n/** CSS class name for the Dirham icon */\nexport const DIRHAM_CSS_CLASS = \"dirham-symbol\";\n\n/** Unicode codepoint as a number (0x20C3) */\nexport const DIRHAM_CODEPOINT = 0x20c3;\n\n// ── Font weight mapping ─────────────────────────────────────────────────\n\n/**\n * Supported visual weights for the Dirham symbol SVG component.\n *\n * Because the Dirham symbol is not yet in standard fonts (until Unicode 18.0),\n * weight simulation is applied via SVG stroke to match surrounding text weight,\n * similar to how $, €, £ adapt to their font's weight.\n */\nexport type DirhamWeight =\n\t| \"thin\"\n\t| \"extralight\"\n\t| \"light\"\n\t| \"regular\"\n\t| \"medium\"\n\t| \"semibold\"\n\t| \"bold\"\n\t| \"extrabold\"\n\t| \"black\";\n\n/**\n * Map from weight name to CSS `font-weight` numeric value.\n * Used for matching the symbol weight to surrounding text.\n */\nexport const DIRHAM_WEIGHT_MAP: Record<DirhamWeight, number> = {\n\tthin: 100,\n\textralight: 200,\n\tlight: 300,\n\tregular: 400,\n\tmedium: 500,\n\tsemibold: 600,\n\tbold: 700,\n\textrabold: 800,\n\tblack: 900,\n};\n\n/**\n * SVG stroke-width values that simulate font weight.\n * Applied with `paint-order: stroke` so stroke renders behind fill.\n */\nexport const DIRHAM_STROKE_MAP: Record<DirhamWeight, number> = {\n\tthin: 0,\n\textralight: 0,\n\tlight: 0,\n\tregular: 0,\n\tmedium: 8,\n\tsemibold: 16,\n\tbold: 24,\n\textrabold: 36,\n\tblack: 48,\n};\n","import type React from \"react\";\nimport { forwardRef, memo } from \"react\";\nimport { DIRHAM_STROKE_MAP, type DirhamWeight } from \"../core/constants\";\n\nexport interface DirhamSymbolProps\n\textends Omit<React.SVGProps<SVGSVGElement>, \"children\"> {\n\t/**\n\t * Size of the symbol in pixels. Sets both width and height.\n\t * @default 24\n\t */\n\tsize?: number | string;\n\n\t/**\n\t * Color of the symbol. Uses `currentColor` by default to inherit text color.\n\t * @default \"currentColor\"\n\t */\n\tcolor?: string;\n\n\t/**\n\t * Accessible label for screen readers.\n\t * @default \"UAE Dirham\"\n\t */\n\t\"aria-label\"?: string;\n\n\t/**\n\t * Visual weight of the symbol. Simulates font-weight via SVG stroke\n\t * so the symbol matches surrounding text weight.\n\t *\n\t * @example\n\t * ```tsx\n\t * <h1 style={{ fontWeight: 700 }}>\n\t *   Price: 100 <DirhamSymbol size=\"1em\" weight=\"bold\" />\n\t * </h1>\n\t * ```\n\t *\n\t * @default \"regular\"\n\t */\n\tweight?: DirhamWeight;\n}\n\n/**\n * SVG-based UAE Dirham symbol React component.\n *\n * Renders the Dirham symbol as an inline SVG. No font loading required.\n * Works with SSR, is tree-shakeable, and avoids FOIT.\n *\n * @example\n * ```tsx\n * import { DirhamSymbol } from \"dirham/react\";\n *\n * <DirhamSymbol size={16} />\n * <DirhamSymbol size={24} color=\"green\" />\n * <span>100 <DirhamSymbol size=\"1em\" /></span>\n * ```\n */\nconst DirhamSymbolBase = forwardRef<SVGSVGElement, DirhamSymbolProps>(\n\t(\n\t\t{\n\t\t\tsize = 24,\n\t\t\tcolor = \"currentColor\",\n\t\t\t\"aria-label\": ariaLabel = \"UAE Dirham\",\n\t\t\tweight = \"regular\",\n\t\t\tstyle,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst strokeWidth = DIRHAM_STROKE_MAP[weight];\n\n\t\treturn (\n\t\t\t<svg\n\t\t\t\tref={ref}\n\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\tviewBox=\"0 0 1000 870\"\n\t\t\t\twidth={size}\n\t\t\t\theight={size}\n\t\t\t\tfill={color}\n\t\t\t\trole=\"img\"\n\t\t\t\taria-label={ariaLabel}\n\t\t\t\tstyle={{\n\t\t\t\t\tdisplay: \"inline-block\",\n\t\t\t\t\tverticalAlign: \"-0.125em\",\n\t\t\t\t\t...style,\n\t\t\t\t}}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<path\n\t\t\t\t\td=\"m88.3 1c0.4 0.6 2.6 3.3 4.7 5.9 15.3 18.2 26.8 47.8 33 85.1 4.1 24.5 4.3 32.2 4.3 125.6v87h-41.8c-38.2 0-42.6-0.2-50.1-1.7-11.8-2.5-24-9.2-32.2-17.8-6.5-6.9-6.3-7.3-5.9 13.6 0.5 17.3 0.7 19.2 3.2 28.6 4 14.9 9.5 26 17.8 35.9 11.3 13.6 22.8 21.2 39.2 26.3 3.5 1 10.9 1.4 37.1 1.6l32.7 0.5v43.3 43.4l-46.1-0.3-46.3-0.3-8-3.2c-9.5-3.8-13.8-6.6-23.1-14.9l-6.8-6.1 0.4 19.1c0.5 17.7 0.6 19.7 3.1 28.7 8.7 31.8 29.7 54.5 57.4 61.9 6.9 1.9 9.6 2 38.5 2.4l30.9 0.4v89.6c0 54.1-0.3 94-0.8 100.8-0.5 6.2-2.1 17.8-3.5 25.9-6.5 37.3-18.2 65.4-35 83.6l-3.4 3.7h169.1c101.1 0 176.7-0.4 187.8-0.9 19.5-1 63-5.3 72.8-7.4 3.1-0.6 8.9-1.5 12.7-2.1 8.1-1.2 21.5-4 40.8-8.9 27.2-6.8 52-15.3 76.3-26.1 7.6-3.4 29.4-14.5 35.2-18 3.1-1.8 6.8-4 8.2-4.7 3.9-2.1 10.4-6.3 19.9-13.1 4.7-3.4 9.4-6.7 10.4-7.4 4.2-2.8 18.7-14.9 25.3-21 25.1-23.1 46.1-48.8 62.4-76.3 2.3-4 5.3-9 6.6-11.1 3.3-5.6 16.9-33.6 18.2-37.8 0.6-1.9 1.4-3.9 1.8-4.3 2.6-3.4 17.6-50.6 19.4-60.9 0.6-3.3 0.9-3.8 3.4-4.3 1.6-0.3 24.9-0.3 51.8-0.1 53.8 0.4 53.8 0.4 65.7 5.9 6.7 3.1 8.7 4.5 16.1 11.2 9.7 8.7 8.8 10.1 8.2-11.7-0.4-12.8-0.9-20.7-1.8-23.9-3.4-12.3-4.2-14.9-7.2-21.1-9.8-21.4-26.2-36.7-47.2-44l-8.2-3-33.4-0.4-33.3-0.5 0.4-11.7c0.4-15.4 0.4-45.9-0.1-61.6l-0.4-12.6 44.6-0.2c38.2-0.2 45.3 0 49.5 1.1 12.6 3.5 21.1 8.3 31.5 17.8l5.8 5.4v-14.8c0-17.6-0.9-25.4-4.5-37-7.1-23.5-21.1-41-41.1-51.8-13-7-13.8-7.2-58.5-7.5-26.2-0.2-39.9-0.6-40.6-1.2-0.6-0.6-1.1-1.6-1.1-2.4 0-0.8-1.5-7.1-3.5-13.9-23.4-82.7-67.1-148.4-131-197.1-8.7-6.7-30-20.8-38.6-25.6-3.3-1.9-6.9-3.9-7.8-4.5-4.2-2.3-28.3-14.1-34.3-16.6-3.6-1.6-8.3-3.6-10.4-4.4-35.3-15.3-94.5-29.8-139.7-34.3-7.4-0.7-17.2-1.8-21.7-2.2-20.4-2.3-48.7-2.6-209.4-2.6-135.8 0-169.9 0.3-169.4 1zm330.7 43.3c33.8 2 54.6 4.6 78.9 10.5 74.2 17.6 126.4 54.8 164.3 117 3.5 5.8 18.3 36 20.5 42.1 10.5 28.3 15.6 45.1 20.1 67.3 1.1 5.4 2.6 12.6 3.3 16 0.7 3.3 1 6.4 0.7 6.7-0.5 0.4-100.9 0.6-223.3 0.5l-222.5-0.2-0.3-128.5c-0.1-70.6 0-129.3 0.3-130.4l0.4-1.9h71.1c39 0 78 0.4 86.5 0.9zm297.5 350.3c0.7 4.3 0.7 77.3 0 80.9l-0.6 2.7-227.5-0.2-227.4-0.3-0.2-42.4c-0.2-23.3 0-42.7 0.2-43.1 0.3-0.5 97.2-0.8 227.7-0.8h227.2zm-10.2 171.7c0.5 1.5-1.9 13.8-6.8 33.8-5.6 22.5-13.2 45.2-20.9 62-3.8 8.6-13.3 27.2-15.6 30.7-1.1 1.6-4.3 6.7-7.1 11.2-18 28.2-43.7 53.9-73 72.9-10.7 6.8-32.7 18.4-38.6 20.2-1.2 0.3-2.5 0.9-3 1.3-0.7 0.6-9.8 4-20.4 7.8-19.5 6.9-56.6 14.4-86.4 17.5-19.3 1.9-22.4 2-96.7 2h-76.9v-129.7-129.8l220.9-0.4c121.5-0.2 221.6-0.5 222.4-0.7 0.9-0.1 1.8 0.5 2.1 1.2z\"\n\t\t\t\t\t{...(strokeWidth > 0 && {\n\t\t\t\t\t\tstroke: color,\n\t\t\t\t\t\tstrokeWidth,\n\t\t\t\t\t\tstrokeLinejoin: \"round\" as const,\n\t\t\t\t\t\tpaintOrder: \"stroke\",\n\t\t\t\t\t})}\n\t\t\t\t/>\n\t\t\t</svg>\n\t\t);\n\t},\n);\n\nDirhamSymbolBase.displayName = \"DirhamSymbol\";\n\n// Memoize so the component only re-renders when its own props change.\n// This is important when DirhamSymbol is used inside list items or tables\n// that re-render frequently due to unrelated parent state changes.\nexport const DirhamSymbol = memo(DirhamSymbolBase);\nDirhamSymbol.displayName = \"DirhamSymbol\";\n","import type React from \"react\";\nimport { forwardRef, memo } from \"react\";\n\nexport interface DirhamIconProps\n\textends Omit<React.HTMLProps<HTMLElement>, \"children\" | \"size\"> {\n\t/**\n\t * Font size of the icon. Applied as the CSS `font-size` property.\n\t * @default \"inherit\"\n\t */\n\tsize?: number | string;\n\n\t/**\n\t * Color of the icon. Applied as the CSS `color` property.\n\t * @default \"currentColor\"\n\t */\n\tcolor?: string;\n\n\t/**\n\t * Accessible label for screen readers.\n\t * @default \"UAE Dirham\"\n\t */\n\t\"aria-label\"?: string;\n\n\t/**\n\t * HTML tag to render.\n\t * @default \"i\"\n\t */\n\tas?: \"i\" | \"span\";\n}\n\n/**\n * Font-based UAE Dirham symbol React component.\n *\n * Requires `dirham/css` to be imported for the `@font-face` and\n * `.dirham-symbol` class to be available.\n *\n * @example\n * ```tsx\n * import \"dirham/css\";\n * import { DirhamIcon } from \"dirham/react\";\n *\n * <DirhamIcon />\n * <DirhamIcon size={32} color=\"green\" />\n * ```\n */\nconst DirhamIconBase = forwardRef<HTMLElement, DirhamIconProps>(\n\t(\n\t\t{\n\t\t\tsize,\n\t\t\tcolor = \"currentColor\",\n\t\t\t\"aria-label\": ariaLabel = \"UAE Dirham\",\n\t\t\tas: Tag = \"i\",\n\t\t\tclassName = \"\",\n\t\t\tstyle,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst classes = `dirham-symbol${className ? ` ${className}` : \"\"}`;\n\t\tconst iconStyle: React.CSSProperties = {\n\t\t\t...(size !== undefined && {\n\t\t\t\tfontSize: typeof size === \"number\" ? `${size}px` : size,\n\t\t\t}),\n\t\t\tcolor,\n\t\t\t...style,\n\t\t};\n\n\t\treturn (\n\t\t\t<Tag\n\t\t\t\tref={ref as React.Ref<HTMLElement>}\n\t\t\t\tclassName={classes}\n\t\t\t\tstyle={iconStyle}\n\t\t\t\trole=\"img\"\n\t\t\t\taria-label={ariaLabel}\n\t\t\t\t{...(props as React.HTMLProps<HTMLElement>)}\n\t\t\t/>\n\t\t);\n\t},\n);\n\nDirhamIconBase.displayName = \"DirhamIcon\";\n\n// Memoize so the component only re-renders when its own props change.\nexport const DirhamIcon = memo(DirhamIconBase);\nDirhamIcon.displayName = \"DirhamIcon\";\n","import {\n\tDIRHAM_CURRENCY_CODE,\n\tDIRHAM_SYMBOL_TEXT,\n\tDIRHAM_UNICODE,\n} from \"./constants\";\n\n// ─── Intl.NumberFormat cache ─────────────────────────────────────────────────\n// Constructing Intl.NumberFormat is expensive (~µs). Cache instances keyed on\n// \"locale:decimals\" so repeated calls (e.g., rendering a price list) reuse\n// the same formatter instead of allocating a new object each time.\nconst _fmtCache = new Map<string, Intl.NumberFormat>();\n\nfunction getFormatter(\n\tlocale: string,\n\tdecimals: number,\n\tnotation: \"standard\" | \"compact\" = \"standard\",\n): Intl.NumberFormat {\n\tconst key = `${locale}:${decimals}:${notation}`;\n\tlet fmt = _fmtCache.get(key);\n\tif (!fmt) {\n\t\tfmt = new Intl.NumberFormat(locale, {\n\t\t\tminimumFractionDigits: notation === \"compact\" ? 0 : decimals,\n\t\t\tmaximumFractionDigits: decimals,\n\t\t\t...(notation === \"compact\" && {\n\t\t\t\tnotation: \"compact\",\n\t\t\t\tcompactDisplay: \"short\",\n\t\t\t}),\n\t\t});\n\t\t_fmtCache.set(key, fmt);\n\t}\n\treturn fmt;\n}\n\n/**\n * Options for formatting a Dirham amount.\n */\nexport interface FormatDirhamOptions {\n\t/**\n\t * Locale string for number formatting.\n\t * @default \"en-AE\"\n\t */\n\tlocale?: string;\n\n\t/**\n\t * Number of decimal places.\n\t * @default 2\n\t */\n\tdecimals?: number;\n\n\t/**\n\t * Whether to place the symbol before the amount.\n\t * When `undefined`, determined by locale:\n\t * - Arabic locales (ar-*): symbol after amount\n\t * - Other locales: symbol before amount\n\t */\n\tsymbolFirst?: boolean;\n\n\t/**\n\t * Use ISO currency code (AED) instead of the symbol.\n\t * @default false\n\t */\n\tuseCode?: boolean;\n\n\t/**\n\t * Separator between symbol and amount.\n\t * @default \" \" (non-breaking space)\n\t */\n\tseparator?: string;\n\n\t/**\n\t * Number notation style.\n\t * - `\"standard\"` — full digits (e.g. 1,500,000.00)\n\t * - `\"compact\"` — abbreviated (e.g. 1.5M)\n\t * @default \"standard\"\n\t */\n\tnotation?: \"standard\" | \"compact\";\n}\n\n/**\n * Format a number as a Dirham currency string.\n *\n * @example\n * ```ts\n * formatDirham(100);          // \"\\u20C3 100.00\"\n * formatDirham(1234.5);       // \"\\u20C3 1,234.50\"\n * formatDirham(100, { locale: \"ar-AE\" }); // \"100.00 \\u20C3\"\n * formatDirham(100, { useCode: true });   // \"AED 100.00\"\n * formatDirham(1500000, { notation: \"compact\" }); // \"\\u20C3 1.5M\"\n * ```\n */\nexport function formatDirham(\n\tamount: number,\n\toptions: FormatDirhamOptions = {},\n): string {\n\tif (!Number.isFinite(amount)) {\n\t\tthrow new RangeError(\n\t\t\t`formatDirham: amount must be a finite number, got ${amount}`,\n\t\t);\n\t}\n\n\tconst {\n\t\tlocale = \"en-AE\",\n\t\tdecimals = 2,\n\t\tuseCode = false,\n\t\tseparator = \"\\u00A0\", // non-breaking space\n\t\tnotation = \"standard\",\n\t} = options;\n\n\tconst symbol = useCode ? DIRHAM_CURRENCY_CODE : DIRHAM_UNICODE;\n\n\t// Determine symbol placement\n\tlet symbolFirst: boolean;\n\tif (options.symbolFirst !== undefined) {\n\t\tsymbolFirst = options.symbolFirst;\n\t} else {\n\t\t// Arabic locales place symbol after amount\n\t\tsymbolFirst = !locale.startsWith(\"ar\");\n\t}\n\n\t// Format the number (use cached formatter)\n\tconst formatted = getFormatter(locale, decimals, notation).format(amount);\n\n\treturn symbolFirst\n\t\t? `${symbol}${separator}${formatted}`\n\t\t: `${formatted}${separator}${symbol}`;\n}\n\n/**\n * Options for parsing a Dirham-formatted string.\n */\nexport interface ParseDirhamOptions {\n\t/**\n\t * Normalize Arabic-Indic digits (٠١٢٣٤٥٦٧٨٩ / U+0660–U+0669) to ASCII\n\t * digits before parsing. Enables round-tripping strings produced by\n\t * `formatDirham` with Arabic locales (e.g. `\"ar-AE\"`).\n\t * @default true\n\t */\n\tnormalizeArabicNumerals?: boolean;\n}\n\n/**\n * Parse a Dirham-formatted string back to a number.\n * Strips currency symbols, codes, and formatting characters.\n * By default also normalizes Arabic-Indic digits so strings produced by\n * `formatDirham({ locale: \"ar-AE\" })` round-trip correctly.\n *\n * @example\n * ```ts\n * parseDirham(\"\\u20C3 1,234.50\");                  // 1234.5\n * parseDirham(\"AED 100.00\");                        // 100\n * parseDirham(\"١٬٢٣٤٫٥٠ \\u20C3\");                  // 1234.5\n * parseDirham(\"١٠٠٫٠٠ \\u20C3\", { normalizeArabicNumerals: false }); // throws\n * ```\n */\nexport function parseDirham(\n\tvalue: string,\n\toptions: ParseDirhamOptions = {},\n): number {\n\tconst { normalizeArabicNumerals = true } = options;\n\n\tlet cleaned = value\n\t\t.replaceAll(DIRHAM_UNICODE, \"\")\n\t\t.replaceAll(DIRHAM_SYMBOL_TEXT, \"\")\n\t\t.replaceAll(DIRHAM_CURRENCY_CODE, \"\")\n\t\t.replace(/[,\\s\\u00A0\\u066C]/g, \"\") // ASCII comma, whitespace, NBSP, Arabic thousands sep\n\t\t.trim();\n\n\tif (normalizeArabicNumerals) {\n\t\t// Arabic-Indic digits U+0660–U+0669 → ASCII 0–9\n\t\tcleaned = cleaned.replace(/[\\u0660-\\u0669]/g, (d) =>\n\t\t\tString(d.charCodeAt(0) - 0x0660),\n\t\t);\n\t\t// Arabic decimal separator (U+066B) → '.'\n\t\tcleaned = cleaned.replace(/\\u066B/g, \".\");\n\t}\n\n\tconst result = Number.parseFloat(cleaned);\n\tif (Number.isNaN(result)) {\n\t\tthrow new Error(`Cannot parse \"${value}\" as a Dirham amount`);\n\t}\n\treturn result;\n}\n","import type React from \"react\";\nimport { forwardRef, memo, useMemo } from \"react\";\nimport type { DirhamWeight } from \"../core/constants\";\nimport { formatDirham } from \"../core/format\";\nimport { DirhamSymbol } from \"./DirhamSymbol\";\n\nexport interface DirhamPriceProps\n\textends Omit<React.HTMLProps<HTMLSpanElement>, \"children\"> {\n\t/**\n\t * Numeric amount to display.\n\t */\n\tamount: number;\n\n\t/**\n\t * Locale string for number formatting.\n\t * @default \"en-AE\"\n\t */\n\tlocale?: string;\n\n\t/**\n\t * Number of decimal places.\n\t * @default 2\n\t */\n\tdecimals?: number;\n\n\t/**\n\t * Use ISO currency code (AED) instead of the symbol.\n\t * @default false\n\t */\n\tuseCode?: boolean;\n\n\t/**\n\t * Number notation style.\n\t * @default \"standard\"\n\t */\n\tnotation?: \"standard\" | \"compact\";\n\n\t/**\n\t * Size of the Dirham symbol when using SVG variant.\n\t * @default \"1em\"\n\t */\n\tsymbolSize?: number | string;\n\n\t/**\n\t * Visual weight of the SVG symbol.\n\t * @default \"regular\"\n\t */\n\tweight?: DirhamWeight;\n\n\t/**\n\t * Accessible label for the currency symbol.\n\t * @default \"UAE Dirham\"\n\t */\n\t\"aria-label\"?: string;\n\n\t/**\n\t * Additional CSS class name(s) to apply to the root `<span>` element.\n\t * Useful for custom styling via Tailwind, CSS modules, etc.\n\t *\n\t * @example\n\t * ```tsx\n\t * <DirhamPrice amount={100} className=\"text-green-500 font-bold\" />\n\t * ```\n\t */\n\tclassName?: string;\n}\n\nconst DirhamPriceBase = forwardRef<HTMLSpanElement, DirhamPriceProps>(\n\t(\n\t\t{\n\t\t\tamount,\n\t\t\tlocale = \"en-AE\",\n\t\t\tdecimals = 2,\n\t\t\tuseCode = false,\n\t\t\tnotation = \"standard\",\n\t\t\tsymbolSize = \"1em\",\n\t\t\tweight = \"regular\",\n\t\t\t\"aria-label\": ariaLabel,\n\t\t\tstyle,\n\t\t\tclassName,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst symbolFirst = !locale.startsWith(\"ar\");\n\n\t\tconst formatted = useMemo(() => {\n\t\t\tif (!Number.isFinite(amount)) return \"—\";\n\t\t\treturn formatDirham(amount, {\n\t\t\t\tlocale,\n\t\t\t\tdecimals,\n\t\t\t\tuseCode: true, // Always use code so we can strip it and render SVG instead\n\t\t\t\tnotation,\n\t\t\t})\n\t\t\t\t.replace(\"AED\", \"\")\n\t\t\t\t.trim();\n\t\t}, [amount, locale, decimals, notation]);\n\n\t\tconst symbol = useCode ? (\n\t\t\t<span>AED</span>\n\t\t) : (\n\t\t\t<DirhamSymbol\n\t\t\t\tsize={symbolSize}\n\t\t\t\tweight={weight}\n\t\t\t\taria-label={ariaLabel ?? \"UAE Dirham\"}\n\t\t\t/>\n\t\t);\n\n\t\treturn (\n\t\t\t<span\n\t\t\t\tref={ref}\n\t\t\t\tclassName={className}\n\t\t\t\tdir={locale.startsWith(\"ar\") ? \"rtl\" : undefined}\n\t\t\t\tstyle={{ whiteSpace: \"nowrap\", ...style }}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{symbolFirst ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t{symbol}\n\t\t\t\t\t\t{\"\\u00A0\"}\n\t\t\t\t\t\t{formatted}\n\t\t\t\t\t</>\n\t\t\t\t) : (\n\t\t\t\t\t<>\n\t\t\t\t\t\t{formatted}\n\t\t\t\t\t\t{\"\\u00A0\"}\n\t\t\t\t\t\t{symbol}\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</span>\n\t\t);\n\t},\n);\n\nDirhamPriceBase.displayName = \"DirhamPrice\";\n\nexport const DirhamPrice = memo(DirhamPriceBase);\nDirhamPrice.displayName = \"DirhamPrice\";\n","import type React from \"react\";\nimport { forwardRef, memo, useCallback, useRef, useState } from \"react\";\nimport type { DirhamWeight } from \"../core/constants\";\nimport { DirhamSymbol } from \"./DirhamSymbol\";\n\n// ─── Formatting helper (scoped to this module) ──────────────────────────────\n\nconst _fmtCache = new Map<string, Intl.NumberFormat>();\n\nfunction getInputFormatter(\n\tlocale: string,\n\tdecimals: number,\n): Intl.NumberFormat {\n\tconst key = `input:${locale}:${decimals}`;\n\tlet fmt = _fmtCache.get(key);\n\tif (!fmt) {\n\t\tfmt = new Intl.NumberFormat(locale, {\n\t\t\tminimumFractionDigits: 0,\n\t\t\tmaximumFractionDigits: decimals,\n\t\t});\n\t\t_fmtCache.set(key, fmt);\n\t}\n\treturn fmt;\n}\n\nfunction formatInputValue(\n\tvalue: number | undefined,\n\tlocale: string,\n\tdecimals: number,\n): string {\n\tif (value === undefined || !Number.isFinite(value)) return \"\";\n\treturn getInputFormatter(locale, decimals).format(value);\n}\n\nfunction stripFormatting(raw: string): string {\n\t// Normalize Arabic-Indic digits to ASCII\n\tlet cleaned = raw.replace(/[\\u0660-\\u0669]/g, (d) =>\n\t\tString(d.charCodeAt(0) - 0x0660),\n\t);\n\t// Arabic decimal separator → dot\n\tcleaned = cleaned.replace(/\\u066B/g, \".\");\n\t// Remove thousands separators (comma, NBSP, Arabic thousands sep, space)\n\tcleaned = cleaned.replace(/[,\\s\\u00A0\\u066C]/g, \"\");\n\t// Remove any currency symbols/text\n\tcleaned = cleaned.replace(/[\\u20C3]/g, \"\");\n\tcleaned = cleaned.replace(/AED/gi, \"\");\n\tcleaned = cleaned.replace(/د\\.إ/g, \"\");\n\treturn cleaned.trim();\n}\n\n// ─── Component Props ────────────────────────────────────────────────────────\n\nexport interface DirhamInputProps\n\textends Omit<\n\t\tReact.InputHTMLAttributes<HTMLInputElement>,\n\t\t\"value\" | \"defaultValue\" | \"onChange\" | \"type\"\n\t> {\n\t/**\n\t * Controlled numeric value.\n\t */\n\tvalue?: number;\n\n\t/**\n\t * Default numeric value (uncontrolled mode).\n\t */\n\tdefaultValue?: number;\n\n\t/**\n\t * Called when the numeric value changes.\n\t * Receives the parsed number, or `undefined` when the input is cleared.\n\t */\n\tonChange?: (value: number | undefined) => void;\n\n\t/**\n\t * Locale for number formatting.\n\t * @default \"en-AE\"\n\t */\n\tlocale?: string;\n\n\t/**\n\t * Maximum decimal places allowed.\n\t * @default 2\n\t */\n\tdecimals?: number;\n\n\t/**\n\t * Minimum allowed value.\n\t */\n\tmin?: number;\n\n\t/**\n\t * Maximum allowed value.\n\t */\n\tmax?: number;\n\n\t/**\n\t * Whether to show the Dirham symbol inside the input.\n\t * @default true\n\t */\n\tshowSymbol?: boolean;\n\n\t/**\n\t * Use ISO code \"AED\" instead of the symbol.\n\t * @default false\n\t */\n\tuseCode?: boolean;\n\n\t/**\n\t * Size of the Dirham symbol.\n\t * @default \"1em\"\n\t */\n\tsymbolSize?: number | string;\n\n\t/**\n\t * Weight of the Dirham symbol.\n\t * @default \"regular\"\n\t */\n\tweight?: DirhamWeight;\n\n\t/**\n\t * Accessible label for the input.\n\t * @default \"Amount in AED\"\n\t */\n\t\"aria-label\"?: string;\n\n\t/**\n\t * Additional CSS class name(s) for the wrapper element.\n\t */\n\tclassName?: string;\n\n\t/**\n\t * Additional inline styles for the wrapper element.\n\t */\n\tstyle?: React.CSSProperties;\n\n\t/**\n\t * Additional CSS class name(s) for the `<input>` element.\n\t */\n\tinputClassName?: string;\n\n\t/**\n\t * Additional inline styles for the `<input>` element.\n\t */\n\tinputStyle?: React.CSSProperties;\n\n\t/**\n\t * Called on blur after value is clamped/formatted.\n\t */\n\tonBlur?: React.FocusEventHandler<HTMLInputElement>;\n\n\t/**\n\t * Called on focus.\n\t */\n\tonFocus?: React.FocusEventHandler<HTMLInputElement>;\n\n\t/**\n\t * Select all text on focus.\n\t * @default true\n\t */\n\tselectOnFocus?: boolean;\n}\n\n/**\n * Masked currency input with auto-formatting for AED.\n *\n * Features:\n * - Auto-formats with thousands separators on blur\n * - Decimal precision enforcement\n * - Min/max clamping\n * - Paste handling (including Arabic numerals)\n * - Mobile-friendly with `inputMode=\"decimal\"`\n * - RTL support for Arabic locales\n * - Controlled and uncontrolled modes\n *\n * @example\n * ```tsx\n * import { DirhamInput } from \"dirham/react\";\n *\n * function PaymentForm() {\n *   const [amount, setAmount] = useState<number | undefined>(0);\n *   return (\n *     <DirhamInput\n *       value={amount}\n *       onChange={setAmount}\n *       min={0}\n *       max={999999}\n *       placeholder=\"Enter amount\"\n *     />\n *   );\n * }\n * ```\n */\nconst DirhamInputBase = forwardRef<HTMLInputElement, DirhamInputProps>(\n\t(\n\t\t{\n\t\t\tvalue: controlledValue,\n\t\t\tdefaultValue,\n\t\t\tonChange,\n\t\t\tlocale = \"en-AE\",\n\t\t\tdecimals = 2,\n\t\t\tmin,\n\t\t\tmax,\n\t\t\tshowSymbol = true,\n\t\t\tuseCode = false,\n\t\t\tsymbolSize = \"1em\",\n\t\t\tweight = \"regular\",\n\t\t\t\"aria-label\": ariaLabel = \"Amount in AED\",\n\t\t\tclassName,\n\t\t\tstyle,\n\t\t\tinputClassName,\n\t\t\tinputStyle,\n\t\t\tonBlur,\n\t\t\tonFocus,\n\t\t\tselectOnFocus = true,\n\t\t\tplaceholder,\n\t\t\tdisabled,\n\t\t\treadOnly,\n\t\t\t...inputProps\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst isControlled = controlledValue !== undefined;\n\t\tconst [internalValue, setInternalValue] = useState<number | undefined>(\n\t\t\tdefaultValue,\n\t\t);\n\t\tconst numericValue = isControlled ? controlledValue : internalValue;\n\n\t\t// Raw text the user is typing (only used while focused)\n\t\tconst [rawText, setRawText] = useState<string>(\"\");\n\t\tconst [isFocused, setIsFocused] = useState(false);\n\t\tconst inputRef = useRef<HTMLInputElement>(null);\n\n\t\t// Merge refs\n\t\tconst mergedRef = useCallback(\n\t\t\t(node: HTMLInputElement | null) => {\n\t\t\t\t(inputRef as React.MutableRefObject<HTMLInputElement | null>).current =\n\t\t\t\t\tnode;\n\t\t\t\tif (typeof ref === \"function\") ref(node);\n\t\t\t\telse if (ref)\n\t\t\t\t\t(ref as React.MutableRefObject<HTMLInputElement | null>).current =\n\t\t\t\t\t\tnode;\n\t\t\t},\n\t\t\t[ref],\n\t\t);\n\n\t\tconst isRTL = locale.startsWith(\"ar\");\n\n\t\t// Clamp value within min/max\n\t\tconst clamp = useCallback(\n\t\t\t(v: number): number => {\n\t\t\t\tlet result = v;\n\t\t\t\tif (min !== undefined && result < min) result = min;\n\t\t\t\tif (max !== undefined && result > max) result = max;\n\t\t\t\treturn result;\n\t\t\t},\n\t\t\t[min, max],\n\t\t);\n\n\t\t// The display text when not focused\n\t\tconst displayText = isFocused\n\t\t\t? rawText\n\t\t\t: formatInputValue(numericValue, locale, decimals);\n\n\t\t// When entering focus, show the raw numeric value\n\t\tconst handleFocus = useCallback(\n\t\t\t(e: React.FocusEvent<HTMLInputElement>) => {\n\t\t\t\tsetIsFocused(true);\n\t\t\t\t// Show plain number for editing\n\t\t\t\tconst plain =\n\t\t\t\t\tnumericValue !== undefined && Number.isFinite(numericValue)\n\t\t\t\t\t\t? numericValue.toString()\n\t\t\t\t\t\t: \"\";\n\t\t\t\tsetRawText(plain);\n\n\t\t\t\tif (selectOnFocus) {\n\t\t\t\t\t// setTimeout so the value is set before selection\n\t\t\t\t\tsetTimeout(() => inputRef.current?.select(), 0);\n\t\t\t\t}\n\t\t\t\tonFocus?.(e);\n\t\t\t},\n\t\t\t[numericValue, selectOnFocus, onFocus],\n\t\t);\n\n\t\t// On blur, parse+clamp+format\n\t\tconst handleBlur = useCallback(\n\t\t\t(e: React.FocusEvent<HTMLInputElement>) => {\n\t\t\t\tsetIsFocused(false);\n\n\t\t\t\tconst stripped = stripFormatting(rawText);\n\t\t\t\tif (stripped === \"\" || stripped === \".\" || stripped === \"-\") {\n\t\t\t\t\tif (!isControlled) setInternalValue(undefined);\n\t\t\t\t\tonChange?.(undefined);\n\t\t\t\t} else {\n\t\t\t\t\tlet parsed = Number.parseFloat(stripped);\n\t\t\t\t\tif (Number.isNaN(parsed)) {\n\t\t\t\t\t\tif (!isControlled) setInternalValue(undefined);\n\t\t\t\t\t\tonChange?.(undefined);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Enforce decimal precision\n\t\t\t\t\t\tconst factor = 10 ** decimals;\n\t\t\t\t\t\tparsed = Math.round(parsed * factor) / factor;\n\t\t\t\t\t\tparsed = clamp(parsed);\n\t\t\t\t\t\tif (!isControlled) setInternalValue(parsed);\n\t\t\t\t\t\tonChange?.(parsed);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tonBlur?.(e);\n\t\t\t},\n\t\t\t[rawText, decimals, clamp, isControlled, onChange, onBlur],\n\t\t);\n\n\t\t// Handle typing\n\t\tconst handleChange = useCallback(\n\t\t\t(e: React.ChangeEvent<HTMLInputElement>) => {\n\t\t\t\tconst text = e.target.value;\n\n\t\t\t\t// Allow only digits, one decimal point, optional leading minus\n\t\t\t\tconst cleaned = stripFormatting(text);\n\n\t\t\t\t// Validate: optional minus, digits, optional single dot + digits\n\t\t\t\tif (cleaned !== \"\" && !/^-?\\d*\\.?\\d*$/.test(cleaned)) {\n\t\t\t\t\treturn; // reject invalid input\n\t\t\t\t}\n\n\t\t\t\t// Enforce max decimal places while typing\n\t\t\t\tconst dotIndex = cleaned.indexOf(\".\");\n\t\t\t\tif (dotIndex !== -1) {\n\t\t\t\t\tconst decimalPart = cleaned.slice(dotIndex + 1);\n\t\t\t\t\tif (decimalPart.length > decimals) {\n\t\t\t\t\t\treturn; // too many decimal places\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tsetRawText(cleaned);\n\n\t\t\t\t// Emit intermediate value for controlled components\n\t\t\t\tif (cleaned === \"\" || cleaned === \".\" || cleaned === \"-\") {\n\t\t\t\t\tif (!isControlled) setInternalValue(undefined);\n\t\t\t\t\tonChange?.(undefined);\n\t\t\t\t} else {\n\t\t\t\t\tconst parsed = Number.parseFloat(cleaned);\n\t\t\t\t\tif (!Number.isNaN(parsed)) {\n\t\t\t\t\t\tif (!isControlled) setInternalValue(parsed);\n\t\t\t\t\t\tonChange?.(parsed);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t[decimals, isControlled, onChange],\n\t\t);\n\n\t\t// Handle paste — support formatted and Arabic numeral values\n\t\tconst handlePaste = useCallback(\n\t\t\t(e: React.ClipboardEvent<HTMLInputElement>) => {\n\t\t\t\te.preventDefault();\n\t\t\t\tconst pasted = e.clipboardData.getData(\"text/plain\");\n\t\t\t\tconst stripped = stripFormatting(pasted);\n\n\t\t\t\tif (stripped === \"\") return;\n\n\t\t\t\t// Enforce decimal places\n\t\t\t\tconst dotIndex = stripped.indexOf(\".\");\n\t\t\t\tlet final = stripped;\n\t\t\t\tif (dotIndex !== -1) {\n\t\t\t\t\tfinal = `${stripped.slice(0, dotIndex)}.${stripped.slice(dotIndex + 1, dotIndex + 1 + decimals)}`;\n\t\t\t\t}\n\n\t\t\t\tif (!/^-?\\d*\\.?\\d*$/.test(final)) return;\n\n\t\t\t\tsetRawText(final);\n\n\t\t\t\tconst parsed = Number.parseFloat(final);\n\t\t\t\tif (!Number.isNaN(parsed)) {\n\t\t\t\t\tconst clamped = clamp(\n\t\t\t\t\t\tMath.round(parsed * 10 ** decimals) / 10 ** decimals,\n\t\t\t\t\t);\n\t\t\t\t\tif (!isControlled) setInternalValue(clamped);\n\t\t\t\t\tonChange?.(clamped);\n\t\t\t\t}\n\t\t\t},\n\t\t\t[decimals, clamp, isControlled, onChange],\n\t\t);\n\n\t\tconst symbolElement = showSymbol ? (\n\t\t\tuseCode ? (\n\t\t\t\t<span\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tuserSelect: \"none\",\n\t\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\t\t...(isRTL ? { marginLeft: \"0.5em\" } : { marginRight: \"0.5em\" }),\n\t\t\t\t\t}}\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t>\n\t\t\t\t\tAED\n\t\t\t\t</span>\n\t\t\t) : (\n\t\t\t\t<DirhamSymbol\n\t\t\t\t\tsize={symbolSize}\n\t\t\t\t\tweight={weight}\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\t\t...(isRTL ? { marginLeft: \"0.5em\" } : { marginRight: \"0.5em\" }),\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t)\n\t\t) : null;\n\n\t\treturn (\n\t\t\t<span\n\t\t\t\tclassName={className}\n\t\t\t\tstyle={{\n\t\t\t\t\tdisplay: \"inline-flex\",\n\t\t\t\t\talignItems: \"center\",\n\t\t\t\t\tdirection: isRTL ? \"rtl\" : \"ltr\",\n\t\t\t\t\t...style,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{!isRTL && symbolElement}\n\t\t\t\t<input\n\t\t\t\t\t{...inputProps}\n\t\t\t\t\tref={mergedRef}\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t\tinputMode=\"decimal\"\n\t\t\t\t\tdir={isRTL ? \"rtl\" : \"ltr\"}\n\t\t\t\t\taria-label={ariaLabel}\n\t\t\t\t\tclassName={inputClassName}\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tminWidth: 0,\n\t\t\t\t\t\tflex: 1,\n\t\t\t\t\t\t...inputStyle,\n\t\t\t\t\t}}\n\t\t\t\t\tvalue={displayText}\n\t\t\t\t\tplaceholder={placeholder ?? formatInputValue(0, locale, decimals)}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\treadOnly={readOnly}\n\t\t\t\t\tonChange={handleChange}\n\t\t\t\t\tonFocus={handleFocus}\n\t\t\t\t\tonBlur={handleBlur}\n\t\t\t\t\tonPaste={handlePaste}\n\t\t\t\t/>\n\t\t\t\t{isRTL && symbolElement}\n\t\t\t</span>\n\t\t);\n\t},\n);\n\nDirhamInputBase.displayName = \"DirhamInput\";\n\nexport const DirhamInput = memo(DirhamInputBase);\nDirhamInput.displayName = \"DirhamInput\";\n","import type React from \"react\";\nimport { forwardRef, memo, useEffect, useRef, useState } from \"react\";\nimport type { DirhamWeight } from \"../core/constants\";\nimport { formatDirham } from \"../core/format\";\nimport { DirhamSymbol } from \"./DirhamSymbol\";\n\nexport interface AnimatedDirhamPriceProps\n\textends Omit<React.HTMLProps<HTMLSpanElement>, \"children\"> {\n\t/**\n\t * Target numeric amount to animate to.\n\t */\n\tamount: number;\n\n\t/**\n\t * Animation duration in milliseconds.\n\t * @default 600\n\t */\n\tduration?: number;\n\n\t/**\n\t * Easing function.\n\t * @default \"easeOut\"\n\t */\n\teasing?: \"linear\" | \"easeIn\" | \"easeOut\" | \"easeInOut\";\n\n\t/**\n\t * Locale for number formatting.\n\t * @default \"en-AE\"\n\t */\n\tlocale?: string;\n\n\t/**\n\t * Number of decimal places.\n\t * @default 2\n\t */\n\tdecimals?: number;\n\n\t/**\n\t * Use ISO code \"AED\" instead of the symbol.\n\t * @default false\n\t */\n\tuseCode?: boolean;\n\n\t/**\n\t * Number notation style.\n\t * @default \"standard\"\n\t */\n\tnotation?: \"standard\" | \"compact\";\n\n\t/**\n\t * Size of the Dirham symbol.\n\t * @default \"1em\"\n\t */\n\tsymbolSize?: number | string;\n\n\t/**\n\t * Weight of the Dirham symbol.\n\t * @default \"regular\"\n\t */\n\tweight?: DirhamWeight;\n\n\t/**\n\t * Accessible label.\n\t * @default \"UAE Dirham\"\n\t */\n\t\"aria-label\"?: string;\n\n\t/**\n\t * CSS class name(s).\n\t */\n\tclassName?: string;\n}\n\nconst EASING_FNS: Record<string, (t: number) => number> = {\n\tlinear: (t: number) => t,\n\teaseIn: (t: number) => t * t,\n\teaseOut: (t: number) => t * (2 - t),\n\teaseInOut: (t: number) => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t),\n};\n\n/**\n * Animated Dirham price display with count-up/count-down transitions.\n *\n * Uses `requestAnimationFrame` for smooth 60fps animations.\n * No external dependencies.\n *\n * @example\n * ```tsx\n * import { AnimatedDirhamPrice } from \"dirham/react\";\n *\n * <AnimatedDirhamPrice amount={1250} />\n * <AnimatedDirhamPrice amount={total} duration={1000} easing=\"easeInOut\" />\n * ```\n */\nconst AnimatedDirhamPriceBase = forwardRef<\n\tHTMLSpanElement,\n\tAnimatedDirhamPriceProps\n>(\n\t(\n\t\t{\n\t\t\tamount,\n\t\t\tduration = 600,\n\t\t\teasing = \"easeOut\",\n\t\t\tlocale = \"en-AE\",\n\t\t\tdecimals = 2,\n\t\t\tuseCode = false,\n\t\t\tnotation = \"standard\",\n\t\t\tsymbolSize = \"1em\",\n\t\t\tweight = \"regular\",\n\t\t\t\"aria-label\": ariaLabel,\n\t\t\tstyle,\n\t\t\tclassName,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst [displayAmount, setDisplayAmount] = useState(amount);\n\t\tconst prevAmountRef = useRef(amount);\n\t\tconst frameRef = useRef<number>(0);\n\n\t\tuseEffect(() => {\n\t\t\tconst from = prevAmountRef.current;\n\t\t\tconst to = amount;\n\t\t\tprevAmountRef.current = to;\n\n\t\t\tif (from === to) return;\n\n\t\t\tconst easeFn = EASING_FNS[easing] ?? EASING_FNS.easeOut;\n\t\t\tconst start = performance.now();\n\n\t\t\tconst animate = (now: number) => {\n\t\t\t\tconst elapsed = now - start;\n\t\t\t\tconst progress = Math.min(elapsed / duration, 1);\n\t\t\t\tconst eased = easeFn(progress);\n\t\t\t\tconst current = from + (to - from) * eased;\n\n\t\t\t\tsetDisplayAmount(current);\n\n\t\t\t\tif (progress < 1) {\n\t\t\t\t\tframeRef.current = requestAnimationFrame(animate);\n\t\t\t\t} else {\n\t\t\t\t\tsetDisplayAmount(to); // ensure we land exactly on target\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tframeRef.current = requestAnimationFrame(animate);\n\n\t\t\treturn () => {\n\t\t\t\tif (frameRef.current) cancelAnimationFrame(frameRef.current);\n\t\t\t};\n\t\t}, [amount, duration, easing]);\n\n\t\tconst symbolFirst = !locale.startsWith(\"ar\");\n\t\tconst isRTL = locale.startsWith(\"ar\");\n\n\t\tconst formatted = Number.isFinite(displayAmount)\n\t\t\t? formatDirham(displayAmount, {\n\t\t\t\t\tlocale,\n\t\t\t\t\tdecimals,\n\t\t\t\t\tuseCode: true,\n\t\t\t\t\tnotation,\n\t\t\t\t})\n\t\t\t\t\t.replace(\"AED\", \"\")\n\t\t\t\t\t.trim()\n\t\t\t: \"—\";\n\n\t\tconst symbol = useCode ? (\n\t\t\t<span>AED</span>\n\t\t) : (\n\t\t\t<DirhamSymbol\n\t\t\t\tsize={symbolSize}\n\t\t\t\tweight={weight}\n\t\t\t\taria-label={ariaLabel ?? \"UAE Dirham\"}\n\t\t\t/>\n\t\t);\n\n\t\treturn (\n\t\t\t<span\n\t\t\t\tref={ref}\n\t\t\t\tclassName={className}\n\t\t\t\tdir={isRTL ? \"rtl\" : undefined}\n\t\t\t\tstyle={{ whiteSpace: \"nowrap\", ...style }}\n\t\t\t\taria-live=\"polite\"\n\t\t\t\taria-atomic=\"true\"\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{symbolFirst ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t{symbol}\n\t\t\t\t\t\t{\"\\u00A0\"}\n\t\t\t\t\t\t{formatted}\n\t\t\t\t\t</>\n\t\t\t\t) : (\n\t\t\t\t\t<>\n\t\t\t\t\t\t{formatted}\n\t\t\t\t\t\t{\"\\u00A0\"}\n\t\t\t\t\t\t{symbol}\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</span>\n\t\t);\n\t},\n);\n\nAnimatedDirhamPriceBase.displayName = \"AnimatedDirhamPrice\";\n\nexport const AnimatedDirhamPrice = memo(AnimatedDirhamPriceBase);\nAnimatedDirhamPrice.displayName = \"AnimatedDirhamPrice\";\n","/**\n * Common exchange rates cache entry.\n */\ninterface CachedRates {\n\ttimestamp: number;\n\trates: Record<string, number>;\n}\n\nlet _cache: CachedRates | null = null;\n\n/** Default TTL for cached rates: 1 hour */\nconst CACHE_TTL = 60 * 60 * 1000;\n\n/**\n * Options for currency conversion.\n */\nexport interface ConvertOptions {\n\t/**\n\t * Number of decimal places for the result.\n\t * @default 2\n\t */\n\tdecimals?: number;\n\n\t/**\n\t * Custom exchange rate (AED per 1 unit of target currency).\n\t * When provided, skips network fetch.\n\t */\n\trate?: number;\n}\n\n/**\n * Fetch exchange rates from the Central Bank of UAE open API.\n * Results are cached in memory for 1 hour.\n *\n * Uses the free, no-auth-required exchangerate.host API as a fallback-safe source.\n *\n * @returns Map of currency codes to their AED exchange rates.\n */\nexport async function fetchExchangeRates(): Promise<Record<string, number>> {\n\tif (_cache && Date.now() - _cache.timestamp < CACHE_TTL) {\n\t\treturn _cache.rates;\n\t}\n\n\tconst res = await fetch(\"https://open.er-api.com/v6/latest/AED\");\n\n\tif (!res.ok) {\n\t\tthrow new Error(\n\t\t\t`Failed to fetch exchange rates: ${res.status} ${res.statusText}`,\n\t\t);\n\t}\n\n\tconst data = (await res.json()) as { rates?: Record<string, number> };\n\n\tif (!data.rates) {\n\t\tthrow new Error(\"Invalid exchange rate response: missing rates\");\n\t}\n\n\t_cache = { timestamp: Date.now(), rates: data.rates };\n\treturn data.rates;\n}\n\n/**\n * Clear the in-memory exchange rate cache.\n * Useful for testing or forcing a refresh.\n */\nexport function clearRateCache(): void {\n\t_cache = null;\n}\n\n/**\n * Convert an AED amount to another currency.\n *\n * @example\n * ```ts\n * const usd = await convertFromAED(100, \"USD\");\n * const eur = await convertFromAED(100, \"EUR\", { decimals: 4 });\n * const manual = await convertFromAED(100, \"USD\", { rate: 0.2723 });\n * ```\n */\nexport async function convertFromAED(\n\tamount: number,\n\tcurrency: string,\n\toptions: ConvertOptions = {},\n): Promise<number> {\n\tif (!Number.isFinite(amount)) {\n\t\tthrow new RangeError(\n\t\t\t`convertFromAED: amount must be a finite number, got ${amount}`,\n\t\t);\n\t}\n\tconst { decimals = 2 } = options;\n\tconst code = currency.toUpperCase();\n\n\tlet rate: number;\n\tif (options.rate !== undefined) {\n\t\trate = options.rate;\n\t} else {\n\t\tconst rates = await fetchExchangeRates();\n\t\tconst r = rates[code];\n\t\tif (r === undefined) {\n\t\t\tthrow new Error(`Unknown currency code: ${code}`);\n\t\t}\n\t\trate = r;\n\t}\n\n\tconst factor = 10 ** decimals;\n\treturn Math.round(amount * rate * factor) / factor;\n}\n\n/**\n * Convert a foreign currency amount to AED.\n *\n * @example\n * ```ts\n * const aed = await convertToAED(27.23, \"USD\");\n * ```\n */\nexport async function convertToAED(\n\tamount: number,\n\tcurrency: string,\n\toptions: ConvertOptions = {},\n): Promise<number> {\n\tif (!Number.isFinite(amount)) {\n\t\tthrow new RangeError(\n\t\t\t`convertToAED: amount must be a finite number, got ${amount}`,\n\t\t);\n\t}\n\tconst { decimals = 2 } = options;\n\tconst code = currency.toUpperCase();\n\n\tlet rate: number;\n\tif (options.rate !== undefined) {\n\t\trate = options.rate;\n\t} else {\n\t\tconst rates = await fetchExchangeRates();\n\t\tconst r = rates[code];\n\t\tif (r === undefined) {\n\t\t\tthrow new Error(`Unknown currency code: ${code}`);\n\t\t}\n\t\trate = r;\n\t}\n\n\tif (rate === 0) {\n\t\tthrow new Error(`Exchange rate for ${code} is zero`);\n\t}\n\n\tconst factor = 10 ** decimals;\n\treturn Math.round((amount / rate) * factor) / factor;\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { clearRateCache, fetchExchangeRates } from \"../core/conversion\";\n\nexport interface UseDirhamRateResult {\n\t/** The exchange rate (AED → target currency). `undefined` while loading. */\n\trate: number | undefined;\n\t/** Whether rates are currently being fetched. */\n\tloading: boolean;\n\t/** Error message if the fetch failed. */\n\terror: string | undefined;\n\t/** Re-fetch the exchange rates (clears cache). */\n\trefetch: () => void;\n\t/** Convert an AED amount to the target currency using the fetched rate. */\n\tconvert: (amount: number) => number | undefined;\n\t/** Convert from the target currency back to AED using the fetched rate. */\n\tconvertBack: (amount: number) => number | undefined;\n}\n\n/**\n * React hook that fetches and caches the AED exchange rate for a given currency.\n *\n * @example\n * ```tsx\n * import { useDirhamRate } from \"dirham/react\";\n *\n * function PriceConverter() {\n *   const { rate, loading, convert } = useDirhamRate(\"USD\");\n *\n *   if (loading) return <span>Loading...</span>;\n *   return <span>100 AED = {convert(100)} USD</span>;\n * }\n * ```\n */\nexport function useDirhamRate(currency: string): UseDirhamRateResult {\n\tconst [rate, setRate] = useState<number | undefined>(undefined);\n\tconst [loading, setLoading] = useState(true);\n\tconst [error, setError] = useState<string | undefined>(undefined);\n\tconst mountedRef = useRef(true);\n\n\tconst code = currency.toUpperCase();\n\n\tconst doFetch = useCallback(() => {\n\t\tsetLoading(true);\n\t\tsetError(undefined);\n\t\tfetchExchangeRates()\n\t\t\t.then((rates) => {\n\t\t\t\tif (!mountedRef.current) return;\n\t\t\t\tconst r = rates[code];\n\t\t\t\tif (r === undefined) {\n\t\t\t\t\tsetError(`Unknown currency code: ${code}`);\n\t\t\t\t\tsetRate(undefined);\n\t\t\t\t} else {\n\t\t\t\t\tsetRate(r);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch((err: unknown) => {\n\t\t\t\tif (!mountedRef.current) return;\n\t\t\t\tsetError(err instanceof Error ? err.message : String(err));\n\t\t\t\tsetRate(undefined);\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tif (mountedRef.current) setLoading(false);\n\t\t\t});\n\t}, [code]);\n\n\tuseEffect(() => {\n\t\tmountedRef.current = true;\n\t\tdoFetch();\n\t\treturn () => {\n\t\t\tmountedRef.current = false;\n\t\t};\n\t}, [doFetch]);\n\n\tconst refetch = useCallback(() => {\n\t\tclearRateCache();\n\t\tdoFetch();\n\t}, [doFetch]);\n\n\tconst convert = useCallback(\n\t\t(amount: number): number | undefined => {\n\t\t\tif (rate === undefined) return undefined;\n\t\t\tconst factor = 100;\n\t\t\treturn Math.round(amount * rate * factor) / factor;\n\t\t},\n\t\t[rate],\n\t);\n\n\tconst convertBack = useCallback(\n\t\t(amount: number): number | undefined => {\n\t\t\tif (rate === undefined || rate === 0) return undefined;\n\t\t\tconst factor = 100;\n\t\t\treturn Math.round((amount / rate) * factor) / factor;\n\t\t},\n\t\t[rate],\n\t);\n\n\treturn { rate, loading, error, refetch, convert, convertBack };\n}\n"]}