PageSourceSearch

https://mairie-savigny69.fr/typo3conf/ext/e_magineurs/themes/Resources/Public/JavaScript/parsley.js?1790844362

js mairie-savigny69.fr collected 2026-10-02 16:47:48 UTC 86,753 bytes, 2,462 lines download raw bytes

1/*!
2 * Parsley.js
3 * Version 2.7.2 - built Tue, May 9th 2017, 11:21 am
4 * http://parsleyjs.org
5 * Guillaume Potier - <[email protected]>
6 * Marc-Andre Lafortune - <[email protected]>
7 * MIT Licensed
8 */
9
10// The source code below is generated by babel as
11// Parsley is written in ECMAScript 6
12//
13var _slice = Array.prototype.slice;
14
15var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();
16
17var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
18
19function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }
20
21(function (global, factory) {
22	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery')) : typeof define === 'function' && define.amd ? define(['jquery'], factory) : global.parsley = factory(global.jQuery);
23})(this, function ($) {
24	'use strict';
25
26	var globalID = 1;
27	var pastWarnings = {};
28
29	var Utils = {
30		// Parsley DOM-API
31		// returns object from dom attributes and values
32		attr: function attr(element, namespace, obj) {
33			var i;
34			var attribute;
35			var attributes;
36			var regex = new RegExp('^' + namespace, 'i');
37
38			if ('undefined' === typeof obj) obj = {};else {
39				// Clear all own properties. This won't affect prototype's values
40				for (i in obj) {
41					if (obj.hasOwnProperty(i)) delete obj[i];
42				}
43			}
44
45			if (!element) return obj;
46
47			attributes = element.attributes;
48			for (i = attributes.length; i--;) {
49				attribute = attributes[i];
50
51				if (attribute && attribute.specified && regex.test(attribute.name)) {
52					obj[this.camelize(attribute.name.slice(namespace.length))] = this.deserializeValue(attribute.value);
53				}
54			}
55
56			return obj;
57		},
58
59		checkAttr: function checkAttr(element, namespace, _checkAttr) {
60			return element.hasAttribute(namespace + _checkAttr);
61		},
62
63		setAttr: function setAttr(element, namespace, attr, value) {
64			element.setAttribute(this.dasherize(namespace + attr), String(value));
65		},
66
67		generateID: function generateID() {
68			return '' + globalID++;
69		},
70
71		/** Third party functions **/
72		// Zepto deserialize function
73		deserializeValue: function deserializeValue(value) {
74			var num;
75
76			try {
77				return value ? value == "true" || (value == "false" ? false : value == "null" ? null : !isNaN(num = Number(value)) ? num : /^[\[\{]/.test(value) ? $.parseJSON(value) : value) : value;
78			} catch (e) {
79				return value;
80			}
81		},
82
83		// Zepto camelize function
84		camelize: function camelize(str) {
85			return str.replace(/-+(.)?/g, function (match, chr) {
86				return chr ? chr.toUpperCase() : '';
87			});
88		},
89
90		// Zepto dasherize function
91		dasherize: function dasherize(str) {
92			return str.replace(/::/g, '/').replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2').replace(/([a-z\d])([A-Z])/g, '$1_$2').replace(/_/g, '-').toLowerCase();
93		},
94
95		warn: function warn() {
96			var _window$console;
97
98			if (window.console && 'function' === typeof window.console.warn) (_window$console = window.console).warn.apply(_window$console, arguments);
99		},
100
101		warnOnce: function warnOnce(msg) {
102			if (!pastWarnings[msg]) {
103				pastWarnings[msg] = true;
104				this.warn.apply(this, arguments);
105			}
106		},
107
108		_resetWarnings: function _resetWarnings() {
109			pastWarnings = {};
110		},
111
112		trimString: function trimString(string) {
113			return string.replace(/^\s+|\s+$/g, '');
114		},
115
116		parse: {
117			date: function date(string) {
118				var parsed = string.match(/^(\d{4,})-(\d\d)-(\d\d)$/);
119				if (!parsed) return null;
120
121				var _parsed$map = parsed.map(function (x) {
122					return parseInt(x, 10);
123				});
124
125				var _parsed$map2 = _slicedToArray(_parsed$map, 4);
126
127				var _ = _parsed$map2[0];
128				var year = _parsed$map2[1];
vendor: 18,150 bytes, lines 129-637
129				var month = _parsed$map2[2];
130				var day = _parsed$map2[3];
131
132				var date = new Date(year, month - 1, day);
133				if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) return null;
134				return date;
135			},
136			string: function string(_string) {
137				return _string;
138			},
139			integer: function integer(string) {
140				if (isNaN(string)) return null;
141				return parseInt(string, 10);
142			},
143			number: function number(string) {
144				if (isNaN(string)) throw null;
145				return parseFloat(string);
146			},
147			'boolean': function _boolean(string) {
148				return !/^\s*false\s*$/i.test(string);
149			},
150			object: function object(string) {
151				return Utils.deserializeValue(string);
152			},
153			regexp: function regexp(_regexp) {
154				var flags = '';
155
156				// Test if RegExp is literal, if not, nothing to be done, otherwise, we need to isolate flags and pattern
157				if (/^\/.*\/(?:[gimy]*)$/.test(_regexp)) {
158					// Replace the regexp literal string with the first match group: ([gimy]*)
159					// If no flag is present, this will be a blank string
160					flags = _regexp.replace(/.*\/([gimy]*)$/, '$1');
161					// Again, replace the regexp literal string with the first match group:
162					// everything excluding the opening and closing slashes and the flags
163					_regexp = _regexp.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1');
164				} else {
165					// Anchor regexp:
166					_regexp = '^' + _regexp + '$';
167				}
168				return new RegExp(_regexp, flags);
169			}
170		},
171
172		parseRequirement: function parseRequirement(requirementType, string) {
173			var converter = this.parse[requirementType || 'string'];
174			if (!converter) throw 'Unknown requirement specification: "' + requirementType + '"';
175			var converted = converter(string);
176			if (converted === null) throw 'Requirement is not a ' + requirementType + ': "' + string + '"';
177			return converted;
178		},
179
180		namespaceEvents: function namespaceEvents(events, namespace) {
181			events = this.trimString(events || '').split(/\s+/);
182			if (!events[0]) return '';
183			return $.map(events, function (evt) {
184				return evt + '.' + namespace;
185			}).join(' ');
186		},
187
188		difference: function difference(array, remove) {
189			// This is O(N^2), should be optimized
190			var result = [];
191			$.each(array, function (_, elem) {
192				if (remove.indexOf(elem) == -1) result.push(elem);
193			});
194			return result;
195		},
196
197		// Alter-ego to native Promise.all, but for jQuery
198		all: function all(promises) {
199			// jQuery treats $.when() and $.when(singlePromise) differently; let's avoid that and add spurious elements
200			return $.when.apply($, _toConsumableArray(promises).concat([42, 42]));
201		},
202
203		// Object.create polyfill, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create#Polyfill
204		objectCreate: Object.create || (function () {
205			var Object = function Object() {};
206			return function (prototype) {
207				if (arguments.length > 1) {
208					throw Error('Second argument not supported');
209				}
210				if (typeof prototype != 'object') {
211					throw TypeError('Argument must be an object');
212				}
213				Object.prototype = prototype;
214				var result = new Object();
215				Object.prototype = null;
216				return result;
217			};
218		})(),
219
220		_SubmitSelector: 'input[type="submit"], button:submit'
221	};
222
223	// All these options could be overriden and specified directly in DOM using
224	// `data-parsley-` default DOM-API
225	// eg: `inputs` can be set in DOM using `data-parsley-inputs="input, textarea"`
226	// eg: `data-parsley-stop-on-first-failing-constraint="false"`
227
228	var Defaults = {
229		// ### General
230
231		// Default data-namespace for DOM API
232		namespace: 'data-parsley-',
233
234		// Supported inputs by default
235		inputs: 'input, textarea, select',
236
237		// Excluded inputs by default
238		excluded: 'input[type=button], input[type=submit], input[type=reset], input[type=hidden]',
239
240		// Stop validating field on highest priority failing constraint
241		priorityEnabled: true,
242
243		// ### Field only
244
245		// identifier used to group together inputs (e.g. radio buttons...)
246		multiple: null,
247
248		// identifier (or array of identifiers) used to validate only a select group of inputs
249		group: null,
250
251		// ### UI
252		// Enable\Disable error messages
253		uiEnabled: true,
254
255		// Key events threshold before validation
256		validationThreshold: 3,
257
258		// Focused field on form validation error. 'first'|'last'|'none'
259		focus: 'first',
260
261		// event(s) that will trigger validation before first failure. eg: `input`...
262		trigger: false,
263
264		// event(s) that will trigger validation after first failure.
265		triggerAfterFailure: 'input',
266
267		// Class that would be added on every failing validation Parsley field
268		errorClass: 'parsley-error',
269
270		// Same for success validation
271		successClass: 'parsley-success',
272
273		// Return the `$element` that will receive these above success or error classes
274		// Could also be (and given directly from DOM) a valid selector like `'#div'`
275		classHandler: function classHandler(Field) {},
276
277		// Return the `$element` where errors will be appended
278		// Could also be (and given directly from DOM) a valid selector like `'#div'`
279		errorsContainer: function errorsContainer(Field) {},
280
281		// ul elem that would receive errors' list
282		errorsWrapper: '<ul class="parsley-errors-list"></ul>',
283
284		// li elem that would receive error message
285		errorTemplate: '<li></li>'
286	};
287
288	var Base = function Base() {
289		this.__id__ = Utils.generateID();
290	};
291
292	Base.prototype = {
293		asyncSupport: true, // Deprecated
294
295		_pipeAccordingToValidationResult: function _pipeAccordingToValidationResult() {
296			var _this = this;
297
298			var pipe = function pipe() {
299				var r = $.Deferred();
300				if (true !== _this.validationResult) r.reject();
301				return r.resolve().promise();
302			};
303			return [pipe, pipe];
304		},
305
306		actualizeOptions: function actualizeOptions() {
307			Utils.attr(this.element, this.options.namespace, this.domOptions);
308			if (this.parent && this.parent.actualizeOptions) this.parent.actualizeOptions();
309			return this;
310		},
311
312		_resetOptions: function _resetOptions(initOptions) {
313			this.domOptions = Utils.objectCreate(this.parent.options);
314			this.options = Utils.objectCreate(this.domOptions);
315			// Shallow copy of ownProperties of initOptions:
316			for (var i in initOptions) {
317				if (initOptions.hasOwnProperty(i)) this.options[i] = initOptions[i];
318			}
319			this.actualizeOptions();
320		},
321
322		_listeners: null,
323
324		// Register a callback for the given event name
325		// Callback is called with context as the first argument and the `this`
326		// The context is the current parsley instance, or window.Parsley if global
327		// A return value of `false` will interrupt the calls
328		on: function on(name, fn) {
329			this._listeners = this._listeners || {};
330			var queue = this._listeners[name] = this._listeners[name] || [];
331			queue.push(fn);
332
333			return this;
334		},
335
336		// Deprecated. Use `on` instead
337		subscribe: function subscribe(name, fn) {
338			$.listenTo(this, name.toLowerCase(), fn);
339		},
340
341		// Unregister a callback (or all if none is given) for the given event name
342		off: function off(name, fn) {
343			var queue = this._listeners && this._listeners[name];
344			if (queue) {
345				if (!fn) {
346					delete this._listeners[name];
347				} else {
348					for (var i = queue.length; i--;) if (queue[i] === fn) queue.splice(i, 1);
349				}
350			}
351			return this;
352		},
353
354		// Deprecated. Use `off`
355		unsubscribe: function unsubscribe(name, fn) {
356			$.unsubscribeTo(this, name.toLowerCase());
357		},
358
359		// Trigger an event of the given name
360		// A return value of `false` interrupts the callback chain
361		// Returns false if execution was interrupted
362		trigger: function trigger(name, target, extraArg) {
363			target = target || this;
364			var queue = this._listeners && this._listeners[name];
365			var result;
366			var parentResult;
367			if (queue) {
368				for (var i = queue.length; i--;) {
369					result = queue[i].call(target, target, extraArg);
370					if (result === false) return result;
371				}
372			}
373			if (this.parent) {
374				return this.parent.trigger(name, target, extraArg);
375			}
376			return true;
377		},
378
379		asyncIsValid: function asyncIsValid(group, force) {
380			Utils.warnOnce("asyncIsValid is deprecated; please use whenValid instead");
381			return this.whenValid({ group: group, force: force });
382		},
383
384		_findRelated: function _findRelated() {
385			return this.options.multiple ? $(this.parent.element.querySelectorAll('[' + this.options.namespace + 'multiple="' + this.options.multiple + '"]')) : this.$element;
386		}
387	};
388
389	var convertArrayRequirement = function convertArrayRequirement(string, length) {
390		var m = string.match(/^\s*\[(.*)\]\s*$/);
391		if (!m) throw 'Requirement is not an array: "' + string + '"';
392		var values = m[1].split(',').map(Utils.trimString);
393		if (values.length !== length) throw 'Requirement has ' + values.length + ' values when ' + length + ' are needed';
394		return values;
395	};
396
397	var convertExtraOptionRequirement = function convertExtraOptionRequirement(requirementSpec, string, extraOptionReader) {
398		var main = null;
399		var extra = {};
400		for (var key in requirementSpec) {
401			if (key) {
402				var value = extraOptionReader(key);
403				if ('string' === typeof value) value = Utils.parseRequirement(requirementSpec[key], value);
404				extra[key] = value;
405			} else {
406				main = Utils.parseRequirement(requirementSpec[key], string);
407			}
408		}
409		return [main, extra];
410	};
411
412	// A Validator needs to implement the methods `validate` and `parseRequirements`
413
414	var Validator = function Validator(spec) {
415		$.extend(true, this, spec);
416	};
417
418	Validator.prototype = {
419		// Returns `true` iff the given `value` is valid according the given requirements.
420		validate: function validate(value, requirementFirstArg) {
421			if (this.fn) {
422				// Legacy style validator
423
424				if (arguments.length > 3) // If more args then value, requirement, instance...
425					requirementFirstArg = [].slice.call(arguments, 1, -1); // Skip first arg (value) and last (instance), combining the rest
426				return this.fn(value, requirementFirstArg);
427			}
428
429			if (Array.isArray(value)) {
430				if (!this.validateMultiple) throw 'Validator `' + this.name + '` does not handle multiple values';
431				return this.validateMultiple.apply(this, arguments);
432			} else {
433				var instance = arguments[arguments.length - 1];
434				if (this.validateDate && instance._isDateInput()) {
435					arguments[0] = Utils.parse.date(arguments[0]);
436					if (arguments[0] === null) return false;
437					return this.validateDate.apply(this, arguments);
438				}
439				if (this.validateNumber) {
440					if (isNaN(value)) return false;
441					arguments[0] = parseFloat(arguments[0]);
442					return this.validateNumber.apply(this, arguments);
443				}
444				if (this.validateString) {
445					return this.validateString.apply(this, arguments);
446				}
447				throw 'Validator `' + this.name + '` only handles multiple values';
448			}
449		},
450
451		// Parses `requirements` into an array of arguments,
452		// according to `this.requirementType`
453		parseRequirements: function parseRequirements(requirements, extraOptionReader) {
454			if ('string' !== typeof requirements) {
455				// Assume requirement already parsed
456				// but make sure we return an array
457				return Array.isArray(requirements) ? requirements : [requirements];
458			}
459			var type = this.requirementType;
460			if (Array.isArray(type)) {
461				var values = convertArrayRequirement(requirements, type.length);
462				for (var i = 0; i < values.length; i++) values[i] = Utils.parseRequirement(type[i], values[i]);
463				return values;
464			} else if ($.isPlainObject(type)) {
465				return convertExtraOptionRequirement(type, requirements, extraOptionReader);
466			} else {
467				return [Utils.parseRequirement(type, requirements)];
468			}
469		},
470		// Defaults:
471		requirementType: 'string',
472
473		priority: 2
474
475	};
476
477	var ValidatorRegistry = function ValidatorRegistry(validators, catalog) {
478		this.__class__ = 'ValidatorRegistry';
479
480		// Default Parsley locale is en
481		this.locale = 'en';
482
483		this.init(validators || {}, catalog || {});
484	};
485
486	var typeTesters = {
487		email: /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\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]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,
488
489		// Follow https://www.w3.org/TR/html5/infrastructure.html#floating-point-numbers
490		number: /^-?(\d*\.)?\d+(e[-+]?\d+)?$/i,
491
492		integer: /^-?\d+$/,
493
494		digits: /^\d+$/,
495
496		alphanum: /^\w+$/i,
497
498		date: {
499			test: function test(value) {
500				return Utils.parse.date(value) !== null;
501			}
502		},
503
504		url: new RegExp("^" +
505			// protocol identifier
506			"(?:(?:https?|ftp)://)?" + // ** mod: make scheme optional
507			// user:pass authentication
508			"(?:\\S+(?::\\S*)?@)?" + "(?:" +
509			// IP address exclusion
510			// private & local networks
511			// "(?!(?:10|127)(?:\\.\\d{1,3}){3})" +   // ** mod: allow local networks
512			// "(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" +  // ** mod: allow local networks
513			// "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" +  // ** mod: allow local networks
514			// IP address dotted notation octets
515			// excludes loopback network 0.0.0.0
516			// excludes reserved space >= 224.0.0.0
517			// excludes network & broacast addresses
518			// (first & last IP address of each class)
519			"(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" + "(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" + "(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" + "|" +
520			// host name
521			'(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)' +
522			// domain name
523			'(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*' +
524			// TLD identifier
525			'(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))' + ")" +
526			// port number
527			"(?::\\d{2,5})?" +
528			// resource path
529			"(?:/\\S*)?" + "$", 'i')
530	};
531	typeTesters.range = typeTesters.number;
532
533	// See http://stackoverflow.com/a/10454560/8279
534	var decimalPlaces = function decimalPlaces(num) {
535		var match = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
536		if (!match) {
537			return 0;
538		}
539		return Math.max(0,
540			// Number of digits right of decimal point.
541			(match[1] ? match[1].length : 0) - (
542				// Adjust for scientific notation.
543				match[2] ? +match[2] : 0));
544	};
545
546	// parseArguments('number', ['1', '2']) => [1, 2]
547	var ValidatorRegistry__parseArguments = function ValidatorRegistry__parseArguments(type, args) {
548		return args.map(Utils.parse[type]);
549	};
550	// operatorToValidator returns a validating function for an operator function, applied to the given type
551	var ValidatorRegistry__operatorToValidator = function ValidatorRegistry__operatorToValidator(type, operator) {
552		return function (value) {
553			for (var _len = arguments.length, requirementsAndInput = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
554				requirementsAndInput[_key - 1] = arguments[_key];
555			}
556
557			requirementsAndInput.pop(); // Get rid of `input` argument
558			return operator.apply(undefined, [value].concat(_toConsumableArray(ValidatorRegistry__parseArguments(type, requirementsAndInput))));
559		};
560	};
561
562	var ValidatorRegistry__comparisonOperator = function ValidatorRegistry__comparisonOperator(operator) {
563		return {
564			validateDate: ValidatorRegistry__operatorToValidator('date', operator),
565			validateNumber: ValidatorRegistry__operatorToValidator('number', operator),
566			requirementType: operator.length <= 2 ? 'string' : ['string', 'string'], // Support operators with a 1 or 2 requirement(s)
567			priority: 30
568		};
569	};
570
571	ValidatorRegistry.prototype = {
572		init: function init(validators, catalog) {
573			this.catalog = catalog;
574			// Copy prototype's validators:
575			this.validators = _extends({}, this.validators);
576
577			for (var name in validators) this.addValidator(name, validators[name].fn, validators[name].priority);
578
579			window.Parsley.trigger('parsley:validator:init');
580		},
581
582		// Set new messages locale if we have dictionary loaded in ParsleyConfig.i18n
583		setLocale: function setLocale(locale) {
584			if ('undefined' === typeof this.catalog[locale]) throw new Error(locale + ' is not available in the catalog');
585
586			this.locale = locale;
587
588			return this;
589		},
590
591		// Add a new messages catalog for a given locale. Set locale for this catalog if set === `true`
592		addCatalog: function addCatalog(locale, messages, set) {
593			if ('object' === typeof messages) this.catalog[locale] = messages;
594
595			if (true === set) return this.setLocale(locale);
596
597			return this;
598		},
599
600		// Add a specific message for a given constraint in a given locale
601		addMessage: function addMessage(locale, name, message) {
602			if ('undefined' === typeof this.catalog[locale]) this.catalog[locale] = {};
603
604			this.catalog[locale][name] = message;
605
606			return this;
607		},
608
609		// Add messages for a given locale
610		addMessages: function addMessages(locale, nameMessageObject) {
611			for (var name in nameMessageObject) this.addMessage(locale, name, nameMessageObject[name]);
612
613			return this;
614		},
615
616		// Add a new validator
617		//
618		//    addValidator('custom', {
619		//        requirementType: ['integer', 'integer'],
620		//        validateString: function(value, from, to) {},
621		//        priority: 22,
622		//        messages: {
623		//          en: "Hey, that's no good",
624		//          fr: "Aye aye, pas bon du tout",
625		//        }
626		//    })
627		//
628		// Old API was addValidator(name, function, priority)
629		//
630		addValidator: function addValidator(name, arg1, arg2) {
631			if (this.validators[name]) Utils.warn('Validator "' + name + '" is already defined.');else if (Defaults.hasOwnProperty(name)) {
632				Utils.warn('"' + name + '" is a restricted keyword and is not a valid validator name.');
633				return;
634			}
635			return this._setValidator.apply(this, arguments);
636		},
637
638		updateValidator: function updateValidator(name, arg1, arg2) {
639			if (!this.validators[name]) {
640				Utils.warn('Validator "' + name + '" is not already defined.');
641				return this.addValidator.apply(this, arguments);
642			}
643			return this._setValidator.apply(this, arguments);
644		},
645
646		removeValidator: function removeValidator(name) {
647			if (!this.validators[name]) Utils.warn('Validator "' + name + '" is not defined.');
648
649			delete this.validators[name];
650
651			return this;
652		},
653
654		_setValidator: function _setValidator(name, validator, priority) {
655			if ('object' !== typeof validator) {
656				// Old style validator, with `fn` and `priority`
657				validator = {
658					fn: validator,
659					priority: priority
660				};
661			}
662			if (!validator.validate) {
663				validator = new Validator(validator);
664			}
665			this.validators[name] = validator;
666
667			for (var locale in validator.messages || {}) this.addMessage(locale, name, validator.messages[locale]);
668
669			return this;
670		},
671
672		getErrorMessage: function getErrorMessage(constraint) {
673			var message;
674
675			// Type constraints are a bit different, we have to match their requirements too to find right error message
676			if ('type' === constraint.name) {
677				var typeMessages = this.catalog[this.locale][constraint.name] || {};
678				message = typeMessages[constraint.requirements];
679			} else message = this.formatMessage(this.catalog[this.locale][constraint.name], constraint.requirements);
680
681			return message || this.catalog[this.locale].defaultMessage || this.catalog.en.defaultMessage;
682		},
683
684		// Kind of light `sprintf()` implementation
685		formatMessage: function formatMessage(string, parameters) {
686			if ('object' === typeof parameters) {
687				for (var i in parameters) string = this.formatMessage(string, parameters[i]);
688
689				return string;
690			}
691
692			return 'string' === typeof string ? string.replace(/%s/i, parameters) : '';
693		},
694
695		// Here is the Parsley default validators list.
696		// A validator is an object with the following key values:
697		//  - priority: an integer
698		//  - requirement: 'string' (default), 'integer', 'number', 'regexp' or an Array of these
699		//  - validateString, validateMultiple, validateNumber: functions returning `true`, `false` or a promise
700		// Alternatively, a validator can be a function that returns such an object
701		//
702		validators: {
703			notblank: {
704				validateString: function validateString(value) {
705					return (/\S/.test(value)
706					);
707				},
708				priority: 2
709			},
710			required: {
711				validateMultiple: function validateMultiple(values) {
712					return values.length > 0;
713				},
714				validateString: function validateString(value) {
715					return (/\S/.test(value)
716					);
717				},
718				priority: 512
719			},
720			type: {
721				validateString: function validateString(value, type) {
722					var _ref = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
723
724					var _ref$step = _ref.step;
725					var step = _ref$step === undefined ? 'any' : _ref$step;
726					var _ref$base = _ref.base;
727					var base = _ref$base === undefined ? 0 : _ref$base;
728
729					var tester = typeTesters[type];
730					if (!tester) {
731						throw new Error('validator type `' + type + '` is not supported');
732					}
733					if (!tester.test(value)) return false;
734					if ('number' === type) {
735						if (!/^any$/i.test(step || '')) {
736							var nb = Number(value);
737							var decimals = Math.max(decimalPlaces(step), decimalPlaces(base));
738							if (decimalPlaces(nb) > decimals) // Value can't have too many decimals
739								return false;
740							// Be careful of rounding errors by using integers.
741							var toInt = function toInt(f) {
742								return Math.round(f * Math.pow(10, decimals));
743							};
744							if ((toInt(nb) - toInt(base)) % toInt(step) != 0) return false;
745						}
746					}
747					return true;
748				},
749				requirementType: {
750					'': 'string',
751					step: 'string',
752					base: 'number'
753				},
754				priority: 256
755			},
756			pattern: {
757				validateString: function validateString(value, regexp) {
758					return regexp.test(value);
759				},
760				requirementType: 'regexp',
761				priority: 64
762			},
763			minlength: {
764				validateString: function validateString(value, requirement) {
765					return value.length >= requirement;
766				},
767				requirementType: 'integer',
768				priority: 30
769			},
770			maxlength: {
771				validateString: function validateString(value, requirement) {
772					return value.length <= requirement;
773				},
774				requirementType: 'integer',
775				priority: 30
776			},
777			length: {
778				validateString: function validateString(value, min, max) {
779					return value.length >= min && value.length <= max;
780				},
781				requirementType: ['integer', 'integer'],
782				priority: 30
783			},
784			mincheck: {
785				validateMultiple: function validateMultiple(values, requirement) {
786					return values.length >= requirement;
787				},
788				requirementType: 'integer',
789				priority: 30
790			},
791			maxcheck: {
792				validateMultiple: function validateMultiple(values, requirement) {
793					return values.length <= requirement;
794				},
795				requirementType: 'integer',
796				priority: 30
797			},
798			check: {
799				validateMultiple: function validateMultiple(values, min, max) {
800					return values.length >= min && values.length <= max;
801				},
802				requirementType: ['integer', 'integer'],
803				priority: 30
804			},
805			min: ValidatorRegistry__comparisonOperator(function (value, requirement) {
806				return value >= requirement;
807			}),
808			max: ValidatorRegistry__comparisonOperator(function (value, requirement) {
809				return value <= requirement;
810			}),
811			range: ValidatorRegistry__comparisonOperator(function (value, min, max) {
812				return value >= min && value <= max;
813			}),
814			equalto: {
815				validateString: function validateString(value, refOrValue) {
816					var $reference = $(refOrValue);
817					if ($reference.length) return value === $reference.val();else return value === refOrValue;
818				},
819				priority: 256
820			}
821		}
822	};
823
824	var UI = {};
825
826	var diffResults = function diffResults(newResult, oldResult, deep) {
827		var added = [];
828		var kept = [];
829
830		for (var i = 0; i < newResult.length; i++) {
831			var found = false;
vendor: 6,277 bytes, lines 832-1010
832
833			for (var j = 0; j < oldResult.length; j++) if (newResult[i].assert.name === oldResult[j].assert.name) {
834				found = true;
835				break;
836			}
837
838			if (found) kept.push(newResult[i]);else added.push(newResult[i]);
839		}
840
841		return {
842			kept: kept,
843			added: added,
844			removed: !deep ? diffResults(oldResult, newResult, true).added : []
845		};
846	};
847
848	UI.Form = {
849
850		_actualizeTriggers: function _actualizeTriggers() {
851			var _this2 = this;
852
853			this.$element.on('submit.Parsley', function (evt) {
854				_this2.onSubmitValidate(evt);
855			});
856			this.$element.on('click.Parsley', Utils._SubmitSelector, function (evt) {
857				_this2.onSubmitButton(evt);
858			});
859
860			// UI could be disabled
861			if (false === this.options.uiEnabled) return;
862
863			this.element.setAttribute('novalidate', '');
864		},
865
866		focus: function focus() {
867			this._focusedField = null;
868
869			if (true === this.validationResult || 'none' === this.options.focus) return null;
870
871			for (var i = 0; i < this.fields.length; i++) {
872				var field = this.fields[i];
873				if (true !== field.validationResult && field.validationResult.length > 0 && 'undefined' === typeof field.options.noFocus) {
874					this._focusedField = field.$element;
875					if ('first' === this.options.focus) break;
876				}
877			}
878
879			if (null === this._focusedField) return null;
880
881			return this._focusedField.focus();
882		},
883
884		_destroyUI: function _destroyUI() {
885			// Reset all event listeners
886			this.$element.off('.Parsley');
887		}
888
889	};
890
891	UI.Field = {
892
893		_reflowUI: function _reflowUI() {
894			this._buildUI();
895
896			// If this field doesn't have an active UI don't bother doing something
897			if (!this._ui) return;
898
899			// Diff between two validation results
900			var diff = diffResults(this.validationResult, this._ui.lastValidationResult);
901
902			// Then store current validation result for next reflow
903			this._ui.lastValidationResult = this.validationResult;
904
905			// Handle valid / invalid / none field class
906			this._manageStatusClass();
907
908			// Add, remove, updated errors messages
909			this._manageErrorsMessages(diff);
910
911			// Triggers impl
912			this._actualizeTriggers();
913
914			// If field is not valid for the first time, bind keyup trigger to ease UX and quickly inform user
915			if ((diff.kept.length || diff.added.length) && !this._failedOnce) {
916				this._failedOnce = true;
917				this._actualizeTriggers();
918			}
919		},
920
921		// Returns an array of field's error message(s)
922		getErrorsMessages: function getErrorsMessages() {
923			// No error message, field is valid
924			if (true === this.validationResult) return [];
925
926			var messages = [];
927
928			for (var i = 0; i < this.validationResult.length; i++) messages.push(this.validationResult[i].errorMessage || this._getErrorMessage(this.validationResult[i].assert));
929
930			return messages;
931		},
932
933		// It's a goal of Parsley that this method is no longer required [#1073]
934		addError: function addError(name) {
935			var _ref2 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
936
937			var message = _ref2.message;
938			var assert = _ref2.assert;
939			var _ref2$updateClass = _ref2.updateClass;
940			var updateClass = _ref2$updateClass === undefined ? true : _ref2$updateClass;
941
942			this._buildUI();
943			this._addError(name, { message: message, assert: assert });
944
945			if (updateClass) this._errorClass();
946		},
947
948		// It's a goal of Parsley that this method is no longer required [#1073]
949		updateError: function updateError(name) {
950			var _ref3 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
951
952			var message = _ref3.message;
953			var assert = _ref3.assert;
954			var _ref3$updateClass = _ref3.updateClass;
955			var updateClass = _ref3$updateClass === undefined ? true : _ref3$updateClass;
956
957			this._buildUI();
958			this._updateError(name, { message: message, assert: assert });
959
960			if (updateClass) this._errorClass();
961		},
962
963		// It's a goal of Parsley that this method is no longer required [#1073]
964		removeError: function removeError(name) {
965			var _ref4 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
966
967			var _ref4$updateClass = _ref4.updateClass;
968			var updateClass = _ref4$updateClass === undefined ? true : _ref4$updateClass;
969
970			this._buildUI();
971			this._removeError(name);
972
973			// edge case possible here: remove a standard Parsley error that is still failing in this.validationResult
974			// but highly improbable cuz' manually removing a well Parsley handled error makes no sense.
975			if (updateClass) this._manageStatusClass();
976		},
977
978		_manageStatusClass: function _manageStatusClass() {
979			if (this.hasConstraints() && this.needsValidation() && true === this.validationResult) this._successClass();else if (this.validationResult.length > 0) this._errorClass();else this._resetClass();
980		},
981
982		_manageErrorsMessages: function _manageErrorsMessages(diff) {
983			if ('undefined' !== typeof this.options.errorsMessagesDisabled) return;
984
985			// Case where we have errorMessage option that configure an unique field error message, regardless failing validators
986			if ('undefined' !== typeof this.options.errorMessage) {
987				if (diff.added.length || diff.kept.length) {
988					this._insertErrorWrapper();
989
990					if (0 === this._ui.$errorsWrapper.find('.parsley-custom-error-message').length) this._ui.$errorsWrapper.append($(this.options.errorTemplate).addClass('parsley-custom-error-message'));
991
992					return this._ui.$errorsWrapper.addClass('filled').find('.parsley-custom-error-message').html(this.options.errorMessage);
993				}
994				return this._ui.$errorsWrapper.removeClass('filled').find('.parsley-custom-error-message').remove();
995			}
996
997			// Show, hide, update failing constraints messages
998			for (var i = 0; i < diff.removed.length; i++) this._removeError(diff.removed[i].assert.name);
999
1000			for (i = 0; i < diff.added.length; i++) this._addError(diff.added[i].assert.name, { message: diff.added[i].errorMessage, assert: diff.added[i].assert });
1001
1002			for (i = 0; i < diff.kept.length; i++) this._updateError(diff.kept[i].assert.name, { message: diff.kept[i].errorMessage, assert: diff.kept[i].assert });
1003		},
1004
1005		_addError: function _addError(name, _ref5) {
1006			var message = _ref5.message;
1007			var assert = _ref5.assert;
1008
1009			this._insertErrorWrapper();
1010			this._ui.$errorsWrapper.addClass('filled').append($(this.options.errorTemplate).addClass('parsley-' + name).html(message || this._getErrorMessage(
1010assert)));
1011		},
1012
1013		_updateError: function _updateError(name, _ref6) {
1014			var message = _ref6.message;
1015			var assert = _ref6.assert;
1016
1017			this._ui.$errorsWrapper.addClass('filled').find('.parsley-' + name).html(message || this._getErrorMessage(assert));
1018		},
1019
1020		_removeError: function _removeError(name) {
1021			this._ui.$errorsWrapper.removeClass('filled').find('.parsley-' + name).remove();
1022		},
1023
1024		_getErrorMessage: function _getErrorMessage(constraint) {
1025			var customConstraintErrorMessage = constraint.name + 'Message';
1026
1027			if ('undefined' !== typeof this.options[customConstraintErrorMessage]) return window.Parsley.formatMessage(this.options[customConstraintErrorMessage], constraint.requirements);
1028
1029			return window.Parsley.getErrorMessage(constraint);
1030		},
1031
1032		_buildUI: function _buildUI() {
1033			// UI could be already built or disabled
1034			if (this._ui || false === this.options.uiEnabled) return;
1035
1036			var _ui = {};
1037
1038			// Give field its Parsley id in DOM
1039			this.element.setAttribute(this.options.namespace + 'id', this.__id__);
1040
1041			/** Generate important UI elements and store them in this **/
1042			// $errorClassHandler is the $element that woul have parsley-error and parsley-success classes
1043			_ui.$errorClassHandler = this._manageClassHandler();
1044
1045			// $errorsWrapper is a div that would contain the various field errors, it will be appended into $errorsContainer
1046			_ui.errorsWrapperId = 'parsley-id-' + (this.options.multiple ? 'multiple-' + this.options.multiple : this.__id__);
1047			_ui.$errorsWrapper = $(this.options.errorsWrapper).attr('id', _ui.errorsWrapperId);
1048			_ui.$errorClassHandler.attr('aria-describedby', _ui.errorsWrapperId);
1049
1050			// ValidationResult UI storage to detect what have changed bwt two validations, and update DOM accordingly
1051			_ui.lastValidationResult = [];
1052			_ui.validationInformationVisible = false;
1053
1054			// Store it in this for later
1055			this._ui = _ui;
1056		},
1057
1058		// Determine which element will have `parsley-error` and `parsley-success` classes
1059		_manageClassHandler: function _manageClassHandler() {
1060			// An element selector could be passed through DOM with `data-parsley-class-handler=#foo`
1061			if ('string' === typeof this.options.classHandler) {
1062				if ($(this.options.classHandler).length === 0) ParsleyUtils.warn('No elements found that match the selector `' + this.options.classHandler + '` set in options.classHandler or data-parsley-class-handler');
1063
1064				//return element or empty set
1065				return $(this.options.classHandler);
1066			}
1067
1068			// Class handled could also be determined by function given in Parsley options
1069			if ('function' === typeof this.options.classHandler) var $handler = this.options.classHandler.call(this, this);
1070
1071			// If this function returned a valid existing DOM element, go for it
1072			if ('undefined' !== typeof $handler && $handler.length) return $handler;
1073
1074			return this._inputHolder();
1075		},
1076
1077		_inputHolder: function _inputHolder() {
1078			// if simple element (input, texatrea, select...) it will perfectly host the classes and precede the error container
1079			if (!this.options.multiple || this.element.nodeName === 'SELECT') return this.$element;
1080
1081			// But if multiple element (radio, checkbox), that would be their parent
1082			return this.$element.parent();
1083		},
1084
1085		_insertErrorWrapper: function _insertErrorWrapper() {
1086			var $errorsContainer;
1087
1088			// Nothing to do if already inserted
1089			if (0 !== this._ui.$errorsWrapper.parent().length) return this._ui.$errorsWrapper.parent();
1090
1091			if ('string' === typeof this.options.errorsContainer) {
1092				if ($(this.options.errorsContainer).length) return $(this.options.errorsContainer).append(this._ui.$errorsWrapper);else Utils.warn('The errors container `' + this.options.errorsContainer + '` does not exist in DOM');
1093			} else if ('function' === typeof this.options.errorsContainer) $errorsContainer = this.options.errorsContainer.call(this, this);
1094
1095			if ('undefined' !== typeof $errorsContainer && $errorsContainer.length) return $errorsContainer.append(this._ui.$errorsWrapper);
1096
1097			return this._inputHolder().after(this._ui.$errorsWrapper);
1098		},
1099
1100		_actualizeTriggers: function _actualizeTriggers() {
1101			var _this3 = this;
1102
1103			var $toBind = this._findRelated();
1104			var trigger;
1105
1106			// Remove Parsley events already bound on this field
1107			$toBind.off('.Parsley');
1108			if (this._failedOnce) $toBind.on(Utils.namespaceEvents(this.options.triggerAfterFailure, 'Parsley'), function () {
1109				_this3._validateIfNeeded();
1110			});else if (trigger = Utils.namespaceEvents(this.options.trigger, 'Parsley')) {
1111				$toBind.on(trigger, function (event) {
1112					_this3._validateIfNeeded(event);
1113				});
1114			}
1115		},
1116
1117		_validateIfNeeded: function _validateIfNeeded(event) {
1118			var _this4 = this;
1119
vendor: 47,075 bytes, lines 1120-2462
1120			// For keyup, keypress, keydown, input... events that could be a little bit obstrusive
1121			// do not validate if val length < min threshold on first validation. Once field have been validated once and info
1122			// about success or failure have been displayed, always validate with this trigger to reflect every yalidation change.
1123			if (event && /key|input/.test(event.type)) if (!(this._ui && this._ui.validationInformationVisible) && this.getValue().length <= this.options.validationThreshold) return;
1124
1125			if (this.options.debounce) {
1126				window.clearTimeout(this._debounced);
1127				this._debounced = window.setTimeout(function () {
1128					return _this4.validate();
1129				}, this.options.debounce);
1130			} else this.validate();
1131		},
1132
1133		_resetUI: function _resetUI() {
1134			// Reset all event listeners
1135			this._failedOnce = false;
1136			this._actualizeTriggers();
1137
1138			// Nothing to do if UI never initialized for this field
1139			if ('undefined' === typeof this._ui) return;
1140
1141			// Reset all errors' li
1142			this._ui.$errorsWrapper.removeClass('filled').children().remove();
1143
1144			// Reset validation class
1145			this._resetClass();
1146
1147			// Reset validation flags and last validation result
1148			this._ui.lastValidationResult = [];
1149			this._ui.validationInformationVisible = false;
1150		},
1151
1152		_destroyUI: function _destroyUI() {
1153			this._resetUI();
1154
1155			if ('undefined' !== typeof this._ui) this._ui.$errorsWrapper.remove();
1156
1157			delete this._ui;
1158		},
1159
1160		_successClass: function _successClass() {
1161			this._ui.validationInformationVisible = true;
1162			this._ui.$errorClassHandler.removeClass(this.options.errorClass).addClass(this.options.successClass);
1163		},
1164		_errorClass: function _errorClass() {
1165			this._ui.validationInformationVisible = true;
1166			this._ui.$errorClassHandler.removeClass(this.options.successClass).addClass(this.options.errorClass);
1167		},
1168		_resetClass: function _resetClass() {
1169			this._ui.$errorClassHandler.removeClass(this.options.successClass).removeClass(this.options.errorClass);
1170		}
1171	};
1172
1173	var Form = function Form(element, domOptions, options) {
1174		this.__class__ = 'Form';
1175
1176		this.element = element;
1177		this.$element = $(element);
1178		this.domOptions = domOptions;
1179		this.options = options;
1180		this.parent = window.Parsley;
1181
1182		this.fields = [];
1183		this.validationResult = null;
1184	};
1185
1186	var Form__statusMapping = { pending: null, resolved: true, rejected: false };
1187
1188	Form.prototype = {
1189		onSubmitValidate: function onSubmitValidate(event) {
1190			var _this5 = this;
1191
1192			// This is a Parsley generated submit event, do not validate, do not prevent, simply exit and keep normal behavior
1193			if (true === event.parsley) return;
1194
1195			// If we didn't come here through a submit button, use the first one in the form
1196			var submitSource = this._submitSource || this.$element.find(Utils._SubmitSelector)[0];
1197			this._submitSource = null;
1198			this.$element.find('.parsley-synthetic-submit-button').prop('disabled', true);
1199			if (submitSource && null !== submitSource.getAttribute('formnovalidate')) return;
1200
1201			window.Parsley._remoteCache = {};
1202
1203			var promise = this.whenValidate({ event: event });
1204
1205			if ('resolved' === promise.state() && false !== this._trigger('submit')) {
1206				// All good, let event go through. We make this distinction because browsers
1207				// differ in their handling of `submit` being called from inside a submit event [#1047]
1208			} else {
1209				// Rejected or pending: cancel this submit
1210				event.stopImmediatePropagation();
1211				event.preventDefault();
1212				if ('pending' === promise.state()) promise.done(function () {
1213					_this5._submit(submitSource);
1214				});
1215			}
1216		},
1217
1218		onSubmitButton: function onSubmitButton(event) {
1219			this._submitSource = event.currentTarget;
1220		},
1221		// internal
1222		// _submit submits the form, this time without going through the validations.
1223		// Care must be taken to "fake" the actual submit button being clicked.
1224		_submit: function _submit(submitSource) {
1225			if (false === this._trigger('submit')) return;
1226			// Add submit button's data
1227			if (submitSource) {
1228				var $synthetic = this.$element.find('.parsley-synthetic-submit-button').prop('disabled', false);
1229				if (0 === $synthetic.length) $synthetic = $('<input class="parsley-synthetic-submit-button" type="hidden">').appendTo(this.$element);
1230				$synthetic.attr({
1231					name: submitSource.getAttribute('name'),
1232					value: submitSource.getAttribute('value')
1233				});
1234			}
1235
1236			this.$element.trigger(_extends($.Event('submit'), { parsley: true }));
1237		},
1238
1239		// Performs validation on fields while triggering events.
1240		// @returns `true` if all validations succeeds, `false`
1241		// if a failure is immediately detected, or `null`
1242		// if dependant on a promise.
1243		// Consider using `whenValidate` instead.
1244		validate: function validate(options) {
1245			if (arguments.length >= 1 && !$.isPlainObject(options)) {
1246				Utils.warnOnce('Calling validate on a parsley form without passing arguments as an object is deprecated.');
1247
1248				var _arguments = _slice.call(arguments);
1249
1250				var group = _arguments[0];
1251				var force = _arguments[1];
1252				var event = _arguments[2];
1253
1254				options = { group: group, force: force, event: event };
1255			}
1256			return Form__statusMapping[this.whenValidate(options).state()];
1257		},
1258
1259		whenValidate: function whenValidate() {
1260			var _Utils$all$done$fail$always,
1261				_this6 = this;
1262
1263			var _ref7 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
1264
1265			var group = _ref7.group;
1266			var force = _ref7.force;
1267			var event = _ref7.event;
1268
1269			this.submitEvent = event;
1270			if (event) {
1271				this.submitEvent = _extends({}, event, { preventDefault: function preventDefault() {
1272					Utils.warnOnce("Using `this.submitEvent.preventDefault()` is deprecated; instead, call `this.validationResult = false`");
1273					_this6.validationResult = false;
1274				} });
1275			}
1276			this.validationResult = true;
1277
1278			// fire validate event to eventually modify things before every validation
1279			this._trigger('validate');
1280
1281			// Refresh form DOM options and form's fields that could have changed
1282			this._refreshFields();
1283
1284			var promises = this._withoutReactualizingFormOptions(function () {
1285				return $.map(_this6.fields, function (field) {
1286					return field.whenValidate({ force: force, group: group });
1287				});
1288			});
1289
1290			return (_Utils$all$done$fail$always = Utils.all(promises).done(function () {
1291				_this6._trigger('success');
1292			}).fail(function () {
1293				_this6.validationResult = false;
1294				_this6.focus();
1295				_this6._trigger('error');
1296			}).always(function () {
1297				_this6._trigger('validated');
1298			})).pipe.apply(_Utils$all$done$fail$always, _toConsumableArray(this._pipeAccordingToValidationResult()));
1299		},
1300
1301		// Iterate over refreshed fields, and stop on first failure.
1302		// Returns `true` if all fields are valid, `false` if a failure is detected
1303		// or `null` if the result depends on an unresolved promise.
1304		// Prefer using `whenValid` instead.
1305		isValid: function isValid(options) {
1306			if (arguments.length >= 1 && !$.isPlainObject(options)) {
1307				Utils.warnOnce('Calling isValid on a parsley form without passing arguments as an object is deprecated.');
1308
1309				var _arguments2 = _slice.call(arguments);
1310
1311				var group = _arguments2[0];
1312				var force = _arguments2[1];
1313
1314				options = { group: group, force: force };
1315			}
1316			return Form__statusMapping[this.whenValid(options).state()];
1317		},
1318
1319		// Iterate over refreshed fields and validate them.
1320		// Returns a promise.
1321		// A validation that immediately fails will interrupt the validations.
1322		whenValid: function whenValid() {
1323			var _this7 = this;
1324
1325			var _ref8 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
1326
1327			var group = _ref8.group;
1328			var force = _ref8.force;
1329
1330			this._refreshFields();
1331
1332			var promises = this._withoutReactualizingFormOptions(function () {
1333				return $.map(_this7.fields, function (field) {
1334					return field.whenValid({ group: group, force: force });
1335				});
1336			});
1337			return Utils.all(promises);
1338		},
1339
1340		// Reset UI
1341		reset: function reset() {
1342			// Form case: emit a reset event for each field
1343			for (var i = 0; i < this.fields.length; i++) this.fields[i].reset();
1344
1345			this._trigger('reset');
1346		},
1347
1348		// Destroy Parsley instance (+ UI)
1349		destroy: function destroy() {
1350			// Field case: emit destroy event to clean UI and then destroy stored instance
1351			this._destroyUI();
1352
1353			// Form case: destroy all its fields and then destroy stored instance
1354			for (var i = 0; i < this.fields.length; i++) this.fields[i].destroy();
1355
1356			this.$element.removeData('Parsley');
1357			this._trigger('destroy');
1358		},
1359
1360		_refreshFields: function _refreshFields() {
1361			return this.actualizeOptions()._bindFields();
1362		},
1363
1364		_bindFields: function _bindFields() {
1365			var _this8 = this;
1366
1367			var oldFields = this.fields;
1368
1369			this.fields = [];
1370			this.fieldsMappedById = {};
1371
1372			this._withoutReactualizingFormOptions(function () {
1373				_this8.$element.find(_this8.options.inputs).not(_this8.options.excluded).each(function (_, element) {
1374					var fieldInstance = new window.Parsley.Factory(element, {}, _this8);
1375
1376					// Only add valid and not excluded `Field` and `FieldMultiple` children
1377					if (('Field' === fieldInstance.__class__ || 'FieldMultiple' === fieldInstance.__class__) && true !== fieldInstance.options.excluded) {
1378						var uniqueId = fieldInstance.__class__ + '-' + fieldInstance.__id__;
1379						if ('undefined' === typeof _this8.fieldsMappedById[uniqueId]) {
1380							_this8.fieldsMappedById[uniqueId] = fieldInstance;
1381							_this8.fields.push(fieldInstance);
1382						}
1383					}
1384				});
1385
1386				$.each(Utils.difference(oldFields, _this8.fields), function (_, field) {
1387					field.reset();
1388				});
1389			});
1390			return this;
1391		},
1392
1393		// Internal only.
1394		// Looping on a form's fields to do validation or similar
1395		// will trigger reactualizing options on all of them, which
1396		// in turn will reactualize the form's options.
1397		// To avoid calling actualizeOptions so many times on the form
1398		// for nothing, _withoutReactualizingFormOptions temporarily disables
1399		// the method actualizeOptions on this form while `fn` is called.
1400		_withoutReactualizingFormOptions: function _withoutReactualizingFormOptions(fn) {
1401			var oldActualizeOptions = this.actualizeOptions;
1402			this.actualizeOptions = function () {
1403				return this;
1404			};
1405			var result = fn();
1406			this.actualizeOptions = oldActualizeOptions;
1407			return result;
1408		},
1409
1410		// Internal only.
1411		// Shortcut to trigger an event
1412		// Returns true iff event is not interrupted and default not prevented.
1413		_trigger: function _trigger(eventName) {
1414			return this.trigger('form:' + eventName);
1415		}
1416
1417	};
1418
1419	var Constraint = function Constraint(parsleyField, name, requirements, priority, isDomConstraint) {
1420		var validatorSpec = window.Parsley._validatorRegistry.validators[name];
1421		var validator = new Validator(validatorSpec);
1422		priority = priority || parsleyField.options[name + 'Priority'] || validator.priority;
1423		isDomConstraint = true === isDomConstraint;
1424
1425		_extends(this, {
1426			validator: validator,
1427			name: name,
1428			requirements: requirements,
1429			priority: priority,
1430			isDomConstraint: isDomConstraint
1431		});
1432		this._parseRequirements(parsleyField.options);
1433	};
1434
1435	var capitalize = function capitalize(str) {
1436		var cap = str[0].toUpperCase();
1437		return cap + str.slice(1);
1438	};
1439
1440	Constraint.prototype = {
1441		validate: function validate(value, instance) {
1442			var _validator;
1443
1444			return (_validator = this.validator).validate.apply(_validator, [value].concat(_toConsumableArray(this.requirementList), [instance]));
1445		},
1446
1447		_parseRequirements: function _parseRequirements(options) {
1448			var _this9 = this;
1449
1450			this.requirementList = this.validator.parseRequirements(this.requirements, function (key) {
1451				return options[_this9.name + capitalize(key)];
1452			});
1453		}
1454	};
1455
1456	var Field = function Field(field, domOptions, options, parsleyFormInstance) {
1457		this.__class__ = 'Field';
1458
1459		this.element = field;
1460		this.$element = $(field);
1461
1462		// Set parent if we have one
1463		if ('undefined' !== typeof parsleyFormInstance) {
1464			this.parent = parsleyFormInstance;
1465		}
1466
1467		this.options = options;
1468		this.domOptions = domOptions;
1469
1470		// Initialize some properties
1471		this.constraints = [];
1472		this.constraintsByName = {};
1473		this.validationResult = true;
1474
1475		// Bind constraints
1476		this._bindConstraints();
1477	};
1478
1479	var parsley_field__statusMapping = { pending: null, resolved: true, rejected: false };
1480
1481	Field.prototype = {
1482		// # Public API
1483		// Validate field and trigger some events for mainly `UI`
1484		// @returns `true`, an array of the validators that failed, or
1485		// `null` if validation is not finished. Prefer using whenValidate
1486		validate: function validate(options) {
1487			if (arguments.length >= 1 && !$.isPlainObject(options)) {
1488				Utils.warnOnce('Calling validate on a parsley field without passing arguments as an object is deprecated.');
1489				options = { options: options };
1490			}
1491			var promise = this.whenValidate(options);
1492			if (!promise) // If excluded with `group` option
1493				return true;
1494			switch (promise.state()) {
1495				case 'pending':
1496					return null;
1497				case 'resolved':
1498					return true;
1499				case 'rejected':
1500					return this.validationResult;
1501			}
1502		},
1503
1504		// Validate field and trigger some events for mainly `UI`
1505		// @returns a promise that succeeds only when all validations do
1506		// or `undefined` if field is not in the given `group`.
1507		whenValidate: function whenValidate() {
1508			var _whenValid$always$done$fail$always,
1509				_this10 = this;
1510
1511			var _ref9 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
1512
1513			var force = _ref9.force;
1514			var group = _ref9.group;
1515
1516			// do not validate a field if not the same as given validation group
1517			this.refreshConstraints();
1518			if (group && !this._isInGroup(group)) return;
1519
1520			this.value = this.getValue();
1521
1522			// Field Validate event. `this.value` could be altered for custom needs
1523			this._trigger('validate');
1524
1525			return (_whenValid$always$done$fail$always = this.whenValid({ force: force, value: this.value, _refreshed: true }).always(function () {
1526				_this10._reflowUI();
1527			}).done(function () {
1528				_this10._trigger('success');
1529			}).fail(function () {
1530				_this10._trigger('error');
1531			}).always(function () {
1532				_this10._trigger('validated');
1533			})).pipe.apply(_whenValid$always$done$fail$always, _toConsumableArray(this._pipeAccordingToValidationResult()));
1534		},
1535
1536		hasConstraints: function hasConstraints() {
1537			return 0 !== this.constraints.length;
1538		},
1539
1540		// An empty optional field does not need validation
1541		needsValidation: function needsValidation(value) {
1542			if ('undefined' === typeof value) value = this.getValue();
1543
1544			// If a field is empty and not required, it is valid
1545			// Except if `data-parsley-validate-if-empty` explicitely added, useful for some custom validators
1546			if (!value.length && !this._isRequired() && 'undefined' === typeof this.options.validateIfEmpty) return false;
1547
1548			return true;
1549		},
1550
1551		_isInGroup: function _isInGroup(group) {
1552			if (Array.isArray(this.options.group)) return -1 !== $.inArray(group, this.options.group);
1553			return this.options.group === group;
1554		},
1555
1556		// Just validate field. Do not trigger any event.
1557		// Returns `true` iff all constraints pass, `false` if there are failures,
1558		// or `null` if the result can not be determined yet (depends on a promise)
1559		// See also `whenValid`.
1560		isValid: function isValid(options) {
1561			if (arguments.length >= 1 && !$.isPlainObject(options)) {
1562				Utils.warnOnce('Calling isValid on a parsley field without passing arguments as an object is deprecated.');
1563
1564				var _arguments3 = _slice.call(arguments);
1565
1566				var force = _arguments3[0];
1567				var value = _arguments3[1];
1568
1569				options = { force: force, value: value };
1570			}
1571			var promise = this.whenValid(options);
1572			if (!promise) // Excluded via `group`
1573				return true;
1574			return parsley_field__statusMapping[promise.state()];
1575		},
1576
1577		// Just validate field. Do not trigger any event.
1578		// @returns a promise that succeeds only when all validations do
1579		// or `undefined` if the field is not in the given `group`.
1580		// The argument `force` will force validation of empty fields.
1581		// If a `value` is given, it will be validated instead of the value of the input.
1582		whenValid: function whenValid() {
1583			var _this11 = this;
1584
1585			var _ref10 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
1586
1587			var _ref10$force = _ref10.force;
1588			var force = _ref10$force === undefined ? false : _ref10$force;
1589			var value = _ref10.value;
1590			var group = _ref10.group;
1591			var _refreshed = _ref10._refreshed;
1592
1593			// Recompute options and rebind constraints to have latest changes
1594			if (!_refreshed) this.refreshConstraints();
1595			// do not validate a field if not the same as given validation group
1596			if (group && !this._isInGroup(group)) return;
1597
1598			this.validationResult = true;
1599
1600			// A field without constraint is valid
1601			if (!this.hasConstraints()) return $.when();
1602
1603			// Value could be passed as argument, needed to add more power to 'field:validate'
1604			if ('undefined' === typeof value || null === value) value = this.getValue();
1605
1606			if (!this.needsValidation(value) && true !== force) return $.when();
1607
1608			var groupedConstraints = this._getGroupedConstraints();
1609			var promises = [];
1610			$.each(groupedConstraints, function (_, constraints) {
1611				// Process one group of constraints at a time, we validate the constraints
1612				// and combine the promises together.
1613				var promise = Utils.all($.map(constraints, function (constraint) {
1614					return _this11._validateConstraint(value, constraint);
1615				}));
1616				promises.push(promise);
1617				if (promise.state() === 'rejected') return false; // Interrupt processing if a group has already failed
1618			});
1619			return Utils.all(promises);
1620		},
1621
1622		// @returns a promise
1623		_validateConstraint: function _validateConstraint(value, constraint) {
1624			var _this12 = this;
1625
1626			var result = constraint.validate(value, this);
1627			// Map false to a failed promise
1628			if (false === result) result = $.Deferred().reject();
1629			// Make sure we return a promise and that we record failures
1630			return Utils.all([result]).fail(function (errorMessage) {
1631				if (!(_this12.validationResult instanceof Array)) _this12.validationResult = [];
1632				_this12.validationResult.push({
1633					assert: constraint,
1634					errorMessage: 'string' === typeof errorMessage && errorMessage
1635				});
1636			});
1637		},
1638
1639		// @returns Parsley field computed value that could be overrided or configured in DOM
1640		getValue: function getValue() {
1641			var value;
1642
1643			// Value could be overriden in DOM or with explicit options
1644			if ('function' === typeof this.options.value) value = this.options.value(this);else if ('undefined' !== typeof this.options.value) value = this.options.value;else value = this.$element.val();
1645
1646			// Handle wrong DOM or configurations
1647			if ('undefined' === typeof value || null === value) return '';
1648
1649			return this._handleWhitespace(value);
1650		},
1651
1652		// Reset UI
1653		reset: function reset() {
1654			this._resetUI();
1655			return this._trigger('reset');
1656		},
1657
1658		// Destroy Parsley instance (+ UI)
1659		destroy: function destroy() {
1660			// Field case: emit destroy event to clean UI and then destroy stored instance
1661			this._destroyUI();
1662			this.$element.removeData('Parsley');
1663			this.$element.removeData('FieldMultiple');
1664			this._trigger('destroy');
1665		},
1666
1667		// Actualize options that could have change since previous validation
1668		// Re-bind accordingly constraints (could be some new, removed or updated)
1669		refreshConstraints: function refreshConstraints() {
1670			return this.actualizeOptions()._bindConstraints();
1671		},
1672
1673		/**
1674		 * Add a new constraint to a field
1675		 *
1676		 * @param {String}   name
1677		 * @param {Mixed}    requirements      optional
1678		 * @param {Number}   priority          optional
1679		 * @param {Boolean}  isDomConstraint   optional
1680		 */
1681		addConstraint: function addConstraint(name, requirements, priority, isDomConstraint) {
1682
1683			if (window.Parsley._validatorRegistry.validators[name]) {
1684				var constraint = new Constraint(this, name, requirements, priority, isDomConstraint);
1685
1686				// if constraint already exist, delete it and push new version
1687				if ('undefined' !== this.constraintsByName[constraint.name]) this.removeConstraint(constraint.name);
1688
1689				this.constraints.push(constraint);
1690				this.constraintsByName[constraint.name] = constraint;
1691			}
1692
1693			return this;
1694		},
1695
1696		// Remove a constraint
1697		removeConstraint: function removeConstraint(name) {
1698			for (var i = 0; i < this.constraints.length; i++) if (name === this.constraints[i].name) {
1699				this.constraints.splice(i, 1);
1700				break;
1701			}
1702			delete this.constraintsByName[name];
1703			return this;
1704		},
1705
1706		// Update a constraint (Remove + re-add)
1707		updateConstraint: function updateConstraint(name, parameters, priority) {
1708			return this.removeConstraint(name).addConstraint(name, parameters, priority);
1709		},
1710
1711		// # Internals
1712
1713		// Internal only.
1714		// Bind constraints from config + options + DOM
1715		_bindConstraints: function _bindConstraints() {
1716			var constraints = [];
1717			var constraintsByName = {};
1718
1719			// clean all existing DOM constraints to only keep javascript user constraints
1720			for (var i = 0; i < this.constraints.length; i++) if (false === this.constraints[i].isDomConstraint) {
1721				constraints.push(this.constraints[i]);
1722				constraintsByName[this.constraints[i].name] = this.constraints[i];
1723			}
1724
1725			this.constraints = constraints;
1726			this.constraintsByName = constraintsByName;
1727
1728			// then re-add Parsley DOM-API constraints
1729			for (var name in this.options) this.addConstraint(name, this.options[name], undefined, true);
1730
1731			// finally, bind special HTML5 constraints
1732			return this._bindHtml5Constraints();
1733		},
1734
1735		// Internal only.
1736		// Bind specific HTML5 constraints to be HTML5 compliant
1737		_bindHtml5Constraints: function _bindHtml5Constraints() {
1738			// html5 required
1739			if (null !== this.element.getAttribute('required')) this.addConstraint('required', true, undefined, true);
1740
1741			// html5 pattern
1742			if (null !== this.element.getAttribute('pattern')) this.addConstraint('pattern', this.element.getAttribute('pattern'), undefined, true);
1743
1744			// range
1745			var min = this.element.getAttribute('min');
1746			var max = this.element.getAttribute('max');
1747			if (null !== min && null !== max) this.addConstraint('range', [min, max], undefined, true);
1748
1749			// HTML5 min
1750			else if (null !== min) this.addConstraint('min', min, undefined, true);
1751
1752			// HTML5 max
1753			else if (null !== max) this.addConstraint('max', max, undefined, true);
1754
1755			// length
1756			if (null !== this.element.getAttribute('minlength') && null !== this.element.getAttribute('maxlength')) this.addConstraint('length', [this.element.getAttribute('minlength'), this.element.getAttribute('maxlength')], undefined, true);
1757
1758			// HTML5 minlength
1759			else if (null !== this.element.getAttribute('minlength')) this.addConstraint('minlength', this.element.getAttribute('minlength'), undefined, true);
1760
1761			// HTML5 maxlength
1762			else if (null !== this.element.getAttribute('maxlength')) this.addConstraint('maxlength', this.element.getAttribute('maxlength'), undefined, true);
1763
1764			// html5 types
1765			var type = this.element.type;
1766
1767			// Small special case here for HTML5 number: integer validator if step attribute is undefined or an integer value, number otherwise
1768			if ('number' === type) {
1769				return this.addConstraint('type', ['number', {
1770					step: this.element.getAttribute('step') || '1',
1771					base: min || this.element.getAttribute('value')
1772				}], undefined, true);
1773				// Regular other HTML5 supported types
1774			} else if (/^(email|url|range|date)$/i.test(type)) {
1775				return this.addConstraint('type', type, undefined, true);
1776			}
1777			return this;
1778		},
1779
1780		// Internal only.
1781		// Field is required if have required constraint without `false` value
1782		_isRequired: function _isRequired() {
1783			if ('undefined' === typeof this.constraintsByName.required) return false;
1784
1785			return false !== this.constraintsByName.required.requirements;
1786		},
1787
1788		// Internal only.
1789		// Shortcut to trigger an event
1790		_trigger: function _trigger(eventName) {
1791			return this.trigger('field:' + eventName);
1792		},
1793
1794		// Internal only
1795		// Handles whitespace in a value
1796		// Use `data-parsley-whitespace="squish"` to auto squish input value
1797		// Use `data-parsley-whitespace="trim"` to auto trim input value
1798		_handleWhitespace: function _handleWhitespace(value) {
1799			if (true === this.options.trimValue) Utils.warnOnce('data-parsley-trim-value="true" is deprecated, please use data-parsley-whitespace="trim"');
1800
1801			if ('squish' === this.options.whitespace) value = value.replace(/\s{2,}/g, ' ');
1802
1803			if ('trim' === this.options.whitespace || 'squish' === this.options.whitespace || true === this.options.trimValue) value = Utils.trimString(value);
1804
1805			return value;
1806		},
1807
1808		_isDateInput: function _isDateInput() {
1809			var c = this.constraintsByName.type;
1810			return c && c.requirements === 'date';
1811		},
1812
1813		// Internal only.
1814		// Returns the constraints, grouped by descending priority.
1815		// The result is thus an array of arrays of constraints.
1816		_getGroupedConstraints: function _getGroupedConstraints() {
1817			if (false === this.options.priorityEnabled) return [this.constraints];
1818
1819			var groupedConstraints = [];
1820			var index = {};
1821
1822			// Create array unique of priorities
1823			for (var i = 0; i < this.constraints.length; i++) {
1824				var p = this.constraints[i].priority;
1825				if (!index[p]) groupedConstraints.push(index[p] = []);
1826				index[p].push(this.constraints[i]);
1827			}
1828			// Sort them by priority DESC
1829			groupedConstraints.sort(function (a, b) {
1830				return b[0].priority - a[0].priority;
1831			});
1832
1833			return groupedConstraints;
1834		}
1835
1836	};
1837
1838	var parsley_field = Field;
1839
1840	var Multiple = function Multiple() {
1841		this.__class__ = 'FieldMultiple';
1842	};
1843
1844	Multiple.prototype = {
1845		// Add new `$element` sibling for multiple field
1846		addElement: function addElement($element) {
1847			this.$elements.push($element);
1848
1849			return this;
1850		},
1851
1852		// See `Field.refreshConstraints()`
1853		refreshConstraints: function refreshConstraints() {
1854			var fieldConstraints;
1855
1856			this.constraints = [];
1857
1858			// Select multiple special treatment
1859			if (this.element.nodeName === 'SELECT') {
1860				this.actualizeOptions()._bindConstraints();
1861
1862				return this;
1863			}
1864
1865			// Gather all constraints for each input in the multiple group
1866			for (var i = 0; i < this.$elements.length; i++) {
1867
1868				// Check if element have not been dynamically removed since last binding
1869				if (!$('html').has(this.$elements[i]).length) {
1870					this.$elements.splice(i, 1);
1871					continue;
1872				}
1873
1874				fieldConstraints = this.$elements[i].data('FieldMultiple').refreshConstraints().constraints;
1875
1876				for (var j = 0; j < fieldConstraints.length; j++) this.addConstraint(fieldConstraints[j].name, fieldConstraints[j].requirements, fieldConstraints[j].priority, fieldConstraints[j].isDomConstraint);
1877			}
1878
1879			return this;
1880		},
1881
1882		// See `Field.getValue()`
1883		getValue: function getValue() {
1884			// Value could be overriden in DOM
1885			if ('function' === typeof this.options.value) return this.options.value(this);else if ('undefined' !== typeof this.options.value) return this.options.value;
1886
1887			// Radio input case
1888			if (this.element.nodeName === 'INPUT') {
1889				if (this.element.type === 'radio') return this._findRelated().filter(':checked').val() || '';
1890
1891				// checkbox input case
1892				if (this.element.type === 'checkbox') {
1893					var values = [];
1894
1895					this._findRelated().filter(':checked').each(function () {
1896						values.push($(this).val());
1897					});
1898
1899					return values;
1900				}
1901			}
1902
1903			// Select multiple case
1904			if (this.element.nodeName === 'SELECT' && null === this.$element.val()) return [];
1905
1906			// Default case that should never happen
1907			return this.$element.val();
1908		},
1909
1910		_init: function _init() {
1911			this.$elements = [this.$element];
1912
1913			return this;
1914		}
1915	};
1916
1917	var Factory = function Factory(element, options, parsleyFormInstance) {
1918		this.element = element;
1919		this.$element = $(element);
1920
1921		// If the element has already been bound, returns its saved Parsley instance
1922		var savedparsleyFormInstance = this.$element.data('Parsley');
1923		if (savedparsleyFormInstance) {
1924
1925			// If the saved instance has been bound without a Form parent and there is one given in this call, add it
1926			if ('undefined' !== typeof parsleyFormInstance && savedparsleyFormInstance.parent === window.Parsley) {
1927				savedparsleyFormInstance.parent = parsleyFormInstance;
1928				savedparsleyFormInstance._resetOptions(savedparsleyFormInstance.options);
1929			}
1930
1931			if ('object' === typeof options) {
1932				_extends(savedparsleyFormInstance.options, options);
1933			}
1934
1935			return savedparsleyFormInstance;
1936		}
1937
1938		// Parsley must be instantiated with a DOM element or jQuery $element
1939		if (!this.$element.length) throw new Error('You must bind Parsley on an existing element.');
1940
1941		if ('undefined' !== typeof parsleyFormInstance && 'Form' !== parsleyFormInstance.__class__) throw new Error('Parent instance must be a Form instance');
1942
1943		this.parent = parsleyFormInstance || window.Parsley;
1944		return this.init(options);
1945	};
1946
1947	Factory.prototype = {
1948		init: function init(options) {
1949			this.__class__ = 'Parsley';
1950			this.__version__ = '2.7.2';
1951			this.__id__ = Utils.generateID();
1952
1953			// Pre-compute options
1954			this._resetOptions(options);
1955
1956			// A Form instance is obviously a `<form>` element but also every node that is not an input and has the `data-parsley-validate` attribute
1957			if (this.element.nodeName === 'FORM' || Utils.checkAttr(this.element, this.options.namespace, 'validate') && !this.$element.is(this.options.inputs)) return this.bind('parsleyForm');
1958
1959			// Every other element is bound as a `Field` or `FieldMultiple`
1960			return this.isMultiple() ? this.handleMultiple() : this.bind('parsleyField');
1961		},
1962
1963		isMultiple: function isMultiple() {
1964			return this.element.type === 'radio' || this.element.type === 'checkbox' || this.element.nodeName === 'SELECT' && null !== this.element.getAttribute('multiple');
1965		},
1966
1967		// Multiples fields are a real nightmare :(
1968		// Maybe some refactoring would be appreciated here...
1969		handleMultiple: function handleMultiple() {
1970			var _this13 = this;
1971
1972			var name;
1973			var multiple;
1974			var parsleyMultipleInstance;
1975
1976			// Handle multiple name
1977			this.options.multiple = this.options.multiple || (name = this.element.getAttribute('name')) || this.element.getAttribute('id');
1978
1979			// Special select multiple input
1980			if (this.element.nodeName === 'SELECT' && null !== this.element.getAttribute('multiple')) {
1981				this.options.multiple = this.options.multiple || this.__id__;
1982				return this.bind('parsleyFieldMultiple');
1983
1984				// Else for radio / checkboxes, we need a `name` or `data-parsley-multiple` to properly bind it
1985			} else if (!this.options.multiple) {
1986				Utils.warn('To be bound by Parsley, a radio, a checkbox and a multiple select input must have either a name or a multiple option.', this.$element);
1987				return this;
1988			}
1989
1990			// Remove special chars
1991			this.options.multiple = this.options.multiple.replace(/(:|\.|\[|\]|\{|\}|\$)/g, '');
1992
1993			// Add proper `data-parsley-multiple` to siblings if we have a valid multiple name
1994			if (name) {
1995				$('input[name="' + name + '"]').each(function (i, input) {
1996					if (input.type === 'radio' || input.type === 'checkbox') input.setAttribute(_this13.options.namespace + 'multiple', _this13.options.multiple);
1997				});
1998			}
1999
2000			// Check here if we don't already have a related multiple instance saved
2001			var $previouslyRelated = this._findRelated();
2002			for (var i = 0; i < $previouslyRelated.length; i++) {
2003				parsleyMultipleInstance = $($previouslyRelated.get(i)).data('Parsley');
2004				if ('undefined' !== typeof parsleyMultipleInstance) {
2005
2006					if (!this.$element.data('FieldMultiple')) {
2007						parsleyMultipleInstance.addElement(this.$element);
2008					}
2009
2010					break;
2011				}
2012			}
2013
2014			// Create a secret Field instance for every multiple field. It will be stored in `data('FieldMultiple')`
2015			// And will be useful later to access classic `Field` stuff while being in a `FieldMultiple` instance
2016			this.bind('parsleyField', true);
2017
2018			return parsleyMultipleInstance || this.bind('parsleyFieldMultiple');
2019		},
2020
2021		// Return proper `Form`, `Field` or `FieldMultiple`
2022		bind: function bind(type, doNotStore) {
2023			var parsleyInstance;
2024
2025			switch (type) {
2026				case 'parsleyForm':
2027					parsleyInstance = $.extend(new Form(this.element, this.domOptions, this.options), new Base(), window.ParsleyExtend)._bindFields();
2028					break;
2029				case 'parsleyField':
2030					parsleyInstance = $.extend(new parsley_field(this.element, this.domOptions, this.options, this.parent), new Base(), window.ParsleyExtend);
2031					break;
2032				case 'parsleyFieldMultiple':
2033					parsleyInstance = $.extend(new parsley_field(this.element, this.domOptions, this.options, this.parent), new Multiple(), new Base(), window.ParsleyExtend)._init();
2034					break;
2035				default:
2036					throw new Error(type + 'is not a supported Parsley type');
2037			}
2038
2039			if (this.options.multiple) Utils.setAttr(this.element, this.options.namespace, 'multiple', this.options.multiple);
2040
2041			if ('undefined' !== typeof doNotStore) {
2042				this.$element.data('FieldMultiple', parsleyInstance);
2043
2044				return parsleyInstance;
2045			}
2046
2047			// Store the freshly bound instance in a DOM element for later access using jQuery `data()`
2048			this.$element.data('Parsley', parsleyInstance);
2049
2050			// Tell the world we have a new Form or Field instance!
2051			parsleyInstance._actualizeTriggers();
2052			parsleyInstance._trigger('init');
2053
2054			return parsleyInstance;
2055		}
2056	};
2057
2058	var vernums = $.fn.jquery.split('.');
2059	if (parseInt(vernums[0]) <= 1 && parseInt(vernums[1]) < 8) {
2060		throw "The loaded version of jQuery is too old. Please upgrade to 1.8.x or better.";
2061	}
2062	if (!vernums.forEach) {
2063		Utils.warn('Parsley requires ES5 to run properly. Please include https://github.com/es-shims/es5-shim');
2064	}
2065	// Inherit `on`, `off` & `trigger` to Parsley:
2066	var Parsley = _extends(new Base(), {
2067		element: document,
2068		$element: $(document),
2069		actualizeOptions: null,
2070		_resetOptions: null,
2071		Factory: Factory,
2072		version: '2.7.2'
2073	});
2074
2075	// Supplement Field and Form with Base
2076	// This way, the constructors will have access to those methods
2077	_extends(parsley_field.prototype, UI.Field, Base.prototype);
2078	_extends(Form.prototype, UI.Form, Base.prototype);
2079	// Inherit actualizeOptions and _resetOptions:
2080	_extends(Factory.prototype, Base.prototype);
2081
2082	// ### jQuery API
2083	// `$('.elem').parsley(options)` or `$('.elem').psly(options)`
2084	$.fn.parsley = $.fn.psly = function (options) {
2085		if (this.length > 1) {
2086			var instances = [];
2087
2088			this.each(function () {
2089				instances.push($(this).parsley(options));
2090			});
2091
2092			return instances;
2093		}
2094
2095		// Return undefined if applied to non existing DOM element
2096		if (!$(this).length) {
2097			Utils.warn('You must bind Parsley on an existing element.');
2098
2099			return;
2100		}
2101
2102		return new Factory(this[0], options);
2103	};
2104
2105	// ### Field and Form extension
2106	// Ensure the extension is now defined if it wasn't previously
2107	if ('undefined' === typeof window.ParsleyExtend) window.ParsleyExtend = {};
2108
2109	// ### Parsley config
2110	// Inherit from ParsleyDefault, and copy over any existing values
2111	Parsley.options = _extends(Utils.objectCreate(Defaults), window.ParsleyConfig);
2112	window.ParsleyConfig = Parsley.options; // Old way of accessing global options
2113
2114	// ### Globals
2115	window.Parsley = window.psly = Parsley;
2116	Parsley.Utils = Utils;
2117	window.ParsleyUtils = {};
2118	$.each(Utils, function (key, value) {
2119		if ('function' === typeof value) {
2120			window.ParsleyUtils[key] = function () {
2121				Utils.warnOnce('Accessing `window.ParsleyUtils` is deprecated. Use `window.Parsley.Utils` instead.');
2122				return Utils[key].apply(Utils, arguments);
2123			};
2124		}
2125	});
2126
2127	// ### Define methods that forward to the registry, and deprecate all access except through window.Parsley
2128	var registry = window.Parsley._validatorRegistry = new ValidatorRegistry(window.ParsleyConfig.validators, window.ParsleyConfig.i18n);
2129	window.ParsleyValidator = {};
2130	$.each('setLocale addCatalog addMessage addMessages getErrorMessage formatMessage addValidator updateValidator removeValidator'.split(' '), function (i, method) {
2131		window.Parsley[method] = function () {
2132			return registry[method].apply(registry, arguments);
2133		};
2134		window.ParsleyValidator[method] = function () {
2135			var _window$Parsley;
2136
2137			Utils.warnOnce('Accessing the method \'' + method + '\' through Validator is deprecated. Simply call \'window.Parsley.' + method + '(...)\'');
2138			return (_window$Parsley = window.Parsley)[method].apply(_window$Parsley, arguments);
2139		};
2140	});
2141
2142	// ### UI
2143	// Deprecated global object
2144	window.Parsley.UI = UI;
2145	window.ParsleyUI = {
2146		removeError: function removeError(instance, name, doNotUpdateClass) {
2147			var updateClass = true !== doNotUpdateClass;
2148			Utils.warnOnce('Accessing UI is deprecated. Call \'removeError\' on the instance directly. Please comment in issue 1073 as to your need to call this method.');
2149			return instance.removeError(name, { updateClass: updateClass });
2150		},
2151		getErrorsMessages: function getErrorsMessages(instance) {
2152			Utils.warnOnce('Accessing UI is deprecated. Call \'getErrorsMessages\' on the instance directly.');
2153			return instance.getErrorsMessages();
2154		}
2155	};
2156	$.each('addError updateError'.split(' '), function (i, method) {
2157		window.ParsleyUI[method] = function (instance, name, message, assert, doNotUpdateClass) {
2158			var updateClass = true !== doNotUpdateClass;
2159			Utils.warnOnce('Accessing UI is deprecated. Call \'' + method + '\' on the instance directly. Please comment in issue 1073 as to your need to call this method.');
2160			return instance[method](name, { message: message, assert: assert, updateClass: updateClass });
2161		};
2162	});
2163
2164	// ### PARSLEY auto-binding
2165	// Prevent it by setting `ParsleyConfig.autoBind` to `false`
2166	if (false !== window.ParsleyConfig.autoBind) {
2167		$(function () {
2168			// Works only on `data-parsley-validate`.
2169			if ($('[data-parsley-validate]').length) $('[data-parsley-validate]').parsley();
2170		});
2171	}
2172
2173	var o = $({});
2174	var deprecated = function deprecated() {
2175		Utils.warnOnce("Parsley's pubsub module is deprecated; use the 'on' and 'off' methods on parsley instances or window.Parsley");
2176	};
2177
2178	// Returns an event handler that calls `fn` with the arguments it expects
2179	function adapt(fn, context) {
2180		// Store to allow unbinding
2181		if (!fn.parsleyAdaptedCallback) {
2182			fn.parsleyAdaptedCallback = function () {
2183				var args = Array.prototype.slice.call(arguments, 0);
2184				args.unshift(this);
2185				fn.apply(context || o, args);
2186			};
2187		}
2188		return fn.parsleyAdaptedCallback;
2189	}
2190
2191	var eventPrefix = 'parsley:';
2192	// Converts 'parsley:form:validate' into 'form:validate'
2193	function eventName(name) {
2194		if (name.lastIndexOf(eventPrefix, 0) === 0) return name.substr(eventPrefix.length);
2195		return name;
2196	}
2197
2198	// $.listen is deprecated. Use Parsley.on instead.
2199	$.listen = function (name, callback) {
2200		var context;
2201		deprecated();
2202		if ('object' === typeof arguments[1] && 'function' === typeof arguments[2]) {
2203			context = arguments[1];
2204			callback = arguments[2];
2205		}
2206
2207		if ('function' !== typeof callback) throw new Error('Wrong parameters');
2208
2209		window.Parsley.on(eventName(name), adapt(callback, context));
2210	};
2211
2212	$.listenTo = function (instance, name, fn) {
2213		deprecated();
2214		if (!(instance instanceof parsley_field) && !(instance instanceof Form)) throw new Error('Must give Parsley instance');
2215
2216		if ('string' !== typeof name || 'function' !== typeof fn) throw new Error('Wrong parameters');
2217
2218		instance.on(eventName(name), adapt(fn));
2219	};
2220
2221	$.unsubscribe = function (name, fn) {
2222		deprecated();
2223		if ('string' !== typeof name || 'function' !== typeof fn) throw new Error('Wrong arguments');
2224		window.Parsley.off(eventName(name), fn.parsleyAdaptedCallback);
2225	};
2226
2227	$.unsubscribeTo = function (instance, name) {
2228		deprecated();
2229		if (!(instance instanceof parsley_field) && !(instance instanceof Form)) throw new Error('Must give Parsley instance');
2230		instance.off(eventName(name));
2231	};
2232
2233	$.unsubscribeAll = function (name) {
2234		deprecated();
2235		window.Parsley.off(eventName(name));
2236		$('form,input,textarea,select').each(function () {
2237			var instance = $(this).data('Parsley');
2238			if (instance) {
2239				instance.off(eventName(name));
2240			}
2241		});
2242	};
2243
2244	// $.emit is deprecated. Use jQuery events instead.
2245	$.emit = function (name, instance) {
2246		var _instance;
2247
2248		deprecated();
2249		var instanceGiven = instance instanceof parsley_field || instance instanceof Form;
2250		var args = Array.prototype.slice.call(arguments, instanceGiven ? 2 : 1);
2251		args.unshift(eventName(name));
2252		if (!instanceGiven) {
2253			instance = window.Parsley;
2254		}
2255		(_instance = instance).trigger.apply(_instance, _toConsumableArray(args));
2256	};
2257
2258	var pubsub = {};
2259
2260	$.extend(true, Parsley, {
2261		asyncValidators: {
2262			'default': {
2263				fn: function fn(xhr) {
2264					// By default, only status 2xx are deemed successful.
2265					// Note: we use status instead of state() because responses with status 200
2266					// but invalid messages (e.g. an empty body for content type set to JSON) will
2267					// result in state() === 'rejected'.
2268					return xhr.status >= 200 && xhr.status < 300;
2269				},
2270				url: false
2271			},
2272			reverse: {
2273				fn: function fn(xhr) {
2274					// If reverse option is set, a failing ajax request is considered successful
2275					return xhr.status < 200 || xhr.status >= 300;
2276				},
2277				url: false
2278			}
2279		},
2280
2281		addAsyncValidator: function addAsyncValidator(name, fn, url, options) {
2282			Parsley.asyncValidators[name] = {
2283				fn: fn,
2284				url: url || false,
2285				options: options || {}
2286			};
2287
2288			return this;
2289		}
2290
2291	});
2292
2293	Parsley.addValidator('remote', {
2294		requirementType: {
2295			'': 'string',
2296			'validator': 'string',
2297			'reverse': 'boolean',
2298			'options': 'object'
2299		},
2300
2301		validateString: function validateString(value, url, options, instance) {
2302			var data = {};
2303			var ajaxOptions;
2304			var csr;
2305			var validator = options.validator || (true === options.reverse ? 'reverse' : 'default');
2306
2307			if ('undefined' === typeof Parsley.asyncValidators[validator]) throw new Error('Calling an undefined async validator: `' + validator + '`');
2308
2309			url = Parsley.asyncValidators[validator].url || url;
2310
2311			// Fill current value
2312			if (url.indexOf('{value}') > -1) {
2313				url = url.replace('{value}', encodeURIComponent(value));
2314			} else {
2315				data[instance.element.getAttribute('name') || instance.element.getAttribute('id')] = value;
2316			}
2317
2318			// Merge options passed in from the function with the ones in the attribute
2319			var remoteOptions = $.extend(true, options.options || {}, Parsley.asyncValidators[validator].options);
2320
2321			// All `$.ajax(options)` could be overridden or extended directly from DOM in `data-parsley-remote-options`
2322			ajaxOptions = $.extend(true, {}, {
2323				url: url,
2324				data: data,
2325				type: 'GET'
2326			}, remoteOptions);
2327
2328			// Generate store key based on ajax options
2329			instance.trigger('field:ajaxoptions', instance, ajaxOptions);
2330
2331			csr = $.param(ajaxOptions);
2332
2333			// Initialise querry cache
2334			if ('undefined' === typeof Parsley._remoteCache) Parsley._remoteCache = {};
2335
2336			// Try to retrieve stored xhr
2337			var xhr = Parsley._remoteCache[csr] = Parsley._remoteCache[csr] || $.ajax(ajaxOptions);
2338
2339			var handleXhr = function handleXhr() {
2340				var result = Parsley.asyncValidators[validator].fn.call(instance, xhr, url, options);
2341				if (!result) // Map falsy results to rejected promise
2342					result = $.Deferred().reject();
2343				return $.when(result);
2344			};
2345
2346			return xhr.then(handleXhr, handleXhr);
2347		},
2348
2349		priority: -1
2350	});
2351
2352	Parsley.on('form:submit', function () {
2353		Parsley._remoteCache = {};
2354	});
2355
2356	Base.prototype.addAsyncValidator = function () {
2357		Utils.warnOnce('Accessing the method `addAsyncValidator` through an instance is deprecated. Simply call `Parsley.addAsyncValidator(...)`');
2358		return Parsley.addAsyncValidator.apply(Parsley, arguments);
2359	};
2360
2361	// This is included with the Parsley library itself,
2362	// thus there is no use in adding it to your project.
2363	Parsley.addMessages('en', {
2364		defaultMessage: "This value seems to be invalid.",
2365		type: {
2366			email: "This value should be a valid email.",
2367			url: "This value should be a valid url.",
2368			number: "This value should be a valid number.",
2369			integer: "This value should be a valid integer.",
2370			digits: "This value should be digits.",
2371			alphanum: "This value should be alphanumeric."
2372		},
2373		notblank: "This value should not be blank.",
2374		required: "This value is required.",
2375		pattern: "This value seems to be invalid.",
2376		min: "This value should be greater than or equal to %s.",
2377		max: "This value should be lower than or equal to %s.",
2378		range: "This value should be between %s and %s.",
2379		minlength: "This value is too short. It should have %s characters or more.",
2380		maxlength: "This value is too long. It should have %s characters or fewer.",
2381		length: "This value length is invalid. It should be between %s and %s characters long.",
2382		mincheck: "You must select at least %s choices.",
2383		maxcheck: "You must select %s choices or fewer.",
2384		check: "You must select between %s and %s choices.",
2385		equalto: "This value should be the same."
2386	});
2387
2388	Parsley.setLocale('en');
2389
2390	/**
2391	 * inputevent - Alleviate browser bugs for input events
2392	 * https://github.com/marcandre/inputevent
2393	 * @version v0.0.3 - (built Thu, Apr 14th 2016, 5:58 pm)
2394	 * @author Marc-Andre Lafortune <[email protected]>
2395	 * @license MIT
2396	 */
2397
2398	function InputEvent() {
2399		var _this14 = this;
2400
2401		var globals = window || global;
2402
2403		// Slightly odd way construct our object. This way methods are force bound.
2404		// Used to test for duplicate library.
2405		_extends(this, {
2406
2407			// For browsers that do not support isTrusted, assumes event is native.
2408			isNativeEvent: function isNativeEvent(evt) {
2409				return evt.originalEvent && evt.originalEvent.isTrusted !== false;
2410			},
2411
2412			fakeInputEvent: function fakeInputEvent(evt) {
2413				if (_this14.isNativeEvent(evt)) {
2414					$(evt.target).trigger('input');
2415				}
2416			},
2417
2418			misbehaves: function misbehaves(evt) {
2419				if (_this14.isNativeEvent(evt)) {
2420					_this14.behavesOk(evt);
2421					$(document).on('change.inputevent', evt.data.selector, _this14.fakeInputEvent);
2422					_this14.fakeInputEvent(evt);
2423				}
2424			},
2425
2426			behavesOk: function behavesOk(evt) {
2427				if (_this14.isNativeEvent(evt)) {
2428					$(document) // Simply unbinds the testing handler
2429						.off('input.inputevent', evt.data.selector, _this14.behavesOk).off('change.inputevent', evt.data.selector, _this14.misbehaves);
2430				}
2431			},
2432
2433			// Bind the testing handlers
2434			install: function install() {
2435				if (globals.inputEventPatched) {
2436					return;
2437				}
2438				globals.inputEventPatched = '0.0.3';
2439				var _arr = ['select', 'input[type="checkbox"]', 'input[type="radio"]', 'input[type="file"]'];
2440				for (var _i = 0; _i < _arr.length; _i++) {
2441					var selector = _arr[_i];
2442					$(document).on('input.inputevent', selector, { selector: selector }, _this14.behavesOk).on('change.inputevent', selector, { selector: selector }, _this14.misbehaves);
2443				}
2444			},
2445
2446			uninstall: function uninstall() {
2447				delete globals.inputEventPatched;
2448				$(document).off('.inputevent');
2449			}
2450
2451		});
2452	};
2453
2454	var inputevent = new InputEvent();
2455
2456	inputevent.install();
2457
2458	var parsley = Parsley;
2459
2460	return parsley;
2461});
2462//# sourceMappingURL=parsley.js.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.