PageSourceSearch

https://www.fascismoeliberta.info/wp-content/plugins/users-ultra/j…ine_ver-0be6bc3fbb20339c9e1f886bf2c380cb.js

js fascismoeliberta.info collected 2026-10-02 12:13:07 UTC 71,638 bytes, 2,094 lines download raw bytes

1/*
2 * Inline Form Validation Engine 2.6.2, jQuery plugin
3 *
4 * Copyright(c) 2010, Cedric Dugas
5 * http://www.position-absolute.com
6 *
7 * 2.0 Rewrite by Olivier Refalo
8 * http://www.crionics.com
9 *
10 * Form validation engine allowing custom regex rules to be added.
11 * Licensed under the MIT License
12 */
13 (function($) {
14
15	"use strict";
16
17	var methods = {
18
19		/**
20		* Kind of the constructor, called before any action
21		* @param {Map} user options
22		*/
23		init: function(options) {
24			var form = this;
25			if (!form.data('jqv') || form.data('jqv') == null ) {
26				options = methods._saveOptions(form, options);
27				// bind all formError elements to close on click
28				$(document).on("click", ".formError", function() {
29					$(this).fadeOut(150, function() {
30						// remove prompt once invisible
31						$(this).parent('.formErrorOuter').remove();
32						$(this).remove();
33					});
34				});
35			}
36			return this;
37		 },
38		/**
39		* Attachs jQuery.validationEngine to form.submit and field.blur events
40		* Takes an optional params: a list of options
41		* ie. jQuery("#formID1").validationEngine('attach', {promptPosition : "centerRight"});
42		*/
43		attach: function(userOptions) {
44
45			var form = this;
46			var options;
47
48			if(userOptions)
49				options = methods._saveOptions(form, userOptions);
50			else
51				options = form.data('jqv');
52
53			options.validateAttribute = (form.find("[data-validation-engine*=validate]").length) ? "data-validation-engine" : "class";
54			if (options.binded) {
55
56				// delegate fields
57				form.on(options.validationEventTrigger, "["+options.validateAttribute+"*=validate]:not([type=checkbox]):not([type=radio]):not(.datepicker)", methods._onFieldEvent);
58				form.on("click", "["+options.validateAttribute+"*=validate][type=checkbox],["+options.validateAttribute+"*=validate][type=radio]", methods._onFieldEvent);
59				form.on(options.validationEventTrigger,"["+options.validateAttribute+"*=validate][class*=datepicker]", {"delay": 300}, methods._onFieldEvent);
60			}
61			if (options.autoPositionUpdate) {
62				$(window).bind("resize", {
63					"noAnimation": true,
64					"formElem": form
65				}, methods.updatePromptsPosition);
66			}
67			form.on("click","a[data-validation-engine-skip], a[class*='validate-skip'], button[data-validation-engine-skip], button[class*='validate-skip'], input[data-validation-engine-skip], input[class*='validate-skip']", methods._submitButtonClick);
68			form.removeData('jqv_submitButton');
69
70			// bind form.submit
71			form.on("submit", methods._onSubmitEvent);
72			return this;
73		},
74		/**
75		* Unregisters any bindings that may point to jQuery.validaitonEngine
76		*/
77		detach: function() {
78
79			var form = this;
80			var options = form.data('jqv');
81
82			// unbind fields
83			form.off(options.validationEventTrigger, "["+options.validateAttribute+"*=validate]:not([type=checkbox]):not([type=radio]):not(.datepicker)", methods._onFieldEvent);
84			form.off("click", "["+options.validateAttribute+"*=validate][type=checkbox],["+options.validateAttribute+"*=validate][type=radio]", methods._onFieldEvent);
85			form.off(options.validationEventTrigger,"["+options.validateAttribute+"*=validate][class*=datepicker]", methods._onFieldEvent);
86
87			// unbind form.submit
88			form.off("submit", methods._onSubmitEvent);
89			form.removeData('jqv');
90
91			form.off("click", "a[data-validation-engine-skip], a[class*='validate-skip'], button[data-validation-engine-skip], button[class*='validate-skip'], input[data-validation-engine-skip], input[class*='validate-skip']", methods._submitButtonClick);
92			form.removeData('jqv_submitButton');
93
94			if (options.autoPositionUpdate)
95				$(window).off("resize", methods.updatePromptsPosition);
96
97			return this;
98		},
99		/**
100		* Validates either a form or a list of fields, shows prompts accordingly.
101		* Note: There is no ajax form validation with this method, only field ajax validation are evaluated
102		*
103		* @return true if the form validates, false if it fails
104		*/
105		validate: function() {
106			var element = $(this);
107			var valid = null;
108
109			if (element.is("form") || element.hasClass("validationEngineContainer")) {
110				if (element.hasClass('validating')) {
111					// form is already validating.
112					// Should abort old validation and start new one. I don't know how to implement it.
113					return false;
114				} else {
115					element.addClass('validating');
116					var options = element.data('jqv');
117					var valid = methods._validateFields(this);
118
119					// If the form doesn't validate, clear the 'validating' class before the user has a chance to submit again
120					setTimeout(function(){
121						element.removeClass('validating');
122					}, 100);
123					if (valid && options.onSuccess) {
124						options.onSuccess();
125					} else if (!valid && options.onFailure) {
126						options.onFailure();
127					}
128				}
129			} else if (element.is('form') || element.hasClass('validationEngineContainer')) {
130				element.removeClass('validating');
131			} else {
132				// field validation
133				var form = element.closest('form, .validationEngineContainer'),
134					options = (form.data('jqv')) ? form.data('jqv') : $.validationEngine.defaults,
135					valid = methods._validateField(element, options);
136			}
137			if(options.onValidationComplete) {
138				// !! ensures that an undefined return is interpreted as return false but allows a onValidationComplete() to possibly return true and have form continue processing
139				return !!options.onValidationComplete(form, valid);
140			}
141			return valid;
142		},
143		/**
144		*  Redraw prompts position, useful when you change the DOM state when validating
145		*/
146		updatePromptsPosition: function(event) {
147
148			if (event && this == window) {
149				var form = event.data.formElem;
150				var noAnimation = event.data.noAnimation;
151			}
152			else
153				var form = $(this.closest('form, .validationEngineContainer'));
154
155			var options = form.data('jqv');
156			// No option, take default one
157			if (!options)
158				options = methods._saveOptions(form, options);
159			form.find('['+options.validateAttribute+'*=validate]').not(":disabled").each(function(){
160				var field = $(this);
161				if (options.prettySelect && field.is(":hidden"))
162				  field = form.find("#" + options.usePrefix + field.attr('id') + options.useSuffix);
163				var prompt = methods._getPrompt(field);
164				var promptText = $(prompt).find(".formErrorContent").html();
165
166				if(prompt)
167					methods._updatePrompt(field, $(prompt), promptText, undefined, false, options, noAnimation);
168			});
169			return this;
170		},
171		/**
172		* Displays a prompt on a element.
173		* Note that the element needs an id!
174		*
175		* @param {String} promptText html text to display type
176		* @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)
177		* @param {String} possible values topLeft, topRight, bottomLeft, centerRight, bottomRight
178		*/
179		showPrompt: function(promptText, type, promptPosition, showArrow) {
180			var form = this.closest('form, .validationEngineContainer');
181			var options = form.data('jqv');
182			// No option, take default one
183			if(!options)
184				options = methods._saveOptions(this, options);
185			if(promptPosition)
186				options.promptPosition=promptPosition;
187			options.showArrow = showArrow==true;
188
189			methods._showPrompt(this, promptText, type, false, options);
190			return this;
191		},
192		/**
193		* Closes form error prompts, CAN be invidual
194		*/
195		hide: function() {
196			 var form = $(this).closest('form, .validationEngineContainer');
197			 var options = form.data('jqv');
198			 // No option, take default one
199			 if (!options)
200				options = methods._saveOptions(form, options);
201			 var fadeDuration = (options && options.fadeDuration) ? options.fadeDuration : 0.3;
202			 var closingtag;
203
204			 if($(this).is("form") || $(this).hasClass("validationEngineContainer")) {
205				 closingtag = "parentForm"+methods._getClassName($(this).attr("id"));
206			 } else {
207				 closingtag = methods._getClassName($(this).attr("id")) +"formError";
208			 }
209			 $('.'+closingtag).fadeTo(fadeDuration, 0.3, function() {
210				 $(this).parent('.formErrorOuter').remove();
211				 $(this).remove();
212			 });
213			 return this;
214		 },
215		 /**
216		 * Closes all error prompts on the page
217		 */
218		 hideAll: function() {
219
220			 var form = this;
221			 var options = form.data('jqv');
222			 var duration = options ? options.fadeDuration:300;
223			 $('.formError').fadeTo(duration, 300, function() {
224				 $(this).parent('.formErrorOuter').remove();
225				 $(this).remove();
226			 });
227			 return this;
228		 },
229		/**
230		* Typically called when user exists a field using tab or a mouse click, triggers a field
231		* validation
232		*/
233		_onFieldEvent: function(event) {
234			var field = $(this);
235			var form = field.closest('form, .validationEngineContainer');
236			var options = form.data('jqv');
237			// No option, take default one
238			if (!options)
239				options = methods._saveOptions(form, options);
240			options.eventTrigger = "field";
241			// validate the current field
242			window.setTimeout(function() {
243				methods._validateField(field, options);
244			}, (event.data) ? event.data.delay : 0);
245
246		},
247		/**
248		* Called when the form is submited, shows prompts accordingly
249		*
250		* @param {jqObject}
251		*            form
252		* @return false if form submission needs to be cancelled
253		*/
254		_onSubmitEvent: function() {
255			var form = $(this);
256			var options = form.data('jqv');
257
258			//check if it is trigger from skipped button
259			if (form.data("jqv_submitButton")){
260				var submitButton = $("#" + form.data("jqv_submitButton"));
261				if (submitButton){
262					if (submitButton.length > 0){
263						if (submitButton.hasClass("validate-skip") || submitButton.attr("data-validation-engine-skip") == "true")
264							return true;
265					}
266				}
267			}
268
269			options.eventTrigger = "submit";
270
271			// validate each field
272			// (- skip field ajax validation, not necessary IF we will perform an ajax form validation)
273			var r=methods._validateFields(form);
274
275			if (r && options.ajaxFormValidation) {
276				methods._validateFormWithAjax(form, options);
277				// cancel form auto-submission - process with async call onAjaxFormComplete
278				return false;
279			}
280
281			if(options.onValidationComplete) {
282				// !! ensures that an undefined return is interpreted as return false but allows a onValidationComplete() to possibly return true and have form continue processing
283				return !!options.onValidationComplete(form, r);
284			}
285			return r;
286		},
287		/**
288		* Return true if the ajax field validations passed so far
289		* @param {Object} options
290		* @return true, is all ajax validation passed so far (remember ajax is async)
291		*/
292		_checkAjaxStatus: function(options) {
293			var status = true;
294			$.each(options.ajaxValidCache, function(key, value) {
295				if (!value) {
296					status = false;
297					// break the each
298					return false;
299				}
300			});
301			return status;
302		},
303
304		/**
305		* Return true if the ajax field is validated
306		* @param {String} fieldid
307		* @param {Object} options
308		* @return true, if validation passed, false if false or doesn't exist
309		*/
310		_checkAjaxFieldStatus: function(fieldid, options) {
311			return options.ajaxValidCache[fieldid] == true;
312		},
313		/**
314		* Validates form fields, shows prompts accordingly
315		*
316		* @param {jqObject}
317		*            form
318		* @param {skipAjaxFieldValidation}
319		*            boolean - when set to true, ajax field validation is skipped, typically used when the submit button is clicked
320		*
321		* @return true if form is valid, false if not, undefined if ajax form validation is done
322		*/
323		_validateFields: function(form) {
324			var options = form.data('jqv');
325
326			// this variable is set to true if an error is found
327			var errorFound = false;
328
329			// Trigger hook, start validation
330			form.trigger("jqv.form.validating");
331			// first, evaluate status of non ajax fields
332			var first_err=null;
333			form.find('['+options.validateAttribute+'*=validate]').not(":disabled").each( function() {
334				var field = $(this);
335				var names = [];
336				if ($.inArray(field.attr('name'), names) < 0) {
337					errorFound |= methods._validateField(field, options);
338					if (errorFound && first_err==null)
339						if (field.is(":hidden") && options.prettySelect)
340							first_err = field = form.find("#" + options.usePrefix + methods._jqSelector(field.attr('id')) + options.useSuffix);
341						else {
342
343							//Check if we need to adjust what element to show the prompt on
344							//and and such scroll to instead
345							if(field.data('jqv-prompt-at') instanceof jQuery ){
346								field = field.data('jqv-prompt-at');
347							} else if(field.data('jqv-prompt-at')) {
348								field = $(field.data('jqv-prompt-at'));
349							}
350							first_err=field;
351						}
352					if (options.doNotShowAllErrosOnSubmit)
353						return false;
354					names.push(field.attr('name'));
355
356					//if option set, stop checking validation rules after one error is found
357					if(options.showOneMessage == true && errorFound){
358						return false;
359					}
360				}
361			});
362
363			// second, check to see if all ajax calls completed ok
364			// errorFound |= !methods._checkAjaxStatus(options);
365
366			// third, check status and scroll the container accordingly
367			form.trigger("jqv.form.result", [errorFound]);
368
369			if (errorFound) {
370				if (options.scroll) {
371					var destination=first_err.offset().top;
372					var fixleft = first_err.offset().left;
373
374					//prompt positioning adjustment support. Usage: positionType:Xshift,Yshift (for ex.: bottomLeft:+20 or bottomLeft:-20,+10)
375					var positionType=options.promptPosition;
376					if (typeof(positionType)=='string' && positionType.indexOf(":")!=-1)
377						positionType=positionType.substring(0,positionType.indexOf(":"));
378
379					if (positionType!="bottomRight" && positionType!="bottomLeft") {
380						var prompt_err= methods._getPrompt(first_err);
381						if (prompt_err) {
382							destination=prompt_err.offset().top;
383						}
384					}
385
386					// Offset the amount the page scrolls by an amount in px to accomodate fixed elements at top of page
387					if (options.scrollOffset) {
388						destination -= options.scrollOffset;
389					}
390
391					// get the position of the first error, there should be at least one, no need to check this
392					//var destination = form.find(".formError:not('.greenPopup'):first").offset().top;
393					if (options.isOverflown) {
394						var overflowDIV = $(options.overflownDIV);
395						if(!overflowDIV.length) return false;
396						var scrollContainerScroll = overflowDIV.scrollTop();
397						var scrollContainerPos = -parseInt(overflowDIV.offset().top);
398
399						destination += scrollContainerScroll + scrollContainerPos - 5;
400						var scrollContainer = $(options.overflownDIV + ":not(:animated)");
401
402						scrollContainer.animate({ scrollTop: destination }, 1100, function(){
403							if(options.focusFirstField) first_err.focus();
404						});
405
406					} else {
407						$("html, body").animate({
408							scrollTop: destination
409						}, 1100, function(){
410							if(options.focusFirstField) first_err.focus();
411						});
412						$("html, body").animate({scrollLeft: fixleft},1100)
413					}
414
415				} else if(options.focusFirstField)
416					first_err.focus();
417				return false;
418			}
419			return true;
420		},
421		/**
422		* This method is called to perform an ajax form validation.
423		* During this process all the (field, value) pairs are sent to the server which returns a list of invalid fields or true
424		*
425		* @param {jqObject} form
426		* @param {Map} options
427		*/
428		_validateFormWithAjax: function(form, options) {
429
430			var data = form.serialize();
431									var type = (options.ajaxFormValidationMethod) ? options.ajaxFormValidationMethod : "GET";
432			var url = (options.ajaxFormValidationURL) ? options.ajaxFormValidationURL : form.attr("action");
433									var dataType = (options.dataType) ? options.dataType : "json";
434			$.ajax({
435				type: type,
436				url: url,
437				cache: false,
438				dataType: dataType,
439				data: data,
440				form: form,
441				methods: methods,
442				options: options,
443				beforeSend: function() {
444					return options.onBeforeAjaxFormValidation(form, options);
445				},
446				error: function(data, transport) {
447					if (options.onFailure) {
448						options.onFailure(data, transport);
449					} else {
450						methods._ajaxError(data, transport);
451					}
452				},
453				success: function(json) {
454					if ((dataType == "json") && (json !== true)) {
455						// getting to this case doesn't necessary means that the form is invalid
456						// the server may return green or closing prompt actions
457						// this flag helps figuring it out
458						var errorInForm=false;
459						for (var i = 0; i < json.length; i++) {
460							var value = json[i];
461
462							var errorFieldId = value[0];
463							var errorField = $($("#" + errorFieldId)[0]);
464
465							// make sure we found the element
466							if (errorField.length == 1) {
467
468								// promptText or selector
469								var msg = value[2];
470								// if the field is valid
471								if (value[1] == true) {
472
473									if (msg == ""  || !msg){
474										// if for some reason, status==true and error="", just close the prompt
475										methods._closePrompt(errorField);
476									} else {
477										// the field is valid, but we are displaying a green prompt
478										if (options.allrules[msg]) {
479											var txt = options.allrules[msg].alertTextOk;
480											if (txt)
481												msg = txt;
482										}
483										if (options.showPrompts) methods._showPrompt(errorField, msg, "pass", false, options, true);
484									}
485								} else {
486									// the field is invalid, show the red error prompt
487									errorInForm|=true;
488									if (options.allrules[msg]) {
489										var txt = options.allrules[msg].alertText;
490										if (txt)
491											msg = txt;
492									}
493									if(options.showPrompts) methods._showPrompt(errorField, msg, "", false, options, true);
494								}
495							}
496						}
497						options.onAjaxFormComplete(!errorInForm, form, json, options);
498					} else
499						options.onAjaxFormComplete(true, form, json, options);
500
501				}
502			});
503
504		},
505		/**
506		* Validates field, shows prompts accordingly
507		*
508		* @param {jqObject}
509		*            field
510		* @param {Array[String]}
511		*            field's validation rules
512		* @param {Map}
513		*            user options
514		* @return false if field is valid (It is inversed for *fields*, it return false on validate and true on errors.)
515		*/
516		_validateField: function(field, options, skipAjaxValidation) {
517			if (!field.attr("id")) {
518				field.attr("id", "form-validation-field-" + $.validationEngine.fieldIdCounter);
519				++$.validationEngine.fieldIdCounter;
520			}
521
522           if (!options.validateNonVisibleFields && (field.is(":hidden") && !options.prettySelect || field.parent().is(":hidden")))
523				return false;
524
525			var rulesParsing = field.attr(options.validateAttribute);
526			var getRules = /validate\[(.*)\]/.exec(rulesParsing);
527
528			if (!getRules)
529				return false;
530			var str = getRules[1];
531			var rules = str.split(/\[|,|\]/);
532
533			// true if we ran the ajax validation, tells the logic to stop messing with prompts
534			var isAjaxValidator = false;
535			var fieldName = field.attr("name");
536			var promptText = "";
537			var promptType = "";
538			var required = false;
539			var limitErrors = false;
540			options.isError = false;
541			options.showArrow = true;
542
543			// If the programmer wants to limit the amount of error messages per field,
544			if (options.maxErrorsPerField > 0) {
545				limitErrors = true;
546			}
547
548			var form = $(field.closest("form, .validationEngineContainer"));
549			// Fix for adding spaces in the rules
550			for (var i = 0; i < rules.length; i++) {
551				rules[i] = rules[i].replace(" ", "");
552				// Remove any parsing errors
553				if (rules[i] === '') {
554					delete rules[i];
555				}
556			}
557
558			for (var i = 0, field_errors = 0; i < rules.length; i++) {
559
560				// If we are limiting errors, and have hit the max, break
561				if (limitErrors && field_errors >= options.maxErrorsPerField) {
562					// If we haven't hit a required yet, check to see if there is one in the validation rules for this
563					// field and that it's index is greater or equal to our current index
564					if (!required) {
565						var have_required = $.inArray('required', rules);
566						required = (have_required != -1 &&  have_required >= i);
567					}
568					break;
569				}
570
571
572				var errorMsg = undefined;
573				switch (rules[i]) {
574
575					case "required":
576						required = true;
577						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._required);
578						break;
579					case "custom":
580						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._custom);
581						break;
582					case "groupRequired":
583						// Check is its the first of group, if not, reload validation with first field
584						// AND continue normal validation on present field
585						var classGroup = "["+options.validateAttribute+"*=" +rules[i + 1] +"]";
586						var firstOfGroup = form.find(classGroup).eq(0);
587						if(firstOfGroup[0] != field[0]){
588
589							methods._validateField(firstOfGroup, options, skipAjaxValidation);
590							options.showArrow = true;
591
592						}
593						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._groupRequired);
594						if(errorMsg)  required = true;
595						options.showArrow = false;
596						break;
597					case "ajax":
598						// AJAX defaults to returning it's loading message
599						errorMsg = methods._ajax(field, rules, i, options);
600						if (errorMsg) {
601							promptType = "load";
602						}
603						break;
604					case "minSize":
605						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._minSize);
606						break;
607					case "maxSize":
608						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._maxSize);
609						break;
610					case "min":
611						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._min);
612						break;
613					case "max":
614						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._max);
615						break;
616					case "past":
617						errorMsg = methods._getErrorMessage(form, field,rules[i], rules, i, options, methods._past);
618						break;
619					case "future":
620						errorMsg = methods._getErrorMessage(form, field,rules[i], rules, i, options, methods._future);
621						break;
622					case "dateRange":
623						var classGroup = "["+options.validateAttribute+"*=" + rules[i + 1] + "]";
624						options.firstOfGroup = form.find(classGroup).eq(0);
625						options.secondOfGroup = form.find(classGroup).eq(1);
626
627						//if one entry out of the pair has value then proceed to run through validation
628						if (options.firstOfGroup[0].value || options.secondOfGroup[0].value) {
629							errorMsg = methods._getErrorMessage(form, field,rules[i], rules, i, options, methods._dateRange);
630						}
631						if (errorMsg) required = true;
632						options.showArrow = false;
633						break;
634
635					case "dateTimeRange":
636						var classGroup = "["+options.validateAttribute+"*=" + rules[i + 1] + "]";
637						options.firstOfGroup = form.find(classGroup).eq(0);
638						options.secondOfGroup = form.find(classGroup).eq(1);
639
640						//if one entry out of the pair has value then proceed to run through validation
641						if (options.firstOfGroup[0].value || options.secondOfGroup[0].value) {
642							errorMsg = methods._getErrorMessage(form, field,rules[i], rules, i, options, methods._dateTimeRange);
643						}
644						if (errorMsg) required = true;
645						options.showArrow = false;
646						break;
647					case "maxCheckbox":
648						field = $(form.find("input[name='" + fieldName + "']"));
649						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._maxCheckbox);
650						break;
651					case "minCheckbox":
652						field = $(form.find("input[name='" + fieldName + "']"));
653						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._minCheckbox);
654						break;
655					case "equals":
656						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._equals);
657						break;
658					case "funcCall":
659						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._funcCall);
660						break;
661					case "creditCard":
662						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._creditCard);
663						break;
664					case "condRequired":
665						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._condRequired);
666						if (errorMsg !== undefined) {
667							required = true;
668						}
669						break;
670					case "funcCallRequired":
671						errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._funcCallRequired);
672						if (errorMsg !== undefined) {
673							required = true;
674						}
675						break;
676
677					default:
678				}
679
680				var end_validation = false;
681
682				// If we were passed back an message object, check what the status was to determine what to do
683				if (typeof errorMsg == "object") {
684					switch (errorMsg.status) {
685						case "_break":
686							end_validation = true;
687							break;
688						// If we have an error message, set errorMsg to the error message
689						case "_error":
690							errorMsg = errorMsg.message;
691							break;
692						// If we want to throw an error, but not show a prompt, return early with true
693						case "_error_no_prompt":
694							return true;
695							break;
696						// Anything else we continue on
697						default:
698							break;
699					}
700				}
701				
702				//funcCallRequired, first in rules, and has error, skip anything else
703				if( i==0 && str.indexOf('funcCallRequired')==0 && errorMsg !== undefined ){
704					promptText += errorMsg + "<br/>";
705					options.isError=true;
706					field_errors++;
707					end_validation=true;
708				}
709
710				// If it has been specified that validation should end now, break
711				if (end_validation) {
712					break;
713				}
714
715				// If we have a string, that means that we have an error, so add it to the error message.
716				if (typeof errorMsg == 'string') {
717					promptText += errorMsg + "<br/>";
718					options.isError = true;
719					field_errors++;
720				}
721			}
722			// If the rules required is not added, an empty field is not validated
723			//the 3rd condition is added so that even empty password fields should be equal
724			//otherwise if one is filled and another left empty, the "equal" condition would fail
725			//which does not make any sense
726			if(!required && !(field.val()) && field.val().length < 1 && $.inArray('equals', rules) < 0) options.isError = false;
727
728			// Hack for radio/checkbox group button, the validation go into the
729			// first radio/checkbox of the group
730			var fieldType = field.prop("type");
731			var positionType=field.data("promptPosition") || options.promptPosition;
732
733			if ((fieldType == "radio" || fieldType == "checkbox") && form.find("input[name='" + fieldName + "']").size() > 1) {
734				if(positionType === 'inline') {
735					field = $(form.find("input[name='" + fieldName + "'][type!=hidden]:last"));
736				} else {
737				field = $(form.find("input[name='" + fieldName + "'][type!=hidden]:first"));
738				}
739				options.showArrow = options.showArrowOnRadioAndCheckbox;
740			}
741
742			if(field.is(":hidden") && options.prettySelect) {
743				field = form.find("#" + options.usePrefix + methods._jqSelector(field.attr('id')) + options.useSuffix);
744			}
745
746			if (options.isError && options.showPrompts){
747				methods._showPrompt(field, promptText, promptType, false, options);
748			}else{
749				if (!isAjaxValidator) methods._closePrompt(field);
750			}
751
752			if (!isAjaxValidator) {
753				field.trigger("jqv.field.result", [field, options.isError, promptText]);
754			}
755
756			/* Record error */
757			var errindex = $.inArray(field[0], options.InvalidFields);
758			if (errindex == -1) {
759				if (options.isError)
760				options.InvalidFields.push(field[0]);
761			} else if (!options.isError) {
762				options.InvalidFields.splice(errindex, 1);
763			}
764
765			methods._handleStatusCssClasses(field, options);
766
767			/* run callback function for each field */
768			if (options.isError && options.onFieldFailure)
769				options.onFieldFailure(field);
770
771			if (!options.isError && options.onFieldSuccess)
772				options.onFieldSuccess(field);
773
774			return options.isError;
775		},
776		/**
777		* Handling css classes of fields indicating result of validation
778		*
779		* @param {jqObject}
780		*            field
781		* @param {Array[String]}
782		*            field's validation rules
783		* @private
784		*/
785		_handleStatusCssClasses: function(field, options) {
786			/* remove all classes */
787			if(options.addSuccessCssClassToField)
788				field.removeClass(options.addSuccessCssClassToField);
789
790			if(options.addFailureCssClassToField)
791				field.removeClass(options.addFailureCssClassToField);
792
793			/* Add classes */
794			if (options.addSuccessCssClassToField && !options.isError)
795				field.addClass(options.addSuccessCssClassToField);
796
797			if (options.addFailureCssClassToField && options.isError)
798				field.addClass(options.addFailureCssClassToField);
799		},
800
801		 /********************
802		  * _getErrorMessage
803		  *
804		  * @param form
805		  * @param field
806		  * @param rule
807		  * @param rules
808		  * @param i
809		  * @param options
810		  * @param originalValidationMethod
811		  * @return {*}
812		  * @private
813		  */
814		 _getErrorMessage:function (form, field, rule, rules, i, options, originalValidationMethod) {
815			 // If we are using the custon validation type, build the index for the rule.
816			 // Otherwise if we are doing a function call, make the call and return the object
817			 // that is passed back.
818	 		 var rule_index = jQuery.inArray(rule, rules);
819			 if (rule === "custom" || rule === "funcCall" || rule === "funcCallRequired") {
820				 var custom_validation_type = rules[rule_index + 1];
821				 rule = rule + "[" + custom_validation_type + "]";
822				 // Delete the rule from the rules array so that it doesn't try to call the
823			    // same rule over again
824			    delete(rules[rule_index]);
825			 }
826			 // Change the rule to the composite rule, if it was different from the original
827			 var alteredRule = rule;
828
829
830			 var element_classes = (field.attr("data-validation-engine")) ? field.attr("data-validation-engine") : field.attr("class");
831			 var element_classes_array = element_classes.split(" ");
832
833			 // Call the original validation method. If we are dealing with dates or checkboxes, also pass the form
834			 var errorMsg;
835			 if (rule == "future" || rule == "past"  || rule == "maxCheckbox" || rule == "minCheckbox") {
836				 errorMsg = originalValidationMethod(form, field, rules, i, options);
837			 } else {
838				 errorMsg = originalValidationMethod(field, rules, i, options);
839			 }
840
841			 // If the original validation method returned an error and we have a custom error message,
842			 // return the custom message instead. Otherwise return the original error message.
843			 if (errorMsg != undefined) {
844				 var custom_message = methods._getCustomErrorMessage($(field), element_classes_array, alteredRule, options);
845				 if (custom_message) errorMsg = custom_message;
846			 }
847			 return errorMsg;
848
849		 },
850		 _getCustomErrorMessage:function (field, classes, rule, options) {
851			var custom_message = false;
852			var validityProp = /^custom\[.*\]$/.test(rule) ? methods._validityProp["custom"] : methods._validityProp[rule];
853			 // If there is a validityProp for this rule, check to see if the field has an attribute for it
854			if (validityProp != undefined) {
855				custom_message = field.attr("data-errormessage-"+validityProp);
856				// If there was an error message for it, return the message
857				if (custom_message != undefined)
858					return custom_message;
859			}
860			custom_message = field.attr("data-errormessage");
861			 // If there is an inline custom error message, return it
862			if (custom_message != undefined)
863				return custom_message;
864			var id = '#' + field.attr("id");
865			// If we have custom messages for the element's id, get the message for the rule from the id.
866			// Otherwise, if we have custom messages for the element's classes, use the first class message we find instead.
867			if (typeof options.custom_error_messages[id] != "undefined" &&
868				typeof options.custom_error_messages[id][rule] != "undefined" ) {
869						  custom_message = options.custom_error_messages[id][rule]['message'];
870			} else if (classes.length > 0) {
871				for (var i = 0; i < classes.length && classes.length > 0; i++) {
872					 var element_class = "." + classes[i];
873					if (typeof options.custom_error_messages[element_class] != "undefined" &&
874						typeof options.custom_error_messages[element_class][rule] != "undefined") {
875							custom_message = options.custom_error_messages[element_class][rule]['message'];
876							break;
877					}
878				}
879			}
880			if (!custom_message &&
881				typeof options.custom_error_messages[rule] != "undefined" &&
882				typeof options.custom_error_messages[rule]['message'] != "undefined"){
883					 custom_message = options.custom_error_messages[rule]['message'];
884			 }
885			 return custom_message;
886		 },
887		 _validityProp: {
888			 "required": "value-missing",
889			 "custom": "custom-error",
890			 "groupRequired": "value-missing",
891			 "ajax": "custom-error",
892			 "minSize": "range-underflow",
893			 "maxSize": "range-overflow",
894			 "min": "range-underflow",
895			 "max": "range-overflow",
896			 "past": "type-mismatch",
897			 "future": "type-mismatch",
898			 "dateRange": "type-mismatch",
899			 "dateTimeRange": "type-mismatch",
900			 "maxCheckbox": "range-overflow",
901			 "minCheckbox": "range-underflow",
902			 "equals": "pattern-mismatch",
903			 "funcCall": "custom-error",
904			 "funcCallRequired": "custom-error",
905			 "creditCard": "pattern-mismatch",
906			 "condRequired": "value-missing"
907		 },
908		/**
909		* Required validation
910		*
911		* @param {jqObject} field
912		* @param {Array[String]} rules
913		* @param {int} i rules index
914		* @param {Map}
915		*            user options
916		* @param {bool} condRequired flag when method is used for internal purpose in condRequired check
917		* @return an error string if validation failed
918		*/
919		_required: function(field, rules, i, options, condRequired) {
920			switch (field.prop("type")) {
921				case "radio":
922				case "checkbox":
923					// new validation style to only check dependent field
924					if (condRequired) {
925						if (!field.prop('checked')) {
926							return options.allrules[rules[i]].alertTextCheckboxMultiple;
927						}
928						break;
929					}
930					// old validation style
931					var form = field.closest("form, .validationEngineContainer");
932					var name = field.attr("name");
933					if (form.find("input[name='" + name + "']:checked").size() == 0) {
934						if (form.find("input[name='" + name + "']:visible").size() == 1)
935							return options.allrules[rules[i]].alertTextCheckboxe;
936						else
937							return options.allrules[rules[i]].alertTextCheckboxMultiple;
938					}
939					break;
940				case "text":
941				case "password":
942				case "textarea":
943				case "file":
944				case "select-one":
945				case "select-multiple":
946				default:
947					var field_val      = $.trim( field.val()                               );
948					var dv_placeholder = $.trim( field.attr("data-validation-placeholder") );
949					var placeholder    = $.trim( field.attr("placeholder")                 );
950					if (
951						   ( !field_val                                    )
952						|| ( dv_placeholder && field_val == dv_placeholder )
953						|| ( placeholder    && field_val == placeholder    )
954					) {
955						return options.allrules[rules[i]].alertText;
956					}
957					break;
958			}
959		},
960		/**
961		* Validate that 1 from the group field is required
962		*
963		* @param {jqObject} field
964		* @param {Array[String]} rules
965		* @param {int} i rules index
966		* @param {Map}
967		*            user options
968		* @return an error string if validation failed
969		*/
970		_groupRequired: function(field, rules, i, options) {
971			var classGroup = "["+options.validateAttribute+"*=" +rules[i + 1] +"]";
972			var isValid = false;
973			// Check all fields from the group
974			field.closest("form, .validationEngineContainer").find(classGroup).each(function(){
975				if(!methods._required($(this), rules, i, options)){
976					isValid = true;
977					return false;
978				}
979			});
980
981			if(!isValid) {
982		  return options.allrules[rules[i]].alertText;
983		}
984		},
985		/**
986		* Validate rules
987		*
988		* @param {jqObject} field
989		* @param {Array[String]} rules
990		* @param {int} i rules index
991		* @param {Map}
992		*            user options
993		* @return an error string if validation failed
994		*/
995		_custom: function(field, rules, i, options) {
996			var customRule = rules[i + 1];
997			var rule = options.allrules[customRule];
998			var fn;
999			if(!rule) {
1000				alert("jqv:custom rule not found - "+customRule);
1001				return;
1002			}
1003
1004			if(rule["regex"]) {
1005				 var ex=rule.regex;
1006					if(!ex) {
1007						alert("jqv:custom regex not found - "+customRule);
1008						return;
1009					}
1010					var pattern = new RegExp(ex);
1011
1012					if (!pattern.test(field.val())) return options.allrules[customRule].alertText;
1013
1014			} else if(rule["func"]) {
1015				fn = rule["func"];
1016
1017				if (typeof(fn) !== "function") {
1018					alert("jqv:custom parameter 'function' is no function - "+customRule);
1019						return;
1020				}
1021
1022				if (!fn(field, rules, i, options))
1023					return options.allrules[customRule].alertText;
1024			} else {
1025				alert("jqv:custom type not allowed "+customRule);
1026					return;
1027			}
1028		},
1029		/**
1030		* Validate custom function outside of the engine scope
1031		*
1032		* @param {jqObject} field
1033		* @param {Array[String]} rules
1034		* @param {int} i rules index
1035		* @param {Map}
1036		*            user options
1037		* @return an error string if validation failed
1038		*/
1039		_funcCall: function(field, rules, i, options) {
1040			var functionName = rules[i + 1];
1041			var fn;
1042			if(functionName.indexOf('.') >-1)
1043			{
1044				var namespaces = functionName.split('.');
1045				var scope = window;
1046				while(namespaces.length)
1047				{
1048					scope = scope[namespaces.shift()];
1049				}
1050				fn = scope;
1051			}
1052			else
1053				fn = window[functionName] || options.customFunctions[functionName];
1054			if (typeof(fn) == 'function')
1055				return fn(field, rules, i, options);
1056
1057		},
1058		_funcCallRequired: function(field, rules, i, options) {
1059			return methods._funcCall(field,rules,i,options);
1060		},
1061		/**
1062		* Field match
1063		*
1064		* @param {jqObject} field
1065		* @param {Array[String]} rules
1066		* @param {int} i rules index
1067		* @param {Map}
1068		*            user options
1069		* @return an error string if validation failed
1070		*/
1071		_equals: function(field, rules, i, options) {
1072			var equalsField = rules[i + 1];
1073
1074			if (field.val() != $("#" + equalsField).val())
1075				return options.allrules.equals.alertText;
1076		},
1077		/**
1078		* Check the maximum size (in characters)
1079		*
1080		* @param {jqObject} field
1081		* @param {Array[String]} rules
1082		* @param {int} i rules index
1083		* @param {Map}
1084		*            user options
1085		* @return an error string if validation failed
1086		*/
1087		_maxSize: function(field, rules, i, options) {
1088			var max = rules[i + 1];
1089			var len = field.val().length;
1090
1091			if (len > max) {
1092				var rule = options.allrules.maxSize;
1093				return rule.alertText + max + rule.alertText2;
1094			}
1095		},
1096		/**
1097		* Check the minimum size (in characters)
1098		*
1099		* @param {jqObject} field
1100		* @param {Array[String]} rules
1101		* @param {int} i rules index
1102		* @param {Map}
1103		*            user options
1104		* @return an error string if validation failed
1105		*/
1106		_minSize: function(field, rules, i, options) {
1107			var min = rules[i + 1];
1108			var len = field.val().length;
1109
1110			if (len < min) {
1111				var rule = options.allrules.minSize;
1112				return rule.alertText + min + rule.alertText2;
1113			}
1114		},
1115		/**
1116		* Check number minimum value
1117		*
1118		* @param {jqObject} field
1119		* @param {Array[String]} rules
1120		* @param {int} i rules index
1121		* @param {Map}
1122		*            user options
1123		* @return an error string if validation failed
1124		*/
1125		_min: function(field, rules, i, options) {
1126			var min = parseFloat(rules[i + 1]);
1127			var len = parseFloat(field.val());
1128
1129			if (len < min) {
1130				var rule = options.allrules.min;
1131				if (rule.alertText2) return rule.alertText + min + rule.alertText2;
1132				return rule.alertText + min;
1133			}
1134		},
1135		/**
1136		* Check number maximum value
1137		*
1138		* @param {jqObject} field
1139		* @param {Array[String]} rules
1140		* @param {int} i rules index
1141		* @param {Map}
1142		*            user options
1143		* @return an error string if validation failed
1144		*/
1145		_max: function(field, rules, i, options) {
1146			var max = parseFloat(rules[i + 1]);
1147			var len = parseFloat(field.val());
1148
1149			if (len >max ) {
1150				var rule = options.allrules.max;
1151				if (rule.alertText2) return rule.alertText + max + rule.alertText2;
1152				//orefalo: to review, also do the translations
1153				return rule.alertText + max;
1154			}
1155		},
1156		/**
1157		* Checks date is in the past
1158		*
1159		* @param {jqObject} field
1160		* @param {Array[String]} rules
1161		* @param {int} i rules index
1162		* @param {Map}
1163		*            user options
1164		* @return an error string if validation failed
1165		*/
1166		_past: function(form, field, rules, i, options) {
1167
1168			var p=rules[i + 1];
1169			var fieldAlt = $(form.find("*[name='" + p.replace(/^#+/, '') + "']"));
1170			var pdate;
1171
1172			if (p.toLowerCase() == "now") {
1173				pdate = new Date();
1174			} else if (undefined != fieldAlt.val()) {
1175				if (fieldAlt.is(":disabled"))
1176					return;
1177				pdate = methods._parseDate(fieldAlt.val());
1178			} else {
1179				pdate = methods._parseDate(p);
1180			}
1181			var vdate = methods._parseDate(field.val());
1182
1183			if (vdate > pdate ) {
1184				var rule = options.allrules.past;
1185				if (rule.alertText2) return rule.alertText + methods._dateToString(pdate) + rule.alertText2;
1186				return rule.alertText + methods._dateToString(pdate);
1187			}
1188		},
1189		/**
1190		* Checks date is in the future
1191		*
1192		* @param {jqObject} field
1193		* @param {Array[String]} rules
1194		* @param {int} i rules index
1195		* @param {Map}
1196		*            user options
1197		* @return an error string if validation failed
1198		*/
1199		_future: function(form, field, rules, i, options) {
1200
1201			var p=rules[i + 1];
1202			var fieldAlt = $(form.find("*[name='" + p.replace(/^#+/, '') + "']"));
1203			var pdate;
1204
1205			if (p.toLowerCase() == "now") {
1206				pdate = new Date();
1207			} else if (undefined != fieldAlt.val()) {
1208				if (fieldAlt.is(":disabled"))
1209					return;
1210				pdate = methods._parseDate(fieldAlt.val());
1211			} else {
1212				pdate = methods._parseDate(p);
1213			}
1214			var vdate = methods._parseDate(field.val());
1215
1216			if (vdate < pdate ) {
1217				var rule = options.allrules.future;
1218				if (rule.alertText2)
1219					return rule.alertText + methods._dateToString(pdate) + rule.alertText2;
1220				return rule.alertText + methods._dateToString(pdate);
1221			}
1222		},
1223		/**
1224		* Checks if valid date
1225		*
1226		* @param {string} date string
1227		* @return a bool based on determination of valid date
1228		*/
1229		_isDate: function (value) {
1230			var dateRegEx = new RegExp(/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$|^(?:(?:(?
1230:0?[13578]|1[02])(\/|-)31)|(?:(?:0?[1,3-9]|1[0-2])(\/|-)(?:29|30)))(\/|-)(?:[1-9]\d\d\d|\d[1-9]\d\d|\d\d[1-9]\d|\d\d\d[1-9])$|^(?:(?:0?[1-9]|1[0-2])(\/|-)(?:0?[1-9]|1\d|2[0-8]))(\/|-)(?:[1-9]\d\d\d|\d[1-9]\d\d|\d\d[1-9]\d|\d\d\d[1-9])$|^(0?2(\/|-)29)(\/|-)(?:(?:0[48]00|[13579][26]00|[2468][048]00)|(?:\d\d)?(?:0[48]|[2468][048]|[13579][26]))$/);
1231			return dateRegEx.test(value);
1232		},
1233		/**
1234		* Checks if valid date time
1235		*
1236		* @param {string} date string
1237		* @return a bool based on determination of valid date time
1238		*/
1239		_isDateTime: function (value){
1240			var dateTimeRegEx = new RegExp(/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])\s+(1[012]|0?[1-9]){1}:(0?[1-5]|[0-6][0-9]){1}:(0?[0-6]|[0-6][0-9]){1}\s+(am|pm|AM|PM){1}$|^(?:(?:(?:0?[13578]|1[02])(\/|-)31)|(?:(?:0?[1,3-9]|1[0-2])(\/|-)(?:29|30)))(\/|-)(?:[1-9]\d\d\d|\d[1-9]\d\d|\d\d[1-9]\d|\d\d\d[1-9])$|^((1[012]|0?[1-9]){1}\/(0?[1-9]|[12][0-9]|3[01]){1}\/\d{2,4}\s+(1[012]|0?[1-9]){1}:(0?[1-5]|[0-6][0-9]){1}:(0?[0-6]|[0-6][0-9]){1}\s+(am|pm|AM|PM){1})$/);
1241			return dateTimeRegEx.test(value);
1242		},
1243		//Checks if the start date is before the end date
1244		//returns true if end is later than start
1245		_dateCompare: function (start, end) {
1246			return (new Date(start.toString()) < new Date(end.toString()));
1247		},
1248		/**
1249		* Checks date range
1250		*
1251		* @param {jqObject} first field name
1252		* @param {jqObject} second field name
1253		* @return an error string if validation failed
1254		*/
1255		_dateRange: function (field, rules, i, options) {
1256			//are not both populated
1257			if ((!options.firstOfGroup[0].value && options.secondOfGroup[0].value) || (options.firstOfGroup[0].value && !options.secondOfGroup[0].value)) {
1258				return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
1259			}
1260
1261			//are not both dates
1262			if (!methods._isDate(options.firstOfGroup[0].value) || !methods._isDate(options.secondOfGroup[0].value)) {
1263				return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
1264			}
1265
1266			//are both dates but range is off
1267			if (!methods._dateCompare(options.firstOfGroup[0].value, options.secondOfGroup[0].value)) {
1268				return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
1269			}
1270		},
1271		/**
1272		* Checks date time range
1273		*
1274		* @param {jqObject} first field name
1275		* @param {jqObject} second field name
1276		* @return an error string if validation failed
1277		*/
1278		_dateTimeRange: function (field, rules, i, options) {
1279			//are not both populated
1280			if ((!options.firstOfGroup[0].value && options.secondOfGroup[0].value) || (options.firstOfGroup[0].value && !options.secondOfGroup[0].value)) {
1281				return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
1282			}
1283			//are not both dates
1284			if (!methods._isDateTime(options.firstOfGroup[0].value) || !methods._isDateTime(options.secondOfGroup[0].value)) {
1285				return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
1286			}
1287			//are both dates but range is off
1288			if (!methods._dateCompare(options.firstOfGroup[0].value, options.secondOfGroup[0].value)) {
1289				return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
1290			}
1291		},
1292		/**
1293		* Max number of checkbox selected
1294		*
1295		* @param {jqObject} field
1296		* @param {Array[String]} rules
1297		* @param {int} i rules index
1298		* @param {Map}
1299		*            user options
1300		* @return an error string if validation failed
1301		*/
1302		_maxCheckbox: function(form, field, rules, i, options) {
1303
1304			var nbCheck = rules[i + 1];
1305			var groupname = field.attr("name");
1306			var groupSize = form.find("input[name='" + groupname + "']:checked").size();
1307			if (groupSize > nbCheck) {
1308				options.showArrow = false;
1309				if (options.allrules.maxCheckbox.alertText2)
1310					 return options.allrules.maxCheckbox.alertText + " " + nbCheck + " " + options.allrules.maxCheckbox.alertText2;
1311				return options.allrules.maxCheckbox.alertText;
1312			}
1313		},
1314		/**
1315		* Min number of checkbox selected
1316		*
1317		* @param {jqObject} field
1318		* @param {Array[String]} rules
1319		* @param {int} i rules index
1320		* @param {Map}
1321		*            user options
1322		* @return an error string if validation failed
1323		*/
1324		_minCheckbox: function(form, field, rules, i, options) {
1325
1326			var nbCheck = rules[i + 1];
1327			var groupname = field.attr("name");
1328			var groupSize = form.find("input[name='" + groupname + "']:checked").size();
1329			if (groupSize < nbCheck) {
1330				options.showArrow = false;
1331				return options.allrules.minCheckbox.alertText + " " + nbCheck + " " + options.allrules.minCheckbox.alertText2;
1332			}
1333		},
1334		/**
1335		* Checks that it is a valid credit card number according to the
1336		* Luhn checksum algorithm.
1337		*
1338		* @param {jqObject} field
1339		* @param {Array[String]} rules
1340		* @param {int} i rules index
1341		* @param {Map}
1342		*            user options
1343		* @return an error string if validation failed
1344		*/
1345		_creditCard: function(field, rules, i, options) {
1346			//spaces and dashes may be valid characters, but must be stripped to calculate the checksum.
1347			var valid = false, cardNumber = field.val().replace(/ +/g, '').replace(/-+/g, '');
1348
1349			var numDigits = cardNumber.length;
1350			if (numDigits >= 14 && numDigits <= 16 && parseInt(cardNumber) > 0) {
1351
1352				var sum = 0, i = numDigits - 1, pos = 1, digit, luhn = new String();
1353				do {
1354					digit = parseInt(cardNumber.charAt(i));
1355					luhn += (pos++ % 2 == 0) ? digit * 2 : digit;
1356				} while (--i >= 0)
1357
1358				for (i = 0; i < luhn.length; i++) {
1359					sum += parseInt(luhn.charAt(i));
1360				}
1361				valid = sum % 10 == 0;
1362			}
1363			if (!valid) return options.allrules.creditCard.alertText;
1364		},
1365		/**
1366		* Ajax field validation
1367		*
1368		* @param {jqObject} field
1369		* @param {Array[String]} rules
1370		* @param {int} i rules index
1371		* @param {Map}
1372		*            user options
1373		* @return nothing! the ajax validator handles the prompts itself
1374		*/
1375		 _ajax: function(field, rules, i, options) {
1376
1377			 var errorSelector = rules[i + 1];
1378			 var rule = options.allrules[errorSelector];
1379			 var extraData = rule.extraData;
1380			 var extraDataDynamic = rule.extraDataDynamic;
1381			 var data = {
1382				"fieldId" : field.attr("id"),
1383				"fieldValue" : field.val()
1384			 };
1385
1386			 if (typeof extraData === "object") {
1387				$.extend(data, extraData);
1388			 } else if (typeof extraData === "string") {
1389				var tempData = extraData.split("&");
1390				for(var i = 0; i < tempData.length; i++) {
1391					var values = tempData[i].split("=");
1392					if (values[0] && values[0]) {
1393						data[values[0]] = values[1];
1394					}
1395				}
1396			 }
1397
1398			 if (extraDataDynamic) {
1399				 var tmpData = [];
1400				 var domIds = String(extraDataDynamic).split(",");
1401				 for (var i = 0; i < domIds.length; i++) {
1402					 var id = domIds[i];
1403					 if ($(id).length) {
1404						 var inputValue = field.closest("form, .validationEngineContainer").find(id).val();
1405						 var keyValue = id.replace('#', '') + '=' + escape(inputValue);
1406						 data[id.replace('#', '')] = inputValue;
1407					 }
1408				 }
1409			 }
1410
1411			 // If a field change event triggered this we want to clear the cache for this ID
1412			 if (options.eventTrigger == "field") {
1413				delete(options.ajaxValidCache[field.attr("id")]);
1414			 }
1415
1416			 // If there is an error or if the the field is already validated, do not re-execute AJAX
1417			 if (!options.isError && !methods._checkAjaxFieldStatus(field.attr("id"), options)) {
1418				 $.ajax({
1419					 type: options.ajaxFormValidationMethod,
1420					 url: rule.url,
1421					 cache: false,
1422					 dataType: "json",
1423					 data: data,
1424					 field: field,
1425					 rule: rule,
1426					 methods: methods,
1427					 options: options,
1428					 beforeSend: function() {},
1429					 error: function(data, transport) {
1430						if (options.onFailure) {
1431							options.onFailure(data, transport);
1432						} else {
1433							methods._ajaxError(data, transport);
1434						}
1435					 },
1436					 success: function(json) {
1437
1438						 // asynchronously called on success, data is the json answer from the server
1439						 var errorFieldId = json[0];
1440						 //var errorField = $($("#" + errorFieldId)[0]);
1441						 var errorField = $("#"+ errorFieldId).eq(0);
1442
1443						 // make sure we found the element
1444						 if (errorField.length == 1) {
1445							 var status = json[1];
1446							 // read the optional msg from the server
1447							 var msg = json[2];
1448							 if (!status) {
1449								 // Houston we got a problem - display an red prompt
1450								 options.ajaxValidCache[errorFieldId] = false;
1451								 options.isError = true;
1452
1453								 // resolve the msg prompt
1454								 if(msg) {
1455									 if (options.allrules[msg]) {
1456										 var txt = options.allrules[msg].alertText;
1457										 if (txt) {
1458											msg = txt;
1459							}
1460									 }
1461								 }
1462								 else
1463									msg = rule.alertText;
1464
1465								 if (options.showPrompts) methods._showPrompt(errorField, msg, "", true, options);
1466							 } else {
1467								 options.ajaxValidCache[errorFieldId] = true;
1468
1469								 // resolves the msg prompt
1470								 if(msg) {
1471									 if (options.allrules[msg]) {
1472										 var txt = options.allrules[msg].alertTextOk;
1473										 if (txt) {
1474											msg = txt;
1475							}
1476									 }
1477								 }
1478								 else
1479								 msg = rule.alertTextOk;
1480
1481								 if (options.showPrompts) {
1482									 // see if we should display a green prompt
1483									 if (msg)
1484										methods._showPrompt(errorField, msg, "pass", true, options);
1485									 else
1486										methods._closePrompt(errorField);
1487								}
1488
1489								 // If a submit form triggered this, we want to re-submit the form
1490								 if (options.eventTrigger == "submit")
1491									field.closest("form").submit();
1492							 }
1493						 }
1494						 errorField.trigger("jqv.field.result", [errorField, options.isError, msg]);
1495					 }
1496				 });
1497
1498				 return rule.alertTextLoad;
1499			 }
1500		 },
1501		/**
1502		* Common method to handle ajax errors
1503		*
1504		* @param {Object} data
1505		* @param {Object} transport
1506		*/
1507		_ajaxError: function(data, transport) {
1508			if(data.status == 0 && transport == null)
1509				alert("The page is not served from a server! ajax call failed");
1510			else if(typeof console != "undefined")
1511				console.log("Ajax error: " + data.status + " " + transport);
1512		},
1513		/**
1514		* date -> string
1515		*
1516		* @param {Object} date
1517		*/
1518		_dateToString: function(date) {
1519			return date.getFullYear()+"-"+(date.getMonth()+1)+"-"+date.getDate();
1520		},
1521		/**
1522		* Parses an ISO date
1523		* @param {String} d
1524		*/
1525		_parseDate: function(d) {
1526
1527			var dateParts = d.split("-");
1528			if(dateParts==d)
1529				dateParts = d.split("/");
1530			if(dateParts==d) {
1531				dateParts = d.split(".");
1532				return new Date(dateParts[2], (dateParts[1] - 1), dateParts[0]);
1533			}
1534			return new Date(dateParts[0], (dateParts[1] - 1) ,dateParts[2]);
1535		},
1536		/**
1537		* Builds or updates a prompt with the given information
1538		*
1539		* @param {jqObject} field
1540		* @param {String} promptText html text to display type
1541		* @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)
1542		* @param {boolean} ajaxed - use to mark fields than being validated with ajax
1543		* @param {Map} options user options
1544		*/
1545		 _showPrompt: function(field, promptText, type, ajaxed, options, ajaxform) {
1546		 	//Check if we need to adjust what element to show the prompt on
1547			if(field.data('jqv-prompt-at') instanceof jQuery ){
1548				field = field.data('jqv-prompt-at');
1549			} else if(field.data('jqv-prompt-at')) {
1550				field = $(field.data('jqv-prompt-at'));
1551			}
1552
1553			 var prompt = methods._getPrompt(field);
1554			 // The ajax submit errors are not see has an error in the form,
1555			 // When the form errors are returned, the engine see 2 bubbles, but those are ebing closed by the engine at the same time
1556			 // Because no error was found befor submitting
1557			 if(ajaxform) prompt = false;
1558			 // Check that there is indded text
1559			 if($.trim(promptText)){
1560				 if (prompt)
1561					methods._updatePrompt(field, prompt, promptText, type, ajaxed, options);
1562				 else
1563					methods._buildPrompt(field, promptText, type, ajaxed, options);
1564			}
1565		 },
1566		/**
1567		* Builds and shades a prompt for the given field.
1568		*
1569		* @param {jqObject} field
1570		* @param {String} promptText html text to display type
1571		* @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)
1572		* @param {boolean} ajaxed - use to mark fields than being validated with ajax
1573		* @param {Map} options user options
1574		*/
1575		_buildPrompt: function(field, promptText, type, ajaxed, options) {
1576
1577			// create the prompt
1578			var prompt = $('<div>');
1579			prompt.addClass(methods._getClassName(field.attr("id")) + "formError");
1580			// add a class name to identify the parent form of the prompt
1581			prompt.addClass("parentForm"+methods._getClassName(field.closest('form, .validationEngineContainer').attr("id")));
1582			prompt.addClass("formError");
1583
1584			switch (type) {
1585				case "pass":
1586					prompt.addClass("greenPopup");
1587					break;
1588				case "load":
1589					prompt.addClass("blackPopup");
1590					break;
1591				default:
1592					/* it has error  */
1593					//alert("unknown popup type:"+type);
1594			}
1595			if (ajaxed)
1596				prompt.addClass("ajaxed");
1597
1598			// create the prompt content
1599			var promptContent = $('<div>').addClass("formErrorContent").html(promptText).appendTo(prompt);
1600
1601			// determine position type
1602			var positionType=field.data("promptPosition") || options.promptPosition;
1603
1604			// create the css arrow pointing at the field
1605			// note that there is no triangle on max-checkbox and radio
1606			if (options.showArrow) {
1607				var arrow = $('<div>').addClass("formErrorArrow");
1608
1609				//prompt positioning adjustment support. Usage: positionType:Xshift,Yshift (for ex.: bottomLeft:+20 or bottomLeft:-20,+10)
1610				if (typeof(positionType)=='string')
1611				{
1612					var pos=positionType.indexOf(":");
1613					if(pos!=-1)
1614						positionType=positionType.substring(0,pos);
1615				}
1616
1617				switch (positionType) {
1618					case "bottomLeft":
1619					case "bottomRight":
1620						prompt.find(".formErrorContent").before(arrow);
1621						arrow.addClass("formErrorArrowBottom").html('<div class="line1"><!-- --></div><div class="line2"><!-- --></div><div class="line3"><!-- --></div><div class="line4"><!-- --></div><div class="line5"><!-- --></div><div class="line6"><!-- --></div><div class="line7"><!-- --></div><div class="line8"><!-- --></div><div class="line9"><!-- --></div><div class="line10"><!-- --></div>');
1622						break;
1623					case "topLeft":
1624					case "topRight":
1625						arrow.html('<div class="line10"><!-- --></div><div class="line9"><!-- --></div><div class="line8"><!-- --></div><div class="line7"><!-- --></div><div class="line6"><!-- --></div><div class="line5"><!-- --></div><div class="line4"><!-- --></div><div class="line3"><!-- --></div><div class="line2"><!-- --></div><div class="line1"><!-- --></div>');
1626						prompt.append(arrow);
1627						break;
1628				}
1629			}
1630			// Add custom prompt class
1631			if (options.addPromptClass)
1632				prompt.addClass(options.addPromptClass);
1633
1634            // Add custom prompt class defined in element
1635            var requiredOverride = field.attr('data-required-class');
1636            if(requiredOverride !== undefined) {
1637                prompt.addClass(requiredOverride);
1638            } else {
1639                if(options.prettySelect) {
1640                    if($('#' + field.attr('id')).next().is('select')) {
1641                        var prettyOverrideClass = $('#' + field.attr('id').substr(options.usePrefix.length).substring(options.useSuffix.length)).attr('data-required-class');
1642                        if(prettyOverrideClass !== undefined) {
1643                            prompt.addClass(prettyOverrideClass);
1644                        }
1645                    }
1646                }
1647            }
1648
1649			prompt.css({
1650				"opacity": 0
1651			});
1652			if(positionType === 'inline') {
1653				prompt.addClass("inline");
1654				if(typeof field.attr('data-prompt-target') !== 'undefined' && $('#'+field.attr('data-prompt-target')).length > 0) {
1655					prompt.appendTo($('#'+field.attr('data-prompt-target')));
1656				} else {
1657					field.after(prompt);
1658				}
1659			} else {
1660				field.before(prompt);
1661			}
1662
1663			var pos = methods._calculatePosition(field, prompt, options);
1664			prompt.css({
1665				'position': positionType === 'inline' ? 'relative' : 'absolute',
1666				"top": pos.callerTopPosition,
1667				"left": pos.callerleftPosition,
1668				"marginTop": pos.marginTopSize,
1669				"opacity": 0
1670			}).data("callerField", field);
1671
1672
1673			if (options.autoHidePrompt) {
1674				setTimeout(function(){
1675					prompt.animate({
1676						"opacity": 0
1677					},function(){
1678						prompt.closest('.formErrorOuter').remove();
1679						prompt.remove();
1680					});
1681				}, options.autoHideDelay);
1682			}
1683			return prompt.animate({
1684				"opacity": 0.87
1685			});
1686		},
1687		/**
1688		* Updates the prompt text field - the field for which the prompt
1689		* @param {jqObject} field
1690		* @param {String} promptText html text to display type
1691		* @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)
1692		* @param {boolean} ajaxed - use to mark fields than being validated with ajax
1693		* @param {Map} options user options
1694		*/
1695		_updatePrompt: function(field, prompt, promptText, type, ajaxed, options, noAnimation) {
1696
1697			if (prompt) {
1698				if (typeof type !== "undefined") {
1699					if (type == "pass")
1700						prompt.addClass("greenPopup");
1701					else
1702						prompt.removeClass("greenPopup");
1703
1704					if (type == "load")
1705						prompt.addClass("blackPopup");
1706					else
1707						prompt.removeClass("blackPopup");
1708				}
1709				if (ajaxed)
1710					prompt.addClass("ajaxed");
1711				else
1712					prompt.removeClass("ajaxed");
1713
1714				prompt.find(".formErrorContent").html(promptText);
1715
1716				var pos = methods._calculatePosition(field, prompt, options);
1717				var css = {"top": pos.callerTopPosition,
1718				"left": pos.callerleftPosition,
1719				"marginTop": pos.marginTopSize};
1720
1721				if (noAnimation)
1722					prompt.css(css);
1723				else
1724					prompt.animate(css);
1725			}
1726		},
1727		/**
1728		* Closes the prompt associated with the given field
1729		*
1730		* @param {jqObject}
1731		*            field
1732		*/
1733		 _closePrompt: function(field) {
1734			 var prompt = methods._getPrompt(field);
1735			 if (prompt)
1736				 prompt.fadeTo("fast", 0, function() {
1737					 prompt.parent('.formErrorOuter').remove();
1738					 prompt.remove();
1739				 });
1740		 },
1741		 closePrompt: function(field) {
1742			 return methods._closePrompt(field);
1743		 },
1744		/**
1745		* Returns the error prompt matching the field if any
1746		*
1747		* @param {jqObject}
1748		*            field
1749		* @return undefined or the error prompt (jqObject)
1750		*/
1751		_getPrompt: function(field) {
1752				var formId = $(field).closest('form, .validationEngineContainer').attr('id');
1753			var className = methods._getClassName(field.attr("id")) + "formError";
1754				var match = $("." + methods._escapeExpression(className) + '.parentForm' + methods._getClassName(formId))[0];
1755			if (match)
1756			return $(match);
1757		},
1758		/**
1759		  * Returns the escapade classname
1760		  *
1761		  * @param {selector}
1762		  *            className
1763		  */
1764		  _escapeExpression: function (selector) {
1765			  return selector.replace(/([#;&,\.\+\*\~':"\!\^$\[\]\(\)=>\|])/g, "\\$1");
1766		  },
1767		/**
1768		 * returns true if we are in a RTLed document
1769		 *
1770		 * @param {jqObject} field
1771		 */
1772		isRTL: function(field)
1773		{
1774			var $document = $(document);
1775			var $body = $('body');
1776			var rtl =
1777				(field && field.hasClass('rtl')) ||
1778				(field && (field.attr('dir') || '').toLowerCase()==='rtl') ||
1779				$document.hasClass('rtl') ||
1780				($document.attr('dir') || '').toLowerCase()==='rtl' ||
1781				$body.hasClass('rtl') ||
1782				($body.attr('dir') || '').toLowerCase()==='rtl';
1783			return Boolean(rtl);
1784		},
1785		/**
1786		* Calculates prompt position
1787		*
1788		* @param {jqObject}
1789		*            field
1790		* @param {jqObject}
1791		*            the prompt
1792		* @param {Map}
1793		*            options
1794		* @return positions
1795		*/
1796		_calculatePosition: function (field, promptElmt, options) {
1797
1798			var promptTopPosition, promptleftPosition, marginTopSize;
1799			var fieldWidth 	= field.width();
1800			var fieldLeft 	= field.position().left;
1801			var fieldTop 	=  field.position().top;
1802			var fieldHeight 	=  field.height();
1803			var promptHeight = promptElmt.height();
1804
1805
1806			// is the form contained in an overflown container?
1807			promptTopPosition = promptleftPosition = 0;
1808			// compensation for the arrow
1809			marginTopSize = -promptHeight;
1810
1811
1812			//prompt positioning adjustment support
1813			//now you can adjust prompt position
1814			//usage: positionType:Xshift,Yshift
1815			//for example:
1816			//   bottomLeft:+20 means bottomLeft position shifted by 20 pixels right horizontally
1817			//   topRight:20, -15 means topRight position shifted by 20 pixels to right and 15 pixels to top
1818			//You can use +pixels, - pixels. If no sign is provided than + is default.
1819			var positionType=field.data("promptPosition") || options.promptPosition;
1820			var shift1="";
1821			var shift2="";
1822			var shiftX=0;
1823			var shiftY=0;
1824			if (typeof(positionType)=='string') {
1825				//do we have any position adjustments ?
1826				if (positionType.indexOf(":")!=-1) {
1827					shift1=positionType.substring(positionType.indexOf(":")+1);
1828					positionType=positionType.substring(0,positionType.indexOf(":"));
1829
1830					//if any advanced positioning will be needed (percents or something else) - parser should be added here
1831					//for now we use simple parseInt()
1832
1833					//do we have second parameter?
1834					if (shift1.indexOf(",") !=-1) {
1835						shift2=shift1.substring(shift1.indexOf(",") +1);
1836						shift1=shift1.substring(0,shift1.indexOf(","));
1837						shiftY=parseInt(shift2);
1838						if (isNaN(shiftY)) shiftY=0;
1839					};
1840
1841					shiftX=parseInt(shift1);
1842					if (isNaN(shift1)) shift1=0;
1843
1844				};
1845			};
1846
1847
1848			switch (positionType) {
1849				default:
1850				case "topRight":
1851					promptleftPosition +=  fieldLeft + fieldWidth - 27;
1852					promptTopPosition +=  fieldTop;
1853					break;
1854
1855				case "topLeft":
1856					promptTopPosition +=  fieldTop;
1857					promptleftPosition += fieldLeft;
1858					break;
1859
1860				case "centerRight":
1861					promptTopPosition = fieldTop+4;
1862					marginTopSize = 0;
1863					promptleftPosition= fieldLeft + field.outerWidth(true)+5;
1864					break;
1865				case "centerLeft":
1866					promptleftPosition = fieldLeft - (promptElmt.width() + 2);
1867					promptTopPosition = fieldTop+4;
1868					marginTopSize = 0;
1869
1870					break;
1871
1872				case "bottomLeft":
1873					promptTopPosition = fieldTop + field.height() + 5;
1874					marginTopSize = 0;
1875					promptleftPosition = fieldLeft;
1876					break;
1877				case "bottomRight":
1878					promptleftPosition = fieldLeft + fieldWidth - 27;
1879					promptTopPosition =  fieldTop +  field.height() + 5;
1880					marginTopSize = 0;
1881					break;
1882				case "inline":
1883					promptleftPosition = 0;
1884					promptTopPosition = 0;
1885					marginTopSize = 0;
1886			};
1887
1888
1889
1890			//apply adjusments if any
1891			promptleftPosition += shiftX;
1892			promptTopPosition  += shiftY;
1893
1894			return {
1895				"callerTopPosition": promptTopPosition + "px",
1896				"callerleftPosition": promptleftPosition + "px",
1897				"marginTopSize": marginTopSize + "px"
1898			};
1899		},
1900		/**
1901		* Saves the user options and variables in the form.data
1902		*
1903		* @param {jqObject}
1904		*            form - the form where the user option should be saved
1905		* @param {Map}
1906		*            options - the user options
1907		* @return the user options (extended from the defaults)
1908		*/
1909		 _saveOptions: function(form, options) {
1910
1911			 // is there a language localisation ?
1912			 if ($.validationEngineLanguage)
1913			 var allRules = $.validationEngineLanguage.allRules;
1914			 else
1915			 $.error("jQuery.validationEngine rules are not loaded, plz add localization files to the page");
1916			 // --- Internals DO NOT TOUCH or OVERLOAD ---
1917			 // validation rules and i18
1918			 $.validationEngine.defaults.allrules = allRules;
1919
1920			 var userOptions = $.extend(true,{},$.validationEngine.defaults,options);
1921
1922			 form.data('jqv', userOptions);
1923			 return userOptions;
1924		 },
1925
1926		 /**
1927		 * Removes forbidden characters from class name
1928		 * @param {String} className
1929		 */
1930		 _getClassName: function(className) {
1931			 if(className)
1932				 return className.replace(/:/g, "_").replace(/\./g, "_");
1933					  },
1934		/**
1935		 * Escape special character for jQuery selector
1936		 * http://totaldev.com/content/escaping-characters-get-valid-jquery-id
1937		 * @param {String} selector
1938		 */
1939		 _jqSelector: function(str){
1940			return str.replace(/([;&,\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g, '\\$1');
1941		},
1942		/**
1943		* Conditionally required field
1944		*
1945		* @param {jqObject} field
1946		* @param {Array[String]} rules
1947		* @param {int} i rules index
1948		* @param {Map}
1949		* user options
1950		* @return an error string if validation failed
1951		*/
1952		_condRequired: function(field, rules, i, options) {
1953			var idx, dependingField;
1954
1955			for(idx = (i + 1); idx < rules.length; idx++) {
1956				dependingField = jQuery("#" + rules[idx]).first();
1957
1958				/* Use _required for determining wether dependingField has a value.
1959				 * There is logic there for handling all field types, and default value; so we won't replicate that here
1960				 * Indicate this special use by setting the last parameter to true so we only validate the dependingField on chackboxes and radio buttons (#462)
1961				 */
1962				if (dependingField.length && methods._required(dependingField, ["required"], 0, options, true) == undefined) {
1963					/* We now know any of the depending fields has a value,
1964					 * so we can validate this field as per normal required code
1965					 */
1966					return methods._required(field, ["required"], 0, options);
1967				}
1968			}
1969		},
1970
1971	    _submitButtonClick: function(event) {
1972	        var button = $(this);
1973	        var form = button.closest('form, .validationEngineContainer');
1974	        form.data("jqv_submitButton", button.attr("id"));
1975	    }
1976		  };
1977
1978	 /**
1979	 * Plugin entry point.
1980	 * You may pass an action as a parameter or a list of options.
1981	 * if none, the init and attach methods are being called.
1982	 * Remember: if you pass options, the attached method is NOT called automatically
1983	 *
1984	 * @param {String}
1985	 *            method (optional) action
1986	 */
1987	 $.fn.validationEngine = function(method) {
1988
1989		 var form = $(this);
1990		 if(!form[0]) return form;  // stop here if the form does not exist
1991
1992		 if (typeof(method) == 'string' && method.charAt(0) != '_' && methods[method]) {
1993
1994			 // make sure init is called once
1995			 if(method != "showPrompt" && method != "hide" && method != "hideAll")
1996			 methods.init.apply(form);
1997
1998			 return methods[method].apply(form, Array.prototype.slice.call(arguments, 1));
1999		 } else if (typeof method == 'object' || !method) {
2000
2001			 // default constructor with or without arguments
2002			 methods.init.apply(form, arguments);
2003			 return methods.attach.apply(form);
2004		 } else {
2005			 $.error('Method ' + method + ' does not exist in jQuery.validationEngine');
2006		 }
2007	};
2008
2009
2010
2011	// LEAK GLOBAL OPTIONS
2012	$.validationEngine= {fieldIdCounter: 0,defaults:{
2013
2014		// Name of the event triggering field validation
2015		validationEventTrigger: "blur",
2016		// Automatically scroll viewport to the first error
2017		scroll: true,
2018		// Focus on the first input
2019		focusFirstField:true,
2020		// Show prompts, set to false to disable prompts
2021		showPrompts: true,
2022       // Should we attempt to validate non-visible input fields contained in the form? (Useful in cases of tabbed containers, e.g. jQuery-UI tabs)
2023       validateNonVisibleFields: false,
2024		// Opening box position, possible locations are: topLeft,
2025		// topRight, bottomLeft, centerRight, bottomRight, inline
2026		// inline gets inserted after the validated field or into an element specified in data-prompt-target
2027		promptPosition: "topRight",
2028		bindMethod:"bind",
2029		// internal, automatically set to true when it parse a _ajax rule
2030		inlineAjax: false,
2031		// if set to true, the form data is sent asynchronously via ajax to the form.action url (get)
2032		ajaxFormValidation: false,
2033		// The url to send the submit ajax validation (default to action)
2034		ajaxFormValidationURL: false,
2035		// HTTP method used for ajax validation
2036		ajaxFormValidationMethod: 'get',
2037		// Ajax form validation callback method: boolean onComplete(form, status, errors, options)
2038		// retuns false if the form.submit event needs to be canceled.
2039		onAjaxFormComplete: $.noop,
2040		// called right before the ajax call, may return false to cancel
2041		onBeforeAjaxFormValidation: $.noop,
2042		// Stops form from submitting and execute function assiciated with it
2043		onValidationComplete: false,
2044
2045		// Used when you have a form fields too close and the errors messages are on top of other disturbing viewing messages
2046		doNotShowAllErrosOnSubmit: false,
2047		// Object where you store custom messages to override the default error messages
2048		custom_error_messages:{},
2049		// true if you want to validate the input fields on blur event
2050		binded: true,
2051		// set to true, when the prompt arrow needs to be displayed
2052		showArrow: true,
2053		// set to false, determines if the prompt arrow should be displayed when validating
2054		// checkboxes and radio buttons
2055		showArrowOnRadioAndCheckbox: false,
2056		// did one of the validation fail ? kept global to stop further ajax validations
2057		isError: false,
2058		// Limit how many displayed errors a field can have
2059		maxErrorsPerField: false,
2060
2061		// Caches field validation status, typically only bad status are created.
2062		// the array is used during ajax form validation to detect issues early and prevent an expensive submit
2063		ajaxValidCache: {},
2064		// Auto update prompt position after window resize
2065		autoPositionUpdate: false,
2066
2067		InvalidFields: [],
2068		onFieldSuccess: false,
2069		onFieldFailure: false,
2070		onSuccess: false,
2071		onFailure: false,
2072		validateAttribute: "class",
2073		addSuccessCssClassToField: "",
2074		addFailureCssClassToField: "",
2075
2076		// Auto-hide prompt
2077		autoHidePrompt: false,
2078		// Delay before auto-hide
2079		autoHideDelay: 10000,
2080		// Fade out duration while hiding the validations
2081		fadeDuration: 0.3,
2082	 // Use Prettify select library
2083	 prettySelect: false,
2084	 // Add css class on prompt
2085	 addPromptClass : "",
2086	 // Custom ID uses prefix
2087	 usePrefix: "",
2088	 // Custom ID uses suffix
2089	 useSuffix: "",
2090	 // Only show one message per error prompt
2091	 showOneMessage: false
2092	}};
2093	$(function(){$.validationEngine.defaults.promptPosition = methods.isRTL()?'topLeft':"topRight"});
2094})(jQuery);

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.