UNPKG

65.2 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 _typeof(obj) {
30 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
31 _typeof = function (obj) {
32 return typeof obj;
33 };
34 } else {
35 _typeof = function (obj) {
36 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
37 };
38 }
39
40 return _typeof(obj);
41}
42
43function _toArray(arr) {
44 return _arrayWithHoles(arr) || _iterableToArray(arr) || _nonIterableRest();
45}
46
47function _arrayWithHoles(arr) {
48 if (Array.isArray(arr)) return arr;
49}
50
51function _iterableToArray(iter) {
52 if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
53}
54
55function _nonIterableRest() {
56 throw new TypeError("Invalid attempt to destructure non-iterable instance");
57}
58
59function _toPrimitive(input, hint) {
60 if (typeof input !== "object" || input === null) return input;
61 var prim = input[Symbol.toPrimitive];
62
63 if (prim !== undefined) {
64 var res = prim.call(input, hint || "default");
65 if (typeof res !== "object") return res;
66 throw new TypeError("@@toPrimitive must return a primitive value.");
67 }
68
69 return (hint === "string" ? String : Number)(input);
70}
71
72function _toPropertyKey(arg) {
73 var key = _toPrimitive(arg, "string");
74
75 return typeof key === "symbol" ? key : String(key);
76}
77
78function _addElementPlacement(element, placements, silent) {
79 var keys = placements[element.placement];
80
81 if (!silent && keys.indexOf(element.key) !== -1) {
82 throw new TypeError("Duplicated element (" + element.key + ")");
83 }
84
85 keys.push(element.key);
86}
87
88function _fromElementDescriptor(element) {
89 var obj = {
90 kind: element.kind,
91 key: element.key,
92 placement: element.placement,
93 descriptor: element.descriptor
94 };
95 var desc = {
96 value: "Descriptor",
97 configurable: true
98 };
99 Object.defineProperty(obj, Symbol.toStringTag, desc);
100 if (element.kind === "field") obj.initializer = element.initializer;
101 return obj;
102}
103
104function _toElementDescriptors(elementObjects) {
105 if (elementObjects === undefined) return;
106 return _toArray(elementObjects).map(function (elementObject) {
107 var element = _toElementDescriptor(elementObject);
108
109 _disallowProperty(elementObject, "finisher", "An element descriptor");
110
111 _disallowProperty(elementObject, "extras", "An element descriptor");
112
113 return element;
114 });
115}
116
117function _toElementDescriptor(elementObject) {
118 var kind = String(elementObject.kind);
119
120 if (kind !== "method" && kind !== "field") {
121 throw new TypeError('An element descriptor\'s .kind property must be either "method" or' + ' "field", but a decorator created an element descriptor with' + ' .kind "' + kind + '"');
122 }
123
124 var key = _toPropertyKey(elementObject.key);
125
126 var placement = String(elementObject.placement);
127
128 if (placement !== "static" && placement !== "prototype" && placement !== "own") {
129 throw new TypeError('An element descriptor\'s .placement property must be one of "static",' + ' "prototype" or "own", but a decorator created an element descriptor' + ' with .placement "' + placement + '"');
130 }
131
132 var descriptor = elementObject.descriptor;
133
134 _disallowProperty(elementObject, "elements", "An element descriptor");
135
136 var element = {
137 kind: kind,
138 key: key,
139 placement: placement,
140 descriptor: Object.assign({}, descriptor)
141 };
142
143 if (kind !== "field") {
144 _disallowProperty(elementObject, "initializer", "A method descriptor");
145 } else {
146 _disallowProperty(descriptor, "get", "The property descriptor of a field descriptor");
147
148 _disallowProperty(descriptor, "set", "The property descriptor of a field descriptor");
149
150 _disallowProperty(descriptor, "value", "The property descriptor of a field descriptor");
151
152 element.initializer = elementObject.initializer;
153 }
154
155 return element;
156}
157
158function _toElementFinisherExtras(elementObject) {
159 var element = _toElementDescriptor(elementObject);
160
161 var finisher = _optionalCallableProperty(elementObject, "finisher");
162
163 var extras = _toElementDescriptors(elementObject.extras);
164
165 return {
166 element: element,
167 finisher: finisher,
168 extras: extras
169 };
170}
171
172function _fromClassDescriptor(elements) {
173 var obj = {
174 kind: "class",
175 elements: elements.map(_fromElementDescriptor)
176 };
177 var desc = {
178 value: "Descriptor",
179 configurable: true
180 };
181 Object.defineProperty(obj, Symbol.toStringTag, desc);
182 return obj;
183}
184
185function _toClassDescriptor(obj) {
186 var kind = String(obj.kind);
187
188 if (kind !== "class") {
189 throw new TypeError('A class descriptor\'s .kind property must be "class", but a decorator' + ' created a class descriptor with .kind "' + kind + '"');
190 }
191
192 _disallowProperty(obj, "key", "A class descriptor");
193
194 _disallowProperty(obj, "placement", "A class descriptor");
195
196 _disallowProperty(obj, "descriptor", "A class descriptor");
197
198 _disallowProperty(obj, "initializer", "A class descriptor");
199
200 _disallowProperty(obj, "extras", "A class descriptor");
201
202 var finisher = _optionalCallableProperty(obj, "finisher");
203
204 var elements = _toElementDescriptors(obj.elements);
205
206 return {
207 elements: elements,
208 finisher: finisher
209 };
210}
211
212function _disallowProperty(obj, name, objectType) {
213 if (obj[name] !== undefined) {
214 throw new TypeError(objectType + " can't have a ." + name + " property.");
215 }
216}
217
218function _optionalCallableProperty(obj, name) {
219 var value = obj[name];
220
221 if (value !== undefined && typeof value !== "function") {
222 throw new TypeError("Expected '" + name + "' to be a function");
223 }
224
225 return value;
226}
227
228function assertString(input) {
229 var isString = typeof input === 'string' || input instanceof String;
230
231 if (!isString) {
232 var invalidType;
233
234 if (input === null) {
235 invalidType = 'null';
236 } else {
237 invalidType = _typeof(input);
238
239 if (invalidType === 'object' && input.constructor && input.constructor.hasOwnProperty('name')) {
240 invalidType = input.constructor.name;
241 } else {
242 invalidType = "a ".concat(invalidType);
243 }
244 }
245
246 throw new TypeError("Expected string but received ".concat(invalidType, "."));
247 }
248}
249
250function toDate(date) {
251 assertString(date);
252 date = Date.parse(date);
253 return !isNaN(date) ? new Date(date) : null;
254}
255
256function toFloat(str) {
257 assertString(str);
258 return parseFloat(str);
259}
260
261function toInt(str, radix) {
262 assertString(str);
263 return parseInt(str, radix || 10);
264}
265
266function toBoolean(str, strict) {
267 assertString(str);
268
269 if (strict) {
270 return str === '1' || str === 'true';
271 }
272
273 return str !== '0' && str !== 'false' && str !== '';
274}
275
276function equals(str, comparison) {
277 assertString(str);
278 return str === comparison;
279}
280
281function toString(input) {
282 if (_typeof(input) === 'object' && input !== null) {
283 if (typeof input.toString === 'function') {
284 input = input.toString();
285 } else {
286 input = '[object Object]';
287 }
288 } else if (input === null || typeof input === 'undefined' || isNaN(input) && !input.length) {
289 input = '';
290 }
291
292 return String(input);
293}
294
295function contains(str, elem) {
296 assertString(str);
297 return str.indexOf(toString(elem)) >= 0;
298}
299
300function matches(str, pattern, modifiers) {
301 assertString(str);
302
303 if (Object.prototype.toString.call(pattern) !== '[object RegExp]') {
304 pattern = new RegExp(pattern, modifiers);
305 }
306
307 return pattern.test(str);
308}
309
310function merge() {
311 var obj = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
312 var defaults = arguments.length > 1 ? arguments[1] : undefined;
313
314 for (var key in defaults) {
315 if (typeof obj[key] === 'undefined') {
316 obj[key] = defaults[key];
317 }
318 }
319
320 return obj;
321}
322
323/* eslint-disable prefer-rest-params */
324
325function isByteLength(str, options) {
326 assertString(str);
327 var min;
328 var max;
329
330 if (_typeof(options) === 'object') {
331 min = options.min || 0;
332 max = options.max;
333 } else {
334 // backwards compatibility: isByteLength(str, min [, max])
335 min = arguments[1];
336 max = arguments[2];
337 }
338
339 var len = encodeURI(str).split(/%..|./).length - 1;
340 return len >= min && (typeof max === 'undefined' || len <= max);
341}
342
343var default_fqdn_options = {
344 require_tld: true,
345 allow_underscores: false,
346 allow_trailing_dot: false
347};
348function isFQDN(str, options) {
349 assertString(str);
350 options = merge(options, default_fqdn_options);
351 /* Remove the optional trailing dot before checking validity */
352
353 if (options.allow_trailing_dot && str[str.length - 1] === '.') {
354 str = str.substring(0, str.length - 1);
355 }
356
357 var parts = str.split('.');
358
359 for (var i = 0; i < parts.length; i++) {
360 if (parts[i].length > 63) {
361 return false;
362 }
363 }
364
365 if (options.require_tld) {
366 var tld = parts.pop();
367
368 if (!parts.length || !/^([a-z\u00a1-\uffff]{2,}|xn[a-z0-9-]{2,})$/i.test(tld)) {
369 return false;
370 } // disallow spaces
371
372
373 if (/[\s\u2002-\u200B\u202F\u205F\u3000\uFEFF\uDB40\uDC20]/.test(tld)) {
374 return false;
375 }
376 }
377
378 for (var part, _i = 0; _i < parts.length; _i++) {
379 part = parts[_i];
380
381 if (options.allow_underscores) {
382 part = part.replace(/_/g, '');
383 }
384
385 if (!/^[a-z\u00a1-\uffff0-9-]+$/i.test(part)) {
386 return false;
387 } // disallow full-width chars
388
389
390 if (/[\uff01-\uff5e]/.test(part)) {
391 return false;
392 }
393
394 if (part[0] === '-' || part[part.length - 1] === '-') {
395 return false;
396 }
397 }
398
399 return true;
400}
401
402var ipv4Maybe = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
403var ipv6Block = /^[0-9A-F]{1,4}$/i;
404function isIP(str) {
405 var version = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
406 assertString(str);
407 version = String(version);
408
409 if (!version) {
410 return isIP(str, 4) || isIP(str, 6);
411 } else if (version === '4') {
412 if (!ipv4Maybe.test(str)) {
413 return false;
414 }
415
416 var parts = str.split('.').sort(function (a, b) {
417 return a - b;
418 });
419 return parts[3] <= 255;
420 } else if (version === '6') {
421 var blocks = str.split(':');
422 var foundOmissionBlock = false; // marker to indicate ::
423 // At least some OS accept the last 32 bits of an IPv6 address
424 // (i.e. 2 of the blocks) in IPv4 notation, and RFC 3493 says
425 // that '::ffff:a.b.c.d' is valid for IPv4-mapped IPv6 addresses,
426 // and '::a.b.c.d' is deprecated, but also valid.
427
428 var foundIPv4TransitionBlock = isIP(blocks[blocks.length - 1], 4);
429 var expectedNumberOfBlocks = foundIPv4TransitionBlock ? 7 : 8;
430
431 if (blocks.length > expectedNumberOfBlocks) {
432 return false;
433 } // initial or final ::
434
435
436 if (str === '::') {
437 return true;
438 } else if (str.substr(0, 2) === '::') {
439 blocks.shift();
440 blocks.shift();
441 foundOmissionBlock = true;
442 } else if (str.substr(str.length - 2) === '::') {
443 blocks.pop();
444 blocks.pop();
445 foundOmissionBlock = true;
446 }
447
448 for (var i = 0; i < blocks.length; ++i) {
449 // test for a :: which can not be at the string start/end
450 // since those cases have been handled above
451 if (blocks[i] === '' && i > 0 && i < blocks.length - 1) {
452 if (foundOmissionBlock) {
453 return false; // multiple :: in address
454 }
455
456 foundOmissionBlock = true;
457 } else if (foundIPv4TransitionBlock && i === blocks.length - 1) {// it has been checked before that the last
458 // block is a valid IPv4 address
459 } else if (!ipv6Block.test(blocks[i])) {
460 return false;
461 }
462 }
463
464 if (foundOmissionBlock) {
465 return blocks.length >= 1;
466 }
467
468 return blocks.length === expectedNumberOfBlocks;
469 }
470
471 return false;
472}
473
474var default_email_options = {
475 allow_display_name: false,
476 require_display_name: false,
477 allow_utf8_local_part: true,
478 require_tld: true
479};
480/* eslint-disable max-len */
481
482/* eslint-disable no-control-regex */
483
484var displayName = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\.\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\,\.\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF\s]*<(.+)>$/i;
485var emailUserPart = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~]+$/i;
486var gmailUserPart = /^[a-z\d]+$/;
487var quotedEmailUser = /^([\s\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e]|(\\[\x01-\x09\x0b\x0c\x0d-\x7f]))*$/i;
488var emailUserUtf8Part = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+$/i;
489var 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;
490/* eslint-enable max-len */
491
492/* eslint-enable no-control-regex */
493
494function isEmail(str, options) {
495 assertString(str);
496 options = merge(options, default_email_options);
497
498 if (options.require_display_name || options.allow_display_name) {
499 var display_email = str.match(displayName);
500
501 if (display_email) {
502 str = display_email[1];
503 } else if (options.require_display_name) {
504 return false;
505 }
506 }
507
508 var parts = str.split('@');
509 var domain = parts.pop();
510 var user = parts.join('@');
511 var lower_domain = domain.toLowerCase();
512
513 if (options.domain_specific_validation && (lower_domain === 'gmail.com' || lower_domain === 'googlemail.com')) {
514 /*
515 Previously we removed dots for gmail addresses before validating.
516 This was removed because it allows `multiple..dots@gmail.com`
517 to be reported as valid, but it is not.
518 Gmail only normalizes single dots, removing them from here is pointless,
519 should be done in normalizeEmail
520 */
521 user = user.toLowerCase(); // Removing sub-address from username before gmail validation
522
523 var username = user.split('+')[0]; // Dots are not included in gmail length restriction
524
525 if (!isByteLength(username.replace('.', ''), {
526 min: 6,
527 max: 30
528 })) {
529 return false;
530 }
531
532 var _user_parts = username.split('.');
533
534 for (var i = 0; i < _user_parts.length; i++) {
535 if (!gmailUserPart.test(_user_parts[i])) {
536 return false;
537 }
538 }
539 }
540
541 if (!isByteLength(user, {
542 max: 64
543 }) || !isByteLength(domain, {
544 max: 254
545 })) {
546 return false;
547 }
548
549 if (!isFQDN(domain, {
550 require_tld: options.require_tld
551 })) {
552 if (!options.allow_ip_domain) {
553 return false;
554 }
555
556 if (!isIP(domain)) {
557 if (!domain.startsWith('[') || !domain.endsWith(']')) {
558 return false;
559 }
560
561 var noBracketdomain = domain.substr(1, domain.length - 2);
562
563 if (noBracketdomain.length === 0 || !isIP(noBracketdomain)) {
564 return false;
565 }
566 }
567 }
568
569 if (user[0] === '"') {
570 user = user.slice(1, user.length - 1);
571 return options.allow_utf8_local_part ? quotedEmailUserUtf8.test(user) : quotedEmailUser.test(user);
572 }
573
574 var pattern = options.allow_utf8_local_part ? emailUserUtf8Part : emailUserPart;
575 var user_parts = user.split('.');
576
577 for (var _i = 0; _i < user_parts.length; _i++) {
578 if (!pattern.test(user_parts[_i])) {
579 return false;
580 }
581 }
582
583 return true;
584}
585
586var default_url_options = {
587 protocols: ['http', 'https', 'ftp'],
588 require_tld: true,
589 require_protocol: false,
590 require_host: true,
591 require_valid_protocol: true,
592 allow_underscores: false,
593 allow_trailing_dot: false,
594 allow_protocol_relative_urls: false
595};
596var wrapped_ipv6 = /^\[([^\]]+)\](?::([0-9]+))?$/;
597
598function isRegExp(obj) {
599 return Object.prototype.toString.call(obj) === '[object RegExp]';
600}
601
602function checkHost(host, matches) {
603 for (var i = 0; i < matches.length; i++) {
604 var match = matches[i];
605
606 if (host === match || isRegExp(match) && match.test(host)) {
607 return true;
608 }
609 }
610
611 return false;
612}
613
614function isURL(url, options) {
615 assertString(url);
616
617 if (!url || url.length >= 2083 || /[\s<>]/.test(url)) {
618 return false;
619 }
620
621 if (url.indexOf('mailto:') === 0) {
622 return false;
623 }
624
625 options = merge(options, default_url_options);
626 var protocol, auth, host, hostname, port, port_str, split, ipv6;
627 split = url.split('#');
628 url = split.shift();
629 split = url.split('?');
630 url = split.shift();
631 split = url.split('://');
632
633 if (split.length > 1) {
634 protocol = split.shift().toLowerCase();
635
636 if (options.require_valid_protocol && options.protocols.indexOf(protocol) === -1) {
637 return false;
638 }
639 } else if (options.require_protocol) {
640 return false;
641 } else if (url.substr(0, 2) === '//') {
642 if (!options.allow_protocol_relative_urls) {
643 return false;
644 }
645
646 split[0] = url.substr(2);
647 }
648
649 url = split.join('://');
650
651 if (url === '') {
652 return false;
653 }
654
655 split = url.split('/');
656 url = split.shift();
657
658 if (url === '' && !options.require_host) {
659 return true;
660 }
661
662 split = url.split('@');
663
664 if (split.length > 1) {
665 if (options.disallow_auth) {
666 return false;
667 }
668
669 auth = split.shift();
670
671 if (auth.indexOf(':') >= 0 && auth.split(':').length > 2) {
672 return false;
673 }
674 }
675
676 hostname = split.join('@');
677 port_str = null;
678 ipv6 = null;
679 var ipv6_match = hostname.match(wrapped_ipv6);
680
681 if (ipv6_match) {
682 host = '';
683 ipv6 = ipv6_match[1];
684 port_str = ipv6_match[2] || null;
685 } else {
686 split = hostname.split(':');
687 host = split.shift();
688
689 if (split.length) {
690 port_str = split.join(':');
691 }
692 }
693
694 if (port_str !== null) {
695 port = parseInt(port_str, 10);
696
697 if (!/^[0-9]+$/.test(port_str) || port <= 0 || port > 65535) {
698 return false;
699 }
700 }
701
702 if (!isIP(host) && !isFQDN(host, options) && (!ipv6 || !isIP(ipv6, 6))) {
703 return false;
704 }
705
706 host = host || ipv6;
707
708 if (options.host_whitelist && !checkHost(host, options.host_whitelist)) {
709 return false;
710 }
711
712 if (options.host_blacklist && checkHost(host, options.host_blacklist)) {
713 return false;
714 }
715
716 return true;
717}
718
719var macAddress = /^([0-9a-fA-F][0-9a-fA-F]:){5}([0-9a-fA-F][0-9a-fA-F])$/;
720var macAddressNoColons = /^([0-9a-fA-F]){12}$/;
721function isMACAddress(str, options) {
722 assertString(str);
723
724 if (options && options.no_colons) {
725 return macAddressNoColons.test(str);
726 }
727
728 return macAddress.test(str);
729}
730
731var subnetMaybe = /^\d{1,2}$/;
732function isIPRange(str) {
733 assertString(str);
734 var parts = str.split('/'); // parts[0] -> ip, parts[1] -> subnet
735
736 if (parts.length !== 2) {
737 return false;
738 }
739
740 if (!subnetMaybe.test(parts[1])) {
741 return false;
742 } // Disallow preceding 0 i.e. 01, 02, ...
743
744
745 if (parts[1].length > 1 && parts[1].startsWith('0')) {
746 return false;
747 }
748
749 return isIP(parts[0], 4) && parts[1] <= 32 && parts[1] >= 0;
750}
751
752function isBoolean(str) {
753 assertString(str);
754 return ['true', 'false', '1', '0'].indexOf(str) >= 0;
755}
756
757var alpha = {
758 'en-US': /^[A-Z]+$/i,
759 'bg-BG': /^[А-Я]+$/i,
760 'cs-CZ': /^[A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]+$/i,
761 'da-DK': /^[A-ZÆØÅ]+$/i,
762 'de-DE': /^[A-ZÄÖÜß]+$/i,
763 'el-GR': /^[Α-ω]+$/i,
764 'es-ES': /^[A-ZÁÉÍÑÓÚÜ]+$/i,
765 'fr-FR': /^[A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ]+$/i,
766 'it-IT': /^[A-ZÀÉÈÌÎÓÒÙ]+$/i,
767 'nb-NO': /^[A-ZÆØÅ]+$/i,
768 'nl-NL': /^[A-ZÁÉËÏÓÖÜÚ]+$/i,
769 'nn-NO': /^[A-ZÆØÅ]+$/i,
770 'hu-HU': /^[A-ZÁÉÍÓÖŐÚÜŰ]+$/i,
771 'pl-PL': /^[A-ZĄĆĘŚŁŃÓŻŹ]+$/i,
772 'pt-PT': /^[A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ]+$/i,
773 'ru-RU': /^[А-ЯЁ]+$/i,
774 'sl-SI': /^[A-ZČĆĐŠŽ]+$/i,
775 'sk-SK': /^[A-ZÁČĎÉÍŇÓŠŤÚÝŽĹŔĽÄÔ]+$/i,
776 'sr-RS@latin': /^[A-ZČĆŽŠĐ]+$/i,
777 'sr-RS': /^[А-ЯЂЈЉЊЋЏ]+$/i,
778 'sv-SE': /^[A-ZÅÄÖ]+$/i,
779 'tr-TR': /^[A-ZÇĞİıÖŞÜ]+$/i,
780 'uk-UA': /^[А-ЩЬЮЯЄIЇҐі]+$/i,
781 'ku-IQ': /^[ئابپتجچحخدرڕزژسشعغفڤقکگلڵمنوۆھەیێيطؤثآإأكضصةظذ]+$/i,
782 ar: /^[ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ]+$/
783};
784var alphanumeric = {
785 'en-US': /^[0-9A-Z]+$/i,
786 'bg-BG': /^[0-9А-Я]+$/i,
787 'cs-CZ': /^[0-9A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]+$/i,
788 'da-DK': /^[0-9A-ZÆØÅ]+$/i,
789 'de-DE': /^[0-9A-ZÄÖÜß]+$/i,
790 'el-GR': /^[0-9Α-ω]+$/i,
791 'es-ES': /^[0-9A-ZÁÉÍÑÓÚÜ]+$/i,
792 'fr-FR': /^[0-9A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ]+$/i,
793 'it-IT': /^[0-9A-ZÀÉÈÌÎÓÒÙ]+$/i,
794 'hu-HU': /^[0-9A-ZÁÉÍÓÖŐÚÜŰ]+$/i,
795 'nb-NO': /^[0-9A-ZÆØÅ]+$/i,
796 'nl-NL': /^[0-9A-ZÁÉËÏÓÖÜÚ]+$/i,
797 'nn-NO': /^[0-9A-ZÆØÅ]+$/i,
798 'pl-PL': /^[0-9A-ZĄĆĘŚŁŃÓŻŹ]+$/i,
799 'pt-PT': /^[0-9A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ]+$/i,
800 'ru-RU': /^[0-9А-ЯЁ]+$/i,
801 'sl-SI': /^[0-9A-ZČĆĐŠŽ]+$/i,
802 'sk-SK': /^[0-9A-ZÁČĎÉÍŇÓŠŤÚÝŽĹŔĽÄÔ]+$/i,
803 'sr-RS@latin': /^[0-9A-ZČĆŽŠĐ]+$/i,
804 'sr-RS': /^[0-9А-ЯЂЈЉЊЋЏ]+$/i,
805 'sv-SE': /^[0-9A-ZÅÄÖ]+$/i,
806 'tr-TR': /^[0-9A-ZÇĞİıÖŞÜ]+$/i,
807 'uk-UA': /^[0-9А-ЩЬЮЯЄIЇҐі]+$/i,
808 'ku-IQ': /^[٠١٢٣٤٥٦٧٨٩0-9ئابپتجچحخدرڕزژسشعغفڤقکگلڵمنوۆھەیێيطؤثآإأكضصةظذ]+$/i,
809 ar: /^[٠١٢٣٤٥٦٧٨٩0-9ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ]+$/
810};
811var decimal = {
812 'en-US': '.',
813 ar: '٫'
814};
815var englishLocales = ['AU', 'GB', 'HK', 'IN', 'NZ', 'ZA', 'ZM'];
816
817for (var locale, i = 0; i < englishLocales.length; i++) {
818 locale = "en-".concat(englishLocales[i]);
819 alpha[locale] = alpha['en-US'];
820 alphanumeric[locale] = alphanumeric['en-US'];
821 decimal[locale] = decimal['en-US'];
822} // Source: http://www.localeplanet.com/java/
823
824
825var arabicLocales = ['AE', 'BH', 'DZ', 'EG', 'IQ', 'JO', 'KW', 'LB', 'LY', 'MA', 'QM', 'QA', 'SA', 'SD', 'SY', 'TN', 'YE'];
826
827for (var _locale, _i = 0; _i < arabicLocales.length; _i++) {
828 _locale = "ar-".concat(arabicLocales[_i]);
829 alpha[_locale] = alpha.ar;
830 alphanumeric[_locale] = alphanumeric.ar;
831 decimal[_locale] = decimal.ar;
832} // Source: https://en.wikipedia.org/wiki/Decimal_mark
833
834
835var dotDecimal = [];
836var commaDecimal = ['bg-BG', 'cs-CZ', 'da-DK', 'de-DE', 'el-GR', 'es-ES', 'fr-FR', 'it-IT', 'ku-IQ', 'hu-HU', 'nb-NO', 'nn-NO', 'nl-NL', 'pl-PL', 'pt-PT', 'ru-RU', 'sl-SI', 'sr-RS@latin', 'sr-RS', 'sv-SE', 'tr-TR', 'uk-UA'];
837
838for (var _i2 = 0; _i2 < dotDecimal.length; _i2++) {
839 decimal[dotDecimal[_i2]] = decimal['en-US'];
840}
841
842for (var _i3 = 0; _i3 < commaDecimal.length; _i3++) {
843 decimal[commaDecimal[_i3]] = ',';
844}
845
846alpha['pt-BR'] = alpha['pt-PT'];
847alphanumeric['pt-BR'] = alphanumeric['pt-PT'];
848decimal['pt-BR'] = decimal['pt-PT']; // see #862
849
850alpha['pl-Pl'] = alpha['pl-PL'];
851alphanumeric['pl-Pl'] = alphanumeric['pl-PL'];
852decimal['pl-Pl'] = decimal['pl-PL'];
853
854function isAlpha(str) {
855 var locale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'en-US';
856 assertString(str);
857
858 if (locale in alpha) {
859 return alpha[locale].test(str);
860 }
861
862 throw new Error("Invalid locale '".concat(locale, "'"));
863}
864var locales = Object.keys(alpha);
865
866function isAlphanumeric(str) {
867 var locale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'en-US';
868 assertString(str);
869
870 if (locale in alphanumeric) {
871 return alphanumeric[locale].test(str);
872 }
873
874 throw new Error("Invalid locale '".concat(locale, "'"));
875}
876var locales$1 = Object.keys(alphanumeric);
877
878var numeric = /^[+-]?([0-9]*[.])?[0-9]+$/;
879var numericNoSymbols = /^[0-9]+$/;
880function isNumeric(str, options) {
881 assertString(str);
882
883 if (options && options.no_symbols) {
884 return numericNoSymbols.test(str);
885 }
886
887 return numeric.test(str);
888}
889
890var int = /^(?:[-+]?(?:0|[1-9][0-9]*))$/;
891var intLeadingZeroes = /^[-+]?[0-9]+$/;
892function isInt(str, options) {
893 assertString(str);
894 options = options || {}; // Get the regex to use for testing, based on whether
895 // leading zeroes are allowed or not.
896
897 var regex = options.hasOwnProperty('allow_leading_zeroes') && !options.allow_leading_zeroes ? int : intLeadingZeroes; // Check min/max/lt/gt
898
899 var minCheckPassed = !options.hasOwnProperty('min') || str >= options.min;
900 var maxCheckPassed = !options.hasOwnProperty('max') || str <= options.max;
901 var ltCheckPassed = !options.hasOwnProperty('lt') || str < options.lt;
902 var gtCheckPassed = !options.hasOwnProperty('gt') || str > options.gt;
903 return regex.test(str) && minCheckPassed && maxCheckPassed && ltCheckPassed && gtCheckPassed;
904}
905
906function isPort(str) {
907 return isInt(str, {
908 min: 0,
909 max: 65535
910 });
911}
912
913function isLowercase(str) {
914 assertString(str);
915 return str === str.toLowerCase();
916}
917
918function isUppercase(str) {
919 assertString(str);
920 return str === str.toUpperCase();
921}
922
923/* eslint-disable no-control-regex */
924
925var ascii = /^[\x00-\x7F]+$/;
926/* eslint-enable no-control-regex */
927
928function isAscii(str) {
929 assertString(str);
930 return ascii.test(str);
931}
932
933var fullWidth = /[^\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]/;
934function isFullWidth(str) {
935 assertString(str);
936 return fullWidth.test(str);
937}
938
939var halfWidth = /[\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]/;
940function isHalfWidth(str) {
941 assertString(str);
942 return halfWidth.test(str);
943}
944
945function isVariableWidth(str) {
946 assertString(str);
947 return fullWidth.test(str) && halfWidth.test(str);
948}
949
950/* eslint-disable no-control-regex */
951
952var multibyte = /[^\x00-\x7F]/;
953/* eslint-enable no-control-regex */
954
955function isMultibyte(str) {
956 assertString(str);
957 return multibyte.test(str);
958}
959
960var surrogatePair = /[\uD800-\uDBFF][\uDC00-\uDFFF]/;
961function isSurrogatePair(str) {
962 assertString(str);
963 return surrogatePair.test(str);
964}
965
966function isFloat(str, options) {
967 assertString(str);
968 options = options || {};
969 var float = new RegExp("^(?:[-+])?(?:[0-9]+)?(?:\\".concat(options.locale ? decimal[options.locale] : '.', "[0-9]*)?(?:[eE][\\+\\-]?(?:[0-9]+))?$"));
970
971 if (str === '' || str === '.' || str === '-' || str === '+') {
972 return false;
973 }
974
975 var value = parseFloat(str.replace(',', '.'));
976 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);
977}
978var locales$2 = Object.keys(decimal);
979
980var includes = function includes(arr, val) {
981 return arr.some(function (arrVal) {
982 return val === arrVal;
983 });
984};
985
986function decimalRegExp(options) {
987 var regExp = new RegExp("^[-+]?([0-9]+)?(\\".concat(decimal[options.locale], "[0-9]{").concat(options.decimal_digits, "})").concat(options.force_decimal ? '' : '?', "$"));
988 return regExp;
989}
990
991var default_decimal_options = {
992 force_decimal: false,
993 decimal_digits: '1,',
994 locale: 'en-US'
995};
996var blacklist = ['', '-', '+'];
997function isDecimal(str, options) {
998 assertString(str);
999 options = merge(options, default_decimal_options);
1000
1001 if (options.locale in decimal) {
1002 return !includes(blacklist, str.replace(/ /g, '')) && decimalRegExp(options).test(str);
1003 }
1004
1005 throw new Error("Invalid locale '".concat(options.locale, "'"));
1006}
1007
1008var hexadecimal = /^[0-9A-F]+$/i;
1009function isHexadecimal(str) {
1010 assertString(str);
1011 return hexadecimal.test(str);
1012}
1013
1014function isDivisibleBy(str, num) {
1015 assertString(str);
1016 return toFloat(str) % parseInt(num, 10) === 0;
1017}
1018
1019var hexcolor = /^#?([0-9A-F]{3}|[0-9A-F]{6})$/i;
1020function isHexColor(str) {
1021 assertString(str);
1022 return hexcolor.test(str);
1023}
1024
1025var isrc = /^[A-Z]{2}[0-9A-Z]{3}\d{2}\d{5}$/;
1026function isISRC(str) {
1027 assertString(str);
1028 return isrc.test(str);
1029}
1030
1031var md5 = /^[a-f0-9]{32}$/;
1032function isMD5(str) {
1033 assertString(str);
1034 return md5.test(str);
1035}
1036
1037var lengths = {
1038 md5: 32,
1039 md4: 32,
1040 sha1: 40,
1041 sha256: 64,
1042 sha384: 96,
1043 sha512: 128,
1044 ripemd128: 32,
1045 ripemd160: 40,
1046 tiger128: 32,
1047 tiger160: 40,
1048 tiger192: 48,
1049 crc32: 8,
1050 crc32b: 8
1051};
1052function isHash(str, algorithm) {
1053 assertString(str);
1054 var hash = new RegExp("^[a-f0-9]{".concat(lengths[algorithm], "}$"));
1055 return hash.test(str);
1056}
1057
1058var jwt = /^([A-Za-z0-9\-_~+\/]+[=]{0,2})\.([A-Za-z0-9\-_~+\/]+[=]{0,2})(?:\.([A-Za-z0-9\-_~+\/]+[=]{0,2}))?$/;
1059function isJWT(str) {
1060 assertString(str);
1061 return jwt.test(str);
1062}
1063
1064function isJSON(str) {
1065 assertString(str);
1066
1067 try {
1068 var obj = JSON.parse(str);
1069 return !!obj && _typeof(obj) === 'object';
1070 } catch (e) {
1071 /* ignore */
1072 }
1073
1074 return false;
1075}
1076
1077var default_is_empty_options = {
1078 ignore_whitespace: false
1079};
1080function isEmpty(str, options) {
1081 assertString(str);
1082 options = merge(options, default_is_empty_options);
1083 return (options.ignore_whitespace ? str.trim().length : str.length) === 0;
1084}
1085
1086/* eslint-disable prefer-rest-params */
1087
1088function isLength(str, options) {
1089 assertString(str);
1090 var min;
1091 var max;
1092
1093 if (_typeof(options) === 'object') {
1094 min = options.min || 0;
1095 max = options.max;
1096 } else {
1097 // backwards compatibility: isLength(str, min [, max])
1098 min = arguments[1];
1099 max = arguments[2];
1100 }
1101
1102 var surrogatePairs = str.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g) || [];
1103 var len = str.length - surrogatePairs.length;
1104 return len >= min && (typeof max === 'undefined' || len <= max);
1105}
1106
1107var uuid = {
1108 3: /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,
1109 4: /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,
1110 5: /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,
1111 all: /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i
1112};
1113function isUUID(str) {
1114 var version = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'all';
1115 assertString(str);
1116 var pattern = uuid[version];
1117 return pattern && pattern.test(str);
1118}
1119
1120function isMongoId(str) {
1121 assertString(str);
1122 return isHexadecimal(str) && str.length === 24;
1123}
1124
1125function isAfter(str) {
1126 var date = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : String(new Date());
1127 assertString(str);
1128 var comparison = toDate(date);
1129 var original = toDate(str);
1130 return !!(original && comparison && original > comparison);
1131}
1132
1133function isBefore(str) {
1134 var date = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : String(new Date());
1135 assertString(str);
1136 var comparison = toDate(date);
1137 var original = toDate(str);
1138 return !!(original && comparison && original < comparison);
1139}
1140
1141function isIn(str, options) {
1142 assertString(str);
1143 var i;
1144
1145 if (Object.prototype.toString.call(options) === '[object Array]') {
1146 var array = [];
1147
1148 for (i in options) {
1149 if ({}.hasOwnProperty.call(options, i)) {
1150 array[i] = toString(options[i]);
1151 }
1152 }
1153
1154 return array.indexOf(str) >= 0;
1155 } else if (_typeof(options) === 'object') {
1156 return options.hasOwnProperty(str);
1157 } else if (options && typeof options.indexOf === 'function') {
1158 return options.indexOf(str) >= 0;
1159 }
1160
1161 return false;
1162}
1163
1164/* eslint-disable max-len */
1165
1166var 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})$/;
1167/* eslint-enable max-len */
1168
1169function isCreditCard(str) {
1170 assertString(str);
1171 var sanitized = str.replace(/[- ]+/g, '');
1172
1173 if (!creditCard.test(sanitized)) {
1174 return false;
1175 }
1176
1177 var sum = 0;
1178 var digit;
1179 var tmpNum;
1180 var shouldDouble;
1181
1182 for (var i = sanitized.length - 1; i >= 0; i--) {
1183 digit = sanitized.substring(i, i + 1);
1184 tmpNum = parseInt(digit, 10);
1185
1186 if (shouldDouble) {
1187 tmpNum *= 2;
1188
1189 if (tmpNum >= 10) {
1190 sum += tmpNum % 10 + 1;
1191 } else {
1192 sum += tmpNum;
1193 }
1194 } else {
1195 sum += tmpNum;
1196 }
1197
1198 shouldDouble = !shouldDouble;
1199 }
1200
1201 return !!(sum % 10 === 0 ? sanitized : false);
1202}
1203
1204var validators = {
1205 ES: function ES(str) {
1206 assertString(str);
1207 var DNI = /^[0-9X-Z][0-9]{7}[TRWAGMYFPDXBNJZSQVHLCKE]$/;
1208 var charsValue = {
1209 X: 0,
1210 Y: 1,
1211 Z: 2
1212 };
1213 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']; // sanitize user input
1214
1215 var sanitized = str.trim().toUpperCase(); // validate the data structure
1216
1217 if (!DNI.test(sanitized)) {
1218 return false;
1219 } // validate the control digit
1220
1221
1222 var number = sanitized.slice(0, -1).replace(/[X,Y,Z]/g, function (char) {
1223 return charsValue[char];
1224 });
1225 return sanitized.endsWith(controlDigits[number % 23]);
1226 }
1227};
1228function isIdentityCard(str) {
1229 var locale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'any';
1230 assertString(str);
1231
1232 if (locale in validators) {
1233 return validators[locale](str);
1234 } else if (locale === 'any') {
1235 for (var key in validators) {
1236 if (validators.hasOwnProperty(key)) {
1237 var validator = validators[key];
1238
1239 if (validator(str)) {
1240 return true;
1241 }
1242 }
1243 }
1244
1245 return false;
1246 }
1247
1248 throw new Error("Invalid locale '".concat(locale, "'"));
1249}
1250
1251var isin = /^[A-Z]{2}[0-9A-Z]{9}[0-9]$/;
1252function isISIN(str) {
1253 assertString(str);
1254
1255 if (!isin.test(str)) {
1256 return false;
1257 }
1258
1259 var checksumStr = str.replace(/[A-Z]/g, function (character) {
1260 return parseInt(character, 36);
1261 });
1262 var sum = 0;
1263 var digit;
1264 var tmpNum;
1265 var shouldDouble = true;
1266
1267 for (var i = checksumStr.length - 2; i >= 0; i--) {
1268 digit = checksumStr.substring(i, i + 1);
1269 tmpNum = parseInt(digit, 10);
1270
1271 if (shouldDouble) {
1272 tmpNum *= 2;
1273
1274 if (tmpNum >= 10) {
1275 sum += tmpNum + 1;
1276 } else {
1277 sum += tmpNum;
1278 }
1279 } else {
1280 sum += tmpNum;
1281 }
1282
1283 shouldDouble = !shouldDouble;
1284 }
1285
1286 return parseInt(str.substr(str.length - 1), 10) === (10000 - sum) % 10;
1287}
1288
1289var isbn10Maybe = /^(?:[0-9]{9}X|[0-9]{10})$/;
1290var isbn13Maybe = /^(?:[0-9]{13})$/;
1291var factor = [1, 3];
1292function isISBN(str) {
1293 var version = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
1294 assertString(str);
1295 version = String(version);
1296
1297 if (!version) {
1298 return isISBN(str, 10) || isISBN(str, 13);
1299 }
1300
1301 var sanitized = str.replace(/[\s-]+/g, '');
1302 var checksum = 0;
1303 var i;
1304
1305 if (version === '10') {
1306 if (!isbn10Maybe.test(sanitized)) {
1307 return false;
1308 }
1309
1310 for (i = 0; i < 9; i++) {
1311 checksum += (i + 1) * sanitized.charAt(i);
1312 }
1313
1314 if (sanitized.charAt(9) === 'X') {
1315 checksum += 10 * 10;
1316 } else {
1317 checksum += 10 * sanitized.charAt(9);
1318 }
1319
1320 if (checksum % 11 === 0) {
1321 return !!sanitized;
1322 }
1323 } else if (version === '13') {
1324 if (!isbn13Maybe.test(sanitized)) {
1325 return false;
1326 }
1327
1328 for (i = 0; i < 12; i++) {
1329 checksum += factor[i % 2] * sanitized.charAt(i);
1330 }
1331
1332 if (sanitized.charAt(12) - (10 - checksum % 10) % 10 === 0) {
1333 return !!sanitized;
1334 }
1335 }
1336
1337 return false;
1338}
1339
1340var issn = '^\\d{4}-?\\d{3}[\\dX]$';
1341function isISSN(str) {
1342 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1343 assertString(str);
1344 var testIssn = issn;
1345 testIssn = options.require_hyphen ? testIssn.replace('?', '') : testIssn;
1346 testIssn = options.case_sensitive ? new RegExp(testIssn) : new RegExp(testIssn, 'i');
1347
1348 if (!testIssn.test(str)) {
1349 return false;
1350 }
1351
1352 var digits = str.replace('-', '').toUpperCase();
1353 var checksum = 0;
1354
1355 for (var i = 0; i < digits.length; i++) {
1356 var digit = digits[i];
1357 checksum += (digit === 'X' ? 10 : +digit) * (8 - i);
1358 }
1359
1360 return checksum % 11 === 0;
1361}
1362
1363/* eslint-disable max-len */
1364
1365var phones = {
1366 'ar-AE': /^((\+?971)|0)?5[024568]\d{7}$/,
1367 'ar-DZ': /^(\+?213|0)(5|6|7)\d{8}$/,
1368 'ar-EG': /^((\+?20)|0)?1[012]\d{8}$/,
1369 'ar-IQ': /^(\+?964|0)?7[0-9]\d{8}$/,
1370 'ar-JO': /^(\+?962|0)?7[789]\d{7}$/,
1371 'ar-KW': /^(\+?965)[569]\d{7}$/,
1372 'ar-SA': /^(!?(\+?966)|0)?5\d{8}$/,
1373 'ar-SY': /^(!?(\+?963)|0)?9\d{8}$/,
1374 'ar-TN': /^(\+?216)?[2459]\d{7}$/,
1375 'be-BY': /^(\+?375)?(24|25|29|33|44)\d{7}$/,
1376 'bg-BG': /^(\+?359|0)?8[789]\d{7}$/,
1377 'bn-BD': /\+?(88)?0?1[356789][0-9]{8}\b/,
1378 'cs-CZ': /^(\+?420)? ?[1-9][0-9]{2} ?[0-9]{3} ?[0-9]{3}$/,
1379 'da-DK': /^(\+?45)?\s?\d{2}\s?\d{2}\s?\d{2}\s?\d{2}$/,
1380 'de-DE': /^(\+?49[ \.\-]?)?([\(]{1}[0-9]{1,6}[\)])?([0-9 \.\-\/]{3,20})((x|ext|extension)[ ]?[0-9]{1,4})?$/,
1381 'el-GR': /^(\+?30|0)?(69\d{8})$/,
1382 'en-AU': /^(\+?61|0)4\d{8}$/,
1383 'en-GB': /^(\+?44|0)7\d{9}$/,
1384 'en-GH': /^(\+233|0)(20|50|24|54|27|57|26|56|23|28)\d{7}$/,
1385 'en-HK': /^(\+?852\-?)?[456789]\d{3}\-?\d{4}$/,
1386 'en-IN': /^(\+?91|0)?[6789]\d{9}$/,
1387 'en-KE': /^(\+?254|0)?[7]\d{8}$/,
1388 'en-MU': /^(\+?230|0)?\d{8}$/,
1389 'en-NG': /^(\+?234|0)?[789]\d{9}$/,
1390 'en-NZ': /^(\+?64|0)[28]\d{7,9}$/,
1391 'en-PK': /^((\+92)|(0092))-{0,1}\d{3}-{0,1}\d{7}$|^\d{11}$|^\d{4}-\d{7}$/,
1392 'en-RW': /^(\+?250|0)?[7]\d{8}$/,
1393 'en-SG': /^(\+65)?[89]\d{7}$/,
1394 'en-TZ': /^(\+?255|0)?[67]\d{8}$/,
1395 'en-UG': /^(\+?256|0)?[7]\d{8}$/,
1396 'en-US': /^(\+?1?( |-)?)?(\([2-9][0-9]{2}\)|[2-9][0-9]{2})( |-)?([2-9][0-9]{2}( |-)?[0-9]{4})$/,
1397 'en-ZA': /^(\+?27|0)\d{9}$/,
1398 'en-ZM': /^(\+?26)?09[567]\d{7}$/,
1399 'es-ES': /^(\+?34)?(6\d{1}|7[1234])\d{7}$/,
1400 'es-MX': /^(\+?52)?(1|01)?\d{10,11}$/,
1401 'es-UY': /^(\+598|0)9[1-9][\d]{6}$/,
1402 'et-EE': /^(\+?372)?\s?(5|8[1-4])\s?([0-9]\s?){6,7}$/,
1403 'fa-IR': /^(\+?98[\-\s]?|0)9[0-39]\d[\-\s]?\d{3}[\-\s]?\d{4}$/,
1404 'fi-FI': /^(\+?358|0)\s?(4(0|1|2|4|5|6)?|50)\s?(\d\s?){4,8}\d$/,
1405 'fo-FO': /^(\+?298)?\s?\d{2}\s?\d{2}\s?\d{2}$/,
1406 'fr-FR': /^(\+?33|0)[67]\d{8}$/,
1407 'he-IL': /^(\+972|0)([23489]|5[012345689]|77)[1-9]\d{6}$/,
1408 'hu-HU': /^(\+?36)(20|30|70)\d{7}$/,
1409 'id-ID': /^(\+?62|0)8(1[123456789]|2[1238]|3[1238]|5[12356789]|7[78]|9[56789]|8[123456789])([\s?|\d]{5,11})$/,
1410 'it-IT': /^(\+?39)?\s?3\d{2} ?\d{6,7}$/,
1411 'ja-JP': /^(\+?81|0)[789]0[ \-]?[1-9]\d{2}[ \-]?\d{5}$/,
1412 'kk-KZ': /^(\+?7|8)?7\d{9}$/,
1413 'kl-GL': /^(\+?299)?\s?\d{2}\s?\d{2}\s?\d{2}$/,
1414 'ko-KR': /^((\+?82)[ \-]?)?0?1([0|1|6|7|8|9]{1})[ \-]?\d{3,4}[ \-]?\d{4}$/,
1415 'lt-LT': /^(\+370|8)\d{8}$/,
1416 'ms-MY': /^(\+?6?01){1}(([145]{1}(\-|\s)?\d{7,8})|([236789]{1}(\s|\-)?\d{7}))$/,
1417 'nb-NO': /^(\+?47)?[49]\d{7}$/,
1418 'nl-BE': /^(\+?32|0)4?\d{8}$/,
1419 'nn-NO': /^(\+?47)?[49]\d{7}$/,
1420 'pl-PL': /^(\+?48)? ?[5-8]\d ?\d{3} ?\d{2} ?\d{2}$/,
1421 'pt-BR': /(?=^(\+?5{2}\-?|0)[1-9]{2}\-?\d{4}\-?\d{4}$)(^(\+?5{2}\-?|0)[1-9]{2}\-?[6-9]{1}\d{3}\-?\d{4}$)|(^(\+?5{2}\-?|0)[1-9]{2}\-?9[6-9]{1}\d{3}\-?\d{4}$)/,
1422 'pt-PT': /^(\+?351)?9[1236]\d{7}$/,
1423 'ro-RO': /^(\+?4?0)\s?7\d{2}(\/|\s|\.|\-)?\d{3}(\s|\.|\-)?\d{3}$/,
1424 'ru-RU': /^(\+?7|8)?9\d{9}$/,
1425 'sl-SI': /^(\+386\s?|0)(\d{1}\s?\d{3}\s?\d{2}\s?\d{2}|\d{2}\s?\d{3}\s?\d{3})$/,
1426 'sk-SK': /^(\+?421)? ?[1-9][0-9]{2} ?[0-9]{3} ?[0-9]{3}$/,
1427 'sr-RS': /^(\+3816|06)[- \d]{5,9}$/,
1428 'sv-SE': /^(\+?46|0)[\s\-]?7[\s\-]?[02369]([\s\-]?\d){7}$/,
1429 'th-TH': /^(\+66|66|0)\d{9}$/,
1430 'tr-TR': /^(\+?90|0)?5\d{9}$/,
1431 'uk-UA': /^(\+?38|8)?0\d{9}$/,
1432 'vi-VN': /^(\+?84|0)((3([2-9]))|(5([689]))|(7([0|6-9]))|(8([1-5]))|(9([0-9])))([0-9]{7})$/,
1433 'zh-CN': /^((\+|00)86)?1([358][0-9]|4[579]|66|7[0135678]|9[89])[0-9]{8}$/,
1434 'zh-TW': /^(\+?886\-?|0)?9\d{8}$/
1435};
1436/* eslint-enable max-len */
1437// aliases
1438
1439phones['en-CA'] = phones['en-US'];
1440phones['fr-BE'] = phones['nl-BE'];
1441phones['zh-HK'] = phones['en-HK'];
1442function isMobilePhone(str, locale, options) {
1443 assertString(str);
1444
1445 if (options && options.strictMode && !str.startsWith('+')) {
1446 return false;
1447 }
1448
1449 if (Array.isArray(locale)) {
1450 return locale.some(function (key) {
1451 if (phones.hasOwnProperty(key)) {
1452 var phone = phones[key];
1453
1454 if (phone.test(str)) {
1455 return true;
1456 }
1457 }
1458
1459 return false;
1460 });
1461 } else if (locale in phones) {
1462 return phones[locale].test(str); // alias falsey locale as 'any'
1463 } else if (!locale || locale === 'any') {
1464 for (var key in phones) {
1465 if (phones.hasOwnProperty(key)) {
1466 var phone = phones[key];
1467
1468 if (phone.test(str)) {
1469 return true;
1470 }
1471 }
1472 }
1473
1474 return false;
1475 }
1476
1477 throw new Error("Invalid locale '".concat(locale, "'"));
1478}
1479var locales$3 = Object.keys(phones);
1480
1481function currencyRegex(options) {
1482 var decimal_digits = "\\d{".concat(options.digits_after_decimal[0], "}");
1483 options.digits_after_decimal.forEach(function (digit, index) {
1484 if (index !== 0) decimal_digits = "".concat(decimal_digits, "|\\d{").concat(digit, "}");
1485 });
1486 var symbol = "(\\".concat(options.symbol.replace(/\./g, '\\.'), ")").concat(options.require_symbol ? '' : '?'),
1487 negative = '-?',
1488 whole_dollar_amount_without_sep = '[1-9]\\d*',
1489 whole_dollar_amount_with_sep = "[1-9]\\d{0,2}(\\".concat(options.thousands_separator, "\\d{3})*"),
1490 valid_whole_dollar_amounts = ['0', whole_dollar_amount_without_sep, whole_dollar_amount_with_sep],
1491 whole_dollar_amount = "(".concat(valid_whole_dollar_amounts.join('|'), ")?"),
1492 decimal_amount = "(\\".concat(options.decimal_separator, "(").concat(decimal_digits, "))").concat(options.require_decimal ? '' : '?');
1493 var pattern = whole_dollar_amount + (options.allow_decimal || options.require_decimal ? decimal_amount : ''); // default is negative sign before symbol, but there are two other options (besides parens)
1494
1495 if (options.allow_negatives && !options.parens_for_negatives) {
1496 if (options.negative_sign_after_digits) {
1497 pattern += negative;
1498 } else if (options.negative_sign_before_digits) {
1499 pattern = negative + pattern;
1500 }
1501 } // South African Rand, for example, uses R 123 (space) and R-123 (no space)
1502
1503
1504 if (options.allow_negative_sign_placeholder) {
1505 pattern = "( (?!\\-))?".concat(pattern);
1506 } else if (options.allow_space_after_symbol) {
1507 pattern = " ?".concat(pattern);
1508 } else if (options.allow_space_after_digits) {
1509 pattern += '( (?!$))?';
1510 }
1511
1512 if (options.symbol_after_digits) {
1513 pattern += symbol;
1514 } else {
1515 pattern = symbol + pattern;
1516 }
1517
1518 if (options.allow_negatives) {
1519 if (options.parens_for_negatives) {
1520 pattern = "(\\(".concat(pattern, "\\)|").concat(pattern, ")");
1521 } else if (!(options.negative_sign_before_digits || options.negative_sign_after_digits)) {
1522 pattern = negative + pattern;
1523 }
1524 } // ensure there's a dollar and/or decimal amount, and that
1525 // it doesn't start with a space or a negative sign followed by a space
1526
1527
1528 return new RegExp("^(?!-? )(?=.*\\d)".concat(pattern, "$"));
1529}
1530
1531var default_currency_options = {
1532 symbol: '$',
1533 require_symbol: false,
1534 allow_space_after_symbol: false,
1535 symbol_after_digits: false,
1536 allow_negatives: true,
1537 parens_for_negatives: false,
1538 negative_sign_before_digits: false,
1539 negative_sign_after_digits: false,
1540 allow_negative_sign_placeholder: false,
1541 thousands_separator: ',',
1542 decimal_separator: '.',
1543 allow_decimal: true,
1544 require_decimal: false,
1545 digits_after_decimal: [2],
1546 allow_space_after_digits: false
1547};
1548function isCurrency(str, options) {
1549 assertString(str);
1550 options = merge(options, default_currency_options);
1551 return currencyRegex(options).test(str);
1552}
1553
1554/* eslint-disable max-len */
1555// from http://goo.gl/0ejHHW
1556
1557var 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)?)?)?)?$/;
1558/* eslint-enable max-len */
1559
1560var isValidDate = function isValidDate(str) {
1561 // str must have passed the ISO8601 check
1562 // this check is meant to catch invalid dates
1563 // like 2009-02-31
1564 // first check for ordinal dates
1565 var ordinalMatch = str.match(/^(\d{4})-?(\d{3})([ T]{1}\.*|$)/);
1566
1567 if (ordinalMatch) {
1568 var oYear = Number(ordinalMatch[1]);
1569 var oDay = Number(ordinalMatch[2]); // if is leap year
1570
1571 if (oYear % 4 === 0 && oYear % 100 !== 0) return oDay <= 366;
1572 return oDay <= 365;
1573 }
1574
1575 var match = str.match(/(\d{4})-?(\d{0,2})-?(\d*)/).map(Number);
1576 var year = match[1];
1577 var month = match[2];
1578 var day = match[3]; // create a date object and compare
1579
1580 var d = new Date("".concat(year, "-").concat(month || 1, "-").concat(day || 1));
1581 if (isNaN(d.getFullYear())) return false;
1582
1583 if (month && day) {
1584 return d.getFullYear() === year && d.getMonth() + 1 === month && d.getDate() === day;
1585 }
1586
1587 return true;
1588};
1589
1590function isISO8601(str, options) {
1591 assertString(str);
1592 var check = iso8601.test(str);
1593 if (!options) return check;
1594 if (check && options.strict) return isValidDate(str);
1595 return check;
1596}
1597
1598/* Based on https://tools.ietf.org/html/rfc3339#section-5.6 */
1599
1600var dateFullYear = /[0-9]{4}/;
1601var dateMonth = /(0[1-9]|1[0-2])/;
1602var dateMDay = /([12]\d|0[1-9]|3[01])/;
1603var timeHour = /([01][0-9]|2[0-3])/;
1604var timeMinute = /[0-5][0-9]/;
1605var timeSecond = /([0-5][0-9]|60)/;
1606var timeSecFrac = /(\.[0-9]+)?/;
1607var timeNumOffset = new RegExp("[-+]".concat(timeHour.source, ":").concat(timeMinute.source));
1608var timeOffset = new RegExp("([zZ]|".concat(timeNumOffset.source, ")"));
1609var partialTime = new RegExp("".concat(timeHour.source, ":").concat(timeMinute.source, ":").concat(timeSecond.source).concat(timeSecFrac.source));
1610var fullDate = new RegExp("".concat(dateFullYear.source, "-").concat(dateMonth.source, "-").concat(dateMDay.source));
1611var fullTime = new RegExp("".concat(partialTime.source).concat(timeOffset.source));
1612var rfc3339 = new RegExp("".concat(fullDate.source, "[ tT]").concat(fullTime.source));
1613function isRFC3339(str) {
1614 assertString(str);
1615 return rfc3339.test(str);
1616}
1617
1618var validISO31661Alpha2CountriesCodes = ['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'];
1619function isISO31661Alpha2(str) {
1620 assertString(str);
1621 return includes(validISO31661Alpha2CountriesCodes, str.toUpperCase());
1622}
1623
1624var validISO31661Alpha3CountriesCodes = ['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'];
1625function isISO31661Alpha3(str) {
1626 assertString(str);
1627 return includes(validISO31661Alpha3CountriesCodes, str.toUpperCase());
1628}
1629
1630var notBase64 = /[^A-Z0-9+\/=]/i;
1631function isBase64(str) {
1632 assertString(str);
1633 var len = str.length;
1634
1635 if (!len || len % 4 !== 0 || notBase64.test(str)) {
1636 return false;
1637 }
1638
1639 var firstPaddingChar = str.indexOf('=');
1640 return firstPaddingChar === -1 || firstPaddingChar === len - 1 || firstPaddingChar === len - 2 && str[len - 1] === '=';
1641}
1642
1643var validMediaType = /^[a-z]+\/[a-z0-9\-\+]+$/i;
1644var validAttribute = /^[a-z\-]+=[a-z0-9\-]+$/i;
1645var validData = /^[a-z0-9!\$&'\(\)\*\+,;=\-\._~:@\/\?%\s]*$/i;
1646function isDataURI(str) {
1647 assertString(str);
1648 var data = str.split(',');
1649
1650 if (data.length < 2) {
1651 return false;
1652 }
1653
1654 var attributes = data.shift().trim().split(';');
1655 var schemeAndMediaType = attributes.shift();
1656
1657 if (schemeAndMediaType.substr(0, 5) !== 'data:') {
1658 return false;
1659 }
1660
1661 var mediaType = schemeAndMediaType.substr(5);
1662
1663 if (mediaType !== '' && !validMediaType.test(mediaType)) {
1664 return false;
1665 }
1666
1667 for (var i = 0; i < attributes.length; i++) {
1668 if (i === attributes.length - 1 && attributes[i].toLowerCase() === 'base64') {// ok
1669 } else if (!validAttribute.test(attributes[i])) {
1670 return false;
1671 }
1672 }
1673
1674 for (var _i = 0; _i < data.length; _i++) {
1675 if (!validData.test(data[_i])) {
1676 return false;
1677 }
1678 }
1679
1680 return true;
1681}
1682
1683var magnetURI = /^magnet:\?xt=urn:[a-z0-9]+:[a-z0-9]{32,40}&dn=.+&tr=.+$/i;
1684function isMagnetURI(url) {
1685 assertString(url);
1686 return magnetURI.test(url.trim());
1687}
1688
1689/*
1690 Checks if the provided string matches to a correct Media type format (MIME type)
1691
1692 This function only checks is the string format follows the
1693 etablished rules by the according RFC specifications.
1694 This function supports 'charset' in textual media types
1695 (https://tools.ietf.org/html/rfc6657).
1696
1697 This function does not check against all the media types listed
1698 by the IANA (https://www.iana.org/assignments/media-types/media-types.xhtml)
1699 because of lightness purposes : it would require to include
1700 all these MIME types in this librairy, which would weigh it
1701 significantly. This kind of effort maybe is not worth for the use that
1702 this function has in this entire librairy.
1703
1704 More informations in the RFC specifications :
1705 - https://tools.ietf.org/html/rfc2045
1706 - https://tools.ietf.org/html/rfc2046
1707 - https://tools.ietf.org/html/rfc7231#section-3.1.1.1
1708 - https://tools.ietf.org/html/rfc7231#section-3.1.1.5
1709*/
1710// Match simple MIME types
1711// NB :
1712// Subtype length must not exceed 100 characters.
1713// This rule does not comply to the RFC specs (what is the max length ?).
1714
1715var mimeTypeSimple = /^(application|audio|font|image|message|model|multipart|text|video)\/[a-zA-Z0-9\.\-\+]{1,100}$/i; // eslint-disable-line max-len
1716// Handle "charset" in "text/*"
1717
1718var 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
1719// Handle "boundary" in "multipart/*"
1720
1721var 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
1722
1723function isMimeType(str) {
1724 assertString(str);
1725 return mimeTypeSimple.test(str) || mimeTypeText.test(str) || mimeTypeMultipart.test(str);
1726}
1727
1728var lat = /^\(?[+-]?(90(\.0+)?|[1-8]?\d(\.\d+)?)$/;
1729var long = /^\s?[+-]?(180(\.0+)?|1[0-7]\d(\.\d+)?|\d{1,2}(\.\d+)?)\)?$/;
1730var isLatLong = function (str) {
1731 assertString(str);
1732 if (!str.includes(',')) return false;
1733 var pair = str.split(',');
1734 return lat.test(pair[0]) && long.test(pair[1]);
1735};
1736
1737var threeDigit = /^\d{3}$/;
1738var fourDigit = /^\d{4}$/;
1739var fiveDigit = /^\d{5}$/;
1740var sixDigit = /^\d{6}$/;
1741var patterns = {
1742 AD: /^AD\d{3}$/,
1743 AT: fourDigit,
1744 AU: fourDigit,
1745 BE: fourDigit,
1746 BG: fourDigit,
1747 CA: /^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][\s\-]?\d[ABCEGHJ-NPRSTV-Z]\d$/i,
1748 CH: fourDigit,
1749 CZ: /^\d{3}\s?\d{2}$/,
1750 DE: fiveDigit,
1751 DK: fourDigit,
1752 DZ: fiveDigit,
1753 EE: fiveDigit,
1754 ES: fiveDigit,
1755 FI: fiveDigit,
1756 FR: /^\d{2}\s?\d{3}$/,
1757 GB: /^(gir\s?0aa|[a-z]{1,2}\d[\da-z]?\s?(\d[a-z]{2})?)$/i,
1758 GR: /^\d{3}\s?\d{2}$/,
1759 HR: /^([1-5]\d{4}$)/,
1760 HU: fourDigit,
1761 IL: fiveDigit,
1762 IN: sixDigit,
1763 IS: threeDigit,
1764 IT: fiveDigit,
1765 JP: /^\d{3}\-\d{4}$/,
1766 KE: fiveDigit,
1767 LI: /^(948[5-9]|949[0-7])$/,
1768 LT: /^LT\-\d{5}$/,
1769 LU: fourDigit,
1770 LV: /^LV\-\d{4}$/,
1771 MX: fiveDigit,
1772 NL: /^\d{4}\s?[a-z]{2}$/i,
1773 NO: fourDigit,
1774 PL: /^\d{2}\-\d{3}$/,
1775 PT: /^\d{4}\-\d{3}?$/,
1776 RO: sixDigit,
1777 RU: sixDigit,
1778 SA: fiveDigit,
1779 SE: /^\d{3}\s?\d{2}$/,
1780 SI: fourDigit,
1781 SK: /^\d{3}\s?\d{2}$/,
1782 TN: fourDigit,
1783 TW: /^\d{3}(\d{2})?$/,
1784 US: /^\d{5}(-\d{4})?$/,
1785 ZA: fourDigit,
1786 ZM: fiveDigit
1787};
1788var locales$4 = Object.keys(patterns);
1789var isPostalCode = function (str, locale) {
1790 assertString(str);
1791
1792 if (locale in patterns) {
1793 return patterns[locale].test(str);
1794 } else if (locale === 'any') {
1795 for (var key in patterns) {
1796 if (patterns.hasOwnProperty(key)) {
1797 var pattern = patterns[key];
1798
1799 if (pattern.test(str)) {
1800 return true;
1801 }
1802 }
1803 }
1804
1805 return false;
1806 }
1807
1808 throw new Error("Invalid locale '".concat(locale, "'"));
1809};
1810
1811function ltrim(str, chars) {
1812 assertString(str);
1813 var pattern = chars ? new RegExp("^[".concat(chars, "]+"), 'g') : /^\s+/g;
1814 return str.replace(pattern, '');
1815}
1816
1817function rtrim(str, chars) {
1818 assertString(str);
1819 var pattern = chars ? new RegExp("[".concat(chars, "]")) : /\s/;
1820 var idx = str.length - 1;
1821
1822 for (; idx >= 0 && pattern.test(str[idx]); idx--) {
1823
1824 }
1825
1826 return idx < str.length ? str.substr(0, idx + 1) : str;
1827}
1828
1829function trim(str, chars) {
1830 return rtrim(ltrim(str, chars), chars);
1831}
1832
1833function escape(str) {
1834 assertString(str);
1835 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;');
1836}
1837
1838function unescape(str) {
1839 assertString(str);
1840 return str.replace(/&amp;/g, '&').replace(/&quot;/g, '"').replace(/&#x27;/g, "'").replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&#x2F;/g, '/').replace(/&#x5C;/g, '\\').replace(/&#96;/g, '`');
1841}
1842
1843function blacklist$1(str, chars) {
1844 assertString(str);
1845 return str.replace(new RegExp("[".concat(chars, "]+"), 'g'), '');
1846}
1847
1848function stripLow(str, keep_new_lines) {
1849 assertString(str);
1850 var chars = keep_new_lines ? '\\x00-\\x09\\x0B\\x0C\\x0E-\\x1F\\x7F' : '\\x00-\\x1F\\x7F';
1851 return blacklist$1(str, chars);
1852}
1853
1854function whitelist(str, chars) {
1855 assertString(str);
1856 return str.replace(new RegExp("[^".concat(chars, "]+"), 'g'), '');
1857}
1858
1859function isWhitelisted(str, chars) {
1860 assertString(str);
1861
1862 for (var i = str.length - 1; i >= 0; i--) {
1863 if (chars.indexOf(str[i]) === -1) {
1864 return false;
1865 }
1866 }
1867
1868 return true;
1869}
1870
1871var default_normalize_email_options = {
1872 // The following options apply to all email addresses
1873 // Lowercases the local part of the email address.
1874 // Please note this may violate RFC 5321 as per http://stackoverflow.com/a/9808332/192024).
1875 // The domain is always lowercased, as per RFC 1035
1876 all_lowercase: true,
1877 // The following conversions are specific to GMail
1878 // Lowercases the local part of the GMail address (known to be case-insensitive)
1879 gmail_lowercase: true,
1880 // Removes dots from the local part of the email address, as that's ignored by GMail
1881 gmail_remove_dots: true,
1882 // Removes the subaddress (e.g. "+foo") from the email address
1883 gmail_remove_subaddress: true,
1884 // Conversts the googlemail.com domain to gmail.com
1885 gmail_convert_googlemaildotcom: true,
1886 // The following conversions are specific to Outlook.com / Windows Live / Hotmail
1887 // Lowercases the local part of the Outlook.com address (known to be case-insensitive)
1888 outlookdotcom_lowercase: true,
1889 // Removes the subaddress (e.g. "+foo") from the email address
1890 outlookdotcom_remove_subaddress: true,
1891 // The following conversions are specific to Yahoo
1892 // Lowercases the local part of the Yahoo address (known to be case-insensitive)
1893 yahoo_lowercase: true,
1894 // Removes the subaddress (e.g. "-foo") from the email address
1895 yahoo_remove_subaddress: true,
1896 // The following conversions are specific to Yandex
1897 // Lowercases the local part of the Yandex address (known to be case-insensitive)
1898 yandex_lowercase: true,
1899 // The following conversions are specific to iCloud
1900 // Lowercases the local part of the iCloud address (known to be case-insensitive)
1901 icloud_lowercase: true,
1902 // Removes the subaddress (e.g. "+foo") from the email address
1903 icloud_remove_subaddress: true
1904}; // List of domains used by iCloud
1905
1906var icloud_domains = ['icloud.com', 'me.com']; // List of domains used by Outlook.com and its predecessors
1907// This list is likely incomplete.
1908// Partial reference:
1909// https://blogs.office.com/2013/04/17/outlook-com-gets-two-step-verification-sign-in-by-alias-and-new-international-domains/
1910
1911var 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']; // List of domains used by Yahoo Mail
1912// This list is likely incomplete
1913
1914var yahoo_domains = ['rocketmail.com', 'yahoo.ca', 'yahoo.co.uk', 'yahoo.com', 'yahoo.de', 'yahoo.fr', 'yahoo.in', 'yahoo.it', 'ymail.com']; // List of domains used by yandex.ru
1915
1916var yandex_domains = ['yandex.ru', 'yandex.ua', 'yandex.kz', 'yandex.com', 'yandex.by', 'ya.ru']; // replace single dots, but not multiple consecutive dots
1917
1918function dotsReplacer(match) {
1919 if (match.length > 1) {
1920 return match;
1921 }
1922
1923 return '';
1924}
1925
1926function normalizeEmail(email, options) {
1927 options = merge(options, default_normalize_email_options);
1928 var raw_parts = email.split('@');
1929 var domain = raw_parts.pop();
1930 var user = raw_parts.join('@');
1931 var parts = [user, domain]; // The domain is always lowercased, as it's case-insensitive per RFC 1035
1932
1933 parts[1] = parts[1].toLowerCase();
1934
1935 if (parts[1] === 'gmail.com' || parts[1] === 'googlemail.com') {
1936 // Address is GMail
1937 if (options.gmail_remove_subaddress) {
1938 parts[0] = parts[0].split('+')[0];
1939 }
1940
1941 if (options.gmail_remove_dots) {
1942 // this does not replace consecutive dots like example..email@gmail.com
1943 parts[0] = parts[0].replace(/\.+/g, dotsReplacer);
1944 }
1945
1946 if (!parts[0].length) {
1947 return false;
1948 }
1949
1950 if (options.all_lowercase || options.gmail_lowercase) {
1951 parts[0] = parts[0].toLowerCase();
1952 }
1953
1954 parts[1] = options.gmail_convert_googlemaildotcom ? 'gmail.com' : parts[1];
1955 } else if (icloud_domains.indexOf(parts[1]) >= 0) {
1956 // Address is iCloud
1957 if (options.icloud_remove_subaddress) {
1958 parts[0] = parts[0].split('+')[0];
1959 }
1960
1961 if (!parts[0].length) {
1962 return false;
1963 }
1964
1965 if (options.all_lowercase || options.icloud_lowercase) {
1966 parts[0] = parts[0].toLowerCase();
1967 }
1968 } else if (outlookdotcom_domains.indexOf(parts[1]) >= 0) {
1969 // Address is Outlook.com
1970 if (options.outlookdotcom_remove_subaddress) {
1971 parts[0] = parts[0].split('+')[0];
1972 }
1973
1974 if (!parts[0].length) {
1975 return false;
1976 }
1977
1978 if (options.all_lowercase || options.outlookdotcom_lowercase) {
1979 parts[0] = parts[0].toLowerCase();
1980 }
1981 } else if (yahoo_domains.indexOf(parts[1]) >= 0) {
1982 // Address is Yahoo
1983 if (options.yahoo_remove_subaddress) {
1984 var components = parts[0].split('-');
1985 parts[0] = components.length > 1 ? components.slice(0, -1).join('-') : components[0];
1986 }
1987
1988 if (!parts[0].length) {
1989 return false;
1990 }
1991
1992 if (options.all_lowercase || options.yahoo_lowercase) {
1993 parts[0] = parts[0].toLowerCase();
1994 }
1995 } else if (yandex_domains.indexOf(parts[1]) >= 0) {
1996 if (options.all_lowercase || options.yandex_lowercase) {
1997 parts[0] = parts[0].toLowerCase();
1998 }
1999
2000 parts[1] = 'yandex.ru'; // all yandex domains are equal, 1st preffered
2001 } else if (options.all_lowercase) {
2002 // Any other address
2003 parts[0] = parts[0].toLowerCase();
2004 }
2005
2006 return parts.join('@');
2007}
2008
2009var version = '10.9.0';
2010var validator = {
2011 version: version,
2012 toDate: toDate,
2013 toFloat: toFloat,
2014 toInt: toInt,
2015 toBoolean: toBoolean,
2016 equals: equals,
2017 contains: contains,
2018 matches: matches,
2019 isEmail: isEmail,
2020 isURL: isURL,
2021 isMACAddress: isMACAddress,
2022 isIP: isIP,
2023 isIPRange: isIPRange,
2024 isFQDN: isFQDN,
2025 isBoolean: isBoolean,
2026 isAlpha: isAlpha,
2027 isAlphaLocales: locales,
2028 isAlphanumeric: isAlphanumeric,
2029 isAlphanumericLocales: locales$1,
2030 isNumeric: isNumeric,
2031 isPort: isPort,
2032 isLowercase: isLowercase,
2033 isUppercase: isUppercase,
2034 isAscii: isAscii,
2035 isFullWidth: isFullWidth,
2036 isHalfWidth: isHalfWidth,
2037 isVariableWidth: isVariableWidth,
2038 isMultibyte: isMultibyte,
2039 isSurrogatePair: isSurrogatePair,
2040 isInt: isInt,
2041 isFloat: isFloat,
2042 isFloatLocales: locales$2,
2043 isDecimal: isDecimal,
2044 isHexadecimal: isHexadecimal,
2045 isDivisibleBy: isDivisibleBy,
2046 isHexColor: isHexColor,
2047 isISRC: isISRC,
2048 isMD5: isMD5,
2049 isHash: isHash,
2050 isJWT: isJWT,
2051 isJSON: isJSON,
2052 isEmpty: isEmpty,
2053 isLength: isLength,
2054 isByteLength: isByteLength,
2055 isUUID: isUUID,
2056 isMongoId: isMongoId,
2057 isAfter: isAfter,
2058 isBefore: isBefore,
2059 isIn: isIn,
2060 isCreditCard: isCreditCard,
2061 isIdentityCard: isIdentityCard,
2062 isISIN: isISIN,
2063 isISBN: isISBN,
2064 isISSN: isISSN,
2065 isMobilePhone: isMobilePhone,
2066 isMobilePhoneLocales: locales$3,
2067 isPostalCode: isPostalCode,
2068 isPostalCodeLocales: locales$4,
2069 isCurrency: isCurrency,
2070 isISO8601: isISO8601,
2071 isRFC3339: isRFC3339,
2072 isISO31661Alpha2: isISO31661Alpha2,
2073 isISO31661Alpha3: isISO31661Alpha3,
2074 isBase64: isBase64,
2075 isDataURI: isDataURI,
2076 isMagnetURI: isMagnetURI,
2077 isMimeType: isMimeType,
2078 isLatLong: isLatLong,
2079 ltrim: ltrim,
2080 rtrim: rtrim,
2081 trim: trim,
2082 escape: escape,
2083 unescape: unescape,
2084 stripLow: stripLow,
2085 whitelist: whitelist,
2086 blacklist: blacklist$1,
2087 isWhitelisted: isWhitelisted,
2088 normalizeEmail: normalizeEmail,
2089 toString: toString
2090};
2091
2092return validator;
2093
2094})));