PageSourceSearch

https://live-red.mcphs.edu/Student/bundles/jqueryval?v=pFCBJc6dRX8YuaUenN6jDjgm_o0

js mcphs.edu collected 2026-09-24 09:39:11 UTC 125,008 bytes, 2,955 lines download raw bytes

1/*
2* This file has been commented to support Visual Studio Intellisense.
3* You should not use this file at runtime inside the browser--it is only
4* intended to be used only for design-time IntelliSense.  Please use the
5* standard jQuery library for all production use.
6
7* Comment version: 1.19.5
8*/
9
10/*
11* Note: While Microsoft is not the author of this file, Microsoft is
12* offering you a license subject to the terms of the Microsoft Software
13* License Terms for Microsoft ASP.NET Model View Controller 3.
14* Microsoft reserves all other rights. The notices below are provided
15* for informational purposes only and are not the license terms under
16* which Microsoft distributed this file.
17*
18* jQuery Validation Plugin - v1.19.5 - 12/5/2016
19* https://github.com/jzaefferer/jquery-validation
20* Copyright (c) 2013 J�rn Zaefferer; Licensed MIT
21*
22*/
23
24(function ($) {
25
26	$.extend($.fn, {
27		// http://docs.jquery.com/Plugins/Validation/validate
28		validate: function (options) {
29			/// <summary>
30			/// Validates the selected form. This method sets up event handlers for submit, focus,
31			/// keyup, blur and click to trigger validation of the entire form or individual
32			/// elements. Each one can be disabled, see the onxxx options (onsubmit, onfocusout,
33			/// onkeyup, onclick). focusInvalid focuses elements when submitting a invalid form.
34			/// </summary>
35			/// <param name="options" type="Object">
36			/// A set of key/value pairs that configure the validate. All options are optional.
37			/// </param>
38
39			// if nothing is selected, return nothing; can't chain anyway
40			if (!this.length) {
41				options && options.debug && window.console && console.warn("nothing selected, can't validate, returning nothing");
42				return;
43			}
44
45			// check if a validator for this form was already created
46			var validator = $.data(this[0], 'validator');
47			if (validator) {
48				return validator;
49			}
50
51			validator = new $.validator(options, this[0]);
52			$.data(this[0], 'validator', validator);
53
54			if (validator.settings.onsubmit) {
55
56				// allow suppresing validation by adding a cancel class to the submit button
57				this.find("input, button").filter(".cancel").click(function () {
58					validator.cancelSubmit = true;
59				});
60
61				// when a submitHandler is used, capture the submitting button
62				if (validator.settings.submitHandler) {
63					this.find("input, button").filter(":submit").click(function () {
64						validator.submitButton = this;
65					});
66				}
67
68				// validate the form on submit
69				this.submit(function (event) {
70					if (validator.settings.debug)
71						// prevent form submit to be able to see console output
72						event.preventDefault();
73
74					function handle() {
75						if (validator.settings.submitHandler) {
76							if (validator.submitButton) {
77								// insert a hidden input as a replacement for the missing submit button
78								var hidden = $("<input type='hidden'/>").attr("name", validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm);
79							}
80							validator.settings.submitHandler.call(validator, validator.currentForm);
81							if (validator.submitButton) {
82								// and clean up afterwards; thanks to no-block-scope, hidden can be referenced
83								hidden.remove();
84							}
85							return false;
86						}
87						return true;
88					}
89
90					// prevent submit for invalid forms or custom submit handlers
91					if (validator.cancelSubmit) {
92						validator.cancelSubmit = false;
93						return handle();
94					}
95					if (validator.form()) {
96						if (validator.pendingRequest) {
97							validator.formSubmitted = true;
98							return false;
99						}
100						return handle();
101					} else {
102						validator.focusInvalid();
103						return false;
104					}
105				});
106			}
107
108			return validator;
109		},
110		// http://docs.jquery.com/Plugins/Validation/valid
111		valid: function () {
112			/// <summary>
113			/// Checks if the selected form is valid or if all selected elements are valid.
114			/// validate() needs to be called on the form before checking it using this method.
115			/// </summary>
116			/// <returns type="Boolean" />
117
118			if ($(this[0]).is('form')) {
119				return this.validate().form();
120			} else {
121				var valid = true;
122				var validator = $(this[0].form).validate();
123				this.each(function () {
124					valid &= validator.element(this);
125				});
126				return valid;
127			}
128		},
129		// attributes: space seperated list of attributes to retrieve and remove
130		removeAttrs: function (attributes) {
131			/// <summary>
132			/// Remove the specified attributes from the first matched element and return them.
133			/// </summary>
134			/// <param name="attributes" type="String">
135			/// A space-seperated list of attribute names to remove.
136			/// </param>
137
138			var result = {},
139				$element = this;
140			$.each(attributes.split(/\s/), function (index, value) {
141				result[value] = $element.attr(value);
142				$element.removeAttr(value);
143			});
144			return result;
145		},
146		// http://docs.jquery.com/Plugins/Validation/rules
147		rules: function (command, argument) {
148			/// <summary>
149			/// Return the validations rules for the first selected element.
150			/// </summary>
151			/// <param name="command" type="String">
152			/// Can be either "add" or "remove".
153			/// </param>
154			/// <param name="argument" type="">
155			/// A list of rules to add or remove.
156			/// </param>
157
158			var element = this[0];
159
160			if (command) {
161				var settings = $.data(element.form, 'validator').settings;
162				var staticRules = settings.rules;
163				var existingRules = $.validator.staticRules(element);
164				switch (command) {
165					case "add":
166						$.extend(existingRules, $.validator.normalizeRule(argument));
167						staticRules[element.name] = existingRules;
168						if (argument.messages)
169							settings.messages[element.name] = $.extend(settings.messages[element.name], argument.messages);
170						break;
171					case "remove":
172						if (!argument) {
173							delete staticRules[element.name];
174							return existingRules;
175						}
176						var filtered = {};
177						$.each(argument.split(/\s/), function (index, method) {
178							filtered[method] = existingRules[method];
179							delete existingRules[method];
180						});
181						return filtered;
182				}
183			}
184
185			var data = $.validator.normalizeRules(
186				$.extend(
187					{},
188					$.validator.metadataRules(element),
189					$.validator.classRules(element),
190					$.validator.attributeRules(element),
191					$.validator.staticRules(element)
192				), element);
193
194			// make sure required is at front
195			if (data.required) {
196				var param = data.required;
197				delete data.required;
198				data = $.extend({ required: param }, data);
199			}
200
201			return data;
202		}
203	});
204
205	// Custom selectors
206	$.extend($.expr[":"], {
207		// http://docs.jquery.com/Plugins/Validation/blank
208		blank: function (a) { return !$.trim("" + a.value); },
209		// http://docs.jquery.com/Plugins/Validation/filled
210		filled: function (a) { return !!$.trim("" + a.value); },
211		// http://docs.jquery.com/Plugins/Validation/unchecked
212		unchecked: function (a) { return !a.checked; }
213	});
214
215	// constructor for validator
216	$.validator = function (options, form) {
217		this.settings = $.extend(true, {}, $.validator.defaults, options);
218		this.currentForm = form;
219		this.init();
220	};
221
222	$.validator.format = function (source, params) {
223		/// <summary>
224		/// Replaces {n} placeholders with arguments.
225		/// One or more arguments can be passed, in addition to the string template itself, to insert
226		/// into the string.
227		/// </summary>
228		/// <param name="source" type="String">
229		/// The string to format.
230		/// </param>
231		/// <param name="params" type="String">
232		/// The first argument to insert, or an array of Strings to insert
233		/// </param>
234		/// <returns type="String" />
235
236		if (arguments.length == 1)
237			return function () {
238				var args = $.makeArray(arguments);
239				args.unshift(source);
240				return $.validator.format.apply(this, args);
241			};
242		if (arguments.length > 2 && params.constructor != Array) {
243			params = $.makeArray(arguments).slice(1);
244		}
245		if (params.constructor != Array) {
246			params = [params];
247		}
248		$.each(params, function (i, n) {
249			source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n);
250		});
251		return source;
252	};
253
254	$.extend($.validator, {
255
256		defaults: {
257			messages: {},
258			groups: {},
259			rules: {},
260			errorClass: "error",
261			validClass: "valid",
262			errorElement: "label",
263			focusInvalid: true,
264			errorContainer: $([]),
265			errorLabelContainer: $([]),
266			onsubmit: true,
267			ignore: [],
268			ignoreTitle: false,
269			onfocusin: function (element) {
270				this.lastActive = element;
271
272				// hide error label and remove error class on focus if enabled
273				if (this.settings.focusCleanup && !this.blockFocusCleanup) {
274					this.settings.unhighlight && this.settings.unhighlight.call(this, element, this.settings.errorClass, this.settings.val
274idClass);
275					this.addWrapper(this.errorsFor(element)).hide();
276				}
277			},
278			onfocusout: function (element) {
279				if (!this.checkable(element) && (element.name in this.submitted || !this.optional(element))) {
280					this.element(element);
281				}
282			},
283			onkeyup: function (element) {
284				if (element.name in this.submitted || element == this.lastElement) {
285					this.element(element);
286				}
287			},
288			onclick: function (element) {
289				// click on selects, radiobuttons and checkboxes
290				if (element.name in this.submitted)
291					this.element(element);
292				// or option elements, check parent select in that case
293				else if (element.parentNode.name in this.submitted)
294					this.element(element.parentNode);
295			},
296			highlight: function (element, errorClass, validClass) {
297				$(element).addClass(errorClass).removeClass(validClass);
298			},
299			unhighlight: function (element, errorClass, validClass) {
300				$(element).removeClass(errorClass).addClass(validClass);
301			}
302		},
303
304		// http://docs.jquery.com/Plugins/Validation/Validator/setDefaults
305		setDefaults: function (settings) {
306			/// <summary>
307			/// Modify default settings for validation.
308			/// Accepts everything that Plugins/Validation/validate accepts.
309			/// </summary>
310			/// <param name="settings" type="Options">
311			/// Options to set as default.
312			/// </param>
313
314			$.extend($.validator.defaults, settings);
315		},
316
317		messages: {
318			required: "This field is required.",
319			remote: "Please fix this field.",
320			email: "Please enter a valid email address.",
321			url: "Please enter a valid URL.",
322			date: "Please enter a valid date.",
323			dateISO: "Please enter a valid date (ISO).",
324			number: "Please enter a valid number.",
325			digits: "Please enter only digits.",
326			creditcard: "Please enter a valid credit card number.",
327			equalTo: "Please enter the same value again.",
328			accept: "Please enter a value with a valid extension.",
329			maxlength: $.validator.format("Please enter no more than {0} characters."),
330			minlength: $.validator.format("Please enter at least {0} characters."),
331			rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."),
332			range: $.validator.format("Please enter a value between {0} and {1}."),
333			max: $.validator.format("Please enter a value less than or equal to {0}."),
334			min: $.validator.format("Please enter a value greater than or equal to {0}.")
335		},
336
337		autoCreateRanges: false,
338
339		prototype: {
340
341			init: function () {
342				this.labelContainer = $(this.settings.errorLabelContainer);
343				this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm);
344				this.containers = $(this.settings.errorContainer).add(this.settings.errorLabelContainer);
345				this.submitted = {};
346				this.valueCache = {};
347				this.pendingRequest = 0;
348				this.pending = {};
349				this.invalid = {};
350				this.reset();
351
352				var groups = (this.groups = {});
353				$.each(this.settings.groups, function (key, value) {
354					$.each(value.split(/\s/), function (index, name) {
355						groups[name] = key;
356					});
357				});
358				var rules = this.settings.rules;
359				$.each(rules, function (key, value) {
360					rules[key] = $.validator.normalizeRule(value);
361				});
362
363				function delegate(event) {
364					var validator = $.data(this[0].form, "validator"),
365						eventType = "on" + event.type.replace(/^validate/, "");
366					validator.settings[eventType] && validator.settings[eventType].call(validator, this[0]);
367				}
368				$(this.currentForm)
369					.validateDelegate(":text, :password, :file, select, textarea", "focusin focusout keyup", delegate)
370					.validateDelegate(":radio, :checkbox, select, option", "click", delegate);
371
372				if (this.settings.invalidHandler)
373					$(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);
374			},
375
376			// http://docs.jquery.com/Plugins/Validation/Validator/form
377			form: function () {
378				/// <summary>
379				/// Validates the form, returns true if it is valid, false otherwise.
380				/// This behaves as a normal submit event, but returns the result.
381				/// </summary>
382				/// <returns type="Boolean" />
383
384				this.checkForm();
385				$.extend(this.submitted, this.errorMap);
386				this.invalid = $.extend({}, this.errorMap);
387				if (!this.valid())
388					$(this.currentForm).triggerHandler("invalid-form", [this]);
389				this.showErrors();
390				return this.valid();
391			},
392
393			checkForm: function () {
394				this.prepareForm();
395				for (var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++) {
396					this.check(elements[i]);
397				}
398				return this.valid();
399			},
400
401			// http://docs.jquery.com/Plugins/Validation/Validator/element
402			element: function (element) {
403				/// <summary>
404				/// Validates a single element, returns true if it is valid, false otherwise.
405				/// This behaves as validation on blur or keyup, but returns the result.
406				/// </summary>
407				/// <param name="element" type="Selector">
408				/// An element to validate, must be inside the validated form.
409				/// </param>
410				/// <returns type="Boolean" />
411
412				element = this.clean(element);
413				this.lastElement = element;
414				this.prepareElement(element);
415				this.currentElements = $(element);
416				var result = this.check(element);
417				if (result) {
418					delete this.invalid[element.name];
419				} else {
420					this.invalid[element.name] = true;
421				}
422				if (!this.numberOfInvalids()) {
423					// Hide error containers on last error
424					this.toHide = this.toHide.add(this.containers);
425				}
426				this.showErrors();
427				return result;
428			},
429
430			// http://docs.jquery.com/Plugins/Validation/Validator/showErrors
431			showErrors: function (errors) {
432				/// <summary>
433				/// Show the specified messages.
434				/// Keys have to refer to the names of elements, values are displayed for those elements, using the configured error placement.
435				/// </summary>
436				/// <param name="errors" type="Object">
437				/// One or more key/value pairs of input names and messages.
438				/// </param>
439
440				if (errors) {
441					// add items to error list and map
442					$.extend(this.errorMap, errors);
443					this.errorList = [];
444					for (var name in errors) {
445						this.errorList.push({
446							message: errors[name],
447							element: this.findByName(name)[0]
448						});
449					}
450					// remove items from success list
451					this.successList = $.grep(this.successList, function (element) {
452						return !(element.name in errors);
453					});
454				}
455				this.settings.showErrors
456					? this.settings.showErrors.call(this, this.errorMap, this.errorList)
457					: this.defaultShowErrors();
458			},
459
460			// http://docs.jquery.com/Plugins/Validation/Validator/resetForm
461			resetForm: function () {
462				/// <summary>
463				/// Resets the controlled form.
464				/// Resets input fields to their original value (requires form plugin), removes classes
465				/// indicating invalid elements and hides error messages.
466				/// </summary>
467
468				if ($.fn.resetForm)
469					$(this.currentForm).resetForm();
470				this.submitted = {};
471				this.prepareForm();
472				this.hideErrors();
473				this.elements().removeClass(this.settings.errorClass);
474			},
475
476			numberOfInvalids: function () {
477				/// <summary>
478				/// Returns the number of invalid fields.
479				/// This depends on the internal validator state. It covers all fields only after
480				/// validating the complete form (on submit or via $("form").valid()). After validating
481				/// a single element, only that element is counted. Most useful in combination with the
482				/// invalidHandler-option.
483				/// </summary>
484				/// <returns type="Number" />
485
486				return this.objectLength(this.invalid);
487			},
488
489			objectLength: function (obj) {
490				var count = 0;
491				for (var i in obj)
492					count++;
493				return count;
494			},
495
496			hideErrors: function () {
497				this.addWrapper(this.toHide).hide();
498			},
499
500			valid: function () {
501				return this.size() == 0;
502			},
503
504			size: function () {
505				return this.errorList.length;
506			},
507
508			focusInvalid: function () {
509				if (this.settings.focusInvalid) {
510					try {
511						$(this.findLastActive() || this.errorList.length && this.errorList[0].element || [])
512							.filter(":visible")
513							.focus()
514							// manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
515							.trigger("focusin");
516					} catch (e) {
517						// ignore IE throwing errors when focusing hidden elements
518					}
519				}
520			},
521
522			findLastActive: function () {
523				var lastActive = this.lastActive;
524				return lastActive && $.grep(this.errorList, function (n) {
525					return n.element.name == lastActive.name;
526				}).length == 1 && lastActive;
527			},
528
529			elements: function () {
530				var validator = this,
531					rulesCache = {};
532
533				// select all valid inputs inside the form (no submit or reset buttons)
534				// workaround $Query([]).add until http://dev.jquery.com/ticket/2114 is solved
535				return $([]).add(this.currentForm.elements)
536					.filter(":input")
537					.not(":submit, :reset, :image, [disabled]")
538					.not(this.settings.ignore)
539					.filter(function () {
540						!this.name && validator.settings.debug && window.console && console.error("%o has no name assigned", this);
541
542						// select only the first element for each name, and only those with rules specified
543						if (this.name in rulesCache || !validator.objectLength($(this).rules()))
544							return false;
545
546						rulesCache[this.name] = true;
547						return true;
548					});
549			},
550
551			clean: function (selector) {
552				return $(selector)[0];
553			},
554
555			errors: function () {
556				return $(this.settings.errorElement + "." + this.settings.errorClass, this.errorContext);
557			},
558
559			reset: function () {
560				this.successList = [];
561				this.errorList = [];
562				this.errorMap = {};
563				this.toShow = $([]);
564				this.toHide = $([]);
565				this.currentElements = $([]);
566			},
567
568			prepareForm: function () {
569				this.reset();
570				this.toHide = this.errors().add(this.containers);
571			},
572
573			prepareElement: function (element) {
574				this.reset();
575				this.toHide = this.errorsFor(element);
576			},
577
578			check: function (element) {
579				element = this.clean(element);
580
581				// if radio/checkbox, validate first element in group instead
582				if (this.checkable(element)) {
583					element = this.findByName(element.name).not(this.settings.ignore)[0];
584				}
585
586				var rules = $(element).rules();
587				var dependencyMismatch = false;
588				for (var method in rules) {
589					var rule = { method: method, parameters: rules[method] };
590					try {
591						var result = $.validator.methods[method].call(this, element.value.replace(/\r/g, ""), element, rule.parameters);
592
593						// if a method indicates that the field is optional and therefore valid,
594						// don't mark it as valid when there are no other rules
595						if (result == "dependency-mismatch") {
596							dependencyMismatch = true;
597							continue;
598						}
599						dependencyMismatch = false;
600
601						if (result == "pending") {
602							this.toHide = this.toHide.not(this.errorsFor(element));
603							return;
604						}
605
606						if (!result) {
607							this.formatAndAdd(element, rule);
608							return false;
609						}
610					} catch (e) {
611						this.settings.debug && window.console && console.log("exception occured when checking element " + element.id
612							+ ", check the '" + rule.method + "' method", e);
613						throw e;
614					}
615				}
616				if (dependencyMismatch)
617					return;
618				if (this.objectLength(rules))
619					this.successList.push(element);
620				return true;
621			},
622
623			// return the custom message for the given element and validation method
624			// specified in the element's "messages" metadata
625			customMetaMessage: function (element, method) {
626				if (!$.metadata)
627					return;
628
629				var meta = this.settings.meta
630					? $(element).metadata()[this.settings.meta]
631					: $(element).metadata();
632
633				return meta && meta.messages && meta.messages[method];
634			},
635
636			// return the custom message for the given element name and validation method
637			customMessage: function (name, method) {
638				var m = this.settings.messages[name];
639				return m && (m.constructor == String
640					? m
641					: m[method]);
642			},
643
644			// return the first defined argument, allowing empty strings
645			findDefined: function () {
646				for (var i = 0; i < arguments.length; i++) {
647					if (arguments[i] !== undefined)
648						return arguments[i];
649				}
650				return undefined;
651			},
652
653			defaultMessage: function (element, method) {
654				return this.findDefined(
655					this.customMessage(element.name, method),
656					this.customMetaMessage(element, method),
657					// title is never undefined, so handle empty string as undefined
658					!this.settings.ignoreTitle && element.title || undefined,
659					$.validator.messages[method],
660					"<strong>Warning: No message defined for " + element.name + "</strong>"
661				);
662			},
663
664			formatAndAdd: function (element, rule) {
665				var message = this.defaultMessage(element, rule.method),
666					theregex = /\$?\{(\d+)\}/g;
667				if (typeof message == "function") {
668					message = message.call(this, rule.parameters, element);
669				} else if (theregex.test(message)) {
670					message = jQuery.format(message.replace(theregex, '{$1}'), rule.parameters);
671				}
672				this.errorList.push({
673					message: message,
674					element: element
675				});
676
677				this.errorMap[element.name] = message;
678				this.submitted[element.name] = message;
679			},
680
681			addWrapper: function (toToggle) {
682				if (this.settings.wrapper)
683					toToggle = toToggle.add(toToggle.parent(this.settings.wrapper));
684				return toToggle;
685			},
686
687			defaultShowErrors: function () {
688				for (var i = 0; this.errorList[i]; i++) {
689					var error = this.errorList[i];
690					this.settings.highlight && this.settings.highlight.call(this, error.element, this.settings.errorClass, this.settings.validClass);
691					this.showLabel(error.element, error.message);
692				}
693				if (this.errorList.length) {
694					this.toShow = this.toShow.add(this.containers);
695				}
696				if (this.settings.success) {
697					for (var i = 0; this.successList[i]; i++) {
698						this.showLabel(this.successList[i]);
699					}
700				}
701				if (this.settings.unhighlight) {
702					for (var i = 0, elements = this.validElements(); elements[i]; i++) {
703						this.settings.unhighlight.call(this, elements[i], this.settings.errorClass, this.settings.validClass);
704					}
705				}
706				this.toHide = this.toHide.not(this.toShow);
707				this.hideErrors();
708				this.addWrapper(this.toShow).show();
709			},
710
711			validElements: function () {
712				return this.currentElements.not(this.invalidElements());
713			},
714
715			invalidElements: function () {
716				return $(this.errorList).map(function () {
717					return this.element;
718				});
719			},
720
721			showLabel: function (element, message) {
722				var label = this.errorsFor(element);
723				if (label.length) {
724					// refresh error/success class
725					label.removeClass().addClass(this.settings.errorClass);
726
727					// check if we have a generated label, replace the message then
728					label.attr("generated") && label.html(message);
729				} else {
730					// create label
731					label = $("<" + this.settings.errorElement + "/>")
732						.attr({ "for": this.idOrName(element), generated: true })
733						.addClass(this.settings.errorClass)
734						.html(message || "");
735					if (this.settings.wrapper) {
736						// make sure the element is visible, even in IE
737						// actually showing the wrapped element is handled elsewhere
738						label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
739					}
740					if (!this.labelContainer.append(label).length)
741						this.settings.errorPlacement
742							? this.settings.errorPlacement(label, $(element))
743							: label.insertAfter(element);
744				}
745				if (!message && this.settings.success) {
746					label.text("");
747					typeof this.settings.success == "string"
748						? label.addClass(this.settings.success)
749						: this.settings.success(label);
750				}
751				this.toShow = this.toShow.add(label);
752			},
753
754			errorsFor: function (element) {
755				var name = this.idOrName(element);
756				return this.errors().filter(function () {
757					return $(this).attr('for') == name;
758				});
759			},
760
761			idOrName: function (element) {
762				return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name);
763			},
764
765			checkable: function (element) {
766				return /radio|checkbox/i.test(element.type);
767			},
768
769			findByName: function (name) {
770				// select by name and filter by form for performance over form.find("[name=...]")
771				var form = this.currentForm;
772				return $(document.getElementsByName(name)).map(function (index, element) {
773					return element.form == form && element.name == name && element || null;
774				});
775			},
776
777			getLength: function (value, element) {
778				switch (element.nodeName.toLowerCase()) {
779					case 'select':
780						return $("option:selected", element).length;
781					case 'input':
782						if (this.checkable(element))
783							return this.findByName(element.name).filter(':checked').length;
784				}
785				return value.length;
786			},
787
788			depend: function (param, element) {
789				return this.dependTypes[typeof param]
790					? this.dependTypes[typeof param](param, element)
791					: true;
792			},
793
794			dependTypes: {
795				"boolean": function (param, element) {
796					return param;
797				},
798				"string": function (param, element) {
799					return !!$(param, element.form).length;
800				},
801				"function": function (param, element) {
802					return param(element);
803				}
804			},
805
806			optional: function (element) {
807				return !$.validator.methods.required.call(this, $.trim(element.value), element) && "dependency-mismatch";
808			},
809
810			startRequest: function (element) {
811				if (!this.pending[element.name]) {
812					this.pendingRequest++;
813					this.pending[element.name] = true;
814				}
815			},
816
817			stopRequest: function (element, valid) {
818				this.pendingRequest--;
819				// sometimes synchronization fails, make sure pendingRequest is never < 0
820				if (this.pendingRequest < 0)
821					this.pendingRequest = 0;
822				delete this.pending[element.name];
823				if (valid && this.pendingRequest == 0 && this.formSubmitted && this.form()) {
824					$(this.currentForm).submit();
825					this.formSubmitted = false;
826				} else if (!valid && this.pendingRequest == 0 && this.formSubmitted) {
827					$(this.currentForm).triggerHandler("invalid-form", [this]);
828					this.formSubmitted = false;
829				}
830			},
831
832			previousValue: function (element) {
833				return $.data(element, "previousValue") || $.data(element, "previousValue", {
834					old: null,
835					valid: true,
836					message: this.defaultMessage(element, "remote")
837				});
838			}
839
840		},
841
842		classRuleSettings: {
843			required: { required: true },
844			email: { email: true },
845			url: { url: true },
846			date: { date: true },
847			dateISO: { dateISO: true },
848			dateDE: { dateDE: true },
849			number: { number: true },
850			numberDE: { numberDE: true },
851			digits: { digits: true },
852			creditcard: { creditcard: true }
853		},
854
855		addClassRules: function (className, rules) {
856			/// <summary>
857			/// Add a compound class method - useful to refactor common combinations of rules into a single
858			/// class.
859			/// </summary>
860			/// <param name="name" type="String">
861			/// The name of the class rule to add
862			/// </param>
863			/// <param name="rules" type="Options">
864			/// The compound rules
865			/// </param>
866
867			className.constructor == String ?
868				this.classRuleSettings[className] = rules :
869				$.extend(this.classRuleSettings, className);
870		},
871
872		classRules: function (element) {
873			var rules = {};
874			var classes = $(element).attr('class');
875			classes && $.each(classes.split(' '), function () {
876				if (this in $.validator.classRuleSettings) {
877					$.extend(rules, $.validator.classRuleSettings[this]);
878				}
879			});
880			return rules;
881		},
882
883		attributeRules: function (element) {
884			var rules = {};
885			var $element = $(element);
886
887			for (var method in $.validator.methods) {
888				var value = $element.attr(method);
889				if (value) {
890					rules[method] = value;
891				}
892			}
893
894			// maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs
895			if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) {
896				delete rules.maxlength;
897			}
898
899			return rules;
900		},
901
902		metadataRules: function (element) {
903			if (!$.metadata) return {};
904
905			var meta = $.data(element.form, 'validator').settings.meta;
906			return meta ?
907				$(element).metadata()[meta] :
908				$(element).metadata();
909		},
910
911		staticRules: function (element) {
912			var rules = {};
913			var validator = $.data(element.form, 'validator');
914			if (validator.settings.rules) {
915				rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {};
916			}
917			return rules;
918		},
919
920		normalizeRules: function (rules, element) {
921			// handle dependency check
922			$.each(rules, function (prop, val) {
923				// ignore rule when param is explicitly false, eg. required:false
924				if (val === false) {
925					delete rules[prop];
926					return;
927				}
928				if (val.param || val.depends) {
929					var keepRule = true;
930					switch (typeof val.depends) {
931						case "string":
932							keepRule = !!$(val.depends, element.form).length;
933							break;
934						case "function":
935							keepRule = val.depends.call(element, element);
936							break;
937					}
938					if (keepRule) {
939						rules[prop] = val.param !== undefined ? val.param : true;
940					} else {
941						delete rules[prop];
942					}
943				}
944			});
945
946			// evaluate parameters
947			$.each(rules, function (rule, parameter) {
948				rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter;
949			});
950
951			// clean number parameters
952			$.each(['minlength', 'maxlength', 'min', 'max'], function () {
953				if (rules[this]) {
954					rules[this] = Number(rules[this]);
955				}
956			});
957			$.each(['rangelength', 'range'], function () {
958				if (rules[this]) {
959					rules[this] = [Number(rules[this][0]), Number(rules[this][1])];
960				}
961			});
962
963			if ($.validator.autoCreateRanges) {
964				// auto-create ranges
965				if (rules.min && rules.max) {
966					rules.range = [rules.min, rules.max];
967					delete rules.min;
968					delete rules.max;
969				}
970				if (rules.minlength && rules.maxlength) {
971					rules.rangelength = [rules.minlength, rules.maxlength];
972					delete rules.minlength;
973					delete rules.maxlength;
974				}
975			}
976
977			// To support custom messages in metadata ignore rule methods titled "messages"
978			if (rules.messages) {
979				delete rules.messages;
980			}
981
982			return rules;
983		},
984
985		// Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
986		normalizeRule: function (data) {
987			if (typeof data == "string") {
988				var transformed = {};
989				$.each(data.split(/\s/), function () {
990					transformed[this] = true;
991				});
992				data = transformed;
993			}
994			return data;
995		},
996
997		// http://docs.jquery.com/Plugins/Validation/Validator/addMethod
998		addMethod: function (name, method, message) {
999			/// <summary>
1000			/// Add a custom validation method. It must consist of a name (must be a legal javascript 
1001			/// identifier), a javascript based function and a default string message.
1002			/// </summary>
1003			/// <param name="name" type="String">
1004			/// The name of the method, used to identify and referencing it, must be a valid javascript
1005			/// identifier
1006			/// </param>
1007			/// <param name="method" type="Function">
1008			/// The actual method implementation, returning true if an element is valid
1009			/// </param>
1010			/// <param name="message" type="String" optional="true">
1011			/// (Optional) The default message to display for this method. Can be a function created by 
1012			/// jQuery.validator.format(value). When undefined, an already existing message is used 
1013			/// (handy for localization), otherwise the field-specific messages have to be defined.
1014			/// </param>
1015
1016			$.validator.methods[name] = method;
1017			$.validator.messages[name] = message != undefined ? message : $.validator.messages[name];
1018			if (method.length < 3) {
1019				$.validator.addClassRules(name, $.validator.normalizeRule(name));
1020			}
1021		},
1022
1023		methods: {
1024
1025			// http://docs.jquery.com/Plugins/Validation/Methods/required
1026			required: function (value, element, param) {
1027				// check if dependency is met
1028				if (!this.depend(param, element))
1029					return "dependency-mismatch";
1030				switch (element.nodeName.toLowerCase()) {
1031					case 'select':
1032						// could be an array for select-multiple or a string, both are fine this way
1033						var val = $(element).val();
1034						return val && val.length > 0;
1035					case 'input':
1036						if (this.checkable(element))
1037							return this.getLength(value, element) > 0;
1038					default:
1039						return $.trim(value).length > 0;
1040				}
1041			},
1042
1043			// http://docs.jquery.com/Plugins/Validation/Methods/remote
1044			remote: function (value, element, param) {
1045				if (this.optional(element))
1046					return "dependency-mismatch";
1047
1048				var previous = this.previousValue(element);
1049				if (!this.settings.messages[element.name])
1050					this.settings.messages[element.name] = {};
1051				previous.originalMessage = this.settings.messages[element.name].remote;
1052				this.settings.messages[element.name].remote = previous.message;
1053
1054				param = typeof param == "string" && { url: param } || param;
1055
1056				if (this.pending[element.name]) {
1057					return "pending";
1058				}
1059				if (previous.old === value) {
1060					return previous.valid;
1061				}
1062
1063				previous.old = value;
1064				var validator = this;
1065				this.startRequest(element);
1066				var data = {};
1067				data[element.name] = value;
1068				$.ajax($.extend(true, {
1069					url: param,
1070					mode: "abort",
1071					port: "validate" + element.name,
1072					dataType: "json",
1073					data: data,
1074					success: function (response) {
1075						validator.settings.messages[element.name].remote = previous.originalMessage;
1076						var valid = response === true;
1077						if (valid) {
1078							var submitted = validator.formSubmitted;
1079							validator.prepareElement(element);
1080							validator.formSubmitted = submitted;
1081							validator.successList.push(element);
1082							validator.showErrors();
1083						} else {
1084							var errors = {};
1085							var message = response || validator.defaultMessage(element, "remote");
1086							errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message;
1087							validator.showErrors(errors);
1088						}
1089						previous.valid = valid;
1090						validator.stopRequest(element, valid);
1091					}
1092				}, param));
1093				return "pending";
1094			},
1095
1096			// http://docs.jquery.com/Plugins/Validation/Methods/minlength
1097			minlength: function (value, element, param) {
1098				return this.optional(element) || this.getLength($.trim(value), element) >= param;
1099			},
1100
1101			// http://docs.jquery.com/Plugins/Validation/Methods/maxlength
1102			maxlength: function (value, element, param) {
1103				return this.optional(element) || this.getLength($.trim(value), element) <= param;
1104			},
1105
1106			// http://docs.jquery.com/Plugins/Validation/Methods/rangelength
1107			rangelength: function (value, element, param) {
1108				var length = this.getLength($.trim(value), element);
1109				return this.optional(element) || (length >= param[0] && length <= param[1]);
1110			},
1111
1112			// http://docs.jquery.com/Plugins/Validation/Methods/min
1113			min: function (value, element, param) {
1114				return this.optional(element) || value >= param;
1115			},
1116
1117			// http://docs.jquery.com/Plugins/Validation/Methods/max
1118			max: function (value, element, param) {
1119				return this.optional(element) || value <= param;
1120			},
1121
1122			// http://docs.jquery.com/Plugins/Validation/Methods/range
1123			range: function (value, element, param) {
1124				return this.optional(element) || (value >= param[0] && value <= param[1]);
1125			},
1126
1127			// http://docs.jquery.com/Plugins/Validation/Methods/email
1128			email: function (value, element) {
1129				// contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
1130				return this.optional(element) || /^((([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.test(value);
1131			},
1132
1133			// http://docs.jquery.com/Plugins/Validation/Methods/url
1134			url: function (value, element) {
1135				// contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
1136				return this.optional(element) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([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])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
1137			},
1138
1139			// http://docs.jquery.com/Plugins/Validation/Methods/date
1140			date: function (value, element) {
1141				return this.optional(element) || !/Invalid|NaN/.test(new Date(value));
1142			},
1143
1144			// http://docs.jquery.com/Plugins/Validation/Methods/dateISO
1145			dateISO: function (value, element) {
1146				return this.optional(element) || /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value);
1147			},
1148
1149			// http://docs.jquery.com/Plugins/Validation/Methods/number
1150			number: function (value, element) {
1151				return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value);
1152			},
1153
1154			// http://docs.jquery.com/Plugins/Validation/Methods/digits
1155			digits: function (value, element) {
1156				return this.optional(element) || /^\d+$/.test(value);
1157			},
1158
1159			// http://docs.jquery.com/Plugins/Validation/Methods/creditcard
1160			// based on http://en.wikipedia.org/wiki/Luhn
1161			creditcard: function (value, element) {
1162				if (this.optional(element))
1163					return "dependency-mismatch";
1164				// accept only digits and dashes
1165				if (/[^0-9-]+/.test(value))
1166					return false;
1167				var nCheck = 0,
1168					nDigit = 0,
1169					bEven = false;
1170
1171				value = value.replace(/\D/g, "");
1172
1173				for (var n = value.length - 1; n >= 0; n--) {
1174					var cDigit = value.charAt(n);
1175					var nDigit = parseInt(cDigit, 10);
1176					if (bEven) {
1177						if ((nDigit *= 2) > 9)
1178							nDigit -= 9;
1179					}
1180					nCheck += nDigit;
1181					bEven = !bEven;
1182				}
1183
1184				return (nCheck % 10) == 0;
1185			},
1186
1187			// http://docs.jquery.com/Plugins/Validation/Methods/accept
1188			accept: function (value, element, param) {
1189				param = typeof param == "string" ? param.replace(/,/g, '|') : "png|jpe?g|gif";
1190				return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i"));
1191			},
1192
1193			// http://docs.jquery.com/Plugins/Validation/Methods/equalTo
1194			equalTo: function (value, element, param) {
1195				// bind to the blur event of the target in order to revalidate whenever the target field is updated
1196				// TODO find a way to bind the event just once, avoiding the unbind-rebind overhead
1197				var target = $(param).unbind(".validate-equalTo").bind("blur.validate-equalTo", function () {
1198					$(element).valid();
1199				});
1200				return value == target.val();
1201			}
1202
1203		}
1204
1205	});
1206
1207	// deprecated, use $.validator.format instead
1208	$.format = $.validator.format;
1209
1210})(jQuery);
1211
1212// ajax mode: abort
1213// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
1214// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() 
1215; (function ($) {
1216	var pendingRequests = {};
1217	// Use a prefilter if available (1.5+)
1218	if ($.ajaxPrefilter) {
1219		$.ajaxPrefilter(function (settings, _, xhr) {
1220			var port = settings.port;
1221			if (settings.mode == "abort") {
1222				if (pendingRequests[port]) {
1223					pendingRequests[port].abort();
1224				} pendingRequests[port] = xhr;
1225			}
1226		});
1227	} else {
1228		// Proxy ajax
1229		var ajax = $.ajax;
1230		$.ajax = function (settings) {
1231			var mode = ("mode" in settings ? settings : $.ajaxSettings).mode,
1232				port = ("port" in settings ? settings : $.ajaxSettings).port;
1233			if (mode == "abort") {
1234				if (pendingRequests[port]) {
1235					pendingRequests[port].abort();
1236				}
1237
1238				return (pendingRequests[port] = ajax.apply(this, arguments));
1239			}
1240			return ajax.apply(this, arguments);
1241		};
1242	}
1243})(jQuery);
1244
1245// provides cross-browser focusin and focusout events
1246// IE has native support, in other browsers, use event caputuring (neither bubbles)
1247
1248// provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
1249// handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target 
1250; (function ($) {
1251	// only implement if not provided by jQuery core (since 1.4)
1252	// TODO verify if jQuery 1.4's implementation is compatible with older jQuery special-event APIs
1253	if (!jQuery.event.special.focusin && !jQuery.event.special.focusout && document.addEventListener) {
1254		$.each({
1255			focus: 'focusin',
1256			blur: 'focusout'
1257		}, function (original, fix) {
1258			$.event.special[fix] = {
1259				setup: function () {
1260					this.addEventListener(original, handler, true);
1261				},
1262				teardown: function () {
1263					this.removeEventListener(original, handler, true);
1264				},
1265				handler: function (e) {
1266					arguments[0] = $.event.fix(e);
1267					arguments[0].type = fix;
1268					return $.event.handle.apply(this, arguments);
1269				}
1270			};
1271			function handler(e) {
1272				e = $.event.fix(e);
1273				e.type = fix;
1274				return $.event.handle.call(this, e);
1275			}
1276		});
1277	};
1278	$.extend($.fn, {
1279		validateDelegate: function (delegate, type, handler) {
1280			return this.bind(type, function (event) {
1281				var target = $(event.target);
1282				if (target.is(delegate)) {
1283					return handler.apply(target, arguments);
1284				}
1285			});
1286		}
1287	});
1288})(jQuery);
1289
1290/*!
1291 * jQuery Validation Plugin v1.19.5
1292 *
1293 * https://jqueryvalidation.org/
1294 *
1295 * Copyright (c) 2022 Jörn Zaefferer
1296 * Released under the MIT license
1297 */
1298(function( factory ) {
1299	if ( typeof define === "function" && define.amd ) {
1300		define( ["jquery"], factory );
1301	} else if (typeof module === "object" && module.exports) {
1302		module.exports = factory( require( "jquery" ) );
1303	} else {
1304		factory( jQuery );
1305	}
1306}(function( $ ) {
1307
1308$.extend( $.fn, {
1309
1310	// https://jqueryvalidation.org/validate/
1311	validate: function( options ) {
1312
1313		// If nothing is selected, return nothing; can't chain anyway
1314		if ( !this.length ) {
1315			if ( options && options.debug && window.console ) {
1316				console.warn( "Nothing selected, can't validate, returning nothing." );
1317			}
1318			return;
1319		}
1320
1321		// Check if a validator for this form was already created
vendor: 49,688 bytes, lines 1322-2874
1322		var validator = $.data( this[ 0 ], "validator" );
1323		if ( validator ) {
1324			return validator;
1325		}
1326
1327		// Add novalidate tag if HTML5.
1328		this.attr( "novalidate", "novalidate" );
1329
1330		validator = new $.validator( options, this[ 0 ] );
1331		$.data( this[ 0 ], "validator", validator );
1332
1333		if ( validator.settings.onsubmit ) {
1334
1335			this.on( "click.validate", ":submit", function( event ) {
1336
1337				// Track the used submit button to properly handle scripted
1338				// submits later.
1339				validator.submitButton = event.currentTarget;
1340
1341				// Allow suppressing validation by adding a cancel class to the submit button
1342				if ( $( this ).hasClass( "cancel" ) ) {
1343					validator.cancelSubmit = true;
1344				}
1345
1346				// Allow suppressing validation by adding the html5 formnovalidate attribute to the submit button
1347				if ( $( this ).attr( "formnovalidate" ) !== undefined ) {
1348					validator.cancelSubmit = true;
1349				}
1350			} );
1351
1352			// Validate the form on submit
1353			this.on( "submit.validate", function( event ) {
1354				if ( validator.settings.debug ) {
1355
1356					// Prevent form submit to be able to see console output
1357					event.preventDefault();
1358				}
1359
1360				function handle() {
1361					var hidden, result;
1362
1363					// Insert a hidden input as a replacement for the missing submit button
1364					// The hidden input is inserted in two cases:
1365					//   - A user defined a `submitHandler`
1366					//   - There was a pending request due to `remote` method and `stopRequest()`
1367					//     was called to submit the form in case it's valid
1368					if ( validator.submitButton && ( validator.settings.submitHandler || validator.formSubmitted ) ) {
1369						hidden = $( "<input type='hidden'/>" )
1370							.attr( "name", validator.submitButton.name )
1371							.val( $( validator.submitButton ).val() )
1372							.appendTo( validator.currentForm );
1373					}
1374
1375					if ( validator.settings.submitHandler && !validator.settings.debug ) {
1376						result = validator.settings.submitHandler.call( validator, validator.currentForm, event );
1377						if ( hidden ) {
1378
1379							// And clean up afterwards; thanks to no-block-scope, hidden can be referenced
1380							hidden.remove();
1381						}
1382						if ( result !== undefined ) {
1383							return result;
1384						}
1385						return false;
1386					}
1387					return true;
1388				}
1389
1390				// Prevent submit for invalid forms or custom submit handlers
1391				if ( validator.cancelSubmit ) {
1392					validator.cancelSubmit = false;
1393					return handle();
1394				}
1395				if ( validator.form() ) {
1396					if ( validator.pendingRequest ) {
1397						validator.formSubmitted = true;
1398						return false;
1399					}
1400					return handle();
1401				} else {
1402					validator.focusInvalid();
1403					return false;
1404				}
1405			} );
1406		}
1407
1408		return validator;
1409	},
1410
1411	// https://jqueryvalidation.org/valid/
1412	valid: function() {
1413		var valid, validator, errorList;
1414
1415		if ( $( this[ 0 ] ).is( "form" ) ) {
1416			valid = this.validate().form();
1417		} else {
1418			errorList = [];
1419			valid = true;
1420			validator = $( this[ 0 ].form ).validate();
1421			this.each( function() {
1422				valid = validator.element( this ) && valid;
1423				if ( !valid ) {
1424					errorList = errorList.concat( validator.errorList );
1425				}
1426			} );
1427			validator.errorList = errorList;
1428		}
1429		return valid;
1430	},
1431
1432	// https://jqueryvalidation.org/rules/
1433	rules: function( command, argument ) {
1434		var element = this[ 0 ],
1435			isContentEditable = typeof this.attr( "contenteditable" ) !== "undefined" && this.attr( "contenteditable" ) !== "false",
1436			settings, staticRules, existingRules, data, param, filtered;
1437
1438		// If nothing is selected, return empty object; can't chain anyway
1439		if ( element == null ) {
1440			return;
1441		}
1442
1443		if ( !element.form && isContentEditable ) {
1444			element.form = this.closest( "form" )[ 0 ];
1445			element.name = this.attr( "name" );
1446		}
1447
1448		if ( element.form == null ) {
1449			return;
1450		}
1451
1452		if ( command ) {
1453			settings = $.data( element.form, "validator" ).settings;
1454			staticRules = settings.rules;
1455			existingRules = $.validator.staticRules( element );
1456			switch ( command ) {
1457			case "add":
1458				$.extend( existingRules, $.validator.normalizeRule( argument ) );
1459
1460				// Remove messages from rules, but allow them to be set separately
1461				delete existingRules.messages;
1462				staticRules[ element.name ] = existingRules;
1463				if ( argument.messages ) {
1464					settings.messages[ element.name ] = $.extend( settings.messages[ element.name ], argument.messages );
1465				}
1466				break;
1467			case "remove":
1468				if ( !argument ) {
1469					delete staticRules[ element.name ];
1470					return existingRules;
1471				}
1472				filtered = {};
1473				$.each( argument.split( /\s/ ), function( index, method ) {
1474					filtered[ method ] = existingRules[ method ];
1475					delete existingRules[ method ];
1476				} );
1477				return filtered;
1478			}
1479		}
1480
1481		data = $.validator.normalizeRules(
1482		$.extend(
1483			{},
1484			$.validator.classRules( element ),
1485			$.validator.attributeRules( element ),
1486			$.validator.dataRules( element ),
1487			$.validator.staticRules( element )
1488		), element );
1489
1490		// Make sure required is at front
1491		if ( data.required ) {
1492			param = data.required;
1493			delete data.required;
1494			data = $.extend( { required: param }, data );
1495		}
1496
1497		// Make sure remote is at back
1498		if ( data.remote ) {
1499			param = data.remote;
1500			delete data.remote;
1501			data = $.extend( data, { remote: param } );
1502		}
1503
1504		return data;
1505	}
1506} );
1507
1508// JQuery trim is deprecated, provide a trim method based on String.prototype.trim
1509var trim = function( str ) {
1510
1511	// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trim#Polyfill
1512	return str.replace( /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, "" );
1513};
1514
1515// Custom selectors
1516$.extend( $.expr.pseudos || $.expr[ ":" ], {		// '|| $.expr[ ":" ]' here enables backwards compatibility to jQuery 1.7. Can be removed when dropping jQ 1.7.x support
1517
1518	// https://jqueryvalidation.org/blank-selector/
1519	blank: function( a ) {
1520		return !trim( "" + $( a ).val() );
1521	},
1522
1523	// https://jqueryvalidation.org/filled-selector/
1524	filled: function( a ) {
1525		var val = $( a ).val();
1526		return val !== null && !!trim( "" + val );
1527	},
1528
1529	// https://jqueryvalidation.org/unchecked-selector/
1530	unchecked: function( a ) {
1531		return !$( a ).prop( "checked" );
1532	}
1533} );
1534
1535// Constructor for validator
1536$.validator = function( options, form ) {
1537	this.settings = $.extend( true, {}, $.validator.defaults, options );
1538	this.currentForm = form;
1539	this.init();
1540};
1541
1542// https://jqueryvalidation.org/jQuery.validator.format/
1543$.validator.format = function( source, params ) {
1544	if ( arguments.length === 1 ) {
1545		return function() {
1546			var args = $.makeArray( arguments );
1547			args.unshift( source );
1548			return $.validator.format.apply( this, args );
1549		};
1550	}
1551	if ( params === undefined ) {
1552		return source;
1553	}
1554	if ( arguments.length > 2 && params.constructor !== Array  ) {
1555		params = $.makeArray( arguments ).slice( 1 );
1556	}
1557	if ( params.constructor !== Array ) {
1558		params = [ params ];
1559	}
1560	$.each( params, function( i, n ) {
1561		source = source.replace( new RegExp( "\\{" + i + "\\}", "g" ), function() {
1562			return n;
1563		} );
1564	} );
1565	return source;
1566};
1567
1568$.extend( $.validator, {
1569
1570	defaults: {
1571		messages: {},
1572		groups: {},
1573		rules: {},
1574		errorClass: "error",
1575		pendingClass: "pending",
1576		validClass: "valid",
1577		errorElement: "label",
1578		focusCleanup: false,
1579		focusInvalid: true,
1580		errorContainer: $( [] ),
1581		errorLabelContainer: $( [] ),
1582		onsubmit: true,
1583		ignore: ":hidden",
1584		ignoreTitle: false,
1585		onfocusin: function( element ) {
1586			this.lastActive = element;
1587
1588			// Hide error label and remove error class on focus if enabled
1589			if ( this.settings.focusCleanup ) {
1590				if ( this.settings.unhighlight ) {
1591					this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
1592				}
1593				this.hideThese( this.errorsFor( element ) );
1594			}
1595		},
1596		onfocusout: function( element ) {
1597			if ( !this.checkable( element ) && ( element.name in this.submitted || !this.optional( element ) ) ) {
1598				this.element( element );
1599			}
1600		},
1601		onkeyup: function( element, event ) {
1602
1603			// Avoid revalidate the field when pressing one of the following keys
1604			// Shift       => 16
1605			// Ctrl        => 17
1606			// Alt         => 18
1607			// Caps lock   => 20
1608			// End         => 35
1609			// Home        => 36
1610			// Left arrow  => 37
1611			// Up arrow    => 38
1612			// Right arrow => 39
1613			// Down arrow  => 40
1614			// Insert      => 45
1615			// Num lock    => 144
1616			// AltGr key   => 225
1617			var excludedKeys = [
1618				16, 17, 18, 20, 35, 36, 37,
1619				38, 39, 40, 45, 144, 225
1620			];
1621
1622			if ( event.which === 9 && this.elementValue( element ) === "" || $.inArray( event.keyCode, excludedKeys ) !== -1 ) {
1623				return;
1624			} else if ( element.name in this.submitted || element.name in this.invalid ) {
1625				this.element( element );
1626			}
1627		},
1628		onclick: function( element ) {
1629
1630			// Click on selects, radiobuttons and checkboxes
1631			if ( element.name in this.submitted ) {
1632				this.element( element );
1633
1634			// Or option elements, check parent select in that case
1635			} else if ( element.parentNode.name in this.submitted ) {
1636				this.element( element.parentNode );
1637			}
1638		},
1639		highlight: function( element, errorClass, validClass ) {
1640			if ( element.type === "radio" ) {
1641				this.findByName( element.name ).addClass( errorClass ).removeClass( validClass );
1642			} else {
1643				$( element ).addClass( errorClass ).removeClass( validClass );
1644			}
1645		},
1646		unhighlight: function( element, errorClass, validClass ) {
1647			if ( element.type === "radio" ) {
1648				this.findByName( element.name ).removeClass( errorClass ).addClass( validClass );
1649			} else {
1650				$( element ).removeClass( errorClass ).addClass( validClass );
1651			}
1652		}
1653	},
1654
1655	// https://jqueryvalidation.org/jQuery.validator.setDefaults/
1656	setDefaults: function( settings ) {
1657		$.extend( $.validator.defaults, settings );
1658	},
1659
1660	messages: {
1661		required: "This field is required.",
1662		remote: "Please fix this field.",
1663		email: "Please enter a valid email address.",
1664		url: "Please enter a valid URL.",
1665		date: "Please enter a valid date.",
1666		dateISO: "Please enter a valid date (ISO).",
1667		number: "Please enter a valid number.",
1668		digits: "Please enter only digits.",
1669		equalTo: "Please enter the same value again.",
1670		maxlength: $.validator.format( "Please enter no more than {0} characters." ),
1671		minlength: $.validator.format( "Please enter at least {0} characters." ),
1672		rangelength: $.validator.format( "Please enter a value between {0} and {1} characters long." ),
1673		range: $.validator.format( "Please enter a value between {0} and {1}." ),
1674		max: $.validator.format( "Please enter a value less than or equal to {0}." ),
1675		min: $.validator.format( "Please enter a value greater than or equal to {0}." ),
1676		step: $.validator.format( "Please enter a multiple of {0}." )
1677	},
1678
1679	autoCreateRanges: false,
1680
1681	prototype: {
1682
1683		init: function() {
1684			this.labelContainer = $( this.settings.errorLabelContainer );
1685			this.errorContext = this.labelContainer.length && this.labelContainer || $( this.currentForm );
1686			this.containers = $( this.settings.errorContainer ).add( this.settings.errorLabelContainer );
1687			this.submitted = {};
1688			this.valueCache = {};
1689			this.pendingRequest = 0;
1690			this.pending = {};
1691			this.invalid = {};
1692			this.reset();
1693
1694			var currentForm = this.currentForm,
1695				groups = ( this.groups = {} ),
1696				rules;
1697			$.each( this.settings.groups, function( key, value ) {
1698				if ( typeof value === "string" ) {
1699					value = value.split( /\s/ );
1700				}
1701				$.each( value, function( index, name ) {
1702					groups[ name ] = key;
1703				} );
1704			} );
1705			rules = this.settings.rules;
1706			$.each( rules, function( key, value ) {
1707				rules[ key ] = $.validator.normalizeRule( value );
1708			} );
1709
1710			function delegate( event ) {
1711				var isContentEditable = typeof $( this ).attr( "contenteditable" ) !== "undefined" && $( this ).attr( "contenteditable" ) !== "false";
1712
1713				// Set form expando on contenteditable
1714				if ( !this.form && isContentEditable ) {
1715					this.form = $( this ).closest( "form" )[ 0 ];
1716					this.name = $( this ).attr( "name" );
1717				}
1718
1719				// Ignore the element if it belongs to another form. This will happen mainly
1720				// when setting the `form` attribute of an input to the id of another form.
1721				if ( currentForm !== this.form ) {
1722					return;
1723				}
1724
1725				var validator = $.data( this.form, "validator" ),
1726					eventType = "on" + event.type.replace( /^validate/, "" ),
1727					settings = validator.settings;
1728				if ( settings[ eventType ] && !$( this ).is( settings.ignore ) ) {
1729					settings[ eventType ].call( validator, this, event );
1730				}
1731			}
1732
1733			$( this.currentForm )
1734				.on( "focusin.validate focusout.validate keyup.validate",
1735					":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], " +
1736					"[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], " +
1737					"[type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], " +
1738					"[type='radio'], [type='checkbox'], [contenteditable], [type='button']", delegate )
1739
1740				// Support: Chrome, oldIE
1741				// "select" is provided as event.target when clicking a option
1742				.on( "click.validate", "select, option, [type='radio'], [type='checkbox']", delegate );
1743
1744			if ( this.settings.invalidHandler ) {
1745				$( this.currentForm ).on( "invalid-form.validate", this.settings.invalidHandler );
1746			}
1747		},
1748
1749		// https://jqueryvalidation.org/Validator.form/
1750		form: function() {
1751			this.checkForm();
1752			$.extend( this.submitted, this.errorMap );
1753			this.invalid = $.extend( {}, this.errorMap );
1754			if ( !this.valid() ) {
1755				$( this.currentForm ).triggerHandler( "invalid-form", [ this ] );
1756			}
1757			this.showErrors();
1758			return this.valid();
1759		},
1760
1761		checkForm: function() {
1762			this.prepareForm();
1763			for ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) {
1764				this.check( elements[ i ] );
1765			}
1766			return this.valid();
1767		},
1768
1769		// https://jqueryvalidation.org/Validator.element/
1770		element: function( element ) {
1771			var cleanElement = this.clean( element ),
1772				checkElement = this.validationTargetFor( cleanElement ),
1773				v = this,
1774				result = true,
1775				rs, group;
1776
1777			if ( checkElement === undefined ) {
1778				delete this.invalid[ cleanElement.name ];
1779			} else {
1780				this.prepareElement( checkElement );
1781				this.currentElements = $( checkElement );
1782
1783				// If this element is grouped, then validate all group elements already
1784				// containing a value
1785				group = this.groups[ checkElement.name ];
1786				if ( group ) {
1787					$.each( this.groups, function( name, testgroup ) {
1788						if ( testgroup === group && name !== checkElement.name ) {
1789							cleanElement = v.validationTargetFor( v.clean( v.findByName( name ) ) );
1790							if ( cleanElement && cleanElement.name in v.invalid ) {
1791								v.currentElements.push( cleanElement );
1792								result = v.check( cleanElement ) && result;
1793							}
1794						}
1795					} );
1796				}
1797
1798				rs = this.check( checkElement ) !== false;
1799				result = result && rs;
1800				if ( rs ) {
1801					this.invalid[ checkElement.name ] = false;
1802				} else {
1803					this.invalid[ checkElement.name ] = true;
1804				}
1805
1806				if ( !this.numberOfInvalids() ) {
1807
1808					// Hide error containers on last error
1809					this.toHide = this.toHide.add( this.containers );
1810				}
1811				this.showErrors();
1812
1813				// Add aria-invalid status for screen readers
1814				$( element ).attr( "aria-invalid", !rs );
1815			}
1816
1817			return result;
1818		},
1819
1820		// https://jqueryvalidation.org/Validator.showErrors/
1821		showErrors: function( errors ) {
1822			if ( errors ) {
1823				var validator = this;
1824
1825				// Add items to error list and map
1826				$.extend( this.errorMap, errors );
1827				this.errorList = $.map( this.errorMap, function( message, name ) {
1828					return {
1829						message: message,
1830						element: validator.findByName( name )[ 0 ]
1831					};
1832				} );
1833
1834				// Remove items from success list
1835				this.successList = $.grep( this.successList, function( element ) {
1836					return !( element.name in errors );
1837				} );
1838			}
1839			if ( this.settings.showErrors ) {
1840				this.settings.showErrors.call( this, this.errorMap, this.errorList );
1841			} else {
1842				this.defaultShowErrors();
1843			}
1844		},
1845
1846		// https://jqueryvalidation.org/Validator.resetForm/
1847		resetForm: function() {
1848			if ( $.fn.resetForm ) {
1849				$( this.currentForm ).resetForm();
1850			}
1851			this.invalid = {};
1852			this.submitted = {};
1853			this.prepareForm();
1854			this.hideErrors();
1855			var elements = this.elements()
1856				.removeData( "previousValue" )
1857				.removeAttr( "aria-invalid" );
1858
1859			this.resetElements( elements );
1860		},
1861
1862		resetElements: function( elements ) {
1863			var i;
1864
1865			if ( this.settings.unhighlight ) {
1866				for ( i = 0; elements[ i ]; i++ ) {
1867					this.settings.unhighlight.call( this, elements[ i ],
1868						this.settings.errorClass, "" );
1869					this.findByName( elements[ i ].name ).removeClass( this.settings.validClass );
1870				}
1871			} else {
1872				elements
1873					.removeClass( this.settings.errorClass )
1874					.removeClass( this.settings.validClass );
1875			}
1876		},
1877
1878		numberOfInvalids: function() {
1879			return this.objectLength( this.invalid );
1880		},
1881
1882		objectLength: function( obj ) {
1883			/* jshint unused: false */
1884			var count = 0,
1885				i;
1886			for ( i in obj ) {
1887
1888				// This check allows counting elements with empty error
1889				// message as invalid elements
1890				if ( obj[ i ] !== undefined && obj[ i ] !== null && obj[ i ] !== false ) {
1891					count++;
1892				}
1893			}
1894			return count;
1895		},
1896
1897		hideErrors: function() {
1898			this.hideThese( this.toHide );
1899		},
1900
1901		hideThese: function( errors ) {
1902			errors.not( this.containers ).text( "" );
1903			this.addWrapper( errors ).hide();
1904		},
1905
1906		valid: function() {
1907			return this.size() === 0;
1908		},
1909
1910		size: function() {
1911			return this.errorList.length;
1912		},
1913
1914		focusInvalid: function() {
1915			if ( this.settings.focusInvalid ) {
1916				try {
1917					$( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || [] )
1918					.filter( ":visible" )
1919					.trigger( "focus" )
1920
1921					// Manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
1922					.trigger( "focusin" );
1923				} catch ( e ) {
1924
1925					// Ignore IE throwing errors when focusing hidden elements
1926				}
1927			}
1928		},
1929
1930		findLastActive: function() {
1931			var lastActive = this.lastActive;
1932			return lastActive && $.grep( this.errorList, function( n ) {
1933				return n.element.name === lastActive.name;
1934			} ).length === 1 && lastActive;
1935		},
1936
1937		elements: function() {
1938			var validator = this,
1939				rulesCache = {};
1940
1941			// Select all valid inputs inside the form (no submit or reset buttons)
1942			return $( this.currentForm )
1943			.find( "input, select, textarea, [contenteditable]" )
1944			.not( ":submit, :reset, :image, :disabled" )
1945			.not( this.settings.ignore )
1946			.filter( function() {
1947				var name = this.name || $( this ).attr( "name" ); // For contenteditable
1948				var isContentEditable = typeof $( this ).attr( "contenteditable" ) !== "undefined" && $( this ).attr( "contenteditable" ) !== "false";
1949
1950				if ( !name && validator.settings.debug && window.console ) {
1951					console.error( "%o has no name assigned", this );
1952				}
1953
1954				// Set form expando on contenteditable
1955				if ( isContentEditable ) {
1956					this.form = $( this ).closest( "form" )[ 0 ];
1957					this.name = name;
1958				}
1959
1960				// Ignore elements that belong to other/nested forms
1961				if ( this.form !== validator.currentForm ) {
1962					return false;
1963				}
1964
1965				// Select only the first element for each name, and only those with rules specified
1966				if ( name in rulesCache || !validator.objectLength( $( this ).rules() ) ) {
1967					return false;
1968				}
1969
1970				rulesCache[ name ] = true;
1971				return true;
1972			} );
1973		},
1974
1975		clean: function( selector ) {
1976			return $( selector )[ 0 ];
1977		},
1978
1979		errors: function() {
1980			var errorClass = this.settings.errorClass.split( " " ).join( "." );
1981			return $( this.settings.errorElement + "." + errorClass, this.errorContext );
1982		},
1983
1984		resetInternals: function() {
1985			this.successList = [];
1986			this.errorList = [];
1987			this.errorMap = {};
1988			this.toShow = $( [] );
1989			this.toHide = $( [] );
1990		},
1991
1992		reset: function() {
1993			this.resetInternals();
1994			this.currentElements = $( [] );
1995		},
1996
1997		prepareForm: function() {
1998			this.reset();
1999			this.toHide = this.errors().add( this.containers );
2000		},
2001
2002		prepareElement: function( element ) {
2003			this.reset();
2004			this.toHide = this.errorsFor( element );
2005		},
2006
2007		elementValue: function( element ) {
2008			var $element = $( element ),
2009				type = element.type,
2010				isContentEditable = typeof $element.attr( "contenteditable" ) !== "undefined" && $element.attr( "contenteditable" ) !== "false",
2011				val, idx;
2012
2013			if ( type === "radio" || type === "checkbox" ) {
2014				return this.findByName( element.name ).filter( ":checked" ).val();
2015			} else if ( type === "number" && typeof element.validity !== "undefined" ) {
2016				return element.validity.badInput ? "NaN" : $element.val();
2017			}
2018
2019			if ( isContentEditable ) {
2020				val = $element.text();
2021			} else {
2022				val = $element.val();
2023			}
2024
2025			if ( type === "file" ) {
2026
2027				// Modern browser (chrome & safari)
2028				if ( val.substr( 0, 12 ) === "C:\\fakepath\\" ) {
2029					return val.substr( 12 );
2030				}
2031
2032				// Legacy browsers
2033				// Unix-based path
2034				idx = val.lastIndexOf( "/" );
2035				if ( idx >= 0 ) {
2036					return val.substr( idx + 1 );
2037				}
2038
2039				// Windows-based path
2040				idx = val.lastIndexOf( "\\" );
2041				if ( idx >= 0 ) {
2042					return val.substr( idx + 1 );
2043				}
2044
2045				// Just the file name
2046				return val;
2047			}
2048
2049			if ( typeof val === "string" ) {
2050				return val.replace( /\r/g, "" );
2051			}
2052			return val;
2053		},
2054
2055		check: function( element ) {
2056			element = this.validationTargetFor( this.clean( element ) );
2057
2058			var rules = $( element ).rules(),
2059				rulesCount = $.map( rules, function( n, i ) {
2060					return i;
2061				} ).length,
2062				dependencyMismatch = false,
2063				val = this.elementValue( element ),
2064				result, method, rule, normalizer;
2065
2066			// Prioritize the local normalizer defined for this element over the global one
2067			// if the former exists, otherwise user the global one in case it exists.
2068			if ( typeof rules.normalizer === "function" ) {
2069				normalizer = rules.normalizer;
2070			} else if (	typeof this.settings.normalizer === "function" ) {
2071				normalizer = this.settings.normalizer;
2072			}
2073
2074			// If normalizer is defined, then call it to retreive the changed value instead
2075			// of using the real one.
2076			// Note that `this` in the normalizer is `element`.
2077			if ( normalizer ) {
2078				val = normalizer.call( element, val );
2079
2080				// Delete the normalizer from rules to avoid treating it as a pre-defined method.
2081				delete rules.normalizer;
2082			}
2083
2084			for ( method in rules ) {
2085				rule = { method: method, parameters: rules[ method ] };
2086				try {
2087					result = $.validator.methods[ method ].call( this, val, element, rule.parameters );
2088
2089					// If a method indicates that the field is optional and therefore valid,
2090					// don't mark it as valid when there are no other rules
2091					if ( result === "dependency-mismatch" && rulesCount === 1 ) {
2092						dependencyMismatch = true;
2093						continue;
2094					}
2095					dependencyMismatch = false;
2096
2097					if ( result === "pending" ) {
2098						this.toHide = this.toHide.not( this.errorsFor( element ) );
2099						return;
2100					}
2101
2102					if ( !result ) {
2103						this.formatAndAdd( element, rule );
2104						return false;
2105					}
2106				} catch ( e ) {
2107					if ( this.settings.debug && window.console ) {
2108						console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e );
2109					}
2110					if ( e instanceof TypeError ) {
2111						e.message += ".  Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.";
2112					}
2113
2114					throw e;
2115				}
2116			}
2117			if ( dependencyMismatch ) {
2118				return;
2119			}
2120			if ( this.objectLength( rules ) ) {
2121				this.successList.push( element );
2122			}
2123			return true;
2124		},
2125
2126		// Return the custom message for the given element and validation method
2127		// specified in the element's HTML5 data attribute
2128		// return the generic message if present and no method specific message is present
2129		customDataMessage: function( element, method ) {
2130			return $( element ).data( "msg" + method.charAt( 0 ).toUpperCase() +
2131				method.substring( 1 ).toLowerCase() ) || $( element ).data( "msg" );
2132		},
2133
2134		// Return the custom message for the given element name and validation method
2135		customMessage: function( name, method ) {
2136			var m = this.settings.messages[ name ];
2137			return m && ( m.constructor === String ? m : m[ method ] );
2138		},
2139
2140		// Return the first defined argument, allowing empty strings
2141		findDefined: function() {
2142			for ( var i = 0; i < arguments.length; i++ ) {
2143				if ( arguments[ i ] !== undefined ) {
2144					return arguments[ i ];
2145				}
2146			}
2147			return undefined;
2148		},
2149
2150		// The second parameter 'rule' used to be a string, and extended to an object literal
2151		// of the following form:
2152		// rule = {
2153		//     method: "method name",
2154		//     parameters: "the given method parameters"
2155		// }
2156		//
2157		// The old behavior still supported, kept to maintain backward compatibility with
2158		// old code, and will be removed in the next major release.
2159		defaultMessage: function( element, rule ) {
2160			if ( typeof rule === "string" ) {
2161				rule = { method: rule };
2162			}
2163
2164			var message = this.findDefined(
2165					this.customMessage( element.name, rule.method ),
2166					this.customDataMessage( element, rule.method ),
2167
2168					// 'title' is never undefined, so handle empty string as undefined
2169					!this.settings.ignoreTitle && element.title || undefined,
2170					$.validator.messages[ rule.method ],
2171					"<strong>Warning: No message defined for " + element.name + "</strong>"
2172				),
2173				theregex = /\$?\{(\d+)\}/g;
2174			if ( typeof message === "function" ) {
2175				message = message.call( this, rule.parameters, element );
2176			} else if ( theregex.test( message ) ) {
2177				message = $.validator.format( message.replace( theregex, "{$1}" ), rule.parameters );
2178			}
2179
2180			return message;
2181		},
2182
2183		formatAndAdd: function( element, rule ) {
2184			var message = this.defaultMessage( element, rule );
2185
2186			this.errorList.push( {
2187				message: message,
2188				element: element,
2189				method: rule.method
2190			} );
2191
2192			this.errorMap[ element.name ] = message;
2193			this.submitted[ element.name ] = message;
2194		},
2195
2196		addWrapper: function( toToggle ) {
2197			if ( this.settings.wrapper ) {
2198				toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
2199			}
2200			return toToggle;
2201		},
2202
2203		defaultShowErrors: function() {
2204			var i, elements, error;
2205			for ( i = 0; this.errorList[ i ]; i++ ) {
2206				error = this.errorList[ i ];
2207				if ( this.settings.highlight ) {
2208					this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
2209				}
2210				this.showLabel( error.element, error.message );
2211			}
2212			if ( this.errorList.length ) {
2213				this.toShow = this.toShow.add( this.containers );
2214			}
2215			if ( this.settings.success ) {
2216				for ( i = 0; this.successList[ i ]; i++ ) {
2217					this.showLabel( this.successList[ i ] );
2218				}
2219			}
2220			if ( this.settings.unhighlight ) {
2221				for ( i = 0, elements = this.validElements(); elements[ i ]; i++ ) {
2222					this.settings.unhighlight.call( this, elements[ i ], this.settings.errorClass, this.settings.validClass );
2223				}
2224			}
2225			this.toHide = this.toHide.not( this.toShow );
2226			this.hideErrors();
2227			this.addWrapper( this.toShow ).show();
2228		},
2229
2230		validElements: function() {
2231			return this.currentElements.not( this.invalidElements() );
2232		},
2233
2234		invalidElements: function() {
2235			return $( this.errorList ).map( function() {
2236				return this.element;
2237			} );
2238		},
2239
2240		showLabel: function( element, message ) {
2241			var place, group, errorID, v,
2242				error = this.errorsFor( element ),
2243				elementID = this.idOrName( element ),
2244				describedBy = $( element ).attr( "aria-describedby" );
2245
2246			if ( error.length ) {
2247
2248				// Refresh error/success class
2249				error.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );
2250
2251				// Replace message on existing label
2252				error.html( message );
2253			} else {
2254
2255				// Create error element
2256				error = $( "<" + this.settings.errorElement + ">" )
2257					.attr( "id", elementID + "-error" )
2258					.addClass( this.settings.errorClass )
2259					.html( message || "" );
2260
2261				// Maintain reference to the element to be placed into the DOM
2262				place = error;
2263				if ( this.settings.wrapper ) {
2264
2265					// Make sure the element is visible, even in IE
2266					// actually showing the wrapped element is handled elsewhere
2267					place = error.hide().show().wrap( "<" + this.settings.wrapper + "/>" ).parent();
2268				}
2269				if ( this.labelContainer.length ) {
2270					this.labelContainer.append( place );
2271				} else if ( this.settings.errorPlacement ) {
2272					this.settings.errorPlacement.call( this, place, $( element ) );
2273				} else {
2274					place.insertAfter( element );
2275				}
2276
2277				// Link error back to the element
2278				if ( error.is( "label" ) ) {
2279
2280					// If the error is a label, then associate using 'for'
2281					error.attr( "for", elementID );
2282
2283					// If the element is not a child of an associated label, then it's necessary
2284					// to explicitly apply aria-describedby
2285				} else if ( error.parents( "label[for='" + this.escapeCssMeta( elementID ) + "']" ).length === 0 ) {
2286					errorID = error.attr( "id" );
2287
2288					// Respect existing non-error aria-describedby
2289					if ( !describedBy ) {
2290						describedBy = errorID;
2291					} else if ( !describedBy.match( new RegExp( "\\b" + this.escapeCssMeta( errorID ) + "\\b" ) ) ) {
2292
2293						// Add to end of list if not already present
2294						describedBy += " " + errorID;
2295					}
2296					$( element ).attr( "aria-describedby", describedBy );
2297
2298					// If this element is grouped, then assign to all elements in the same group
2299					group = this.groups[ element.name ];
2300					if ( group ) {
2301						v = this;
2302						$.each( v.groups, function( name, testgroup ) {
2303							if ( testgroup === group ) {
2304								$( "[name='" + v.escapeCssMeta( name ) + "']", v.currentForm )
2305									.attr( "aria-describedby", error.attr( "id" ) );
2306							}
2307						} );
2308					}
2309				}
2310			}
2311			if ( !message && this.settings.success ) {
2312				error.text( "" );
2313				if ( typeof this.settings.success === "string" ) {
2314					error.addClass( this.settings.success );
2315				} else {
2316					this.settings.success( error, element );
2317				}
2318			}
2319			this.toShow = this.toShow.add( error );
2320		},
2321
2322		errorsFor: function( element ) {
2323			var name = this.escapeCssMeta( this.idOrName( element ) ),
2324				describer = $( element ).attr( "aria-describedby" ),
2325				selector = "label[for='" + name + "'], label[for='" + name + "'] *";
2326
2327			// 'aria-describedby' should directly reference the error element
2328			if ( describer ) {
2329				selector = selector + ", #" + this.escapeCssMeta( describer )
2330					.replace( /\s+/g, ", #" );
2331			}
2332
2333			return this
2334				.errors()
2335				.filter( selector );
2336		},
2337
2338		// See https://api.jquery.com/category/selectors/, for CSS
2339		// meta-characters that should be escaped in order to be used with JQuery
2340		// as a literal part of a name/id or any selector.
2341		escapeCssMeta: function( string ) {
2342			if ( string === undefined ) {
2343				return "";
2344			}
2345
2346			return string.replace( /([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g, "\\$1" );
2347		},
2348
2349		idOrName: function( element ) {
2350			return this.groups[ element.name ] || ( this.checkable( element ) ? element.name : element.id || element.name );
2351		},
2352
2353		validationTargetFor: function( element ) {
2354
2355			// If radio/checkbox, validate first element in group instead
2356			if ( this.checkable( element ) ) {
2357				element = this.findByName( element.name );
2358			}
2359
2360			// Always apply ignore filter
2361			return $( element ).not( this.settings.ignore )[ 0 ];
2362		},
2363
2364		checkable: function( element ) {
2365			return ( /radio|checkbox/i ).test( element.type );
2366		},
2367
2368		findByName: function( name ) {
2369			return $( this.currentForm ).find( "[name='" + this.escapeCssMeta( name ) + "']" );
2370		},
2371
2372		getLength: function( value, element ) {
2373			switch ( element.nodeName.toLowerCase() ) {
2374			case "select":
2375				return $( "option:selected", element ).length;
2376			case "input":
2377				if ( this.checkable( element ) ) {
2378					return this.findByName( element.name ).filter( ":checked" ).length;
2379				}
2380			}
2381			return value.length;
2382		},
2383
2384		depend: function( param, element ) {
2385			return this.dependTypes[ typeof param ] ? this.dependTypes[ typeof param ]( param, element ) : true;
2386		},
2387
2388		dependTypes: {
2389			"boolean": function( param ) {
2390				return param;
2391			},
2392			"string": function( param, element ) {
2393				return !!$( param, element.form ).length;
2394			},
2395			"function": function( param, element ) {
2396				return param( element );
2397			}
2398		},
2399
2400		optional: function( element ) {
2401			var val = this.elementValue( element );
2402			return !$.validator.methods.required.call( this, val, element ) && "dependency-mismatch";
2403		},
2404
2405		startRequest: function( element ) {
2406			if ( !this.pending[ element.name ] ) {
2407				this.pendingRequest++;
2408				$( element ).addClass( this.settings.pendingClass );
2409				this.pending[ element.name ] = true;
2410			}
2411		},
2412
2413		stopRequest: function( element, valid ) {
2414			this.pendingRequest--;
2415
2416			// Sometimes synchronization fails, make sure pendingRequest is never < 0
2417			if ( this.pendingRequest < 0 ) {
2418				this.pendingRequest = 0;
2419			}
2420			delete this.pending[ element.name ];
2421			$( element ).removeClass( this.settings.pendingClass );
2422			if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() && this.pendingRequest === 0 ) {
2423				$( this.currentForm ).trigger( "submit" );
2424
2425				// Remove the hidden input that was used as a replacement for the
2426				// missing submit button. The hidden input is added by `handle()`
2427				// to ensure that the value of the used submit button is passed on
2428				// for scripted submits triggered by this method
2429				if ( this.submitButton ) {
2430					$( "input:hidden[name='" + this.submitButton.name + "']", this.currentForm ).remove();
2431				}
2432
2433				this.formSubmitted = false;
2434			} else if ( !valid && this.pendingRequest === 0 && this.formSubmitted ) {
2435				$( this.currentForm ).triggerHandler( "invalid-form", [ this ] );
2436				this.formSubmitted = false;
2437			}
2438		},
2439
2440		previousValue: function( element, method ) {
2441			method = typeof method === "string" && method || "remote";
2442
2443			return $.data( element, "previousValue" ) || $.data( element, "previousValue", {
2444				old: null,
2445				valid: true,
2446				message: this.defaultMessage( element, { method: method } )
2447			} );
2448		},
2449
2450		// Cleans up all forms and elements, removes validator-specific events
2451		destroy: function() {
2452			this.resetForm();
2453
2454			$( this.currentForm )
2455				.off( ".validate" )
2456				.removeData( "validator" )
2457				.find( ".validate-equalTo-blur" )
2458					.off( ".validate-equalTo" )
2459					.removeClass( "validate-equalTo-blur" )
2460				.find( ".validate-lessThan-blur" )
2461					.off( ".validate-lessThan" )
2462					.removeClass( "validate-lessThan-blur" )
2463				.find( ".validate-lessThanEqual-blur" )
2464					.off( ".validate-lessThanEqual" )
2465					.removeClass( "validate-lessThanEqual-blur" )
2466				.find( ".validate-greaterThanEqual-blur" )
2467					.off( ".validate-greaterThanEqual" )
2468					.removeClass( "validate-greaterThanEqual-blur" )
2469				.find( ".validate-greaterThan-blur" )
2470					.off( ".validate-greaterThan" )
2471					.removeClass( "validate-greaterThan-blur" );
2472		}
2473
2474	},
2475
2476	classRuleSettings: {
2477		required: { required: true },
2478		email: { email: true },
2479		url: { url: true },
2480		date: { date: true },
2481		dateISO: { dateISO: true },
2482		number: { number: true },
2483		digits: { digits: true },
2484		creditcard: { creditcard: true }
2485	},
2486
2487	addClassRules: function( className, rules ) {
2488		if ( className.constructor === String ) {
2489			this.classRuleSettings[ className ] = rules;
2490		} else {
2491			$.extend( this.classRuleSettings, className );
2492		}
2493	},
2494
2495	classRules: function( element ) {
2496		var rules = {},
2497			classes = $( element ).attr( "class" );
2498
2499		if ( classes ) {
2500			$.each( classes.split( " " ), function() {
2501				if ( this in $.validator.classRuleSettings ) {
2502					$.extend( rules, $.validator.classRuleSettings[ this ] );
2503				}
2504			} );
2505		}
2506		return rules;
2507	},
2508
2509	normalizeAttributeRule: function( rules, type, method, value ) {
2510
2511		// Convert the value to a number for number inputs, and for text for backwards compability
2512		// allows type="date" and others to be compared as strings
2513		if ( /min|max|step/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) {
2514			value = Number( value );
2515
2516			// Support Opera Mini, which returns NaN for undefined minlength
2517			if ( isNaN( value ) ) {
2518				value = undefined;
2519			}
2520		}
2521
2522		if ( value || value === 0 ) {
2523			rules[ method ] = value;
2524		} else if ( type === method && type !== "range" ) {
2525
2526			// Exception: the jquery validate 'range' method
2527			// does not test for the html5 'range' type
2528			rules[ type === "date" ? "dateISO" : method ] = true;
2529		}
2530	},
2531
2532	attributeRules: function( element ) {
2533		var rules = {},
2534			$element = $( element ),
2535			type = element.getAttribute( "type" ),
2536			method, value;
2537
2538		for ( method in $.validator.methods ) {
2539
2540			// Support for <input required> in both html5 and older browsers
2541			if ( method === "required" ) {
2542				value = element.getAttribute( method );
2543
2544				// Some browsers return an empty string for the required attribute
2545				// and non-HTML5 browsers might have required="" markup
2546				if ( value === "" ) {
2547					value = true;
2548				}
2549
2550				// Force non-HTML5 browsers to return bool
2551				value = !!value;
2552			} else {
2553				value = $element.attr( method );
2554			}
2555
2556			this.normalizeAttributeRule( rules, type, method, value );
2557		}
2558
2559		// 'maxlength' may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs
2560		if ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) {
2561			delete rules.maxlength;
2562		}
2563
2564		return rules;
2565	},
2566
2567	dataRules: function( element ) {
2568		var rules = {},
2569			$element = $( element ),
2570			type = element.getAttribute( "type" ),
2571			method, value;
2572
2573		for ( method in $.validator.methods ) {
2574			value = $element.data( "rule" + method.charAt( 0 ).toUpperCase() + method.substring( 1 ).toLowerCase() );
2575
2576			// Cast empty attributes like `data-rule-required` to `true`
2577			if ( value === "" ) {
2578				value = true;
2579			}
2580
2581			this.normalizeAttributeRule( rules, type, method, value );
2582		}
2583		return rules;
2584	},
2585
2586	staticRules: function( element ) {
2587		var rules = {},
2588			validator = $.data( element.form, "validator" );
2589
2590		if ( validator.settings.rules ) {
2591			rules = $.validator.normalizeRule( validator.settings.rules[ element.name ] ) || {};
2592		}
2593		return rules;
2594	},
2595
2596	normalizeRules: function( rules, element ) {
2597
2598		// Handle dependency check
2599		$.each( rules, function( prop, val ) {
2600
2601			// Ignore rule when param is explicitly false, eg. required:false
2602			if ( val === false ) {
2603				delete rules[ prop ];
2604				return;
2605			}
2606			if ( val.param || val.depends ) {
2607				var keepRule = true;
2608				switch ( typeof val.depends ) {
2609				case "string":
2610					keepRule = !!$( val.depends, element.form ).length;
2611					break;
2612				case "function":
2613					keepRule = val.depends.call( element, element );
2614					break;
2615				}
2616				if ( keepRule ) {
2617					rules[ prop ] = val.param !== undefined ? val.param : true;
2618				} else {
2619					$.data( element.form, "validator" ).resetElements( $( element ) );
2620					delete rules[ prop ];
2621				}
2622			}
2623		} );
2624
2625		// Evaluate parameters
2626		$.each( rules, function( rule, parameter ) {
2627			rules[ rule ] = typeof parameter === "function" && rule !== "normalizer" ? parameter( element ) : parameter;
2628		} );
2629
2630		// Clean number parameters
2631		$.each( [ "minlength", "maxlength" ], function() {
2632			if ( rules[ this ] ) {
2633				rules[ this ] = Number( rules[ this ] );
2634			}
2635		} );
2636		$.each( [ "rangelength", "range" ], function() {
2637			var parts;
2638			if ( rules[ this ] ) {
2639				if ( Array.isArray( rules[ this ] ) ) {
2640					rules[ this ] = [ Number( rules[ this ][ 0 ] ), Number( rules[ this ][ 1 ] ) ];
2641				} else if ( typeof rules[ this ] === "string" ) {
2642					parts = rules[ this ].replace( /[\[\]]/g, "" ).split( /[\s,]+/ );
2643					rules[ this ] = [ Number( parts[ 0 ] ), Number( parts[ 1 ] ) ];
2644				}
2645			}
2646		} );
2647
2648		if ( $.validator.autoCreateRanges ) {
2649
2650			// Auto-create ranges
2651			if ( rules.min != null && rules.max != null ) {
2652				rules.range = [ rules.min, rules.max ];
2653				delete rules.min;
2654				delete rules.max;
2655			}
2656			if ( rules.minlength != null && rules.maxlength != null ) {
2657				rules.rangelength = [ rules.minlength, rules.maxlength ];
2658				delete rules.minlength;
2659				delete rules.maxlength;
2660			}
2661		}
2662
2663		return rules;
2664	},
2665
2666	// Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
2667	normalizeRule: function( data ) {
2668		if ( typeof data === "string" ) {
2669			var transformed = {};
2670			$.each( data.split( /\s/ ), function() {
2671				transformed[ this ] = true;
2672			} );
2673			data = transformed;
2674		}
2675		return data;
2676	},
2677
2678	// https://jqueryvalidation.org/jQuery.validator.addMethod/
2679	addMethod: function( name, method, message ) {
2680		$.validator.methods[ name ] = method;
2681		$.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ];
2682		if ( method.length < 3 ) {
2683			$.validator.addClassRules( name, $.validator.normalizeRule( name ) );
2684		}
2685	},
2686
2687	// https://jqueryvalidation.org/jQuery.validator.methods/
2688	methods: {
2689
2690		// https://jqueryvalidation.org/required-method/
2691		required: function( value, element, param ) {
2692
2693			// Check if dependency is met
2694			if ( !this.depend( param, element ) ) {
2695				return "dependency-mismatch";
2696			}
2697			if ( element.nodeName.toLowerCase() === "select" ) {
2698
2699				// Could be an array for select-multiple or a string, both are fine this way
2700				var val = $( element ).val();
2701				return val && val.length > 0;
2702			}
2703			if ( this.checkable( element ) ) {
2704				return this.getLength( value, element ) > 0;
2705			}
2706			return value !== undefined && value !== null && value.length > 0;
2707		},
2708
2709		// https://jqueryvalidation.org/email-method/
2710		email: function( value, element ) {
2711
2712			// From https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address
2713			// Retrieved 2014-01-14
2714			// If you have a problem with this implementation, report a bug against the above spec
2715			// Or use custom methods to implement your own email validation
2716			return this.optional( element ) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test( value );
2717		},
2718
2719		// https://jqueryvalidation.org/url-method/
2720		url: function( value, element ) {
2721
2722			// Copyright (c) 2010-2013 Diego Perini, MIT licensed
2723			// https://gist.github.com/dperini/729294
2724			// see also https://mathiasbynens.be/demo/url-regex
2725			// modified to allow protocol-relative URLs
2726			return this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:(?:[^\]\[?\/<~#`!@$^&*()+=}|:";',>{ ]|%[0-9A-Fa-f]{2})+(?::(?:[^\]\[?\/<~#`!@$^&*()+=}|:";',>{ ]|%[0-9A-Fa-f]{2})*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[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]))|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff]\.)+(?:[a-z\u00a1-\uffff]{2,}\.?))(?::\d{2,5})?(?:[/?#]\S*)?$/i.test( value );
2727		},
2728
2729		// https://jqueryvalidation.org/date-method/
2730		date: ( function() {
2731			var called = false;
2732
2733			return function( value, element ) {
2734				if ( !called ) {
2735					called = true;
2736					if ( this.settings.debug && window.console ) {
2737						console.warn(
2738							"The `date` method is deprecated and will be removed in version '2.0.0'.\n" +
2739							"Please don't use it, since it relies on the Date constructor, which\n" +
2740							"behaves very differently across browsers and locales. Use `dateISO`\n" +
2741							"instead or one of the locale specific methods in `localizations/`\n" +
2742							"and `additional-methods.js`."
2743						);
2744					}
2745				}
2746
2747				return this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() );
2748			};
2749		}() ),
2750
2751		// https://jqueryvalidation.org/dateISO-method/
2752		dateISO: function( value, element ) {
2753			return this.optional( element ) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test( value );
2754		},
2755
2756		// https://jqueryvalidation.org/number-method/
2757		number: function( value, element ) {
2758			return this.optional( element ) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test( value );
2759		},
2760
2761		// https://jqueryvalidation.org/digits-method/
2762		digits: function( value, element ) {
2763			return this.optional( element ) || /^\d+$/.test( value );
2764		},
2765
2766		// https://jqueryvalidation.org/minlength-method/
2767		minlength: function( value, element, param ) {
2768			var length = Array.isArray( value ) ? value.length : this.getLength( value, element );
2769			return this.optional( element ) || length >= param;
2770		},
2771
2772		// https://jqueryvalidation.org/maxlength-method/
2773		maxlength: function( value, element, param ) {
2774			var length = Array.isArray( value ) ? value.length : this.getLength( value, element );
2775			return this.optional( element ) || length <= param;
2776		},
2777
2778		// https://jqueryvalidation.org/rangelength-method/
2779		rangelength: function( value, element, param ) {
2780			var length = Array.isArray( value ) ? value.length : this.getLength( value, element );
2781			return this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] );
2782		},
2783
2784		// https://jqueryvalidation.org/min-method/
2785		min: function( value, element, param ) {
2786			return this.optional( element ) || value >= param;
2787		},
2788
2789		// https://jqueryvalidation.org/max-method/
2790		max: function( value, element, param ) {
2791			return this.optional( element ) || value <= param;
2792		},
2793
2794		// https://jqueryvalidation.org/range-method/
2795		range: function( value, element, param ) {
2796			return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] );
2797		},
2798
2799		// https://jqueryvalidation.org/step-method/
2800		step: function( value, element, param ) {
2801			var type = $( element ).attr( "type" ),
2802				errorMessage = "Step attribute on input type " + type + " is not supported.",
2803				supportedTypes = [ "text", "number", "range" ],
2804				re = new RegExp( "\\b" + type + "\\b" ),
2805				notSupported = type && !re.test( supportedTypes.join() ),
2806				decimalPlaces = function( num ) {
2807					var match = ( "" + num ).match( /(?:\.(\d+))?$/ );
2808					if ( !match ) {
2809						return 0;
2810					}
2811
2812					// Number of digits right of decimal point.
2813					return match[ 1 ] ? match[ 1 ].length : 0;
2814				},
2815				toInt = function( num ) {
2816					return Math.round( num * Math.pow( 10, decimals ) );
2817				},
2818				valid = true,
2819				decimals;
2820
2821			// Works only for text, number and range input types
2822			// TODO find a way to support input types date, datetime, datetime-local, month, time and week
2823			if ( notSupported ) {
2824				throw new Error( errorMessage );
2825			}
2826
2827			decimals = decimalPlaces( param );
2828
2829			// Value can't have too many decimals
2830			if ( decimalPlaces( value ) > decimals || toInt( value ) % toInt( param ) !== 0 ) {
2831				valid = false;
2832			}
2833
2834			return this.optional( element ) || valid;
2835		},
2836
2837		// https://jqueryvalidation.org/equalTo-method/
2838		equalTo: function( value, element, param ) {
2839
2840			// Bind to the blur event of the target in order to revalidate whenever the target field is updated
2841			var target = $( param );
2842			if ( this.settings.onfocusout && target.not( ".validate-equalTo-blur" ).length ) {
2843				target.addClass( "validate-equalTo-blur" ).on( "blur.validate-equalTo", function() {
2844					$( element ).valid();
2845				} );
2846			}
2847			return value === target.val();
2848		},
2849
2850		// https://jqueryvalidation.org/remote-method/
2851		remote: function( value, element, param, method ) {
2852			if ( this.optional( element ) ) {
2853				return "dependency-mismatch";
2854			}
2855
2856			method = typeof method === "string" && method || "remote";
2857
2858			var previous = this.previousValue( element, method ),
2859				validator, data, optionDataString;
2860
2861			if ( !this.settings.messages[ element.name ] ) {
2862				this.settings.messages[ element.name ] = {};
2863			}
2864			previous.originalMessage = previous.originalMessage || this.settings.messages[ element.name ][ method ];
2865			this.settings.messages[ element.name ][ method ] = previous.message;
2866
2867			param = typeof param === "string" && { url: param } || param;
2868			optionDataString = $.param( $.extend( { data: value }, param.data ) );
2869			if ( previous.old === optionDataString ) {
2870				return previous.valid;
2871			}
2872
2873			previous.old = optionDataString;
2874			validator = this;
vendor: 29,940 bytes, lines 2875-2955
2875			this.startRequest( element );
2876			data = {};
2877			data[ element.name ] = value;
2878			$.ajax( $.extend( true, {
2879				mode: "abort",
2880				port: "validate" + element.name,
2881				dataType: "json",
2882				data: data,
2883				context: validator.currentForm,
2884				success: function( response ) {
2885					var valid = response === true || response === "true",
2886						errors, message, submitted;
2887
2888					validator.settings.messages[ element.name ][ method ] = previous.originalMessage;
2889					if ( valid ) {
2890						submitted = validator.formSubmitted;
2891						validator.resetInternals();
2892						validator.toHide = validator.errorsFor( element );
2893						validator.formSubmitted = submitted;
2894						validator.successList.push( element );
2895						validator.invalid[ element.name ] = false;
2896						validator.showErrors();
2897					} else {
2898						errors = {};
2899						message = response || validator.defaultMessage( element, { method: method, parameters: value } );
2900						errors[ element.name ] = previous.message = message;
2901						validator.invalid[ element.name ] = true;
2902						validator.showErrors( errors );
2903					}
2904					previous.valid = valid;
2905					validator.stopRequest( element, valid );
2906				}
2907			}, param ) );
2908			return "pending";
2909		}
2910	}
2911
2912} );
2913
2914// Ajax mode: abort
2915// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
2916// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
2917
2918var pendingRequests = {},
2919	ajax;
2920
2921// Use a prefilter if available (1.5+)
2922if ( $.ajaxPrefilter ) {
2923	$.ajaxPrefilter( function( settings, _, xhr ) {
2924		var port = settings.port;
2925		if ( settings.mode === "abort" ) {
2926			if ( pendingRequests[ port ] ) {
2927				pendingRequests[ port ].abort();
2928			}
2929			pendingRequests[ port ] = xhr;
2930		}
2931	} );
2932} else {
2933
2934	// Proxy ajax
2935	ajax = $.ajax;
2936	$.ajax = function( settings ) {
2937		var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
2938			port = ( "port" in settings ? settings : $.ajaxSettings ).port;
2939		if ( mode === "abort" ) {
2940			if ( pendingRequests[ port ] ) {
2941				pendingRequests[ port ].abort();
2942			}
2943			pendingRequests[ port ] = ajax.apply( this, arguments );
2944			return pendingRequests[ port ];
2945		}
2946		return ajax.apply( this, arguments );
2947	};
2948}
2949return $;
2950}));
2951
2952/*! jQuery Validation Plugin - v1.19.5 - 7/1/2022
2953 * https://jqueryvalidation.org/
2954 * Copyright (c) 2022 J�rn Zaefferer; Licensed MIT */
2955!function (a) { "function" == typeof define && define.amd ? define(["jquery"], a) : "object" == typeof module && module.exports ? module.exports = a(require("jquery")) : a(jQuery) }(function (a) { a.extend(a.fn, { validate: function (b) { if (!this.length) return void (b && b.debug && window.console && console.warn("Nothing selected, can't validate, returning nothing.")); var c = a.data(this[0], "validator"); return c ? c : (this.attr("novalidate", "novalidate"), c = new a.validator(b, this[0]), a.data(this[0], "validator", c), c.settings.onsubmit && (this.on("click.validate", ":submit", function (b) { c.submitButton = b.currentTarget, a(this).hasClass("cancel") && (c.cancelSubmit = !0), void 0 !== a(this).attr("formnovalidate") && (c.cancelSubmit = !0) }), this.on("submit.validate", function (b) { function d() { var d, e; return c.submitButton && (c.settings.submitHandler || c.formSubmitted) && (d = a("<input type='hidden'/>").attr("name", c.submitButton.name).val(a(c.submitButton).val()).appendTo(c.currentForm)), !(c.settings.submitHandler && !c.settings.debug) || (e = c.settings.submitHandler.call(c, c.currentForm, b), d && d.remove(), void 0 !== e && e) } return c.settings.debug && b.preventDefault(), c.cancelSubmit ? (c.cancelSubmit = !1, d()) : c.form() ? c.pendingRequest ? (c.formSubmitted = !0, !1) : d() : (c.focusInvalid(), !1) })), c) }, valid: function () { var b, c, d; return a(this[0]).is("form") ? b = this.validate().form() : (d = [], b = !0, c = a(this[0].form).validate(), this.each(function () { b = c.element(this) && b, b || (d = d.concat(c.errorList)) }), c.errorList = d), b }, rules: function (b, c) { var d, e, f, g, h, i, j = this[0], k = "undefined" != typeof this.attr("contenteditable") && "false" !== this.attr("contenteditable"); if (null != j && (!j.form && k && (j.form = this.closest("form")[0], j.name = this.attr("name")), null != j.form)) { if (b) switch (d = a.data(j.form, "validator").settings, e = d.rules, f = a.validator.staticRules(j), b) { case "add": a.extend(f, a.validator.normalizeRule(c)), delete f.messages, e[j.name] = f, c.messages && (d.messages[j.name] = a.extend(d.messages[j.name], c.messages)); break; case "remove": return c ? (i = {}, a.each(c.split(/\s/), function (a, b) { i[b] = f[b], delete f[b] }), i) : (delete e[j.name], f) }return g = a.validator.normalizeRules(a.extend({}, a.validator.classRules(j), a.validator.attributeRules(j), a.validator.dataRules(j), a.validator.staticRules(j)), j), g.required && (h = g.required, delete g.required, g = a.extend({ required: h }, g)), g.remote && (h = g.remote, delete g.remote, g = a.extend(g, { remote: h })), g } } }); var b = function (a) { return a.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, "") }; a.extend(a.expr.pseudos || a.expr[":"], { blank: function (c) { return !b("" + a(c).val()) }, filled: function (c) { var d = a(c).val(); return null !== d && !!b("" + d) }, unchecked: function (b) { return !a(b).prop("checked") } }), a.validator = function (b, c) { this.settings = a.extend(!0, {}, a.validator.defaults, b), this.currentForm = c, this.init() }, a.validator.format = function (b, c) { return 1 === arguments.length ? function () { var c = a.makeArray(arguments); return c.unshift(b), a.validator.format.apply(this, c) } : void 0 === c ? b : (arguments.length > 2 && c.constructor !== Array && (c = a.makeArray(arguments).slice(1)), c.constructor !== Array && (c = [c]), a.each(c, function (a, c) { b = b.replace(new RegExp("\\{" + a + "\\}", "g"), function () { return c }) }), b) }, a.extend(a.validator, { defaults: { messages: {}, groups: {}, rules: {}, errorClass: "error", pendingClass: "pending", validClass: "valid", errorElement: "label", focusCleanup: !1, focusInvalid: !0, errorContainer: a([]), errorLabelContainer: a([]), onsubmit: !0, ignore: ":hidden", ignoreTitle: !1, onfocusin: function (a) { this.lastActive = a, this.settings.focusCleanup && (this.settings.unhighlight && this.settings.unhighlight.call(this, a, this.settings.errorClass, this.settings.validClass), this.hideThese(this.errorsFor(a))) }, onfocusout: function (a) { this.checkable(a) || !(a.name in this.submitted) && this.optional(a) || this.element(a) }, onkeyup: function (b, c) { var d = [16, 17, 18, 20, 35, 36, 37, 38, 39, 40, 45, 144, 225]; 9 === c.which && "" === this.elementValue(b) || a.inArray(c.keyCode, d) !== -1 || (b.name in this.submitted || b.name in this.invalid) && this.element(b) }, onclick: function (a) { a.name in this.submitted ? this.element(a) : a.parentNode.name in this.submitted && this.element(a.parentNode) }, highlight: function (b, c, d) { "radio" === b.type ? this.findByName(b.name).addClass(c).removeClass(d) : a(b).addClass(c).removeClass(d) }, unhighlight: function (b, c, d) { "radio" === b.type ? this.findByName(b.name).removeClass(c).addClass(d) : a(b).removeClass(c).addClass(d) } }, setDefaults: function (b) { a.extend(a.validator.defaults, b) }, messages: { required: "This field is required.", remote: "Please fix this field.", email: "Please enter a valid email address.", url: "Please enter a valid URL.", date: "Please enter a valid date.", dateISO: "Please enter a valid date (ISO).", number: "Please enter a valid number.", digits: "Please enter only digits.", equalTo: "Please enter the same value again.", maxlength: a.validator.format("Please enter no more than {0} characters."), minlength: a.validator.format("Please enter at least {0} characters."), rangelength: a.validator.format("Please enter a value between {0} and {1} characters long."), range: a.validator.format("Please enter a value between {0} and {1}."), max: a.validator.format("Please enter a value less than or equal to {0}."), min: a.validator.format("Please enter a value greater than or equal to {0}."), step: a.validator.format("Please enter a multiple of {0}.") }, autoCreateRanges: !1, prototype: { init: function () { function b(b) { var c = "undefined" != typeof a(this).attr("contenteditable") && "false" !== a(this).attr("contenteditable"); if (!this.form && c && (this.form = a(this).closest("form")[0], this.name = a(this).attr("name")), d === this.form) { var e = a.data(this.form, "validator"), f = "on" + b.type.replace(/^validate/, ""), g = e.settings; g[f] && !a(this).is(g.ignore) && g[f].call(e, this, b) } } this.labelContainer = a(this.settings.errorLabelContainer), this.errorContext = this.labelContainer.length && this.labelContainer || a(this.currentForm), this.containers = a(this.settings.errorContainer).add(this.settings.errorLabelContainer), this.submitted = {}, this.valueCache = {}, this.pendingRequest = 0, this.pending = {}, this.invalid = {}, this.reset(); var c, d = this.currentForm, e = this.groups = {}; a.each(this.settings.groups, function (b, c) { "string" == typeof c && (c = c.split(/\s/)), a.each(c, function (a, c) { e[c] = b }) }), c = this.settings.rules, a.each(c, function (b, d) { c[b] = a.validator.normalizeRule(d) }), a(this.currentForm).on("focusin.validate focusout.validate keyup.validate", ":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], [type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], [type='radio'], [type='checkbox'], [contenteditable], [type='button']", b).on("click.validate", "select, option, [type='radio'], [type='checkbox']", b), this.settings.invalidHandler && a(this.currentForm).on("invalid-form.validate", this.settings.invalidHandler) }, form: function () { return this.checkForm(), a.extend(this.submitted, this.errorMap), this.invalid = a.extend({}, this.errorMap), this.valid() || a(this.currentForm).triggerHandler("invalid-form", [this]), this.showErrors(), this.valid() }, checkForm: function () { this.prepareForm(); for (var a = 0, b = this.currentElements = this.elements(); b[a]; a++)this.check(b[a]); return this.valid() }, element: function (b) { var c, d, e = this.clean(b), f = this.validationTargetFor(e), g = this, h = !0; return void 0 === f ? delete this.invalid[e.name] : (this.prepareElement(f), this.currentElements = a(f), d = this.groups[f.name], d && a.each(this.groups, function (a, b) { b === d && a !== f.name && (e = g.validationTargetFor(g.clean(g.findByName(a))), e && e.name in g.invalid && (g.currentElements.push(e), h = g.check(e) && h)) }), c = this.check(f) !== !1, h = h && c, c ? this.invalid[f.name] = !1 : this.invalid[f.name] = !0, this.numberOfInvalids() || (this.toHide = this.toHide.add(this.containers)), this.showErrors(), a(b).attr("aria-invalid", !c)), h }, showErrors: function (b) { if (b) { var c = this; a.extend(this.errorMap, b), this.errorList = a.map(this.errorMap, function (a, b) { return { message: a, element: c.findByName(b)[0] } }), this.successList = a.grep(this.successList, function (a) { return !(a.name in b) }) } this.settings.showErrors ? this.settings.showErrors.call(this, this.errorMap, this.errorList) : this.defaultShowErrors() }, resetForm: function () { a.fn.resetForm && a(this.currentForm).resetForm(), this.invalid = {}, this.submitted = {}, this.prepareForm(), this.hideErrors(); var b = this.elements().removeData("previousValue").removeAttr("aria-invalid"); this.resetElements(b) }, resetElements: function (a) { var b; if (this.settings.unhighlight) for (b = 0; a[b]; b++)this.settings.unhighlight.call(this, a[b], this.settings.errorClass, ""), this.findByName(a[b].name).removeClass(this.settings.validClass); else a.removeClass(this.settings.errorClass).removeClass(this.settings.validClass) }, numberOfInvalids: function () { return this.objectLength(this.invalid) }, objectLength: function (a) { var b, c = 0; for (b in a) void 0 !== a[b] && null !== a[b] && a[b] !== !1 && c++; return c }, hideErrors: function () { this.hideThese(this.toHide) }, hideThese: function (a) { a.not(this.containers).text(""), this.addWrapper(a).hide() }, valid: function () { return 0 === this.size() }, size: function () { return this.errorList.length }, focusInvalid: function () { if (this.settings.focusInvalid) try { a(this.findLastActive() || this.errorList.length && this.errorList[0].element || []).filter(":visible").trigger("focus").trigger("focusin") } catch (b) { } }, findLastActive: function () { var b = this.lastActive; return b && 1 === a.grep(this.errorList, function (a) { return a.element.name === b.name }).length && b }, elements: function () { var b = this, c = {}; return a(this.currentForm).find("input, select, textarea, [contenteditable]").not(":submit, :reset, :image, :disabled").not(this.settings.ignore).filter(function () { var d = this.name || a(this).attr("name"), e = "undefined" != typeof a(this).attr("contenteditable") && "false" !== a(this).attr("contenteditable"); return !d && b.settings.debug && window.console && console.error("%o has no name assigned", this), e && (this.form = a(this).closest("form")[0], this.name = d), this.form === b.currentForm && (!(d in c || !b.objectLength(a(this).rules())) && (c[d] = !0, !0)) }) }, clean: function (b) { return a(b)[0] }, errors: function () { var b = this.settings.errorClass.split(" ").join("."); return a(this.settings.errorElement + "." + b, this.errorContext) }, resetInternals: function () { this.successList = [], this.errorList = [], this.errorMap = {}, this.toShow = a([]), this.toHide = a([]) }, reset: function () { this.resetInternals(), this.currentElements = a([]) }, prepareForm: function () { this.reset(), this.toHide = this.errors().add(this.containers) }, prepareElement: function (a) { this.reset(), this.toHide = this.errorsFor(a) }, elementValue: function (b) { var c, d, e = a(b), f = b.type, g = "undefined" != typeof e.attr("contenteditable") && "false" !== e.attr("contenteditable"); return "radio" === f || "checkbox" === f ? this.findByName(b.name).filter(":checked").val() : "number" === f && "undefined" != typeof b.validity ? b.validity.badInput ? "NaN" : e.val() : (c = g ? e.text() : e.val(), "file" === f ? "C:\\fakepath\\" === c.substr(0, 12) ? c.substr(12) : (d = c.lastIndexOf("/"), d >= 0 ? c.substr(d + 1) : (d = c.lastIndexOf("\\"), d >= 0 ? c.substr(d + 1) : c)) : "string" == typeof c ? c.replace(/\r/g, "") : c) }, check: function (b) { b = this.validationTargetFor(this.clean(b)); var c, d, e, f, g = a(b).rules(), h = a.map(g, function (a, b) { return b }).length, i = !1, j = this.elementValue(b); "function" == typeof g.normalizer ? f = g.normalizer : "function" == typeof this.settings.normalizer && (f = this.settings.normalizer), f && (j = f.call(b, j), delete g.normalizer); for (d in g) { e = { method: d, parameters: g[d] }; try { if (c = a.validator.methods[d].call(this, j, b, e.parameters), "dependency-mismatch" === c && 1 === h) { i = !0; continue } if (i = !1, "pending" === c) return void (this.toHide = this.toHide.not(this.errorsFor(b))); if (!c) return this.formatAndAdd(b, e), !1 } catch (k) { throw this.settings.debug && window.console && console.log("Exception occurred when checking element " + b.id + ", check the '" + e.method + "' method.", k), k instanceof TypeError && (k.message += ".  Exception occurred when checking element " + b.id + ", check the '" + e.method + "' method."), k } } if (!i) return this.objectLength(g) && this.successList.push(b), !0 }, customDataMessage: function (b, c) { return a(b).data("msg" + c.charAt(0).toUpperCase() + c.substring(1).toLowerCase()) || a(b).data("msg") }, customMessage: function (a, b) { var c = this.settings.messages[a]; return c && (c.constructor === String ? c : c[b]) }, findDefined: function () { for (var a = 0; a < arguments.length; a++)if (void 0 !== arguments[a]) return arguments[a] }, defaultMessage: function (b, c) { "string" == typeof c && (c = { method: c }); var d = this.findDefined(this.customMessage(b.name, c.method), this.customDataMessage(b, c.method), !this.settings.ignoreTitle && b.title || void 0, a.validator.messages[c.method], "<strong>Warning: No message defined for " + b.name + "</strong>"), e = /\$?\{(\d+)\}/g; return "function" == typeof d ? d = d.call(this, c.parameters, b) : e.test(d) && (d = a.validator.format(d.replace(e, "{$1}"), c.parameters)), d }, formatAndAdd: function (a, b) { var c = this.defaultMessage(a, b); this.errorList.push({ message: c, element: a, method: b.method }), this.errorMap[a.name] = c, this.submitted[a.name] = c }, addWrapper: function (a) { return this.settings.wrapper && (a = a.add(a.parent(this.settings.wrapper))), a }, defaultShowErrors: function () { var a, b, c; for (a = 0; this.errorList[a]; a++)c = this.errorList[a], this.settings.highlight && this.settings.highlight.call(this, c.element, this.settings.errorClass, this.settings.validClass), this.showLabel(c.element, c.message); if (this.errorList.length && (this.toShow = this.toShow.add(this.containers)), this.settings.success) for (a = 0; this.successList[a]; a++)this.showLabel(this.successList[a]); if (this.settings.unhighlight) for (a = 0, b = this.validElements(); b[a]; a++)this.settings.unhighlight.call(this, b[a], this.settings.errorClass, this.settings.validClass); this.toHide = this.toHide.not(this.toShow), this.hideErrors(), this.addWrapper(this.toShow).show() }, validElements: function () { return this.currentElements.not(this.invalidElements()) }, invalidElements: function () { return a(this.errorList).map(function () { return this.element }) }, showLabel: function (b, c) { var d, e, f, g, h = this.errorsFor(b), i = this.idOrName(b), j = a(b).attr("aria-describedby"); h.length ? (h.removeClass(this.settings.validClass).addClass(this.settings.errorClass), h.html(c)) : (h = a("<" + this.settings.errorElement + ">").attr("id", i + "-error").addClass(this.settings.errorClass).html(c || ""), d = h, this.settings.wrapper && (d = h.hide().show().wrap("<" + this.settings.wrapper + "/>").parent()), this.labelContainer.length ? this.labelContainer.append(d) : this.settings.errorPlacement ? this.settings.errorPlacement.call(this, d, a(b)) : d.insertAfter(b), h.is("label") ? h.attr("for", i) : 0 === h.parents("label[for='" + this.escapeCssMeta(i) + "']").length && (f = h.attr("id"), j ? j.match(new RegExp("\\b" + this.escapeCssMeta(f) + "\\b")) || (j += " " + f) : j = f, a(b).attr("aria-describedby", j), e = this.groups[b.name], e && (g = this, a.each(g.groups, function (b, c) { c === e && a("[name='" + g.escapeCssMeta(b) + "']", g.currentForm).attr("aria-describedby", h.attr("id")) })))), !c && this.settings.success && (h.text(""), "string" == typeof this.settings.success ? h.addClass(this.settings.success) : this.settings.success(h, b)), this.toShow = this.toShow.add(h) }, errorsFor: function (b) { var c = this.escapeCssMeta(this.idOrName(b)), d = a(b).attr("aria-describedby"), e = "label[for='" + c + "'], label[for='" + c + "'] *"; return d && (e = e + ", #" + this.escapeCssMeta(d).replace(/\s+/g, ", #")), this.errors().filter(e) }, escapeCssMeta: function (a) { return void 0 === a ? "" : a.replace(/([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g, "\\$1") }, idOrName: function (a) { return this.groups[a.name] || (this.checkable(a) ? a.name : a.id || a.name) }, validationTargetFor: function (b) { return this.checkable(b) && (b = this.findByName(b.name)), a(b).not(this.settings.ignore)[0] }, checkable: function (a) { return /radio|checkbox/i.test(a.type) }, findByName: function (b) { return a(this.currentForm).find("[name='" + this.escapeCssMeta(b) + "']") }, getLength: function (b, c) { switch (c.nodeName.toLowerCase()) { case "select": return a("option:selected", c).length; case "input": if (this.checkable(c)) return this.findByName(c.name).filter(":checked").length }return b.length }, depend: function (a, b) { return !this.dependTypes[typeof a] || this.dependTypes[typeof a](a, b) }, dependTypes: { "boolean": function (a) { return a }, string: function (b, c) { return !!a(b, c.form).length }, "function": function (a, b) { return a(b) } }, optional: function (b) { var c = this.elementValue(b); return !a.validator.methods.required.call(this, c, b) && "dependency-mismatch" }, startRequest: function (b) { this.pending[b.name] || (this.pendingRequest++, a(b).addClass(this.settings.pendingClass), this.pending[b.name] = !0) }, stopRequest: function (b, c) { this.pendingRequest--, this.pendingRequest < 0 && (this.pendingRequest = 0), delete this.pending[b.name], a(b).removeClass(this.settings.pendingClass), c && 0 === this.pendingRequest && this.formSubmitted && this.form() && 0 === this.pendingRequest ? (a(this.currentForm).trigger("submit"), this.submitButton && a("input:hidden[name='" + this.submitButton.name + "']", this.currentForm).remove(), this.formSubmitted = !1) : !c && 0 === this.pendingRequest && this.formSubmitted && (a(this.currentForm).triggerHandler("invalid-form", [this]), this.formSubmitted = !1) }, previousValue: function (b, c) { return c = "string" == typeof c && c || "remote", a.data(b, "previousValue") || a.data(b, "previousValue", { old: null, valid: !0, message: this.defaultMessage(b, { method: c }) }) }, destroy: function () { this.resetForm(), a(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur").find(".validate-lessThan-blur").off(".validate-lessThan").removeClass("validate-lessThan-blur").find(".validate-lessThanEqual-blur").off(".validate-lessThanEqual").removeClass("validate-lessThanEqual-blur").find(".validate-greaterThanEqual-blur").off(".validate-greaterThanEqual").removeClass("validate-greaterThanEqual-blur").find(".validate-greaterThan-blur").off(".validate-greaterThan").removeClass("validate-greaterThan-blur") } }, classRuleSettings: { required: { required: !0 }, email: { email: !0 }, url: { url: !0 }, date: { date: !0 }, dateISO: { dateISO: !0 }, number: { number: !0 }, digits: { digits: !0 }, creditcard: { creditcard: !0 } }, addClassRules: function (b, c) { b.constructor === String ? this.classRuleSettings[b] = c : a.extend(this.classRuleSettings, b) }, classRules: function (b) { var c = {}, d = a(b).attr("class"); return d && a.each(d.split(" "), function () { this in a.validator.classRuleSettings && a.extend(c, a.validator.classRuleSettings[this]) }), c }, normalizeAttributeRule: function (a, b, c, d) { /min|max|step/.test(c) && (null === b || /number|range|text/.test(b)) && (d = Number(d), isNaN(d) && (d = void 0)), d || 0 === d ? a[c] = d : b === c && "range" !== b && (a["date" === b ? "dateISO" : c] = !0) }, attributeRules: function (b) { var c, d, e = {}, f = a(b), g = b.getAttribute("type"); for (c in a.validator.methods) "required" === c ? (d = b.getAttribute(c), "" === d && (d = !0), d = !!d) : d = f.attr(c), this.normalizeAttributeRule(e, g, c, d); return e.maxlength && /-1|2147483647|524288/.test(e.maxlength) && delete e.maxlength, e }, dataRules: function (b) { var c, d, e = {}, f = a(b), g = b.getAttribute("type"); for (c in a.validator.methods) d = f.data("rule" + c.charAt(0).toUpperCase() + c.substring(1).toLowerCase()), "" === d && (d = !0), this.normalizeAttributeRule(e, g, c, d); return e }, staticRules: function (b) { var c = {}, d = a.data(b.form, "validator"); return d.settings.rules && (c = a.validator.normalizeRule(d.settings.rules[b.name]) || {}), c }, normalizeRules: function (b, c) { return a.each(b, function (d, e) { if (e === !1) return void delete b[d]; if (e.param || e.depends) { var f = !0; switch (typeof e.depends) { case "string": f = !!a(e.depends, c.form).length; break; case "function": f = e.depends.call(c, c) }f ? b[d] = void 0 === e.param || e.param : (a.data(c.form, "validator").resetElements(a(c)), delete b[d]) } }), a.each(b, function (a, d) { b[a] = "function" == typeof d && "normalizer" !== a ? d(c) : d }), a.each(["minlength", "maxlength"], function () { b[this] && (b[this] = Number(b[this])) }), a.each(["rangelength", "range"], function () { var a; b[this] && (Array.isArray(b[this]) ? b[this] = [Number(b[this][0]), Number(b[this][1])] : "string" == typeof b[this] && (a = b[this].replace(/[\[\]]/g, "").split(/[\s,]+/), b[this] = [Number(a[0]), Number(a[1])])) }), a.validator.autoCreateRanges && (null != b.min && null != b.max && (b.range = [b.min, b.max], delete b.min, delete b.max), null != b.minlength && null != b.maxlength && (b.rangelength = [b.minlength, b.maxlength], delete b.minlength, delete b.maxlength)), b }, normalizeRule: function (b) { if ("string" == typeof b) { var c = {}; a.each(b.split(/\s/), function () { c[this] = !0 }), b = c } return b }, addMethod: function (b, c, d) { a.validator.methods[b] = c, a.validator.messages[b] = void 0 !== d ? d : a.validator.messages[b], c.length < 3 && a.validator.addClassRules(b, a.validator.normalizeRule(b)) }, methods: { required: function (b, c, d) { if (!this.depend(d, c)) return "dependency-mismatch"; if ("select" === c.nodeName.toLowerCase()) { var e = a(c).val(); return e && e.length > 0 } return this.checkable(c) ? this.getLength(b, c) > 0 : void 0 !== b && null !== b && b.length > 0 }, email: function (a, b) { return this.optional(b) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(a) }, url: function (a, b) { return this.optional(b) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:(?:[^\]\[?\/<~#`!@$^&*()+=}|:";',>{ ]|%[0-9A-Fa-f]{2})+(?::(?:[^\]\[?\/<~#`!@$^&*()+=}|:";',>{ ]|%[0-9A-Fa-f]{2})*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[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]))|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff]\.)+(?:[a-z\u00a1-\uffff]{2,}\.?))(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(a) }, date: function () { var a = !1; return function (b, c) { return a || (a = !0, this.settings.debug && window.console && console.warn("The `date` method is deprecated and will be removed in version '2.0.0'.\nPlease don't use it, since it relies on the Date constructor, which\nbehaves very differently across browsers and locales. Use `dateISO`\ninstead or one of the locale specific methods in `localizations/`\nand `additional-methods.js`.")), this.optional(c) || !/Invalid|NaN/.test(new Date(b).toString()) } }(), dateISO: function (a, b) { return this.optional(b) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(a) }, number: function (a, b) { return this.optional(b) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a) }, digits: function (a, b) { return this.optional(b) || /^\d+$/.test(a) }, minlength: function (a, b, c) { var d = Array.isArray(a) ? a.length : this.getLength(a, b); return this.optional(b) || d >= c }, maxlength: function (a, b, c) { var d = Array.isArray(a) ? a.length : this.getLength(a, b); return this.optional(b) || d <= c }, rangelength: function (a, b, c) { var d = Array.isArray(a) ? a.length : this.getLength(a, b); return this.optional(b) || d >= c[0] && d <= c[1] }, min: function (a, b, c) { return this.optional(b) || a >= c }, max: function (a, b, c) { return this.optional(b) || a <= c }, range: function (a, b, c) { return this.optional(b) || a >= c[0] && a <= c[1] }, step: function (b, c, d) { var e, f = a(c).attr("type"), g = "Step attribute on input type " + f + " is not supported.", h = ["text", "number", "range"], i = new RegExp("\\b" + f + "\\b"), j = f && !i.test(h.join()), k = function (a) { var b = ("" + a).match(/(?:\.(\d+))?$/); return b && b[1] ? b[1].length : 0 }, l = function (a) { return Math.round(a * Math.pow(10, e)) }, m = !0; if (j) throw new Error(g); return e = k(d), (k(b) > e || l(b) % l(d) !== 0) && (m = !1), this.optional(c) || m }, equalTo: function (b, c, d) { var e = a(d); return this.settings.onfocusout && e.not(".validate-equalTo-blur").length && e.addClass("validate-equalTo-blur").on("blur.validate-equalTo", function () { a(c).valid() }), b === e.val() }, remote: function (b, c, d, e) { if (this.optional(c)) return "dependency-mismatch"; e = "string" == typeof e && e || "remote"; var f, g, h, i = this.previousValue(c, e); return this.settings.messages[c.name] || (this.settings.messages[c.name] = {}), i.originalMessage = i.originalMessage || this.settings.messages[c.name][e], this.settings.messages[c.name][e] = i.message, d = "string" == typeof d && { url: d } || d, h = a.param(a.extend({ data: b }, d.data)), i.old === h ? i.valid : (i.old = h, f = this, this.startRequest(c), g = {}, g[c.name] = b, a.ajax(a.extend(!0, { mode: "abort", port: "validate" + c.name, dataType: "json", data: g, context: f.currentForm, success: function (a) { var d, g, h, j = a === !0 || "true" === a; f.settings.messages[c.name][e] = i.originalMessage, j ? (h = f.formSubmitted, f.resetInternals(), f.toHide = f.errorsFor(c), f.formSubmitted = h, f.successList.push(c), f.invalid[c.name] = !1, f.showErrors()) : (d = {}, g = a || f.defaultMessage(c, { method: e, parameters: b }), d[c.name] = i.message = g, f.invalid[c.name] = !0, f.showErrors(d)), i.valid = j, f.stopRequest(c, j) } }, d)), "pending") } } }); var c, d = {}; return a.ajaxPrefilter ? a.ajaxPrefilter(function (a, b, c) { var e = a.port; "abort" === a.mode && (d[e] && d[e].abort(), d[e] = c) }) : (c = a.ajax, a.ajax = function (b) { var e = ("mode" in b ? b : a.ajaxSettings).mode, f = ("port" in b ? b : a.ajaxSettings).port; return "abort" === e ? (d[f] && d[f].abort(), d[f] = c.apply(this, arguments), d[f]) : c.apply(this, arguments) }), a });

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.