UNPKG

188 kBJavaScriptView Raw
1/*!
2 * Copyright (c) 2018 Chris O'Hara <cohara87@gmail.com>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23(function (global, factory) {
24 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
25 typeof define === 'function' && define.amd ? define(factory) :
26 (global.validator = factory());
27}(this, (function () { 'use strict';
28
29function old_createMetadataMethodsForProperty(e, t, a, r) {
30 return {
31 getMetadata: function (o) {
32 old_assertNotFinished(r, "getMetadata"), old_assertMetadataKey(o);
33 var i = e[o];
34 if (void 0 !== i) if (1 === t) {
35 var n = i.public;
36 if (void 0 !== n) return n[a];
37 } else if (2 === t) {
38 var l = i.private;
39 if (void 0 !== l) return l.get(a);
40 } else if (Object.hasOwnProperty.call(i, "constructor")) return i.constructor;
41 },
42 setMetadata: function (o, i) {
43 old_assertNotFinished(r, "setMetadata"), old_assertMetadataKey(o);
44 var n = e[o];
45 if (void 0 === n && (n = e[o] = {}), 1 === t) {
46 var l = n.public;
47 void 0 === l && (l = n.public = {}), l[a] = i;
48 } else if (2 === t) {
49 var s = n.priv;
50 void 0 === s && (s = n.private = new Map()), s.set(a, i);
51 } else n.constructor = i;
52 }
53 };
54}
55function old_createAddInitializerMethod(e, t) {
56 return function (a) {
57 old_assertNotFinished(t, "addInitializer"), old_assertCallable(a, "An initializer"), e.push(a);
58 };
59}
60function old_memberDec(e, t, a, r, o, i, n, l, s) {
61 var c;
62 switch (i) {
63 case 1:
64 c = "accessor";
65 break;
66 case 2:
67 c = "method";
68 break;
69 case 3:
70 c = "getter";
71 break;
72 case 4:
73 c = "setter";
74 break;
75 default:
76 c = "field";
77 }
78 var d,
79 u,
80 f = {
81 kind: c,
82 name: l ? "#" + t : _toPropertyKey(t),
83 isStatic: n,
84 isPrivate: l
85 },
86 p = {
87 v: !1
88 };
89 if (0 !== i && (f.addInitializer = old_createAddInitializerMethod(o, p)), l) {
90 d = 2, u = Symbol(t);
91 var v = {};
92 0 === i ? (v.get = a.get, v.set = a.set) : 2 === i ? v.get = function () {
93 return a.value;
94 } : (1 !== i && 3 !== i || (v.get = function () {
95 return a.get.call(this);
96 }), 1 !== i && 4 !== i || (v.set = function (e) {
97 a.set.call(this, e);
98 })), f.access = v;
99 } else d = 1, u = t;
100 try {
101 return e(s, Object.assign(f, old_createMetadataMethodsForProperty(r, d, u, p)));
102 } finally {
103 p.v = !0;
104 }
105}
106function old_assertNotFinished(e, t) {
107 if (e.v) throw Error("attempted to call " + t + " after decoration was finished");
108}
109function old_assertMetadataKey(e) {
110 if ("symbol" != typeof e) throw new TypeError("Metadata keys must be symbols, received: " + e);
111}
112function old_assertCallable(e, t) {
113 if ("function" != typeof e) throw new TypeError(t + " must be a function");
114}
115function old_assertValidReturnValue(e, t) {
116 var a = typeof t;
117 if (1 === e) {
118 if ("object" !== a || null === t) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
119 void 0 !== t.get && old_assertCallable(t.get, "accessor.get"), void 0 !== t.set && old_assertCallable(t.set, "accessor.set"), void 0 !== t.init && old_assertCallable(t.init, "accessor.init"), void 0 !== t.initializer && old_assertCallable(t.initializer, "accessor.initializer");
120 } else if ("function" !== a) throw new TypeError((0 === e ? "field" : 10 === e ? "class" : "method") + " decorators must return a function or void 0");
121}
122function old_getInit(e) {
123 var t;
124 return null == (t = e.init) && (t = e.initializer) && void 0 !== console && console.warn(".initializer has been renamed to .init as of March 2022"), t;
125}
126function _iterableToArrayLimit(r, l) {
127 var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
128 if (null != t) {
129 var e,
130 n,
131 i,
132 u,
133 a = [],
134 f = !0,
135 o = !1;
136 try {
137 if (i = (t = t.call(r)).next, 0 === l) {
138 if (Object(t) !== t) return;
139 f = !1;
140 } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
141 } catch (r) {
142 o = !0, n = r;
143 } finally {
144 try {
145 if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
146 } finally {
147 if (o) throw n;
148 }
149 }
150 return a;
151 }
152}
153function _setFunctionName(e, t, n) {
154 "symbol" == typeof t && (t = (t = t.description) ? "[" + t + "]" : "");
155 try {
156 Object.defineProperty(e, "name", {
157 configurable: !0,
158 value: n ? n + " " + t : t
159 });
160 } catch (e) {}
161 return e;
162}
163function _toPrimitive(t, r) {
164 if ("object" != typeof t || !t) return t;
165 var e = t[Symbol.toPrimitive];
166 if (void 0 !== e) {
167 var i = e.call(t, r || "default");
168 if ("object" != typeof i) return i;
169 throw new TypeError("@@toPrimitive must return a primitive value.");
170 }
171 return ("string" === r ? String : Number)(t);
172}
173function _toPropertyKey(t) {
174 var i = _toPrimitive(t, "string");
175 return "symbol" == typeof i ? i : i + "";
176}
177function _typeof(o) {
178 "@babel/helpers - typeof";
179
180 return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
181 return typeof o;
182 } : function (o) {
183 return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
184 }, _typeof(o);
185}
186function _slicedToArray(arr, i) {
187 return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
188}
189function _toConsumableArray(arr) {
190 return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
191}
192function _arrayWithoutHoles(arr) {
193 if (Array.isArray(arr)) return _arrayLikeToArray(arr);
194}
195function _arrayWithHoles(arr) {
196 if (Array.isArray(arr)) return arr;
197}
198function _iterableToArray(iter) {
199 if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
200}
201function _unsupportedIterableToArray(o, minLen) {
202 if (!o) return;
203 if (typeof o === "string") return _arrayLikeToArray(o, minLen);
204 var n = Object.prototype.toString.call(o).slice(8, -1);
205 if (n === "Object" && o.constructor) n = o.constructor.name;
206 if (n === "Map" || n === "Set") return Array.from(o);
207 if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
208}
209function _arrayLikeToArray(arr, len) {
210 if (len == null || len > arr.length) len = arr.length;
211 for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
212 return arr2;
213}
214function _nonIterableSpread() {
215 throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
216}
217function _nonIterableRest() {
218 throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
219}
220function _createForOfIteratorHelper(o, allowArrayLike) {
221 var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
222 if (!it) {
223 if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
224 if (it) o = it;
225 var i = 0;
226 var F = function () {};
227 return {
228 s: F,
229 n: function () {
230 if (i >= o.length) return {
231 done: true
232 };
233 return {
234 done: false,
235 value: o[i++]
236 };
237 },
238 e: function (e) {
239 throw e;
240 },
241 f: F
242 };
243 }
244 throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
245 }
246 var normalCompletion = true,
247 didErr = false,
248 err;
249 return {
250 s: function () {
251 it = it.call(o);
252 },
253 n: function () {
254 var step = it.next();
255 normalCompletion = step.done;
256 return step;
257 },
258 e: function (e) {
259 didErr = true;
260 err = e;
261 },
262 f: function () {
263 try {
264 if (!normalCompletion && it.return != null) it.return();
265 } finally {
266 if (didErr) throw err;
267 }
268 }
269 };
270}
271
272function assertString(input) {
273 var isString = typeof input === 'string' || input instanceof String;
274 if (!isString) {
275 var invalidType = _typeof(input);
276 if (input === null) invalidType = 'null';else if (invalidType === 'object') invalidType = input.constructor.name;
277 throw new TypeError("Expected a string but received a ".concat(invalidType));
278 }
279}
280
281function toDate(date) {
282 assertString(date);
283 date = Date.parse(date);
284 return !isNaN(date) ? new Date(date) : null;
285}
286
287var alpha = {
288 'en-US': /^[A-Z]+$/i,
289 'az-AZ': /^[A-VXYZÇƏĞİıÖŞÜ]+$/i,
290 'bg-BG': /^[А-Я]+$/i,
291 'cs-CZ': /^[A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]+$/i,
292 'da-DK': /^[A-ZÆØÅ]+$/i,
293 'de-DE': /^[A-ZÄÖÜß]+$/i,
294 'el-GR': /^[Α-ώ]+$/i,
295 'es-ES': /^[A-ZÁÉÍÑÓÚÜ]+$/i,
296 'fa-IR': /^[ابپتثجچحخدذرزژسشصضطظعغفقکگلمنوهی]+$/i,
297 'fi-FI': /^[A-ZÅÄÖ]+$/i,
298 'fr-FR': /^[A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ]+$/i,
299 'it-IT': /^[A-ZÀÉÈÌÎÓÒÙ]+$/i,
300 'ja-JP': /^[ぁ-んァ-ヶヲ-゚一-龠ー・。、]+$/i,
301 'nb-NO': /^[A-ZÆØÅ]+$/i,
302 'nl-NL': /^[A-ZÁÉËÏÓÖÜÚ]+$/i,
303 'nn-NO': /^[A-ZÆØÅ]+$/i,
304 'hu-HU': /^[A-ZÁÉÍÓÖŐÚÜŰ]+$/i,
305 'pl-PL': /^[A-ZĄĆĘŚŁŃÓŻŹ]+$/i,
306 'pt-PT': /^[A-ZÃÁÀÂÄÇÉÊËÍÏÕÓÔÖÚÜ]+$/i,
307 'ru-RU': /^[А-ЯЁ]+$/i,
308 'kk-KZ': /^[А-ЯЁ\u04D8\u04B0\u0406\u04A2\u0492\u04AE\u049A\u04E8\u04BA]+$/i,
309 'sl-SI': /^[A-ZČĆĐŠŽ]+$/i,
310 'sk-SK': /^[A-ZÁČĎÉÍŇÓŠŤÚÝŽĹŔĽÄÔ]+$/i,
311 'sr-RS@latin': /^[A-ZČĆŽŠĐ]+$/i,
312 'sr-RS': /^[А-ЯЂЈЉЊЋЏ]+$/i,
313 'sv-SE': /^[A-ZÅÄÖ]+$/i,
314 'th-TH': /^[ก-๐\s]+$/i,
315 'tr-TR': /^[A-ZÇĞİıÖŞÜ]+$/i,
316 'uk-UA': /^[А-ЩЬЮЯЄIЇҐі]+$/i,
317 'vi-VN': /^[A-ZÀÁẠẢÃÂẦẤẬẨẪĂẰẮẶẲẴĐÈÉẸẺẼÊỀẾỆỂỄÌÍỊỈĨÒÓỌỎÕÔỒỐỘỔỖƠỜỚỢỞỠÙÚỤỦŨƯỪỨỰỬỮỲÝỴỶỸ]+$/i,
318 'ko-KR': /^[ㄱ-ㅎㅏ-ㅣ가-힣]*$/,
319 'ku-IQ': /^[ئابپتجچحخدرڕزژسشعغفڤقکگلڵمنوۆھەیێيطؤثآإأكضصةظذ]+$/i,
320 ar: /^[ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ]+$/,
321 he: /^[א-ת]+$/,
322 fa: /^['آاءأؤئبپتثجچحخدذرزژسشصضطظعغفقکگلمنوهةی']+$/i,
323 bn: /^['ঀঁংঃঅআইঈউঊঋঌএঐওঔকখগঘঙচছজঝঞটঠডঢণতথদধনপফবভমযরলশষসহ়ঽািীুূৃৄেৈোৌ্ৎৗড়ঢ়য়ৠৡৢৣৰৱ৲৳৴৵৶৷৸৹৺৻']+$/,
324 eo: /^[ABCĈD-GĜHĤIJĴK-PRSŜTUŬVZ]+$/i,
325 'hi-IN': /^[\u0900-\u0961]+[\u0972-\u097F]*$/i,
326 'si-LK': /^[\u0D80-\u0DFF]+$/
327};
328var alphanumeric = {
329 'en-US': /^[0-9A-Z]+$/i,
330 'az-AZ': /^[0-9A-VXYZÇƏĞİıÖŞÜ]+$/i,
331 'bg-BG': /^[0-9А-Я]+$/i,
332 'cs-CZ': /^[0-9A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]+$/i,
333 'da-DK': /^[0-9A-ZÆØÅ]+$/i,
334 'de-DE': /^[0-9A-ZÄÖÜß]+$/i,
335 'el-GR': /^[0-9Α-ω]+$/i,
336 'es-ES': /^[0-9A-ZÁÉÍÑÓÚÜ]+$/i,
337 'fi-FI': /^[0-9A-ZÅÄÖ]+$/i,
338 'fr-FR': /^[0-9A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ]+$/i,
339 'it-IT': /^[0-9A-ZÀÉÈÌÎÓÒÙ]+$/i,
340 'ja-JP': /^[0-90-9ぁ-んァ-ヶヲ-゚一-龠ー・。、]+$/i,
341 'hu-HU': /^[0-9A-ZÁÉÍÓÖŐÚÜŰ]+$/i,
342 'nb-NO': /^[0-9A-ZÆØÅ]+$/i,
343 'nl-NL': /^[0-9A-ZÁÉËÏÓÖÜÚ]+$/i,
344 'nn-NO': /^[0-9A-ZÆØÅ]+$/i,
345 'pl-PL': /^[0-9A-ZĄĆĘŚŁŃÓŻŹ]+$/i,
346 'pt-PT': /^[0-9A-ZÃÁÀÂÄÇÉÊËÍÏÕÓÔÖÚÜ]+$/i,
347 'ru-RU': /^[0-9А-ЯЁ]+$/i,
348 'kk-KZ': /^[0-9А-ЯЁ\u04D8\u04B0\u0406\u04A2\u0492\u04AE\u049A\u04E8\u04BA]+$/i,
349 'sl-SI': /^[0-9A-ZČĆĐŠŽ]+$/i,
350 'sk-SK': /^[0-9A-ZÁČĎÉÍŇÓŠŤÚÝŽĹŔĽÄÔ]+$/i,
351 'sr-RS@latin': /^[0-9A-ZČĆŽŠĐ]+$/i,
352 'sr-RS': /^[0-9А-ЯЂЈЉЊЋЏ]+$/i,
353 'sv-SE': /^[0-9A-ZÅÄÖ]+$/i,
354 'th-TH': /^[ก-๙\s]+$/i,
355 'tr-TR': /^[0-9A-ZÇĞİıÖŞÜ]+$/i,
356 'uk-UA': /^[0-9А-ЩЬЮЯЄIЇҐі]+$/i,
357 'ko-KR': /^[0-9ㄱ-ㅎㅏ-ㅣ가-힣]*$/,
358 'ku-IQ': /^[٠١٢٣٤٥٦٧٨٩0-9ئابپتجچحخدرڕزژسشعغفڤقکگلڵمنوۆھەیێيطؤثآإأكضصةظذ]+$/i,
359 'vi-VN': /^[0-9A-ZÀÁẠẢÃÂẦẤẬẨẪĂẰẮẶẲẴĐÈÉẸẺẼÊỀẾỆỂỄÌÍỊỈĨÒÓỌỎÕÔỒỐỘỔỖƠỜỚỢỞỠÙÚỤỦŨƯỪỨỰỬỮỲÝỴỶỸ]+$/i,
360 ar: /^[٠١٢٣٤٥٦٧٨٩0-9ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ]+$/,
361 he: /^[0-9א-ת]+$/,
362 fa: /^['0-9آاءأؤئبپتثجچحخدذرزژسشصضطظعغفقکگلمنوهةی۱۲۳۴۵۶۷۸۹۰']+$/i,
363 bn: /^['ঀঁংঃঅআইঈউঊঋঌএঐওঔকখগঘঙচছজঝঞটঠডঢণতথদধনপফবভমযরলশষসহ়ঽািীুূৃৄেৈোৌ্ৎৗড়ঢ়য়ৠৡৢৣ০১২৩৪৫৬৭৮৯ৰৱ৲৳৴৵৶৷৸৹৺৻']+$/,
364 eo: /^[0-9ABCĈD-GĜHĤIJĴK-PRSŜTUŬVZ]+$/i,
365 'hi-IN': /^[\u0900-\u0963]+[\u0966-\u097F]*$/i,
366 'si-LK': /^[0-9\u0D80-\u0DFF]+$/
367};
368var decimal = {
369 'en-US': '.',
370 ar: '٫'
371};
372var englishLocales = ['AU', 'GB', 'HK', 'IN', 'NZ', 'ZA', 'ZM'];
373for (var locale, i = 0; i < englishLocales.length; i++) {
374 locale = "en-".concat(englishLocales[i]);
375 alpha[locale] = alpha['en-US'];
376 alphanumeric[locale] = alphanumeric['en-US'];
377 decimal[locale] = decimal['en-US'];
378}
379
380// Source: http://www.localeplanet.com/java/
381var arabicLocales = ['AE', 'BH', 'DZ', 'EG', 'IQ', 'JO', 'KW', 'LB', 'LY', 'MA', 'QM', 'QA', 'SA', 'SD', 'SY', 'TN', 'YE'];
382for (var _locale, _i = 0; _i < arabicLocales.length; _i++) {
383 _locale = "ar-".concat(arabicLocales[_i]);
384 alpha[_locale] = alpha.ar;
385 alphanumeric[_locale] = alphanumeric.ar;
386 decimal[_locale] = decimal.ar;
387}
388var farsiLocales = ['IR', 'AF'];
389for (var _locale2, _i2 = 0; _i2 < farsiLocales.length; _i2++) {
390 _locale2 = "fa-".concat(farsiLocales[_i2]);
391 alphanumeric[_locale2] = alphanumeric.fa;
392 decimal[_locale2] = decimal.ar;
393}
394var bengaliLocales = ['BD', 'IN'];
395for (var _locale3, _i3 = 0; _i3 < bengaliLocales.length; _i3++) {
396 _locale3 = "bn-".concat(bengaliLocales[_i3]);
397 alpha[_locale3] = alpha.bn;
398 alphanumeric[_locale3] = alphanumeric.bn;
399 decimal[_locale3] = decimal['en-US'];
400}
401
402// Source: https://en.wikipedia.org/wiki/Decimal_mark
403var dotDecimal = ['ar-EG', 'ar-LB', 'ar-LY'];
404var commaDecimal = ['bg-BG', 'cs-CZ', 'da-DK', 'de-DE', 'el-GR', 'en-ZM', 'eo', 'es-ES', 'fr-CA', 'fr-FR', 'id-ID', 'it-IT', 'ku-IQ', 'hi-IN', 'hu-HU', 'nb-NO', 'nn-NO', 'nl-NL', 'pl-PL', 'pt-PT', 'ru-RU', 'kk-KZ', 'si-LK', 'sl-SI', 'sr-RS@latin', 'sr-RS', 'sv-SE', 'tr-TR', 'uk-UA', 'vi-VN'];
405for (var _i4 = 0; _i4 < dotDecimal.length; _i4++) {
406 decimal[dotDecimal[_i4]] = decimal['en-US'];
407}
408for (var _i5 = 0; _i5 < commaDecimal.length; _i5++) {
409 decimal[commaDecimal[_i5]] = ',';
410}
411alpha['fr-CA'] = alpha['fr-FR'];
412alphanumeric['fr-CA'] = alphanumeric['fr-FR'];
413alpha['pt-BR'] = alpha['pt-PT'];
414alphanumeric['pt-BR'] = alphanumeric['pt-PT'];
415decimal['pt-BR'] = decimal['pt-PT'];
416
417// see #862
418alpha['pl-Pl'] = alpha['pl-PL'];
419alphanumeric['pl-Pl'] = alphanumeric['pl-PL'];
420decimal['pl-Pl'] = decimal['pl-PL'];
421
422// see #1455
423alpha['fa-AF'] = alpha.fa;
424
425function isFloat(str, options) {
426 assertString(str);
427 options = options || {};
428 var _float = new RegExp("^(?:[-+])?(?:[0-9]+)?(?:\\".concat(options.locale ? decimal[options.locale] : '.', "[0-9]*)?(?:[eE][\\+\\-]?(?:[0-9]+))?$"));
429 if (str === '' || str === '.' || str === ',' || str === '-' || str === '+') {
430 return false;
431 }
432 var value = parseFloat(str.replace(',', '.'));
433 return _float.test(str) && (!options.hasOwnProperty('min') || value >= options.min) && (!options.hasOwnProperty('max') || value <= options.max) && (!options.hasOwnProperty('lt') || value < options.lt) && (!options.hasOwnProperty('gt') || value > options.gt);
434}
435var locales = Object.keys(decimal);
436
437function toFloat(str) {
438 if (!isFloat(str)) return NaN;
439 return parseFloat(str);
440}
441
442function toInt(str, radix) {
443 assertString(str);
444 return parseInt(str, radix || 10);
445}
446
447function toBoolean(str, strict) {
448 assertString(str);
449 if (strict) {
450 return str === '1' || /^true$/i.test(str);
451 }
452 return str !== '0' && !/^false$/i.test(str) && str !== '';
453}
454
455function equals(str, comparison) {
456 assertString(str);
457 return str === comparison;
458}
459
460function toString$1(input) {
461 if (_typeof(input) === 'object' && input !== null) {
462 if (typeof input.toString === 'function') {
463 input = input.toString();
464 } else {
465 input = '[object Object]';
466 }
467 } else if (input === null || typeof input === 'undefined' || isNaN(input) && !input.length) {
468 input = '';
469 }
470 return String(input);
471}
472
473function merge() {
474 var obj = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
475 var defaults = arguments.length > 1 ? arguments[1] : undefined;
476 for (var key in defaults) {
477 if (typeof obj[key] === 'undefined') {
478 obj[key] = defaults[key];
479 }
480 }
481 return obj;
482}
483
484var defaulContainsOptions = {
485 ignoreCase: false,
486 minOccurrences: 1
487};
488function contains(str, elem, options) {
489 assertString(str);
490 options = merge(options, defaulContainsOptions);
491 if (options.ignoreCase) {
492 return str.toLowerCase().split(toString$1(elem).toLowerCase()).length > options.minOccurrences;
493 }
494 return str.split(toString$1(elem)).length > options.minOccurrences;
495}
496
497function matches(str, pattern, modifiers) {
498 assertString(str);
499 if (Object.prototype.toString.call(pattern) !== '[object RegExp]') {
500 pattern = new RegExp(pattern, modifiers);
501 }
502 return !!str.match(pattern);
503}
504
505/* eslint-disable prefer-rest-params */
506function isByteLength(str, options) {
507 assertString(str);
508 var min;
509 var max;
510 if (_typeof(options) === 'object') {
511 min = options.min || 0;
512 max = options.max;
513 } else {
514 // backwards compatibility: isByteLength(str, min [, max])
515 min = arguments[1];
516 max = arguments[2];
517 }
518 var len = encodeURI(str).split(/%..|./).length - 1;
519 return len >= min && (typeof max === 'undefined' || len <= max);
520}
521
522var default_fqdn_options = {
523 require_tld: true,
524 allow_underscores: false,
525 allow_trailing_dot: false,
526 allow_numeric_tld: false,
527 allow_wildcard: false,
528 ignore_max_length: false
529};
530function isFQDN(str, options) {
531 assertString(str);
532 options = merge(options, default_fqdn_options);
533
534 /* Remove the optional trailing dot before checking validity */
535 if (options.allow_trailing_dot && str[str.length - 1] === '.') {
536 str = str.substring(0, str.length - 1);
537 }
538
539 /* Remove the optional wildcard before checking validity */
540 if (options.allow_wildcard === true && str.indexOf('*.') === 0) {
541 str = str.substring(2);
542 }
543 var parts = str.split('.');
544 var tld = parts[parts.length - 1];
545 if (options.require_tld) {
546 // disallow fqdns without tld
547 if (parts.length < 2) {
548 return false;
549 }
550 if (!options.allow_numeric_tld && !/^([a-z\u00A1-\u00A8\u00AA-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{2,}|xn[a-z0-9-]{2,})$/i.test(tld)) {
551 return false;
552 }
553
554 // disallow spaces
555 if (/\s/.test(tld)) {
556 return false;
557 }
558 }
559
560 // reject numeric TLDs
561 if (!options.allow_numeric_tld && /^\d+$/.test(tld)) {
562 return false;
563 }
564 return parts.every(function (part) {
565 if (part.length > 63 && !options.ignore_max_length) {
566 return false;
567 }
568 if (!/^[a-z_\u00a1-\uffff0-9-]+$/i.test(part)) {
569 return false;
570 }
571
572 // disallow full-width chars
573 if (/[\uff01-\uff5e]/.test(part)) {
574 return false;
575 }
576
577 // disallow parts starting or ending with hyphen
578 if (/^-|-$/.test(part)) {
579 return false;
580 }
581 if (!options.allow_underscores && /_/.test(part)) {
582 return false;
583 }
584 return true;
585 });
586}
587
588/**
58911.3. Examples
590
591 The following addresses
592
593 fe80::1234 (on the 1st link of the node)
594 ff02::5678 (on the 5th link of the node)
595 ff08::9abc (on the 10th organization of the node)
596
597 would be represented as follows:
598
599 fe80::1234%1
600 ff02::5678%5
601 ff08::9abc%10
602
603 (Here we assume a natural translation from a zone index to the
604 <zone_id> part, where the Nth zone of any scope is translated into
605 "N".)
606
607 If we use interface names as <zone_id>, those addresses could also be
608 represented as follows:
609
610 fe80::1234%ne0
611 ff02::5678%pvc1.3
612 ff08::9abc%interface10
613
614 where the interface "ne0" belongs to the 1st link, "pvc1.3" belongs
615 to the 5th link, and "interface10" belongs to the 10th organization.
616 * * */
617var IPv4SegmentFormat = '(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])';
618var IPv4AddressFormat = "(".concat(IPv4SegmentFormat, "[.]){3}").concat(IPv4SegmentFormat);
619var IPv4AddressRegExp = new RegExp("^".concat(IPv4AddressFormat, "$"));
620var IPv6SegmentFormat = '(?:[0-9a-fA-F]{1,4})';
621var IPv6AddressRegExp = new RegExp('^(' + "(?:".concat(IPv6SegmentFormat, ":){7}(?:").concat(IPv6SegmentFormat, "|:)|") + "(?:".concat(IPv6SegmentFormat, ":){6}(?:").concat(IPv4AddressFormat, "|:").concat(IPv6SegmentFormat, "|:)|") + "(?:".concat(IPv6SegmentFormat, ":){5}(?::").concat(IPv4AddressFormat, "|(:").concat(IPv6SegmentFormat, "){1,2}|:)|") + "(?:".concat(IPv6SegmentFormat, ":){4}(?:(:").concat(IPv6SegmentFormat, "){0,1}:").concat(IPv4AddressFormat, "|(:").concat(IPv6SegmentFormat, "){1,3}|:)|") + "(?:".concat(IPv6SegmentFormat, ":){3}(?:(:").concat(IPv6SegmentFormat, "){0,2}:").concat(IPv4AddressFormat, "|(:").concat(IPv6SegmentFormat, "){1,4}|:)|") + "(?:".concat(IPv6SegmentFormat, ":){2}(?:(:").concat(IPv6SegmentFormat, "){0,3}:").concat(IPv4AddressFormat, "|(:").concat(IPv6SegmentFormat, "){1,5}|:)|") + "(?:".concat(IPv6SegmentFormat, ":){1}(?:(:").concat(IPv6SegmentFormat, "){0,4}:").concat(IPv4AddressFormat, "|(:").concat(IPv6SegmentFormat, "){1,6}|:)|") + "(?::((?::".concat(IPv6SegmentFormat, "){0,5}:").concat(IPv4AddressFormat, "|(?::").concat(IPv6SegmentFormat, "){1,7}|:))") + ')(%[0-9a-zA-Z-.:]{1,})?$');
622function isIP(str) {
623 var version = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
624 assertString(str);
625 version = String(version);
626 if (!version) {
627 return isIP(str, 4) || isIP(str, 6);
628 }
629 if (version === '4') {
630 return IPv4AddressRegExp.test(str);
631 }
632 if (version === '6') {
633 return IPv6AddressRegExp.test(str);
634 }
635 return false;
636}
637
638var default_email_options = {
639 allow_display_name: false,
640 allow_underscores: false,
641 require_display_name: false,
642 allow_utf8_local_part: true,
643 require_tld: true,
644 blacklisted_chars: '',
645 ignore_max_length: false,
646 host_blacklist: [],
647 host_whitelist: []
648};
649
650/* eslint-disable max-len */
651/* eslint-disable no-control-regex */
652var splitNameAddress = /^([^\x00-\x1F\x7F-\x9F\cX]+)</i;
653var emailUserPart = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~]+$/i;
654var gmailUserPart = /^[a-z\d]+$/;
655var quotedEmailUser = /^([\s\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e]|(\\[\x01-\x09\x0b\x0c\x0d-\x7f]))*$/i;
656var emailUserUtf8Part = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\u00A1-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+$/i;
657var quotedEmailUserUtf8 = /^([\s\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|(\\[\x01-\x09\x0b\x0c\x0d-\x7f\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))*$/i;
658var defaultMaxEmailLength = 254;
659/* eslint-enable max-len */
660/* eslint-enable no-control-regex */
661
662/**
663 * Validate display name according to the RFC2822: https://tools.ietf.org/html/rfc2822#appendix-A.1.2
664 * @param {String} display_name
665 */
666function validateDisplayName(display_name) {
667 var display_name_without_quotes = display_name.replace(/^"(.+)"$/, '$1');
668 // display name with only spaces is not valid
669 if (!display_name_without_quotes.trim()) {
670 return false;
671 }
672
673 // check whether display name contains illegal character
674 var contains_illegal = /[\.";<>]/.test(display_name_without_quotes);
675 if (contains_illegal) {
676 // if contains illegal characters,
677 // must to be enclosed in double-quotes, otherwise it's not a valid display name
678 if (display_name_without_quotes === display_name) {
679 return false;
680 }
681
682 // the quotes in display name must start with character symbol \
683 var all_start_with_back_slash = display_name_without_quotes.split('"').length === display_name_without_quotes.split('\\"').length;
684 if (!all_start_with_back_slash) {
685 return false;
686 }
687 }
688 return true;
689}
690function isEmail(str, options) {
691 assertString(str);
692 options = merge(options, default_email_options);
693 if (options.require_display_name || options.allow_display_name) {
694 var display_email = str.match(splitNameAddress);
695 if (display_email) {
696 var display_name = display_email[1];
697
698 // Remove display name and angle brackets to get email address
699 // Can be done in the regex but will introduce a ReDOS (See #1597 for more info)
700 str = str.replace(display_name, '').replace(/(^<|>$)/g, '');
701
702 // sometimes need to trim the last space to get the display name
703 // because there may be a space between display name and email address
704 // eg. myname <address@gmail.com>
705 // the display name is `myname` instead of `myname `, so need to trim the last space
706 if (display_name.endsWith(' ')) {
707 display_name = display_name.slice(0, -1);
708 }
709 if (!validateDisplayName(display_name)) {
710 return false;
711 }
712 } else if (options.require_display_name) {
713 return false;
714 }
715 }
716 if (!options.ignore_max_length && str.length > defaultMaxEmailLength) {
717 return false;
718 }
719 var parts = str.split('@');
720 var domain = parts.pop();
721 var lower_domain = domain.toLowerCase();
722 if (options.host_blacklist.includes(lower_domain)) {
723 return false;
724 }
725 if (options.host_whitelist.length > 0 && !options.host_whitelist.includes(lower_domain)) {
726 return false;
727 }
728 var user = parts.join('@');
729 if (options.domain_specific_validation && (lower_domain === 'gmail.com' || lower_domain === 'googlemail.com')) {
730 /*
731 Previously we removed dots for gmail addresses before validating.
732 This was removed because it allows `multiple..dots@gmail.com`
733 to be reported as valid, but it is not.
734 Gmail only normalizes single dots, removing them from here is pointless,
735 should be done in normalizeEmail
736 */
737 user = user.toLowerCase();
738
739 // Removing sub-address from username before gmail validation
740 var username = user.split('+')[0];
741
742 // Dots are not included in gmail length restriction
743 if (!isByteLength(username.replace(/\./g, ''), {
744 min: 6,
745 max: 30
746 })) {
747 return false;
748 }
749 var _user_parts = username.split('.');
750 for (var i = 0; i < _user_parts.length; i++) {
751 if (!gmailUserPart.test(_user_parts[i])) {
752 return false;
753 }
754 }
755 }
756 if (options.ignore_max_length === false && (!isByteLength(user, {
757 max: 64
758 }) || !isByteLength(domain, {
759 max: 254
760 }))) {
761 return false;
762 }
763 if (!isFQDN(domain, {
764 require_tld: options.require_tld,
765 ignore_max_length: options.ignore_max_length,
766 allow_underscores: options.allow_underscores
767 })) {
768 if (!options.allow_ip_domain) {
769 return false;
770 }
771 if (!isIP(domain)) {
772 if (!domain.startsWith('[') || !domain.endsWith(']')) {
773 return false;
774 }
775 var noBracketdomain = domain.slice(1, -1);
776 if (noBracketdomain.length === 0 || !isIP(noBracketdomain)) {
777 return false;
778 }
779 }
780 }
781 if (user[0] === '"') {
782 user = user.slice(1, user.length - 1);
783 return options.allow_utf8_local_part ? quotedEmailUserUtf8.test(user) : quotedEmailUser.test(user);
784 }
785 var pattern = options.allow_utf8_local_part ? emailUserUtf8Part : emailUserPart;
786 var user_parts = user.split('.');
787 for (var _i = 0; _i < user_parts.length; _i++) {
788 if (!pattern.test(user_parts[_i])) {
789 return false;
790 }
791 }
792 if (options.blacklisted_chars) {
793 if (user.search(new RegExp("[".concat(options.blacklisted_chars, "]+"), 'g')) !== -1) return false;
794 }
795 return true;
796}
797
798/*
799options for isURL method
800
801require_protocol - if set as true isURL will return false if protocol is not present in the URL
802require_valid_protocol - isURL will check if the URL's protocol is present in the protocols option
803protocols - valid protocols can be modified with this option
804require_host - if set as false isURL will not check if host is present in the URL
805require_port - if set as true isURL will check if port is present in the URL
806allow_protocol_relative_urls - if set as true protocol relative URLs will be allowed
807validate_length - if set as false isURL will skip string length validation (IE maximum is 2083)
808
809*/
810
811var default_url_options = {
812 protocols: ['http', 'https', 'ftp'],
813 require_tld: true,
814 require_protocol: false,
815 require_host: true,
816 require_port: false,
817 require_valid_protocol: true,
818 allow_underscores: false,
819 allow_trailing_dot: false,
820 allow_protocol_relative_urls: false,
821 allow_fragments: true,
822 allow_query_components: true,
823 validate_length: true
824};
825var wrapped_ipv6 = /^\[([^\]]+)\](?::([0-9]+))?$/;
826function isRegExp(obj) {
827 return Object.prototype.toString.call(obj) === '[object RegExp]';
828}
829function checkHost(host, matches) {
830 for (var i = 0; i < matches.length; i++) {
831 var match = matches[i];
832 if (host === match || isRegExp(match) && match.test(host)) {
833 return true;
834 }
835 }
836 return false;
837}
838function isURL(url, options) {
839 assertString(url);
840 if (!url || /[\s<>]/.test(url)) {
841 return false;
842 }
843 if (url.indexOf('mailto:') === 0) {
844 return false;
845 }
846 options = merge(options, default_url_options);
847 if (options.validate_length && url.length >= 2083) {
848 return false;
849 }
850 if (!options.allow_fragments && url.includes('#')) {
851 return false;
852 }
853 if (!options.allow_query_components && (url.includes('?') || url.includes('&'))) {
854 return false;
855 }
856 var protocol, auth, host, hostname, port, port_str, split, ipv6;
857 split = url.split('#');
858 url = split.shift();
859 split = url.split('?');
860 url = split.shift();
861 split = url.split('://');
862 if (split.length > 1) {
863 protocol = split.shift().toLowerCase();
864 if (options.require_valid_protocol && options.protocols.indexOf(protocol) === -1) {
865 return false;
866 }
867 } else if (options.require_protocol) {
868 return false;
869 } else if (url.slice(0, 2) === '//') {
870 if (!options.allow_protocol_relative_urls) {
871 return false;
872 }
873 split[0] = url.slice(2);
874 }
875 url = split.join('://');
876 if (url === '') {
877 return false;
878 }
879 split = url.split('/');
880 url = split.shift();
881 if (url === '' && !options.require_host) {
882 return true;
883 }
884 split = url.split('@');
885 if (split.length > 1) {
886 if (options.disallow_auth) {
887 return false;
888 }
889 if (split[0] === '') {
890 return false;
891 }
892 auth = split.shift();
893 if (auth.indexOf(':') >= 0 && auth.split(':').length > 2) {
894 return false;
895 }
896 var _auth$split = auth.split(':'),
897 _auth$split2 = _slicedToArray(_auth$split, 2),
898 user = _auth$split2[0],
899 password = _auth$split2[1];
900 if (user === '' && password === '') {
901 return false;
902 }
903 }
904 hostname = split.join('@');
905 port_str = null;
906 ipv6 = null;
907 var ipv6_match = hostname.match(wrapped_ipv6);
908 if (ipv6_match) {
909 host = '';
910 ipv6 = ipv6_match[1];
911 port_str = ipv6_match[2] || null;
912 } else {
913 split = hostname.split(':');
914 host = split.shift();
915 if (split.length) {
916 port_str = split.join(':');
917 }
918 }
919 if (port_str !== null && port_str.length > 0) {
920 port = parseInt(port_str, 10);
921 if (!/^[0-9]+$/.test(port_str) || port <= 0 || port > 65535) {
922 return false;
923 }
924 } else if (options.require_port) {
925 return false;
926 }
927 if (options.host_whitelist) {
928 return checkHost(host, options.host_whitelist);
929 }
930 if (host === '' && !options.require_host) {
931 return true;
932 }
933 if (!isIP(host) && !isFQDN(host, options) && (!ipv6 || !isIP(ipv6, 6))) {
934 return false;
935 }
936 host = host || ipv6;
937 if (options.host_blacklist && checkHost(host, options.host_blacklist)) {
938 return false;
939 }
940 return true;
941}
942
943var macAddress48 = /^(?:[0-9a-fA-F]{2}([-:\s]))([0-9a-fA-F]{2}\1){4}([0-9a-fA-F]{2})$/;
944var macAddress48NoSeparators = /^([0-9a-fA-F]){12}$/;
945var macAddress48WithDots = /^([0-9a-fA-F]{4}\.){2}([0-9a-fA-F]{4})$/;
946var macAddress64 = /^(?:[0-9a-fA-F]{2}([-:\s]))([0-9a-fA-F]{2}\1){6}([0-9a-fA-F]{2})$/;
947var macAddress64NoSeparators = /^([0-9a-fA-F]){16}$/;
948var macAddress64WithDots = /^([0-9a-fA-F]{4}\.){3}([0-9a-fA-F]{4})$/;
949function isMACAddress(str, options) {
950 assertString(str);
951 if (options !== null && options !== void 0 && options.eui) {
952 options.eui = String(options.eui);
953 }
954 /**
955 * @deprecated `no_colons` TODO: remove it in the next major
956 */
957 if (options !== null && options !== void 0 && options.no_colons || options !== null && options !== void 0 && options.no_separators) {
958 if (options.eui === '48') {
959 return macAddress48NoSeparators.test(str);
960 }
961 if (options.eui === '64') {
962 return macAddress64NoSeparators.test(str);
963 }
964 return macAddress48NoSeparators.test(str) || macAddress64NoSeparators.test(str);
965 }
966 if ((options === null || options === void 0 ? void 0 : options.eui) === '48') {
967 return macAddress48.test(str) || macAddress48WithDots.test(str);
968 }
969 if ((options === null || options === void 0 ? void 0 : options.eui) === '64') {
970 return macAddress64.test(str) || macAddress64WithDots.test(str);
971 }
972 return isMACAddress(str, {
973 eui: '48'
974 }) || isMACAddress(str, {
975 eui: '64'
976 });
977}
978
979var subnetMaybe = /^\d{1,3}$/;
980var v4Subnet = 32;
981var v6Subnet = 128;
982function isIPRange(str) {
983 var version = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
984 assertString(str);
985 var parts = str.split('/');
986
987 // parts[0] -> ip, parts[1] -> subnet
988 if (parts.length !== 2) {
989 return false;
990 }
991 if (!subnetMaybe.test(parts[1])) {
992 return false;
993 }
994
995 // Disallow preceding 0 i.e. 01, 02, ...
996 if (parts[1].length > 1 && parts[1].startsWith('0')) {
997 return false;
998 }
999 var isValidIP = isIP(parts[0], version);
1000 if (!isValidIP) {
1001 return false;
1002 }
1003
1004 // Define valid subnet according to IP's version
1005 var expectedSubnet = null;
1006 switch (String(version)) {
1007 case '4':
1008 expectedSubnet = v4Subnet;
1009 break;
1010 case '6':
1011 expectedSubnet = v6Subnet;
1012 break;
1013 default:
1014 expectedSubnet = isIP(parts[0], '6') ? v6Subnet : v4Subnet;
1015 }
1016 return parts[1] <= expectedSubnet && parts[1] >= 0;
1017}
1018
1019var default_date_options = {
1020 format: 'YYYY/MM/DD',
1021 delimiters: ['/', '-'],
1022 strictMode: false
1023};
1024function isValidFormat(format) {
1025 return /(^(y{4}|y{2})[.\/-](m{1,2})[.\/-](d{1,2})$)|(^(m{1,2})[.\/-](d{1,2})[.\/-]((y{4}|y{2})$))|(^(d{1,2})[.\/-](m{1,2})[.\/-]((y{4}|y{2})$))/gi.test(format);
1026}
1027function zip(date, format) {
1028 var zippedArr = [],
1029 len = Math.min(date.length, format.length);
1030 for (var i = 0; i < len; i++) {
1031 zippedArr.push([date[i], format[i]]);
1032 }
1033 return zippedArr;
1034}
1035function isDate(input, options) {
1036 if (typeof options === 'string') {
1037 // Allow backward compatibility for old format isDate(input [, format])
1038 options = merge({
1039 format: options
1040 }, default_date_options);
1041 } else {
1042 options = merge(options, default_date_options);
1043 }
1044 if (typeof input === 'string' && isValidFormat(options.format)) {
1045 var formatDelimiter = options.delimiters.find(function (delimiter) {
1046 return options.format.indexOf(delimiter) !== -1;
1047 });
1048 var dateDelimiter = options.strictMode ? formatDelimiter : options.delimiters.find(function (delimiter) {
1049 return input.indexOf(delimiter) !== -1;
1050 });
1051 var dateAndFormat = zip(input.split(dateDelimiter), options.format.toLowerCase().split(formatDelimiter));
1052 var dateObj = {};
1053 var _iterator = _createForOfIteratorHelper(dateAndFormat),
1054 _step;
1055 try {
1056 for (_iterator.s(); !(_step = _iterator.n()).done;) {
1057 var _step$value = _slicedToArray(_step.value, 2),
1058 dateWord = _step$value[0],
1059 formatWord = _step$value[1];
1060 if (dateWord.length !== formatWord.length) {
1061 return false;
1062 }
1063 dateObj[formatWord.charAt(0)] = dateWord;
1064 }
1065 } catch (err) {
1066 _iterator.e(err);
1067 } finally {
1068 _iterator.f();
1069 }
1070 var fullYear = dateObj.y;
1071
1072 // Check if the year starts with a hyphen
1073 if (fullYear.startsWith('-')) {
1074 return false; // Hyphen before year is not allowed
1075 }
1076 if (dateObj.y.length === 2) {
1077 var parsedYear = parseInt(dateObj.y, 10);
1078 if (isNaN(parsedYear)) {
1079 return false;
1080 }
1081 var currentYearLastTwoDigits = new Date().getFullYear() % 100;
1082 if (parsedYear < currentYearLastTwoDigits) {
1083 fullYear = "20".concat(dateObj.y);
1084 } else {
1085 fullYear = "19".concat(dateObj.y);
1086 }
1087 }
1088 var month = dateObj.m;
1089 if (dateObj.m.length === 1) {
1090 month = "0".concat(dateObj.m);
1091 }
1092 var day = dateObj.d;
1093 if (dateObj.d.length === 1) {
1094 day = "0".concat(dateObj.d);
1095 }
1096 return new Date("".concat(fullYear, "-").concat(month, "-").concat(day, "T00:00:00.000Z")).getUTCDate() === +dateObj.d;
1097 }
1098 if (!options.strictMode) {
1099 return Object.prototype.toString.call(input) === '[object Date]' && isFinite(input);
1100 }
1101 return false;
1102}
1103
1104var default_time_options = {
1105 hourFormat: 'hour24',
1106 mode: 'default'
1107};
1108var formats = {
1109 hour24: {
1110 "default": /^([01]?[0-9]|2[0-3]):([0-5][0-9])$/,
1111 withSeconds: /^([01]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$/
1112 },
1113 hour12: {
1114 "default": /^(0?[1-9]|1[0-2]):([0-5][0-9]) (A|P)M$/,
1115 withSeconds: /^(0?[1-9]|1[0-2]):([0-5][0-9]):([0-5][0-9]) (A|P)M$/
1116 }
1117};
1118function isTime(input, options) {
1119 options = merge(options, default_time_options);
1120 if (typeof input !== 'string') return false;
1121 return formats[options.hourFormat][options.mode].test(input);
1122}
1123
1124var defaultOptions = {
1125 loose: false
1126};
1127var strictBooleans = ['true', 'false', '1', '0'];
1128var looseBooleans = [].concat(strictBooleans, ['yes', 'no']);
1129function isBoolean(str) {
1130 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultOptions;
1131 assertString(str);
1132 if (options.loose) {
1133 return looseBooleans.includes(str.toLowerCase());
1134 }
1135 return strictBooleans.includes(str);
1136}
1137
1138/*
1139 = 3ALPHA ; selected ISO 639 codes
1140 *2("-" 3ALPHA) ; permanently reserved
1141 */
1142var extlang = '([A-Za-z]{3}(-[A-Za-z]{3}){0,2})';
1143
1144/*
1145 = 2*3ALPHA ; shortest ISO 639 code
1146 ["-" extlang] ; sometimes followed by
1147 ; extended language subtags
1148 / 4ALPHA ; or reserved for future use
1149 / 5*8ALPHA ; or registered language subtag
1150 */
1151var language = "(([a-zA-Z]{2,3}(-".concat(extlang, ")?)|([a-zA-Z]{5,8}))");
1152
1153/*
1154 = 4ALPHA ; ISO 15924 code
1155 */
1156var script = '([A-Za-z]{4})';
1157
1158/*
1159 = 2ALPHA ; ISO 3166-1 code
1160 / 3DIGIT ; UN M.49 code
1161 */
1162var region = '([A-Za-z]{2}|\\d{3})';
1163
1164/*
1165 = 5*8alphanum ; registered variants
1166 / (DIGIT 3alphanum)
1167 */
1168var variant = '([A-Za-z0-9]{5,8}|(\\d[A-Z-a-z0-9]{3}))';
1169
1170/*
1171 = DIGIT ; 0 - 9
1172 / %x41-57 ; A - W
1173 / %x59-5A ; Y - Z
1174 / %x61-77 ; a - w
1175 / %x79-7A ; y - z
1176 */
1177var singleton = '(\\d|[A-W]|[Y-Z]|[a-w]|[y-z])';
1178
1179/*
1180 = singleton 1*("-" (2*8alphanum))
1181 ; Single alphanumerics
1182 ; "x" reserved for private use
1183 */
1184var extension = "(".concat(singleton, "(-[A-Za-z0-9]{2,8})+)");
1185
1186/*
1187 = "x" 1*("-" (1*8alphanum))
1188 */
1189var privateuse = '(x(-[A-Za-z0-9]{1,8})+)';
1190
1191// irregular tags do not match the 'langtag' production and would not
1192// otherwise be considered 'well-formed'. These tags are all valid, but
1193// most are deprecated in favor of more modern subtags or subtag combination
1194
1195var irregular = '((en-GB-oed)|(i-ami)|(i-bnn)|(i-default)|(i-enochian)|' + '(i-hak)|(i-klingon)|(i-lux)|(i-mingo)|(i-navajo)|(i-pwn)|(i-tao)|' + '(i-tay)|(i-tsu)|(sgn-BE-FR)|(sgn-BE-NL)|(sgn-CH-DE))';
1196
1197// regular tags match the 'langtag' production, but their subtags are not
1198// extended language or variant subtags: their meaning is defined by
1199// their registration and all of these are deprecated in favor of a more
1200// modern subtag or sequence of subtags
1201
1202var regular = '((art-lojban)|(cel-gaulish)|(no-bok)|(no-nyn)|(zh-guoyu)|' + '(zh-hakka)|(zh-min)|(zh-min-nan)|(zh-xiang))';
1203
1204/*
1205 = irregular ; non-redundant tags registered
1206 / regular ; during the RFC 3066 era
1207
1208 */
1209var grandfathered = "(".concat(irregular, "|").concat(regular, ")");
1210
1211/*
1212 RFC 5646 defines delimitation of subtags via a hyphen:
1213
1214 "Subtag" refers to a specific section of a tag, delimited by a
1215 hyphen, such as the subtags 'zh', 'Hant', and 'CN' in the tag "zh-
1216 Hant-CN". Examples of subtags in this document are enclosed in
1217 single quotes ('Hant')
1218
1219 However, we need to add "_" to maintain the existing behaviour.
1220 */
1221var delimiter = '(-|_)';
1222
1223/*
1224 = language
1225 ["-" script]
1226 ["-" region]
1227 *("-" variant)
1228 *("-" extension)
1229 ["-" privateuse]
1230 */
1231var langtag = "".concat(language, "(").concat(delimiter).concat(script, ")?(").concat(delimiter).concat(region, ")?(").concat(delimiter).concat(variant, ")*(").concat(delimiter).concat(extension, ")*(").concat(delimiter).concat(privateuse, ")?");
1232
1233/*
1234 Regex implementation based on BCP RFC 5646
1235 Tags for Identifying Languages
1236 https://www.rfc-editor.org/rfc/rfc5646.html
1237 */
1238var languageTagRegex = new RegExp("(^".concat(privateuse, "$)|(^").concat(grandfathered, "$)|(^").concat(langtag, "$)"));
1239function isLocale(str) {
1240 assertString(str);
1241 return languageTagRegex.test(str);
1242}
1243
1244// http://www.brainjar.com/js/validation/
1245// https://www.aba.com/news-research/research-analysis/routing-number-policy-procedures
1246// series reserved for future use are excluded
1247var isRoutingReg = /^(?!(1[3-9])|(20)|(3[3-9])|(4[0-9])|(5[0-9])|(60)|(7[3-9])|(8[1-9])|(9[0-2])|(9[3-9]))[0-9]{9}$/;
1248function isAbaRouting(str) {
1249 assertString(str);
1250 if (!isRoutingReg.test(str)) return false;
1251 var checkSumVal = 0;
1252 for (var i = 0; i < str.length; i++) {
1253 if (i % 3 === 0) checkSumVal += str[i] * 3;else if (i % 3 === 1) checkSumVal += str[i] * 7;else checkSumVal += str[i] * 1;
1254 }
1255 return checkSumVal % 10 === 0;
1256}
1257
1258function isAlpha(_str) {
1259 var locale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'en-US';
1260 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1261 assertString(_str);
1262 var str = _str;
1263 var ignore = options.ignore;
1264 if (ignore) {
1265 if (ignore instanceof RegExp) {
1266 str = str.replace(ignore, '');
1267 } else if (typeof ignore === 'string') {
1268 str = str.replace(new RegExp("[".concat(ignore.replace(/[-[\]{}()*+?.,\\^$|#\\s]/g, '\\$&'), "]"), 'g'), ''); // escape regex for ignore
1269 } else {
1270 throw new Error('ignore should be instance of a String or RegExp');
1271 }
1272 }
1273 if (locale in alpha) {
1274 return alpha[locale].test(str);
1275 }
1276 throw new Error("Invalid locale '".concat(locale, "'"));
1277}
1278var locales$1 = Object.keys(alpha);
1279
1280function isAlphanumeric(_str) {
1281 var locale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'en-US';
1282 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1283 assertString(_str);
1284 var str = _str;
1285 var ignore = options.ignore;
1286 if (ignore) {
1287 if (ignore instanceof RegExp) {
1288 str = str.replace(ignore, '');
1289 } else if (typeof ignore === 'string') {
1290 str = str.replace(new RegExp("[".concat(ignore.replace(/[-[\]{}()*+?.,\\^$|#\\s]/g, '\\$&'), "]"), 'g'), ''); // escape regex for ignore
1291 } else {
1292 throw new Error('ignore should be instance of a String or RegExp');
1293 }
1294 }
1295 if (locale in alphanumeric) {
1296 return alphanumeric[locale].test(str);
1297 }
1298 throw new Error("Invalid locale '".concat(locale, "'"));
1299}
1300var locales$2 = Object.keys(alphanumeric);
1301
1302var numericNoSymbols = /^[0-9]+$/;
1303function isNumeric(str, options) {
1304 assertString(str);
1305 if (options && options.no_symbols) {
1306 return numericNoSymbols.test(str);
1307 }
1308 return new RegExp("^[+-]?([0-9]*[".concat((options || {}).locale ? decimal[options.locale] : '.', "])?[0-9]+$")).test(str);
1309}
1310
1311/**
1312 * Reference:
1313 * https://en.wikipedia.org/ -- Wikipedia
1314 * https://docs.microsoft.com/en-us/microsoft-365/compliance/eu-passport-number -- EU Passport Number
1315 * https://countrycode.org/ -- Country Codes
1316 */
1317var passportRegexByCountryCode = {
1318 AM: /^[A-Z]{2}\d{7}$/,
1319 // ARMENIA
1320 AR: /^[A-Z]{3}\d{6}$/,
1321 // ARGENTINA
1322 AT: /^[A-Z]\d{7}$/,
1323 // AUSTRIA
1324 AU: /^[A-Z]\d{7}$/,
1325 // AUSTRALIA
1326 AZ: /^[A-Z]{1}\d{8}$/,
1327 // AZERBAIJAN
1328 BE: /^[A-Z]{2}\d{6}$/,
1329 // BELGIUM
1330 BG: /^\d{9}$/,
1331 // BULGARIA
1332 BR: /^[A-Z]{2}\d{6}$/,
1333 // BRAZIL
1334 BY: /^[A-Z]{2}\d{7}$/,
1335 // BELARUS
1336 CA: /^[A-Z]{2}\d{6}$/,
1337 // CANADA
1338 CH: /^[A-Z]\d{7}$/,
1339 // SWITZERLAND
1340 CN: /^G\d{8}$|^E(?![IO])[A-Z0-9]\d{7}$/,
1341 // CHINA [G=Ordinary, E=Electronic] followed by 8-digits, or E followed by any UPPERCASE letter (except I and O) followed by 7 digits
1342 CY: /^[A-Z](\d{6}|\d{8})$/,
1343 // CYPRUS
1344 CZ: /^\d{8}$/,
1345 // CZECH REPUBLIC
1346 DE: /^[CFGHJKLMNPRTVWXYZ0-9]{9}$/,
1347 // GERMANY
1348 DK: /^\d{9}$/,
1349 // DENMARK
1350 DZ: /^\d{9}$/,
1351 // ALGERIA
1352 EE: /^([A-Z]\d{7}|[A-Z]{2}\d{7})$/,
1353 // ESTONIA (K followed by 7-digits), e-passports have 2 UPPERCASE followed by 7 digits
1354 ES: /^[A-Z0-9]{2}([A-Z0-9]?)\d{6}$/,
1355 // SPAIN
1356 FI: /^[A-Z]{2}\d{7}$/,
1357 // FINLAND
1358 FR: /^\d{2}[A-Z]{2}\d{5}$/,
1359 // FRANCE
1360 GB: /^\d{9}$/,
1361 // UNITED KINGDOM
1362 GR: /^[A-Z]{2}\d{7}$/,
1363 // GREECE
1364 HR: /^\d{9}$/,
1365 // CROATIA
1366 HU: /^[A-Z]{2}(\d{6}|\d{7})$/,
1367 // HUNGARY
1368 IE: /^[A-Z0-9]{2}\d{7}$/,
1369 // IRELAND
1370 IN: /^[A-Z]{1}-?\d{7}$/,
1371 // INDIA
1372 ID: /^[A-C]\d{7}$/,
1373 // INDONESIA
1374 IR: /^[A-Z]\d{8}$/,
1375 // IRAN
1376 IS: /^(A)\d{7}$/,
1377 // ICELAND
1378 IT: /^[A-Z0-9]{2}\d{7}$/,
1379 // ITALY
1380 JM: /^[Aa]\d{7}$/,
1381 // JAMAICA
1382 JP: /^[A-Z]{2}\d{7}$/,
1383 // JAPAN
1384 KR: /^[MS]\d{8}$/,
1385 // SOUTH KOREA, REPUBLIC OF KOREA, [S=PS Passports, M=PM Passports]
1386 KZ: /^[a-zA-Z]\d{7}$/,
1387 // KAZAKHSTAN
1388 LI: /^[a-zA-Z]\d{5}$/,
1389 // LIECHTENSTEIN
1390 LT: /^[A-Z0-9]{8}$/,
1391 // LITHUANIA
1392 LU: /^[A-Z0-9]{8}$/,
1393 // LUXEMBURG
1394 LV: /^[A-Z0-9]{2}\d{7}$/,
1395 // LATVIA
1396 LY: /^[A-Z0-9]{8}$/,
1397 // LIBYA
1398 MT: /^\d{7}$/,
1399 // MALTA
1400 MZ: /^([A-Z]{2}\d{7})|(\d{2}[A-Z]{2}\d{5})$/,
1401 // MOZAMBIQUE
1402 MY: /^[AHK]\d{8}$/,
1403 // MALAYSIA
1404 MX: /^\d{10,11}$/,
1405 // MEXICO
1406 NL: /^[A-Z]{2}[A-Z0-9]{6}\d$/,
1407 // NETHERLANDS
1408 NZ: /^([Ll]([Aa]|[Dd]|[Ff]|[Hh])|[Ee]([Aa]|[Pp])|[Nn])\d{6}$/,
1409 // NEW ZEALAND
1410 PH: /^([A-Z](\d{6}|\d{7}[A-Z]))|([A-Z]{2}(\d{6}|\d{7}))$/,
1411 // PHILIPPINES
1412 PK: /^[A-Z]{2}\d{7}$/,
1413 // PAKISTAN
1414 PL: /^[A-Z]{2}\d{7}$/,
1415 // POLAND
1416 PT: /^[A-Z]\d{6}$/,
1417 // PORTUGAL
1418 RO: /^\d{8,9}$/,
1419 // ROMANIA
1420 RU: /^\d{9}$/,
1421 // RUSSIAN FEDERATION
1422 SE: /^\d{8}$/,
1423 // SWEDEN
1424 SL: /^(P)[A-Z]\d{7}$/,
1425 // SLOVENIA
1426 SK: /^[0-9A-Z]\d{7}$/,
1427 // SLOVAKIA
1428 TH: /^[A-Z]{1,2}\d{6,7}$/,
1429 // THAILAND
1430 TR: /^[A-Z]\d{8}$/,
1431 // TURKEY
1432 UA: /^[A-Z]{2}\d{6}$/,
1433 // UKRAINE
1434 US: /^\d{9}$/,
1435 // UNITED STATES
1436 ZA: /^[TAMD]\d{8}$/ // SOUTH AFRICA
1437};
1438
1439/**
1440 * Check if str is a valid passport number
1441 * relative to provided ISO Country Code.
1442 *
1443 * @param {string} str
1444 * @param {string} countryCode
1445 * @return {boolean}
1446 */
1447function isPassportNumber(str, countryCode) {
1448 assertString(str);
1449 /** Remove All Whitespaces, Convert to UPPERCASE */
1450 var normalizedStr = str.replace(/\s/g, '').toUpperCase();
1451 return countryCode.toUpperCase() in passportRegexByCountryCode && passportRegexByCountryCode[countryCode].test(normalizedStr);
1452}
1453
1454var _int = /^(?:[-+]?(?:0|[1-9][0-9]*))$/;
1455var intLeadingZeroes = /^[-+]?[0-9]+$/;
1456function isInt(str, options) {
1457 assertString(str);
1458 options = options || {};
1459
1460 // Get the regex to use for testing, based on whether
1461 // leading zeroes are allowed or not.
1462 var regex = options.allow_leading_zeroes === false ? _int : intLeadingZeroes;
1463
1464 // Check min/max/lt/gt
1465 var minCheckPassed = !options.hasOwnProperty('min') || str >= options.min;
1466 var maxCheckPassed = !options.hasOwnProperty('max') || str <= options.max;
1467 var ltCheckPassed = !options.hasOwnProperty('lt') || str < options.lt;
1468 var gtCheckPassed = !options.hasOwnProperty('gt') || str > options.gt;
1469 return regex.test(str) && minCheckPassed && maxCheckPassed && ltCheckPassed && gtCheckPassed;
1470}
1471
1472function isPort(str) {
1473 return isInt(str, {
1474 allow_leading_zeroes: false,
1475 min: 0,
1476 max: 65535
1477 });
1478}
1479
1480function isLowercase(str) {
1481 assertString(str);
1482 return str === str.toLowerCase();
1483}
1484
1485function isUppercase(str) {
1486 assertString(str);
1487 return str === str.toUpperCase();
1488}
1489
1490var imeiRegexWithoutHypens = /^[0-9]{15}$/;
1491var imeiRegexWithHypens = /^\d{2}-\d{6}-\d{6}-\d{1}$/;
1492function isIMEI(str, options) {
1493 assertString(str);
1494 options = options || {};
1495
1496 // default regex for checking imei is the one without hyphens
1497
1498 var imeiRegex = imeiRegexWithoutHypens;
1499 if (options.allow_hyphens) {
1500 imeiRegex = imeiRegexWithHypens;
1501 }
1502 if (!imeiRegex.test(str)) {
1503 return false;
1504 }
1505 str = str.replace(/-/g, '');
1506 var sum = 0,
1507 mul = 2,
1508 l = 14;
1509 for (var i = 0; i < l; i++) {
1510 var digit = str.substring(l - i - 1, l - i);
1511 var tp = parseInt(digit, 10) * mul;
1512 if (tp >= 10) {
1513 sum += tp % 10 + 1;
1514 } else {
1515 sum += tp;
1516 }
1517 if (mul === 1) {
1518 mul += 1;
1519 } else {
1520 mul -= 1;
1521 }
1522 }
1523 var chk = (10 - sum % 10) % 10;
1524 if (chk !== parseInt(str.substring(14, 15), 10)) {
1525 return false;
1526 }
1527 return true;
1528}
1529
1530/* eslint-disable no-control-regex */
1531var ascii = /^[\x00-\x7F]+$/;
1532/* eslint-enable no-control-regex */
1533
1534function isAscii(str) {
1535 assertString(str);
1536 return ascii.test(str);
1537}
1538
1539var fullWidth = /[^\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]/;
1540function isFullWidth(str) {
1541 assertString(str);
1542 return fullWidth.test(str);
1543}
1544
1545var halfWidth = /[\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]/;
1546function isHalfWidth(str) {
1547 assertString(str);
1548 return halfWidth.test(str);
1549}
1550
1551function isVariableWidth(str) {
1552 assertString(str);
1553 return fullWidth.test(str) && halfWidth.test(str);
1554}
1555
1556/* eslint-disable no-control-regex */
1557var multibyte = /[^\x00-\x7F]/;
1558/* eslint-enable no-control-regex */
1559
1560function isMultibyte(str) {
1561 assertString(str);
1562 return multibyte.test(str);
1563}
1564
1565/**
1566 * Build RegExp object from an array
1567 * of multiple/multi-line regexp parts
1568 *
1569 * @param {string[]} parts
1570 * @param {string} flags
1571 * @return {object} - RegExp object
1572 */
1573function multilineRegexp(parts, flags) {
1574 var regexpAsStringLiteral = parts.join('');
1575 return new RegExp(regexpAsStringLiteral, flags);
1576}
1577
1578/**
1579 * Regular Expression to match
1580 * semantic versioning (SemVer)
1581 * built from multi-line, multi-parts regexp
1582 * Reference: https://semver.org/
1583 */
1584var semanticVersioningRegex = multilineRegexp(['^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)', '(?:-((?:0|[1-9]\\d*|\\d*[a-z-][0-9a-z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-z-][0-9a-z-]*))*))', '?(?:\\+([0-9a-z-]+(?:\\.[0-9a-z-]+)*))?$'], 'i');
1585function isSemVer(str) {
1586 assertString(str);
1587 return semanticVersioningRegex.test(str);
1588}
1589
1590var surrogatePair = /[\uD800-\uDBFF][\uDC00-\uDFFF]/;
1591function isSurrogatePair(str) {
1592 assertString(str);
1593 return surrogatePair.test(str);
1594}
1595
1596var includes = function includes(arr, val) {
1597 return arr.some(function (arrVal) {
1598 return val === arrVal;
1599 });
1600};
1601
1602function decimalRegExp(options) {
1603 var regExp = new RegExp("^[-+]?([0-9]+)?(\\".concat(decimal[options.locale], "[0-9]{").concat(options.decimal_digits, "})").concat(options.force_decimal ? '' : '?', "$"));
1604 return regExp;
1605}
1606var default_decimal_options = {
1607 force_decimal: false,
1608 decimal_digits: '1,',
1609 locale: 'en-US'
1610};
1611var blacklist = ['', '-', '+'];
1612function isDecimal(str, options) {
1613 assertString(str);
1614 options = merge(options, default_decimal_options);
1615 if (options.locale in decimal) {
1616 return !includes(blacklist, str.replace(/ /g, '')) && decimalRegExp(options).test(str);
1617 }
1618 throw new Error("Invalid locale '".concat(options.locale, "'"));
1619}
1620
1621var hexadecimal = /^(0x|0h)?[0-9A-F]+$/i;
1622function isHexadecimal(str) {
1623 assertString(str);
1624 return hexadecimal.test(str);
1625}
1626
1627var octal = /^(0o)?[0-7]+$/i;
1628function isOctal(str) {
1629 assertString(str);
1630 return octal.test(str);
1631}
1632
1633function isDivisibleBy(str, num) {
1634 assertString(str);
1635 return toFloat(str) % parseInt(num, 10) === 0;
1636}
1637
1638var hexcolor = /^#?([0-9A-F]{3}|[0-9A-F]{4}|[0-9A-F]{6}|[0-9A-F]{8})$/i;
1639function isHexColor(str) {
1640 assertString(str);
1641 return hexcolor.test(str);
1642}
1643
1644var rgbColor = /^rgb\((([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]),){2}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\)$/;
1645var rgbaColor = /^rgba\((([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]),){3}(0?\.\d|1(\.0)?|0(\.0)?)\)$/;
1646var rgbColorPercent = /^rgb\((([0-9]%|[1-9][0-9]%|100%),){2}([0-9]%|[1-9][0-9]%|100%)\)$/;
1647var rgbaColorPercent = /^rgba\((([0-9]%|[1-9][0-9]%|100%),){3}(0?\.\d|1(\.0)?|0(\.0)?)\)$/;
1648function isRgbColor(str) {
1649 var includePercentValues = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
1650 assertString(str);
1651 if (!includePercentValues) {
1652 return rgbColor.test(str) || rgbaColor.test(str);
1653 }
1654 return rgbColor.test(str) || rgbaColor.test(str) || rgbColorPercent.test(str) || rgbaColorPercent.test(str);
1655}
1656
1657var hslComma = /^hsla?\(((\+|\-)?([0-9]+(\.[0-9]+)?(e(\+|\-)?[0-9]+)?|\.[0-9]+(e(\+|\-)?[0-9]+)?))(deg|grad|rad|turn)?(,(\+|\-)?([0-9]+(\.[0-9]+)?(e(\+|\-)?[0-9]+)?|\.[0-9]+(e(\+|\-)?[0-9]+)?)%){2}(,((\+|\-)?([0-9]+(\.[0-9]+)?(e(\+|\-)?[0-9]+)?|\.[0-9]+(e(\+|\-)?[0-9]+)?)%?))?\)$/i;
1658var hslSpace = /^hsla?\(((\+|\-)?([0-9]+(\.[0-9]+)?(e(\+|\-)?[0-9]+)?|\.[0-9]+(e(\+|\-)?[0-9]+)?))(deg|grad|rad|turn)?(\s(\+|\-)?([0-9]+(\.[0-9]+)?(e(\+|\-)?[0-9]+)?|\.[0-9]+(e(\+|\-)?[0-9]+)?)%){2}\s?(\/\s((\+|\-)?([0-9]+(\.[0-9]+)?(e(\+|\-)?[0-9]+)?|\.[0-9]+(e(\+|\-)?[0-9]+)?)%?)\s?)?\)$/i;
1659function isHSL(str) {
1660 assertString(str);
1661
1662 // Strip duplicate spaces before calling the validation regex (See #1598 for more info)
1663 var strippedStr = str.replace(/\s+/g, ' ').replace(/\s?(hsla?\(|\)|,)\s?/ig, '$1');
1664 if (strippedStr.indexOf(',') !== -1) {
1665 return hslComma.test(strippedStr);
1666 }
1667 return hslSpace.test(strippedStr);
1668}
1669
1670// see http://isrc.ifpi.org/en/isrc-standard/code-syntax
1671var isrc = /^[A-Z]{2}[0-9A-Z]{3}\d{2}\d{5}$/;
1672function isISRC(str) {
1673 assertString(str);
1674 return isrc.test(str);
1675}
1676
1677/**
1678 * List of country codes with
1679 * corresponding IBAN regular expression
1680 * Reference: https://en.wikipedia.org/wiki/International_Bank_Account_Number
1681 */
1682var ibanRegexThroughCountryCode = {
1683 AD: /^(AD[0-9]{2})\d{8}[A-Z0-9]{12}$/,
1684 AE: /^(AE[0-9]{2})\d{3}\d{16}$/,
1685 AL: /^(AL[0-9]{2})\d{8}[A-Z0-9]{16}$/,
1686 AT: /^(AT[0-9]{2})\d{16}$/,
1687 AZ: /^(AZ[0-9]{2})[A-Z0-9]{4}\d{20}$/,
1688 BA: /^(BA[0-9]{2})\d{16}$/,
1689 BE: /^(BE[0-9]{2})\d{12}$/,
1690 BG: /^(BG[0-9]{2})[A-Z]{4}\d{6}[A-Z0-9]{8}$/,
1691 BH: /^(BH[0-9]{2})[A-Z]{4}[A-Z0-9]{14}$/,
1692 BR: /^(BR[0-9]{2})\d{23}[A-Z]{1}[A-Z0-9]{1}$/,
1693 BY: /^(BY[0-9]{2})[A-Z0-9]{4}\d{20}$/,
1694 CH: /^(CH[0-9]{2})\d{5}[A-Z0-9]{12}$/,
1695 CR: /^(CR[0-9]{2})\d{18}$/,
1696 CY: /^(CY[0-9]{2})\d{8}[A-Z0-9]{16}$/,
1697 CZ: /^(CZ[0-9]{2})\d{20}$/,
1698 DE: /^(DE[0-9]{2})\d{18}$/,
1699 DK: /^(DK[0-9]{2})\d{14}$/,
1700 DO: /^(DO[0-9]{2})[A-Z]{4}\d{20}$/,
1701 DZ: /^(DZ\d{24})$/,
1702 EE: /^(EE[0-9]{2})\d{16}$/,
1703 EG: /^(EG[0-9]{2})\d{25}$/,
1704 ES: /^(ES[0-9]{2})\d{20}$/,
1705 FI: /^(FI[0-9]{2})\d{14}$/,
1706 FO: /^(FO[0-9]{2})\d{14}$/,
1707 FR: /^(FR[0-9]{2})\d{10}[A-Z0-9]{11}\d{2}$/,
1708 GB: /^(GB[0-9]{2})[A-Z]{4}\d{14}$/,
1709 GE: /^(GE[0-9]{2})[A-Z0-9]{2}\d{16}$/,
1710 GI: /^(GI[0-9]{2})[A-Z]{4}[A-Z0-9]{15}$/,
1711 GL: /^(GL[0-9]{2})\d{14}$/,
1712 GR: /^(GR[0-9]{2})\d{7}[A-Z0-9]{16}$/,
1713 GT: /^(GT[0-9]{2})[A-Z0-9]{4}[A-Z0-9]{20}$/,
1714 HR: /^(HR[0-9]{2})\d{17}$/,
1715 HU: /^(HU[0-9]{2})\d{24}$/,
1716 IE: /^(IE[0-9]{2})[A-Z0-9]{4}\d{14}$/,
1717 IL: /^(IL[0-9]{2})\d{19}$/,
1718 IQ: /^(IQ[0-9]{2})[A-Z]{4}\d{15}$/,
1719 IR: /^(IR[0-9]{2})0\d{2}0\d{18}$/,
1720 IS: /^(IS[0-9]{2})\d{22}$/,
1721 IT: /^(IT[0-9]{2})[A-Z]{1}\d{10}[A-Z0-9]{12}$/,
1722 JO: /^(JO[0-9]{2})[A-Z]{4}\d{22}$/,
1723 KW: /^(KW[0-9]{2})[A-Z]{4}[A-Z0-9]{22}$/,
1724 KZ: /^(KZ[0-9]{2})\d{3}[A-Z0-9]{13}$/,
1725 LB: /^(LB[0-9]{2})\d{4}[A-Z0-9]{20}$/,
1726 LC: /^(LC[0-9]{2})[A-Z]{4}[A-Z0-9]{24}$/,
1727 LI: /^(LI[0-9]{2})\d{5}[A-Z0-9]{12}$/,
1728 LT: /^(LT[0-9]{2})\d{16}$/,
1729 LU: /^(LU[0-9]{2})\d{3}[A-Z0-9]{13}$/,
1730 LV: /^(LV[0-9]{2})[A-Z]{4}[A-Z0-9]{13}$/,
1731 MA: /^(MA[0-9]{26})$/,
1732 MC: /^(MC[0-9]{2})\d{10}[A-Z0-9]{11}\d{2}$/,
1733 MD: /^(MD[0-9]{2})[A-Z0-9]{20}$/,
1734 ME: /^(ME[0-9]{2})\d{18}$/,
1735 MK: /^(MK[0-9]{2})\d{3}[A-Z0-9]{10}\d{2}$/,
1736 MR: /^(MR[0-9]{2})\d{23}$/,
1737 MT: /^(MT[0-9]{2})[A-Z]{4}\d{5}[A-Z0-9]{18}$/,
1738 MU: /^(MU[0-9]{2})[A-Z]{4}\d{19}[A-Z]{3}$/,
1739 MZ: /^(MZ[0-9]{2})\d{21}$/,
1740 NL: /^(NL[0-9]{2})[A-Z]{4}\d{10}$/,
1741 NO: /^(NO[0-9]{2})\d{11}$/,
1742 PK: /^(PK[0-9]{2})[A-Z0-9]{4}\d{16}$/,
1743 PL: /^(PL[0-9]{2})\d{24}$/,
1744 PS: /^(PS[0-9]{2})[A-Z0-9]{4}\d{21}$/,
1745 PT: /^(PT[0-9]{2})\d{21}$/,
1746 QA: /^(QA[0-9]{2})[A-Z]{4}[A-Z0-9]{21}$/,
1747 RO: /^(RO[0-9]{2})[A-Z]{4}[A-Z0-9]{16}$/,
1748 RS: /^(RS[0-9]{2})\d{18}$/,
1749 SA: /^(SA[0-9]{2})\d{2}[A-Z0-9]{18}$/,
1750 SC: /^(SC[0-9]{2})[A-Z]{4}\d{20}[A-Z]{3}$/,
1751 SE: /^(SE[0-9]{2})\d{20}$/,
1752 SI: /^(SI[0-9]{2})\d{15}$/,
1753 SK: /^(SK[0-9]{2})\d{20}$/,
1754 SM: /^(SM[0-9]{2})[A-Z]{1}\d{10}[A-Z0-9]{12}$/,
1755 SV: /^(SV[0-9]{2})[A-Z0-9]{4}\d{20}$/,
1756 TL: /^(TL[0-9]{2})\d{19}$/,
1757 TN: /^(TN[0-9]{2})\d{20}$/,
1758 TR: /^(TR[0-9]{2})\d{5}[A-Z0-9]{17}$/,
1759 UA: /^(UA[0-9]{2})\d{6}[A-Z0-9]{19}$/,
1760 VA: /^(VA[0-9]{2})\d{18}$/,
1761 VG: /^(VG[0-9]{2})[A-Z0-9]{4}\d{16}$/,
1762 XK: /^(XK[0-9]{2})\d{16}$/
1763};
1764
1765/**
1766 * Check if the country codes passed are valid using the
1767 * ibanRegexThroughCountryCode as a reference
1768 *
1769 * @param {array} countryCodeArray
1770 * @return {boolean}
1771 */
1772
1773function hasOnlyValidCountryCodes(countryCodeArray) {
1774 var countryCodeArrayFilteredWithObjectIbanCode = countryCodeArray.filter(function (countryCode) {
1775 return !(countryCode in ibanRegexThroughCountryCode);
1776 });
1777 if (countryCodeArrayFilteredWithObjectIbanCode.length > 0) {
1778 return false;
1779 }
1780 return true;
1781}
1782
1783/**
1784 * Check whether string has correct universal IBAN format
1785 * The IBAN consists of up to 34 alphanumeric characters, as follows:
1786 * Country Code using ISO 3166-1 alpha-2, two letters
1787 * check digits, two digits and
1788 * Basic Bank Account Number (BBAN), up to 30 alphanumeric characters.
1789 * NOTE: Permitted IBAN characters are: digits [0-9] and the 26 latin alphabetic [A-Z]
1790 *
1791 * @param {string} str - string under validation
1792 * @param {object} options - object to pass the countries to be either whitelisted or blacklisted
1793 * @return {boolean}
1794 */
1795function hasValidIbanFormat(str, options) {
1796 // Strip white spaces and hyphens
1797 var strippedStr = str.replace(/[\s\-]+/gi, '').toUpperCase();
1798 var isoCountryCode = strippedStr.slice(0, 2).toUpperCase();
1799 var isoCountryCodeInIbanRegexCodeObject = (isoCountryCode in ibanRegexThroughCountryCode);
1800 if (options.whitelist) {
1801 if (!hasOnlyValidCountryCodes(options.whitelist)) {
1802 return false;
1803 }
1804 var isoCountryCodeInWhiteList = options.whitelist.includes(isoCountryCode);
1805 if (!isoCountryCodeInWhiteList) {
1806 return false;
1807 }
1808 }
1809 if (options.blacklist) {
1810 var isoCountryCodeInBlackList = options.blacklist.includes(isoCountryCode);
1811 if (isoCountryCodeInBlackList) {
1812 return false;
1813 }
1814 }
1815 return isoCountryCodeInIbanRegexCodeObject && ibanRegexThroughCountryCode[isoCountryCode].test(strippedStr);
1816}
1817
1818/**
1819 * Check whether string has valid IBAN Checksum
1820 * by performing basic mod-97 operation and
1821 * the remainder should equal 1
1822 * -- Start by rearranging the IBAN by moving the four initial characters to the end of the string
1823 * -- Replace each letter in the string with two digits, A -> 10, B = 11, Z = 35
1824 * -- Interpret the string as a decimal integer and
1825 * -- compute the remainder on division by 97 (mod 97)
1826 * Reference: https://en.wikipedia.org/wiki/International_Bank_Account_Number
1827 *
1828 * @param {string} str
1829 * @return {boolean}
1830 */
1831function hasValidIbanChecksum(str) {
1832 var strippedStr = str.replace(/[^A-Z0-9]+/gi, '').toUpperCase(); // Keep only digits and A-Z latin alphabetic
1833 var rearranged = strippedStr.slice(4) + strippedStr.slice(0, 4);
1834 var alphaCapsReplacedWithDigits = rearranged.replace(/[A-Z]/g, function (_char) {
1835 return _char.charCodeAt(0) - 55;
1836 });
1837 var remainder = alphaCapsReplacedWithDigits.match(/\d{1,7}/g).reduce(function (acc, value) {
1838 return Number(acc + value) % 97;
1839 }, '');
1840 return remainder === 1;
1841}
1842function isIBAN(str) {
1843 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1844 assertString(str);
1845 return hasValidIbanFormat(str, options) && hasValidIbanChecksum(str);
1846}
1847var locales$3 = Object.keys(ibanRegexThroughCountryCode);
1848
1849// from https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
1850var validISO31661Alpha2CountriesCodes = new Set(['AD', 'AE', 'AF', 'AG', 'AI', 'AL', 'AM', 'AO', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AW', 'AX', 'AZ', 'BA', 'BB', 'BD', 'BE', 'BF', 'BG', 'BH', 'BI', 'BJ', 'BL', 'BM', 'BN', 'BO', 'BQ', 'BR', 'BS', 'BT', 'BV', 'BW', 'BY', 'BZ', 'CA', 'CC', 'CD', 'CF', 'CG', 'CH', 'CI', 'CK', 'CL', 'CM', 'CN', 'CO', 'CR', 'CU', 'CV', 'CW', 'CX', 'CY', 'CZ', 'DE', 'DJ', 'DK', 'DM', 'DO', 'DZ', 'EC', 'EE', 'EG', 'EH', 'ER', 'ES', 'ET', 'FI', 'FJ', 'FK', 'FM', 'FO', 'FR', 'GA', 'GB', 'GD', 'GE', 'GF', 'GG', 'GH', 'GI', 'GL', 'GM', 'GN', 'GP', 'GQ', 'GR', 'GS', 'GT', 'GU', 'GW', 'GY', 'HK', 'HM', 'HN', 'HR', 'HT', 'HU', 'ID', 'IE', 'IL', 'IM', 'IN', 'IO', 'IQ', 'IR', 'IS', 'IT', 'JE', 'JM', 'JO', 'JP', 'KE', 'KG', 'KH', 'KI', 'KM', 'KN', 'KP', 'KR', 'KW', 'KY', 'KZ', 'LA', 'LB', 'LC', 'LI', 'LK', 'LR', 'LS', 'LT', 'LU', 'LV', 'LY', 'MA', 'MC', 'MD', 'ME', 'MF', 'MG', 'MH', 'MK', 'ML', 'MM', 'MN', 'MO', 'MP', 'MQ', 'MR', 'MS', 'MT', 'MU', 'MV', 'MW', 'MX', 'MY', 'MZ', 'NA', 'NC', 'NE', 'NF', 'NG', 'NI', 'NL', 'NO', 'NP', 'NR', 'NU', 'NZ', 'OM', 'PA', 'PE', 'PF', 'PG', 'PH', 'PK', 'PL', 'PM', 'PN', 'PR', 'PS', 'PT', 'PW', 'PY', 'QA', 'RE', 'RO', 'RS', 'RU', 'RW', 'SA', 'SB', 'SC', 'SD', 'SE', 'SG', 'SH', 'SI', 'SJ', 'SK', 'SL', 'SM', 'SN', 'SO', 'SR', 'SS', 'ST', 'SV', 'SX', 'SY', 'SZ', 'TC', 'TD', 'TF', 'TG', 'TH', 'TJ', 'TK', 'TL', 'TM', 'TN', 'TO', 'TR', 'TT', 'TV', 'TW', 'TZ', 'UA', 'UG', 'UM', 'US', 'UY', 'UZ', 'VA', 'VC', 'VE', 'VG', 'VI', 'VN', 'VU', 'WF', 'WS', 'YE', 'YT', 'ZA', 'ZM', 'ZW']);
1851function isISO31661Alpha2(str) {
1852 assertString(str);
1853 return validISO31661Alpha2CountriesCodes.has(str.toUpperCase());
1854}
1855var CountryCodes = validISO31661Alpha2CountriesCodes;
1856
1857// https://en.wikipedia.org/wiki/ISO_9362
1858var isBICReg = /^[A-Za-z]{6}[A-Za-z0-9]{2}([A-Za-z0-9]{3})?$/;
1859function isBIC(str) {
1860 assertString(str);
1861
1862 // toUpperCase() should be removed when a new major version goes out that changes
1863 // the regex to [A-Z] (per the spec).
1864 var countryCode = str.slice(4, 6).toUpperCase();
1865 if (!CountryCodes.has(countryCode) && countryCode !== 'XK') {
1866 return false;
1867 }
1868 return isBICReg.test(str);
1869}
1870
1871var md5 = /^[a-f0-9]{32}$/;
1872function isMD5(str) {
1873 assertString(str);
1874 return md5.test(str);
1875}
1876
1877var lengths = {
1878 md5: 32,
1879 md4: 32,
1880 sha1: 40,
1881 sha256: 64,
1882 sha384: 96,
1883 sha512: 128,
1884 ripemd128: 32,
1885 ripemd160: 40,
1886 tiger128: 32,
1887 tiger160: 40,
1888 tiger192: 48,
1889 crc32: 8,
1890 crc32b: 8
1891};
1892function isHash(str, algorithm) {
1893 assertString(str);
1894 var hash = new RegExp("^[a-fA-F0-9]{".concat(lengths[algorithm], "}$"));
1895 return hash.test(str);
1896}
1897
1898var notBase64 = /[^A-Z0-9+\/=]/i;
1899var urlSafeBase64 = /^[A-Z0-9_\-]*$/i;
1900var defaultBase64Options = {
1901 urlSafe: false
1902};
1903function isBase64(str, options) {
1904 assertString(str);
1905 options = merge(options, defaultBase64Options);
1906 var len = str.length;
1907 if (options.urlSafe) {
1908 return urlSafeBase64.test(str);
1909 }
1910 if (len % 4 !== 0 || notBase64.test(str)) {
1911 return false;
1912 }
1913 var firstPaddingChar = str.indexOf('=');
1914 return firstPaddingChar === -1 || firstPaddingChar === len - 1 || firstPaddingChar === len - 2 && str[len - 1] === '=';
1915}
1916
1917function isJWT(str) {
1918 assertString(str);
1919 var dotSplit = str.split('.');
1920 var len = dotSplit.length;
1921 if (len !== 3) {
1922 return false;
1923 }
1924 return dotSplit.reduce(function (acc, currElem) {
1925 return acc && isBase64(currElem, {
1926 urlSafe: true
1927 });
1928 }, true);
1929}
1930
1931var default_json_options = {
1932 allow_primitives: false
1933};
1934function isJSON(str, options) {
1935 assertString(str);
1936 try {
1937 options = merge(options, default_json_options);
1938 var primitives = [];
1939 if (options.allow_primitives) {
1940 primitives = [null, false, true];
1941 }
1942 var obj = JSON.parse(str);
1943 return primitives.includes(obj) || !!obj && _typeof(obj) === 'object';
1944 } catch (e) {/* ignore */}
1945 return false;
1946}
1947
1948var default_is_empty_options = {
1949 ignore_whitespace: false
1950};
1951function isEmpty(str, options) {
1952 assertString(str);
1953 options = merge(options, default_is_empty_options);
1954 return (options.ignore_whitespace ? str.trim().length : str.length) === 0;
1955}
1956
1957/* eslint-disable prefer-rest-params */
1958function isLength(str, options) {
1959 assertString(str);
1960 var min;
1961 var max;
1962 if (_typeof(options) === 'object') {
1963 min = options.min || 0;
1964 max = options.max;
1965 } else {
1966 // backwards compatibility: isLength(str, min [, max])
1967 min = arguments[1] || 0;
1968 max = arguments[2];
1969 }
1970 var presentationSequences = str.match(/(\uFE0F|\uFE0E)/g) || [];
1971 var surrogatePairs = str.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g) || [];
1972 var len = str.length - presentationSequences.length - surrogatePairs.length;
1973 return len >= min && (typeof max === 'undefined' || len <= max);
1974}
1975
1976var uuid = {
1977 1: /^[0-9A-F]{8}-[0-9A-F]{4}-1[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,
1978 2: /^[0-9A-F]{8}-[0-9A-F]{4}-2[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,
1979 3: /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,
1980 4: /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,
1981 5: /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,
1982 7: /^[0-9A-F]{8}-[0-9A-F]{4}-7[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,
1983 all: /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i
1984};
1985function isUUID(str, version) {
1986 assertString(str);
1987 var pattern = uuid[![undefined, null].includes(version) ? version : 'all'];
1988 return !!pattern && pattern.test(str);
1989}
1990
1991function isMongoId(str) {
1992 assertString(str);
1993 return isHexadecimal(str) && str.length === 24;
1994}
1995
1996function isAfter(date, options) {
1997 // For backwards compatibility:
1998 // isAfter(str [, date]), i.e. `options` could be used as argument for the legacy `date`
1999 var comparisonDate = (options === null || options === void 0 ? void 0 : options.comparisonDate) || options || Date().toString();
2000 var comparison = toDate(comparisonDate);
2001 var original = toDate(date);
2002 return !!(original && comparison && original > comparison);
2003}
2004
2005function isBefore(str) {
2006 var date = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : String(new Date());
2007 assertString(str);
2008 var comparison = toDate(date);
2009 var original = toDate(str);
2010 return !!(original && comparison && original < comparison);
2011}
2012
2013function isIn(str, options) {
2014 assertString(str);
2015 var i;
2016 if (Object.prototype.toString.call(options) === '[object Array]') {
2017 var array = [];
2018 for (i in options) {
2019 // https://github.com/gotwarlost/istanbul/blob/master/ignoring-code-for-coverage.md#ignoring-code-for-coverage-purposes
2020 // istanbul ignore else
2021 if ({}.hasOwnProperty.call(options, i)) {
2022 array[i] = toString$1(options[i]);
2023 }
2024 }
2025 return array.indexOf(str) >= 0;
2026 } else if (_typeof(options) === 'object') {
2027 return options.hasOwnProperty(str);
2028 } else if (options && typeof options.indexOf === 'function') {
2029 return options.indexOf(str) >= 0;
2030 }
2031 return false;
2032}
2033
2034function isLuhnNumber(str) {
2035 assertString(str);
2036 var sanitized = str.replace(/[- ]+/g, '');
2037 var sum = 0;
2038 var digit;
2039 var tmpNum;
2040 var shouldDouble;
2041 for (var i = sanitized.length - 1; i >= 0; i--) {
2042 digit = sanitized.substring(i, i + 1);
2043 tmpNum = parseInt(digit, 10);
2044 if (shouldDouble) {
2045 tmpNum *= 2;
2046 if (tmpNum >= 10) {
2047 sum += tmpNum % 10 + 1;
2048 } else {
2049 sum += tmpNum;
2050 }
2051 } else {
2052 sum += tmpNum;
2053 }
2054 shouldDouble = !shouldDouble;
2055 }
2056 return !!(sum % 10 === 0 ? sanitized : false);
2057}
2058
2059var cards = {
2060 amex: /^3[47][0-9]{13}$/,
2061 dinersclub: /^3(?:0[0-5]|[68][0-9])[0-9]{11}$/,
2062 discover: /^6(?:011|5[0-9][0-9])[0-9]{12,15}$/,
2063 jcb: /^(?:2131|1800|35\d{3})\d{11}$/,
2064 mastercard: /^5[1-5][0-9]{2}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}$/,
2065 // /^[25][1-7][0-9]{14}$/;
2066 unionpay: /^(6[27][0-9]{14}|^(81[0-9]{14,17}))$/,
2067 visa: /^(?:4[0-9]{12})(?:[0-9]{3,6})?$/
2068};
2069var allCards = function () {
2070 var tmpCardsArray = [];
2071 for (var cardProvider in cards) {
2072 // istanbul ignore else
2073 if (cards.hasOwnProperty(cardProvider)) {
2074 tmpCardsArray.push(cards[cardProvider]);
2075 }
2076 }
2077 return tmpCardsArray;
2078}();
2079function isCreditCard(card) {
2080 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
2081 assertString(card);
2082 var provider = options.provider;
2083 var sanitized = card.replace(/[- ]+/g, '');
2084 if (provider && provider.toLowerCase() in cards) {
2085 // specific provider in the list
2086 if (!cards[provider.toLowerCase()].test(sanitized)) {
2087 return false;
2088 }
2089 } else if (provider && !(provider.toLowerCase() in cards)) {
2090 /* specific provider not in the list */
2091 throw new Error("".concat(provider, " is not a valid credit card provider."));
2092 } else if (!allCards.some(function (cardProvider) {
2093 return cardProvider.test(sanitized);
2094 })) {
2095 // no specific provider
2096 return false;
2097 }
2098 return isLuhnNumber(card);
2099}
2100
2101var validators = {
2102 PL: function PL(str) {
2103 assertString(str);
2104 var weightOfDigits = {
2105 1: 1,
2106 2: 3,
2107 3: 7,
2108 4: 9,
2109 5: 1,
2110 6: 3,
2111 7: 7,
2112 8: 9,
2113 9: 1,
2114 10: 3,
2115 11: 0
2116 };
2117 if (str != null && str.length === 11 && isInt(str, {
2118 allow_leading_zeroes: true
2119 })) {
2120 var digits = str.split('').slice(0, -1);
2121 var sum = digits.reduce(function (acc, digit, index) {
2122 return acc + Number(digit) * weightOfDigits[index + 1];
2123 }, 0);
2124 var modulo = sum % 10;
2125 var lastDigit = Number(str.charAt(str.length - 1));
2126 if (modulo === 0 && lastDigit === 0 || lastDigit === 10 - modulo) {
2127 return true;
2128 }
2129 }
2130 return false;
2131 },
2132 ES: function ES(str) {
2133 assertString(str);
2134 var DNI = /^[0-9X-Z][0-9]{7}[TRWAGMYFPDXBNJZSQVHLCKE]$/;
2135 var charsValue = {
2136 X: 0,
2137 Y: 1,
2138 Z: 2
2139 };
2140 var controlDigits = ['T', 'R', 'W', 'A', 'G', 'M', 'Y', 'F', 'P', 'D', 'X', 'B', 'N', 'J', 'Z', 'S', 'Q', 'V', 'H', 'L', 'C', 'K', 'E'];
2141
2142 // sanitize user input
2143 var sanitized = str.trim().toUpperCase();
2144
2145 // validate the data structure
2146 if (!DNI.test(sanitized)) {
2147 return false;
2148 }
2149
2150 // validate the control digit
2151 var number = sanitized.slice(0, -1).replace(/[X,Y,Z]/g, function (_char) {
2152 return charsValue[_char];
2153 });
2154 return sanitized.endsWith(controlDigits[number % 23]);
2155 },
2156 FI: function FI(str) {
2157 // https://dvv.fi/en/personal-identity-code#:~:text=control%20character%20for%20a-,personal,-identity%20code%20calculated
2158 assertString(str);
2159 if (str.length !== 11) {
2160 return false;
2161 }
2162 if (!str.match(/^\d{6}[\-A\+]\d{3}[0-9ABCDEFHJKLMNPRSTUVWXY]{1}$/)) {
2163 return false;
2164 }
2165 var checkDigits = '0123456789ABCDEFHJKLMNPRSTUVWXY';
2166 var idAsNumber = parseInt(str.slice(0, 6), 10) * 1000 + parseInt(str.slice(7, 10), 10);
2167 var remainder = idAsNumber % 31;
2168 var checkDigit = checkDigits[remainder];
2169 return checkDigit === str.slice(10, 11);
2170 },
2171 IN: function IN(str) {
2172 var DNI = /^[1-9]\d{3}\s?\d{4}\s?\d{4}$/;
2173
2174 // multiplication table
2175 var d = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 0, 6, 7, 8, 9, 5], [2, 3, 4, 0, 1, 7, 8, 9, 5, 6], [3, 4, 0, 1, 2, 8, 9, 5, 6, 7], [4, 0, 1, 2, 3, 9, 5, 6, 7, 8], [5, 9, 8, 7, 6, 0, 4, 3, 2, 1], [6, 5, 9, 8, 7, 1, 0, 4, 3, 2], [7, 6, 5, 9, 8, 2, 1, 0, 4, 3], [8, 7, 6, 5, 9, 3, 2, 1, 0, 4], [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]];
2176
2177 // permutation table
2178 var p = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 5, 7, 6, 2, 8, 3, 0, 9, 4], [5, 8, 0, 3, 7, 9, 6, 1, 4, 2], [8, 9, 1, 6, 0, 4, 3, 5, 2, 7], [9, 4, 5, 3, 1, 2, 6, 8, 7, 0], [4, 2, 8, 6, 5, 7, 3, 9, 0, 1], [2, 7, 9, 3, 8, 0, 6, 4, 1, 5], [7, 0, 4, 6, 9, 1, 3, 2, 5, 8]];
2179
2180 // sanitize user input
2181 var sanitized = str.trim();
2182
2183 // validate the data structure
2184 if (!DNI.test(sanitized)) {
2185 return false;
2186 }
2187 var c = 0;
2188 var invertedArray = sanitized.replace(/\s/g, '').split('').map(Number).reverse();
2189 invertedArray.forEach(function (val, i) {
2190 c = d[c][p[i % 8][val]];
2191 });
2192 return c === 0;
2193 },
2194 IR: function IR(str) {
2195 if (!str.match(/^\d{10}$/)) return false;
2196 str = "0000".concat(str).slice(str.length - 6);
2197 if (parseInt(str.slice(3, 9), 10) === 0) return false;
2198 var lastNumber = parseInt(str.slice(9, 10), 10);
2199 var sum = 0;
2200 for (var i = 0; i < 9; i++) {
2201 sum += parseInt(str.slice(i, i + 1), 10) * (10 - i);
2202 }
2203 sum %= 11;
2204 return sum < 2 && lastNumber === sum || sum >= 2 && lastNumber === 11 - sum;
2205 },
2206 IT: function IT(str) {
2207 if (str.length !== 9) return false;
2208 if (str === 'CA00000AA') return false; // https://it.wikipedia.org/wiki/Carta_d%27identit%C3%A0_elettronica_italiana
2209 return str.search(/C[A-Z]\d{5}[A-Z]{2}/i) > -1;
2210 },
2211 NO: function NO(str) {
2212 var sanitized = str.trim();
2213 if (isNaN(Number(sanitized))) return false;
2214 if (sanitized.length !== 11) return false;
2215 if (sanitized === '00000000000') return false;
2216
2217 // https://no.wikipedia.org/wiki/F%C3%B8dselsnummer
2218 var f = sanitized.split('').map(Number);
2219 var k1 = (11 - (3 * f[0] + 7 * f[1] + 6 * f[2] + 1 * f[3] + 8 * f[4] + 9 * f[5] + 4 * f[6] + 5 * f[7] + 2 * f[8]) % 11) % 11;
2220 var k2 = (11 - (5 * f[0] + 4 * f[1] + 3 * f[2] + 2 * f[3] + 7 * f[4] + 6 * f[5] + 5 * f[6] + 4 * f[7] + 3 * f[8] + 2 * k1) % 11) % 11;
2221 if (k1 !== f[9] || k2 !== f[10]) return false;
2222 return true;
2223 },
2224 TH: function TH(str) {
2225 if (!str.match(/^[1-8]\d{12}$/)) return false;
2226
2227 // validate check digit
2228 var sum = 0;
2229 for (var i = 0; i < 12; i++) {
2230 sum += parseInt(str[i], 10) * (13 - i);
2231 }
2232 return str[12] === ((11 - sum % 11) % 10).toString();
2233 },
2234 LK: function LK(str) {
2235 var old_nic = /^[1-9]\d{8}[vx]$/i;
2236 var new_nic = /^[1-9]\d{11}$/i;
2237 if (str.length === 10 && old_nic.test(str)) return true;else if (str.length === 12 && new_nic.test(str)) return true;
2238 return false;
2239 },
2240 'he-IL': function heIL(str) {
2241 var DNI = /^\d{9}$/;
2242
2243 // sanitize user input
2244 var sanitized = str.trim();
2245
2246 // validate the data structure
2247 if (!DNI.test(sanitized)) {
2248 return false;
2249 }
2250 var id = sanitized;
2251 var sum = 0,
2252 incNum;
2253 for (var i = 0; i < id.length; i++) {
2254 incNum = Number(id[i]) * (i % 2 + 1); // Multiply number by 1 or 2
2255 sum += incNum > 9 ? incNum - 9 : incNum; // Sum the digits up and add to total
2256 }
2257 return sum % 10 === 0;
2258 },
2259 'ar-LY': function arLY(str) {
2260 // Libya National Identity Number NIN is 12 digits, the first digit is either 1 or 2
2261 var NIN = /^(1|2)\d{11}$/;
2262
2263 // sanitize user input
2264 var sanitized = str.trim();
2265
2266 // validate the data structure
2267 if (!NIN.test(sanitized)) {
2268 return false;
2269 }
2270 return true;
2271 },
2272 'ar-TN': function arTN(str) {
2273 var DNI = /^\d{8}$/;
2274
2275 // sanitize user input
2276 var sanitized = str.trim();
2277
2278 // validate the data structure
2279 if (!DNI.test(sanitized)) {
2280 return false;
2281 }
2282 return true;
2283 },
2284 'zh-CN': function zhCN(str) {
2285 var provincesAndCities = ['11',
2286 // 北京
2287 '12',
2288 // 天津
2289 '13',
2290 // 河北
2291 '14',
2292 // 山西
2293 '15',
2294 // 内蒙古
2295 '21',
2296 // 辽宁
2297 '22',
2298 // 吉林
2299 '23',
2300 // 黑龙江
2301 '31',
2302 // 上海
2303 '32',
2304 // 江苏
2305 '33',
2306 // 浙江
2307 '34',
2308 // 安徽
2309 '35',
2310 // 福建
2311 '36',
2312 // 江西
2313 '37',
2314 // 山东
2315 '41',
2316 // 河南
2317 '42',
2318 // 湖北
2319 '43',
2320 // 湖南
2321 '44',
2322 // 广东
2323 '45',
2324 // 广西
2325 '46',
2326 // 海南
2327 '50',
2328 // 重庆
2329 '51',
2330 // 四川
2331 '52',
2332 // 贵州
2333 '53',
2334 // 云南
2335 '54',
2336 // 西藏
2337 '61',
2338 // 陕西
2339 '62',
2340 // 甘肃
2341 '63',
2342 // 青海
2343 '64',
2344 // 宁夏
2345 '65',
2346 // 新疆
2347 '71',
2348 // 台湾
2349 '81',
2350 // 香港
2351 '82',
2352 // 澳门
2353 '91' // 国外
2354 ];
2355 var powers = ['7', '9', '10', '5', '8', '4', '2', '1', '6', '3', '7', '9', '10', '5', '8', '4', '2'];
2356 var parityBit = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
2357 var checkAddressCode = function checkAddressCode(addressCode) {
2358 return provincesAndCities.includes(addressCode);
2359 };
2360 var checkBirthDayCode = function checkBirthDayCode(birDayCode) {
2361 var yyyy = parseInt(birDayCode.substring(0, 4), 10);
2362 var mm = parseInt(birDayCode.substring(4, 6), 10);
2363 var dd = parseInt(birDayCode.substring(6), 10);
2364 var xdata = new Date(yyyy, mm - 1, dd);
2365 if (xdata > new Date()) {
2366 return false;
2367 // eslint-disable-next-line max-len
2368 } else if (xdata.getFullYear() === yyyy && xdata.getMonth() === mm - 1 && xdata.getDate() === dd) {
2369 return true;
2370 }
2371 return false;
2372 };
2373 var getParityBit = function getParityBit(idCardNo) {
2374 var id17 = idCardNo.substring(0, 17);
2375 var power = 0;
2376 for (var i = 0; i < 17; i++) {
2377 power += parseInt(id17.charAt(i), 10) * parseInt(powers[i], 10);
2378 }
2379 var mod = power % 11;
2380 return parityBit[mod];
2381 };
2382 var checkParityBit = function checkParityBit(idCardNo) {
2383 return getParityBit(idCardNo) === idCardNo.charAt(17).toUpperCase();
2384 };
2385 var check15IdCardNo = function check15IdCardNo(idCardNo) {
2386 var check = /^[1-9]\d{7}((0[1-9])|(1[0-2]))((0[1-9])|([1-2][0-9])|(3[0-1]))\d{3}$/.test(idCardNo);
2387 if (!check) return false;
2388 var addressCode = idCardNo.substring(0, 2);
2389 check = checkAddressCode(addressCode);
2390 if (!check) return false;
2391 var birDayCode = "19".concat(idCardNo.substring(6, 12));
2392 check = checkBirthDayCode(birDayCode);
2393 if (!check) return false;
2394 return true;
2395 };
2396 var check18IdCardNo = function check18IdCardNo(idCardNo) {
2397 var check = /^[1-9]\d{5}[1-9]\d{3}((0[1-9])|(1[0-2]))((0[1-9])|([1-2][0-9])|(3[0-1]))\d{3}(\d|x|X)$/.test(idCardNo);
2398 if (!check) return false;
2399 var addressCode = idCardNo.substring(0, 2);
2400 check = checkAddressCode(addressCode);
2401 if (!check) return false;
2402 var birDayCode = idCardNo.substring(6, 14);
2403 check = checkBirthDayCode(birDayCode);
2404 if (!check) return false;
2405 return checkParityBit(idCardNo);
2406 };
2407 var checkIdCardNo = function checkIdCardNo(idCardNo) {
2408 var check = /^\d{15}|(\d{17}(\d|x|X))$/.test(idCardNo);
2409 if (!check) return false;
2410 if (idCardNo.length === 15) {
2411 return check15IdCardNo(idCardNo);
2412 }
2413 return check18IdCardNo(idCardNo);
2414 };
2415 return checkIdCardNo(str);
2416 },
2417 'zh-HK': function zhHK(str) {
2418 // sanitize user input
2419 str = str.trim();
2420
2421 // HKID number starts with 1 or 2 letters, followed by 6 digits,
2422 // then a checksum contained in square / round brackets or nothing
2423 var regexHKID = /^[A-Z]{1,2}[0-9]{6}((\([0-9A]\))|(\[[0-9A]\])|([0-9A]))$/;
2424 var regexIsDigit = /^[0-9]$/;
2425
2426 // convert the user input to all uppercase and apply regex
2427 str = str.toUpperCase();
2428 if (!regexHKID.test(str)) return false;
2429 str = str.replace(/\[|\]|\(|\)/g, '');
2430 if (str.length === 8) str = "3".concat(str);
2431 var checkSumVal = 0;
2432 for (var i = 0; i <= 7; i++) {
2433 var convertedChar = void 0;
2434 if (!regexIsDigit.test(str[i])) convertedChar = (str[i].charCodeAt(0) - 55) % 11;else convertedChar = str[i];
2435 checkSumVal += convertedChar * (9 - i);
2436 }
2437 checkSumVal %= 11;
2438 var checkSumConverted;
2439 if (checkSumVal === 0) checkSumConverted = '0';else if (checkSumVal === 1) checkSumConverted = 'A';else checkSumConverted = String(11 - checkSumVal);
2440 if (checkSumConverted === str[str.length - 1]) return true;
2441 return false;
2442 },
2443 'zh-TW': function zhTW(str) {
2444 var ALPHABET_CODES = {
2445 A: 10,
2446 B: 11,
2447 C: 12,
2448 D: 13,
2449 E: 14,
2450 F: 15,
2451 G: 16,
2452 H: 17,
2453 I: 34,
2454 J: 18,
2455 K: 19,
2456 L: 20,
2457 M: 21,
2458 N: 22,
2459 O: 35,
2460 P: 23,
2461 Q: 24,
2462 R: 25,
2463 S: 26,
2464 T: 27,
2465 U: 28,
2466 V: 29,
2467 W: 32,
2468 X: 30,
2469 Y: 31,
2470 Z: 33
2471 };
2472 var sanitized = str.trim().toUpperCase();
2473 if (!/^[A-Z][0-9]{9}$/.test(sanitized)) return false;
2474 return Array.from(sanitized).reduce(function (sum, number, index) {
2475 if (index === 0) {
2476 var code = ALPHABET_CODES[number];
2477 return code % 10 * 9 + Math.floor(code / 10);
2478 }
2479 if (index === 9) {
2480 return (10 - sum % 10 - Number(number)) % 10 === 0;
2481 }
2482 return sum + Number(number) * (9 - index);
2483 }, 0);
2484 }
2485};
2486function isIdentityCard(str, locale) {
2487 assertString(str);
2488 if (locale in validators) {
2489 return validators[locale](str);
2490 } else if (locale === 'any') {
2491 for (var key in validators) {
2492 // https://github.com/gotwarlost/istanbul/blob/master/ignoring-code-for-coverage.md#ignoring-code-for-coverage-purposes
2493 // istanbul ignore else
2494 if (validators.hasOwnProperty(key)) {
2495 var validator = validators[key];
2496 if (validator(str)) {
2497 return true;
2498 }
2499 }
2500 }
2501 return false;
2502 }
2503 throw new Error("Invalid locale '".concat(locale, "'"));
2504}
2505
2506/**
2507 * The most commonly used EAN standard is
2508 * the thirteen-digit EAN-13, while the
2509 * less commonly used 8-digit EAN-8 barcode was
2510 * introduced for use on small packages.
2511 * Also EAN/UCC-14 is used for Grouping of individual
2512 * trade items above unit level(Intermediate, Carton or Pallet).
2513 * For more info about EAN-14 checkout: https://www.gtin.info/itf-14-barcodes/
2514 * EAN consists of:
2515 * GS1 prefix, manufacturer code, product code and check digit
2516 * Reference: https://en.wikipedia.org/wiki/International_Article_Number
2517 * Reference: https://www.gtin.info/
2518 */
2519
2520/**
2521 * Define EAN Lenghts; 8 for EAN-8; 13 for EAN-13; 14 for EAN-14
2522 * and Regular Expression for valid EANs (EAN-8, EAN-13, EAN-14),
2523 * with exact numberic matching of 8 or 13 or 14 digits [0-9]
2524 */
2525var LENGTH_EAN_8 = 8;
2526var LENGTH_EAN_14 = 14;
2527var validEanRegex = /^(\d{8}|\d{13}|\d{14})$/;
2528
2529/**
2530 * Get position weight given:
2531 * EAN length and digit index/position
2532 *
2533 * @param {number} length
2534 * @param {number} index
2535 * @return {number}
2536 */
2537function getPositionWeightThroughLengthAndIndex(length, index) {
2538 if (length === LENGTH_EAN_8 || length === LENGTH_EAN_14) {
2539 return index % 2 === 0 ? 3 : 1;
2540 }
2541 return index % 2 === 0 ? 1 : 3;
2542}
2543
2544/**
2545 * Calculate EAN Check Digit
2546 * Reference: https://en.wikipedia.org/wiki/International_Article_Number#Calculation_of_checksum_digit
2547 *
2548 * @param {string} ean
2549 * @return {number}
2550 */
2551function calculateCheckDigit(ean) {
2552 var checksum = ean.slice(0, -1).split('').map(function (_char, index) {
2553 return Number(_char) * getPositionWeightThroughLengthAndIndex(ean.length, index);
2554 }).reduce(function (acc, partialSum) {
2555 return acc + partialSum;
2556 }, 0);
2557 var remainder = 10 - checksum % 10;
2558 return remainder < 10 ? remainder : 0;
2559}
2560
2561/**
2562 * Check if string is valid EAN:
2563 * Matches EAN-8/EAN-13/EAN-14 regex
2564 * Has valid check digit.
2565 *
2566 * @param {string} str
2567 * @return {boolean}
2568 */
2569function isEAN(str) {
2570 assertString(str);
2571 var actualCheckDigit = Number(str.slice(-1));
2572 return validEanRegex.test(str) && actualCheckDigit === calculateCheckDigit(str);
2573}
2574
2575var isin = /^[A-Z]{2}[0-9A-Z]{9}[0-9]$/;
2576
2577// this link details how the check digit is calculated:
2578// https://www.isin.org/isin-format/. it is a little bit
2579// odd in that it works with digits, not numbers. in order
2580// to make only one pass through the ISIN characters, the
2581// each alpha character is handled as 2 characters within
2582// the loop.
2583
2584function isISIN(str) {
2585 assertString(str);
2586 if (!isin.test(str)) {
2587 return false;
2588 }
2589 var _double = true;
2590 var sum = 0;
2591 // convert values
2592 for (var i = str.length - 2; i >= 0; i--) {
2593 if (str[i] >= 'A' && str[i] <= 'Z') {
2594 var value = str[i].charCodeAt(0) - 55;
2595 var lo = value % 10;
2596 var hi = Math.trunc(value / 10);
2597 // letters have two digits, so handle the low order
2598 // and high order digits separately.
2599 for (var _i = 0, _arr = [lo, hi]; _i < _arr.length; _i++) {
2600 var digit = _arr[_i];
2601 if (_double) {
2602 if (digit >= 5) {
2603 sum += 1 + (digit - 5) * 2;
2604 } else {
2605 sum += digit * 2;
2606 }
2607 } else {
2608 sum += digit;
2609 }
2610 _double = !_double;
2611 }
2612 } else {
2613 var _digit = str[i].charCodeAt(0) - '0'.charCodeAt(0);
2614 if (_double) {
2615 if (_digit >= 5) {
2616 sum += 1 + (_digit - 5) * 2;
2617 } else {
2618 sum += _digit * 2;
2619 }
2620 } else {
2621 sum += _digit;
2622 }
2623 _double = !_double;
2624 }
2625 }
2626 var check = Math.trunc((sum + 9) / 10) * 10 - sum;
2627 return +str[str.length - 1] === check;
2628}
2629
2630var possibleIsbn10 = /^(?:[0-9]{9}X|[0-9]{10})$/;
2631var possibleIsbn13 = /^(?:[0-9]{13})$/;
2632var factor = [1, 3];
2633function isISBN(isbn, options) {
2634 assertString(isbn);
2635
2636 // For backwards compatibility:
2637 // isISBN(str [, version]), i.e. `options` could be used as argument for the legacy `version`
2638 var version = String((options === null || options === void 0 ? void 0 : options.version) || options);
2639 if (!(options !== null && options !== void 0 && options.version || options)) {
2640 return isISBN(isbn, {
2641 version: 10
2642 }) || isISBN(isbn, {
2643 version: 13
2644 });
2645 }
2646 var sanitizedIsbn = isbn.replace(/[\s-]+/g, '');
2647 var checksum = 0;
2648 if (version === '10') {
2649 if (!possibleIsbn10.test(sanitizedIsbn)) {
2650 return false;
2651 }
2652 for (var i = 0; i < version - 1; i++) {
2653 checksum += (i + 1) * sanitizedIsbn.charAt(i);
2654 }
2655 if (sanitizedIsbn.charAt(9) === 'X') {
2656 checksum += 10 * 10;
2657 } else {
2658 checksum += 10 * sanitizedIsbn.charAt(9);
2659 }
2660 if (checksum % 11 === 0) {
2661 return true;
2662 }
2663 } else if (version === '13') {
2664 if (!possibleIsbn13.test(sanitizedIsbn)) {
2665 return false;
2666 }
2667 for (var _i = 0; _i < 12; _i++) {
2668 checksum += factor[_i % 2] * sanitizedIsbn.charAt(_i);
2669 }
2670 if (sanitizedIsbn.charAt(12) - (10 - checksum % 10) % 10 === 0) {
2671 return true;
2672 }
2673 }
2674 return false;
2675}
2676
2677var issn = '^\\d{4}-?\\d{3}[\\dX]$';
2678function isISSN(str) {
2679 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
2680 assertString(str);
2681 var testIssn = issn;
2682 testIssn = options.require_hyphen ? testIssn.replace('?', '') : testIssn;
2683 testIssn = options.case_sensitive ? new RegExp(testIssn) : new RegExp(testIssn, 'i');
2684 if (!testIssn.test(str)) {
2685 return false;
2686 }
2687 var digits = str.replace('-', '').toUpperCase();
2688 var checksum = 0;
2689 for (var i = 0; i < digits.length; i++) {
2690 var digit = digits[i];
2691 checksum += (digit === 'X' ? 10 : +digit) * (8 - i);
2692 }
2693 return checksum % 11 === 0;
2694}
2695
2696/**
2697 * Algorithmic validation functions
2698 * May be used as is or implemented in the workflow of other validators.
2699 */
2700
2701/*
2702 * ISO 7064 validation function
2703 * Called with a string of numbers (incl. check digit)
2704 * to validate according to ISO 7064 (MOD 11, 10).
2705 */
2706function iso7064Check(str) {
2707 var checkvalue = 10;
2708 for (var i = 0; i < str.length - 1; i++) {
2709 checkvalue = (parseInt(str[i], 10) + checkvalue) % 10 === 0 ? 10 * 2 % 11 : (parseInt(str[i], 10) + checkvalue) % 10 * 2 % 11;
2710 }
2711 checkvalue = checkvalue === 1 ? 0 : 11 - checkvalue;
2712 return checkvalue === parseInt(str[10], 10);
2713}
2714
2715/*
2716 * Luhn (mod 10) validation function
2717 * Called with a string of numbers (incl. check digit)
2718 * to validate according to the Luhn algorithm.
2719 */
2720function luhnCheck(str) {
2721 var checksum = 0;
2722 var second = false;
2723 for (var i = str.length - 1; i >= 0; i--) {
2724 if (second) {
2725 var product = parseInt(str[i], 10) * 2;
2726 if (product > 9) {
2727 // sum digits of product and add to checksum
2728 checksum += product.toString().split('').map(function (a) {
2729 return parseInt(a, 10);
2730 }).reduce(function (a, b) {
2731 return a + b;
2732 }, 0);
2733 } else {
2734 checksum += product;
2735 }
2736 } else {
2737 checksum += parseInt(str[i], 10);
2738 }
2739 second = !second;
2740 }
2741 return checksum % 10 === 0;
2742}
2743
2744/*
2745 * Reverse TIN multiplication and summation helper function
2746 * Called with an array of single-digit integers and a base multiplier
2747 * to calculate the sum of the digits multiplied in reverse.
2748 * Normally used in variations of MOD 11 algorithmic checks.
2749 */
2750function reverseMultiplyAndSum(digits, base) {
2751 var total = 0;
2752 for (var i = 0; i < digits.length; i++) {
2753 total += digits[i] * (base - i);
2754 }
2755 return total;
2756}
2757
2758/*
2759 * Verhoeff validation helper function
2760 * Called with a string of numbers
2761 * to validate according to the Verhoeff algorithm.
2762 */
2763function verhoeffCheck(str) {
2764 var d_table = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 0, 6, 7, 8, 9, 5], [2, 3, 4, 0, 1, 7, 8, 9, 5, 6], [3, 4, 0, 1, 2, 8, 9, 5, 6, 7], [4, 0, 1, 2, 3, 9, 5, 6, 7, 8], [5, 9, 8, 7, 6, 0, 4, 3, 2, 1], [6, 5, 9, 8, 7, 1, 0, 4, 3, 2], [7, 6, 5, 9, 8, 2, 1, 0, 4, 3], [8, 7, 6, 5, 9, 3, 2, 1, 0, 4], [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]];
2765 var p_table = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 5, 7, 6, 2, 8, 3, 0, 9, 4], [5, 8, 0, 3, 7, 9, 6, 1, 4, 2], [8, 9, 1, 6, 0, 4, 3, 5, 2, 7], [9, 4, 5, 3, 1, 2, 6, 8, 7, 0], [4, 2, 8, 6, 5, 7, 3, 9, 0, 1], [2, 7, 9, 3, 8, 0, 6, 4, 1, 5], [7, 0, 4, 6, 9, 1, 3, 2, 5, 8]];
2766
2767 // Copy (to prevent replacement) and reverse
2768 var str_copy = str.split('').reverse().join('');
2769 var checksum = 0;
2770 for (var i = 0; i < str_copy.length; i++) {
2771 checksum = d_table[checksum][p_table[i % 8][parseInt(str_copy[i], 10)]];
2772 }
2773 return checksum === 0;
2774}
2775
2776/**
2777 * TIN Validation
2778 * Validates Tax Identification Numbers (TINs) from the US, EU member states and the United Kingdom.
2779 *
2780 * EU-UK:
2781 * National TIN validity is calculated using public algorithms as made available by DG TAXUD.
2782 *
2783 * See `https://ec.europa.eu/taxation_customs/tin/specs/FS-TIN%20Algorithms-Public.docx` for more information.
2784 *
2785 * US:
2786 * An Employer Identification Number (EIN), also known as a Federal Tax Identification Number,
2787 * is used to identify a business entity.
2788 *
2789 * NOTES:
2790 * - Prefix 47 is being reserved for future use
2791 * - Prefixes 26, 27, 45, 46 and 47 were previously assigned by the Philadelphia campus.
2792 *
2793 * See `http://www.irs.gov/Businesses/Small-Businesses-&-Self-Employed/How-EINs-are-Assigned-and-Valid-EIN-Prefixes`
2794 * for more information.
2795 */
2796
2797// Locale functions
2798
2799/*
2800 * bg-BG validation function
2801 * (Edinen graždanski nomer (EGN/ЕГН), persons only)
2802 * Checks if birth date (first six digits) is valid and calculates check (last) digit
2803 */
2804function bgBgCheck(tin) {
2805 // Extract full year, normalize month and check birth date validity
2806 var century_year = tin.slice(0, 2);
2807 var month = parseInt(tin.slice(2, 4), 10);
2808 if (month > 40) {
2809 month -= 40;
2810 century_year = "20".concat(century_year);
2811 } else if (month > 20) {
2812 month -= 20;
2813 century_year = "18".concat(century_year);
2814 } else {
2815 century_year = "19".concat(century_year);
2816 }
2817 if (month < 10) {
2818 month = "0".concat(month);
2819 }
2820 var date = "".concat(century_year, "/").concat(month, "/").concat(tin.slice(4, 6));
2821 if (!isDate(date, 'YYYY/MM/DD')) {
2822 return false;
2823 }
2824
2825 // split digits into an array for further processing
2826 var digits = tin.split('').map(function (a) {
2827 return parseInt(a, 10);
2828 });
2829
2830 // Calculate checksum by multiplying digits with fixed values
2831 var multip_lookup = [2, 4, 8, 5, 10, 9, 7, 3, 6];
2832 var checksum = 0;
2833 for (var i = 0; i < multip_lookup.length; i++) {
2834 checksum += digits[i] * multip_lookup[i];
2835 }
2836 checksum = checksum % 11 === 10 ? 0 : checksum % 11;
2837 return checksum === digits[9];
2838}
2839
2840/**
2841 * Check if an input is a valid Canadian SIN (Social Insurance Number)
2842 *
2843 * The Social Insurance Number (SIN) is a 9 digit number that
2844 * you need to work in Canada or to have access to government programs and benefits.
2845 *
2846 * https://en.wikipedia.org/wiki/Social_Insurance_Number
2847 * https://www.canada.ca/en/employment-social-development/services/sin.html
2848 * https://www.codercrunch.com/challenge/819302488/sin-validator
2849 *
2850 * @param {string} input
2851 * @return {boolean}
2852 */
2853function isCanadianSIN(input) {
2854 var digitsArray = input.split('');
2855 var even = digitsArray.filter(function (_, idx) {
2856 return idx % 2;
2857 }).map(function (i) {
2858 return Number(i) * 2;
2859 }).join('').split('');
2860 var total = digitsArray.filter(function (_, idx) {
2861 return !(idx % 2);
2862 }).concat(even).map(function (i) {
2863 return Number(i);
2864 }).reduce(function (acc, cur) {
2865 return acc + cur;
2866 });
2867 return total % 10 === 0;
2868}
2869
2870/*
2871 * cs-CZ validation function
2872 * (Rodné číslo (RČ), persons only)
2873 * Checks if birth date (first six digits) is valid and divisibility by 11
2874 * Material not in DG TAXUD document sourced from:
2875 * -`https://lorenc.info/3MA381/overeni-spravnosti-rodneho-cisla.htm`
2876 * -`https://www.mvcr.cz/clanek/rady-a-sluzby-dokumenty-rodne-cislo.aspx`
2877 */
2878function csCzCheck(tin) {
2879 tin = tin.replace(/\W/, '');
2880
2881 // Extract full year from TIN length
2882 var full_year = parseInt(tin.slice(0, 2), 10);
2883 if (tin.length === 10) {
2884 if (full_year < 54) {
2885 full_year = "20".concat(full_year);
2886 } else {
2887 full_year = "19".concat(full_year);
2888 }
2889 } else {
2890 if (tin.slice(6) === '000') {
2891 return false;
2892 } // Three-zero serial not assigned before 1954
2893 if (full_year < 54) {
2894 full_year = "19".concat(full_year);
2895 } else {
2896 return false; // No 18XX years seen in any of the resources
2897 }
2898 }
2899 // Add missing zero if needed
2900 if (full_year.length === 3) {
2901 full_year = [full_year.slice(0, 2), '0', full_year.slice(2)].join('');
2902 }
2903
2904 // Extract month from TIN and normalize
2905 var month = parseInt(tin.slice(2, 4), 10);
2906 if (month > 50) {
2907 month -= 50;
2908 }
2909 if (month > 20) {
2910 // Month-plus-twenty was only introduced in 2004
2911 if (parseInt(full_year, 10) < 2004) {
2912 return false;
2913 }
2914 month -= 20;
2915 }
2916 if (month < 10) {
2917 month = "0".concat(month);
2918 }
2919
2920 // Check date validity
2921 var date = "".concat(full_year, "/").concat(month, "/").concat(tin.slice(4, 6));
2922 if (!isDate(date, 'YYYY/MM/DD')) {
2923 return false;
2924 }
2925
2926 // Verify divisibility by 11
2927 if (tin.length === 10) {
2928 if (parseInt(tin, 10) % 11 !== 0) {
2929 // Some numbers up to and including 1985 are still valid if
2930 // check (last) digit equals 0 and modulo of first 9 digits equals 10
2931 var checkdigit = parseInt(tin.slice(0, 9), 10) % 11;
2932 if (parseInt(full_year, 10) < 1986 && checkdigit === 10) {
2933 if (parseInt(tin.slice(9), 10) !== 0) {
2934 return false;
2935 }
2936 } else {
2937 return false;
2938 }
2939 }
2940 }
2941 return true;
2942}
2943
2944/*
2945 * de-AT validation function
2946 * (Abgabenkontonummer, persons/entities)
2947 * Verify TIN validity by calling luhnCheck()
2948 */
2949function deAtCheck(tin) {
2950 return luhnCheck(tin);
2951}
2952
2953/*
2954 * de-DE validation function
2955 * (Steueridentifikationsnummer (Steuer-IdNr.), persons only)
2956 * Tests for single duplicate/triplicate value, then calculates ISO 7064 check (last) digit
2957 * Partial implementation of spec (same result with both algorithms always)
2958 */
2959function deDeCheck(tin) {
2960 // Split digits into an array for further processing
2961 var digits = tin.split('').map(function (a) {
2962 return parseInt(a, 10);
2963 });
2964
2965 // Fill array with strings of number positions
2966 var occurences = [];
2967 for (var i = 0; i < digits.length - 1; i++) {
2968 occurences.push('');
2969 for (var j = 0; j < digits.length - 1; j++) {
2970 if (digits[i] === digits[j]) {
2971 occurences[i] += j;
2972 }
2973 }
2974 }
2975
2976 // Remove digits with one occurence and test for only one duplicate/triplicate
2977 occurences = occurences.filter(function (a) {
2978 return a.length > 1;
2979 });
2980 if (occurences.length !== 2 && occurences.length !== 3) {
2981 return false;
2982 }
2983
2984 // In case of triplicate value only two digits are allowed next to each other
2985 if (occurences[0].length === 3) {
2986 var trip_locations = occurences[0].split('').map(function (a) {
2987 return parseInt(a, 10);
2988 });
2989 var recurrent = 0; // Amount of neighbour occurences
2990 for (var _i = 0; _i < trip_locations.length - 1; _i++) {
2991 if (trip_locations[_i] + 1 === trip_locations[_i + 1]) {
2992 recurrent += 1;
2993 }
2994 }
2995 if (recurrent === 2) {
2996 return false;
2997 }
2998 }
2999 return iso7064Check(tin);
3000}
3001
3002/*
3003 * dk-DK validation function
3004 * (CPR-nummer (personnummer), persons only)
3005 * Checks if birth date (first six digits) is valid and assigned to century (seventh) digit,
3006 * and calculates check (last) digit
3007 */
3008function dkDkCheck(tin) {
3009 tin = tin.replace(/\W/, '');
3010
3011 // Extract year, check if valid for given century digit and add century
3012 var year = parseInt(tin.slice(4, 6), 10);
3013 var century_digit = tin.slice(6, 7);
3014 switch (century_digit) {
3015 case '0':
3016 case '1':
3017 case '2':
3018 case '3':
3019 year = "19".concat(year);
3020 break;
3021 case '4':
3022 case '9':
3023 if (year < 37) {
3024 year = "20".concat(year);
3025 } else {
3026 year = "19".concat(year);
3027 }
3028 break;
3029 default:
3030 if (year < 37) {
3031 year = "20".concat(year);
3032 } else if (year > 58) {
3033 year = "18".concat(year);
3034 } else {
3035 return false;
3036 }
3037 break;
3038 }
3039 // Add missing zero if needed
3040 if (year.length === 3) {
3041 year = [year.slice(0, 2), '0', year.slice(2)].join('');
3042 }
3043 // Check date validity
3044 var date = "".concat(year, "/").concat(tin.slice(2, 4), "/").concat(tin.slice(0, 2));
3045 if (!isDate(date, 'YYYY/MM/DD')) {
3046 return false;
3047 }
3048
3049 // Split digits into an array for further processing
3050 var digits = tin.split('').map(function (a) {
3051 return parseInt(a, 10);
3052 });
3053 var checksum = 0;
3054 var weight = 4;
3055 // Multiply by weight and add to checksum
3056 for (var i = 0; i < 9; i++) {
3057 checksum += digits[i] * weight;
3058 weight -= 1;
3059 if (weight === 1) {
3060 weight = 7;
3061 }
3062 }
3063 checksum %= 11;
3064 if (checksum === 1) {
3065 return false;
3066 }
3067 return checksum === 0 ? digits[9] === 0 : digits[9] === 11 - checksum;
3068}
3069
3070/*
3071 * el-CY validation function
3072 * (Arithmos Forologikou Mitroou (AFM/ΑΦΜ), persons only)
3073 * Verify TIN validity by calculating ASCII value of check (last) character
3074 */
3075function elCyCheck(tin) {
3076 // split digits into an array for further processing
3077 var digits = tin.slice(0, 8).split('').map(function (a) {
3078 return parseInt(a, 10);
3079 });
3080 var checksum = 0;
3081 // add digits in even places
3082 for (var i = 1; i < digits.length; i += 2) {
3083 checksum += digits[i];
3084 }
3085
3086 // add digits in odd places
3087 for (var _i2 = 0; _i2 < digits.length; _i2 += 2) {
3088 if (digits[_i2] < 2) {
3089 checksum += 1 - digits[_i2];
3090 } else {
3091 checksum += 2 * (digits[_i2] - 2) + 5;
3092 if (digits[_i2] > 4) {
3093 checksum += 2;
3094 }
3095 }
3096 }
3097 return String.fromCharCode(checksum % 26 + 65) === tin.charAt(8);
3098}
3099
3100/*
3101 * el-GR validation function
3102 * (Arithmos Forologikou Mitroou (AFM/ΑΦΜ), persons/entities)
3103 * Verify TIN validity by calculating check (last) digit
3104 * Algorithm not in DG TAXUD document- sourced from:
3105 * - `http://epixeirisi.gr/%CE%9A%CE%A1%CE%99%CE%A3%CE%99%CE%9C%CE%91-%CE%98%CE%95%CE%9C%CE%91%CE%A4%CE%91-%CE%A6%CE%9F%CE%A1%CE%9F%CE%9B%CE%9F%CE%93%CE%99%CE%91%CE%A3-%CE%9A%CE%91%CE%99-%CE%9B%CE%9F%CE%93%CE%99%CE%A3%CE%A4%CE%99%CE%9A%CE%97%CE%A3/23791/%CE%91%CF%81%CE%B9%CE%B8%CE%BC%CF%8C%CF%82-%CE%A6%CE%BF%CF%81%CE%BF%CE%BB%CE%BF%CE%B3%CE%B9%CE%BA%CE%BF%CF%8D-%CE%9C%CE%B7%CF%84%CF%81%CF%8E%CE%BF%CF%85`
3106 */
3107function elGrCheck(tin) {
3108 // split digits into an array for further processing
3109 var digits = tin.split('').map(function (a) {
3110 return parseInt(a, 10);
3111 });
3112 var checksum = 0;
3113 for (var i = 0; i < 8; i++) {
3114 checksum += digits[i] * Math.pow(2, 8 - i);
3115 }
3116 return checksum % 11 % 10 === digits[8];
3117}
3118
3119/*
3120 * en-GB validation function (should go here if needed)
3121 * (National Insurance Number (NINO) or Unique Taxpayer Reference (UTR),
3122 * persons/entities respectively)
3123 */
3124
3125/*
3126 * en-IE validation function
3127 * (Personal Public Service Number (PPS No), persons only)
3128 * Verify TIN validity by calculating check (second to last) character
3129 */
3130function enIeCheck(tin) {
3131 var checksum = reverseMultiplyAndSum(tin.split('').slice(0, 7).map(function (a) {
3132 return parseInt(a, 10);
3133 }), 8);
3134 if (tin.length === 9 && tin[8] !== 'W') {
3135 checksum += (tin[8].charCodeAt(0) - 64) * 9;
3136 }
3137 checksum %= 23;
3138 if (checksum === 0) {
3139 return tin[7].toUpperCase() === 'W';
3140 }
3141 return tin[7].toUpperCase() === String.fromCharCode(64 + checksum);
3142}
3143
3144// Valid US IRS campus prefixes
3145var enUsCampusPrefix = {
3146 andover: ['10', '12'],
3147 atlanta: ['60', '67'],
3148 austin: ['50', '53'],
3149 brookhaven: ['01', '02', '03', '04', '05', '06', '11', '13', '14', '16', '21', '22', '23', '25', '34', '51', '52', '54', '55', '56', '57', '58', '59', '65'],
3150 cincinnati: ['30', '32', '35', '36', '37', '38', '61'],
3151 fresno: ['15', '24'],
3152 internet: ['20', '26', '27', '45', '46', '47'],
3153 kansas: ['40', '44'],
3154 memphis: ['94', '95'],
3155 ogden: ['80', '90'],
3156 philadelphia: ['33', '39', '41', '42', '43', '46', '48', '62', '63', '64', '66', '68', '71', '72', '73', '74', '75', '76', '77', '81', '82', '83', '84', '85', '86', '87', '88', '91', '92', '93', '98', '99'],
3157 sba: ['31']
3158};
3159
3160// Return an array of all US IRS campus prefixes
3161function enUsGetPrefixes() {
3162 var prefixes = [];
3163 for (var location in enUsCampusPrefix) {
3164 // https://github.com/gotwarlost/istanbul/blob/master/ignoring-code-for-coverage.md#ignoring-code-for-coverage-purposes
3165 // istanbul ignore else
3166 if (enUsCampusPrefix.hasOwnProperty(location)) {
3167 prefixes.push.apply(prefixes, _toConsumableArray(enUsCampusPrefix[location]));
3168 }
3169 }
3170 return prefixes;
3171}
3172
3173/*
3174 * en-US validation function
3175 * Verify that the TIN starts with a valid IRS campus prefix
3176 */
3177function enUsCheck(tin) {
3178 return enUsGetPrefixes().indexOf(tin.slice(0, 2)) !== -1;
3179}
3180
3181/*
3182 * es-AR validation function
3183 * Clave Única de Identificación Tributaria (CUIT/CUIL)
3184 * Sourced from:
3185 * - https://servicioscf.afip.gob.ar/publico/abc/ABCpaso2.aspx?id_nivel1=3036&id_nivel2=3040&p=Conceptos%20b%C3%A1sicos
3186 * - https://es.wikipedia.org/wiki/Clave_%C3%9Anica_de_Identificaci%C3%B3n_Tributaria
3187 */
3188
3189function esArCheck(tin) {
3190 var accum = 0;
3191 var digits = tin.split('');
3192 var digit = parseInt(digits.pop(), 10);
3193 for (var i = 0; i < digits.length; i++) {
3194 accum += digits[9 - i] * (2 + i % 6);
3195 }
3196 var verif = 11 - accum % 11;
3197 if (verif === 11) {
3198 verif = 0;
3199 } else if (verif === 10) {
3200 verif = 9;
3201 }
3202 return digit === verif;
3203}
3204
3205/*
3206 * es-ES validation function
3207 * (Documento Nacional de Identidad (DNI)
3208 * or Número de Identificación de Extranjero (NIE), persons only)
3209 * Verify TIN validity by calculating check (last) character
3210 */
3211function esEsCheck(tin) {
3212 // Split characters into an array for further processing
3213 var chars = tin.toUpperCase().split('');
3214
3215 // Replace initial letter if needed
3216 if (isNaN(parseInt(chars[0], 10)) && chars.length > 1) {
3217 var lead_replace = 0;
3218 switch (chars[0]) {
3219 case 'Y':
3220 lead_replace = 1;
3221 break;
3222 case 'Z':
3223 lead_replace = 2;
3224 break;
3225 default:
3226 }
3227 chars.splice(0, 1, lead_replace);
3228 // Fill with zeros if smaller than proper
3229 } else {
3230 while (chars.length < 9) {
3231 chars.unshift(0);
3232 }
3233 }
3234
3235 // Calculate checksum and check according to lookup
3236 var lookup = ['T', 'R', 'W', 'A', 'G', 'M', 'Y', 'F', 'P', 'D', 'X', 'B', 'N', 'J', 'Z', 'S', 'Q', 'V', 'H', 'L', 'C', 'K', 'E'];
3237 chars = chars.join('');
3238 var checksum = parseInt(chars.slice(0, 8), 10) % 23;
3239 return chars[8] === lookup[checksum];
3240}
3241
3242/*
3243 * et-EE validation function
3244 * (Isikukood (IK), persons only)
3245 * Checks if birth date (century digit and six following) is valid and calculates check (last) digit
3246 * Material not in DG TAXUD document sourced from:
3247 * - `https://www.oecd.org/tax/automatic-exchange/crs-implementation-and-assistance/tax-identification-numbers/Estonia-TIN.pdf`
3248 */
3249function etEeCheck(tin) {
3250 // Extract year and add century
3251 var full_year = tin.slice(1, 3);
3252 var century_digit = tin.slice(0, 1);
3253 switch (century_digit) {
3254 case '1':
3255 case '2':
3256 full_year = "18".concat(full_year);
3257 break;
3258 case '3':
3259 case '4':
3260 full_year = "19".concat(full_year);
3261 break;
3262 default:
3263 full_year = "20".concat(full_year);
3264 break;
3265 }
3266 // Check date validity
3267 var date = "".concat(full_year, "/").concat(tin.slice(3, 5), "/").concat(tin.slice(5, 7));
3268 if (!isDate(date, 'YYYY/MM/DD')) {
3269 return false;
3270 }
3271
3272 // Split digits into an array for further processing
3273 var digits = tin.split('').map(function (a) {
3274 return parseInt(a, 10);
3275 });
3276 var checksum = 0;
3277 var weight = 1;
3278 // Multiply by weight and add to checksum
3279 for (var i = 0; i < 10; i++) {
3280 checksum += digits[i] * weight;
3281 weight += 1;
3282 if (weight === 10) {
3283 weight = 1;
3284 }
3285 }
3286 // Do again if modulo 11 of checksum is 10
3287 if (checksum % 11 === 10) {
3288 checksum = 0;
3289 weight = 3;
3290 for (var _i3 = 0; _i3 < 10; _i3++) {
3291 checksum += digits[_i3] * weight;
3292 weight += 1;
3293 if (weight === 10) {
3294 weight = 1;
3295 }
3296 }
3297 if (checksum % 11 === 10) {
3298 return digits[10] === 0;
3299 }
3300 }
3301 return checksum % 11 === digits[10];
3302}
3303
3304/*
3305 * fi-FI validation function
3306 * (Henkilötunnus (HETU), persons only)
3307 * Checks if birth date (first six digits plus century symbol) is valid
3308 * and calculates check (last) digit
3309 */
3310function fiFiCheck(tin) {
3311 // Extract year and add century
3312 var full_year = tin.slice(4, 6);
3313 var century_symbol = tin.slice(6, 7);
3314 switch (century_symbol) {
3315 case '+':
3316 full_year = "18".concat(full_year);
3317 break;
3318 case '-':
3319 full_year = "19".concat(full_year);
3320 break;
3321 default:
3322 full_year = "20".concat(full_year);
3323 break;
3324 }
3325 // Check date validity
3326 var date = "".concat(full_year, "/").concat(tin.slice(2, 4), "/").concat(tin.slice(0, 2));
3327 if (!isDate(date, 'YYYY/MM/DD')) {
3328 return false;
3329 }
3330
3331 // Calculate check character
3332 var checksum = parseInt(tin.slice(0, 6) + tin.slice(7, 10), 10) % 31;
3333 if (checksum < 10) {
3334 return checksum === parseInt(tin.slice(10), 10);
3335 }
3336 checksum -= 10;
3337 var letters_lookup = ['A', 'B', 'C', 'D', 'E', 'F', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y'];
3338 return letters_lookup[checksum] === tin.slice(10);
3339}
3340
3341/*
3342 * fr/nl-BE validation function
3343 * (Numéro national (N.N.), persons only)
3344 * Checks if birth date (first six digits) is valid and calculates check (last two) digits
3345 */
3346function frBeCheck(tin) {
3347 // Zero month/day value is acceptable
3348 if (tin.slice(2, 4) !== '00' || tin.slice(4, 6) !== '00') {
3349 // Extract date from first six digits of TIN
3350 var date = "".concat(tin.slice(0, 2), "/").concat(tin.slice(2, 4), "/").concat(tin.slice(4, 6));
3351 if (!isDate(date, 'YY/MM/DD')) {
3352 return false;
3353 }
3354 }
3355 var checksum = 97 - parseInt(tin.slice(0, 9), 10) % 97;
3356 var checkdigits = parseInt(tin.slice(9, 11), 10);
3357 if (checksum !== checkdigits) {
3358 checksum = 97 - parseInt("2".concat(tin.slice(0, 9)), 10) % 97;
3359 if (checksum !== checkdigits) {
3360 return false;
3361 }
3362 }
3363 return true;
3364}
3365
3366/*
3367 * fr-FR validation function
3368 * (Numéro fiscal de référence (numéro SPI), persons only)
3369 * Verify TIN validity by calculating check (last three) digits
3370 */
3371function frFrCheck(tin) {
3372 tin = tin.replace(/\s/g, '');
3373 var checksum = parseInt(tin.slice(0, 10), 10) % 511;
3374 var checkdigits = parseInt(tin.slice(10, 13), 10);
3375 return checksum === checkdigits;
3376}
3377
3378/*
3379 * fr/lb-LU validation function
3380 * (numéro d’identification personnelle, persons only)
3381 * Verify birth date validity and run Luhn and Verhoeff checks
3382 */
3383function frLuCheck(tin) {
3384 // Extract date and check validity
3385 var date = "".concat(tin.slice(0, 4), "/").concat(tin.slice(4, 6), "/").concat(tin.slice(6, 8));
3386 if (!isDate(date, 'YYYY/MM/DD')) {
3387 return false;
3388 }
3389
3390 // Run Luhn check
3391 if (!luhnCheck(tin.slice(0, 12))) {
3392 return false;
3393 }
3394 // Remove Luhn check digit and run Verhoeff check
3395 return verhoeffCheck("".concat(tin.slice(0, 11)).concat(tin[12]));
3396}
3397
3398/*
3399 * hr-HR validation function
3400 * (Osobni identifikacijski broj (OIB), persons/entities)
3401 * Verify TIN validity by calling iso7064Check(digits)
3402 */
3403function hrHrCheck(tin) {
3404 return iso7064Check(tin);
3405}
3406
3407/*
3408 * hu-HU validation function
3409 * (Adóazonosító jel, persons only)
3410 * Verify TIN validity by calculating check (last) digit
3411 */
3412function huHuCheck(tin) {
3413 // split digits into an array for further processing
3414 var digits = tin.split('').map(function (a) {
3415 return parseInt(a, 10);
3416 });
3417 var checksum = 8;
3418 for (var i = 1; i < 9; i++) {
3419 checksum += digits[i] * (i + 1);
3420 }
3421 return checksum % 11 === digits[9];
3422}
3423
3424/*
3425 * lt-LT validation function (should go here if needed)
3426 * (Asmens kodas, persons/entities respectively)
3427 * Current validation check is alias of etEeCheck- same format applies
3428 */
3429
3430/*
3431 * it-IT first/last name validity check
3432 * Accepts it-IT TIN-encoded names as a three-element character array and checks their validity
3433 * Due to lack of clarity between resources ("Are only Italian consonants used?
3434 * What happens if a person has X in their name?" etc.) only two test conditions
3435 * have been implemented:
3436 * Vowels may only be followed by other vowels or an X character
3437 * and X characters after vowels may only be followed by other X characters.
3438 */
3439function itItNameCheck(name) {
3440 // true at the first occurence of a vowel
3441 var vowelflag = false;
3442
3443 // true at the first occurence of an X AFTER vowel
3444 // (to properly handle last names with X as consonant)
3445 var xflag = false;
3446 for (var i = 0; i < 3; i++) {
3447 if (!vowelflag && /[AEIOU]/.test(name[i])) {
3448 vowelflag = true;
3449 } else if (!xflag && vowelflag && name[i] === 'X') {
3450 xflag = true;
3451 } else if (i > 0) {
3452 if (vowelflag && !xflag) {
3453 if (!/[AEIOU]/.test(name[i])) {
3454 return false;
3455 }
3456 }
3457 if (xflag) {
3458 if (!/X/.test(name[i])) {
3459 return false;
3460 }
3461 }
3462 }
3463 }
3464 return true;
3465}
3466
3467/*
3468 * it-IT validation function
3469 * (Codice fiscale (TIN-IT), persons only)
3470 * Verify name, birth date and codice catastale validity
3471 * and calculate check character.
3472 * Material not in DG-TAXUD document sourced from:
3473 * `https://en.wikipedia.org/wiki/Italian_fiscal_code`
3474 */
3475function itItCheck(tin) {
3476 // Capitalize and split characters into an array for further processing
3477 var chars = tin.toUpperCase().split('');
3478
3479 // Check first and last name validity calling itItNameCheck()
3480 if (!itItNameCheck(chars.slice(0, 3))) {
3481 return false;
3482 }
3483 if (!itItNameCheck(chars.slice(3, 6))) {
3484 return false;
3485 }
3486
3487 // Convert letters in number spaces back to numbers if any
3488 var number_locations = [6, 7, 9, 10, 12, 13, 14];
3489 var number_replace = {
3490 L: '0',
3491 M: '1',
3492 N: '2',
3493 P: '3',
3494 Q: '4',
3495 R: '5',
3496 S: '6',
3497 T: '7',
3498 U: '8',
3499 V: '9'
3500 };
3501 for (var _i4 = 0, _number_locations = number_locations; _i4 < _number_locations.length; _i4++) {
3502 var i = _number_locations[_i4];
3503 if (chars[i] in number_replace) {
3504 chars.splice(i, 1, number_replace[chars[i]]);
3505 }
3506 }
3507
3508 // Extract month and day, and check date validity
3509 var month_replace = {
3510 A: '01',
3511 B: '02',
3512 C: '03',
3513 D: '04',
3514 E: '05',
3515 H: '06',
3516 L: '07',
3517 M: '08',
3518 P: '09',
3519 R: '10',
3520 S: '11',
3521 T: '12'
3522 };
3523 var month = month_replace[chars[8]];
3524 var day = parseInt(chars[9] + chars[10], 10);
3525 if (day > 40) {
3526 day -= 40;
3527 }
3528 if (day < 10) {
3529 day = "0".concat(day);
3530 }
3531 var date = "".concat(chars[6]).concat(chars[7], "/").concat(month, "/").concat(day);
3532 if (!isDate(date, 'YY/MM/DD')) {
3533 return false;
3534 }
3535
3536 // Calculate check character by adding up even and odd characters as numbers
3537 var checksum = 0;
3538 for (var _i5 = 1; _i5 < chars.length - 1; _i5 += 2) {
3539 var char_to_int = parseInt(chars[_i5], 10);
3540 if (isNaN(char_to_int)) {
3541 char_to_int = chars[_i5].charCodeAt(0) - 65;
3542 }
3543 checksum += char_to_int;
3544 }
3545 var odd_convert = {
3546 // Maps of characters at odd places
3547 A: 1,
3548 B: 0,
3549 C: 5,
3550 D: 7,
3551 E: 9,
3552 F: 13,
3553 G: 15,
3554 H: 17,
3555 I: 19,
3556 J: 21,
3557 K: 2,
3558 L: 4,
3559 M: 18,
3560 N: 20,
3561 O: 11,
3562 P: 3,
3563 Q: 6,
3564 R: 8,
3565 S: 12,
3566 T: 14,
3567 U: 16,
3568 V: 10,
3569 W: 22,
3570 X: 25,
3571 Y: 24,
3572 Z: 23,
3573 0: 1,
3574 1: 0
3575 };
3576 for (var _i6 = 0; _i6 < chars.length - 1; _i6 += 2) {
3577 var _char_to_int = 0;
3578 if (chars[_i6] in odd_convert) {
3579 _char_to_int = odd_convert[chars[_i6]];
3580 } else {
3581 var multiplier = parseInt(chars[_i6], 10);
3582 _char_to_int = 2 * multiplier + 1;
3583 if (multiplier > 4) {
3584 _char_to_int += 2;
3585 }
3586 }
3587 checksum += _char_to_int;
3588 }
3589 if (String.fromCharCode(65 + checksum % 26) !== chars[15]) {
3590 return false;
3591 }
3592 return true;
3593}
3594
3595/*
3596 * lv-LV validation function
3597 * (Personas kods (PK), persons only)
3598 * Check validity of birth date and calculate check (last) digit
3599 * Support only for old format numbers (not starting with '32', issued before 2017/07/01)
3600 * Material not in DG TAXUD document sourced from:
3601 * `https://boot.ritakafija.lv/forums/index.php?/topic/88314-personas-koda-algoritms-%C4%8Deksumma/`
3602 */
3603function lvLvCheck(tin) {
3604 tin = tin.replace(/\W/, '');
3605 // Extract date from TIN
3606 var day = tin.slice(0, 2);
3607 if (day !== '32') {
3608 // No date/checksum check if new format
3609 var month = tin.slice(2, 4);
3610 if (month !== '00') {
3611 // No date check if unknown month
3612 var full_year = tin.slice(4, 6);
3613 switch (tin[6]) {
3614 case '0':
3615 full_year = "18".concat(full_year);
3616 break;
3617 case '1':
3618 full_year = "19".concat(full_year);
3619 break;
3620 default:
3621 full_year = "20".concat(full_year);
3622 break;
3623 }
3624 // Check date validity
3625 var date = "".concat(full_year, "/").concat(tin.slice(2, 4), "/").concat(day);
3626 if (!isDate(date, 'YYYY/MM/DD')) {
3627 return false;
3628 }
3629 }
3630
3631 // Calculate check digit
3632 var checksum = 1101;
3633 var multip_lookup = [1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
3634 for (var i = 0; i < tin.length - 1; i++) {
3635 checksum -= parseInt(tin[i], 10) * multip_lookup[i];
3636 }
3637 return parseInt(tin[10], 10) === checksum % 11;
3638 }
3639 return true;
3640}
3641
3642/*
3643 * mt-MT validation function
3644 * (Identity Card Number or Unique Taxpayer Reference, persons/entities)
3645 * Verify Identity Card Number structure (no other tests found)
3646 */
3647function mtMtCheck(tin) {
3648 if (tin.length !== 9) {
3649 // No tests for UTR
3650 var chars = tin.toUpperCase().split('');
3651 // Fill with zeros if smaller than proper
3652 while (chars.length < 8) {
3653 chars.unshift(0);
3654 }
3655 // Validate format according to last character
3656 switch (tin[7]) {
3657 case 'A':
3658 case 'P':
3659 if (parseInt(chars[6], 10) === 0) {
3660 return false;
3661 }
3662 break;
3663 default:
3664 {
3665 var first_part = parseInt(chars.join('').slice(0, 5), 10);
3666 if (first_part > 32000) {
3667 return false;
3668 }
3669 var second_part = parseInt(chars.join('').slice(5, 7), 10);
3670 if (first_part === second_part) {
3671 return false;
3672 }
3673 }
3674 }
3675 }
3676 return true;
3677}
3678
3679/*
3680 * nl-NL validation function
3681 * (Burgerservicenummer (BSN) or Rechtspersonen Samenwerkingsverbanden Informatie Nummer (RSIN),
3682 * persons/entities respectively)
3683 * Verify TIN validity by calculating check (last) digit (variant of MOD 11)
3684 */
3685function nlNlCheck(tin) {
3686 return reverseMultiplyAndSum(tin.split('').slice(0, 8).map(function (a) {
3687 return parseInt(a, 10);
3688 }), 9) % 11 === parseInt(tin[8], 10);
3689}
3690
3691/*
3692 * pl-PL validation function
3693 * (Powszechny Elektroniczny System Ewidencji Ludności (PESEL)
3694 * or Numer identyfikacji podatkowej (NIP), persons/entities)
3695 * Verify TIN validity by validating birth date (PESEL) and calculating check (last) digit
3696 */
3697function plPlCheck(tin) {
3698 // NIP
3699 if (tin.length === 10) {
3700 // Calculate last digit by multiplying with lookup
3701 var lookup = [6, 5, 7, 2, 3, 4, 5, 6, 7];
3702 var _checksum = 0;
3703 for (var i = 0; i < lookup.length; i++) {
3704 _checksum += parseInt(tin[i], 10) * lookup[i];
3705 }
3706 _checksum %= 11;
3707 if (_checksum === 10) {
3708 return false;
3709 }
3710 return _checksum === parseInt(tin[9], 10);
3711 }
3712
3713 // PESEL
3714 // Extract full year using month
3715 var full_year = tin.slice(0, 2);
3716 var month = parseInt(tin.slice(2, 4), 10);
3717 if (month > 80) {
3718 full_year = "18".concat(full_year);
3719 month -= 80;
3720 } else if (month > 60) {
3721 full_year = "22".concat(full_year);
3722 month -= 60;
3723 } else if (month > 40) {
3724 full_year = "21".concat(full_year);
3725 month -= 40;
3726 } else if (month > 20) {
3727 full_year = "20".concat(full_year);
3728 month -= 20;
3729 } else {
3730 full_year = "19".concat(full_year);
3731 }
3732 // Add leading zero to month if needed
3733 if (month < 10) {
3734 month = "0".concat(month);
3735 }
3736 // Check date validity
3737 var date = "".concat(full_year, "/").concat(month, "/").concat(tin.slice(4, 6));
3738 if (!isDate(date, 'YYYY/MM/DD')) {
3739 return false;
3740 }
3741
3742 // Calculate last digit by mulitplying with odd one-digit numbers except 5
3743 var checksum = 0;
3744 var multiplier = 1;
3745 for (var _i7 = 0; _i7 < tin.length - 1; _i7++) {
3746 checksum += parseInt(tin[_i7], 10) * multiplier % 10;
3747 multiplier += 2;
3748 if (multiplier > 10) {
3749 multiplier = 1;
3750 } else if (multiplier === 5) {
3751 multiplier += 2;
3752 }
3753 }
3754 checksum = 10 - checksum % 10;
3755 return checksum === parseInt(tin[10], 10);
3756}
3757
3758/*
3759* pt-BR validation function
3760* (Cadastro de Pessoas Físicas (CPF, persons)
3761* Cadastro Nacional de Pessoas Jurídicas (CNPJ, entities)
3762* Both inputs will be validated
3763*/
3764
3765function ptBrCheck(tin) {
3766 if (tin.length === 11) {
3767 var _sum;
3768 var remainder;
3769 _sum = 0;
3770 if (
3771 // Reject known invalid CPFs
3772 tin === '11111111111' || tin === '22222222222' || tin === '33333333333' || tin === '44444444444' || tin === '55555555555' || tin === '66666666666' || tin === '77777777777' || tin === '88888888888' || tin === '99999999999' || tin === '00000000000') return false;
3773 for (var i = 1; i <= 9; i++) _sum += parseInt(tin.substring(i - 1, i), 10) * (11 - i);
3774 remainder = _sum * 10 % 11;
3775 if (remainder === 10) remainder = 0;
3776 if (remainder !== parseInt(tin.substring(9, 10), 10)) return false;
3777 _sum = 0;
3778 for (var _i8 = 1; _i8 <= 10; _i8++) _sum += parseInt(tin.substring(_i8 - 1, _i8), 10) * (12 - _i8);
3779 remainder = _sum * 10 % 11;
3780 if (remainder === 10) remainder = 0;
3781 if (remainder !== parseInt(tin.substring(10, 11), 10)) return false;
3782 return true;
3783 }
3784 if (
3785 // Reject know invalid CNPJs
3786 tin === '00000000000000' || tin === '11111111111111' || tin === '22222222222222' || tin === '33333333333333' || tin === '44444444444444' || tin === '55555555555555' || tin === '66666666666666' || tin === '77777777777777' || tin === '88888888888888' || tin === '99999999999999') {
3787 return false;
3788 }
3789 var length = tin.length - 2;
3790 var identifiers = tin.substring(0, length);
3791 var verificators = tin.substring(length);
3792 var sum = 0;
3793 var pos = length - 7;
3794 for (var _i9 = length; _i9 >= 1; _i9--) {
3795 sum += identifiers.charAt(length - _i9) * pos;
3796 pos -= 1;
3797 if (pos < 2) {
3798 pos = 9;
3799 }
3800 }
3801 var result = sum % 11 < 2 ? 0 : 11 - sum % 11;
3802 if (result !== parseInt(verificators.charAt(0), 10)) {
3803 return false;
3804 }
3805 length += 1;
3806 identifiers = tin.substring(0, length);
3807 sum = 0;
3808 pos = length - 7;
3809 for (var _i10 = length; _i10 >= 1; _i10--) {
3810 sum += identifiers.charAt(length - _i10) * pos;
3811 pos -= 1;
3812 if (pos < 2) {
3813 pos = 9;
3814 }
3815 }
3816 result = sum % 11 < 2 ? 0 : 11 - sum % 11;
3817 if (result !== parseInt(verificators.charAt(1), 10)) {
3818 return false;
3819 }
3820 return true;
3821}
3822
3823/*
3824 * pt-PT validation function
3825 * (Número de identificação fiscal (NIF), persons/entities)
3826 * Verify TIN validity by calculating check (last) digit (variant of MOD 11)
3827 */
3828function ptPtCheck(tin) {
3829 var checksum = 11 - reverseMultiplyAndSum(tin.split('').slice(0, 8).map(function (a) {
3830 return parseInt(a, 10);
3831 }), 9) % 11;
3832 if (checksum > 9) {
3833 return parseInt(tin[8], 10) === 0;
3834 }
3835 return checksum === parseInt(tin[8], 10);
3836}
3837
3838/*
3839 * ro-RO validation function
3840 * (Cod Numeric Personal (CNP) or Cod de înregistrare fiscală (CIF),
3841 * persons only)
3842 * Verify CNP validity by calculating check (last) digit (test not found for CIF)
3843 * Material not in DG TAXUD document sourced from:
3844 * `https://en.wikipedia.org/wiki/National_identification_number#Romania`
3845 */
3846function roRoCheck(tin) {
3847 if (tin.slice(0, 4) !== '9000') {
3848 // No test found for this format
3849 // Extract full year using century digit if possible
3850 var full_year = tin.slice(1, 3);
3851 switch (tin[0]) {
3852 case '1':
3853 case '2':
3854 full_year = "19".concat(full_year);
3855 break;
3856 case '3':
3857 case '4':
3858 full_year = "18".concat(full_year);
3859 break;
3860 case '5':
3861 case '6':
3862 full_year = "20".concat(full_year);
3863 break;
3864 default:
3865 }
3866
3867 // Check date validity
3868 var date = "".concat(full_year, "/").concat(tin.slice(3, 5), "/").concat(tin.slice(5, 7));
3869 if (date.length === 8) {
3870 if (!isDate(date, 'YY/MM/DD')) {
3871 return false;
3872 }
3873 } else if (!isDate(date, 'YYYY/MM/DD')) {
3874 return false;
3875 }
3876
3877 // Calculate check digit
3878 var digits = tin.split('').map(function (a) {
3879 return parseInt(a, 10);
3880 });
3881 var multipliers = [2, 7, 9, 1, 4, 6, 3, 5, 8, 2, 7, 9];
3882 var checksum = 0;
3883 for (var i = 0; i < multipliers.length; i++) {
3884 checksum += digits[i] * multipliers[i];
3885 }
3886 if (checksum % 11 === 10) {
3887 return digits[12] === 1;
3888 }
3889 return digits[12] === checksum % 11;
3890 }
3891 return true;
3892}
3893
3894/*
3895 * sk-SK validation function
3896 * (Rodné číslo (RČ) or bezvýznamové identifikačné číslo (BIČ), persons only)
3897 * Checks validity of pre-1954 birth numbers (rodné číslo) only
3898 * Due to the introduction of the pseudo-random BIČ it is not possible to test
3899 * post-1954 birth numbers without knowing whether they are BIČ or RČ beforehand
3900 */
3901function skSkCheck(tin) {
3902 if (tin.length === 9) {
3903 tin = tin.replace(/\W/, '');
3904 if (tin.slice(6) === '000') {
3905 return false;
3906 } // Three-zero serial not assigned before 1954
3907
3908 // Extract full year from TIN length
3909 var full_year = parseInt(tin.slice(0, 2), 10);
3910 if (full_year > 53) {
3911 return false;
3912 }
3913 if (full_year < 10) {
3914 full_year = "190".concat(full_year);
3915 } else {
3916 full_year = "19".concat(full_year);
3917 }
3918
3919 // Extract month from TIN and normalize
3920 var month = parseInt(tin.slice(2, 4), 10);
3921 if (month > 50) {
3922 month -= 50;
3923 }
3924 if (month < 10) {
3925 month = "0".concat(month);
3926 }
3927
3928 // Check date validity
3929 var date = "".concat(full_year, "/").concat(month, "/").concat(tin.slice(4, 6));
3930 if (!isDate(date, 'YYYY/MM/DD')) {
3931 return false;
3932 }
3933 }
3934 return true;
3935}
3936
3937/*
3938 * sl-SI validation function
3939 * (Davčna številka, persons/entities)
3940 * Verify TIN validity by calculating check (last) digit (variant of MOD 11)
3941 */
3942function slSiCheck(tin) {
3943 var checksum = 11 - reverseMultiplyAndSum(tin.split('').slice(0, 7).map(function (a) {
3944 return parseInt(a, 10);
3945 }), 8) % 11;
3946 if (checksum === 10) {
3947 return parseInt(tin[7], 10) === 0;
3948 }
3949 return checksum === parseInt(tin[7], 10);
3950}
3951
3952/*
3953 * sv-SE validation function
3954 * (Personnummer or samordningsnummer, persons only)
3955 * Checks validity of birth date and calls luhnCheck() to validate check (last) digit
3956 */
3957function svSeCheck(tin) {
3958 // Make copy of TIN and normalize to two-digit year form
3959 var tin_copy = tin.slice(0);
3960 if (tin.length > 11) {
3961 tin_copy = tin_copy.slice(2);
3962 }
3963
3964 // Extract date of birth
3965 var full_year = '';
3966 var month = tin_copy.slice(2, 4);
3967 var day = parseInt(tin_copy.slice(4, 6), 10);
3968 if (tin.length > 11) {
3969 full_year = tin.slice(0, 4);
3970 } else {
3971 full_year = tin.slice(0, 2);
3972 if (tin.length === 11 && day < 60) {
3973 // Extract full year from centenarian symbol
3974 // Should work just fine until year 10000 or so
3975 var current_year = new Date().getFullYear().toString();
3976 var current_century = parseInt(current_year.slice(0, 2), 10);
3977 current_year = parseInt(current_year, 10);
3978 if (tin[6] === '-') {
3979 if (parseInt("".concat(current_century).concat(full_year), 10) > current_year) {
3980 full_year = "".concat(current_century - 1).concat(full_year);
3981 } else {
3982 full_year = "".concat(current_century).concat(full_year);
3983 }
3984 } else {
3985 full_year = "".concat(current_century - 1).concat(full_year);
3986 if (current_year - parseInt(full_year, 10) < 100) {
3987 return false;
3988 }
3989 }
3990 }
3991 }
3992
3993 // Normalize day and check date validity
3994 if (day > 60) {
3995 day -= 60;
3996 }
3997 if (day < 10) {
3998 day = "0".concat(day);
3999 }
4000 var date = "".concat(full_year, "/").concat(month, "/").concat(day);
4001 if (date.length === 8) {
4002 if (!isDate(date, 'YY/MM/DD')) {
4003 return false;
4004 }
4005 } else if (!isDate(date, 'YYYY/MM/DD')) {
4006 return false;
4007 }
4008 return luhnCheck(tin.replace(/\W/, ''));
4009}
4010
4011/**
4012 * uk-UA validation function
4013 * Verify TIN validity by calculating check (last) digit (variant of MOD 11)
4014 */
4015function ukUaCheck(tin) {
4016 // Calculate check digit
4017 var digits = tin.split('').map(function (a) {
4018 return parseInt(a, 10);
4019 });
4020 var multipliers = [-1, 5, 7, 9, 4, 6, 10, 5, 7];
4021 var checksum = 0;
4022 for (var i = 0; i < multipliers.length; i++) {
4023 checksum += digits[i] * multipliers[i];
4024 }
4025 return checksum % 11 === 10 ? digits[9] === 0 : digits[9] === checksum % 11;
4026}
4027
4028// Locale lookup objects
4029
4030/*
4031 * Tax id regex formats for various locales
4032 *
4033 * Where not explicitly specified in DG-TAXUD document both
4034 * uppercase and lowercase letters are acceptable.
4035 */
4036var taxIdFormat = {
4037 'bg-BG': /^\d{10}$/,
4038 'cs-CZ': /^\d{6}\/{0,1}\d{3,4}$/,
4039 'de-AT': /^\d{9}$/,
4040 'de-DE': /^[1-9]\d{10}$/,
4041 'dk-DK': /^\d{6}-{0,1}\d{4}$/,
4042 'el-CY': /^[09]\d{7}[A-Z]$/,
4043 'el-GR': /^([0-4]|[7-9])\d{8}$/,
4044 'en-CA': /^\d{9}$/,
4045 'en-GB': /^\d{10}$|^(?!GB|NK|TN|ZZ)(?![DFIQUV])[A-Z](?![DFIQUVO])[A-Z]\d{6}[ABCD ]$/i,
4046 'en-IE': /^\d{7}[A-W][A-IW]{0,1}$/i,
4047 'en-US': /^\d{2}[- ]{0,1}\d{7}$/,
4048 'es-AR': /(20|23|24|27|30|33|34)[0-9]{8}[0-9]/,
4049 'es-ES': /^(\d{0,8}|[XYZKLM]\d{7})[A-HJ-NP-TV-Z]$/i,
4050 'et-EE': /^[1-6]\d{6}(00[1-9]|0[1-9][0-9]|[1-6][0-9]{2}|70[0-9]|710)\d$/,
4051 'fi-FI': /^\d{6}[-+A]\d{3}[0-9A-FHJ-NPR-Y]$/i,
4052 'fr-BE': /^\d{11}$/,
4053 'fr-FR': /^[0-3]\d{12}$|^[0-3]\d\s\d{2}(\s\d{3}){3}$/,
4054 // Conforms both to official spec and provided example
4055 'fr-LU': /^\d{13}$/,
4056 'hr-HR': /^\d{11}$/,
4057 'hu-HU': /^8\d{9}$/,
4058 'it-IT': /^[A-Z]{6}[L-NP-V0-9]{2}[A-EHLMPRST][L-NP-V0-9]{2}[A-ILMZ][L-NP-V0-9]{3}[A-Z]$/i,
4059 'lv-LV': /^\d{6}-{0,1}\d{5}$/,
4060 // Conforms both to DG TAXUD spec and original research
4061 'mt-MT': /^\d{3,7}[APMGLHBZ]$|^([1-8])\1\d{7}$/i,
4062 'nl-NL': /^\d{9}$/,
4063 'pl-PL': /^\d{10,11}$/,
4064 'pt-BR': /(?:^\d{11}$)|(?:^\d{14}$)/,
4065 'pt-PT': /^\d{9}$/,
4066 'ro-RO': /^\d{13}$/,
4067 'sk-SK': /^\d{6}\/{0,1}\d{3,4}$/,
4068 'sl-SI': /^[1-9]\d{7}$/,
4069 'sv-SE': /^(\d{6}[-+]{0,1}\d{4}|(18|19|20)\d{6}[-+]{0,1}\d{4})$/,
4070 'uk-UA': /^\d{10}$/
4071};
4072// taxIdFormat locale aliases
4073taxIdFormat['lb-LU'] = taxIdFormat['fr-LU'];
4074taxIdFormat['lt-LT'] = taxIdFormat['et-EE'];
4075taxIdFormat['nl-BE'] = taxIdFormat['fr-BE'];
4076taxIdFormat['fr-CA'] = taxIdFormat['en-CA'];
4077
4078// Algorithmic tax id check functions for various locales
4079var taxIdCheck = {
4080 'bg-BG': bgBgCheck,
4081 'cs-CZ': csCzCheck,
4082 'de-AT': deAtCheck,
4083 'de-DE': deDeCheck,
4084 'dk-DK': dkDkCheck,
4085 'el-CY': elCyCheck,
4086 'el-GR': elGrCheck,
4087 'en-CA': isCanadianSIN,
4088 'en-IE': enIeCheck,
4089 'en-US': enUsCheck,
4090 'es-AR': esArCheck,
4091 'es-ES': esEsCheck,
4092 'et-EE': etEeCheck,
4093 'fi-FI': fiFiCheck,
4094 'fr-BE': frBeCheck,
4095 'fr-FR': frFrCheck,
4096 'fr-LU': frLuCheck,
4097 'hr-HR': hrHrCheck,
4098 'hu-HU': huHuCheck,
4099 'it-IT': itItCheck,
4100 'lv-LV': lvLvCheck,
4101 'mt-MT': mtMtCheck,
4102 'nl-NL': nlNlCheck,
4103 'pl-PL': plPlCheck,
4104 'pt-BR': ptBrCheck,
4105 'pt-PT': ptPtCheck,
4106 'ro-RO': roRoCheck,
4107 'sk-SK': skSkCheck,
4108 'sl-SI': slSiCheck,
4109 'sv-SE': svSeCheck,
4110 'uk-UA': ukUaCheck
4111};
4112// taxIdCheck locale aliases
4113taxIdCheck['lb-LU'] = taxIdCheck['fr-LU'];
4114taxIdCheck['lt-LT'] = taxIdCheck['et-EE'];
4115taxIdCheck['nl-BE'] = taxIdCheck['fr-BE'];
4116taxIdCheck['fr-CA'] = taxIdCheck['en-CA'];
4117
4118// Regexes for locales where characters should be omitted before checking format
4119var allsymbols = /[-\\\/!@#$%\^&\*\(\)\+\=\[\]]+/g;
4120var sanitizeRegexes = {
4121 'de-AT': allsymbols,
4122 'de-DE': /[\/\\]/g,
4123 'fr-BE': allsymbols
4124};
4125// sanitizeRegexes locale aliases
4126sanitizeRegexes['nl-BE'] = sanitizeRegexes['fr-BE'];
4127
4128/*
4129 * Validator function
4130 * Return true if the passed string is a valid tax identification number
4131 * for the specified locale.
4132 * Throw an error exception if the locale is not supported.
4133 */
4134function isTaxID(str) {
4135 var locale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'en-US';
4136 assertString(str);
4137 // Copy TIN to avoid replacement if sanitized
4138 var strcopy = str.slice(0);
4139 if (locale in taxIdFormat) {
4140 if (locale in sanitizeRegexes) {
4141 strcopy = strcopy.replace(sanitizeRegexes[locale], '');
4142 }
4143 if (!taxIdFormat[locale].test(strcopy)) {
4144 return false;
4145 }
4146 if (locale in taxIdCheck) {
4147 return taxIdCheck[locale](strcopy);
4148 }
4149 // Fallthrough; not all locales have algorithmic checks
4150 return true;
4151 }
4152 throw new Error("Invalid locale '".concat(locale, "'"));
4153}
4154
4155/* eslint-disable max-len */
4156var phones = {
4157 'am-AM': /^(\+?374|0)(33|4[134]|55|77|88|9[13-689])\d{6}$/,
4158 'ar-AE': /^((\+?971)|0)?5[024568]\d{7}$/,
4159 'ar-BH': /^(\+?973)?(3|6)\d{7}$/,
4160 'ar-DZ': /^(\+?213|0)(5|6|7)\d{8}$/,
4161 'ar-LB': /^(\+?961)?((3|81)\d{6}|7\d{7})$/,
4162 'ar-EG': /^((\+?20)|0)?1[0125]\d{8}$/,
4163 'ar-IQ': /^(\+?964|0)?7[0-9]\d{8}$/,
4164 'ar-JO': /^(\+?962|0)?7[789]\d{7}$/,
4165 'ar-KW': /^(\+?965)([569]\d{7}|41\d{6})$/,
4166 'ar-LY': /^((\+?218)|0)?(9[1-6]\d{7}|[1-8]\d{7,9})$/,
4167 'ar-MA': /^(?:(?:\+|00)212|0)[5-7]\d{8}$/,
4168 'ar-OM': /^((\+|00)968)?(9[1-9])\d{6}$/,
4169 'ar-PS': /^(\+?970|0)5[6|9](\d{7})$/,
4170 'ar-SA': /^(!?(\+?966)|0)?5\d{8}$/,
4171 'ar-SD': /^((\+?249)|0)?(9[012369]|1[012])\d{7}$/,
4172 'ar-SY': /^(!?(\+?963)|0)?9\d{8}$/,
4173 'ar-TN': /^(\+?216)?[2459]\d{7}$/,
4174 'az-AZ': /^(\+994|0)(10|5[015]|7[07]|99)\d{7}$/,
4175 'bs-BA': /^((((\+|00)3876)|06))((([0-3]|[5-6])\d{6})|(4\d{7}))$/,
4176 'be-BY': /^(\+?375)?(24|25|29|33|44)\d{7}$/,
4177 'bg-BG': /^(\+?359|0)?8[789]\d{7}$/,
4178 'bn-BD': /^(\+?880|0)1[13456789][0-9]{8}$/,
4179 'ca-AD': /^(\+376)?[346]\d{5}$/,
4180 'cs-CZ': /^(\+?420)? ?[1-9][0-9]{2} ?[0-9]{3} ?[0-9]{3}$/,
4181 'da-DK': /^(\+?45)?\s?\d{2}\s?\d{2}\s?\d{2}\s?\d{2}$/,
4182 'de-DE': /^((\+49|0)1)(5[0-25-9]\d|6([23]|0\d?)|7([0-57-9]|6\d))\d{7,9}$/,
4183 'de-AT': /^(\+43|0)\d{1,4}\d{3,12}$/,
4184 'de-CH': /^(\+41|0)([1-9])\d{1,9}$/,
4185 'de-LU': /^(\+352)?((6\d1)\d{6})$/,
4186 'dv-MV': /^(\+?960)?(7[2-9]|9[1-9])\d{5}$/,
4187 'el-GR': /^(\+?30|0)?6(8[5-9]|9(?![26])[0-9])\d{7}$/,
4188 'el-CY': /^(\+?357?)?(9(9|6)\d{6})$/,
4189 'en-AI': /^(\+?1|0)264(?:2(35|92)|4(?:6[1-2]|76|97)|5(?:3[6-9]|8[1-4])|7(?:2(4|9)|72))\d{4}$/,
4190 'en-AU': /^(\+?61|0)4\d{8}$/,
4191 'en-AG': /^(?:\+1|1)268(?:464|7(?:1[3-9]|[28]\d|3[0246]|64|7[0-689]))\d{4}$/,
4192 'en-BM': /^(\+?1)?441(((3|7)\d{6}$)|(5[0-3][0-9]\d{4}$)|(59\d{5}$))/,
4193 'en-BS': /^(\+?1[-\s]?|0)?\(?242\)?[-\s]?\d{3}[-\s]?\d{4}$/,
4194 'en-GB': /^(\+?44|0)7\d{9}$/,
4195 'en-GG': /^(\+?44|0)1481\d{6}$/,
4196 'en-GH': /^(\+233|0)(20|50|24|54|27|57|26|56|23|28|55|59)\d{7}$/,
4197 'en-GY': /^(\+592|0)6\d{6}$/,
4198 'en-HK': /^(\+?852[-\s]?)?[456789]\d{3}[-\s]?\d{4}$/,
4199 'en-MO': /^(\+?853[-\s]?)?[6]\d{3}[-\s]?\d{4}$/,
4200 'en-IE': /^(\+?353|0)8[356789]\d{7}$/,
4201 'en-IN': /^(\+?91|0)?[6789]\d{9}$/,
4202 'en-JM': /^(\+?876)?\d{7}$/,
4203 'en-KE': /^(\+?254|0)(7|1)\d{8}$/,
4204 'fr-CF': /^(\+?236| ?)(70|75|77|72|21|22)\d{6}$/,
4205 'en-SS': /^(\+?211|0)(9[1257])\d{7}$/,
4206 'en-KI': /^((\+686|686)?)?( )?((6|7)(2|3|8)[0-9]{6})$/,
4207 'en-KN': /^(?:\+1|1)869(?:46\d|48[89]|55[6-8]|66\d|76[02-7])\d{4}$/,
4208 'en-LS': /^(\+?266)(22|28|57|58|59|27|52)\d{6}$/,
4209 'en-MT': /^(\+?356|0)?(99|79|77|21|27|22|25)[0-9]{6}$/,
4210 'en-MU': /^(\+?230|0)?\d{8}$/,
4211 'en-MW': /^(\+?265|0)(((77|88|31|99|98|21)\d{7})|(((111)|1)\d{6})|(32000\d{4}))$/,
4212 'en-NA': /^(\+?264|0)(6|8)\d{7}$/,
4213 'en-NG': /^(\+?234|0)?[789]\d{9}$/,
4214 'en-NZ': /^(\+?64|0)[28]\d{7,9}$/,
4215 'en-PG': /^(\+?675|0)?(7\d|8[18])\d{6}$/,
4216 'en-PK': /^((00|\+)?92|0)3[0-6]\d{8}$/,
4217 'en-PH': /^(09|\+639)\d{9}$/,
4218 'en-RW': /^(\+?250|0)?[7]\d{8}$/,
4219 'en-SG': /^(\+65)?[3689]\d{7}$/,
4220 'en-SL': /^(\+?232|0)\d{8}$/,
4221 'en-TZ': /^(\+?255|0)?[67]\d{8}$/,
4222 'en-UG': /^(\+?256|0)?[7]\d{8}$/,
4223 'en-US': /^((\+1|1)?( |-)?)?(\([2-9][0-9]{2}\)|[2-9][0-9]{2})( |-)?([2-9][0-9]{2}( |-)?[0-9]{4})$/,
4224 'en-ZA': /^(\+?27|0)\d{9}$/,
4225 'en-ZM': /^(\+?26)?09[567]\d{7}$/,
4226 'en-ZW': /^(\+263)[0-9]{9}$/,
4227 'en-BW': /^(\+?267)?(7[1-8]{1})\d{6}$/,
4228 'es-AR': /^\+?549(11|[2368]\d)\d{8}$/,
4229 'es-BO': /^(\+?591)?(6|7)\d{7}$/,
4230 'es-CO': /^(\+?57)?3(0(0|1|2|4|5)|1\d|2[0-4]|5(0|1))\d{7}$/,
4231 'es-CL': /^(\+?56|0)[2-9]\d{1}\d{7}$/,
4232 'es-CR': /^(\+506)?[2-8]\d{7}$/,
4233 'es-CU': /^(\+53|0053)?5\d{7}$/,
4234 'es-DO': /^(\+?1)?8[024]9\d{7}$/,
4235 'es-HN': /^(\+?504)?[9|8|3|2]\d{7}$/,
4236 'es-EC': /^(\+?593|0)([2-7]|9[2-9])\d{7}$/,
4237 'es-ES': /^(\+?34)?[6|7]\d{8}$/,
4238 'es-PE': /^(\+?51)?9\d{8}$/,
4239 'es-MX': /^(\+?52)?(1|01)?\d{10,11}$/,
4240 'es-NI': /^(\+?505)\d{7,8}$/,
4241 'es-PA': /^(\+?507)\d{7,8}$/,
4242 'es-PY': /^(\+?595|0)9[9876]\d{7}$/,
4243 'es-SV': /^(\+?503)?[67]\d{7}$/,
4244 'es-UY': /^(\+598|0)9[1-9][\d]{6}$/,
4245 'es-VE': /^(\+?58)?(2|4)\d{9}$/,
4246 'et-EE': /^(\+?372)?\s?(5|8[1-4])\s?([0-9]\s?){6,7}$/,
4247 'fa-IR': /^(\+?98[\-\s]?|0)9[0-39]\d[\-\s]?\d{3}[\-\s]?\d{4}$/,
4248 'fi-FI': /^(\+?358|0)\s?(4[0-6]|50)\s?(\d\s?){4,8}$/,
4249 'fj-FJ': /^(\+?679)?\s?\d{3}\s?\d{4}$/,
4250 'fo-FO': /^(\+?298)?\s?\d{2}\s?\d{2}\s?\d{2}$/,
4251 'fr-BF': /^(\+226|0)[67]\d{7}$/,
4252 'fr-BJ': /^(\+229)\d{8}$/,
4253 'fr-CD': /^(\+?243|0)?(8|9)\d{8}$/,
4254 'fr-CM': /^(\+?237)6[0-9]{8}$/,
4255 'fr-FR': /^(\+?33|0)[67]\d{8}$/,
4256 'fr-GF': /^(\+?594|0|00594)[67]\d{8}$/,
4257 'fr-GP': /^(\+?590|0|00590)[67]\d{8}$/,
4258 'fr-MQ': /^(\+?596|0|00596)[67]\d{8}$/,
4259 'fr-PF': /^(\+?689)?8[789]\d{6}$/,
4260 'fr-RE': /^(\+?262|0|00262)[67]\d{8}$/,
4261 'fr-WF': /^(\+681)?\d{6}$/,
4262 'he-IL': /^(\+972|0)([23489]|5[012345689]|77)[1-9]\d{6}$/,
4263 'hu-HU': /^(\+?36|06)(20|30|31|50|70)\d{7}$/,
4264 'id-ID': /^(\+?62|0)8(1[123456789]|2[1238]|3[1238]|5[12356789]|7[78]|9[56789]|8[123456789])([\s?|\d]{5,11})$/,
4265 'ir-IR': /^(\+98|0)?9\d{9}$/,
4266 'it-IT': /^(\+?39)?\s?3\d{2} ?\d{6,7}$/,
4267 'it-SM': /^((\+378)|(0549)|(\+390549)|(\+3780549))?6\d{5,9}$/,
4268 'ja-JP': /^(\+81[ \-]?(\(0\))?|0)[6789]0[ \-]?\d{4}[ \-]?\d{4}$/,
4269 'ka-GE': /^(\+?995)?(79\d{7}|5\d{8})$/,
4270 'kk-KZ': /^(\+?7|8)?7\d{9}$/,
4271 'kl-GL': /^(\+?299)?\s?\d{2}\s?\d{2}\s?\d{2}$/,
4272 'ko-KR': /^((\+?82)[ \-]?)?0?1([0|1|6|7|8|9]{1})[ \-]?\d{3,4}[ \-]?\d{4}$/,
4273 'ky-KG': /^(\+?7\s?\+?7|0)\s?\d{2}\s?\d{3}\s?\d{4}$/,
4274 'lt-LT': /^(\+370|8)\d{8}$/,
4275 'lv-LV': /^(\+?371)2\d{7}$/,
4276 'mg-MG': /^((\+?261|0)(2|3)\d)?\d{7}$/,
4277 'mn-MN': /^(\+|00|011)?976(77|81|88|91|94|95|96|99)\d{6}$/,
4278 'my-MM': /^(\+?959|09|9)(2[5-7]|3[1-2]|4[0-5]|6[6-9]|7[5-9]|9[6-9])[0-9]{7}$/,
4279 'ms-MY': /^(\+?60|0)1(([0145](-|\s)?\d{7,8})|([236-9](-|\s)?\d{7}))$/,
4280 'mz-MZ': /^(\+?258)?8[234567]\d{7}$/,
4281 'nb-NO': /^(\+?47)?[49]\d{7}$/,
4282 'ne-NP': /^(\+?977)?9[78]\d{8}$/,
4283 'nl-BE': /^(\+?32|0)4\d{8}$/,
4284 'nl-NL': /^(((\+|00)?31\(0\))|((\+|00)?31)|0)6{1}\d{8}$/,
4285 'nl-AW': /^(\+)?297(56|59|64|73|74|99)\d{5}$/,
4286 'nn-NO': /^(\+?47)?[49]\d{7}$/,
4287 'pl-PL': /^(\+?48)? ?([5-8]\d|45) ?\d{3} ?\d{2} ?\d{2}$/,
4288 'pt-BR': /^((\+?55\ ?[1-9]{2}\ ?)|(\+?55\ ?\([1-9]{2}\)\ ?)|(0[1-9]{2}\ ?)|(\([1-9]{2}\)\ ?)|([1-9]{2}\ ?))((\d{4}\-?\d{4})|(9[1-9]{1}\d{3}\-?\d{4}))$/,
4289 'pt-PT': /^(\+?351)?9[1236]\d{7}$/,
4290 'pt-AO': /^(\+244)\d{9}$/,
4291 'ro-MD': /^(\+?373|0)((6(0|1|2|6|7|8|9))|(7(6|7|8|9)))\d{6}$/,
4292 'ro-RO': /^(\+?40|0)\s?7\d{2}(\/|\s|\.|-)?\d{3}(\s|\.|-)?\d{3}$/,
4293 'ru-RU': /^(\+?7|8)?9\d{9}$/,
4294 'si-LK': /^(?:0|94|\+94)?(7(0|1|2|4|5|6|7|8)( |-)?)\d{7}$/,
4295 'sl-SI': /^(\+386\s?|0)(\d{1}\s?\d{3}\s?\d{2}\s?\d{2}|\d{2}\s?\d{3}\s?\d{3})$/,
4296 'sk-SK': /^(\+?421)? ?[1-9][0-9]{2} ?[0-9]{3} ?[0-9]{3}$/,
4297 'so-SO': /^(\+?252|0)((6[0-9])\d{7}|(7[1-9])\d{7})$/,
4298 'sq-AL': /^(\+355|0)6[789]\d{6}$/,
4299 'sr-RS': /^(\+3816|06)[- \d]{5,9}$/,
4300 'sv-SE': /^(\+?46|0)[\s\-]?7[\s\-]?[02369]([\s\-]?\d){7}$/,
4301 'tg-TJ': /^(\+?992)?[5][5]\d{7}$/,
4302 'th-TH': /^(\+66|66|0)\d{9}$/,
4303 'tr-TR': /^(\+?90|0)?5\d{9}$/,
4304 'tk-TM': /^(\+993|993|8)\d{8}$/,
4305 'uk-UA': /^(\+?38|8)?0\d{9}$/,
4306 'uz-UZ': /^(\+?998)?(6[125-79]|7[1-69]|88|9\d)\d{7}$/,
4307 'vi-VN': /^((\+?84)|0)((3([2-9]))|(5([25689]))|(7([0|6-9]))|(8([1-9]))|(9([0-9])))([0-9]{7})$/,
4308 'zh-CN': /^((\+|00)86)?(1[3-9]|9[28])\d{9}$/,
4309 'zh-TW': /^(\+?886\-?|0)?9\d{8}$/,
4310 'dz-BT': /^(\+?975|0)?(17|16|77|02)\d{6}$/,
4311 'ar-YE': /^(((\+|00)9677|0?7)[0137]\d{7}|((\+|00)967|0)[1-7]\d{6})$/,
4312 'ar-EH': /^(\+?212|0)[\s\-]?(5288|5289)[\s\-]?\d{5}$/,
4313 'fa-AF': /^(\+93|0)?(2{1}[0-8]{1}|[3-5]{1}[0-4]{1})(\d{7})$/
4314};
4315/* eslint-enable max-len */
4316
4317// aliases
4318phones['en-CA'] = phones['en-US'];
4319phones['fr-CA'] = phones['en-CA'];
4320phones['fr-BE'] = phones['nl-BE'];
4321phones['zh-HK'] = phones['en-HK'];
4322phones['zh-MO'] = phones['en-MO'];
4323phones['ga-IE'] = phones['en-IE'];
4324phones['fr-CH'] = phones['de-CH'];
4325phones['it-CH'] = phones['fr-CH'];
4326function isMobilePhone(str, locale, options) {
4327 assertString(str);
4328 if (options && options.strictMode && !str.startsWith('+')) {
4329 return false;
4330 }
4331 if (Array.isArray(locale)) {
4332 return locale.some(function (key) {
4333 // https://github.com/gotwarlost/istanbul/blob/master/ignoring-code-for-coverage.md#ignoring-code-for-coverage-purposes
4334 // istanbul ignore else
4335 if (phones.hasOwnProperty(key)) {
4336 var phone = phones[key];
4337 if (phone.test(str)) {
4338 return true;
4339 }
4340 }
4341 return false;
4342 });
4343 } else if (locale in phones) {
4344 return phones[locale].test(str);
4345 // alias falsey locale as 'any'
4346 } else if (!locale || locale === 'any') {
4347 for (var key in phones) {
4348 // istanbul ignore else
4349 if (phones.hasOwnProperty(key)) {
4350 var phone = phones[key];
4351 if (phone.test(str)) {
4352 return true;
4353 }
4354 }
4355 }
4356 return false;
4357 }
4358 throw new Error("Invalid locale '".concat(locale, "'"));
4359}
4360var locales$4 = Object.keys(phones);
4361
4362var eth = /^(0x)[0-9a-f]{40}$/i;
4363function isEthereumAddress(str) {
4364 assertString(str);
4365 return eth.test(str);
4366}
4367
4368function currencyRegex(options) {
4369 var decimal_digits = "\\d{".concat(options.digits_after_decimal[0], "}");
4370 options.digits_after_decimal.forEach(function (digit, index) {
4371 if (index !== 0) decimal_digits = "".concat(decimal_digits, "|\\d{").concat(digit, "}");
4372 });
4373 var symbol = "(".concat(options.symbol.replace(/\W/, function (m) {
4374 return "\\".concat(m);
4375 }), ")").concat(options.require_symbol ? '' : '?'),
4376 negative = '-?',
4377 whole_dollar_amount_without_sep = '[1-9]\\d*',
4378 whole_dollar_amount_with_sep = "[1-9]\\d{0,2}(\\".concat(options.thousands_separator, "\\d{3})*"),
4379 valid_whole_dollar_amounts = ['0', whole_dollar_amount_without_sep, whole_dollar_amount_with_sep],
4380 whole_dollar_amount = "(".concat(valid_whole_dollar_amounts.join('|'), ")?"),
4381 decimal_amount = "(\\".concat(options.decimal_separator, "(").concat(decimal_digits, "))").concat(options.require_decimal ? '' : '?');
4382 var pattern = whole_dollar_amount + (options.allow_decimal || options.require_decimal ? decimal_amount : '');
4383
4384 // default is negative sign before symbol, but there are two other options (besides parens)
4385 if (options.allow_negatives && !options.parens_for_negatives) {
4386 if (options.negative_sign_after_digits) {
4387 pattern += negative;
4388 } else if (options.negative_sign_before_digits) {
4389 pattern = negative + pattern;
4390 }
4391 }
4392
4393 // South African Rand, for example, uses R 123 (space) and R-123 (no space)
4394 if (options.allow_negative_sign_placeholder) {
4395 pattern = "( (?!\\-))?".concat(pattern);
4396 } else if (options.allow_space_after_symbol) {
4397 pattern = " ?".concat(pattern);
4398 } else if (options.allow_space_after_digits) {
4399 pattern += '( (?!$))?';
4400 }
4401 if (options.symbol_after_digits) {
4402 pattern += symbol;
4403 } else {
4404 pattern = symbol + pattern;
4405 }
4406 if (options.allow_negatives) {
4407 if (options.parens_for_negatives) {
4408 pattern = "(\\(".concat(pattern, "\\)|").concat(pattern, ")");
4409 } else if (!(options.negative_sign_before_digits || options.negative_sign_after_digits)) {
4410 pattern = negative + pattern;
4411 }
4412 }
4413
4414 // ensure there's a dollar and/or decimal amount, and that
4415 // it doesn't start with a space or a negative sign followed by a space
4416 return new RegExp("^(?!-? )(?=.*\\d)".concat(pattern, "$"));
4417}
4418var default_currency_options = {
4419 symbol: '$',
4420 require_symbol: false,
4421 allow_space_after_symbol: false,
4422 symbol_after_digits: false,
4423 allow_negatives: true,
4424 parens_for_negatives: false,
4425 negative_sign_before_digits: false,
4426 negative_sign_after_digits: false,
4427 allow_negative_sign_placeholder: false,
4428 thousands_separator: ',',
4429 decimal_separator: '.',
4430 allow_decimal: true,
4431 require_decimal: false,
4432 digits_after_decimal: [2],
4433 allow_space_after_digits: false
4434};
4435function isCurrency(str, options) {
4436 assertString(str);
4437 options = merge(options, default_currency_options);
4438 return currencyRegex(options).test(str);
4439}
4440
4441var bech32 = /^(bc1)[a-z0-9]{25,39}$/;
4442var base58 = /^(1|3)[A-HJ-NP-Za-km-z1-9]{25,39}$/;
4443function isBtcAddress(str) {
4444 assertString(str);
4445 return bech32.test(str) || base58.test(str);
4446}
4447
4448// https://en.wikipedia.org/wiki/ISO_6346
4449// according to ISO6346 standard, checksum digit is mandatory for freight container but recommended
4450// for other container types (J and Z)
4451var isISO6346Str = /^[A-Z]{3}(U[0-9]{7})|([J,Z][0-9]{6,7})$/;
4452var isDigit = /^[0-9]$/;
4453function isISO6346(str) {
4454 assertString(str);
4455 str = str.toUpperCase();
4456 if (!isISO6346Str.test(str)) return false;
4457 if (str.length === 11) {
4458 var sum = 0;
4459 for (var i = 0; i < str.length - 1; i++) {
4460 if (!isDigit.test(str[i])) {
4461 var convertedCode = void 0;
4462 var letterCode = str.charCodeAt(i) - 55;
4463 if (letterCode < 11) convertedCode = letterCode;else if (letterCode >= 11 && letterCode <= 20) convertedCode = 12 + letterCode % 11;else if (letterCode >= 21 && letterCode <= 30) convertedCode = 23 + letterCode % 21;else convertedCode = 34 + letterCode % 31;
4464 sum += convertedCode * Math.pow(2, i);
4465 } else sum += str[i] * Math.pow(2, i);
4466 }
4467 var checkSumDigit = sum % 11;
4468 return Number(str[str.length - 1]) === checkSumDigit;
4469 }
4470 return true;
4471}
4472var isFreightContainerID = isISO6346;
4473
4474var isISO6391Set = new Set(['aa', 'ab', 'ae', 'af', 'ak', 'am', 'an', 'ar', 'as', 'av', 'ay', 'az', 'az', 'ba', 'be', 'bg', 'bh', 'bi', 'bm', 'bn', 'bo', 'br', 'bs', 'ca', 'ce', 'ch', 'co', 'cr', 'cs', 'cu', 'cv', 'cy', 'da', 'de', 'dv', 'dz', 'ee', 'el', 'en', 'eo', 'es', 'et', 'eu', 'fa', 'ff', 'fi', 'fj', 'fo', 'fr', 'fy', 'ga', 'gd', 'gl', 'gn', 'gu', 'gv', 'ha', 'he', 'hi', 'ho', 'hr', 'ht', 'hu', 'hy', 'hz', 'ia', 'id', 'ie', 'ig', 'ii', 'ik', 'io', 'is', 'it', 'iu', 'ja', 'jv', 'ka', 'kg', 'ki', 'kj', 'kk', 'kl', 'km', 'kn', 'ko', 'kr', 'ks', 'ku', 'kv', 'kw', 'ky', 'la', 'lb', 'lg', 'li', 'ln', 'lo', 'lt', 'lu', 'lv', 'mg', 'mh', 'mi', 'mk', 'ml', 'mn', 'mr', 'ms', 'mt', 'my', 'na', 'nb', 'nd', 'ne', 'ng', 'nl', 'nn', 'no', 'nr', 'nv', 'ny', 'oc', 'oj', 'om', 'or', 'os', 'pa', 'pi', 'pl', 'ps', 'pt', 'qu', 'rm', 'rn', 'ro', 'ru', 'rw', 'sa', 'sc', 'sd', 'se', 'sg', 'si', 'sk', 'sl', 'sm', 'sn', 'so', 'sq', 'sr', 'ss', 'st', 'su', 'sv', 'sw', 'ta', 'te', 'tg', 'th', 'ti', 'tk', 'tl', 'tn', 'to', 'tr', 'ts', 'tt', 'tw', 'ty', 'ug', 'uk', 'ur', 'uz', 've', 'vi', 'vo', 'wa', 'wo', 'xh', 'yi', 'yo', 'za', 'zh', 'zu']);
4475function isISO6391(str) {
4476 assertString(str);
4477 return isISO6391Set.has(str);
4478}
4479
4480/* eslint-disable max-len */
4481// from http://goo.gl/0ejHHW
4482var iso8601 = /^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-3])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/;
4483// same as above, except with a strict 'T' separator between date and time
4484var iso8601StrictSeparator = /^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-3])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T]((([01]\d|2[0-3])((:?)[0-5]\d)?|24:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/;
4485/* eslint-enable max-len */
4486var isValidDate = function isValidDate(str) {
4487 // str must have passed the ISO8601 check
4488 // this check is meant to catch invalid dates
4489 // like 2009-02-31
4490 // first check for ordinal dates
4491 var ordinalMatch = str.match(/^(\d{4})-?(\d{3})([ T]{1}\.*|$)/);
4492 if (ordinalMatch) {
4493 var oYear = Number(ordinalMatch[1]);
4494 var oDay = Number(ordinalMatch[2]);
4495 // if is leap year
4496 if (oYear % 4 === 0 && oYear % 100 !== 0 || oYear % 400 === 0) return oDay <= 366;
4497 return oDay <= 365;
4498 }
4499 var match = str.match(/(\d{4})-?(\d{0,2})-?(\d*)/).map(Number);
4500 var year = match[1];
4501 var month = match[2];
4502 var day = match[3];
4503 var monthString = month ? "0".concat(month).slice(-2) : month;
4504 var dayString = day ? "0".concat(day).slice(-2) : day;
4505
4506 // create a date object and compare
4507 var d = new Date("".concat(year, "-").concat(monthString || '01', "-").concat(dayString || '01'));
4508 if (month && day) {
4509 return d.getUTCFullYear() === year && d.getUTCMonth() + 1 === month && d.getUTCDate() === day;
4510 }
4511 return true;
4512};
4513function isISO8601(str) {
4514 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
4515 assertString(str);
4516 var check = options.strictSeparator ? iso8601StrictSeparator.test(str) : iso8601.test(str);
4517 if (check && options.strict) return isValidDate(str);
4518 return check;
4519}
4520
4521/* Based on https://tools.ietf.org/html/rfc3339#section-5.6 */
4522
4523var dateFullYear = /[0-9]{4}/;
4524var dateMonth = /(0[1-9]|1[0-2])/;
4525var dateMDay = /([12]\d|0[1-9]|3[01])/;
4526var timeHour = /([01][0-9]|2[0-3])/;
4527var timeMinute = /[0-5][0-9]/;
4528var timeSecond = /([0-5][0-9]|60)/;
4529var timeSecFrac = /(\.[0-9]+)?/;
4530var timeNumOffset = new RegExp("[-+]".concat(timeHour.source, ":").concat(timeMinute.source));
4531var timeOffset = new RegExp("([zZ]|".concat(timeNumOffset.source, ")"));
4532var partialTime = new RegExp("".concat(timeHour.source, ":").concat(timeMinute.source, ":").concat(timeSecond.source).concat(timeSecFrac.source));
4533var fullDate = new RegExp("".concat(dateFullYear.source, "-").concat(dateMonth.source, "-").concat(dateMDay.source));
4534var fullTime = new RegExp("".concat(partialTime.source).concat(timeOffset.source));
4535var rfc3339 = new RegExp("^".concat(fullDate.source, "[ tT]").concat(fullTime.source, "$"));
4536function isRFC3339(str) {
4537 assertString(str);
4538 return rfc3339.test(str);
4539}
4540
4541// from https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3
4542var validISO31661Alpha3CountriesCodes = new Set(['AFG', 'ALA', 'ALB', 'DZA', 'ASM', 'AND', 'AGO', 'AIA', 'ATA', 'ATG', 'ARG', 'ARM', 'ABW', 'AUS', 'AUT', 'AZE', 'BHS', 'BHR', 'BGD', 'BRB', 'BLR', 'BEL', 'BLZ', 'BEN', 'BMU', 'BTN', 'BOL', 'BES', 'BIH', 'BWA', 'BVT', 'BRA', 'IOT', 'BRN', 'BGR', 'BFA', 'BDI', 'KHM', 'CMR', 'CAN', 'CPV', 'CYM', 'CAF', 'TCD', 'CHL', 'CHN', 'CXR', 'CCK', 'COL', 'COM', 'COG', 'COD', 'COK', 'CRI', 'CIV', 'HRV', 'CUB', 'CUW', 'CYP', 'CZE', 'DNK', 'DJI', 'DMA', 'DOM', 'ECU', 'EGY', 'SLV', 'GNQ', 'ERI', 'EST', 'ETH', 'FLK', 'FRO', 'FJI', 'FIN', 'FRA', 'GUF', 'PYF', 'ATF', 'GAB', 'GMB', 'GEO', 'DEU', 'GHA', 'GIB', 'GRC', 'GRL', 'GRD', 'GLP', 'GUM', 'GTM', 'GGY', 'GIN', 'GNB', 'GUY', 'HTI', 'HMD', 'VAT', 'HND', 'HKG', 'HUN', 'ISL', 'IND', 'IDN', 'IRN', 'IRQ', 'IRL', 'IMN', 'ISR', 'ITA', 'JAM', 'JPN', 'JEY', 'JOR', 'KAZ', 'KEN', 'KIR', 'PRK', 'KOR', 'KWT', 'KGZ', 'LAO', 'LVA', 'LBN', 'LSO', 'LBR', 'LBY', 'LIE', 'LTU', 'LUX', 'MAC', 'MKD', 'MDG', 'MWI', 'MYS', 'MDV', 'MLI', 'MLT', 'MHL', 'MTQ', 'MRT', 'MUS', 'MYT', 'MEX', 'FSM', 'MDA', 'MCO', 'MNG', 'MNE', 'MSR', 'MAR', 'MOZ', 'MMR', 'NAM', 'NRU', 'NPL', 'NLD', 'NCL', 'NZL', 'NIC', 'NER', 'NGA', 'NIU', 'NFK', 'MNP', 'NOR', 'OMN', 'PAK', 'PLW', 'PSE', 'PAN', 'PNG', 'PRY', 'PER', 'PHL', 'PCN', 'POL', 'PRT', 'PRI', 'QAT', 'REU', 'ROU', 'RUS', 'RWA', 'BLM', 'SHN', 'KNA', 'LCA', 'MAF', 'SPM', 'VCT', 'WSM', 'SMR', 'STP', 'SAU', 'SEN', 'SRB', 'SYC', 'SLE', 'SGP', 'SXM', 'SVK', 'SVN', 'SLB', 'SOM', 'ZAF', 'SGS', 'SSD', 'ESP', 'LKA', 'SDN', 'SUR', 'SJM', 'SWZ', 'SWE', 'CHE', 'SYR', 'TWN', 'TJK', 'TZA', 'THA', 'TLS', 'TGO', 'TKL', 'TON', 'TTO', 'TUN', 'TUR', 'TKM', 'TCA', 'TUV', 'UGA', 'UKR', 'ARE', 'GBR', 'USA', 'UMI', 'URY', 'UZB', 'VUT', 'VEN', 'VNM', 'VGB', 'VIR', 'WLF', 'ESH', 'YEM', 'ZMB', 'ZWE']);
4543function isISO31661Alpha3(str) {
4544 assertString(str);
4545 return validISO31661Alpha3CountriesCodes.has(str.toUpperCase());
4546}
4547
4548// from https://en.wikipedia.org/wiki/ISO_4217
4549var validISO4217CurrencyCodes = new Set(['AED', 'AFN', 'ALL', 'AMD', 'ANG', 'AOA', 'ARS', 'AUD', 'AWG', 'AZN', 'BAM', 'BBD', 'BDT', 'BGN', 'BHD', 'BIF', 'BMD', 'BND', 'BOB', 'BOV', 'BRL', 'BSD', 'BTN', 'BWP', 'BYN', 'BZD', 'CAD', 'CDF', 'CHE', 'CHF', 'CHW', 'CLF', 'CLP', 'CNY', 'COP', 'COU', 'CRC', 'CUC', 'CUP', 'CVE', 'CZK', 'DJF', 'DKK', 'DOP', 'DZD', 'EGP', 'ERN', 'ETB', 'EUR', 'FJD', 'FKP', 'GBP', 'GEL', 'GHS', 'GIP', 'GMD', 'GNF', 'GTQ', 'GYD', 'HKD', 'HNL', 'HRK', 'HTG', 'HUF', 'IDR', 'ILS', 'INR', 'IQD', 'IRR', 'ISK', 'JMD', 'JOD', 'JPY', 'KES', 'KGS', 'KHR', 'KMF', 'KPW', 'KRW', 'KWD', 'KYD', 'KZT', 'LAK', 'LBP', 'LKR', 'LRD', 'LSL', 'LYD', 'MAD', 'MDL', 'MGA', 'MKD', 'MMK', 'MNT', 'MOP', 'MRU', 'MUR', 'MVR', 'MWK', 'MXN', 'MXV', 'MYR', 'MZN', 'NAD', 'NGN', 'NIO', 'NOK', 'NPR', 'NZD', 'OMR', 'PAB', 'PEN', 'PGK', 'PHP', 'PKR', 'PLN', 'PYG', 'QAR', 'RON', 'RSD', 'RUB', 'RWF', 'SAR', 'SBD', 'SCR', 'SDG', 'SEK', 'SGD', 'SHP', 'SLE', 'SLL', 'SOS', 'SRD', 'SSP', 'STN', 'SVC', 'SYP', 'SZL', 'THB', 'TJS', 'TMT', 'TND', 'TOP', 'TRY', 'TTD', 'TWD', 'TZS', 'UAH', 'UGX', 'USD', 'USN', 'UYI', 'UYU', 'UYW', 'UZS', 'VES', 'VND', 'VUV', 'WST', 'XAF', 'XAG', 'XAU', 'XBA', 'XBB', 'XBC', 'XBD', 'XCD', 'XDR', 'XOF', 'XPD', 'XPF', 'XPT', 'XSU', 'XTS', 'XUA', 'XXX', 'YER', 'ZAR', 'ZMW', 'ZWL']);
4550function isISO4217(str) {
4551 assertString(str);
4552 return validISO4217CurrencyCodes.has(str.toUpperCase());
4553}
4554
4555var base32 = /^[A-Z2-7]+=*$/;
4556var crockfordBase32 = /^[A-HJKMNP-TV-Z0-9]+$/;
4557var defaultBase32Options = {
4558 crockford: false
4559};
4560function isBase32(str, options) {
4561 assertString(str);
4562 options = merge(options, defaultBase32Options);
4563 if (options.crockford) {
4564 return crockfordBase32.test(str);
4565 }
4566 var len = str.length;
4567 if (len % 8 === 0 && base32.test(str)) {
4568 return true;
4569 }
4570 return false;
4571}
4572
4573// Accepted chars - 123456789ABCDEFGH JKLMN PQRSTUVWXYZabcdefghijk mnopqrstuvwxyz
4574var base58Reg = /^[A-HJ-NP-Za-km-z1-9]*$/;
4575function isBase58(str) {
4576 assertString(str);
4577 if (base58Reg.test(str)) {
4578 return true;
4579 }
4580 return false;
4581}
4582
4583var validMediaType = /^[a-z]+\/[a-z0-9\-\+\._]+$/i;
4584var validAttribute = /^[a-z\-]+=[a-z0-9\-]+$/i;
4585var validData = /^[a-z0-9!\$&'\(\)\*\+,;=\-\._~:@\/\?%\s]*$/i;
4586function isDataURI(str) {
4587 assertString(str);
4588 var data = str.split(',');
4589 if (data.length < 2) {
4590 return false;
4591 }
4592 var attributes = data.shift().trim().split(';');
4593 var schemeAndMediaType = attributes.shift();
4594 if (schemeAndMediaType.slice(0, 5) !== 'data:') {
4595 return false;
4596 }
4597 var mediaType = schemeAndMediaType.slice(5);
4598 if (mediaType !== '' && !validMediaType.test(mediaType)) {
4599 return false;
4600 }
4601 for (var i = 0; i < attributes.length; i++) {
4602 if (!(i === attributes.length - 1 && attributes[i].toLowerCase() === 'base64') && !validAttribute.test(attributes[i])) {
4603 return false;
4604 }
4605 }
4606 for (var _i = 0; _i < data.length; _i++) {
4607 if (!validData.test(data[_i])) {
4608 return false;
4609 }
4610 }
4611 return true;
4612}
4613
4614var magnetURIComponent = /(?:^magnet:\?|[^?&]&)xt(?:\.1)?=urn:(?:(?:aich|bitprint|btih|ed2k|ed2khash|kzhash|md5|sha1|tree:tiger):[a-z0-9]{32}(?:[a-z0-9]{8})?|btmh:1220[a-z0-9]{64})(?:$|&)/i;
4615function isMagnetURI(url) {
4616 assertString(url);
4617 if (url.indexOf('magnet:?') !== 0) {
4618 return false;
4619 }
4620 return magnetURIComponent.test(url);
4621}
4622
4623function rtrim(str, chars) {
4624 assertString(str);
4625 if (chars) {
4626 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Escaping
4627 var pattern = new RegExp("[".concat(chars.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), "]+$"), 'g');
4628 return str.replace(pattern, '');
4629 }
4630 // Use a faster and more safe than regex trim method https://blog.stevenlevithan.com/archives/faster-trim-javascript
4631 var strIndex = str.length - 1;
4632 while (/\s/.test(str.charAt(strIndex))) {
4633 strIndex -= 1;
4634 }
4635 return str.slice(0, strIndex + 1);
4636}
4637
4638function ltrim(str, chars) {
4639 assertString(str);
4640 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Escaping
4641 var pattern = chars ? new RegExp("^[".concat(chars.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), "]+"), 'g') : /^\s+/g;
4642 return str.replace(pattern, '');
4643}
4644
4645function trim(str, chars) {
4646 return rtrim(ltrim(str, chars), chars);
4647}
4648
4649function parseMailtoQueryString(queryString) {
4650 var allowedParams = new Set(['subject', 'body', 'cc', 'bcc']),
4651 query = {
4652 cc: '',
4653 bcc: ''
4654 };
4655 var isParseFailed = false;
4656 var queryParams = queryString.split('&');
4657 if (queryParams.length > 4) {
4658 return false;
4659 }
4660 var _iterator = _createForOfIteratorHelper(queryParams),
4661 _step;
4662 try {
4663 for (_iterator.s(); !(_step = _iterator.n()).done;) {
4664 var q = _step.value;
4665 var _q$split = q.split('='),
4666 _q$split2 = _slicedToArray(_q$split, 2),
4667 key = _q$split2[0],
4668 value = _q$split2[1];
4669
4670 // checked for invalid and duplicated query params
4671 if (key && !allowedParams.has(key)) {
4672 isParseFailed = true;
4673 break;
4674 }
4675 if (value && (key === 'cc' || key === 'bcc')) {
4676 query[key] = value;
4677 }
4678 if (key) {
4679 allowedParams["delete"](key);
4680 }
4681 }
4682 } catch (err) {
4683 _iterator.e(err);
4684 } finally {
4685 _iterator.f();
4686 }
4687 return isParseFailed ? false : query;
4688}
4689function isMailtoURI(url, options) {
4690 assertString(url);
4691 if (url.indexOf('mailto:') !== 0) {
4692 return false;
4693 }
4694 var _url$replace$split = url.replace('mailto:', '').split('?'),
4695 _url$replace$split2 = _slicedToArray(_url$replace$split, 2),
4696 to = _url$replace$split2[0],
4697 _url$replace$split2$ = _url$replace$split2[1],
4698 queryString = _url$replace$split2$ === void 0 ? '' : _url$replace$split2$;
4699 if (!to && !queryString) {
4700 return true;
4701 }
4702 var query = parseMailtoQueryString(queryString);
4703 if (!query) {
4704 return false;
4705 }
4706 return "".concat(to, ",").concat(query.cc, ",").concat(query.bcc).split(',').every(function (email) {
4707 email = trim(email, ' ');
4708 if (email) {
4709 return isEmail(email, options);
4710 }
4711 return true;
4712 });
4713}
4714
4715/*
4716 Checks if the provided string matches to a correct Media type format (MIME type)
4717
4718 This function only checks is the string format follows the
4719 etablished rules by the according RFC specifications.
4720 This function supports 'charset' in textual media types
4721 (https://tools.ietf.org/html/rfc6657).
4722
4723 This function does not check against all the media types listed
4724 by the IANA (https://www.iana.org/assignments/media-types/media-types.xhtml)
4725 because of lightness purposes : it would require to include
4726 all these MIME types in this librairy, which would weigh it
4727 significantly. This kind of effort maybe is not worth for the use that
4728 this function has in this entire librairy.
4729
4730 More informations in the RFC specifications :
4731 - https://tools.ietf.org/html/rfc2045
4732 - https://tools.ietf.org/html/rfc2046
4733 - https://tools.ietf.org/html/rfc7231#section-3.1.1.1
4734 - https://tools.ietf.org/html/rfc7231#section-3.1.1.5
4735*/
4736
4737// Match simple MIME types
4738// NB :
4739// Subtype length must not exceed 100 characters.
4740// This rule does not comply to the RFC specs (what is the max length ?).
4741var mimeTypeSimple = /^(application|audio|font|image|message|model|multipart|text|video)\/[a-zA-Z0-9\.\-\+_]{1,100}$/i; // eslint-disable-line max-len
4742
4743// Handle "charset" in "text/*"
4744var mimeTypeText = /^text\/[a-zA-Z0-9\.\-\+]{1,100};\s?charset=("[a-zA-Z0-9\.\-\+\s]{0,70}"|[a-zA-Z0-9\.\-\+]{0,70})(\s?\([a-zA-Z0-9\.\-\+\s]{1,20}\))?$/i; // eslint-disable-line max-len
4745
4746// Handle "boundary" in "multipart/*"
4747var mimeTypeMultipart = /^multipart\/[a-zA-Z0-9\.\-\+]{1,100}(;\s?(boundary|charset)=("[a-zA-Z0-9\.\-\+\s]{0,70}"|[a-zA-Z0-9\.\-\+]{0,70})(\s?\([a-zA-Z0-9\.\-\+\s]{1,20}\))?){0,2}$/i; // eslint-disable-line max-len
4748
4749function isMimeType(str) {
4750 assertString(str);
4751 return mimeTypeSimple.test(str) || mimeTypeText.test(str) || mimeTypeMultipart.test(str);
4752}
4753
4754var lat = /^\(?[+-]?(90(\.0+)?|[1-8]?\d(\.\d+)?)$/;
4755var _long = /^\s?[+-]?(180(\.0+)?|1[0-7]\d(\.\d+)?|\d{1,2}(\.\d+)?)\)?$/;
4756var latDMS = /^(([1-8]?\d)\D+([1-5]?\d|60)\D+([1-5]?\d|60)(\.\d+)?|90\D+0\D+0)\D+[NSns]?$/i;
4757var longDMS = /^\s*([1-7]?\d{1,2}\D+([1-5]?\d|60)\D+([1-5]?\d|60)(\.\d+)?|180\D+0\D+0)\D+[EWew]?$/i;
4758var defaultLatLongOptions = {
4759 checkDMS: false
4760};
4761function isLatLong(str, options) {
4762 assertString(str);
4763 options = merge(options, defaultLatLongOptions);
4764 if (!str.includes(',')) return false;
4765 var pair = str.split(',');
4766 if (pair[0].startsWith('(') && !pair[1].endsWith(')') || pair[1].endsWith(')') && !pair[0].startsWith('(')) return false;
4767 if (options.checkDMS) {
4768 return latDMS.test(pair[0]) && longDMS.test(pair[1]);
4769 }
4770 return lat.test(pair[0]) && _long.test(pair[1]);
4771}
4772
4773// common patterns
4774var threeDigit = /^\d{3}$/;
4775var fourDigit = /^\d{4}$/;
4776var fiveDigit = /^\d{5}$/;
4777var sixDigit = /^\d{6}$/;
4778var patterns = {
4779 AD: /^AD\d{3}$/,
4780 AT: fourDigit,
4781 AU: fourDigit,
4782 AZ: /^AZ\d{4}$/,
4783 BA: /^([7-8]\d{4}$)/,
4784 BE: fourDigit,
4785 BG: fourDigit,
4786 BR: /^\d{5}-\d{3}$/,
4787 BY: /^2[1-4]\d{4}$/,
4788 CA: /^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][\s\-]?\d[ABCEGHJ-NPRSTV-Z]\d$/i,
4789 CH: fourDigit,
4790 CN: /^(0[1-7]|1[012356]|2[0-7]|3[0-6]|4[0-7]|5[1-7]|6[1-7]|7[1-5]|8[1345]|9[09])\d{4}$/,
4791 CZ: /^\d{3}\s?\d{2}$/,
4792 DE: fiveDigit,
4793 DK: fourDigit,
4794 DO: fiveDigit,
4795 DZ: fiveDigit,
4796 EE: fiveDigit,
4797 ES: /^(5[0-2]{1}|[0-4]{1}\d{1})\d{3}$/,
4798 FI: fiveDigit,
4799 FR: /^\d{2}\s?\d{3}$/,
4800 GB: /^(gir\s?0aa|[a-z]{1,2}\d[\da-z]?\s?(\d[a-z]{2})?)$/i,
4801 GR: /^\d{3}\s?\d{2}$/,
4802 HR: /^([1-5]\d{4}$)/,
4803 HT: /^HT\d{4}$/,
4804 HU: fourDigit,
4805 ID: fiveDigit,
4806 IE: /^(?!.*(?:o))[A-Za-z]\d[\dw]\s\w{4}$/i,
4807 IL: /^(\d{5}|\d{7})$/,
4808 IN: /^((?!10|29|35|54|55|65|66|86|87|88|89)[1-9][0-9]{5})$/,
4809 IR: /^(?!(\d)\1{3})[13-9]{4}[1346-9][013-9]{5}$/,
4810 IS: threeDigit,
4811 IT: fiveDigit,
4812 JP: /^\d{3}\-\d{4}$/,
4813 KE: fiveDigit,
4814 KR: /^(\d{5}|\d{6})$/,
4815 LI: /^(948[5-9]|949[0-7])$/,
4816 LT: /^LT\-\d{5}$/,
4817 LU: fourDigit,
4818 LV: /^LV\-\d{4}$/,
4819 LK: fiveDigit,
4820 MG: threeDigit,
4821 MX: fiveDigit,
4822 MT: /^[A-Za-z]{3}\s{0,1}\d{4}$/,
4823 MY: fiveDigit,
4824 NL: /^[1-9]\d{3}\s?(?!sa|sd|ss)[a-z]{2}$/i,
4825 NO: fourDigit,
4826 NP: /^(10|21|22|32|33|34|44|45|56|57)\d{3}$|^(977)$/i,
4827 NZ: fourDigit,
4828 PL: /^\d{2}\-\d{3}$/,
4829 PR: /^00[679]\d{2}([ -]\d{4})?$/,
4830 PT: /^\d{4}\-\d{3}?$/,
4831 RO: sixDigit,
4832 RU: sixDigit,
4833 SA: fiveDigit,
4834 SE: /^[1-9]\d{2}\s?\d{2}$/,
4835 SG: sixDigit,
4836 SI: fourDigit,
4837 SK: /^\d{3}\s?\d{2}$/,
4838 TH: fiveDigit,
4839 TN: fourDigit,
4840 TW: /^\d{3}(\d{2})?$/,
4841 UA: fiveDigit,
4842 US: /^\d{5}(-\d{4})?$/,
4843 ZA: fourDigit,
4844 ZM: fiveDigit
4845};
4846var locales$5 = Object.keys(patterns);
4847function isPostalCode(str, locale) {
4848 assertString(str);
4849 if (locale in patterns) {
4850 return patterns[locale].test(str);
4851 } else if (locale === 'any') {
4852 for (var key in patterns) {
4853 // https://github.com/gotwarlost/istanbul/blob/master/ignoring-code-for-coverage.md#ignoring-code-for-coverage-purposes
4854 // istanbul ignore else
4855 if (patterns.hasOwnProperty(key)) {
4856 var pattern = patterns[key];
4857 if (pattern.test(str)) {
4858 return true;
4859 }
4860 }
4861 }
4862 return false;
4863 }
4864 throw new Error("Invalid locale '".concat(locale, "'"));
4865}
4866
4867function escape(str) {
4868 assertString(str);
4869 return str.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\//g, '&#x2F;').replace(/\\/g, '&#x5C;').replace(/`/g, '&#96;');
4870}
4871
4872function unescape(str) {
4873 assertString(str);
4874 return str.replace(/&quot;/g, '"').replace(/&#x27;/g, "'").replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&#x2F;/g, '/').replace(/&#x5C;/g, '\\').replace(/&#96;/g, '`').replace(/&amp;/g, '&');
4875 // &amp; replacement has to be the last one to prevent
4876 // bugs with intermediate strings containing escape sequences
4877 // See: https://github.com/validatorjs/validator.js/issues/1827
4878}
4879
4880function blacklist$1(str, chars) {
4881 assertString(str);
4882 return str.replace(new RegExp("[".concat(chars, "]+"), 'g'), '');
4883}
4884
4885function stripLow(str, keep_new_lines) {
4886 assertString(str);
4887 var chars = keep_new_lines ? '\\x00-\\x09\\x0B\\x0C\\x0E-\\x1F\\x7F' : '\\x00-\\x1F\\x7F';
4888 return blacklist$1(str, chars);
4889}
4890
4891function whitelist(str, chars) {
4892 assertString(str);
4893 return str.replace(new RegExp("[^".concat(chars, "]+"), 'g'), '');
4894}
4895
4896function isWhitelisted(str, chars) {
4897 assertString(str);
4898 for (var i = str.length - 1; i >= 0; i--) {
4899 if (chars.indexOf(str[i]) === -1) {
4900 return false;
4901 }
4902 }
4903 return true;
4904}
4905
4906var default_normalize_email_options = {
4907 // The following options apply to all email addresses
4908 // Lowercases the local part of the email address.
4909 // Please note this may violate RFC 5321 as per http://stackoverflow.com/a/9808332/192024).
4910 // The domain is always lowercased, as per RFC 1035
4911 all_lowercase: true,
4912 // The following conversions are specific to GMail
4913 // Lowercases the local part of the GMail address (known to be case-insensitive)
4914 gmail_lowercase: true,
4915 // Removes dots from the local part of the email address, as that's ignored by GMail
4916 gmail_remove_dots: true,
4917 // Removes the subaddress (e.g. "+foo") from the email address
4918 gmail_remove_subaddress: true,
4919 // Conversts the googlemail.com domain to gmail.com
4920 gmail_convert_googlemaildotcom: true,
4921 // The following conversions are specific to Outlook.com / Windows Live / Hotmail
4922 // Lowercases the local part of the Outlook.com address (known to be case-insensitive)
4923 outlookdotcom_lowercase: true,
4924 // Removes the subaddress (e.g. "+foo") from the email address
4925 outlookdotcom_remove_subaddress: true,
4926 // The following conversions are specific to Yahoo
4927 // Lowercases the local part of the Yahoo address (known to be case-insensitive)
4928 yahoo_lowercase: true,
4929 // Removes the subaddress (e.g. "-foo") from the email address
4930 yahoo_remove_subaddress: true,
4931 // The following conversions are specific to Yandex
4932 // Lowercases the local part of the Yandex address (known to be case-insensitive)
4933 yandex_lowercase: true,
4934 // The following conversions are specific to iCloud
4935 // Lowercases the local part of the iCloud address (known to be case-insensitive)
4936 icloud_lowercase: true,
4937 // Removes the subaddress (e.g. "+foo") from the email address
4938 icloud_remove_subaddress: true
4939};
4940
4941// List of domains used by iCloud
4942var icloud_domains = ['icloud.com', 'me.com'];
4943
4944// List of domains used by Outlook.com and its predecessors
4945// This list is likely incomplete.
4946// Partial reference:
4947// https://blogs.office.com/2013/04/17/outlook-com-gets-two-step-verification-sign-in-by-alias-and-new-international-domains/
4948var outlookdotcom_domains = ['hotmail.at', 'hotmail.be', 'hotmail.ca', 'hotmail.cl', 'hotmail.co.il', 'hotmail.co.nz', 'hotmail.co.th', 'hotmail.co.uk', 'hotmail.com', 'hotmail.com.ar', 'hotmail.com.au', 'hotmail.com.br', 'hotmail.com.gr', 'hotmail.com.mx', 'hotmail.com.pe', 'hotmail.com.tr', 'hotmail.com.vn', 'hotmail.cz', 'hotmail.de', 'hotmail.dk', 'hotmail.es', 'hotmail.fr', 'hotmail.hu', 'hotmail.id', 'hotmail.ie', 'hotmail.in', 'hotmail.it', 'hotmail.jp', 'hotmail.kr', 'hotmail.lv', 'hotmail.my', 'hotmail.ph', 'hotmail.pt', 'hotmail.sa', 'hotmail.sg', 'hotmail.sk', 'live.be', 'live.co.uk', 'live.com', 'live.com.ar', 'live.com.mx', 'live.de', 'live.es', 'live.eu', 'live.fr', 'live.it', 'live.nl', 'msn.com', 'outlook.at', 'outlook.be', 'outlook.cl', 'outlook.co.il', 'outlook.co.nz', 'outlook.co.th', 'outlook.com', 'outlook.com.ar', 'outlook.com.au', 'outlook.com.br', 'outlook.com.gr', 'outlook.com.pe', 'outlook.com.tr', 'outlook.com.vn', 'outlook.cz', 'outlook.de', 'outlook.dk', 'outlook.es', 'outlook.fr', 'outlook.hu', 'outlook.id', 'outlook.ie', 'outlook.in', 'outlook.it', 'outlook.jp', 'outlook.kr', 'outlook.lv', 'outlook.my', 'outlook.ph', 'outlook.pt', 'outlook.sa', 'outlook.sg', 'outlook.sk', 'passport.com'];
4949
4950// List of domains used by Yahoo Mail
4951// This list is likely incomplete
4952var yahoo_domains = ['rocketmail.com', 'yahoo.ca', 'yahoo.co.uk', 'yahoo.com', 'yahoo.de', 'yahoo.fr', 'yahoo.in', 'yahoo.it', 'ymail.com'];
4953
4954// List of domains used by yandex.ru
4955var yandex_domains = ['yandex.ru', 'yandex.ua', 'yandex.kz', 'yandex.com', 'yandex.by', 'ya.ru'];
4956
4957// replace single dots, but not multiple consecutive dots
4958function dotsReplacer(match) {
4959 if (match.length > 1) {
4960 return match;
4961 }
4962 return '';
4963}
4964function normalizeEmail(email, options) {
4965 options = merge(options, default_normalize_email_options);
4966 var raw_parts = email.split('@');
4967 var domain = raw_parts.pop();
4968 var user = raw_parts.join('@');
4969 var parts = [user, domain];
4970
4971 // The domain is always lowercased, as it's case-insensitive per RFC 1035
4972 parts[1] = parts[1].toLowerCase();
4973 if (parts[1] === 'gmail.com' || parts[1] === 'googlemail.com') {
4974 // Address is GMail
4975 if (options.gmail_remove_subaddress) {
4976 parts[0] = parts[0].split('+')[0];
4977 }
4978 if (options.gmail_remove_dots) {
4979 // this does not replace consecutive dots like example..email@gmail.com
4980 parts[0] = parts[0].replace(/\.+/g, dotsReplacer);
4981 }
4982 if (!parts[0].length) {
4983 return false;
4984 }
4985 if (options.all_lowercase || options.gmail_lowercase) {
4986 parts[0] = parts[0].toLowerCase();
4987 }
4988 parts[1] = options.gmail_convert_googlemaildotcom ? 'gmail.com' : parts[1];
4989 } else if (icloud_domains.indexOf(parts[1]) >= 0) {
4990 // Address is iCloud
4991 if (options.icloud_remove_subaddress) {
4992 parts[0] = parts[0].split('+')[0];
4993 }
4994 if (!parts[0].length) {
4995 return false;
4996 }
4997 if (options.all_lowercase || options.icloud_lowercase) {
4998 parts[0] = parts[0].toLowerCase();
4999 }
5000 } else if (outlookdotcom_domains.indexOf(parts[1]) >= 0) {
5001 // Address is Outlook.com
5002 if (options.outlookdotcom_remove_subaddress) {
5003 parts[0] = parts[0].split('+')[0];
5004 }
5005 if (!parts[0].length) {
5006 return false;
5007 }
5008 if (options.all_lowercase || options.outlookdotcom_lowercase) {
5009 parts[0] = parts[0].toLowerCase();
5010 }
5011 } else if (yahoo_domains.indexOf(parts[1]) >= 0) {
5012 // Address is Yahoo
5013 if (options.yahoo_remove_subaddress) {
5014 var components = parts[0].split('-');
5015 parts[0] = components.length > 1 ? components.slice(0, -1).join('-') : components[0];
5016 }
5017 if (!parts[0].length) {
5018 return false;
5019 }
5020 if (options.all_lowercase || options.yahoo_lowercase) {
5021 parts[0] = parts[0].toLowerCase();
5022 }
5023 } else if (yandex_domains.indexOf(parts[1]) >= 0) {
5024 if (options.all_lowercase || options.yandex_lowercase) {
5025 parts[0] = parts[0].toLowerCase();
5026 }
5027 parts[1] = 'yandex.ru'; // all yandex domains are equal, 1st preferred
5028 } else if (options.all_lowercase) {
5029 // Any other address
5030 parts[0] = parts[0].toLowerCase();
5031 }
5032 return parts.join('@');
5033}
5034
5035var charsetRegex = /^[^\s-_](?!.*?[-_]{2,})[a-z0-9-\\][^\s]*[^-_\s]$/;
5036function isSlug(str) {
5037 assertString(str);
5038 return charsetRegex.test(str);
5039}
5040
5041var validators$1 = {
5042 'cs-CZ': function csCZ(str) {
5043 return /^(([ABCDEFHIJKLMNPRSTUVXYZ]|[0-9])-?){5,8}$/.test(str);
5044 },
5045 'de-DE': function deDE(str) {
5046 return /^((A|AA|AB|AC|AE|AH|AK|AM|AN|AÖ|AP|AS|AT|AU|AW|AZ|B|BA|BB|BC|BE|BF|BH|BI|BK|BL|BM|BN|BO|BÖ|BS|BT|BZ|C|CA|CB|CE|CO|CR|CW|D|DA|DD|DE|DH|DI|DL|DM|DN|DO|DU|DW|DZ|E|EA|EB|ED|EE|EF|EG|EH|EI|EL|EM|EN|ER|ES|EU|EW|F|FB|FD|FF|FG|FI|FL|FN|FO|FR|FS|FT|FÜ|FW|FZ|G|GA|GC|GD|GE|GF|GG|GI|GK|GL|GM|GN|GÖ|GP|GR|GS|GT|GÜ|GV|GW|GZ|H|HA|HB|HC|HD|HE|HF|HG|HH|HI|HK|HL|HM|HN|HO|HP|HR|HS|HU|HV|HX|HY|HZ|IK|IL|IN|IZ|J|JE|JL|K|KA|KB|KC|KE|KF|KG|KH|KI|KK|KL|KM|KN|KO|KR|KS|KT|KU|KW|KY|L|LA|LB|LC|LD|LF|LG|LH|LI|LL|LM|LN|LÖ|LP|LR|LU|M|MA|MB|MC|MD|ME|MG|MH|MI|MK|ML|MM|MN|MO|MQ|MR|MS|MÜ|MW|MY|MZ|N|NB|ND|NE|NF|NH|NI|NK|NM|NÖ|NP|NR|NT|NU|NW|NY|NZ|OA|OB|OC|OD|OE|OF|OG|OH|OK|OL|OP|OS|OZ|P|PA|PB|PE|PF|PI|PL|PM|PN|PR|PS|PW|PZ|R|RA|RC|RD|RE|RG|RH|RI|RL|RM|RN|RO|RP|RS|RT|RU|RV|RW|RZ|S|SB|SC|SE|SG|SI|SK|SL|SM|SN|SO|SP|SR|ST|SU|SW|SY|SZ|TE|TF|TG|TO|TP|TR|TS|TT|TÜ|ÜB|UE|UH|UL|UM|UN|V|VB|VG|VK|VR|VS|W|WA|WB|WE|WF|WI|WK|WL|WM|WN|WO|WR|WS|WT|WÜ|WW|WZ|Z|ZE|ZI|ZP|ZR|ZW|ZZ)[- ]?[A-Z]{1,2}[- ]?\d{1,4}|(ABG|ABI|AIB|AIC|ALF|ALZ|ANA|ANG|ANK|APD|ARN|ART|ASL|ASZ|AUR|AZE|BAD|BAR|BBG|BCH|BED|BER|BGD|BGL|BID|BIN|BIR|BIT|BIW|BKS|BLB|BLK|BNA|BOG|BOH|BOR|BOT|BRA|BRB|BRG|BRK|BRL|BRV|BSB|BSK|BTF|BÜD|BUL|BÜR|BÜS|BÜZ|CAS|CHA|CLP|CLZ|COC|COE|CUX|DAH|DAN|DAU|DBR|DEG|DEL|DGF|DIL|DIN|DIZ|DKB|DLG|DON|DUD|DÜW|EBE|EBN|EBS|ECK|EIC|EIL|EIN|EIS|EMD|EMS|ERB|ERH|ERK|ERZ|ESB|ESW|FDB|FDS|FEU|FFB|FKB|FLÖ|FOR|FRG|FRI|FRW|FTL|FÜS|GAN|GAP|GDB|GEL|GEO|GER|GHA|GHC|GLA|GMN|GNT|GOA|GOH|GRA|GRH|GRI|GRM|GRZ|GTH|GUB|GUN|GVM|HAB|HAL|HAM|HAS|HBN|HBS|HCH|HDH|HDL|HEB|HEF|HEI|HER|HET|HGN|HGW|HHM|HIG|HIP|HMÜ|HOG|HOH|HOL|HOM|HOR|HÖS|HOT|HRO|HSK|HST|HVL|HWI|IGB|ILL|JÜL|KEH|KEL|KEM|KIB|KLE|KLZ|KÖN|KÖT|KÖZ|KRU|KÜN|KUS|KYF|LAN|LAU|LBS|LBZ|LDK|LDS|LEO|LER|LEV|LIB|LIF|LIP|LÖB|LOS|LRO|LSZ|LÜN|LUP|LWL|MAB|MAI|MAK|MAL|MED|MEG|MEI|MEK|MEL|MER|MET|MGH|MGN|MHL|MIL|MKK|MOD|MOL|MON|MOS|MSE|MSH|MSP|MST|MTK|MTL|MÜB|MÜR|MYK|MZG|NAB|NAI|NAU|NDH|NEA|NEB|NEC|NEN|NES|NEW|NMB|NMS|NOH|NOL|NOM|NOR|NVP|NWM|OAL|OBB|OBG|OCH|OHA|ÖHR|OHV|OHZ|OPR|OSL|OVI|OVL|OVP|PAF|PAN|PAR|PCH|PEG|PIR|PLÖ|PRÜ|QFT|QLB|RDG|REG|REH|REI|RID|RIE|ROD|ROF|ROK|ROL|ROS|ROT|ROW|RSL|RÜD|RÜG|SAB|SAD|SAN|SAW|SBG|SBK|SCZ|SDH|SDL|SDT|SEB|SEE|SEF|SEL|SFB|SFT|SGH|SHA|SHG|SHK|SHL|SIG|SIM|SLE|SLF|SLK|SLN|SLS|SLÜ|SLZ|SMÜ|SOB|SOG|SOK|SÖM|SON|SPB|SPN|SRB|SRO|STA|STB|STD|STE|STL|SUL|SÜW|SWA|SZB|TBB|TDO|TET|TIR|TÖL|TUT|UEM|UER|UFF|USI|VAI|VEC|VER|VIB|VIE|VIT|VOH|WAF|WAK|WAN|WAR|WAT|WBS|WDA|WEL|WEN|WER|WES|WHV|WIL|WIS|WIT|WIZ|WLG|WMS|WND|WOB|WOH|WOL|WOR|WOS|WRN|WSF|WST|WSW|WTL|WTM|WUG|WÜM|WUN|WUR|WZL|ZEL|ZIG)[- ]?(([A-Z][- ]?\d{1,4})|([A-Z]{2}[- ]?\d{1,3})))[- ]?(E|H)?$/.test(str);
5047 },
5048 'de-LI': function deLI(str) {
5049 return /^FL[- ]?\d{1,5}[UZ]?$/.test(str);
5050 },
5051 'en-IN': function enIN(str) {
5052 return /^[A-Z]{2}[ -]?[0-9]{1,2}(?:[ -]?[A-Z])(?:[ -]?[A-Z]*)?[ -]?[0-9]{4}$/.test(str);
5053 },
5054 'es-AR': function esAR(str) {
5055 return /^(([A-Z]{2} ?[0-9]{3} ?[A-Z]{2})|([A-Z]{3} ?[0-9]{3}))$/.test(str);
5056 },
5057 'fi-FI': function fiFI(str) {
5058 return /^(?=.{4,7})(([A-Z]{1,3}|[0-9]{1,3})[\s-]?([A-Z]{1,3}|[0-9]{1,5}))$/.test(str);
5059 },
5060 'hu-HU': function huHU(str) {
5061 return /^((((?!AAA)(([A-NPRSTVZWXY]{1})([A-PR-Z]{1})([A-HJ-NPR-Z]))|(A[ABC]I)|A[ABC]O|A[A-W]Q|BPI|BPO|UCO|UDO|XAO)-(?!000)\d{3})|(M\d{6})|((CK|DT|CD|HC|H[ABEFIKLMNPRSTVX]|MA|OT|R[A-Z]) \d{2}-\d{2})|(CD \d{3}-\d{3})|(C-(C|X) \d{4})|(X-(A|B|C) \d{4})|(([EPVZ]-\d{5}))|(S A[A-Z]{2} \d{2})|(SP \d{2}-\d{2}))$/.test(str);
5062 },
5063 'pt-BR': function ptBR(str) {
5064 return /^[A-Z]{3}[ -]?[0-9][A-Z][0-9]{2}|[A-Z]{3}[ -]?[0-9]{4}$/.test(str);
5065 },
5066 'pt-PT': function ptPT(str) {
5067 return /^([A-Z]{2}|[0-9]{2})[ -·]?([A-Z]{2}|[0-9]{2})[ -·]?([A-Z]{2}|[0-9]{2})$/.test(str);
5068 },
5069 'sq-AL': function sqAL(str) {
5070 return /^[A-Z]{2}[- ]?((\d{3}[- ]?(([A-Z]{2})|T))|(R[- ]?\d{3}))$/.test(str);
5071 },
5072 'sv-SE': function svSE(str) {
5073 return /^[A-HJ-PR-UW-Z]{3} ?[\d]{2}[A-HJ-PR-UW-Z1-9]$|(^[A-ZÅÄÖ ]{2,7}$)/.test(str.trim());
5074 },
5075 'en-PK': function enPK(str) {
5076 return /(^[A-Z]{2}((\s|-){0,1})[0-9]{3,4}((\s|-)[0-9]{2}){0,1}$)|(^[A-Z]{3}((\s|-){0,1})[0-9]{3,4}((\s|-)[0-9]{2}){0,1}$)|(^[A-Z]{4}((\s|-){0,1})[0-9]{3,4}((\s|-)[0-9]{2}){0,1}$)|(^[A-Z]((\s|-){0,1})[0-9]{4}((\s|-)[0-9]{2}){0,1}$)/.test(str.trim());
5077 }
5078};
5079function isLicensePlate(str, locale) {
5080 assertString(str);
5081 if (locale in validators$1) {
5082 return validators$1[locale](str);
5083 } else if (locale === 'any') {
5084 for (var key in validators$1) {
5085 /* eslint guard-for-in: 0 */
5086 var validator = validators$1[key];
5087 if (validator(str)) {
5088 return true;
5089 }
5090 }
5091 return false;
5092 }
5093 throw new Error("Invalid locale '".concat(locale, "'"));
5094}
5095
5096var upperCaseRegex = /^[A-Z]$/;
5097var lowerCaseRegex = /^[a-z]$/;
5098var numberRegex = /^[0-9]$/;
5099var symbolRegex = /^[-#!$@£%^&*()_+|~=`{}\[\]:";'<>?,.\/\\ ]$/;
5100var defaultOptions$1 = {
5101 minLength: 8,
5102 minLowercase: 1,
5103 minUppercase: 1,
5104 minNumbers: 1,
5105 minSymbols: 1,
5106 returnScore: false,
5107 pointsPerUnique: 1,
5108 pointsPerRepeat: 0.5,
5109 pointsForContainingLower: 10,
5110 pointsForContainingUpper: 10,
5111 pointsForContainingNumber: 10,
5112 pointsForContainingSymbol: 10
5113};
5114
5115/* Counts number of occurrences of each char in a string
5116 * could be moved to util/ ?
5117*/
5118function countChars(str) {
5119 var result = {};
5120 Array.from(str).forEach(function (_char) {
5121 var curVal = result[_char];
5122 if (curVal) {
5123 result[_char] += 1;
5124 } else {
5125 result[_char] = 1;
5126 }
5127 });
5128 return result;
5129}
5130
5131/* Return information about a password */
5132function analyzePassword(password) {
5133 var charMap = countChars(password);
5134 var analysis = {
5135 length: password.length,
5136 uniqueChars: Object.keys(charMap).length,
5137 uppercaseCount: 0,
5138 lowercaseCount: 0,
5139 numberCount: 0,
5140 symbolCount: 0
5141 };
5142 Object.keys(charMap).forEach(function (_char2) {
5143 /* istanbul ignore else */
5144 if (upperCaseRegex.test(_char2)) {
5145 analysis.uppercaseCount += charMap[_char2];
5146 } else if (lowerCaseRegex.test(_char2)) {
5147 analysis.lowercaseCount += charMap[_char2];
5148 } else if (numberRegex.test(_char2)) {
5149 analysis.numberCount += charMap[_char2];
5150 } else if (symbolRegex.test(_char2)) {
5151 analysis.symbolCount += charMap[_char2];
5152 }
5153 });
5154 return analysis;
5155}
5156function scorePassword(analysis, scoringOptions) {
5157 var points = 0;
5158 points += analysis.uniqueChars * scoringOptions.pointsPerUnique;
5159 points += (analysis.length - analysis.uniqueChars) * scoringOptions.pointsPerRepeat;
5160 if (analysis.lowercaseCount > 0) {
5161 points += scoringOptions.pointsForContainingLower;
5162 }
5163 if (analysis.uppercaseCount > 0) {
5164 points += scoringOptions.pointsForContainingUpper;
5165 }
5166 if (analysis.numberCount > 0) {
5167 points += scoringOptions.pointsForContainingNumber;
5168 }
5169 if (analysis.symbolCount > 0) {
5170 points += scoringOptions.pointsForContainingSymbol;
5171 }
5172 return points;
5173}
5174function isStrongPassword(str) {
5175 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
5176 assertString(str);
5177 var analysis = analyzePassword(str);
5178 options = merge(options || {}, defaultOptions$1);
5179 if (options.returnScore) {
5180 return scorePassword(analysis, options);
5181 }
5182 return analysis.length >= options.minLength && analysis.lowercaseCount >= options.minLowercase && analysis.uppercaseCount >= options.minUppercase && analysis.numberCount >= options.minNumbers && analysis.symbolCount >= options.minSymbols;
5183}
5184
5185var AU = function AU(str) {
5186 var match = str.match(/^(AU)?(\d{11})$/);
5187 if (!match) {
5188 return false;
5189 }
5190 // @see {@link https://abr.business.gov.au/Help/AbnFormat}
5191 var weights = [10, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19];
5192 str = str.replace(/^AU/, '');
5193 var ABN = (parseInt(str.slice(0, 1), 10) - 1).toString() + str.slice(1);
5194 var total = 0;
5195 for (var i = 0; i < 11; i++) {
5196 total += weights[i] * ABN.charAt(i);
5197 }
5198 return total !== 0 && total % 89 === 0;
5199};
5200var CH = function CH(str) {
5201 // @see {@link https://www.ech.ch/de/ech/ech-0097/5.2.0}
5202 var hasValidCheckNumber = function hasValidCheckNumber(digits) {
5203 var lastDigit = digits.pop(); // used as check number
5204 var weights = [5, 4, 3, 2, 7, 6, 5, 4];
5205 var calculatedCheckNumber = (11 - digits.reduce(function (acc, el, idx) {
5206 return acc + el * weights[idx];
5207 }, 0) % 11) % 11;
5208 return lastDigit === calculatedCheckNumber;
5209 };
5210
5211 // @see {@link https://www.estv.admin.ch/estv/de/home/mehrwertsteuer/uid/mwst-uid-nummer.html}
5212 return /^(CHE[- ]?)?(\d{9}|(\d{3}\.\d{3}\.\d{3})|(\d{3} \d{3} \d{3})) ?(TVA|MWST|IVA)?$/.test(str) && hasValidCheckNumber(str.match(/\d/g).map(function (el) {
5213 return +el;
5214 }));
5215};
5216var PT = function PT(str) {
5217 var match = str.match(/^(PT)?(\d{9})$/);
5218 if (!match) {
5219 return false;
5220 }
5221 var tin = match[2];
5222 var checksum = 11 - reverseMultiplyAndSum(tin.split('').slice(0, 8).map(function (a) {
5223 return parseInt(a, 10);
5224 }), 9) % 11;
5225 if (checksum > 9) {
5226 return parseInt(tin[8], 10) === 0;
5227 }
5228 return checksum === parseInt(tin[8], 10);
5229};
5230var vatMatchers = {
5231 /**
5232 * European Union VAT identification numbers
5233 */
5234 AT: function AT(str) {
5235 return /^(AT)?U\d{8}$/.test(str);
5236 },
5237 BE: function BE(str) {
5238 return /^(BE)?\d{10}$/.test(str);
5239 },
5240 BG: function BG(str) {
5241 return /^(BG)?\d{9,10}$/.test(str);
5242 },
5243 HR: function HR(str) {
5244 return /^(HR)?\d{11}$/.test(str);
5245 },
5246 CY: function CY(str) {
5247 return /^(CY)?\w{9}$/.test(str);
5248 },
5249 CZ: function CZ(str) {
5250 return /^(CZ)?\d{8,10}$/.test(str);
5251 },
5252 DK: function DK(str) {
5253 return /^(DK)?\d{8}$/.test(str);
5254 },
5255 EE: function EE(str) {
5256 return /^(EE)?\d{9}$/.test(str);
5257 },
5258 FI: function FI(str) {
5259 return /^(FI)?\d{8}$/.test(str);
5260 },
5261 FR: function FR(str) {
5262 return /^(FR)?\w{2}\d{9}$/.test(str);
5263 },
5264 DE: function DE(str) {
5265 return /^(DE)?\d{9}$/.test(str);
5266 },
5267 EL: function EL(str) {
5268 return /^(EL)?\d{9}$/.test(str);
5269 },
5270 HU: function HU(str) {
5271 return /^(HU)?\d{8}$/.test(str);
5272 },
5273 IE: function IE(str) {
5274 return /^(IE)?\d{7}\w{1}(W)?$/.test(str);
5275 },
5276 IT: function IT(str) {
5277 return /^(IT)?\d{11}$/.test(str);
5278 },
5279 LV: function LV(str) {
5280 return /^(LV)?\d{11}$/.test(str);
5281 },
5282 LT: function LT(str) {
5283 return /^(LT)?\d{9,12}$/.test(str);
5284 },
5285 LU: function LU(str) {
5286 return /^(LU)?\d{8}$/.test(str);
5287 },
5288 MT: function MT(str) {
5289 return /^(MT)?\d{8}$/.test(str);
5290 },
5291 NL: function NL(str) {
5292 return /^(NL)?\d{9}B\d{2}$/.test(str);
5293 },
5294 PL: function PL(str) {
5295 return /^(PL)?(\d{10}|(\d{3}-\d{3}-\d{2}-\d{2})|(\d{3}-\d{2}-\d{2}-\d{3}))$/.test(str);
5296 },
5297 PT: PT,
5298 RO: function RO(str) {
5299 return /^(RO)?\d{2,10}$/.test(str);
5300 },
5301 SK: function SK(str) {
5302 return /^(SK)?\d{10}$/.test(str);
5303 },
5304 SI: function SI(str) {
5305 return /^(SI)?\d{8}$/.test(str);
5306 },
5307 ES: function ES(str) {
5308 return /^(ES)?\w\d{7}[A-Z]$/.test(str);
5309 },
5310 SE: function SE(str) {
5311 return /^(SE)?\d{12}$/.test(str);
5312 },
5313 /**
5314 * VAT numbers of non-EU countries
5315 */
5316 AL: function AL(str) {
5317 return /^(AL)?\w{9}[A-Z]$/.test(str);
5318 },
5319 MK: function MK(str) {
5320 return /^(MK)?\d{13}$/.test(str);
5321 },
5322 AU: AU,
5323 BY: function BY(str) {
5324 return /^(УНП )?\d{9}$/.test(str);
5325 },
5326 CA: function CA(str) {
5327 return /^(CA)?\d{9}$/.test(str);
5328 },
5329 IS: function IS(str) {
5330 return /^(IS)?\d{5,6}$/.test(str);
5331 },
5332 IN: function IN(str) {
5333 return /^(IN)?\d{15}$/.test(str);
5334 },
5335 ID: function ID(str) {
5336 return /^(ID)?(\d{15}|(\d{2}.\d{3}.\d{3}.\d{1}-\d{3}.\d{3}))$/.test(str);
5337 },
5338 IL: function IL(str) {
5339 return /^(IL)?\d{9}$/.test(str);
5340 },
5341 KZ: function KZ(str) {
5342 return /^(KZ)?\d{12}$/.test(str);
5343 },
5344 NZ: function NZ(str) {
5345 return /^(NZ)?\d{9}$/.test(str);
5346 },
5347 NG: function NG(str) {
5348 return /^(NG)?(\d{12}|(\d{8}-\d{4}))$/.test(str);
5349 },
5350 NO: function NO(str) {
5351 return /^(NO)?\d{9}MVA$/.test(str);
5352 },
5353 PH: function PH(str) {
5354 return /^(PH)?(\d{12}|\d{3} \d{3} \d{3} \d{3})$/.test(str);
5355 },
5356 RU: function RU(str) {
5357 return /^(RU)?(\d{10}|\d{12})$/.test(str);
5358 },
5359 SM: function SM(str) {
5360 return /^(SM)?\d{5}$/.test(str);
5361 },
5362 SA: function SA(str) {
5363 return /^(SA)?\d{15}$/.test(str);
5364 },
5365 RS: function RS(str) {
5366 return /^(RS)?\d{9}$/.test(str);
5367 },
5368 CH: CH,
5369 TR: function TR(str) {
5370 return /^(TR)?\d{10}$/.test(str);
5371 },
5372 UA: function UA(str) {
5373 return /^(UA)?\d{12}$/.test(str);
5374 },
5375 GB: function GB(str) {
5376 return /^GB((\d{3} \d{4} ([0-8][0-9]|9[0-6]))|(\d{9} \d{3})|(((GD[0-4])|(HA[5-9]))[0-9]{2}))$/.test(str);
5377 },
5378 UZ: function UZ(str) {
5379 return /^(UZ)?\d{9}$/.test(str);
5380 },
5381 /**
5382 * VAT numbers of Latin American countries
5383 */
5384 AR: function AR(str) {
5385 return /^(AR)?\d{11}$/.test(str);
5386 },
5387 BO: function BO(str) {
5388 return /^(BO)?\d{7}$/.test(str);
5389 },
5390 BR: function BR(str) {
5391 return /^(BR)?((\d{2}.\d{3}.\d{3}\/\d{4}-\d{2})|(\d{3}.\d{3}.\d{3}-\d{2}))$/.test(str);
5392 },
5393 CL: function CL(str) {
5394 return /^(CL)?\d{8}-\d{1}$/.test(str);
5395 },
5396 CO: function CO(str) {
5397 return /^(CO)?\d{10}$/.test(str);
5398 },
5399 CR: function CR(str) {
5400 return /^(CR)?\d{9,12}$/.test(str);
5401 },
5402 EC: function EC(str) {
5403 return /^(EC)?\d{13}$/.test(str);
5404 },
5405 SV: function SV(str) {
5406 return /^(SV)?\d{4}-\d{6}-\d{3}-\d{1}$/.test(str);
5407 },
5408 GT: function GT(str) {
5409 return /^(GT)?\d{7}-\d{1}$/.test(str);
5410 },
5411 HN: function HN(str) {
5412 return /^(HN)?$/.test(str);
5413 },
5414 MX: function MX(str) {
5415 return /^(MX)?\w{3,4}\d{6}\w{3}$/.test(str);
5416 },
5417 NI: function NI(str) {
5418 return /^(NI)?\d{3}-\d{6}-\d{4}\w{1}$/.test(str);
5419 },
5420 PA: function PA(str) {
5421 return /^(PA)?$/.test(str);
5422 },
5423 PY: function PY(str) {
5424 return /^(PY)?\d{6,8}-\d{1}$/.test(str);
5425 },
5426 PE: function PE(str) {
5427 return /^(PE)?\d{11}$/.test(str);
5428 },
5429 DO: function DO(str) {
5430 return /^(DO)?(\d{11}|(\d{3}-\d{7}-\d{1})|[1,4,5]{1}\d{8}|([1,4,5]{1})-\d{2}-\d{5}-\d{1})$/.test(str);
5431 },
5432 UY: function UY(str) {
5433 return /^(UY)?\d{12}$/.test(str);
5434 },
5435 VE: function VE(str) {
5436 return /^(VE)?[J,G,V,E]{1}-(\d{9}|(\d{8}-\d{1}))$/.test(str);
5437 }
5438};
5439function isVAT(str, countryCode) {
5440 assertString(str);
5441 assertString(countryCode);
5442 if (countryCode in vatMatchers) {
5443 return vatMatchers[countryCode](str);
5444 }
5445 throw new Error("Invalid country code: '".concat(countryCode, "'"));
5446}
5447
5448var version = '13.12.0';
5449var validator = {
5450 version: version,
5451 toDate: toDate,
5452 toFloat: toFloat,
5453 toInt: toInt,
5454 toBoolean: toBoolean,
5455 equals: equals,
5456 contains: contains,
5457 matches: matches,
5458 isEmail: isEmail,
5459 isURL: isURL,
5460 isMACAddress: isMACAddress,
5461 isIP: isIP,
5462 isIPRange: isIPRange,
5463 isFQDN: isFQDN,
5464 isBoolean: isBoolean,
5465 isIBAN: isIBAN,
5466 isBIC: isBIC,
5467 isAbaRouting: isAbaRouting,
5468 isAlpha: isAlpha,
5469 isAlphaLocales: locales$1,
5470 isAlphanumeric: isAlphanumeric,
5471 isAlphanumericLocales: locales$2,
5472 isNumeric: isNumeric,
5473 isPassportNumber: isPassportNumber,
5474 isPort: isPort,
5475 isLowercase: isLowercase,
5476 isUppercase: isUppercase,
5477 isAscii: isAscii,
5478 isFullWidth: isFullWidth,
5479 isHalfWidth: isHalfWidth,
5480 isVariableWidth: isVariableWidth,
5481 isMultibyte: isMultibyte,
5482 isSemVer: isSemVer,
5483 isSurrogatePair: isSurrogatePair,
5484 isInt: isInt,
5485 isIMEI: isIMEI,
5486 isFloat: isFloat,
5487 isFloatLocales: locales,
5488 isDecimal: isDecimal,
5489 isHexadecimal: isHexadecimal,
5490 isOctal: isOctal,
5491 isDivisibleBy: isDivisibleBy,
5492 isHexColor: isHexColor,
5493 isRgbColor: isRgbColor,
5494 isHSL: isHSL,
5495 isISRC: isISRC,
5496 isMD5: isMD5,
5497 isHash: isHash,
5498 isJWT: isJWT,
5499 isJSON: isJSON,
5500 isEmpty: isEmpty,
5501 isLength: isLength,
5502 isLocale: isLocale,
5503 isByteLength: isByteLength,
5504 isUUID: isUUID,
5505 isMongoId: isMongoId,
5506 isAfter: isAfter,
5507 isBefore: isBefore,
5508 isIn: isIn,
5509 isLuhnNumber: isLuhnNumber,
5510 isCreditCard: isCreditCard,
5511 isIdentityCard: isIdentityCard,
5512 isEAN: isEAN,
5513 isISIN: isISIN,
5514 isISBN: isISBN,
5515 isISSN: isISSN,
5516 isMobilePhone: isMobilePhone,
5517 isMobilePhoneLocales: locales$4,
5518 isPostalCode: isPostalCode,
5519 isPostalCodeLocales: locales$5,
5520 isEthereumAddress: isEthereumAddress,
5521 isCurrency: isCurrency,
5522 isBtcAddress: isBtcAddress,
5523 isISO6346: isISO6346,
5524 isFreightContainerID: isFreightContainerID,
5525 isISO6391: isISO6391,
5526 isISO8601: isISO8601,
5527 isRFC3339: isRFC3339,
5528 isISO31661Alpha2: isISO31661Alpha2,
5529 isISO31661Alpha3: isISO31661Alpha3,
5530 isISO4217: isISO4217,
5531 isBase32: isBase32,
5532 isBase58: isBase58,
5533 isBase64: isBase64,
5534 isDataURI: isDataURI,
5535 isMagnetURI: isMagnetURI,
5536 isMailtoURI: isMailtoURI,
5537 isMimeType: isMimeType,
5538 isLatLong: isLatLong,
5539 ltrim: ltrim,
5540 rtrim: rtrim,
5541 trim: trim,
5542 escape: escape,
5543 unescape: unescape,
5544 stripLow: stripLow,
5545 whitelist: whitelist,
5546 blacklist: blacklist$1,
5547 isWhitelisted: isWhitelisted,
5548 normalizeEmail: normalizeEmail,
5549 toString: toString,
5550 isSlug: isSlug,
5551 isStrongPassword: isStrongPassword,
5552 isTaxID: isTaxID,
5553 isDate: isDate,
5554 isTime: isTime,
5555 isLicensePlate: isLicensePlate,
5556 isVAT: isVAT,
5557 ibanLocales: locales$3
5558};
5559
5560return validator;
5561
5562})));