diff --git a/README.md b/README.md
index 53bc33529..9bf2e47b5 100644
--- a/README.md
+++ b/README.md
@@ -100,6 +100,7 @@ Validator | Description
**isHash(str, algorithm)** | check if the string is a hash of type algorithm.
Algorithm is one of `['md4', 'md5', 'sha1', 'sha256', 'sha384', 'sha512', 'ripemd128', 'ripemd160', 'tiger128', 'tiger160', 'tiger192', 'crc32', 'crc32b']`
**isHexColor(str)** | check if the string is a hexadecimal color.
**isHexadecimal(str)** | check if the string is a hexadecimal number.
+**isIBAN(str, locale)** | check if the string is a valid IBAN number,
(locale is one of `[ 'AD', 'AT', 'AU', 'BE', 'BG', 'CA', 'CH', 'CZ', 'DE', 'DK', 'DZ', 'EE', 'ES', 'FI', 'FR', 'GB', 'GR', 'HR', 'HU', 'ID', 'IL', 'IN', 'IS', 'IT', 'JP', 'KE', 'LI', 'LT', 'LU', 'LV', 'MX', 'NL', 'NO', 'PL', 'PT', 'RO', 'RU', 'SA', 'SE', 'SI', 'TN', 'TW', 'UA', 'US', 'ZA', 'ZM' ]` OR 'any'. If 'any' is used, function will check if any of the locals match with the first twi caracters of the IBAN number (wich corresponds to the ISO 3166-1 alpha-2 country code). Locale list is `validator.isIBANLocales`).
**isIdentityCard(str [, locale])** | check if the string is a valid identity card code.
`locale` is one of `['ES', 'zh-TW', 'he-IL']` OR `'any'`. If 'any' is used, function will check if any of the locals match.
Defaults to 'any'.
**isIP(str [, version])** | check if the string is an IP (version 4 or 6).
**isIPRange(str)** | check if the string is an IP Range(version 4 only).
diff --git a/index.js b/index.js
index 0af96d5e6..0d3eda308 100644
--- a/index.js
+++ b/index.js
@@ -95,6 +95,8 @@ var _isBefore = _interopRequireDefault(require("./lib/isBefore"));
var _isIn = _interopRequireDefault(require("./lib/isIn"));
+var _isIBAN = _interopRequireWildcard(require("./lib/isIBAN"));
+
var _isCreditCard = _interopRequireDefault(require("./lib/isCreditCard"));
var _isIdentityCard = _interopRequireDefault(require("./lib/isIdentityCard"));
@@ -206,6 +208,8 @@ var validator = {
isAfter: _isAfter.default,
isBefore: _isBefore.default,
isIn: _isIn.default,
+ isIBAN: _isIBAN.default,
+ isIBANLocales: _isIBAN.locales,
isCreditCard: _isCreditCard.default,
isIdentityCard: _isIdentityCard.default,
isISIN: _isISIN.default,
diff --git a/lib/isIBAN.js b/lib/isIBAN.js
new file mode 100644
index 000000000..29bd60593
--- /dev/null
+++ b/lib/isIBAN.js
@@ -0,0 +1,128 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = isIBAN;
+exports.locales = void 0;
+
+var _assertString = _interopRequireDefault(require("./util/assertString"));
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/* eslint-disable max-len */
+var iban = {
+ AD: /^(AD[0-9]{2})\d{8}[0-9A-Z]{12}$/,
+ AL: /^(AL[0-9]{2})\d{8}[A-Z0-9]{16}$/,
+ AT: /^(AT[0-9]{2})\d{16}$/,
+ BA: /^(BA[0-9]{2})\d{16}$/,
+ BE: /^(BE[0-9]{2})\d{12}$/,
+ BG: /^(BG[0-9]{2})[A-Z]{4}\d{4}[A-Z0-9]{10}$/,
+ BH: /^(BH[0-9]{2})[A-Z]{4}[A-Z0-9]{14}$/,
+ BR: /^(BR[0-9]{2})\d{23}[A-Z][A-Z0-9]$/,
+ CH: /^(CH[0-9]{2})\d{17}$/,
+ CY: /^(CY[0-9]{2})\d{8}[A-Z0-9]{16}$/,
+ CZ: /^(CZ[0-9]{2})\d{20}$/,
+ DE: /^(DE[0-9]{2})\d{18}$/,
+ DK: /^(DK[0-9]{2})\d{14}$/,
+ EE: /^(EE[0-9]{2})\d{16}$/,
+ ES: /^(ES[0-9]{2})\d{20}$/,
+ FO: /^(FO[0-9]{2})\d{14}$/,
+ FI: /^(FI[0-9]{2})\d{14}$/,
+ FR: /^(FR[0-9]{2})\d{10}[A-Z0-9]{11}\d{2}$/,
+ GB: /^(GB[0-9]{2})[A-Z]{4}\d{14}$/,
+ GE: /^(GE[0-9]{2})[A-Z]{2}\d{16}$/,
+ GI: /^(GI[0-9]{2})[A-Z]{4}[A-Z0-9]{15}$/,
+ GL: /^(GL[0-9]{2})\d{14}$/,
+ GR: /^(GR[0-9]{2})\d{7}[A-Z0-9]{16}$/,
+ HR: /^(HR[0-9]{2})\d{17}$/,
+ HU: /^(HU[0-9]{2})\d{24}$/,
+ IE: /^(IE[0-9]{2})[A-Z]{4}\d{14}$/,
+ IS: /^(IS[0-9]{2})\d{22}$/,
+ IT: /^(IT[0-9]{2})[A-Z]\d{10}[A-Z0-9]{12}$/,
+ JO: /^(JO[0-9]{2})[A-Z]{4}\d{4}[A-Z0-9]{18}$/,
+ KW: /^(KW[0-9]{2})[A-Z]{4}[A-Z0-9]{22}$/,
+ KZ: /^(KZ[0-9]{2})\d{3}[A-Z0-9]{13}$/,
+ LB: /^(LB[0-9]{2})\d{4}[A-Z0-9]{20}$/,
+ LI: /^(LI[0-9]{2})\d{5}[A-Z0-9]{12}$/,
+ LT: /^(LT[0-9]{2})\d{16}$/,
+ LU: /^(LU[0-9]{2})\d{3}[A-Z0-9]{13}$/,
+ LV: /^(LV[0-9]{2})[A-Z]{4}[A-Z0-9]{13}$/,
+ MC: /^(MC[0-9]{2})\d{10}[A-Z0-9]{11}\d{2}$/,
+ MD: /^(MD[0-9]{2})[A-Z]{2}[A-Z0-9]{18}$/,
+ ME: /^(ME[0-9]{2})\d{18}$/,
+ MK: /^(MK[0-9]{2})\d{3}[A-Z0-9]{12}$/,
+ MT: /^(MT[0-9]{2})[A-Z]{4}\d{5}[A-Z0-9]{18}$/,
+ NL: /^(NL[0-9]{2})[A-Z]{4}\d{10}$/,
+ NO: /^(NO[0-9]{2})\d{11}$/,
+ PL: /^(PL[0-9]{2})\d{24}$/,
+ PS: /^(PS[0-9]{2})[A-Z]{4}[A-Z0-9]{21}$/,
+ PT: /^(PT[0-9]{2})\d{21}$/,
+ QA: /^(QA[0-9]{2})[A-Z]{4}[A-Z0-9]{21}$/,
+ RO: /^(RO[0-9]{2})[A-Z]{4}[A-Z0-9]{16}$/,
+ SA: /^(SA[0-9]{2})\d{2}[A-Z0-9]{18}$/,
+ SE: /^(SE[0-9]{2})\d{20}$/,
+ SI: /^(SI[0-9]{2})\d{15}$/,
+ SK: /^(SK[0-9]{2})\d{20}$/,
+ SM: /^(SM[0-9]{2})[A-Z]{1}\d{10}[A-Z0-9]{12}$/,
+ RS: /^(RS[0-9]{2})\d{18}$/,
+ TN: /^(TN[0-9]{2})\d{20}$/,
+ TR: /^(TR[0-9]{2})\d{5}[A-Z0-9]{17}$/,
+ UA: /^(UA[0-9]{2})\d{6}[A-Z0-9]{19}$/,
+ XK: /^(XK[0-9]{2})\d{16}$/
+};
+/* eslint-enable max-len */
+
+/**
+ * @function IbanCalcul - calculate if the IBAN corresponds to the reglementation: converting
+ * it into an integer and performing a basic mod-97 operation. If the IBAN is valid, the remainder
+ * equals 1.
+ * 1- Check that the total IBAN length is correct as per the country. If not, the IBAN is invalid
+ * 2- Move the four initial characters to the end of the string
+ * 3- Replace each letter in the string with two digits, thereby expanding the string,
+ * where A = 10..., Z = 35
+ * 4- Interpret the string as a decimal integer and compute the remainder of that number on
+ * division by 97
+ * @param {e} - recieves the IBAN tested
+ * @warns IBAN's length differs from country to another, the maximum length is 34 characters so
+ * calculating its modulus 97 is not possible for all machines.To solve this, the function calculate
+ * the modulus of the first 9 digit by 97 and add the result to the beginning of the remain IBAN
+ * number. The process is repeated untill the result's length is less than 10
+ */
+
+var IbanCalcul = function IbanCalcul(e) {
+ var countryCode = e.slice(0, 4);
+ var result = e.slice(4, e.length) + countryCode;
+
+ for (var counter = 1; counter <= Math.ceil(e.length / 10) + 1; counter++) {
+ var remainder = result.slice(0, 10).replace(/[A-Z]/g, function (element) {
+ return element.charCodeAt() - 55;
+ }) % 97;
+ result = remainder + result.slice(10);
+ }
+
+ if (result === '1') return true;
+ return false;
+};
+
+function isIBAN(str, locale) {
+ (0, _assertString.default)(str);
+ str = str.toUpperCase();
+
+ if (locale in iban) {
+ return iban[locale].test(str) && IbanCalcul(str);
+ } else if (!locale || locale === 'any') {
+ locale = str.slice(0, 2);
+
+ if (locale in iban) {
+ return iban[locale].test(str) && IbanCalcul(str);
+ }
+
+ return false;
+ }
+
+ throw new Error("Invalid locale '".concat(locale, "'"));
+}
+
+var locales = Object.keys(iban);
+exports.locales = locales;
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index 1d21203d9..259e417f5 100644
--- a/src/index.js
+++ b/src/index.js
@@ -57,6 +57,8 @@ import isBefore from './lib/isBefore';
import isIn from './lib/isIn';
+import isIBAN, { locales as isIBANLocales } from './lib/isIBAN';
+
import isCreditCard from './lib/isCreditCard';
import isIdentityCard from './lib/isIdentityCard';
@@ -147,6 +149,8 @@ const validator = {
isAfter,
isBefore,
isIn,
+ isIBAN,
+ isIBANLocales,
isCreditCard,
isIdentityCard,
isISIN,
diff --git a/src/lib/isIBAN.js b/src/lib/isIBAN.js
new file mode 100644
index 000000000..c8a30f341
--- /dev/null
+++ b/src/lib/isIBAN.js
@@ -0,0 +1,109 @@
+import assertString from './util/assertString';
+
+/* eslint-disable max-len */
+const iban = {
+ AD: /^(AD[0-9]{2})\d{8}[0-9A-Z]{12}$/,
+ AL: /^(AL[0-9]{2})\d{8}[A-Z0-9]{16}$/,
+ AT: /^(AT[0-9]{2})\d{16}$/,
+ BA: /^(BA[0-9]{2})\d{16}$/,
+ BE: /^(BE[0-9]{2})\d{12}$/,
+ BG: /^(BG[0-9]{2})[A-Z]{4}\d{4}[A-Z0-9]{10}$/,
+ BH: /^(BH[0-9]{2})[A-Z]{4}[A-Z0-9]{14}$/,
+ BR: /^(BR[0-9]{2})\d{23}[A-Z][A-Z0-9]$/,
+ CH: /^(CH[0-9]{2})\d{17}$/,
+ CY: /^(CY[0-9]{2})\d{8}[A-Z0-9]{16}$/,
+ CZ: /^(CZ[0-9]{2})\d{20}$/,
+ DE: /^(DE[0-9]{2})\d{18}$/,
+ DK: /^(DK[0-9]{2})\d{14}$/,
+ EE: /^(EE[0-9]{2})\d{16}$/,
+ ES: /^(ES[0-9]{2})\d{20}$/,
+ FO: /^(FO[0-9]{2})\d{14}$/,
+ FI: /^(FI[0-9]{2})\d{14}$/,
+ FR: /^(FR[0-9]{2})\d{10}[A-Z0-9]{11}\d{2}$/,
+ GB: /^(GB[0-9]{2})[A-Z]{4}\d{14}$/,
+ GE: /^(GE[0-9]{2})[A-Z]{2}\d{16}$/,
+ GI: /^(GI[0-9]{2})[A-Z]{4}[A-Z0-9]{15}$/,
+ GL: /^(GL[0-9]{2})\d{14}$/,
+ GR: /^(GR[0-9]{2})\d{7}[A-Z0-9]{16}$/,
+ HR: /^(HR[0-9]{2})\d{17}$/,
+ HU: /^(HU[0-9]{2})\d{24}$/,
+ IE: /^(IE[0-9]{2})[A-Z]{4}\d{14}$/,
+ IS: /^(IS[0-9]{2})\d{22}$/,
+ IT: /^(IT[0-9]{2})[A-Z]\d{10}[A-Z0-9]{12}$/,
+ JO: /^(JO[0-9]{2})[A-Z]{4}\d{4}[A-Z0-9]{18}$/,
+ KW: /^(KW[0-9]{2})[A-Z]{4}[A-Z0-9]{22}$/,
+ KZ: /^(KZ[0-9]{2})\d{3}[A-Z0-9]{13}$/,
+ LB: /^(LB[0-9]{2})\d{4}[A-Z0-9]{20}$/,
+ LI: /^(LI[0-9]{2})\d{5}[A-Z0-9]{12}$/,
+ LT: /^(LT[0-9]{2})\d{16}$/,
+ LU: /^(LU[0-9]{2})\d{3}[A-Z0-9]{13}$/,
+ LV: /^(LV[0-9]{2})[A-Z]{4}[A-Z0-9]{13}$/,
+ MC: /^(MC[0-9]{2})\d{10}[A-Z0-9]{11}\d{2}$/,
+ MD: /^(MD[0-9]{2})[A-Z]{2}[A-Z0-9]{18}$/,
+ ME: /^(ME[0-9]{2})\d{18}$/,
+ MK: /^(MK[0-9]{2})\d{3}[A-Z0-9]{12}$/,
+ MT: /^(MT[0-9]{2})[A-Z]{4}\d{5}[A-Z0-9]{18}$/,
+ NL: /^(NL[0-9]{2})[A-Z]{4}\d{10}$/,
+ NO: /^(NO[0-9]{2})\d{11}$/,
+ PL: /^(PL[0-9]{2})\d{24}$/,
+ PS: /^(PS[0-9]{2})[A-Z]{4}[A-Z0-9]{21}$/,
+ PT: /^(PT[0-9]{2})\d{21}$/,
+ QA: /^(QA[0-9]{2})[A-Z]{4}[A-Z0-9]{21}$/,
+ RO: /^(RO[0-9]{2})[A-Z]{4}[A-Z0-9]{16}$/,
+ SA: /^(SA[0-9]{2})\d{2}[A-Z0-9]{18}$/,
+ SE: /^(SE[0-9]{2})\d{20}$/,
+ SI: /^(SI[0-9]{2})\d{15}$/,
+ SK: /^(SK[0-9]{2})\d{20}$/,
+ SM: /^(SM[0-9]{2})[A-Z]{1}\d{10}[A-Z0-9]{12}$/,
+ RS: /^(RS[0-9]{2})\d{18}$/,
+ TN: /^(TN[0-9]{2})\d{20}$/,
+ TR: /^(TR[0-9]{2})\d{5}[A-Z0-9]{17}$/,
+ UA: /^(UA[0-9]{2})\d{6}[A-Z0-9]{19}$/,
+ XK: /^(XK[0-9]{2})\d{16}$/,
+};
+/* eslint-enable max-len */
+
+/**
+ * @function IbanCalcul - calculate if the IBAN corresponds to the reglementation: converting
+ * it into an integer and performing a basic mod-97 operation. If the IBAN is valid, the remainder
+ * equals 1.
+ * 1- Check that the total IBAN length is correct as per the country. If not, the IBAN is invalid
+ * 2- Move the four initial characters to the end of the string
+ * 3- Replace each letter in the string with two digits, thereby expanding the string,
+ * where A = 10..., Z = 35
+ * 4- Interpret the string as a decimal integer and compute the remainder of that number on
+ * division by 97
+ * @param {e} - recieves the IBAN tested
+ * @warns IBAN's length differs from country to another, the maximum length is 34 characters so
+ * calculating its modulus 97 is not possible for all machines.To solve this, the function calculate
+ * the modulus of the first 9 digit by 97 and add the result to the beginning of the remain IBAN
+ * number. The process is repeated untill the result's length is less than 10
+ */
+const IbanCalcul = (e) => {
+ const countryCode = e.slice(0, 4);
+ let result = e.slice(4, e.length) + countryCode;
+ for (let counter = 1; counter <= Math.ceil(e.length / 10) + 1; counter++) {
+ let remainder =
+ result.slice(0, 10).replace(/[A-Z]/g, element => element.charCodeAt() - 55) % 97;
+ result = remainder + result.slice(10);
+ }
+ if (result === '1') return true;
+ return false;
+};
+
+export default function isIBAN(str, locale) {
+ assertString(str);
+ str = str.toUpperCase();
+ if (locale in iban) {
+ return iban[locale].test(str) && IbanCalcul(str);
+ } else if (!locale || locale === 'any') {
+ locale = str.slice(0, 2);
+ if (locale in iban) {
+ return iban[locale].test(str) && IbanCalcul(str);
+ }
+ return false;
+ }
+ throw new Error(`Invalid locale '${locale}'`);
+}
+
+export const locales = Object.keys(iban);
diff --git a/test/validators.js b/test/validators.js
index acb5ac226..e7081309a 100644
--- a/test/validators.js
+++ b/test/validators.js
@@ -5266,6 +5266,496 @@ describe('Validators', () => {
});
});
+ it('should validate IBAN number', () => {
+ let fixtures = [
+ {
+ locale: 'AD',
+ valid: ['AD1200012030200359100100'],
+ invalid: ['AD1200012030200359100109', 'AB1200012030200359100109'],
+ },
+ {
+ locale: 'AL',
+ valid: ['AL47212110090000000235698741'],
+ invalid: [
+ 'AL47212110090000000235698749',
+ 'AL472A2110090000000235698741',
+ 'AL472121100900000002356987419',
+ ],
+ },
+ {
+ locale: 'AT',
+ valid: ['AT611904300234573201'],
+ invalid: ['AT611904300234573209', 'AT6119043002345732019', 'AT61190430023457320X'],
+ },
+ {
+ locale: 'BH',
+ valid: ['BH67BMAG00001299123456'],
+ invalid: ['BH67BMAG00001299123451', 'BH67BM2G00001299123456', 'BH67BMAG000012991234569'],
+ },
+ {
+ locale: 'BE',
+ valid: ['BE68539007547034'],
+ invalid: ['BE68539007547031', 'BE6853900754703X', 'BE685390075470349'],
+ },
+ {
+ locale: 'BA',
+ valid: ['BA391290079401028494'],
+ invalid: ['BA391290079401028499', 'BA39129007940102849X', 'BA3912900794010284949'],
+ },
+ {
+ locale: 'BG',
+ valid: ['BG80BNBG96611020345678'],
+ invalid: [
+ 'BG80BNBG96611020345679',
+ 'BG80B9BG96611020345678',
+ 'BG80BNBG9A611020345678',
+ 'BG80BNBG966110203456789',
+ ],
+ },
+ {
+ locale: 'BR',
+ valid: ['BR9700360305000010009795493P1'],
+ invalid: [
+ 'BR9700360305000010009795499P1',
+ 'BR970036030500001000979549391',
+ 'BR970036030500001000979549AP1',
+ 'BR9700360305000010009795493P19',
+ ],
+ },
+ {
+ locale: 'CH',
+ valid: ['CH9300762011623852957'],
+ invalid: ['CH9300762011623852959', 'CH930076201162385295A', 'CH93007620116238529579'],
+ },
+ {
+ locale: 'CY',
+ valid: ['CY17002001280000001200527600'],
+ invalid: [
+ 'CY17002001280000001200527609',
+ 'CY17A02001280000001200527600',
+ 'CY170020012800000012005276009',
+ ],
+ },
+ {
+ locale: 'CZ',
+ valid: ['CZ6508000000192000145399'],
+ invalid: [
+ 'CZ6508000000192000145391',
+ 'CZ650800000019200014539A',
+ 'CZ65080000001920001453999',
+ ],
+ },
+ {
+ locale: 'DE',
+ valid: ['DE89370400440532013000'],
+ invalid: ['DE89370400440532013009', 'DE8937040044053201300A', 'DE893704004405320130009'],
+ },
+ {
+ locale: 'DK',
+ valid: ['DK5000400440116243'],
+ invalid: ['DK5000400440116249', 'DK500040044011624A', 'DK50004004401162439'],
+ },
+ {
+ locale: 'EE',
+ valid: ['EE382200221020145685'],
+ invalid: ['EE382200221020145689', 'EE38220022102014568A', 'EE3822002210201456859'],
+ },
+ {
+ locale: 'ES',
+ valid: ['ES9121000418450200051332'],
+ invalid: [
+ 'ES9121000418450200051339',
+ 'ES912100041845020005133A',
+ 'ES91210004184502000513329',
+ ],
+ },
+ {
+ locale: 'FO',
+ valid: ['FO6264600001631634'],
+ invalid: ['FO6264600001631639', 'FO626460000163163A', 'FO62646000016316349'],
+ },
+ {
+ locale: 'FI',
+ valid: ['FI2112345600000785'],
+ invalid: ['FI2112345600000789', 'FI211234560000078A', 'FI21123456000007859'],
+ },
+ {
+ locale: 'FR',
+ valid: ['FR1420041010050500013M02606'],
+ invalid: [
+ 'FR1420041010050500013M02609',
+ 'FR1420041010050500013M0260A',
+ 'FR1420041010050500013M026A6',
+ 'FR14A0041010050500013M02606',
+ 'FR1420041010050500013M026069',
+ ],
+ },
+ {
+ locale: 'GB',
+ valid: ['GB29NWBK60161331926819'],
+ invalid: [
+ 'GB29NWBK60161331926811',
+ 'GB29NWBK6016133192681A',
+ 'GB29N9BK60161331926819',
+ 'GB29NWBK601613319268199',
+ ],
+ },
+ {
+ locale: 'GE',
+ valid: ['GE29NB0000000101904917'],
+ invalid: [
+ 'GE29NB0000000101904919',
+ 'GE29NB000000010190491A',
+ 'GE29N90000000101904917',
+ 'GE29NB00000001019049179',
+ ],
+ },
+ {
+ locale: 'GI',
+ valid: ['GI75NWBK000000007099453'],
+ invalid: ['GI75NWBK000000007099459', 'GI75N9BK000000007099453', 'GI75NWBK0000000070994539'],
+ },
+ {
+ locale: 'GL',
+ valid: ['GL8964710001000206'],
+ invalid: ['GL8964710001000209', 'GL896471000100020A', 'GL89647100010002069'],
+ },
+ {
+ locale: 'GR',
+ valid: ['GR1601101250000000012300695'],
+ invalid: [
+ 'GR1601101250000000012300699',
+ 'GR16A1101250000000012300695',
+ 'GR16011012500000000123006959',
+ ],
+ },
+ {
+ locale: 'HU',
+ valid: ['HU42117730161111101800000000'],
+ invalid: [
+ 'HU42117730161111101800000009',
+ 'HU4211773016111110180000000A',
+ 'HU421177301611111018000000009',
+ ],
+ },
+ {
+ locale: 'HR',
+ valid: ['HR1210010051863000160'],
+ invalid: ['HR1210010051863000169', 'HR121001005186300016A', 'HR12100100518630001609'],
+ },
+ {
+ locale: 'IE',
+ valid: ['IE29AIBK93115212345678'],
+ invalid: [
+ 'IE29AIBK93115212345679',
+ 'IE29AEBK9311521234567A',
+ 'IE29A9BK93115212345678',
+ 'IE29AIBK931152123456789',
+ ],
+ },
+ {
+ locale: 'IS',
+ valid: ['IS140159260076545510730339'],
+ invalid: [
+ 'IS140159260076545510730331',
+ 'IS14015926007654551073033A',
+ 'IS1401592600765455107303399',
+ ],
+ },
+ {
+ locale: 'IT',
+ valid: ['IT60X0542811101000000123456'],
+ invalid: [
+ 'IT60X0542811101000000123459',
+ 'IT6090542811101000000123456',
+ 'IT60XA542811101000000123456',
+ 'IT60X05428111010000001234569',
+ ],
+ },
+ {
+ locale: 'JO',
+ valid: ['JO94CBJO0010000000000131000302'],
+ invalid: [
+ 'JO94CBJO0010000000000131000309',
+ 'JO94C9JO0010000000000131000302',
+ 'JO94CBJOA010000000000131000302',
+ 'JO94CBJO00100000000001310003029',
+ ],
+ },
+ {
+ locale: 'KW',
+ valid: ['KW81CBKU0000000000001234560101'],
+ invalid: [
+ 'KW81CBKU0000000000001234560109',
+ 'KW81CB9U0000000000001234560101',
+ 'KW81CBKU00000000000012345601019',
+ ],
+ },
+ {
+ locale: 'KZ',
+ valid: ['KZ86125KZT5004100100'],
+ invalid: ['KZ86125KZT5004100109', 'KZ86125K9T5004100100', 'KZ86125KZT50041001009'],
+ },
+ {
+ locale: 'LB',
+ valid: ['LB62099900000001001901229114'],
+ invalid: [
+ 'LB62099900000001001901229119',
+ 'LB6209A900000001001901229114',
+ 'LB620999000000010019012291149',
+ ],
+ },
+ {
+ locale: 'LI',
+ valid: ['LI21088100002324013AA'],
+ invalid: ['LI21088100002324013A9', 'LI21A88100002324013AA', 'LI21088100002324013AA9'],
+ },
+ {
+ locale: 'LT',
+ valid: ['LT121000011101001000'],
+ invalid: ['LT121000011101001009', 'LT12100001110100100A', 'LT1210000111010010009'],
+ },
+ {
+ locale: 'LV',
+ valid: ['LV80BANK0000435195001'],
+ invalid: ['LV80BANK0000435195009', 'LV80B9NK0000435195001', 'LV80BANK00004351950019'],
+ },
+ {
+ locale: 'MC',
+ valid: ['MC5811222000010123456789030'],
+ invalid: [
+ 'MC5811222000010123456789039',
+ 'MC581122200001012345678903A',
+ 'MC58A1222000010123456789030',
+ 'MC58112220000101234567890309',
+ ],
+ },
+ {
+ locale: 'MD',
+ valid: ['MD24AG000225100013104168'],
+ invalid: [
+ 'MD24AG000225100013104169',
+ 'MD24A9000225100013104168',
+ 'MD24AG0002251000131041689',
+ ],
+ },
+ {
+ locale: 'ME',
+ valid: ['ME25505000012345678951'],
+ invalid: ['ME25505000012345678959', 'ME2550500001234567895A', 'ME255050000123456789519'],
+ },
+ {
+ locale: 'MK',
+ valid: ['MK07250120000058984'],
+ invalid: ['MK07250120000058989', 'MK07A50120000058984', 'MK072501200000589849'],
+ },
+ {
+ locale: 'MT',
+ valid: ['MT84MALT011000012345MTLCAST001S'],
+ invalid: [
+ 'MT84MALT011000012345MTLCAST0019',
+ 'MT84M9LT011000012345MTLCAST001S',
+ 'MT84MALT0A1000012345MTLCAST001S',
+ 'MT84MALT011000012345MTLCAST001S9',
+ ],
+ },
+ {
+ locale: 'NL',
+ valid: ['NL91ABNA0417164300'],
+ invalid: [
+ 'NL91ABNA0417164309',
+ 'NL91AB9A0417164300',
+ 'NL91ABNA041716430A',
+ 'NL91ABNA04171643009',
+ ],
+ },
+ {
+ locale: 'NO',
+ valid: ['NO9386011117947'],
+ invalid: ['NO9386011117949', 'NO938601111794A', 'NO93860111179479'],
+ },
+ {
+ locale: 'PL',
+ valid: ['PL61109010140000071219812874'],
+ invalid: [
+ 'PL61109010140000071219812879',
+ 'PL6110901014000007121981287A',
+ 'PL611090101400000712198128749',
+ ],
+ },
+ {
+ locale: 'PS',
+ valid: ['PS92PALS000000000400123456702'],
+ invalid: [
+ 'PS92PALS000000000400123456709',
+ 'PS92P9LS000000000400123456702',
+ 'PS92PALS0000000004001234567029',
+ ],
+ },
+ {
+ locale: 'PT',
+ valid: ['PT50000201231234567890154'],
+ invalid: [
+ 'PT50000201231234567890159',
+ 'PT5000020123123456789015A',
+ 'PT500002012312345678901549',
+ ],
+ },
+ {
+ locale: 'QA',
+ valid: ['QA73BBME000000000004056677001'],
+ invalid: [
+ 'QA73BBME000000000004056677009',
+ 'QA73B9ME000000000004056677001',
+ 'QA73BBME0000000000040566770019',
+ ],
+ },
+ {
+ locale: 'RO',
+ valid: ['RO49AAAA1B31007593840000'],
+ invalid: [
+ 'RO49AAAA1B31007593840009',
+ 'RO49A9AA1B31007593840000',
+ 'RO49AAAA1B310075938400009',
+ ],
+ },
+ {
+ locale: 'SA',
+ valid: ['SA0380000000608010167519'],
+ invalid: [
+ 'SA0380000000608010167511',
+ 'SA03A0000000608010167519',
+ 'SA03800000006080101675199',
+ ],
+ },
+ {
+ locale: 'SE',
+ valid: ['SE4550000000058398257466'],
+ invalid: [
+ 'SE4550000000058398257469',
+ 'SE455000000005839825746A',
+ 'SE45500000000583982574669',
+ ],
+ },
+ {
+ locale: 'SI',
+ valid: ['SI56263300012039086'],
+ invalid: ['SI56263300012039089', 'SI5626330001203908A', 'SI562633000120390869'],
+ },
+ {
+ locale: 'SK',
+ valid: ['SK3112000000198742637541'],
+ invalid: [
+ 'SK3112000000198742637549',
+ 'SK311200000019874263754A',
+ 'SK31120000001987426375419',
+ ],
+ },
+ {
+ locale: 'SM',
+ valid: ['SM86U0322509800000000270100'],
+ invalid: [
+ 'SM86U0322509800000000270109',
+ 'SM8690322509800000000270100',
+ 'SM86UA322509800000000270100',
+ 'SM86U03225098000000002701009',
+ ],
+ },
+ {
+ locale: 'RS',
+ valid: ['RS35260005601001611379'],
+ invalid: ['RS35260005601001611371', 'RS3526000560100161137A', 'RS352600056010016113799'],
+ },
+ {
+ locale: 'TN',
+ valid: ['TN5910006035183598478831'],
+ invalid: [
+ 'TN5910006035183598478839',
+ 'TN591000603518359847883A',
+ 'TN59100060351835984788319',
+ ],
+ },
+ {
+ locale: 'TR',
+ valid: ['TR330006100519786457841326'],
+ invalid: [
+ 'TR330006100519786457841329',
+ 'TR33A006100519786457841326',
+ 'TR3300061005197864578413269',
+ ],
+ },
+ {
+ locale: 'UA',
+ valid: ['UA213996220000026007233566001'],
+ invalid: [
+ 'UA213996220000026007233566009',
+ 'UA21A996220000026007233566001',
+ 'UA2139962200000260072335660019',
+ ],
+ },
+ {
+ locale: 'XK',
+ valid: ['XK051212012345678906'],
+ invalid: ['XK051212012345678909', 'XK05121201234567890A', 'XK0512120123456789069'],
+ },
+ ];
+
+ let allValid = [];
+
+ fixtures.forEach((fixture) => {
+ // to be used later on for validating 'any' locale
+ if (fixture.valid) allValid = allValid.concat(fixture.valid);
+
+ test({
+ validator: 'isIBAN',
+ valid: fixture.valid,
+ invalid: fixture.invalid,
+ args: [fixture.locale],
+ });
+ });
+
+ test({
+ validator: 'isIBAN',
+ valid: allValid,
+ invalid: [
+ '',
+ 'asdf',
+ '1',
+ 'ASDFGJKLmZXJtZtesting123',
+ 'Vml2YW11cyBmZXJtZtesting123',
+ ],
+ args: ['any'],
+ });
+
+ // falsey locale defaults to 'any'
+ test({
+ validator: 'isIBAN',
+ valid: allValid,
+ invalid: [
+ '',
+ 'asdf',
+ '1',
+ 'ASDFGJKLmZXJtZtesting123',
+ 'Vml2YW11cyBmZXJtZtesting123',
+ ],
+ args: [],
+ });
+ });
+
+ it('should error on invalid locale isIBAN', () => {
+ test({
+ validator: 'isIBAN',
+ args: ['is-NOT'],
+ error: [
+ '',
+ 'asdf',
+ '1',
+ 'ASDFGJKLmZXJtZtesting123',
+ 'Vml2YW11cyBmZXJtZtesting123',
+ ],
+ });
+ });
+
it('should validate currency', () => {
// -$##,###.## (en-US, en-CA, en-AU, en-NZ, en-HK)
test({
diff --git a/validator.js b/validator.js
index f9fe7b4da..f821e3f38 100644
--- a/validator.js
+++ b/validator.js
@@ -1077,6 +1077,122 @@ function isIn(str, options) {
/* eslint-disable max-len */
+var iban = {
+ AD: /^(AD[0-9]{2})\d{8}[0-9A-Z]{12}$/,
+ AL: /^(AL[0-9]{2})\d{8}[A-Z0-9]{16}$/,
+ AT: /^(AT[0-9]{2})\d{16}$/,
+ BA: /^(BA[0-9]{2})\d{16}$/,
+ BE: /^(BE[0-9]{2})\d{12}$/,
+ BG: /^(BG[0-9]{2})[A-Z]{4}\d{4}[A-Z0-9]{10}$/,
+ BH: /^(BH[0-9]{2})[A-Z]{4}[A-Z0-9]{14}$/,
+ BR: /^(BR[0-9]{2})\d{23}[A-Z][A-Z0-9]$/,
+ CH: /^(CH[0-9]{2})\d{17}$/,
+ CY: /^(CY[0-9]{2})\d{8}[A-Z0-9]{16}$/,
+ CZ: /^(CZ[0-9]{2})\d{20}$/,
+ DE: /^(DE[0-9]{2})\d{18}$/,
+ DK: /^(DK[0-9]{2})\d{14}$/,
+ EE: /^(EE[0-9]{2})\d{16}$/,
+ ES: /^(ES[0-9]{2})\d{20}$/,
+ FO: /^(FO[0-9]{2})\d{14}$/,
+ FI: /^(FI[0-9]{2})\d{14}$/,
+ FR: /^(FR[0-9]{2})\d{10}[A-Z0-9]{11}\d{2}$/,
+ GB: /^(GB[0-9]{2})[A-Z]{4}\d{14}$/,
+ GE: /^(GE[0-9]{2})[A-Z]{2}\d{16}$/,
+ GI: /^(GI[0-9]{2})[A-Z]{4}[A-Z0-9]{15}$/,
+ GL: /^(GL[0-9]{2})\d{14}$/,
+ GR: /^(GR[0-9]{2})\d{7}[A-Z0-9]{16}$/,
+ HR: /^(HR[0-9]{2})\d{17}$/,
+ HU: /^(HU[0-9]{2})\d{24}$/,
+ IE: /^(IE[0-9]{2})[A-Z]{4}\d{14}$/,
+ IS: /^(IS[0-9]{2})\d{22}$/,
+ IT: /^(IT[0-9]{2})[A-Z]\d{10}[A-Z0-9]{12}$/,
+ JO: /^(JO[0-9]{2})[A-Z]{4}\d{4}[A-Z0-9]{18}$/,
+ KW: /^(KW[0-9]{2})[A-Z]{4}[A-Z0-9]{22}$/,
+ KZ: /^(KZ[0-9]{2})\d{3}[A-Z0-9]{13}$/,
+ LB: /^(LB[0-9]{2})\d{4}[A-Z0-9]{20}$/,
+ LI: /^(LI[0-9]{2})\d{5}[A-Z0-9]{12}$/,
+ LT: /^(LT[0-9]{2})\d{16}$/,
+ LU: /^(LU[0-9]{2})\d{3}[A-Z0-9]{13}$/,
+ LV: /^(LV[0-9]{2})[A-Z]{4}[A-Z0-9]{13}$/,
+ MC: /^(MC[0-9]{2})\d{10}[A-Z0-9]{11}\d{2}$/,
+ MD: /^(MD[0-9]{2})[A-Z]{2}[A-Z0-9]{18}$/,
+ ME: /^(ME[0-9]{2})\d{18}$/,
+ MK: /^(MK[0-9]{2})\d{3}[A-Z0-9]{12}$/,
+ MT: /^(MT[0-9]{2})[A-Z]{4}\d{5}[A-Z0-9]{18}$/,
+ NL: /^(NL[0-9]{2})[A-Z]{4}\d{10}$/,
+ NO: /^(NO[0-9]{2})\d{11}$/,
+ PL: /^(PL[0-9]{2})\d{24}$/,
+ PS: /^(PS[0-9]{2})[A-Z]{4}[A-Z0-9]{21}$/,
+ PT: /^(PT[0-9]{2})\d{21}$/,
+ QA: /^(QA[0-9]{2})[A-Z]{4}[A-Z0-9]{21}$/,
+ RO: /^(RO[0-9]{2})[A-Z]{4}[A-Z0-9]{16}$/,
+ SA: /^(SA[0-9]{2})\d{2}[A-Z0-9]{18}$/,
+ SE: /^(SE[0-9]{2})\d{20}$/,
+ SI: /^(SI[0-9]{2})\d{15}$/,
+ SK: /^(SK[0-9]{2})\d{20}$/,
+ SM: /^(SM[0-9]{2})[A-Z]{1}\d{10}[A-Z0-9]{12}$/,
+ RS: /^(RS[0-9]{2})\d{18}$/,
+ TN: /^(TN[0-9]{2})\d{20}$/,
+ TR: /^(TR[0-9]{2})\d{5}[A-Z0-9]{17}$/,
+ UA: /^(UA[0-9]{2})\d{6}[A-Z0-9]{19}$/,
+ XK: /^(XK[0-9]{2})\d{16}$/
+};
+/* eslint-enable max-len */
+
+/**
+ * @function IbanCalcul - calculate if the IBAN corresponds to the reglementation: converting
+ * it into an integer and performing a basic mod-97 operation. If the IBAN is valid, the remainder
+ * equals 1.
+ * 1- Check that the total IBAN length is correct as per the country. If not, the IBAN is invalid
+ * 2- Move the four initial characters to the end of the string
+ * 3- Replace each letter in the string with two digits, thereby expanding the string,
+ * where A = 10..., Z = 35
+ * 4- Interpret the string as a decimal integer and compute the remainder of that number on
+ * division by 97
+ * @param {e} - recieves the IBAN tested
+ * @warns IBAN's length differs from country to another, the maximum length is 34 characters so
+ * calculating its modulus 97 is not possible for all machines.To solve this, the function calculate
+ * the modulus of the first 9 digit by 97 and add the result to the beginning of the remain IBAN
+ * number. The process is repeated untill the result's length is less than 10
+ */
+
+var IbanCalcul = function IbanCalcul(e) {
+ var countryCode = e.slice(0, 4);
+ var result = e.slice(4, e.length) + countryCode;
+
+ for (var counter = 1; counter <= Math.ceil(e.length / 10) + 1; counter++) {
+ var remainder = result.slice(0, 10).replace(/[A-Z]/g, function (element) {
+ return element.charCodeAt() - 55;
+ }) % 97;
+ result = remainder + result.slice(10);
+ }
+
+ if (result === '1') return true;
+ return false;
+};
+
+function isIBAN(str, locale) {
+ assertString(str);
+ str = str.toUpperCase();
+
+ if (locale in iban) {
+ return iban[locale].test(str) && IbanCalcul(str);
+ } else if (!locale || locale === 'any') {
+ locale = str.slice(0, 2);
+
+ if (locale in iban) {
+ return iban[locale].test(str) && IbanCalcul(str);
+ }
+
+ return false;
+ }
+
+ throw new Error("Invalid locale '".concat(locale, "'"));
+}
+var locales$3 = Object.keys(iban);
+
+/* eslint-disable max-len */
+
var creditCard = /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11}|6[27][0-9]{14})$/;
/* eslint-enable max-len */
@@ -1471,7 +1587,7 @@ function isMobilePhone(str, locale, options) {
throw new Error("Invalid locale '".concat(locale, "'"));
}
-var locales$3 = Object.keys(phones);
+var locales$4 = Object.keys(phones);
function currencyRegex(options) {
var decimal_digits = "\\d{".concat(options.digits_after_decimal[0], "}");
@@ -1800,7 +1916,7 @@ var patterns = {
ZA: fourDigit,
ZM: fiveDigit
};
-var locales$4 = Object.keys(patterns);
+var locales$5 = Object.keys(patterns);
var isPostalCode = function (str, locale) {
assertString(str);
@@ -2070,15 +2186,17 @@ var validator = {
isAfter: isAfter,
isBefore: isBefore,
isIn: isIn,
+ isIBAN: isIBAN,
+ isIBANLocales: locales$3,
isCreditCard: isCreditCard,
isIdentityCard: isIdentityCard,
isISIN: isISIN,
isISBN: isISBN,
isISSN: isISSN,
isMobilePhone: isMobilePhone,
- isMobilePhoneLocales: locales$3,
+ isMobilePhoneLocales: locales$4,
isPostalCode: isPostalCode,
- isPostalCodeLocales: locales$4,
+ isPostalCodeLocales: locales$5,
isCurrency: isCurrency,
isISO8601: isISO8601,
isRFC3339: isRFC3339,
diff --git a/validator.min.js b/validator.min.js
index 46acfae86..12d36649b 100644
--- a/validator.min.js
+++ b/validator.min.js
@@ -20,4 +20,4 @@
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.validator=e()}(this,function(){"use strict";function a(t){return(a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function g(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){var r=[],n=!0,o=!1,i=void 0;try{for(var a,l=t[Symbol.iterator]();!(n=(a=l.next()).done)&&(r.push(a.value),!e||r.length!==e);n=!0);}catch(t){o=!0,i=t}finally{try{n||null==l.return||l.return()}finally{if(o)throw i}}return r}(t,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}function $(t){var e;if(!("string"==typeof t||t instanceof String))throw e=null===t?"null":"object"===(e=a(t))&&t.constructor&&t.constructor.hasOwnProperty("name")?t.constructor.name:"a ".concat(e),new TypeError("Expected string but received ".concat(e,"."))}function o(t){return $(t),t=Date.parse(t),isNaN(t)?null:new Date(t)}function r(t){return $(t),parseFloat(t)}function i(t){return"object"===a(t)&&null!==t?t="function"==typeof t.toString?t.toString():"[object Object]":(null==t||isNaN(t)&&!t.length)&&(t=""),String(t)}function m(t,e){var r=0i)return!1;if("::"===t)return!0;"::"===t.substr(0,2)?(r.shift(),r.shift(),n=!0):"::"===t.substr(t.length-2)&&(r.pop(),r.pop(),n=!0);for(var a=0;a$/i,E=/^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~]+$/i,x=/^[a-z\d]+$/,M=/^([\s\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e]|(\\[\x01-\x09\x0b\x0c\x0d-\x7f]))*$/i,N=/^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+$/i,C=/^([\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;var d={protocols:["http","https","ftp"],require_tld:!0,require_protocol:!1,require_host:!0,require_valid_protocol:!0,allow_underscores:!1,allow_trailing_dot:!1,allow_protocol_relative_urls:!1},f=/^\[([^\]]+)\](?::([0-9]+))?$/;function p(t,e){for(var r=0;r=e.min,o=!e.hasOwnProperty("max")||t<=e.max,i=!e.hasOwnProperty("lt")||te.gt;return r.test(t)&&n&&o&&i&&a}var V=/^[\x00-\x7F]+$/;var j=/[^\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]/;var J=/[\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]/;var q=/[^\x00-\x7F]/;var Q=/[\uD800-\uDBFF][\uDC00-\uDFFF]/;function X(t,e){return t.some(function(t){return e===t})}var tt=Object.keys(T);var et={force_decimal:!1,decimal_digits:"1,",locale:"en-US"},rt=["","-","+"];var nt=/^[0-9A-F]+$/i;function ot(t){return $(t),nt.test(t)}var it=/^#?([0-9A-F]{3}|[0-9A-F]{6})$/i;var at=/^[A-Z]{2}[0-9A-Z]{3}\d{2}\d{5}$/;var lt=/^[a-f0-9]{32}$/;var st={md5:32,md4:32,sha1:40,sha256:64,sha384:96,sha512:128,ripemd128:32,ripemd160:40,tiger128:32,tiger160:40,tiger192:48,crc32:8,crc32b:8};var ut=/^([A-Za-z0-9\-_~+\/]+[=]{0,2})\.([A-Za-z0-9\-_~+\/]+[=]{0,2})(?:\.([A-Za-z0-9\-_~+\/]+[=]{0,2}))?$/;var ct={ignore_whitespace:!1};var dt={3:/^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,4:/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,5:/^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,all:/^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i};var ft=/^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11}|6[27][0-9]{14})$/;var pt={ES:function(t){$(t);var e={X:0,Y:1,Z:2},r=t.trim().toUpperCase();if(!/^[0-9X-Z][0-9]{7}[TRWAGMYFPDXBNJZSQVHLCKE]$/.test(r))return!1;var n=r.slice(0,-1).replace(/[X,Y,Z]/g,function(t){return e[t]});return r.endsWith(["T","R","W","A","G","M","Y","F","P","D","X","B","N","J","Z","S","Q","V","H","L","C","K","E"][n%23])},"he-IL":function(t){var e=t.trim();if(!/^\d{9}$/.test(e))return!1;for(var r,n=e,o=0,i=0;i]/.test(r)){if(!e)return!1;if(!(r.split('"').length===r.split('\\"').length))return!1}return!0}(n))return!1}else if(e.require_display_name)return!1}if(!e.ignore_max_length&&254]/.test(t))return!1;if(0===t.indexOf("mailto:"))return!1;var r,n,o,i,a,l,s,u;if(e=m(e,d),1<(s=(t=(s=(t=(s=t.split("#")).shift()).split("?")).shift()).split("://")).length){if(r=s.shift().toLowerCase(),e.require_valid_protocol&&-1===e.protocols.indexOf(r))return!1}else{if(e.require_protocol)return!1;if("//"===t.substr(0,2)){if(!e.allow_protocol_relative_urls)return!1;s[0]=t.substr(2)}}if(""===(t=s.join("://")))return!1;if(""===(t=(s=t.split("/")).shift())&&!e.require_host)return!0;if(1<(s=t.split("@")).length){if(e.disallow_auth)return!1;if(0<=(n=s.shift()).indexOf(":")&&2=e.min)&&(!e.hasOwnProperty("max")||n<=e.max)&&(!e.hasOwnProperty("lt")||ne.gt)},isFloatLocales:tt,isDecimal:function(t,e){if($(t),(e=m(e,et)).locale in T)return!X(rt,t.replace(/ /g,""))&&function(t){return new RegExp("^[-+]?([0-9]+)?(\\".concat(T[t.locale],"[0-9]{").concat(t.decimal_digits,"})").concat(t.force_decimal?"":"?","$"))}(e).test(t);throw new Error("Invalid locale '".concat(e.locale,"'"))},isHexadecimal:ot,isDivisibleBy:function(t,e){return $(t),r(t)%parseInt(e,10)==0},isHexColor:function(t){return $(t),it.test(t)},isISRC:function(t){return $(t),at.test(t)},isMD5:function(t){return $(t),lt.test(t)},isHash:function(t,e){return $(t),new RegExp("^[a-fA-F0-9]{".concat(st[e],"}$")).test(t)},isJWT:function(t){return $(t),ut.test(t)},isJSON:function(t){$(t);try{var e=JSON.parse(t);return!!e&&"object"===a(e)}catch(t){}return!1},isEmpty:function(t,e){return $(t),0===((e=m(e,ct)).ignore_whitespace?t.trim().length:t.length)},isLength:function(t,e){var r,n;$(t),n="object"===a(e)?(r=e.min||0,e.max):(r=e||0,arguments[2]);var o=t.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g)||[],i=t.length-o.length;return r<=i&&(void 0===n||i<=n)},isByteLength:v,isUUID:function(t){var e=1/g,">").replace(/\//g,"/").replace(/\\/g,"\").replace(/`/g,"`")},unescape:function(t){return $(t),t.replace(/&/g,"&").replace(/"/g,'"').replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(///g,"/").replace(/\/g,"\\").replace(/`/g,"`")},stripLow:function(t,e){return $(t),Jt(t,e?"\\x00-\\x09\\x0B\\x0C\\x0E-\\x1F\\x7F":"\\x00-\\x1F\\x7F")},whitelist:function(t,e){return $(t),t.replace(new RegExp("[^".concat(e,"]+"),"g"),"")},blacklist:Jt,isWhitelisted:function(t,e){$(t);for(var r=t.length-1;0<=r;r--)if(-1===e.indexOf(t[r]))return!1;return!0},normalizeEmail:function(t,e){e=m(e,qt);var r=t.split("@"),n=r.pop(),o=[r.join("@"),n];if(o[1]=o[1].toLowerCase(),"gmail.com"===o[1]||"googlemail.com"===o[1]){if(e.gmail_remove_subaddress&&(o[0]=o[0].split("+")[0]),e.gmail_remove_dots&&(o[0]=o[0].replace(/\.+/g,re)),!o[0].length)return!1;(e.all_lowercase||e.gmail_lowercase)&&(o[0]=o[0].toLowerCase()),o[1]=e.gmail_convert_googlemaildotcom?"gmail.com":o[1]}else if(0<=Qt.indexOf(o[1])){if(e.icloud_remove_subaddress&&(o[0]=o[0].split("+")[0]),!o[0].length)return!1;(e.all_lowercase||e.icloud_lowercase)&&(o[0]=o[0].toLowerCase())}else if(0<=Xt.indexOf(o[1])){if(e.outlookdotcom_remove_subaddress&&(o[0]=o[0].split("+")[0]),!o[0].length)return!1;(e.all_lowercase||e.outlookdotcom_lowercase)&&(o[0]=o[0].toLowerCase())}else if(0<=te.indexOf(o[1])){if(e.yahoo_remove_subaddress){var i=o[0].split("-");o[0]=1i)return!1;if("::"===t)return!0;"::"===t.substr(0,2)?(r.shift(),r.shift(),n=!0):"::"===t.substr(t.length-2)&&(r.pop(),r.pop(),n=!0);for(var a=0;a$/i,E=/^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~]+$/i,R=/^[a-z\d]+$/,L=/^([\s\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e]|(\\[\x01-\x09\x0b\x0c\x0d-\x7f]))*$/i,M=/^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+$/i,I=/^([\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;var d={protocols:["http","https","ftp"],require_tld:!0,require_protocol:!1,require_host:!0,require_valid_protocol:!0,allow_underscores:!1,allow_trailing_dot:!1,allow_protocol_relative_urls:!1},f=/^\[([^\]]+)\](?::([0-9]+))?$/;function A(t,e){for(var r=0;r=e.min,o=!e.hasOwnProperty("max")||t<=e.max,i=!e.hasOwnProperty("lt")||te.gt;return r.test(t)&&n&&o&&i&&a}var V=/^[\x00-\x7F]+$/;var j=/[^\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]/;var J=/[\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]/;var q=/[^\x00-\x7F]/;var Q=/[\uD800-\uDBFF][\uDC00-\uDFFF]/;function X(t,e){return t.some(function(t){return e===t})}var tt=Object.keys(x);var et={force_decimal:!1,decimal_digits:"1,",locale:"en-US"},rt=["","-","+"];var nt=/^[0-9A-F]+$/i;function ot(t){return g(t),nt.test(t)}var it=/^#?([0-9A-F]{3}|[0-9A-F]{6})$/i;var at=/^[A-Z]{2}[0-9A-Z]{3}\d{2}\d{5}$/;var lt=/^[a-f0-9]{32}$/;var st={md5:32,md4:32,sha1:40,sha256:64,sha384:96,sha512:128,ripemd128:32,ripemd160:40,tiger128:32,tiger160:40,tiger192:48,crc32:8,crc32b:8};var ut=/^([A-Za-z0-9\-_~+\/]+[=]{0,2})\.([A-Za-z0-9\-_~+\/]+[=]{0,2})(?:\.([A-Za-z0-9\-_~+\/]+[=]{0,2}))?$/;var ct={ignore_whitespace:!1};var dt={3:/^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,4:/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,5:/^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,all:/^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i};function ft(t){for(var e=t.slice(0,4),r=t.slice(4,t.length)+e,n=1;n<=Math.ceil(t.length/10)+1;n++){r=r.slice(0,10).replace(/[A-Z]/g,function(t){return t.charCodeAt()-55})%97+r.slice(10)}return"1"===r}var At={AD:/^(AD[0-9]{2})\d{8}[0-9A-Z]{12}$/,AL:/^(AL[0-9]{2})\d{8}[A-Z0-9]{16}$/,AT:/^(AT[0-9]{2})\d{16}$/,BA:/^(BA[0-9]{2})\d{16}$/,BE:/^(BE[0-9]{2})\d{12}$/,BG:/^(BG[0-9]{2})[A-Z]{4}\d{4}[A-Z0-9]{10}$/,BH:/^(BH[0-9]{2})[A-Z]{4}[A-Z0-9]{14}$/,BR:/^(BR[0-9]{2})\d{23}[A-Z][A-Z0-9]$/,CH:/^(CH[0-9]{2})\d{17}$/,CY:/^(CY[0-9]{2})\d{8}[A-Z0-9]{16}$/,CZ:/^(CZ[0-9]{2})\d{20}$/,DE:/^(DE[0-9]{2})\d{18}$/,DK:/^(DK[0-9]{2})\d{14}$/,EE:/^(EE[0-9]{2})\d{16}$/,ES:/^(ES[0-9]{2})\d{20}$/,FO:/^(FO[0-9]{2})\d{14}$/,FI:/^(FI[0-9]{2})\d{14}$/,FR:/^(FR[0-9]{2})\d{10}[A-Z0-9]{11}\d{2}$/,GB:/^(GB[0-9]{2})[A-Z]{4}\d{14}$/,GE:/^(GE[0-9]{2})[A-Z]{2}\d{16}$/,GI:/^(GI[0-9]{2})[A-Z]{4}[A-Z0-9]{15}$/,GL:/^(GL[0-9]{2})\d{14}$/,GR:/^(GR[0-9]{2})\d{7}[A-Z0-9]{16}$/,HR:/^(HR[0-9]{2})\d{17}$/,HU:/^(HU[0-9]{2})\d{24}$/,IE:/^(IE[0-9]{2})[A-Z]{4}\d{14}$/,IS:/^(IS[0-9]{2})\d{22}$/,IT:/^(IT[0-9]{2})[A-Z]\d{10}[A-Z0-9]{12}$/,JO:/^(JO[0-9]{2})[A-Z]{4}\d{4}[A-Z0-9]{18}$/,KW:/^(KW[0-9]{2})[A-Z]{4}[A-Z0-9]{22}$/,KZ:/^(KZ[0-9]{2})\d{3}[A-Z0-9]{13}$/,LB:/^(LB[0-9]{2})\d{4}[A-Z0-9]{20}$/,LI:/^(LI[0-9]{2})\d{5}[A-Z0-9]{12}$/,LT:/^(LT[0-9]{2})\d{16}$/,LU:/^(LU[0-9]{2})\d{3}[A-Z0-9]{13}$/,LV:/^(LV[0-9]{2})[A-Z]{4}[A-Z0-9]{13}$/,MC:/^(MC[0-9]{2})\d{10}[A-Z0-9]{11}\d{2}$/,MD:/^(MD[0-9]{2})[A-Z]{2}[A-Z0-9]{18}$/,ME:/^(ME[0-9]{2})\d{18}$/,MK:/^(MK[0-9]{2})\d{3}[A-Z0-9]{12}$/,MT:/^(MT[0-9]{2})[A-Z]{4}\d{5}[A-Z0-9]{18}$/,NL:/^(NL[0-9]{2})[A-Z]{4}\d{10}$/,NO:/^(NO[0-9]{2})\d{11}$/,PL:/^(PL[0-9]{2})\d{24}$/,PS:/^(PS[0-9]{2})[A-Z]{4}[A-Z0-9]{21}$/,PT:/^(PT[0-9]{2})\d{21}$/,QA:/^(QA[0-9]{2})[A-Z]{4}[A-Z0-9]{21}$/,RO:/^(RO[0-9]{2})[A-Z]{4}[A-Z0-9]{16}$/,SA:/^(SA[0-9]{2})\d{2}[A-Z0-9]{18}$/,SE:/^(SE[0-9]{2})\d{20}$/,SI:/^(SI[0-9]{2})\d{15}$/,SK:/^(SK[0-9]{2})\d{20}$/,SM:/^(SM[0-9]{2})[A-Z]{1}\d{10}[A-Z0-9]{12}$/,RS:/^(RS[0-9]{2})\d{18}$/,TN:/^(TN[0-9]{2})\d{20}$/,TR:/^(TR[0-9]{2})\d{5}[A-Z0-9]{17}$/,UA:/^(UA[0-9]{2})\d{6}[A-Z0-9]{19}$/,XK:/^(XK[0-9]{2})\d{16}$/};var $t=Object.keys(At),ht=/^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11}|6[27][0-9]{14})$/;var pt={ES:function(t){g(t);var e={X:0,Y:1,Z:2},r=t.trim().toUpperCase();if(!/^[0-9X-Z][0-9]{7}[TRWAGMYFPDXBNJZSQVHLCKE]$/.test(r))return!1;var n=r.slice(0,-1).replace(/[X,Y,Z]/g,function(t){return e[t]});return r.endsWith(["T","R","W","A","G","M","Y","F","P","D","X","B","N","J","Z","S","Q","V","H","L","C","K","E"][n%23])},"he-IL":function(t){var e=t.trim();if(!/^\d{9}$/.test(e))return!1;for(var r,n=e,o=0,i=0;i]/.test(r)){if(!e)return!1;if(!(r.split('"').length===r.split('\\"').length))return!1}return!0}(n))return!1}else if(e.require_display_name)return!1}if(!e.ignore_max_length&&254]/.test(t))return!1;if(0===t.indexOf("mailto:"))return!1;var r,n,o,i,a,l,s,u;if(e=m(e,d),1<(s=(t=(s=(t=(s=t.split("#")).shift()).split("?")).shift()).split("://")).length){if(r=s.shift().toLowerCase(),e.require_valid_protocol&&-1===e.protocols.indexOf(r))return!1}else{if(e.require_protocol)return!1;if("//"===t.substr(0,2)){if(!e.allow_protocol_relative_urls)return!1;s[0]=t.substr(2)}}if(""===(t=s.join("://")))return!1;if(""===(t=(s=t.split("/")).shift())&&!e.require_host)return!0;if(1<(s=t.split("@")).length){if(e.disallow_auth)return!1;if(0<=(n=s.shift()).indexOf(":")&&2=e.min)&&(!e.hasOwnProperty("max")||n<=e.max)&&(!e.hasOwnProperty("lt")||ne.gt)},isFloatLocales:tt,isDecimal:function(t,e){if(g(t),(e=m(e,et)).locale in x)return!X(rt,t.replace(/ /g,""))&&function(t){return new RegExp("^[-+]?([0-9]+)?(\\".concat(x[t.locale],"[0-9]{").concat(t.decimal_digits,"})").concat(t.force_decimal?"":"?","$"))}(e).test(t);throw new Error("Invalid locale '".concat(e.locale,"'"))},isHexadecimal:ot,isDivisibleBy:function(t,e){return g(t),r(t)%parseInt(e,10)==0},isHexColor:function(t){return g(t),it.test(t)},isISRC:function(t){return g(t),at.test(t)},isMD5:function(t){return g(t),lt.test(t)},isHash:function(t,e){return g(t),new RegExp("^[a-fA-F0-9]{".concat(st[e],"}$")).test(t)},isJWT:function(t){return g(t),ut.test(t)},isJSON:function(t){g(t);try{var e=JSON.parse(t);return!!e&&"object"===a(e)}catch(t){}return!1},isEmpty:function(t,e){return g(t),0===((e=m(e,ct)).ignore_whitespace?t.trim().length:t.length)},isLength:function(t,e){var r,n;g(t),n="object"===a(e)?(r=e.min||0,e.max):(r=e||0,arguments[2]);var o=t.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g)||[],i=t.length-o.length;return r<=i&&(void 0===n||i<=n)},isByteLength:v,isUUID:function(t){var e=1/g,">").replace(/\//g,"/").replace(/\\/g,"\").replace(/`/g,"`")},unescape:function(t){return g(t),t.replace(/&/g,"&").replace(/"/g,'"').replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(///g,"/").replace(/\/g,"\\").replace(/`/g,"`")},stripLow:function(t,e){return g(t),Xt(t,e?"\\x00-\\x09\\x0B\\x0C\\x0E-\\x1F\\x7F":"\\x00-\\x1F\\x7F")},whitelist:function(t,e){return g(t),t.replace(new RegExp("[^".concat(e,"]+"),"g"),"")},blacklist:Xt,isWhitelisted:function(t,e){g(t);for(var r=t.length-1;0<=r;r--)if(-1===e.indexOf(t[r]))return!1;return!0},normalizeEmail:function(t,e){e=m(e,te);var r=t.split("@"),n=r.pop(),o=[r.join("@"),n];if(o[1]=o[1].toLowerCase(),"gmail.com"===o[1]||"googlemail.com"===o[1]){if(e.gmail_remove_subaddress&&(o[0]=o[0].split("+")[0]),e.gmail_remove_dots&&(o[0]=o[0].replace(/\.+/g,ie)),!o[0].length)return!1;(e.all_lowercase||e.gmail_lowercase)&&(o[0]=o[0].toLowerCase()),o[1]=e.gmail_convert_googlemaildotcom?"gmail.com":o[1]}else if(0<=ee.indexOf(o[1])){if(e.icloud_remove_subaddress&&(o[0]=o[0].split("+")[0]),!o[0].length)return!1;(e.all_lowercase||e.icloud_lowercase)&&(o[0]=o[0].toLowerCase())}else if(0<=re.indexOf(o[1])){if(e.outlookdotcom_remove_subaddress&&(o[0]=o[0].split("+")[0]),!o[0].length)return!1;(e.all_lowercase||e.outlookdotcom_lowercase)&&(o[0]=o[0].toLowerCase())}else if(0<=ne.indexOf(o[1])){if(e.yahoo_remove_subaddress){var i=o[0].split("-");o[0]=1