{"version":3,"file":"date.mjs","sources":["../../../../../../src/composables/useInputMask/masks/date.ts"],"sourcesContent":["import { CursorPosition } from '../cursor'\nimport { Mask, MaskToken } from '../mask'\n\ntype MaskTokenDate = {\n  expect: 'm' | 'd' | 'y',\n  static: false,\n} | { expect: string, static: true }\n\nconst parseTokens = (format: string) => {\n  return format.split('').map((char) => {\n    if (char === 'm' || char === 'd' || char === 'y') {\n      return { static: false, expect: char }\n    }\n\n    return { static: true, expect: char }\n  }) as MaskTokenDate[]\n}\n\ntype MinorToken = { value: string, expect: string, static: boolean }\ntype MajorToken = { value: string, expect: string, tree: MinorToken[], used?: boolean }\n\nconst getFebMaxDays = (year: number) => {\n  if (Number.isNaN(year)) {\n    return 29 // Return max possible days: We need year first\n  }\n\n  return year % 4 === 0 ? 29 : 28\n}\n\nconst getMaxDays = (year: number, month: number) => {\n  if (Number.isNaN(month)) {\n    return 31\n  }\n\n  if (month === 2) {\n    return getFebMaxDays(year)\n  }\n\n  if ([4, 6, 9, 11].includes(month)) {\n    return 30\n  }\n\n  return 31\n}\n\nconst removeStaticCharsFromEnd = <T extends MaskToken>(tokens: T[]) => {\n  let i = tokens.length - 1\n\n  while (tokens[i] && tokens[i].static) {\n    i--\n  }\n\n  return tokens.slice(0, i + 1)\n}\n\nexport const createDateMask = (format: string = 'yyyy/mm/dd'): Mask<MaskToken, MinorToken[]> => {\n  const tokens = parseTokens(format)\n\n  const cache = new Map()\n\n  return {\n    format (text: string) {\n      const minorTokens = [] as MinorToken[]\n      let valueOffset = 0\n      let tokenOffset = 0\n\n      for (let i = 0; i < tokens.length; i++) {\n        const token = tokens[tokenOffset]\n\n        if (token.static) {\n          minorTokens.push({ value: token.expect, expect: token.expect, static: true })\n          tokenOffset++\n\n          if (token.expect === text[valueOffset]) {\n            valueOffset++\n          }\n          continue\n        }\n\n        if (text[valueOffset] === undefined) {\n          break\n        }\n\n        if (!/\\d/.test(text[valueOffset])) {\n          const nextTokensHasStatic = tokens.slice(tokenOffset, text.length).some((t) => t.static)\n\n          if (nextTokensHasStatic) {\n            tokenOffset++\n          } else {\n            valueOffset++\n          }\n\n          continue\n        }\n\n        minorTokens.push({ value: text[valueOffset], expect: token.expect, static: false })\n        valueOffset++\n        tokenOffset++\n      }\n\n      const majorTokens = removeStaticCharsFromEnd(minorTokens).reduce((acc, p, index) => {\n        if (acc[acc.length - 1]?.expect === p.expect) {\n          acc[acc.length - 1].value += p.value\n          acc[acc.length - 1].tree.push(p)\n          return acc\n        }\n\n        acc.push({\n          value: p.value,\n          expect: p.expect,\n          tree: [p],\n        })\n\n        return acc\n      }, [] as MajorToken[])\n\n      majorTokens.forEach((t, index, array) => {\n        if (t.expect === 'm') {\n          const num = parseInt(t.value)\n\n          if (num > 12) {\n            t.value = '12'\n            t.tree[0].static = true\n            t.tree[1].static = false\n          }\n\n          if (num < 1 && t.value.length === 2) {\n            t.value = '01'\n            t.tree[0].static = true\n            t.tree[1].static = false\n          }\n\n          if (num > 1 && num < 10 && t.value.length === 1) {\n            t.value = '0' + num\n            t.tree.unshift({ value: '0', expect: 'm', static: true })\n            t.tree[1].static = false\n          }\n        }\n\n        if (t.expect === 'd') {\n          // Find corresponding year and month\n          // If it is first day we found, seek first year and month\n          // If it is second day we found, seek second year and month\n          // and so on\n          const year = majorTokens.find((t) => t.expect === 'y' && t.used === undefined)\n          const month = majorTokens.find((t) => t.expect === 'm' && t.used === undefined)\n          if (year) { year.used = true }\n          if (month) { month.used = true }\n\n          const m = Number(month?.value)\n\n          const maxDays = getMaxDays(Number(year?.value), m)\n\n          if (m === 2) { // Only for February\n            if (Number(t.value) >= 29) {\n              t.value = '29'\n            }\n\n            // If cached 29, means previously user entered 29, but it changed to\n            // 28 accidentally, when previous year changed to non-leap year\n            if (t.value === '28' && cache.get(index) === '29') {\n              t.value = '29'\n            }\n\n            cache.set(index, t.value)\n          }\n\n          const num = parseInt(t.value)\n\n          if (num > maxDays && t.value.length === 2) {\n            t.value = maxDays.toString()\n            t.tree[0].static = true\n            t.tree[1].static = false\n          }\n\n          if (num < 1 && t.value.length === 2) {\n            t.value = '01'\n            t.tree[0].static = true\n            t.tree[1].static = false\n          }\n\n          if (num > 3 && num < 10 && t.value.length === 1) {\n            t.value = '0' + num\n            t.tree.unshift({ value: '0', expect: 'd', static: true })\n            t.tree[1].static = false\n          }\n        }\n      })\n\n      const newText = majorTokens.reduce((acc, p) => acc + p.value, '')\n\n      const newTokens = tokens.map((t) => ({\n        ...t,\n        static: false,\n      }))\n\n      return {\n        text: newText,\n        tokens: newTokens,\n        data: majorTokens.reduce((acc, p) => acc.concat(p.tree), [] as MinorToken[]),\n      }\n    },\n    handleCursor (cursorStart, cursorEnd, oldTokens, newTokens, data, minorTokens) {\n      cursorStart.updateTokens(minorTokens!)\n      cursorEnd.updateTokens(minorTokens!)\n      cursorStart.moveForward(data.length, CursorPosition.AfterChar)\n      cursorEnd.position = cursorStart.position\n    },\n    unformat: (text: string, tokens: MaskToken[]) => {\n      return text.replace(/\\//g, '')\n    },\n  }\n}\n"],"names":["t","tokens"],"mappings":"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"}