{"version":3,"file":"index.umd.production.min.cjs","sources":["../src/index.ts"],"sourcesContent":["export interface IOptions\n{\n  /**\n   * Set to `true` to compare strings case-insensitively. Default: `false`.\n   * @default false\n   */\n  caseInsensitive?: boolean,\n  /**\n   * A string of characters that define a custom character ordering. Default: `undefined`.\n   */\n  alphabet?: string,\n}\n\nexport type IAlphabetIndexMap = number[];\n\nconst alphabetIndexMapCache: Record<string, IAlphabetIndexMap> = {};\nconst defaultAlphabetIndexMap: IAlphabetIndexMap = [];\n\nexport function isNumberCode(code: number) {\n  return code >= 48/* '0' */ && code <= 57/* '9' */;\n}\n\nexport function naturalCompare(a: string, b: string, opts?: IOptions) {\n  const lengthA = _strLength(a, 'a');\n  const lengthB = _strLength(b, 'b');\n  let indexA = 0;\n  let indexB = 0;\n  let alphabetIndexMap = defaultAlphabetIndexMap;\n  let firstDifferenceInLeadingZeros = 0;\n\n  if (opts) {\n    if (opts.caseInsensitive) {\n      a = a.toLowerCase();\n      b = b.toLowerCase();\n    }\n\n    if (opts.alphabet) {\n      alphabetIndexMap = buildAlphabetIndexMap(opts.alphabet);\n    }\n  }\n\n  while (indexA < lengthA && indexB < lengthB) {\n    let charCodeA = a.charCodeAt(indexA);\n    let charCodeB = b.charCodeAt(indexB);\n    let difference: number;\n\n    if (isNumberCode(charCodeA)) {\n      if (!isNumberCode(charCodeB)) {\n        return charCodeA - charCodeB;\n      }\n\n      let numStartA = indexA;\n      let numStartB = indexB;\n\n      while (charCodeA === 48/* '0' */ && ++numStartA < lengthA) {\n        charCodeA = a.charCodeAt(numStartA);\n      }\n      while (charCodeB === 48/* '0' */ && ++numStartB < lengthB) {\n        charCodeB = b.charCodeAt(numStartB);\n      }\n\n      if (numStartA !== numStartB && firstDifferenceInLeadingZeros === 0) {\n        firstDifferenceInLeadingZeros = numStartA - numStartB;\n      }\n\n      let numEndA = _indexOfNumEnd(a, lengthA, numStartA);\n      let numEndB = _indexOfNumEnd(b, lengthB, numStartB);\n\n      difference = numEndA - numStartA - numEndB + numStartB; // numA length - numB length\n      if (difference !== 0) {\n        return difference;\n      }\n\n      while (numStartA < numEndA) {\n        difference = a.charCodeAt(numStartA++) - b.charCodeAt(numStartB++);\n        if (difference !== 0) {\n          return difference;\n        }\n      }\n\n      indexA = numEndA;\n      indexB = numEndB;\n      continue;\n    }\n\n    if (0 !== (difference = _alphabetCompare(charCodeA, charCodeB, alphabetIndexMap)))\n    {\n      return difference;\n    }\n\n    ++indexA;\n    ++indexB;\n  }\n\n  if (indexA < lengthA) { // `b` is a substring of `a`\n    return 1 as const;\n  }\n\n  if (indexB < lengthB) { // `a` is a substring of `b`\n    return -1 as const;\n  }\n\n  return firstDifferenceInLeadingZeros;\n}\n\nexport function buildAlphabetIndexMap(alphabet: string): IAlphabetIndexMap {\n  const existingMap = alphabetIndexMapCache[alphabet];\n  if (existingMap !== undefined) {\n    return existingMap;\n  }\n\n  const indexMap: IAlphabetIndexMap = [];\n  const maxCharCode = alphabet.split('').reduce((maxCode, char) => {\n    return Math.max(maxCode, char.charCodeAt(0));\n  }, 0);\n\n  for (let i = 0; i <= maxCharCode; i++) {\n    indexMap.push(-1);\n  }\n\n  for (let i = 0; i < alphabet.length; i++) {\n    indexMap[alphabet.charCodeAt(i)] = i;\n  }\n\n  return alphabetIndexMapCache[alphabet] = indexMap;\n}\n\nexport function _indexOfNumEnd(a: string, lengthA: number, numStartA: number)\n{\n  while (numStartA < lengthA && isNumberCode(a.charCodeAt(numStartA)))\n  {\n    ++numStartA;\n  }\n  return numStartA\n}\n\nexport function _alphabetCompare(charCodeA: number, charCodeB: number, alphabetIndexMap: IAlphabetIndexMap)\n{\n  if (charCodeA !== charCodeB) {\n    if (\n      charCodeA < alphabetIndexMap.length &&\n      charCodeB < alphabetIndexMap.length &&\n      alphabetIndexMap[charCodeA] !== -1 &&\n      alphabetIndexMap[charCodeB] !== -1\n    ) {\n      return alphabetIndexMap[charCodeA] - alphabetIndexMap[charCodeB];\n    }\n\n    return charCodeA - charCodeB;\n  }\n\n  return 0 as const\n}\n\nexport function _strLength(a: string, name: string)\n{\n  if (typeof a !== 'string')\n  {\n    throw new TypeError(`The ${name} argument must be a string. Received type '${typeof a}'`);\n  }\n\n  return a.length;\n}\n\nexport default naturalCompare;\n\n// @ts-ignore\nif (process.env.TSDX_FORMAT !== 'esm')\n{\n  Object.defineProperty(naturalCompare, \"__esModule\", { value: true });\n\n  Object.defineProperty(naturalCompare, 'naturalCompare', { value: naturalCompare });\n  Object.defineProperty(naturalCompare, 'default', { value: naturalCompare });\n\n  Object.defineProperty(naturalCompare, 'isNumberCode', { value: isNumberCode });\n  Object.defineProperty(naturalCompare, 'buildAlphabetIndexMap', { value: buildAlphabetIndexMap });\n\n  Object.defineProperty(naturalCompare, '_indexOfNumEnd', { value: _indexOfNumEnd });\n  Object.defineProperty(naturalCompare, '_alphabetCompare', { value: _alphabetCompare });\n  Object.defineProperty(naturalCompare, '_strLength', { value: _strLength });\n}\n"],"names":["alphabetIndexMapCache","defaultAlphabetIndexMap","isNumberCode","code","naturalCompare","a","b","opts","lengthA","_strLength","lengthB","indexA","indexB","alphabetIndexMap","firstDifferenceInLeadingZeros","caseInsensitive","toLowerCase","alphabet","buildAlphabetIndexMap","difference","charCodeA","charCodeAt","charCodeB","numStartA","numStartB","numEndA","_indexOfNumEnd","numEndB","_alphabetCompare","existingMap","undefined","indexMap","maxCharCode","split","reduce","maxCode","char","Math","max","i","push","length","name","TypeError","Object","defineProperty","value"],"mappings":"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"}