PageSourceSearch

https://xxgk.gxau.edu.cn/content/_common/assets/scripts/jquery.val…Rli4PalyQEMC7lnFAScLM0HHbd6lR2En0U3OFPCemjU

js gxau.edu.cn collected 2026-10-06 07:39:06 UTC 52,607 bytes, 1,706 lines download raw bytes

vendor: 47,808 bytes, lines 1-1553
1/*!
2 * jQuery Validation Plugin v1.19.5
3 *
4 * https://jqueryvalidation.org/
5 *
6 * Copyright (c) 2022 Jörn Zaefferer
7 * Released under the MIT license
8 */
9(function (factory) {
10	if (typeof define === "function" && define.amd) {
11		define(["jquery"], factory);
12	} else if (typeof module === "object" && module.exports) {
13		module.exports = factory(require("jquery"));
14	} else {
15		factory(jQuery);
16	}
17}(function ($) {
18
19	$.extend($.fn, {
20
21		// https://jqueryvalidation.org/validate/
22		validate: function (options) {
23
24			// If nothing is selected, return nothing; can't chain anyway
25			if (!this.length) {
26				if (options && options.debug && window.console) {
27					console.warn("Nothing selected, can't validate, returning nothing.");
28				}
29				return;
30			}
31
32			// Check if a validator for this form was already created
33			var validator = $.data(this[0], "validator");
34			if (validator) {
35				return validator;
36			}
37
38			// Add novalidate tag if HTML5.
39			this.attr("novalidate", "novalidate");
40
41			validator = new $.validator(options, this[0]);
42			$.data(this[0], "validator", validator);
43
44			if (validator.settings.onsubmit) {
45
46				this.on("click.validate", ":submit", function (event) {
47
48					// Track the used submit button to properly handle scripted
49					// submits later.
50					validator.submitButton = event.currentTarget;
51
52					// Allow suppressing validation by adding a cancel class to the submit button
53					if ($(this).hasClass("cancel")) {
54						validator.cancelSubmit = true;
55					}
56
57					// Allow suppressing validation by adding the html5 formnovalidate attribute to the submit button
58					if ($(this).attr("formnovalidate") !== undefined) {
59						validator.cancelSubmit = true;
60					}
61				});
62
63				// Validate the form on submit
64				this.on("submit.validate", function (event) {
65					if (validator.settings.debug) {
66
67						// Prevent form submit to be able to see console output
68						event.preventDefault();
69					}
70
71					function handle() {
72						var hidden, result;
73
74						// Insert a hidden input as a replacement for the missing submit button
75						// The hidden input is inserted in two cases:
76						//   - A user defined a `submitHandler`
77						//   - There was a pending request due to `remote` method and `stopRequest()`
78						//     was called to submit the form in case it's valid
79						if (validator.submitButton && (validator.settings.submitHandler || validator.formSubmitted)) {
80							hidden = $("<input type='hidden'/>")
81								.attr("name", validator.submitButton.name)
82								.val($(validator.submitButton).val())
83								.appendTo(validator.currentForm);
84						}
85
86						if (validator.settings.submitHandler && !validator.settings.debug) {
87							result = validator.settings.submitHandler.call(validator, validator.currentForm, event);
88							if (hidden) {
89
90								// And clean up afterwards; thanks to no-block-scope, hidden can be referenced
91								hidden.remove();
92							}
93							if (result !== undefined) {
94								return result;
95							}
96							return false;
97						}
98						return true;
99					}
100
101					// Prevent submit for invalid forms or custom submit handlers
102					if (validator.cancelSubmit) {
103						validator.cancelSubmit = false;
104						return handle();
105					}
106					if (validator.form()) {
107						if (validator.pendingRequest) {
108							validator.formSubmitted = true;
109							return false;
110						}
111						return handle();
112					} else {
113						validator.focusInvalid();
114						return false;
115					}
116				});
117			}
118
119			return validator;
120		},
121
122		// https://jqueryvalidation.org/valid/
123		valid: function () {
124			var valid, validator, errorList;
125
126			if ($(this[0]).is("form")) {
127				valid = this.validate().form();
128			} else {
129				errorList = [];
130				valid = true;
131				validator = $(this[0].form).validate();
132				this.each(function () {
133					valid = validator.element(this) && valid;
134					if (!valid) {
135						errorList = errorList.concat(validator.errorList);
136					}
137				});
138				validator.errorList = errorList;
139			}
140			return valid;
141		},
142
143		// https://jqueryvalidation.org/rules/
144		rules: function (command, argument) {
145			var element = this[0],
146				isContentEditable = typeof this.attr("contenteditable") !== "undefined" && this.attr("contenteditable") !== "false",
147				settings, staticRules, existingRules, data, param, filtered;
148
149			// If nothing is selected, return empty object; can't chain anyway
150			if (element == null) {
151				return;
152			}
153
154			if (!element.form && isContentEditable) {
155				element.form = this.closest("form")[0];
156				element.name = this.attr("name");
157			}
158
159			if (element.form == null) {
160				return;
161			}
162
163			if (command) {
164				settings = $.data(element.form, "validator").settings;
165				staticRules = settings.rules;
166				existingRules = $.validator.staticRules(element);
167				switch (command) {
168					case "add":
169						$.extend(existingRules, $.validator.normalizeRule(argument));
170
171						// Remove messages from rules, but allow them to be set separately
172						delete existingRules.messages;
173						staticRules[element.name] = existingRules;
174						if (argument.messages) {
175							settings.messages[element.name] = $.extend(settings.messages[element.name], argument.messages);
176						}
177						break;
178					case "remove":
179						if (!argument) {
180							delete staticRules[element.name];
181							return existingRules;
182						}
183						filtered = {};
184						$.each(argument.split(/\s/), function (index, method) {
185							filtered[method] = existingRules[method];
186							delete existingRules[method];
187						});
188						return filtered;
189				}
190			}
191
192			data = $.validator.normalizeRules(
193				$.extend(
194					{},
195					$.validator.classRules(element),
196					$.validator.attributeRules(element),
197					$.validator.dataRules(element),
198					$.validator.staticRules(element)
199				), element);
200
201			// Make sure required is at front
202			if (data.required) {
203				param = data.required;
204				delete data.required;
205				data = $.extend({ required: param }, data);
206			}
207
208			// Make sure remote is at back
209			if (data.remote) {
210				param = data.remote;
211				delete data.remote;
212				data = $.extend(data, { remote: param });
213			}
214
215			return data;
216		}
217	});
218
219	// JQuery trim is deprecated, provide a trim method based on String.prototype.trim
220	var trim = function (str) {
221
222		// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trim#Polyfill
223		return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, "");
224	};
225
226	// Custom selectors
227	$.extend($.expr.pseudos || $.expr[":"], {		// '|| $.expr[ ":" ]' here enables backwards compatibility to jQuery 1.7. Can be removed when dropping jQ 1.7.x support
228
229		// https://jqueryvalidation.org/blank-selector/
230		blank: function (a) {
231			return !trim("" + $(a).val());
232		},
233
234		// https://jqueryvalidation.org/filled-selector/
235		filled: function (a) {
236			var val = $(a).val();
237			return val !== null && !!trim("" + val);
238		},
239
240		// https://jqueryvalidation.org/unchecked-selector/
241		unchecked: function (a) {
242			return !$(a).prop("checked");
243		}
244	});
245
246	// Constructor for validator
247	$.validator = function (options, form) {
248		this.settings = $.extend(true, {}, $.validator.defaults, options);
249		this.currentForm = form;
250		this.init();
251	};
252
253	// https://jqueryvalidation.org/jQuery.validator.format/
254	$.validator.format = function (source, params) {
255		if (arguments.length === 1) {
256			return function () {
257				var args = $.makeArray(arguments);
258				args.unshift(source);
259				return $.validator.format.apply(this, args);
260			};
261		}
262		if (params === undefined) {
263			return source;
264		}
265		if (arguments.length > 2 && params.constructor !== Array) {
266			params = $.makeArray(arguments).slice(1);
267		}
268		if (params.constructor !== Array) {
269			params = [params];
270		}
271		$.each(params, function (i, n) {
272			source = source.replace(new RegExp("\\{" + i + "\\}", "g"), function () {
273				return n;
274			});
275		});
276		return source;
277	};
278
279	$.extend($.validator, {
280
281		defaults: {
282			messages: {},
283			groups: {},
284			rules: {},
285			errorClass: "error",
286			pendingClass: "pending",
287			validClass: "valid",
288			errorElement: "label",
289			focusCleanup: false,
290			focusInvalid: true,
291			errorContainer: $([]),
292			errorLabelContainer: $([]),
293			onsubmit: true,
294			ignore: ":hidden",
295			ignoreTitle: false,
296			onfocusin: function (element) {
297				this.lastActive = element;
298
299				// Hide error label and remove error class on focus if enabled
300				if (this.settings.focusCleanup) {
301					if (this.settings.unhighlight) {
302						this.settings.unhighlight.call(this, element, this.settings.errorClass, this.settings.validClass);
303					}
304					this.hideThese(this.errorsFor(element));
305				}
306			},
307			onfocusout: function (element) {
308				if (!this.checkable(element) && (element.name in this.submitted || !this.optional(element))) {
309					this.element(element);
310				}
311			},
312			onkeyup: function (element, event) {
313
314				// Avoid revalidate the field when pressing one of the following keys
315				// Shift       => 16
316				// Ctrl        => 17
317				// Alt         => 18
318				// Caps lock   => 20
319				// End         => 35
320				// Home        => 36
321				// Left arrow  => 37
322				// Up arrow    => 38
323				// Right arrow => 39
324				// Down arrow  => 40
325				// Insert      => 45
326				// Num lock    => 144
327				// AltGr key   => 225
328				var excludedKeys = [
329					16, 17, 18, 20, 35, 36, 37,
330					38, 39, 40, 45, 144, 225
331				];
332
333				if (event.which === 9 && this.elementValue(element) === "" || $.inArray(event.keyCode, excludedKeys) !== -1) {
334					return;
335				} else if (element.name in this.submitted || element.name in this.invalid) {
336					this.element(element);
337				}
338			},
339			onclick: function (element) {
340
341				// Click on selects, radiobuttons and checkboxes
342				if (element.name in this.submitted) {
343					this.element(element);
344
345					// Or option elements, check parent select in that case
346				} else if (element.parentNode.name in this.submitted) {
347					this.element(element.parentNode);
348				}
349			},
350			highlight: function (element, errorClass, validClass) {
351				if (element.type === "radio") {
352					this.findByName(element.name).addClass(errorClass).removeClass(validClass);
353				} else {
354					$(element).addClass(errorClass).removeClass(validClass);
355				}
356			},
357			unhighlight: function (element, errorClass, validClass) {
358				if (element.type === "radio") {
359					this.findByName(element.name).removeClass(errorClass).addClass(validClass);
360				} else {
361					$(element).removeClass(errorClass).addClass(validClass);
362				}
363			}
364		},
365
366		// https://jqueryvalidation.org/jQuery.validator.setDefaults/
367		setDefaults: function (settings) {
368			$.extend($.validator.defaults, settings);
369		},
370
371		messages: {
372			required: "This field is required.",
373			remote: "Please fix this field.",
374			email: "Please enter a valid email address.",
375			phone: "请输入正确的手机号码",
376			url: "Please enter a valid URL.",
377			date: "Please enter a valid date.",
378			dateISO: "Please enter a valid date (ISO).",
379			number: "Please enter a valid number.",
380			digits: "Please enter only digits.",
381			equalTo: "Please enter the same value again.",
382			maxlength: $.validator.format("Please enter no more than {0} characters."),
383			minlength: $.validator.format("Please enter at least {0} characters."),
384			rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."),
385			range: $.validator.format("Please enter a value between {0} and {1}."),
386			max: $.validator.format("Please enter a value less than or equal to {0}."),
387			min: $.validator.format("Please enter a value greater than or equal to {0}."),
388			step: $.validator.format("Please enter a multiple of {0}.")
389		},
390
391		autoCreateRanges: false,
392
393		prototype: {
394
395			init: function () {
396				this.labelContainer = $(this.settings.errorLabelContainer);
397				this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm);
398				this.containers = $(this.settings.errorContainer).add(this.settings.errorLabelContainer);
399				this.submitted = {};
400				this.valueCache = {};
401				this.pendingRequest = 0;
402				this.pending = {};
403				this.invalid = {};
404				this.reset();
405
406				var currentForm = this.currentForm,
407					groups = (this.groups = {}),
408					rules;
409				$.each(this.settings.groups, function (key, value) {
410					if (typeof value === "string") {
411						value = value.split(/\s/);
412					}
413					$.each(value, function (index, name) {
414						groups[name] = key;
415					});
416				});
417				rules = this.settings.rules;
418				$.each(rules, function (key, value) {
419					rules[key] = $.validator.normalizeRule(value);
420				});
421
422				function delegate(event) {
423					var isContentEditable = typeof $(this).attr("contenteditable") !== "undefined" && $(this).attr("contenteditable") !== "false";
424
425					// Set form expando on contenteditable
426					if (!this.form && isContentEditable) {
427						this.form = $(this).closest("form")[0];
428						this.name = $(this).attr("name");
429					}
430
431					// Ignore the element if it belongs to another form. This will happen mainly
432					// when setting the `form` attribute of an input to the id of another form.
433					if (currentForm !== this.form) {
434						return;
435					}
436
437					var validator = $.data(this.form, "validator"),
438						eventType = "on" + event.type.replace(/^validate/, ""),
439						settings = validator.settings;
440					if (settings[eventType] && !$(this).is(settings.ignore)) {
441						settings[eventType].call(validator, this, event);
442					}
443				}
444
445				$(this.currentForm)
446					.on("focusin.validate focusout.validate keyup.validate",
447						":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], " +
448						"[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], " +
449						"[type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], " +
450						"[type='radio'], [type='checkbox'], [contenteditable], [type='button']", delegate)
451
452					// Support: Chrome, oldIE
453					// "select" is provided as event.target when clicking a option
454					.on("click.validate", "select, option, [type='radio'], [type='checkbox']", delegate);
455
456				if (this.settings.invalidHandler) {
457					$(this.currentForm).on("invalid-form.validate", this.settings.invalidHandler);
458				}
459			},
460
461			// https://jqueryvalidation.org/Validator.form/
462			form: function () {
463				this.checkForm();
464				$.extend(this.submitted, this.errorMap);
465				this.invalid = $.extend({}, this.errorMap);
466				if (!this.valid()) {
467					$(this.currentForm).triggerHandler("invalid-form", [this]);
468				}
469				this.showErrors();
470				return this.valid();
471			},
472
473			checkForm: function () {
474				this.prepareForm();
475				for (var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++) {
476					this.check(elements[i]);
477				}
478				return this.valid();
479			},
480
481			// https://jqueryvalidation.org/Validator.element/
482			element: function (element) {
483				var cleanElement = this.clean(element),
484					checkElement = this.validationTargetFor(cleanElement),
485					v = this,
486					result = true,
487					rs, group;
488
489				if (checkElement === undefined) {
490					delete this.invalid[cleanElement.name];
491				} else {
492					this.prepareElement(checkElement);
493					this.currentElements = $(checkElement);
494
495					// If this element is grouped, then validate all group elements already
496					// containing a value
497					group = this.groups[checkElement.name];
498					if (group) {
499						$.each(this.groups, function (name, testgroup) {
500							if (testgroup === group && name !== checkElement.name) {
501								cleanElement = v.validationTargetFor(v.clean(v.findByName(name)));
502								if (cleanElement && cleanElement.name in v.invalid) {
503									v.currentElements.push(cleanElement);
504									result = v.check(cleanElement) && result;
505								}
506							}
507						});
508					}
509
510					rs = this.check(checkElement) !== false;
511					result = result && rs;
512					if (rs) {
513						this.invalid[checkElement.name] = false;
514					} else {
515						this.invalid[checkElement.name] = true;
516					}
517
518					if (!this.numberOfInvalids()) {
519
520						// Hide error containers on last error
521						this.toHide = this.toHide.add(this.containers);
522					}
523					this.showErrors();
524
525					// Add aria-invalid status for screen readers
526					$(element).attr("aria-invalid", !rs);
527				}
528
529				return result;
530			},
531
532			// https://jqueryvalidation.org/Validator.showErrors/
533			showErrors: function (errors) {
534				if (errors) {
535					var validator = this;
536
537					// Add items to error list and map
538					$.extend(this.errorMap, errors);
539					this.errorList = $.map(this.errorMap, function (message, name) {
540						return {
541							message: message,
542							element: validator.findByName(name)[0]
543						};
544					});
545
546					// Remove items from success list
547					this.successList = $.grep(this.successList, function (element) {
548						return !(element.name in errors);
549					});
550				}
551				if (this.settings.showErrors) {
552					this.settings.showErrors.call(this, this.errorMap, this.errorList);
553				} else {
554					this.defaultShowErrors();
555				}
556			},
557
558			// https://jqueryvalidation.org/Validator.resetForm/
559			resetForm: function () {
560				if ($.fn.resetForm) {
561					$(this.currentForm).resetForm();
562				}
563				this.invalid = {};
564				this.submitted = {};
565				this.prepareForm();
566				this.hideErrors();
567				var elements = this.elements()
568					.removeData("previousValue")
569					.removeAttr("aria-invalid");
570
571				this.resetElements(elements);
572			},
573
574			resetElements: function (elements) {
575				var i;
576
577				if (this.settings.unhighlight) {
578					for (i = 0; elements[i]; i++) {
579						this.settings.unhighlight.call(this, elements[i],
580							this.settings.errorClass, "");
581						this.findByName(elements[i].name).removeClass(this.settings.validClass);
582					}
583				} else {
584					elements
585						.removeClass(this.settings.errorClass)
586						.removeClass(this.settings.validClass);
587				}
588			},
589
590			numberOfInvalids: function () {
591				return this.objectLength(this.invalid);
592			},
593
594			objectLength: function (obj) {
595				/* jshint unused: false */
596				var count = 0,
597					i;
598				for (i in obj) {
599
600					// This check allows counting elements with empty error
601					// message as invalid elements
602					if (obj[i] !== undefined && obj[i] !== null && obj[i] !== false) {
603						count++;
604					}
605				}
606				return count;
607			},
608
609			hideErrors: function () {
610				this.hideThese(this.toHide);
611			},
612
613			hideThese: function (errors) {
614				errors.not(this.containers).text("");
615				this.addWrapper(errors).hide();
616			},
617
618			valid: function () {
619				return this.size() === 0;
620			},
621
622			size: function () {
623				return this.errorList.length;
624			},
625
626			focusInvalid: function () {
627				if (this.settings.focusInvalid) {
628					try {
629						$(this.findLastActive() || this.errorList.length && this.errorList[0].element || [])
630							.filter(":visible")
631							.trigger("focus")
632
633							// Manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
634							.trigger("focusin");
635					} catch (e) {
636
637						// Ignore IE throwing errors when focusing hidden elements
638					}
639				}
640			},
641
642			findLastActive: function () {
643				var lastActive = this.lastActive;
644				return lastActive && $.grep(this.errorList, function (n) {
645					return n.element.name === lastActive.name;
646				}).length === 1 && lastActive;
647			},
648
649			elements: function () {
650				var validator = this,
651					rulesCache = {};
652
653				// Select all valid inputs inside the form (no submit or reset buttons)
654				return $(this.currentForm)
655					.find("input, select, textarea, [contenteditable]")
656					.not(":submit, :reset, :image, :disabled")
657					.not(this.settings.ignore)
658					.filter(function () {
659						var name = this.name || $(this).attr("name"); // For contenteditable
660						var isContentEditable = typeof $(this).attr("contenteditable") !== "undefined" && $(this).attr("contenteditable") !== "false";
661
662						if (!name && validator.settings.debug && window.console) {
663							console.error("%o has no name assigned", this);
664						}
665
666						// Set form expando on contenteditable
667						if (isContentEditable) {
668							this.form = $(this).closest("form")[0];
669							this.name = name;
670						}
671
672						// Ignore elements that belong to other/nested forms
673						if (this.form !== validator.currentForm) {
674							return false;
675						}
676
677						// Select only the first element for each name, and only those with rules specified
678						if (name in rulesCache || !validator.objectLength($(this).rules())) {
679							return false;
680						}
681
682						rulesCache[name] = true;
683						return true;
684					});
685			},
686
687			clean: function (selector) {
688				return $(selector)[0];
689			},
690
691			errors: function () {
692				var errorClass = this.settings.errorClass.split(" ").join(".");
693				return $(this.settings.errorElement + "." + errorClass, this.errorContext);
694			},
695
696			resetInternals: function () {
697				this.successList = [];
698				this.errorList = [];
699				this.errorMap = {};
700				this.toShow = $([]);
701				this.toHide = $([]);
702			},
703
704			reset: function () {
705				this.resetInternals();
706				this.currentElements = $([]);
707			},
708
709			prepareForm: function () {
710				this.reset();
711				this.toHide = this.errors().add(this.containers);
712			},
713
714			prepareElement: function (element) {
715				this.reset();
716				this.toHide = this.errorsFor(element);
717			},
718
719			elementValue: function (element) {
720				var $element = $(element),
721					type = element.type,
722					isContentEditable = typeof $element.attr("contenteditable") !== "undefined" && $element.attr("contenteditable") !== "false",
723					val, idx;
724
725				if (type === "radio" || type === "checkbox") {
726					return this.findByName(element.name).filter(":checked").val();
727				} else if (type === "number" && typeof element.validity !== "undefined") {
728					return element.validity.badInput ? "NaN" : $element.val();
729				}
730
731				if (isContentEditable) {
732					val = $element.text();
733				} else {
734					val = $element.val();
735				}
736
737				if (type === "file") {
738
739					// Modern browser (chrome & safari)
740					if (val.substr(0, 12) === "C:\\fakepath\\") {
741						return val.substr(12);
742					}
743
744					// Legacy browsers
745					// Unix-based path
746					idx = val.lastIndexOf("/");
747					if (idx >= 0) {
748						return val.substr(idx + 1);
749					}
750
751					// Windows-based path
752					idx = val.lastIndexOf("\\");
753					if (idx >= 0) {
754						return val.substr(idx + 1);
755					}
756
757					// Just the file name
758					return val;
759				}
760
761				if (typeof val === "string") {
762					return val.replace(/\r/g, "");
763				}
764				return val;
765			},
766
767			check: function (element) {
768				element = this.validationTargetFor(this.clean(element));
769
770				var rules = $(element).rules(),
771					rulesCount = $.map(rules, function (n, i) {
772						return i;
773					}).length,
774					dependencyMismatch = false,
775					val = this.elementValue(element),
776					result, method, rule, normalizer;
777
778				// Prioritize the local normalizer defined for this element over the global one
779				// if the former exists, otherwise user the global one in case it exists.
780				if (typeof rules.normalizer === "function") {
781					normalizer = rules.normalizer;
782				} else if (typeof this.settings.normalizer === "function") {
783					normalizer = this.settings.normalizer;
784				}
785
786				// If normalizer is defined, then call it to retreive the changed value instead
787				// of using the real one.
788				// Note that `this` in the normalizer is `element`.
789				if (normalizer) {
790					val = normalizer.call(element, val);
791
792					// Delete the normalizer from rules to avoid treating it as a pre-defined method.
793					delete rules.normalizer;
794				}
795
796				for (method in rules) {
797					rule = { method: method, parameters: rules[method] };
798					try {
799						result = $.validator.methods[method].call(this, val, element, rule.parameters);
800
801						// If a method indicates that the field is optional and therefore valid,
802						// don't mark it as valid when there are no other rules
803						if (result === "dependency-mismatch" && rulesCount === 1) {
804							dependencyMismatch = true;
805							continue;
806						}
807						dependencyMismatch = false;
808
809						if (result === "pending") {
810							this.toHide = this.toHide.not(this.errorsFor(element));
811							return;
812						}
813
814						if (!result) {
815							this.formatAndAdd(element, rule);
816							return false;
817						}
818					} catch (e) {
819						if (this.settings.debug && window.console) {
820							console.log("Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e);
821						}
822						if (e instanceof TypeError) {
823							e.message += ".  Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.";
824						}
825
826						throw e;
827					}
828				}
829				if (dependencyMismatch) {
830					return;
831				}
832				if (this.objectLength(rules)) {
833					this.successList.push(element);
834				}
835				return true;
836			},
837
838			// Return the custom message for the given element and validation method
839			// specified in the element's HTML5 data attribute
840			// return the generic message if present and no method specific message is present
841			customDataMessage: function (element, method) {
842				return $(element).data("msg" + method.charAt(0).toUpperCase() +
843					method.substring(1).toLowerCase()) || $(element).data("msg");
844			},
845
846			// Return the custom message for the given element name and validation method
847			customMessage: function (name, method) {
848				var m = this.settings.messages[name];
849				return m && (m.constructor === String ? m : m[method]);
850			},
851
852			// Return the first defined argument, allowing empty strings
853			findDefined: function () {
854				for (var i = 0; i < arguments.length; i++) {
855					if (arguments[i] !== undefined) {
856						return arguments[i];
857					}
858				}
859				return undefined;
860			},
861
862			// The second parameter 'rule' used to be a string, and extended to an object literal
863			// of the following form:
864			// rule = {
865			//     method: "method name",
866			//     parameters: "the given method parameters"
867			// }
868			//
869			// The old behavior still supported, kept to maintain backward compatibility with
870			// old code, and will be removed in the next major release.
871			defaultMessage: function (element, rule) {
872				if (typeof rule === "string") {
873					rule = { method: rule };
874				}
875
876				var message = this.findDefined(
877					this.customMessage(element.name, rule.method),
878					this.customDataMessage(element, rule.method),
879
880					// 'title' is never undefined, so handle empty string as undefined
881					!this.settings.ignoreTitle && element.title || undefined,
882					$.validator.messages[rule.method],
883					"<strong>Warning: No message defined for " + element.name + "</strong>"
884				),
885					theregex = /\$?\{(\d+)\}/g;
886				if (typeof message === "function") {
887					message = message.call(this, rule.parameters, element);
888				} else if (theregex.test(message)) {
889					message = $.validator.format(message.replace(theregex, "{$1}"), rule.parameters);
890				}
891
892				return message;
893			},
894
895			formatAndAdd: function (element, rule) {
896				var message = this.defaultMessage(element, rule);
897
898				this.errorList.push({
899					message: message,
900					element: element,
901					method: rule.method
902				});
903
904				this.errorMap[element.name] = message;
905				this.submitted[element.name] = message;
906			},
907
908			addWrapper: function (toToggle) {
909				if (this.settings.wrapper) {
910					toToggle = toToggle.add(toToggle.parent(this.settings.wrapper));
911				}
912				return toToggle;
913			},
914
915			defaultShowErrors: function () {
916				var i, elements, error;
917				for (i = 0; this.errorList[i]; i++) {
918					error = this.errorList[i];
919					if (this.settings.highlight) {
920						this.settings.highlight.call(this, error.element, this.settings.errorClass, this.settings.validClass);
921					}
922					this.showLabel(error.element, error.message);
923				}
924				if (this.errorList.length) {
925					this.toShow = this.toShow.add(this.containers);
926				}
927				if (this.settings.success) {
928					for (i = 0; this.successList[i]; i++) {
929						this.showLabel(this.successList[i]);
930					}
931				}
932				if (this.settings.unhighlight) {
933					for (i = 0, elements = this.validElements(); elements[i]; i++) {
934						this.settings.unhighlight.call(this, elements[i], this.settings.errorClass, this.settings.validClass);
935					}
936				}
937				this.toHide = this.toHide.not(this.toShow);
938				this.hideErrors();
939				this.addWrapper(this.toShow).show();
940			},
941
942			validElements: function () {
943				return this.currentElements.not(this.invalidElements());
944			},
945
946			invalidElements: function () {
947				return $(this.errorList).map(function () {
948					return this.element;
949				});
950			},
951
952			showLabel: function (element, message) {
953				var place, group, errorID, v,
954					error = this.errorsFor(element),
955					elementID = this.idOrName(element),
956					describedBy = $(element).attr("aria-describedby");
957
958				if (error.length) {
959
960					// Refresh error/success class
961					error.removeClass(this.settings.validClass).addClass(this.settings.errorClass);
962
963					// Replace message on existing label
964					error.html(message);
965				} else {
966
967					// Create error element
968					error = $("<" + this.settings.errorElement + ">")
969						.attr("id", elementID + "-error")
970						.addClass(this.settings.errorClass)
971						.html(message || "");
972
973					// Maintain reference to the element to be placed into the DOM
974					place = error;
975					if (this.settings.wrapper) {
976
977						// Make sure the element is visible, even in IE
978						// actually showing the wrapped element is handled elsewhere
979						place = error.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
980					}
981					if (this.labelContainer.length) {
982						this.labelContainer.append(place);
983					} else if (this.settings.errorPlacement) {
984						this.settings.errorPlacement.call(this, place, $(element));
985					} else {
986						place.insertAfter(element);
987					}
988
989					// Link error back to the element
990					if (error.is("label")) {
991
992						// If the error is a label, then associate using 'for'
993						error.attr("for", elementID);
994
995						// If the element is not a child of an associated label, then it's necessary
996						// to explicitly apply aria-describedby
997					} else if (error.parents("label[for='" + this.escapeCssMeta(elementID) + "']").length === 0) {
998						errorID = error.attr("id");
999
1000						// Respect existing non-error aria-describedby
1001						if (!describedBy) {
1002							describedBy = errorID;
1003						} else if (!describedBy.match(new RegExp("\\b" + this.escapeCssMeta(errorID) + "\\b"))) {
1004
1005							// Add to end of list if not already present
1006							describedBy += " " + errorID;
1007						}
1008						$(element).attr("aria-describedby", describedBy);
1009
1010						// If this element is grouped, then assign to all elements in the same group
1011						group = this.groups[element.name];
1012						if (group) {
1013							v = this;
1014							$.each(v.groups, function (name, testgroup) {
1015								if (testgroup === group) {
1016									$("[name='" + v.escapeCssMeta(name) + "']", v.currentForm)
1017										.attr("aria-describedby", error.attr("id"));
1018								}
1019							});
1020						}
1021					}
1022				}
1023				if (!message && this.settings.success) {
1024					error.text("");
1025					if (typeof this.settings.success === "string") {
1026						error.addClass(this.settings.success);
1027					} else {
1028						this.settings.success(error, element);
1029					}
1030				}
1031				this.toShow = this.toShow.add(error);
1032			},
1033
1034			errorsFor: function (element) {
1035				var name = this.escapeCssMeta(this.idOrName(element)),
1036					describer = $(element).attr("aria-describedby"),
1037					selector = "label[for='" + name + "'], label[for='" + name + "'] *";
1038
1039				// 'aria-describedby' should directly reference the error element
1040				if (describer) {
1041					selector = selector + ", #" + this.escapeCssMeta(describer)
1042						.replace(/\s+/g, ", #");
1043				}
1044
1045				return this
1046					.errors()
1047					.filter(selector);
1048			},
1049
1050			// See https://api.jquery.com/category/selectors/, for CSS
1051			// meta-characters that should be escaped in order to be used with JQuery
1052			// as a literal part of a name/id or any selector.
1053			escapeCssMeta: function (string) {
1054				if (string === undefined) {
1055					return "";
1056				}
1057
1058				return string.replace(/([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g, "\\$1");
1059			},
1060
1061			idOrName: function (element) {
1062				return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name);
1063			},
1064
1065			validationTargetFor: function (element) {
1066
1067				// If radio/checkbox, validate first element in group instead
1068				if (this.checkable(element)) {
1069					element = this.findByName(element.name);
1070				}
1071
1072				// Always apply ignore filter
1073				return $(element).not(this.settings.ignore)[0];
1074			},
1075
1076			checkable: function (element) {
1077				return (/radio|checkbox/i).test(element.type);
1078			},
1079
1080			findByName: function (name) {
1081				return $(this.currentForm).find("[name='" + this.escapeCssMeta(name) + "']");
1082			},
1083
1084			getLength: function (value, element) {
1085				switch (element.nodeName.toLowerCase()) {
1086					case "select":
1087						return $("option:selected", element).length;
1088					case "input":
1089						if (this.checkable(element)) {
1090							return this.findByName(element.name).filter(":checked").length;
1091						}
1092				}
1093				return value.length;
1094			},
1095
1096			depend: function (param, element) {
1097				return this.dependTypes[typeof param] ? this.dependTypes[typeof param](param, element) : true;
1098			},
1099
1100			dependTypes: {
1101				"boolean": function (param) {
1102					return param;
1103				},
1104				"string": function (param, element) {
1105					return !!$(param, element.form).length;
1106				},
1107				"function": function (param, element) {
1108					return param(element);
1109				}
1110			},
1111
1112			optional: function (element) {
1113				var val = this.elementValue(element);
1114				return !$.validator.methods.required.call(this, val, element) && "dependency-mismatch";
1115			},
1116
1117			startRequest: function (element) {
1118				if (!this.pending[element.name]) {
1119					this.pendingRequest++;
1120					$(element).addClass(this.settings.pendingClass);
1121					this.pending[element.name] = true;
1122				}
1123			},
1124
1125			stopRequest: function (element, valid) {
1126				this.pendingRequest--;
1127
1128				// Sometimes synchronization fails, make sure pendingRequest is never < 0
1129				if (this.pendingRequest < 0) {
1130					this.pendingRequest = 0;
1131				}
1132				delete this.pending[element.name];
1133				$(element).removeClass(this.settings.pendingClass);
1134				if (valid && this.pendingRequest === 0 && this.formSubmitted && this.form() && this.pendingRequest === 0) {
1135					$(this.currentForm).trigger("submit");
1136
1137					// Remove the hidden input that was used as a replacement for the
1138					// missing submit button. The hidden input is added by `handle()`
1139					// to ensure that the value of the used submit button is passed on
1140					// for scripted submits triggered by this method
1141					if (this.submitButton) {
1142						$("input:hidden[name='" + this.submitButton.name + "']", this.currentForm).remove();
1143					}
1144
1145					this.formSubmitted = false;
1146				} else if (!valid && this.pendingRequest === 0 && this.formSubmitted) {
1147					$(this.currentForm).triggerHandler("invalid-form", [this]);
1148					this.formSubmitted = false;
1149				}
1150			},
1151
1152			previousValue: function (element, method) {
1153				method = typeof method === "string" && method || "remote";
1154
1155				return $.data(element, "previousValue") || $.data(element, "previousValue", {
1156					old: null,
1157					valid: true,
1158					message: this.defaultMessage(element, { method: method })
1159				});
1160			},
1161
1162			// Cleans up all forms and elements, removes validator-specific events
1163			destroy: function () {
1164				this.resetForm();
1165
1166				$(this.currentForm)
1167					.off(".validate")
1168					.removeData("validator")
1169					.find(".validate-equalTo-blur")
1170					.off(".validate-equalTo")
1171					.removeClass("validate-equalTo-blur")
1172					.find(".validate-lessThan-blur")
1173					.off(".validate-lessThan")
1174					.removeClass("validate-lessThan-blur")
1175					.find(".validate-lessThanEqual-blur")
1176					.off(".validate-lessThanEqual")
1177					.removeClass("validate-lessThanEqual-blur")
1178					.find(".validate-greaterThanEqual-blur")
1179					.off(".validate-greaterThanEqual")
1180					.removeClass("validate-greaterThanEqual-blur")
1181					.find(".validate-greaterThan-blur")
1182					.off(".validate-greaterThan")
1183					.removeClass("validate-greaterThan-blur");
1184			}
1185
1186		},
1187
1188		classRuleSettings: {
1189			required: { required: true },
1190			email: { email: true },
1191			phone: { phone: true },
1192			url: { url: true },
1193			date: { date: true },
1194			dateISO: { dateISO: true },
1195			number: { number: true },
1196			digits: { digits: true },
1197			creditcard: { creditcard: true }
1198		},
1199
1200		addClassRules: function (className, rules) {
1201			if (className.constructor === String) {
1202				this.classRuleSettings[className] = rules;
1203			} else {
1204				$.extend(this.classRuleSettings, className);
1205			}
1206		},
1207
1208		classRules: function (element) {
1209			var rules = {},
1210				classes = $(element).attr("class");
1211
1212			if (classes) {
1213				$.each(classes.split(" "), function () {
1214					if (this in $.validator.classRuleSettings) {
1215						$.extend(rules, $.validator.classRuleSettings[this]);
1216					}
1217				});
1218			}
1219			return rules;
1220		},
1221
1222		normalizeAttributeRule: function (rules, type, method, value) {
1223
1224			// Convert the value to a number for number inputs, and for text for backwards compability
1225			// allows type="date" and others to be compared as strings
1226			if (/min|max|step/.test(method) && (type === null || /number|range|text/.test(type))) {
1227				value = Number(value);
1228
1229				// Support Opera Mini, which returns NaN for undefined minlength
1230				if (isNaN(value)) {
1231					value = undefined;
1232				}
1233			}
1234
1235			if (value || value === 0) {
1236				rules[method] = value;
1237			} else if (type === method && type !== "range") {
1238
1239				// Exception: the jquery validate 'range' method
1240				// does not test for the html5 'range' type
1241				rules[type === "date" ? "dateISO" : method] = true;
1242			}
1243		},
1244
1245		attributeRules: function (element) {
1246			var rules = {},
1247				$element = $(element),
1248				type = element.getAttribute("type"),
1249				method, value;
1250
1251			for (method in $.validator.methods) {
1252
1253				// Support for <input required> in both html5 and older browsers
1254				if (method === "required") {
1255					value = element.getAttribute(method);
1256
1257					// Some browsers return an empty string for the required attribute
1258					// and non-HTML5 browsers might have required="" markup
1259					if (value === "") {
1260						value = true;
1261					}
1262
1263					// Force non-HTML5 browsers to return bool
1264					value = !!value;
1265				} else {
1266					value = $element.attr(method);
1267				}
1268
1269				this.normalizeAttributeRule(rules, type, method, value);
1270			}
1271
1272			// 'maxlength' may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs
1273			if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) {
1274				delete rules.maxlength;
1275			}
1276
1277			return rules;
1278		},
1279
1280		dataRules: function (element) {
1281			var rules = {},
1282				$element = $(element),
1283				type = element.getAttribute("type"),
1284				method, value;
1285
1286			for (method in $.validator.methods) {
1287				value = $element.data("rule" + method.charAt(0).toUpperCase() + method.substring(1).toLowerCase());
1288
1289				// Cast empty attributes like `data-rule-required` to `true`
1290				if (value === "") {
1291					value = true;
1292				}
1293
1294				this.normalizeAttributeRule(rules, type, method, value);
1295			}
1296			return rules;
1297		},
1298
1299		staticRules: function (element) {
1300			var rules = {},
1301				validator = $.data(element.form, "validator");
1302
1303			//[蒋冰洋] [2014-09-12] UEditor的单图片上传会触发这里,先暂时这么处理一下
1304			if (!validator) {
1305				return rules;
1306			}
1307
1308			if (validator.settings.rules) {
1309				rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {};
1310			}
1311			return rules;
1312		},
1313
1314		normalizeRules: function (rules, element) {
1315
1316			// Handle dependency check
1317			$.each(rules, function (prop, val) {
1318
1319				// Ignore rule when param is explicitly false, eg. required:false
1320				if (val === false) {
1321					delete rules[prop];
1322					return;
1323				}
1324				if (val.param || val.depends) {
1325					var keepRule = true;
1326					switch (typeof val.depends) {
1327						case "string":
1328							keepRule = !!$(val.depends, element.form).length;
1329							break;
1330						case "function":
1331							keepRule = val.depends.call(element, element);
1332							break;
1333					}
1334					if (keepRule) {
1335						rules[prop] = val.param !== undefined ? val.param : true;
1336					} else {
1337						$.data(element.form, "validator").resetElements($(element));
1338						delete rules[prop];
1339					}
1340				}
1341			});
1342
1343			// Evaluate parameters
1344			$.each(rules, function (rule, parameter) {
1345				rules[rule] = typeof parameter === "function" && rule !== "normalizer" ? parameter(element) : parameter;
1346			});
1347
1348			// Clean number parameters
1349			$.each(["minlength", "maxlength"], function () {
1350				if (rules[this]) {
1351					rules[this] = Number(rules[this]);
1352				}
1353			});
1354			$.each(["rangelength", "range"], function () {
1355				var parts;
1356				if (rules[this]) {
1357					if (Array.isArray(rules[this])) {
1358						rules[this] = [Number(rules[this][0]), Number(rules[this][1])];
1359					} else if (typeof rules[this] === "string") {
1360						parts = rules[this].replace(/[\[\]]/g, "").split(/[\s,]+/);
1361						rules[this] = [Number(parts[0]), Number(parts[1])];
1362					}
1363				}
1364			});
1365
1366			if ($.validator.autoCreateRanges) {
1367
1368				// Auto-create ranges
1369				if (rules.min != null && rules.max != null) {
1370					rules.range = [rules.min, rules.max];
1371					delete rules.min;
1372					delete rules.max;
1373				}
1374				if (rules.minlength != null && rules.maxlength != null) {
1375					rules.rangelength = [rules.minlength, rules.maxlength];
1376					delete rules.minlength;
1377					delete rules.maxlength;
1378				}
1379			}
1380
1381			return rules;
1382		},
1383
1384		// Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
1385		normalizeRule: function (data) {
1386			if (typeof data === "string") {
1387				var transformed = {};
1388				$.each(data.split(/\s/), function () {
1389					transformed[this] = true;
1390				});
1391				data = transformed;
1392			}
1393			return data;
1394		},
1395
1396		// https://jqueryvalidation.org/jQuery.validator.addMethod/
1397		addMethod: function (name, method, message) {
1398			$.validator.methods[name] = method;
1399			$.validator.messages[name] = message !== undefined ? message : $.validator.messages[name];
1400			if (method.length < 3) {
1401				$.validator.addClassRules(name, $.validator.normalizeRule(name));
1402			}
1403		},
1404
1405		// https://jqueryvalidation.org/jQuery.validator.methods/
1406		methods: {
1407
1408			// https://jqueryvalidation.org/required-method/
1409			required: function (value, element, param) {
1410
1411				// Check if dependency is met
1412				if (!this.depend(param, element)) {
1413					return "dependency-mismatch";
1414				}
1415				if (element.nodeName.toLowerCase() === "select") {
1416
1417					// Could be an array for select-multiple or a string, both are fine this way
1418					var val = $(element).val();
1419					return val && val.length > 0;
1420				}
1421				if (this.checkable(element)) {
1422					return this.getLength(value, element) > 0;
1423				}
1424				return value !== undefined && value !== null && value.length > 0;
1425			},
1426
1427			// https://jqueryvalidation.org/email-method/
1428			email: function (value, element) {
1429
1430				// From https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address
1431				// Retrieved 2014-01-14
1432				// If you have a problem with this implementation, report a bug against the above spec
1433				// Or use custom methods to implement your own email validation
1434				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);
1435			},
1436
1437			phone: function (value, element) {
1438				return this.optional(element) || /^(0|86|17951)?(13[0-9]|15[012356789]|17[0-8]|18[0-9]|14[57]|191)[0-9]{8}$/.test(value);
1439			},
1440
1441			// https://jqueryvalidation.org/url-method/
1442			url: function (value, element) {
1443
1444				// Copyright (c) 2010-2013 Diego Perini, MIT licensed
1445				// https://gist.github.com/dperini/729294
1446				// see also https://mathiasbynens.be/demo/url-regex
1447				// modified to allow protocol-relative URLs
1448				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);
1449			},
1450
1451			// https://jqueryvalidation.org/date-method/
1452			date: (function () {
1453				var called = false;
1454
1455				return function (value, element) {
1456					if (!called) {
1457						called = true;
1458						if (this.settings.debug && window.console) {
1459							console.warn(
1460								"The `date` method is deprecated and will be removed in version '2.0.0'.\n" +
1461								"Please don't use it, since it relies on the Date constructor, which\n" +
1462								"behaves very differently across browsers and locales. Use `dateISO`\n" +
1463								"instead or one of the locale specific methods in `localizations/`\n" +
1464								"and `additional-methods.js`."
1465							);
1466						}
1467					}
1468
1469					return this.optional(element) || !/Invalid|NaN/.test(new Date(value).toString());
1470				};
1471			}()),
1472
1473			// https://jqueryvalidation.org/dateISO-method/
1474			dateISO: function (value, element) {
1475				return this.optional(element) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(value);
1476			},
1477
1478			// https://jqueryvalidation.org/number-method/
1479			number: function (value, element) {
1480				return this.optional(element) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value);
1481			},
1482
1483			// https://jqueryvalidation.org/digits-method/
1484			digits: function (value, element) {
1485				return this.optional(element) || /^\d+$/.test(value);
1486			},
1487
1488			// https://jqueryvalidation.org/minlength-method/
1489			minlength: function (value, element, param) {
1490				var length = Array.isArray(value) ? value.length : this.getLength(value, element);
1491				return this.optional(element) || length >= param;
1492			},
1493
1494			// https://jqueryvalidation.org/maxlength-method/
1495			maxlength: function (value, element, param) {
1496				var length = Array.isArray(value) ? value.length : this.getLength(value, element);
1497				return this.optional(element) || length <= param;
1498			},
1499
1500			// https://jqueryvalidation.org/rangelength-method/
1501			rangelength: function (value, element, param) {
1502				var length = Array.isArray(value) ? value.length : this.getLength(value, element);
1503				return this.optional(element) || (length >= param[0] && length <= param[1]);
1504			},
1505
1506			// https://jqueryvalidation.org/min-method/
1507			min: function (value, element, param) {
1508				return this.optional(element) || value >= param;
1509			},
1510
1511			// https://jqueryvalidation.org/max-method/
1512			max: function (value, element, param) {
1513				return this.optional(element) || value <= param;
1514			},
1515
1516			// https://jqueryvalidation.org/range-method/
1517			range: function (value, element, param) {
1518				return this.optional(element) || (value >= param[0] && value <= param[1]);
1519			},
1520
1521			// https://jqueryvalidation.org/step-method/
1522			step: function (value, element, param) {
1523				var type = $(element).attr("type"),
1524					errorMessage = "Step attribute on input type " + type + " is not supported.",
1525					supportedTypes = ["text", "number", "range"],
1526					re = new RegExp("\\b" + type + "\\b"),
1527					notSupported = type && !re.test(supportedTypes.join()),
1528					decimalPlaces = function (num) {
1529						var match = ("" + num).match(/(?:\.(\d+))?$/);
1530						if (!match) {
1531							return 0;
1532						}
1533
1534						// Number of digits right of decimal point.
1535						return match[1] ? match[1].length : 0;
1536					},
1537					toInt = function (num) {
1538						return Math.round(num * Math.pow(10, decimals));
1539					},
1540					valid = true,
1541					decimals;
1542
1543				// Works only for text, number and range input types
1544				// TODO find a way to support input types date, datetime, datetime-local, month, time and week
1545				if (notSupported) {
1546					throw new Error(errorMessage);
1547				}
1548
1549				decimals = decimalPlaces(param);
1550
1551				// Value can't have too many decimals
1552				if (decimalPlaces(value) > decimals || toInt(value) % toInt(param) !== 0) {
1553					valid = false;
1554				}
1555
1556				return this.optional(element) || valid;
1557			},
1558
1559			// https://jqueryvalidation.org/equalTo-method/
1560			equalTo: function (value, element, param) {
1561
1562				// Bind to the blur event of the target in order to revalidate whenever the target field is updated
1563				var target = $(param);
1564				if (this.settings.onfocusout && target.not(".validate-equalTo-blur").length) {
1565					target.addClass("validate-equalTo-blur").on("blur.validate-equalTo", function () {
1566						$(element).valid();
1567					});
1568				}
1569				return value === target.val();
1570			},
1571
1572			// https://jqueryvalidation.org/remote-method/
1573			remote: function (value, element, param, method) {
1574				if (this.optional(element)) {
1575					return "dependency-mismatch";
1576				}
1577
1578				method = typeof method === "string" && method || "remote";
1579
1580				var previous = this.previousValue(element, method),
1581					validator, data, optionDataString;
1582
1583				if (!this.settings.messages[element.name]) {
1584					this.settings.messages[element.name] = {};
1585				}
1586				previous.originalMessage = previous.originalMessage || this.settings.messages[element.name][method];
1587				this.settings.messages[element.name][method] = previous.message;
1588
1589				param = typeof param === "string" && { url: param } || param;
1590				optionDataString = $.param($.extend({ data: value }, param.data));
1591				if (previous.old === optionDataString && !previous.captcha) {
1592					return previous.valid;
1593				}
1594
1595				previous.old = optionDataString;
1596				validator = this;
1597				this.startRequest(element);
1598				data = {};
1599				if ($(element).data("captchaticketid")) {
1600					data["CaptchaTicketId"] = $($(element).data("captchaticketid")).val();
1601					data["CaptchaTicket"] = $($(element).data("captchaticketvalue")).val();
1602				}
1603				data[element.name] = value;
1604				$.ajax($.extend(true, {
1605					mode: "abort",
1606					port: "validate" + element.name,
1607					dataType: "json",
1608					data: data,
1609					context: validator.currentForm,
1610					success: function (response) {
1611						var valid = response === true || response === "true",
1612							errors, message, submitted;
1613						previous.captcha = false;
1614
1615						validator.settings.messages[element.name][method] = previous.originalMessage;
1616						if (valid) {
1617							submitted = validator.formSubmitted;
1618							validator.resetInternals();
1619							validator.toHide = validator.errorsFor(element);
1620							validator.formSubmitted = submitted;
1621							validator.successList.push(element);
1622							validator.invalid[element.name] = false;
1623							validator.showErrors();
1624						} else {
1625							errors = {};
1626							message = response || validator.defaultMessage(element, { method: method, parameters: value });
1627							if (response.state == 'error') {
1628								if (response.type && response.type == "captchaerror") {
1629									// 刷新验证码。
1630									if (window.setCaptchaCallback) {
1631										window.setCaptchaCallback(function () {
1632											$(element).valid();
1633										});
1634									}
1635									var captcha = $($(element).data("captcha"))
1636									if (captcha) {
1637										captcha.click();
1638										previous.captcha = true;
1639										return
1640									}
1641								}
1642
1643								message = response.message;
1644							}
1645							errors[element.name] = previous.message = message;
1646							validator.invalid[element.name] = true;
1647							validator.showErrors(errors);
1648						}
1649						previous.valid = valid;
1650						validator.stopRequest(element, valid);
1651					},
1652					error: function (jqXHR, textStatus, errorThrown) {
1653						previous.valid = false;
1654						if (jqXHR.status === 403) {
1655							let message = jqXHR.responseText;
1656							errors = {};
1657							errors[element.name] = previous.message = message;
1658							validator.invalid[element.name] = true;
1659							validator.showErrors(errors);
1660							validator.stopRequest(element, false);
1661						}
1662					}
1663				}, param));
1664				return "pending";
1665			}
1666		}
1667
1668	});
1669
1670	// Ajax mode: abort
1671	// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
1672	// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
1673
1674	var pendingRequests = {},
1675		ajax;
1676
1677	// Use a prefilter if available (1.5+)
1678	if ($.ajaxPrefilter) {
1679		$.ajaxPrefilter(function (settings, _, xhr) {
1680			var port = settings.port;
1681			if (settings.mode === "abort") {
1682				if (pendingRequests[port]) {
1683					pendingRequests[port].abort();
1684				}
1685				pendingRequests[port] = xhr;
1686			}
1687		});
1688	} else {
1689
1690		// Proxy ajax
1691		ajax = $.ajax;
1692		$.ajax = function (settings) {
1693			var mode = ("mode" in settings ? settings : $.ajaxSettings).mode,
1694				port = ("port" in settings ? settings : $.ajaxSettings).port;
1695			if (mode === "abort") {
1696				if (pendingRequests[port]) {
1697					pendingRequests[port].abort();
1698				}
1699				pendingRequests[port] = ajax.apply(this, arguments);
1700				return pendingRequests[port];
1701			}
1702			return ajax.apply(this, arguments);
1703		};
1704	}
1705	return $;
1706}));

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.