{"version":3,"file":"index.min.js","mappings":"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","sources":["webpack://taiwanIdValidator/webpack/universalModuleDefinition","webpack://taiwanIdValidator/webpack/bootstrap","webpack://taiwanIdValidator/webpack/runtime/define property getters","webpack://taiwanIdValidator/webpack/runtime/hasOwnProperty shorthand","webpack://taiwanIdValidator/webpack/runtime/make namespace object","webpack://taiwanIdValidator/./src/citizen-digital-certificate-number.ts","webpack://taiwanIdValidator/./src/e-invoice-mobile-barcode.ts","webpack://taiwanIdValidator/./src/e-invoice-donate-code.ts","webpack://taiwanIdValidator/./src/helper.ts","webpack://taiwanIdValidator/./src/business-administration-number.ts","webpack://taiwanIdValidator/./src/id-card-number.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"taiwanIdValidator\"] = factory();\n\telse\n\t\troot[\"taiwanIdValidator\"] = factory();\n})(this, function() {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","// define __esModule on exports\n__webpack_require__.r = function(exports) {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","/**\n * Verify the input is a valid Citizen Digital Certificate Number (自然人憑證)\n *\n * @param { string } input - Citizen Digital Certificate Number\n * @returns { boolean } is `input` a valid Citizen Digital Certificate Number\n * @example\n * isCdcNumber('AB12345678901234') // true\n * isCdcNumber('A12345678901234') // false\n */\nexport function isCdcNumber(input: string): boolean {\n  if (typeof input !== 'string') return false\n\n  const n = input.toString()\n\n  // 驗證規則為兩碼英文 + 14 碼數字\n  const regex = /^[A-Z]{2}\\d{14}$/\n\n  return regex.test(n)\n}\n","/**\n * Verify the input is a valid E-Invoice Mobile Barcode (電子發票手機條碼)\n *\n * @param { string } input - E-Invoice Mobile Barcode\n * @returns { boolean } is `input` a valid E-Invoice Mobile Barcode\n * @example\n * isMobileBarcode('/+.-++..') // true\n * isMobileBarcode('/12345678') // false\n */\nexport function isMobileBarcode(input: string): boolean {\n  if (typeof input !== 'string') return false\n\n  const n = input.toString()\n\n  /**\n   * 總長度為 8 碼\n   * 第 1 碼為 /\n   * 第 2-8 碼由 0-9 (數字), A-Z (大寫英文字母), .(period), -(hyphen), +(plus) 組成\n   */\n  const regex = /^\\/[\\dA-Z.\\-+]{7}$/\n\n  return regex.test(n)\n}\n","/**\n * Verify the input is a valid E-Invoice Donate Code (電子發票捐贈碼)\n *\n * @param { string | number } input - E-Invoice Donate Code\n * @returns { boolean } is `input` a valid E-Invoice Donate Code\n * @example\n * isDonateCode('123') // true\n * isDonateCode('abc123') // false\n */\nexport function isDonateCode(input: string | number): boolean {\n  if (typeof input !== 'string' && typeof input !== 'number') return false\n\n  const n = input.toString()\n\n  // 總長度為 3-7 碼 0-9 的數字\n  const regex = /^[\\d]{3,7}$/\n\n  return regex.test(n)\n}\n","export function zipWith<T, R>(a1: T[], a2: T[], f: (v1: T, v2: T) => R): R[] {\n  const length = Math.min(a1.length, a2.length)\n  const result: R[] = []\n\n  for (let i = 0; i < length; i++) result[i] = f(a1[i], a2[i])\n\n  return result\n}\n\nexport function add(a: number, b: number) {\n  return a + b\n}\n\nexport function multiply(a: number, b: number) {\n  return a * b\n}\n\nexport const objectKeys: <T extends Record<string, unknown>>(\n  obj: T\n) => (keyof T)[] = Object.keys\n","import { zipWith, multiply, add } from './helper'\n\nexport type BanValidationOptions = {\n  /**\n   * validate `input` with old format only: https://www.fia.gov.tw/singlehtml/3?cntId=c4d9cff38c8642ef8872774ee9987283\n   */\n  applyOldRules?: boolean\n}\n\n/**\n * Verify the input is a valid Business Administration Number (營利事業統一編號)\n *\n * @param { string | number } input - Business Administration Number\n * @param { BanValidationOptions } [banValidationOptions] - Business Administration Number validation options\n * @returns { boolean } is `input` a valid Business Administration Number\n * @example\n * isBan('12345675') // true\n * isBan('12345675', { applyOldRules: true }) // true\n * isBan('12345678') // false\n */\nexport function isBan(\n  input: string | number,\n  options: BanValidationOptions = {}\n): boolean {\n  const { applyOldRules = false } = options\n\n  if (typeof input !== 'string' && typeof input !== 'number') return false\n\n  /**\n   * Example: 12345675\n   * Step 1:\n   * 1 * 1 = 1\n   * 2 * 2 = 4\n   * 3 * 1 = 3\n   * 4 * 2 = 8\n   * 5 * 1 = 5\n   * 6 * 2 = 12\n   * 7 * 4 = 28\n   * 5 * 1 = 5\n   *\n   * Step 2:\n   * 1 -> 1\n   * 4 -> 4\n   * 3 -> 3\n   * 8 -> 8\n   * 5 -> 5\n   * 12 -> 1 + 2 = 3\n   * 28 -> 2 + 8 = 10\n   * 5 -> 5\n   *\n   * Step 3:\n   * (1 + 4 + 3 + 8 + 5 + 3 + 10 + 5) % 10 = 9\n   */\n\n  const BAN_COEFFICIENTS = [1, 2, 1, 2, 1, 2, 4, 1]\n\n  const n = input.toString()\n  const regex = /^\\d{8}$/\n\n  if (!regex.test(n)) return false\n\n  /**\n   * Step 1: 先把統一編號的每個數字分別乘上對應的係數 (1, 2, 1, 2, 1, 2, 4, 1)\n   * Step 2: 再把個別乘積的十位數與個位數相加,得出八個小於 10 的數字\n   */\n\n  const intRadix = 10\n  const checksum = zipWith(\n    BAN_COEFFICIENTS,\n    n.split('').map(c => parseInt(c, intRadix)),\n    multiply\n  )\n    .map(n => (n % 10) + Math.floor(n / 10))\n    .reduce(add, 0)\n\n  /**\n   * Step 3: 檢查把這 8 個數字相加之後計算此和除以 5 or 10 的餘數\n   * Step 4:\n   *  4-1: 若是餘數為 0,則為正確的統一編號\n   *  4-2: 若是餘數為 9,且原統一編號的第七位是 7,則也為正確的統一編號\n   */\n\n  const divisor = applyOldRules ? 10 : 5\n\n  return (\n    checksum % divisor === 0 ||\n    (parseInt(n.charAt(6), intRadix) === 7 && (checksum + 1) % divisor === 0)\n  )\n}\n","import { zipWith, multiply, add, objectKeys } from './helper'\n\nexport type NewUiValidationOptions =\n  | Partial<{\n      /**\n       * Foreigners or stateless persons (外國人或無國籍人士)\n       */\n      foreignOrStateless: boolean\n      /**\n       * Stateless residents (無戶籍國民)\n       */\n      statelessResident: boolean\n      /**\n       * Hong Kong or Macao residents (香港澳門居民)\n       */\n      hkMacaoResident: boolean\n      /**\n       * Mainland China residents (大陸地區居民)\n       */\n      mainlandChinaResident: boolean\n    }>\n  | boolean\n\nexport type UiNumberValidationOptions =\n  | Partial<{\n      /**\n       * Old format UI number (舊版統一證號)\n       */\n      oldFormat: boolean\n      /**\n       * New format UI number (新版統一證號)\n       */\n      newFormat: NewUiValidationOptions\n    }>\n  | boolean\n\nexport type IdCardValidationOptions = Partial<{\n  /**\n   * National identification number (身分證字號)\n   */\n  nationalId: boolean\n  /**\n   * UI number (統一證號)\n   */\n  uiNumber: UiNumberValidationOptions\n}>\n\ntype Tree<T> = {\n  [key: string]: T | Tree<T>\n}\n\n/**\n * Tree structure containing RegExp patterns for identification numbers\n */\nconst idCardRegExps: Tree<RegExp> = {\n  nationalId: /[A-Z][1,2]\\d{8}/,\n  uiNumber: {\n    oldFormat: /[A-Z][A-D]\\d{8}/,\n    newFormat: {\n      foreignOrStateless: /[A-Z][89][0-6]\\d{7}/,\n      statelessResident: /[A-Z][89][7]\\d{7}/,\n      hkMacaoResident: /[A-Z][89][8]\\d{7}/,\n      mainlandChinaResident: /[A-Z][89][9]\\d{7}/\n    }\n  }\n}\n\n/**\n * Collect all the RegExp patterns from a tree structure.\n * If the validation options are specified, only the patterns with the corresponding options will be collected.\n * If the validation options are not specified, all patterns will be collected.\n * Default options are `true` if not specified.\n *\n * @param { Tree<RegExp> } regexTree - The tree structure containing RegExp patterns\n * @param { Tree<boolean> | boolean } validationOptions - The tree structure containing validation options\n * @returns { RegExp[] } An array of RegExp patterns to be used for validation\n */\nconst collectPatterns: (\n  regexTree: Tree<RegExp>,\n  validationOptions: Tree<boolean> | boolean\n) => RegExp[] = (regexTree, validationOptions) =>\n  objectKeys(regexTree).reduce((patterns, key) => {\n    const currentRegex = regexTree[key]\n\n    const currentOptions =\n      typeof validationOptions === 'boolean'\n        ? validationOptions\n        : validationOptions[key] ?? true // default to true if not specified\n\n    return currentRegex instanceof RegExp\n      ? currentOptions\n        ? patterns.concat(currentRegex)\n        : patterns\n      : patterns.concat(collectPatterns(currentRegex, currentOptions))\n  }, [] as RegExp[])\n\n/**\n * Verify the input is a valid identification number based on provided options.\n *\n * @param { string } input - The identification number to verify\n * @param { IdCardValidationOptions } [options] - Options specifying which types of identification numbers to check\n * @returns `true` if the input is a valid identification number according to the specified options, otherwise `false`\n * @example\n * isIdCardNumber('A123456789') // true\n * isIdCardNumber('A123456789', { nationalId: false }) // false\n */\nexport function isIdCardNumber(\n  input: string,\n  options: IdCardValidationOptions = {\n    nationalId: true,\n    uiNumber: true\n  }\n): boolean {\n  if (typeof input !== 'string') return false\n\n  // collect all the patterns based on the options\n  const patterns: RegExp[] = collectPatterns(idCardRegExps, options)\n\n  // create a regex that matches any of the patterns\n  const joinedRegexString = patterns.map(r => r.source).join('|')\n  const regex = new RegExp(`^(${joinedRegexString})$`)\n\n  return regex.test(input) && verifyTaiwanIdIntermediateString(input)\n}\n\n/**\n * Verify the intermediate string for isNationalIdentificationNumber and isResidentCertificateNumber\n *\n * @param { string } input - String to verify\n * @returns { boolean } is `input` a valid Taiwan ID intermediate string\n * @example\n * verifyTaiwanIdIntermediateString('A123456789') // true\n * verifyTaiwanIdIntermediateString('A123456788') // false\n */\nfunction verifyTaiwanIdIntermediateString(input: string): boolean {\n  const intRadix = 10\n\n  /**\n   *  A=10 台北市     J=18 新竹縣     S=26 高雄縣\n   *  B=11 台中市     K=19 苗栗縣     T=27 屏東縣\n   *  C=12 基隆市     L=20 台中縣     U=28 花蓮縣\n   *  D=13 台南市     M=21 南投縣     V=29 台東縣\n   *  E=14 高雄市     N=22 彰化縣     W=32 金門縣*\n   *  F=15 台北縣     O=35 新竹市*    X=30 澎湖縣\n   *  G=16 宜蘭縣     P=23 雲林縣     Y=31 陽明山\n   *  H=17 桃園縣     Q=24 嘉義縣     Z=33 連江縣*\n   *  I=34 嘉義市*    R=25 台南縣\n   *\n   *  Step 1: 英文字母按照上表轉換為數字之後,十位數 * 1 + 個位數 * 9 相加\n   */\n  const TAIWAN_ID_LOCALE_CODE_LIST = [\n    1, // A -> 10 -> 1 * 1 + 9 * 0 = 1\n    10, // B -> 11 -> 1 * 1 + 9 * 1 = 10\n    19, // C -> 12 -> 1 * 1 + 9 * 2 = 19\n    28, // D\n    37, // E\n    46, // F\n    55, // G\n    64, // H\n    39, // I -> 34 -> 1 * 3 + 9 * 4 = 39\n    73, // J\n    82, // K\n    2, // L\n    11, // M\n    20, // N\n    48, // O -> 35 -> 1 * 3 + 9 * 5 = 48\n    29, // P\n    38, // Q\n    47, // R\n    56, // S\n    65, // T\n    74, // U\n    83, // V\n    21, // W -> 32 -> 1 * 3 + 9 * 2 = 21\n    3, // X\n    12, // Y\n    30 // Z -> 33 -> 1 * 3 + 9 * 3 = 30\n  ]\n\n  const RESIDENT_CERTIFICATE_NUMBER_LIST = [\n    0, // A\n    1, // B\n    2, // C\n    3, // D\n    4, // E\n    5, // F\n    6, // G\n    7, // H\n    4, // I\n    8, // J\n    9, // K\n    0, // L\n    1, // M\n    2, // N\n    5, // O\n    3, // P\n    4, // Q\n    5, // R\n    6, // S\n    7, // T\n    8, // U\n    9, // V\n    2, // W\n    0, // X\n    1, // Y\n    3 // Z\n  ]\n\n  const getCharOrder = (s: string, i: number) =>\n    s.charCodeAt(i) - 'A'.charCodeAt(0)\n\n  const firstDigit = TAIWAN_ID_LOCALE_CODE_LIST[getCharOrder(input, 0)]\n\n  const secondDigit = isNaN(parseInt(input[1], intRadix)) // if is not a number (舊版居留證編號)\n    ? RESIDENT_CERTIFICATE_NUMBER_LIST[getCharOrder(input, 1)]\n    : parseInt(input[1], intRadix)\n\n  const rest = input\n    .substring(2)\n    .split('')\n    .map(n => parseInt(n, intRadix))\n\n  const idInDigits = [firstDigit, secondDigit, ...rest]\n\n  // Step 2: 第 1 位數字 (只能為 1 or 2) 至第 8 位數字分別乘上 8, 7, 6, 5, 4, 3, 2, 1 後相加,再加上第 9 位數字\n\n  const ID_COEFFICIENTS = [1, 8, 7, 6, 5, 4, 3, 2, 1, 1]\n  const sum = zipWith(idInDigits, ID_COEFFICIENTS, multiply).reduce(add, 0)\n\n  // Step 3: 如果該數字為 10 的倍數,則為正確身分證字號\n\n  return sum % 10 === 0\n}\n"],"names":["root","factory","exports","module","define","amd","this","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","isCdcNumber","input","n","toString","test","isMobileBarcode","isDonateCode","zipWith","a1","a2","f","length","Math","min","result","i","add","a","b","multiply","objectKeys","keys","isBan","options","applyOldRules","checksum","split","map","c","parseInt","floor","reduce","divisor","charAt","idCardRegExps","nationalId","uiNumber","oldFormat","newFormat","foreignOrStateless","statelessResident","hkMacaoResident","mainlandChinaResident","collectPatterns","regexTree","validationOptions","patterns","currentRegex","currentOptions","RegExp","concat","isIdCardNumber","joinedRegexString","r","source","join","intRadix","RESIDENT_CERTIFICATE_NUMBER_LIST","getCharOrder","s","charCodeAt","firstDigit","secondDigit","isNaN","rest","substring","verifyTaiwanIdIntermediateString"],"sourceRoot":""}