{"version":3,"file":"parsing-nI2ZAJ1r.cjs","names":["isNonEmptyString"],"sources":["../src/conversions/currency/parsing.ts"],"sourcesContent":["import { isNonEmptyString } from \"@/predicates/is/isNonEmptyString\";\n\n/** -------------------------------------------------------------------------------------------\n * * ***Utility: `parseCurrencyString`.***\n * --------------------------------------------------------------------------------------------\n * **Parses a human-friendly currency string into a JavaScript number.**\n *\n * ---\n * - **Supports multi-locale formats:**\n *     - ***US:***       `\"15,000.10\"`   ➔ `15300.10`.\n *     - ***Swiss:***    `\"15'000.10\"`   ➔ `15300.10`.\n *     - ***French:***   `\"15 000,10\"`   ➔ `15300.10`.\n *     - ***Indian:***   `\"1,23,456.78\"` ➔ `123456.78`.\n *     - ***European:*** `\"151.000,10\"`  ➔ `151300.10`.\n *     - ***Compact:***  `\"15300000,10\"` ➔ `15300000.10`.\n * - **Features:**\n *     - Strips symbols automatically: `\"Rp\"`, `\"$\"`, `\"EUR\"`, `etc`.\n *     - Handles bracket negatives: `\"(15.000,10)\"` ➔ `-15300.10`.\n *     - Normalizes decimal separator (last dot or comma).\n *     - Detects non-breaking spaces (`\\u00A0`, `\\u202F`) often in European data.\n *     - Fallback to `0` for empty, invalid, or non-numeric strings.\n * - **How it parses internally:**\n *      1. Removes all characters except digits, `.`, `,`, `'`,  `space`,\n *         `\\u00A0`, `\\u202F`.\n *      2. Detects bracket (...) as negative.\n *      3. If Indian style (`1,23,456`) detected by multiple ,`\\d{2}`, removes all commas.\n *      4. Otherwise:\n *         - If multiple dots & no commas ➔ thousands: removes all `.`.\n *         - If multiple commas & no dots ➔ thousands: removes all `,`.\n *         - If mixed, treats last `,` or `.` as decimal.\n *      5. Converts final decimal to `.` for JS float.\n * - **Gotchas:**\n *     - If both `.` and `,` are present, last occurrence is used as decimal.\n *     - For strings like `\"1.121.234,56\"` ➔ decimal is `,`.\n *     - For `\"1,121,234.56\"` ➔ decimal is `.`.\n *     - For `\"15300000,2121\"` ➔ decimal becomes `.` internally.\n * - **Note:**\n *       - You can use this function as a first step to **sanitize currency inputs**\n *         before storing into database or doing math.\n *       - Always pair this with your formatter for consistent output display.\n *\n * ---\n * @param {string|null|undefined} input\n *   ***Any messy currency string, may contain:***\n *     * Currency symbols (`Rp`,`$`, `CHF`, `EUR`).\n *     * Thousands separators (`.`, `,`, `'`,  `space`, `\\u00A0`, `\\u202F`).\n *     * Various decimal formats (`,` or `.`).\n *     * Bracket negative: `\"(15.000,10)\"`.\n *\n * ---\n * @returns {number} JavaScript float representation, will return `0` for invalid, empty, or\n *                   non-string input.\n *\n * ---\n * @example\n * ```ts\n * parseCurrencyString(\"Rp 15.300.000,21\");\n * // ➔ 15300000.21\n * parseCurrencyString(\"15 300 000,21\");\n * // ➔ 15300000.21\n * parseCurrencyString(\"CHF 15'300'000.21\");\n * // ➔ 15300000.21\n * parseCurrencyString(\"$15,300,000.21\");\n * // ➔ 15300000.21\n * parseCurrencyString(\"(15.000,10)\");\n * // ➔ -15000.10\n * parseCurrencyString(\"1,23,456.78\");\n * // ➔ 123456.78\n * parseCurrencyString(\"15300000,2121\");\n * // ➔ 15300000.2121\n * parseCurrencyString(\"USD 15 300 000.21\");\n * // ➔ 15300000.21\n * parseCurrencyString(\"\");\n * // ➔ 0\n * parseCurrencyString(\"abc\");\n * // ➔ 0\n * ```\n */\nexport const parseCurrencyString = (\n  input: string | null | undefined\n): number => {\n  if (!isNonEmptyString(input)) return 0;\n\n  let trimmed = input\n    .trim()\n    .replace(/\\u00A0/g, \"\")\n    .replace(/\\u202F/g, \"\");\n\n  // detect brackets (accounting style)\n  let isNegative = false;\n  if (/^\\(.*\\)$/.test(trimmed)) {\n    isNegative = true;\n    trimmed = trimmed.slice(1, -1).trim();\n  }\n\n  trimmed = trimmed\n    .replace(/^[-\\s]+/, (match) => (match.includes(\"-\") ? \"-\" : \"\"))\n    .replace(/[\\s.,-]+$/, \"\");\n\n  isNegative = isNegative || /^-/.test(trimmed) || /^[^\\d]*-/.test(trimmed);\n  const cleaned = trimmed.replace(/[^0-9.,'\\s]/g, \"\");\n  let cleanedNoSpace = cleaned.replace(/[\\s']/g, \"\");\n\n  // detect Indian style (like 1,23,456)\n  const indianMatches = cleanedNoSpace.match(/,\\d{2}/g);\n  const isIndianStyle = indianMatches && indianMatches.length > 1;\n  if (isIndianStyle) {\n    cleanedNoSpace = cleanedNoSpace.replace(/,/g, \"\");\n  } else {\n    const dotCount = (cleanedNoSpace.match(/\\./g) || []).length;\n    const commaCount = (cleanedNoSpace.match(/,/g) || []).length;\n\n    if (dotCount > 1 && commaCount === 0) {\n      // e.g. \"1.121.234\"\n      cleanedNoSpace = cleanedNoSpace.replace(/\\./g, \"\");\n    } else if (commaCount > 1 && dotCount === 0) {\n      // e.g. \"1,121,234\"\n      cleanedNoSpace = cleanedNoSpace.replace(/,/g, \"\");\n    } else {\n      // mixed, or single\n      const lastComma = cleanedNoSpace.lastIndexOf(\",\");\n      const lastDot = cleanedNoSpace.lastIndexOf(\".\");\n\n      if (lastComma > lastDot) {\n        // comma likely decimal\n        cleanedNoSpace = cleanedNoSpace.replace(/\\./g, \"\").replace(\",\", \".\");\n      } else if (lastDot > lastComma) {\n        // dot likely decimal\n        cleanedNoSpace = cleanedNoSpace.replace(/,/g, \"\");\n      } else {\n        if (lastComma > lastDot) {\n          // comma is likely decimal\n          const beforeDecimal = cleanedNoSpace\n            .slice(0, lastComma)\n            .replace(/,/g, \"\")\n            .replace(/\\./g, \"\");\n          const afterDecimal = cleanedNoSpace.slice(lastComma + 1);\n          cleanedNoSpace = beforeDecimal + \".\" + afterDecimal;\n        } else if (lastDot > lastComma) {\n          // dot is likely decimal\n          const beforeDecimal = cleanedNoSpace\n            .slice(0, lastDot)\n            .replace(/\\./g, \"\")\n            .replace(/,/g, \"\");\n          const afterDecimal = cleanedNoSpace.slice(lastDot + 1);\n          cleanedNoSpace = beforeDecimal + \".\" + afterDecimal;\n        } else if (lastComma !== -1) {\n          cleanedNoSpace = cleanedNoSpace.replace(/,/g, \"\");\n        } else if (lastDot !== -1) {\n          cleanedNoSpace = cleanedNoSpace.replace(/\\./g, \"\");\n        }\n      }\n    }\n  }\n\n  const num = parseFloat(cleanedNoSpace) || 0;\n  return isNegative ? -num : num;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8EA,MAAa,uBACX,UACW;CACX,IAAI,CAACA,gCAAiB,KAAK,GAAG,OAAO;CAErC,IAAI,UAAU,MACX,KAAK,CAAC,CACN,QAAQ,WAAW,EAAE,CAAC,CACtB,QAAQ,WAAW,EAAE;CAGxB,IAAI,aAAa;CACjB,IAAI,WAAW,KAAK,OAAO,GAAG;EAC5B,aAAa;EACb,UAAU,QAAQ,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK;CACtC;CAEA,UAAU,QACP,QAAQ,YAAY,UAAW,MAAM,SAAS,GAAG,IAAI,MAAM,EAAG,CAAC,CAC/D,QAAQ,aAAa,EAAE;CAE1B,aAAa,cAAc,KAAK,KAAK,OAAO,KAAK,WAAW,KAAK,OAAO;CAExE,IAAI,iBADY,QAAQ,QAAQ,gBAAgB,EACrB,CAAC,CAAC,QAAQ,UAAU,EAAE;CAGjD,MAAM,gBAAgB,eAAe,MAAM,SAAS;CAEpD,IADsB,iBAAiB,cAAc,SAAS,GAE5D,iBAAiB,eAAe,QAAQ,MAAM,EAAE;MAC3C;EACL,MAAM,YAAY,eAAe,MAAM,KAAK,KAAK,CAAC,EAAC,CAAE;EACrD,MAAM,cAAc,eAAe,MAAM,IAAI,KAAK,CAAC,EAAC,CAAE;EAEtD,IAAI,WAAW,KAAK,eAAe,GAEjC,iBAAiB,eAAe,QAAQ,OAAO,EAAE;OAC5C,IAAI,aAAa,KAAK,aAAa,GAExC,iBAAiB,eAAe,QAAQ,MAAM,EAAE;OAC3C;GAEL,MAAM,YAAY,eAAe,YAAY,GAAG;GAChD,MAAM,UAAU,eAAe,YAAY,GAAG;GAE9C,IAAI,YAAY,SAEd,iBAAiB,eAAe,QAAQ,OAAO,EAAE,CAAC,CAAC,QAAQ,KAAK,GAAG;QAC9D,IAAI,UAAU,WAEnB,iBAAiB,eAAe,QAAQ,MAAM,EAAE;QAEhD,IAAI,YAAY,SAAS;IAEvB,MAAM,gBAAgB,eACnB,MAAM,GAAG,SAAS,CAAC,CACnB,QAAQ,MAAM,EAAE,CAAC,CACjB,QAAQ,OAAO,EAAE;IACpB,MAAM,eAAe,eAAe,MAAM,YAAY,CAAC;IACvD,iBAAiB,gBAAgB,MAAM;GACzC,OAAO,IAAI,UAAU,WAAW;IAE9B,MAAM,gBAAgB,eACnB,MAAM,GAAG,OAAO,CAAC,CACjB,QAAQ,OAAO,EAAE,CAAC,CAClB,QAAQ,MAAM,EAAE;IACnB,MAAM,eAAe,eAAe,MAAM,UAAU,CAAC;IACrD,iBAAiB,gBAAgB,MAAM;GACzC,OAAO,IAAI,cAAc,IACvB,iBAAiB,eAAe,QAAQ,MAAM,EAAE;QAC3C,IAAI,YAAY,IACrB,iBAAiB,eAAe,QAAQ,OAAO,EAAE;EAGvD;CACF;CAEA,MAAM,MAAM,WAAW,cAAc,KAAK;CAC1C,OAAO,aAAa,CAAC,MAAM;AAC7B"}
