Divide the MSB source codes into two repos
[msb/apigateway.git] / apiroute / apiroute-service / src / main / resources / iui-route / js / jquery-validation / jquery.validate.js
1 /*!
2  * jQuery Validation Plugin v1.13.0
3  *
4  * http://jqueryvalidation.org/
5  *
6  * Copyright (c) 2014 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 {
13                 factory( jQuery );
14         }
15 }(function( $ ) {
16
17 $.extend($.fn, {
18         // http://jqueryvalidation.org/validate/
19         validate: function( options ) {
20
21                 // if nothing is selected, return nothing; can't chain anyway
22                 if ( !this.length ) {
23                         if ( options && options.debug && window.console ) {
24                                 console.warn( "Nothing selected, can't validate, returning nothing." );
25                         }
26                         return;
27                 }
28
29                 // check if a validator for this form was already created
30                 var validator = $.data( this[ 0 ], "validator" );
31                 if ( validator ) {
32                         return validator;
33                 }
34
35                 // Add novalidate tag if HTML5.
36                 this.attr( "novalidate", "novalidate" );
37
38                 validator = new $.validator( options, this[ 0 ] );
39                 $.data( this[ 0 ], "validator", validator );
40
41                 if ( validator.settings.onsubmit ) {
42
43                         this.validateDelegate( ":submit", "click", function( event ) {
44                                 if ( validator.settings.submitHandler ) {
45                                         validator.submitButton = event.target;
46                                 }
47                                 // allow suppressing validation by adding a cancel class to the submit button
48                                 if ( $( event.target ).hasClass( "cancel" ) ) {
49                                         validator.cancelSubmit = true;
50                                 }
51
52                                 // allow suppressing validation by adding the html5 formnovalidate attribute to the submit button
53                                 if ( $( event.target ).attr( "formnovalidate" ) !== undefined ) {
54                                         validator.cancelSubmit = true;
55                                 }
56                         });
57
58                         // validate the form on submit
59                         this.submit( function( event ) {
60                                 if ( validator.settings.debug ) {
61                                         // prevent form submit to be able to see console output
62                                         event.preventDefault();
63                                 }
64                                 function handle() {
65                                         var hidden;
66                                         if ( validator.settings.submitHandler ) {
67                                                 if ( validator.submitButton ) {
68                                                         // insert a hidden input as a replacement for the missing submit button
69                                                         hidden = $( "<input type='hidden'/>" )
70                                                                 .attr( "name", validator.submitButton.name )
71                                                                 .val( $( validator.submitButton ).val() )
72                                                                 .appendTo( validator.currentForm );
73                                                 }
74                                                 validator.settings.submitHandler.call( validator, validator.currentForm, event );
75                                                 if ( validator.submitButton ) {
76                                                         // and clean up afterwards; thanks to no-block-scope, hidden can be referenced
77                                                         hidden.remove();
78                                                 }
79                                                 return false;
80                                         }
81                                         return true;
82                                 }
83
84                                 // prevent submit for invalid forms or custom submit handlers
85                                 if ( validator.cancelSubmit ) {
86                                         validator.cancelSubmit = false;
87                                         return handle();
88                                 }
89                                 if ( validator.form() ) {
90                                         if ( validator.pendingRequest ) {
91                                                 validator.formSubmitted = true;
92                                                 return false;
93                                         }
94                                         return handle();
95                                 } else {
96                                         validator.focusInvalid();
97                                         return false;
98                                 }
99                         });
100                 }
101
102                 return validator;
103         },
104         // http://jqueryvalidation.org/valid/
105         valid: function() {
106                 var valid, validator;
107
108                 if ( $( this[ 0 ] ).is( "form" ) ) {
109                         valid = this.validate().form();
110                 } else {
111                         valid = true;
112                         validator = $( this[ 0 ].form ).validate();
113                         this.each( function() {
114                                 valid = validator.element( this ) && valid;
115                         });
116                 }
117                 return valid;
118         },
119         // attributes: space separated list of attributes to retrieve and remove
120         removeAttrs: function( attributes ) {
121                 var result = {},
122                         $element = this;
123                 $.each( attributes.split( /\s/ ), function( index, value ) {
124                         result[ value ] = $element.attr( value );
125                         $element.removeAttr( value );
126                 });
127                 return result;
128         },
129         // http://jqueryvalidation.org/rules/
130         rules: function( command, argument ) {
131                 var element = this[ 0 ],
132                         settings, staticRules, existingRules, data, param, filtered;
133
134                 if ( command ) {
135                         settings = $.data( element.form, "validator" ).settings;
136                         staticRules = settings.rules;
137                         existingRules = $.validator.staticRules( element );
138                         switch ( command ) {
139                         case "add":
140                                 $.extend( existingRules, $.validator.normalizeRule( argument ) );
141                                 // remove messages from rules, but allow them to be set separately
142                                 delete existingRules.messages;
143                                 staticRules[ element.name ] = existingRules;
144                                 if ( argument.messages ) {
145                                         settings.messages[ element.name ] = $.extend( settings.messages[ element.name ], argument.messages );
146                                 }
147                                 break;
148                         case "remove":
149                                 if ( !argument ) {
150                                         delete staticRules[ element.name ];
151                                         return existingRules;
152                                 }
153                                 filtered = {};
154                                 $.each( argument.split( /\s/ ), function( index, method ) {
155                                         filtered[ method ] = existingRules[ method ];
156                                         delete existingRules[ method ];
157                                         if ( method === "required" ) {
158                                                 $( element ).removeAttr( "aria-required" );
159                                         }
160                                 });
161                                 return filtered;
162                         }
163                 }
164
165                 data = $.validator.normalizeRules(
166                 $.extend(
167                         {},
168                         $.validator.classRules( element ),
169                         $.validator.attributeRules( element ),
170                         $.validator.dataRules( element ),
171                         $.validator.staticRules( element )
172                 ), element );
173
174                 // make sure required is at front
175                 if ( data.required ) {
176                         param = data.required;
177                         delete data.required;
178                         data = $.extend( { required: param }, data );
179                         $( element ).attr( "aria-required", "true" );
180                 }
181
182                 // make sure remote is at back
183                 if ( data.remote ) {
184                         param = data.remote;
185                         delete data.remote;
186                         data = $.extend( data, { remote: param });
187                 }
188
189                 return data;
190         }
191 });
192
193 // Custom selectors
194 $.extend( $.expr[ ":" ], {
195         // http://jqueryvalidation.org/blank-selector/
196         blank: function( a ) {
197                 return !$.trim( "" + $( a ).val() );
198         },
199         // http://jqueryvalidation.org/filled-selector/
200         filled: function( a ) {
201                 return !!$.trim( "" + $( a ).val() );
202         },
203         // http://jqueryvalidation.org/unchecked-selector/
204         unchecked: function( a ) {
205                 return !$( a ).prop( "checked" );
206         }
207 });
208
209 // constructor for validator
210 $.validator = function( options, form ) {
211         this.settings = $.extend( true, {}, $.validator.defaults, options );
212         this.currentForm = form;
213         this.init();
214 };
215
216 // http://jqueryvalidation.org/jQuery.validator.format/
217 $.validator.format = function( source, params ) {
218         if ( arguments.length === 1 ) {
219                 return function() {
220                         var args = $.makeArray( arguments );
221                         args.unshift( source );
222                         return $.validator.format.apply( this, args );
223                 };
224         }
225         if ( arguments.length > 2 && params.constructor !== Array  ) {
226                 params = $.makeArray( arguments ).slice( 1 );
227         }
228         if ( params.constructor !== Array ) {
229                 params = [ params ];
230         }
231         $.each( params, function( i, n ) {
232                 source = source.replace( new RegExp( "\\{" + i + "\\}", "g" ), function() {
233                         return n;
234                 });
235         });
236         return source;
237 };
238
239 $.extend( $.validator, {
240
241         defaults: {
242                 messages: {},
243                 groups: {},
244                 rules: {},
245                 errorClass: "error",
246                 validClass: "valid",
247                 errorElement: "label",
248                 focusInvalid: true,
249                 errorContainer: $( [] ),
250                 errorLabelContainer: $( [] ),
251                 onsubmit: true,
252                 ignore: ":hidden",
253                 ignoreTitle: false,
254                 onfocusin: function( element ) {
255                         this.lastActive = element;
256
257                         // hide error label and remove error class on focus if enabled
258                         if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {
259                                 if ( this.settings.unhighlight ) {
260                                         this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
261                                 }
262                                 this.hideThese( this.errorsFor( element ) );
263                         }
264                 },
265                 onfocusout: function( element ) {
266                         if ( !this.checkable( element ) && ( element.name in this.submitted || !this.optional( element ) ) ) {
267                                 this.element( element );
268                         }
269                 },
270                 onkeyup: function( element, event ) {
271                         if ( event.which === 9 && this.elementValue( element ) === "" ) {
272                                 return;
273                         } else if ( element.name in this.submitted || element === this.lastElement ) {
274                                 this.element( element );
275                         }
276                 },
277                 onclick: function( element ) {
278                         // click on selects, radiobuttons and checkboxes
279                         if ( element.name in this.submitted ) {
280                                 this.element( element );
281
282                         // or option elements, check parent select in that case
283                         } else if ( element.parentNode.name in this.submitted ) {
284                                 this.element( element.parentNode );
285                         }
286                 },
287                 highlight: function( element, errorClass, validClass ) {
288                         if ( element.type === "radio" ) {
289                                 this.findByName( element.name ).addClass( errorClass ).removeClass( validClass );
290                         } else {
291                                 $( element ).addClass( errorClass ).removeClass( validClass );
292                         }
293                 },
294                 unhighlight: function( element, errorClass, validClass ) {
295                         if ( element.type === "radio" ) {
296                                 this.findByName( element.name ).removeClass( errorClass ).addClass( validClass );
297                         } else {
298                                 $( element ).removeClass( errorClass ).addClass( validClass );
299                         }
300                 }
301         },
302
303         // http://jqueryvalidation.org/jQuery.validator.setDefaults/
304         setDefaults: function( settings ) {
305                 $.extend( $.validator.defaults, settings );
306         },
307
308         messages: {
309                 required: "This field is required.",
310                 remote: "Please fix this field.",
311                 email: "Please enter a valid email address.",
312                 url: "Please enter a valid URL.",
313                 date: "Please enter a valid date.",
314                 dateISO: "Please enter a valid date ( ISO ).",
315                 number: "Please enter a valid number.",
316                 digits: "Please enter only digits.",
317                 creditcard: "Please enter a valid credit card number.",
318                 equalTo: "Please enter the same value again.",
319                 maxlength: $.validator.format( "Please enter no more than {0} characters." ),
320                 minlength: $.validator.format( "Please enter at least {0} characters." ),
321                 rangelength: $.validator.format( "Please enter a value between {0} and {1} characters long." ),
322                 range: $.validator.format( "Please enter a value between {0} and {1}." ),
323                 max: $.validator.format( "Please enter a value less than or equal to {0}." ),
324                 min: $.validator.format( "Please enter a value greater than or equal to {0}." )
325         },
326
327         autoCreateRanges: false,
328
329         prototype: {
330
331                 init: function() {
332                         this.labelContainer = $( this.settings.errorLabelContainer );
333                         this.errorContext = this.labelContainer.length && this.labelContainer || $( this.currentForm );
334                         this.containers = $( this.settings.errorContainer ).add( this.settings.errorLabelContainer );
335                         this.submitted = {};
336                         this.valueCache = {};
337                         this.pendingRequest = 0;
338                         this.pending = {};
339                         this.invalid = {};
340                         this.reset();
341
342                         var groups = ( this.groups = {} ),
343                                 rules;
344                         $.each( this.settings.groups, function( key, value ) {
345                                 if ( typeof value === "string" ) {
346                                         value = value.split( /\s/ );
347                                 }
348                                 $.each( value, function( index, name ) {
349                                         groups[ name ] = key;
350                                 });
351                         });
352                         rules = this.settings.rules;
353                         $.each( rules, function( key, value ) {
354                                 rules[ key ] = $.validator.normalizeRule( value );
355                         });
356
357                         function delegate( event ) {
358                                 var validator = $.data( this[ 0 ].form, "validator" ),
359                                         eventType = "on" + event.type.replace( /^validate/, "" ),
360                                         settings = validator.settings;
361                                 if ( settings[ eventType ] && !this.is( settings.ignore ) ) {
362                                         settings[ eventType ].call( validator, this[ 0 ], event );
363                                 }
364                         }
365                         $( this.currentForm )
366                                 .validateDelegate( ":text, [type='password'], [type='file'], select, textarea, " +
367                                         "[type='number'], [type='search'] ,[type='tel'], [type='url'], " +
368                                         "[type='email'], [type='datetime'], [type='date'], [type='month'], " +
369                                         "[type='week'], [type='time'], [type='datetime-local'], " +
370                                         "[type='range'], [type='color'], [type='radio'], [type='checkbox']",
371                                         "focusin focusout keyup", delegate)
372                                 // Support: Chrome, oldIE
373                                 // "select" is provided as event.target when clicking a option
374                                 .validateDelegate("select, option, [type='radio'], [type='checkbox']", "click", delegate);
375
376                         if ( this.settings.invalidHandler ) {
377                                 $( this.currentForm ).bind( "invalid-form.validate", this.settings.invalidHandler );
378                         }
379
380                         // Add aria-required to any Static/Data/Class required fields before first validation
381                         // Screen readers require this attribute to be present before the initial submission http://www.w3.org/TR/WCAG-TECHS/ARIA2.html
382                         $( this.currentForm ).find( "[required], [data-rule-required], .required" ).attr( "aria-required", "true" );
383                 },
384
385                 // http://jqueryvalidation.org/Validator.form/
386                 form: function() {
387                         this.checkForm();
388                         $.extend( this.submitted, this.errorMap );
389                         this.invalid = $.extend({}, this.errorMap );
390                         if ( !this.valid() ) {
391                                 $( this.currentForm ).triggerHandler( "invalid-form", [ this ]);
392                         }
393                         this.showErrors();
394                         return this.valid();
395                 },
396
397                 checkForm: function() {
398                         this.prepareForm();
399                         for ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) {
400                                 this.check( elements[ i ] );
401                         }
402                         return this.valid();
403                 },
404
405                 // http://jqueryvalidation.org/Validator.element/
406                 element: function( element ) {
407                         var cleanElement = this.clean( element ),
408                                 checkElement = this.validationTargetFor( cleanElement ),
409                                 result = true;
410
411                         this.lastElement = checkElement;
412
413                         if ( checkElement === undefined ) {
414                                 delete this.invalid[ cleanElement.name ];
415                         } else {
416                                 this.prepareElement( checkElement );
417                                 this.currentElements = $( checkElement );
418
419                                 result = this.check( checkElement ) !== false;
420                                 if ( result ) {
421                                         delete this.invalid[ checkElement.name ];
422                                 } else {
423                                         this.invalid[ checkElement.name ] = true;
424                                 }
425                         }
426                         // Add aria-invalid status for screen readers
427                         $( element ).attr( "aria-invalid", !result );
428
429                         if ( !this.numberOfInvalids() ) {
430                                 // Hide error containers on last error
431                                 this.toHide = this.toHide.add( this.containers );
432                         }
433                         this.showErrors();
434                         return result;
435                 },
436
437                 // http://jqueryvalidation.org/Validator.showErrors/
438                 showErrors: function( errors ) {
439                         if ( errors ) {
440                                 // add items to error list and map
441                                 $.extend( this.errorMap, errors );
442                                 this.errorList = [];
443                                 for ( var name in errors ) {
444                                         this.errorList.push({
445                                                 message: errors[ name ],
446                                                 element: this.findByName( name )[ 0 ]
447                                         });
448                                 }
449                                 // remove items from success list
450                                 this.successList = $.grep( this.successList, function( element ) {
451                                         return !( element.name in errors );
452                                 });
453                         }
454                         if ( this.settings.showErrors ) {
455                                 this.settings.showErrors.call( this, this.errorMap, this.errorList );
456                         } else {
457                                 this.defaultShowErrors();
458                         }
459                 },
460
461                 // http://jqueryvalidation.org/Validator.resetForm/
462                 resetForm: function() {
463                         if ( $.fn.resetForm ) {
464                                 $( this.currentForm ).resetForm();
465                         }
466                         this.submitted = {};
467                         this.lastElement = null;
468                         this.prepareForm();
469                         this.hideErrors();
470                         this.elements()
471                                         .removeClass( this.settings.errorClass )
472                                         .removeData( "previousValue" )
473                                         .removeAttr( "aria-invalid" );
474                 },
475
476                 numberOfInvalids: function() {
477                         return this.objectLength( this.invalid );
478                 },
479
480                 objectLength: function( obj ) {
481                         /* jshint unused: false */
482                         var count = 0,
483                                 i;
484                         for ( i in obj ) {
485                                 count++;
486                         }
487                         return count;
488                 },
489
490                 hideErrors: function() {
491                         this.hideThese( this.toHide );
492                 },
493
494                 hideThese: function( errors ) {
495                         errors.not( this.containers ).text( "" );
496                         this.addWrapper( errors ).hide();
497                 },
498
499                 valid: function() {
500                         return this.size() === 0;
501                 },
502
503                 size: function() {
504                         return this.errorList.length;
505                 },
506
507                 focusInvalid: function() {
508                         if ( this.settings.focusInvalid ) {
509                                 try {
510                                         $( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || [])
511                                         .filter( ":visible" )
512                                         .focus()
513                                         // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
514                                         .trigger( "focusin" );
515                                 } catch ( e ) {
516                                         // ignore IE throwing errors when focusing hidden elements
517                                 }
518                         }
519                 },
520
521                 findLastActive: function() {
522                         var lastActive = this.lastActive;
523                         return lastActive && $.grep( this.errorList, function( n ) {
524                                 return n.element.name === lastActive.name;
525                         }).length === 1 && lastActive;
526                 },
527
528                 elements: function() {
529                         var validator = this,
530                                 rulesCache = {};
531
532                         // select all valid inputs inside the form (no submit or reset buttons)
533                         return $( this.currentForm )
534                         .find( "input, select, textarea" )
535                         .not( ":submit, :reset, :image, [disabled]" )
536                         .not( this.settings.ignore )
537                         .filter( function() {
538                                 if ( !this.name && validator.settings.debug && window.console ) {
539                                         console.error( "%o has no name assigned", this );
540                                 }
541
542                                 // select only the first element for each name, and only those with rules specified
543                                 if ( this.name in rulesCache || !validator.objectLength( $( this ).rules() ) ) {
544                                         return false;
545                                 }
546
547                                 rulesCache[ this.name ] = true;
548                                 return true;
549                         });
550                 },
551
552                 clean: function( selector ) {
553                         return $( selector )[ 0 ];
554                 },
555
556                 errors: function() {
557                         var errorClass = this.settings.errorClass.split( " " ).join( "." );
558                         return $( this.settings.errorElement + "." + errorClass, this.errorContext );
559                 },
560
561                 reset: function() {
562                         this.successList = [];
563                         this.errorList = [];
564                         this.errorMap = {};
565                         this.toShow = $( [] );
566                         this.toHide = $( [] );
567                         this.currentElements = $( [] );
568                 },
569
570                 prepareForm: function() {
571                         this.reset();
572                         this.toHide = this.errors().add( this.containers );
573                 },
574
575                 prepareElement: function( element ) {
576                         this.reset();
577                         this.toHide = this.errorsFor( element );
578                 },
579
580                 elementValue: function( element ) {
581                         var val,
582                                 $element = $( element ),
583                                 type = element.type;
584
585                         if ( type === "radio" || type === "checkbox" ) {
586                                 return $( "input[name='" + element.name + "']:checked" ).val();
587                         } else if ( type === "number" && typeof element.validity !== "undefined" ) {
588                                 return element.validity.badInput ? false : $element.val();
589                         }
590
591                         val = $element.val();
592                         if ( typeof val === "string" ) {
593                                 return val.replace(/\r/g, "" );
594                         }
595                         return val;
596                 },
597
598                 check: function( element ) {
599                         element = this.validationTargetFor( this.clean( element ) );
600
601                         var rules = $( element ).rules(),
602                                 rulesCount = $.map( rules, function( n, i ) {
603                                         return i;
604                                 }).length,
605                                 dependencyMismatch = false,
606                                 val = this.elementValue( element ),
607                                 result, method, rule;
608
609                         for ( method in rules ) {
610                                 rule = { method: method, parameters: rules[ method ] };
611                                 try {
612
613                                         result = $.validator.methods[ method ].call( this, val, element, rule.parameters );
614
615                                         // if a method indicates that the field is optional and therefore valid,
616                                         // don't mark it as valid when there are no other rules
617                                         if ( result === "dependency-mismatch" && rulesCount === 1 ) {
618                                                 dependencyMismatch = true;
619                                                 continue;
620                                         }
621                                         dependencyMismatch = false;
622
623                                         if ( result === "pending" ) {
624                                                 this.toHide = this.toHide.not( this.errorsFor( element ) );
625                                                 return;
626                                         }
627
628                                         if ( !result ) {
629                                                 this.formatAndAdd( element, rule );
630                                                 return false;
631                                         }
632                                 } catch ( e ) {
633                                         if ( this.settings.debug && window.console ) {
634                                                 console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e );
635                                         }
636                                         throw e;
637                                 }
638                         }
639                         if ( dependencyMismatch ) {
640                                 return;
641                         }
642                         if ( this.objectLength( rules ) ) {
643                                 this.successList.push( element );
644                         }
645                         return true;
646                 },
647
648                 // return the custom message for the given element and validation method
649                 // specified in the element's HTML5 data attribute
650                 // return the generic message if present and no method specific message is present
651                 customDataMessage: function( element, method ) {
652                         return $( element ).data( "msg" + method.charAt( 0 ).toUpperCase() +
653                                 method.substring( 1 ).toLowerCase() ) || $( element ).data( "msg" );
654                 },
655
656                 // return the custom message for the given element name and validation method
657                 customMessage: function( name, method ) {
658                         var m = this.settings.messages[ name ];
659                         return m && ( m.constructor === String ? m : m[ method ]);
660                 },
661
662                 // return the first defined argument, allowing empty strings
663                 findDefined: function() {
664                         for ( var i = 0; i < arguments.length; i++) {
665                                 if ( arguments[ i ] !== undefined ) {
666                                         return arguments[ i ];
667                                 }
668                         }
669                         return undefined;
670                 },
671
672                 defaultMessage: function( element, method ) {
673                         return this.findDefined(
674                                 this.customMessage( element.name, method ),
675                                 this.customDataMessage( element, method ),
676                                 // title is never undefined, so handle empty string as undefined
677                                 !this.settings.ignoreTitle && element.title || undefined,
678                                 $.validator.messages[ method ],
679                                 "<strong>Warning: No message defined for " + element.name + "</strong>"
680                         );
681                 },
682
683                 formatAndAdd: function( element, rule ) {
684                         var message = this.defaultMessage( element, rule.method ),
685                                 theregex = /\$?\{(\d+)\}/g;
686                         if ( typeof message === "function" ) {
687                                 message = message.call( this, rule.parameters, element );
688                         } else if ( theregex.test( message ) ) {
689                                 message = $.validator.format( message.replace( theregex, "{$1}" ), rule.parameters );
690                         }
691                         this.errorList.push({
692                                 message: message,
693                                 element: element,
694                                 method: rule.method
695                         });
696
697                         this.errorMap[ element.name ] = message;
698                         this.submitted[ element.name ] = message;
699                 },
700
701                 addWrapper: function( toToggle ) {
702                         if ( this.settings.wrapper ) {
703                                 toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
704                         }
705                         return toToggle;
706                 },
707
708                 defaultShowErrors: function() {
709                         var i, elements, error;
710                         for ( i = 0; this.errorList[ i ]; i++ ) {
711                                 error = this.errorList[ i ];
712                                 if ( this.settings.highlight ) {
713                                         this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
714                                 }
715                                 this.showLabel( error.element, error.message );
716                         }
717                         if ( this.errorList.length ) {
718                                 this.toShow = this.toShow.add( this.containers );
719                         }
720                         if ( this.settings.success ) {
721                                 for ( i = 0; this.successList[ i ]; i++ ) {
722                                         this.showLabel( this.successList[ i ] );
723                                 }
724                         }
725                         if ( this.settings.unhighlight ) {
726                                 for ( i = 0, elements = this.validElements(); elements[ i ]; i++ ) {
727                                         this.settings.unhighlight.call( this, elements[ i ], this.settings.errorClass, this.settings.validClass );
728                                 }
729                         }
730                         this.toHide = this.toHide.not( this.toShow );
731                         this.hideErrors();
732                         this.addWrapper( this.toShow ).show();
733                 },
734
735                 validElements: function() {
736                         return this.currentElements.not( this.invalidElements() );
737                 },
738
739                 invalidElements: function() {
740                         return $( this.errorList ).map(function() {
741                                 return this.element;
742                         });
743                 },
744
745                 showLabel: function( element, message ) {
746                         var place, group, errorID,
747                                 error = this.errorsFor( element ),
748                                 elementID = this.idOrName( element ),
749                                 describedBy = $( element ).attr( "aria-describedby" );
750                         if ( error.length ) {
751                                 // refresh error/success class
752                                 error.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );
753                                 // replace message on existing label
754                                 error.html( message );
755                         } else {
756                                 // create error element
757                                 error = $( "<" + this.settings.errorElement + ">" )
758                                         .attr( "id", elementID + "-error" )
759                                         .addClass( this.settings.errorClass )
760                                         .html( message || "" );
761
762                                 // Maintain reference to the element to be placed into the DOM
763                                 place = error;
764                                 if ( this.settings.wrapper ) {
765                                         // make sure the element is visible, even in IE
766                                         // actually showing the wrapped element is handled elsewhere
767                                         place = error.hide().show().wrap( "<" + this.settings.wrapper + "/>" ).parent();
768                                 }
769                                 if ( this.labelContainer.length ) {
770                                         this.labelContainer.append( place );
771                                 } else if ( this.settings.errorPlacement ) {
772                                         this.settings.errorPlacement( place, $( element ) );
773                                 } else {
774                                         place.insertAfter( element );
775                                 }
776
777                                 // Link error back to the element
778                                 if ( error.is( "label" ) ) {
779                                         // If the error is a label, then associate using 'for'
780                                         error.attr( "for", elementID );
781                                 } else if ( error.parents( "label[for='" + elementID + "']" ).length === 0 ) {
782                                         // If the element is not a child of an associated label, then it's necessary
783                                         // to explicitly apply aria-describedby
784
785                                         errorID = error.attr( "id" );
786                                         // Respect existing non-error aria-describedby
787                                         if ( !describedBy ) {
788                                                 describedBy = errorID;
789                                         } else if ( !describedBy.match( new RegExp( "\b" + errorID + "\b" ) ) ) {
790                                                 // Add to end of list if not already present
791                                                 describedBy += " " + errorID;
792                                         }
793                                         $( element ).attr( "aria-describedby", describedBy );
794
795                                         // If this element is grouped, then assign to all elements in the same group
796                                         group = this.groups[ element.name ];
797                                         if ( group ) {
798                                                 $.each( this.groups, function( name, testgroup ) {
799                                                         if ( testgroup === group ) {
800                                                                 $( "[name='" + name + "']", this.currentForm )
801                                                                         .attr( "aria-describedby", error.attr( "id" ) );
802                                                         }
803                                                 });
804                                         }
805                                 }
806                         }
807                         if ( !message && this.settings.success ) {
808                                 error.text( "" );
809                                 if ( typeof this.settings.success === "string" ) {
810                                         error.addClass( this.settings.success );
811                                 } else {
812                                         this.settings.success( error, element );
813                                 }
814                         }
815                         this.toShow = this.toShow.add( error );
816                 },
817
818                 errorsFor: function( element ) {
819                         var name = this.idOrName( element ),
820                                 describer = $( element ).attr( "aria-describedby" ),
821                                 selector = "label[for='" + name + "'], label[for='" + name + "'] *";
822                         // aria-describedby should directly reference the error element
823                         if ( describer ) {
824                                 selector = selector + ", #" + describer.replace( /\s+/g, ", #" );
825                         }
826                         return this
827                                 .errors()
828                                 .filter( selector );
829                 },
830
831                 idOrName: function( element ) {
832                         return this.groups[ element.name ] || ( this.checkable( element ) ? element.name : element.id || element.name );
833                 },
834
835                 validationTargetFor: function( element ) {
836                         // if radio/checkbox, validate first element in group instead
837                         if ( this.checkable( element ) ) {
838                                 element = this.findByName( element.name ).not( this.settings.ignore )[ 0 ];
839                         }
840                         return element;
841                 },
842
843                 checkable: function( element ) {
844                         return ( /radio|checkbox/i ).test( element.type );
845                 },
846
847                 findByName: function( name ) {
848                         return $( this.currentForm ).find( "[name='" + name + "']" );
849                 },
850
851                 getLength: function( value, element ) {
852                         switch ( element.nodeName.toLowerCase() ) {
853                         case "select":
854                                 return $( "option:selected", element ).length;
855                         case "input":
856                                 if ( this.checkable( element ) ) {
857                                         return this.findByName( element.name ).filter( ":checked" ).length;
858                                 }
859                         }
860                         return value.length;
861                 },
862
863                 depend: function( param, element ) {
864                         return this.dependTypes[typeof param] ? this.dependTypes[typeof param]( param, element ) : true;
865                 },
866
867                 dependTypes: {
868                         "boolean": function( param ) {
869                                 return param;
870                         },
871                         "string": function( param, element ) {
872                                 return !!$( param, element.form ).length;
873                         },
874                         "function": function( param, element ) {
875                                 return param( element );
876                         }
877                 },
878
879                 optional: function( element ) {
880                         var val = this.elementValue( element );
881                         return !$.validator.methods.required.call( this, val, element ) && "dependency-mismatch";
882                 },
883
884                 startRequest: function( element ) {
885                         if ( !this.pending[ element.name ] ) {
886                                 this.pendingRequest++;
887                                 this.pending[ element.name ] = true;
888                         }
889                 },
890
891                 stopRequest: function( element, valid ) {
892                         this.pendingRequest--;
893                         // sometimes synchronization fails, make sure pendingRequest is never < 0
894                         if ( this.pendingRequest < 0 ) {
895                                 this.pendingRequest = 0;
896                         }
897                         delete this.pending[ element.name ];
898                         if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) {
899                                 $( this.currentForm ).submit();
900                                 this.formSubmitted = false;
901                         } else if (!valid && this.pendingRequest === 0 && this.formSubmitted ) {
902                                 $( this.currentForm ).triggerHandler( "invalid-form", [ this ]);
903                                 this.formSubmitted = false;
904                         }
905                 },
906
907                 previousValue: function( element ) {
908                         return $.data( element, "previousValue" ) || $.data( element, "previousValue", {
909                                 old: null,
910                                 valid: true,
911                                 message: this.defaultMessage( element, "remote" )
912                         });
913                 }
914
915         },
916
917         classRuleSettings: {
918                 required: { required: true },
919                 email: { email: true },
920                 url: { url: true },
921                 date: { date: true },
922                 dateISO: { dateISO: true },
923                 number: { number: true },
924                 digits: { digits: true },
925                 creditcard: { creditcard: true }
926         },
927
928         addClassRules: function( className, rules ) {
929                 if ( className.constructor === String ) {
930                         this.classRuleSettings[ className ] = rules;
931                 } else {
932                         $.extend( this.classRuleSettings, className );
933                 }
934         },
935
936         classRules: function( element ) {
937                 var rules = {},
938                         classes = $( element ).attr( "class" );
939
940                 if ( classes ) {
941                         $.each( classes.split( " " ), function() {
942                                 if ( this in $.validator.classRuleSettings ) {
943                                         $.extend( rules, $.validator.classRuleSettings[ this ]);
944                                 }
945                         });
946                 }
947                 return rules;
948         },
949
950         attributeRules: function( element ) {
951                 var rules = {},
952                         $element = $( element ),
953                         type = element.getAttribute( "type" ),
954                         method, value;
955
956                 for ( method in $.validator.methods ) {
957
958                         // support for <input required> in both html5 and older browsers
959                         if ( method === "required" ) {
960                                 value = element.getAttribute( method );
961                                 // Some browsers return an empty string for the required attribute
962                                 // and non-HTML5 browsers might have required="" markup
963                                 if ( value === "" ) {
964                                         value = true;
965                                 }
966                                 // force non-HTML5 browsers to return bool
967                                 value = !!value;
968                         } else {
969                                 value = $element.attr( method );
970                         }
971
972                         // convert the value to a number for number inputs, and for text for backwards compability
973                         // allows type="date" and others to be compared as strings
974                         if ( /min|max/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) {
975                                 value = Number( value );
976                         }
977
978                         if ( value || value === 0 ) {
979                                 rules[ method ] = value;
980                         } else if ( type === method && type !== "range" ) {
981                                 // exception: the jquery validate 'range' method
982                                 // does not test for the html5 'range' type
983                                 rules[ method ] = true;
984                         }
985                 }
986
987                 // maxlength may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs
988                 if ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) {
989                         delete rules.maxlength;
990                 }
991
992                 return rules;
993         },
994
995         dataRules: function( element ) {
996                 var method, value,
997                         rules = {}, $element = $( element );
998                 for ( method in $.validator.methods ) {
999                         value = $element.data( "rule" + method.charAt( 0 ).toUpperCase() + method.substring( 1 ).toLowerCase() );
1000                         if ( value !== undefined ) {
1001                                 rules[ method ] = value;
1002                         }
1003                 }
1004                 return rules;
1005         },
1006
1007         staticRules: function( element ) {
1008                 var rules = {},
1009                         validator = $.data( element.form, "validator" );
1010
1011                 if ( validator.settings.rules ) {
1012                         rules = $.validator.normalizeRule( validator.settings.rules[ element.name ] ) || {};
1013                 }
1014                 return rules;
1015         },
1016
1017         normalizeRules: function( rules, element ) {
1018                 // handle dependency check
1019                 $.each( rules, function( prop, val ) {
1020                         // ignore rule when param is explicitly false, eg. required:false
1021                         if ( val === false ) {
1022                                 delete rules[ prop ];
1023                                 return;
1024                         }
1025                         if ( val.param || val.depends ) {
1026                                 var keepRule = true;
1027                                 switch ( typeof val.depends ) {
1028                                 case "string":
1029                                         keepRule = !!$( val.depends, element.form ).length;
1030                                         break;
1031                                 case "function":
1032                                         keepRule = val.depends.call( element, element );
1033                                         break;
1034                                 }
1035                                 if ( keepRule ) {
1036                                         rules[ prop ] = val.param !== undefined ? val.param : true;
1037                                 } else {
1038                                         delete rules[ prop ];
1039                                 }
1040                         }
1041                 });
1042
1043                 // evaluate parameters
1044                 $.each( rules, function( rule, parameter ) {
1045                         rules[ rule ] = $.isFunction( parameter ) ? parameter( element ) : parameter;
1046                 });
1047
1048                 // clean number parameters
1049                 $.each([ "minlength", "maxlength" ], function() {
1050                         if ( rules[ this ] ) {
1051                                 rules[ this ] = Number( rules[ this ] );
1052                         }
1053                 });
1054                 $.each([ "rangelength", "range" ], function() {
1055                         var parts;
1056                         if ( rules[ this ] ) {
1057                                 if ( $.isArray( rules[ this ] ) ) {
1058                                         rules[ this ] = [ Number( rules[ this ][ 0 ]), Number( rules[ this ][ 1 ] ) ];
1059                                 } else if ( typeof rules[ this ] === "string" ) {
1060                                         parts = rules[ this ].replace(/[\[\]]/g, "" ).split( /[\s,]+/ );
1061                                         rules[ this ] = [ Number( parts[ 0 ]), Number( parts[ 1 ] ) ];
1062                                 }
1063                         }
1064                 });
1065
1066                 if ( $.validator.autoCreateRanges ) {
1067                         // auto-create ranges
1068                         if ( rules.min && rules.max ) {
1069                                 rules.range = [ rules.min, rules.max ];
1070                                 delete rules.min;
1071                                 delete rules.max;
1072                         }
1073                         if ( rules.minlength && rules.maxlength ) {
1074                                 rules.rangelength = [ rules.minlength, rules.maxlength ];
1075                                 delete rules.minlength;
1076                                 delete rules.maxlength;
1077                         }
1078                 }
1079
1080                 return rules;
1081         },
1082
1083         // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
1084         normalizeRule: function( data ) {
1085                 if ( typeof data === "string" ) {
1086                         var transformed = {};
1087                         $.each( data.split( /\s/ ), function() {
1088                                 transformed[ this ] = true;
1089                         });
1090                         data = transformed;
1091                 }
1092                 return data;
1093         },
1094
1095         // http://jqueryvalidation.org/jQuery.validator.addMethod/
1096         addMethod: function( name, method, message ) {
1097                 $.validator.methods[ name ] = method;
1098                 $.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ];
1099                 if ( method.length < 3 ) {
1100                         $.validator.addClassRules( name, $.validator.normalizeRule( name ) );
1101                 }
1102         },
1103
1104         methods: {
1105
1106                 // http://jqueryvalidation.org/required-method/
1107                 required: function( value, element, param ) {
1108                         // check if dependency is met
1109                         if ( !this.depend( param, element ) ) {
1110                                 return "dependency-mismatch";
1111                         }
1112                         if ( element.nodeName.toLowerCase() === "select" ) {
1113                                 // could be an array for select-multiple or a string, both are fine this way
1114                                 var val = $( element ).val();
1115                                 return val && val.length > 0;
1116                         }
1117                         if ( this.checkable( element ) ) {
1118                                 return this.getLength( value, element ) > 0;
1119                         }
1120                         return $.trim( value ).length > 0;
1121                 },
1122
1123                 // http://jqueryvalidation.org/email-method/
1124                 email: function( value, element ) {
1125                         // From http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#e-mail-state-%28type=email%29
1126                         // Retrieved 2014-01-14
1127                         // If you have a problem with this implementation, report a bug against the above spec
1128                         // Or use custom methods to implement your own email validation
1129                         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 );
1130                 },
1131
1132                 // http://jqueryvalidation.org/url-method/
1133                 url: function( value, element ) {
1134                         // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
1135                         return this.optional( element ) || /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test( value );
1136                 },
1137
1138                 // http://jqueryvalidation.org/date-method/
1139                 date: function( value, element ) {
1140                         return this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() );
1141                 },
1142
1143                 // http://jqueryvalidation.org/dateISO-method/
1144                 dateISO: function( value, element ) {
1145                         return this.optional( element ) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test( value );
1146                 },
1147
1148                 // http://jqueryvalidation.org/number-method/
1149                 number: function( value, element ) {
1150                         return this.optional( element ) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test( value );
1151                 },
1152
1153                 // http://jqueryvalidation.org/digits-method/
1154                 digits: function( value, element ) {
1155                         return this.optional( element ) || /^\d+$/.test( value );
1156                 },
1157
1158                 // http://jqueryvalidation.org/creditcard-method/
1159                 // based on http://en.wikipedia.org/wiki/Luhn/
1160                 creditcard: function( value, element ) {
1161                         if ( this.optional( element ) ) {
1162                                 return "dependency-mismatch";
1163                         }
1164                         // accept only spaces, digits and dashes
1165                         if ( /[^0-9 \-]+/.test( value ) ) {
1166                                 return false;
1167                         }
1168                         var nCheck = 0,
1169                                 nDigit = 0,
1170                                 bEven = false,
1171                                 n, cDigit;
1172
1173                         value = value.replace( /\D/g, "" );
1174
1175                         // Basing min and max length on
1176                         // http://developer.ean.com/general_info/Valid_Credit_Card_Types
1177                         if ( value.length < 13 || value.length > 19 ) {
1178                                 return false;
1179                         }
1180
1181                         for ( n = value.length - 1; n >= 0; n--) {
1182                                 cDigit = value.charAt( n );
1183                                 nDigit = parseInt( cDigit, 10 );
1184                                 if ( bEven ) {
1185                                         if ( ( nDigit *= 2 ) > 9 ) {
1186                                                 nDigit -= 9;
1187                                         }
1188                                 }
1189                                 nCheck += nDigit;
1190                                 bEven = !bEven;
1191                         }
1192
1193                         return ( nCheck % 10 ) === 0;
1194                 },
1195
1196                 // http://jqueryvalidation.org/minlength-method/
1197                 minlength: function( value, element, param ) {
1198                         var length = $.isArray( value ) ? value.length : this.getLength( $.trim( value ), element );
1199                         return this.optional( element ) || length >= param;
1200                 },
1201
1202                 // http://jqueryvalidation.org/maxlength-method/
1203                 maxlength: function( value, element, param ) {
1204                         var length = $.isArray( value ) ? value.length : this.getLength( $.trim( value ), element );
1205                         return this.optional( element ) || length <= param;
1206                 },
1207
1208                 // http://jqueryvalidation.org/rangelength-method/
1209                 rangelength: function( value, element, param ) {
1210                         var length = $.isArray( value ) ? value.length : this.getLength( $.trim( value ), element );
1211                         return this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] );
1212                 },
1213
1214                 // http://jqueryvalidation.org/min-method/
1215                 min: function( value, element, param ) {
1216                         return this.optional( element ) || value >= param;
1217                 },
1218
1219                 // http://jqueryvalidation.org/max-method/
1220                 max: function( value, element, param ) {
1221                         return this.optional( element ) || value <= param;
1222                 },
1223
1224                 // http://jqueryvalidation.org/range-method/
1225                 range: function( value, element, param ) {
1226                         return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] );
1227                 },
1228
1229                 // http://jqueryvalidation.org/equalTo-method/
1230                 equalTo: function( value, element, param ) {
1231                         // bind to the blur event of the target in order to revalidate whenever the target field is updated
1232                         // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead
1233                         var target = $( param );
1234                         if ( this.settings.onfocusout ) {
1235                                 target.unbind( ".validate-equalTo" ).bind( "blur.validate-equalTo", function() {
1236                                         $( element ).valid();
1237                                 });
1238                         }
1239                         return value === target.val();
1240                 },
1241
1242                 // http://jqueryvalidation.org/remote-method/
1243                 remote: function( value, element, param ) {
1244                         if ( this.optional( element ) ) {
1245                                 return "dependency-mismatch";
1246                         }
1247
1248                         var previous = this.previousValue( element ),
1249                                 validator, data;
1250
1251                         if (!this.settings.messages[ element.name ] ) {
1252                                 this.settings.messages[ element.name ] = {};
1253                         }
1254                         previous.originalMessage = this.settings.messages[ element.name ].remote;
1255                         this.settings.messages[ element.name ].remote = previous.message;
1256
1257                         param = typeof param === "string" && { url: param } || param;
1258
1259                         if ( previous.old === value ) {
1260                                 return previous.valid;
1261                         }
1262
1263                         previous.old = value;
1264                         validator = this;
1265                         this.startRequest( element );
1266                         data = {};
1267                         data[ element.name ] = value;
1268                         $.ajax( $.extend( true, {
1269                                 url: param,
1270                                 mode: "abort",
1271                                 port: "validate" + element.name,
1272                                 dataType: "json",
1273                                 data: data,
1274                                 context: validator.currentForm,
1275                                 success: function( response ) {
1276                                         var valid = response === true || response === "true",
1277                                                 errors, message, submitted;
1278
1279                                         validator.settings.messages[ element.name ].remote = previous.originalMessage;
1280                                         if ( valid ) {
1281                                                 submitted = validator.formSubmitted;
1282                                                 validator.prepareElement( element );
1283                                                 validator.formSubmitted = submitted;
1284                                                 validator.successList.push( element );
1285                                                 delete validator.invalid[ element.name ];
1286                                                 validator.showErrors();
1287                                         } else {
1288                                                 errors = {};
1289                                                 message = response || validator.defaultMessage( element, "remote" );
1290                                                 errors[ element.name ] = previous.message = $.isFunction( message ) ? message( value ) : message;
1291                                                 validator.invalid[ element.name ] = true;
1292                                                 validator.showErrors( errors );
1293                                         }
1294                                         previous.valid = valid;
1295                                         validator.stopRequest( element, valid );
1296                                 }
1297                         }, param ) );
1298                         return "pending";
1299                 }
1300
1301         }
1302
1303 });
1304
1305 $.format = function deprecated() {
1306         throw "$.format has been deprecated. Please use $.validator.format instead.";
1307 };
1308
1309 // ajax mode: abort
1310 // usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
1311 // if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
1312
1313 var pendingRequests = {},
1314         ajax;
1315 // Use a prefilter if available (1.5+)
1316 if ( $.ajaxPrefilter ) {
1317         $.ajaxPrefilter(function( settings, _, xhr ) {
1318                 var port = settings.port;
1319                 if ( settings.mode === "abort" ) {
1320                         if ( pendingRequests[port] ) {
1321                                 pendingRequests[port].abort();
1322                         }
1323                         pendingRequests[port] = xhr;
1324                 }
1325         });
1326 } else {
1327         // Proxy ajax
1328         ajax = $.ajax;
1329         $.ajax = function( settings ) {
1330                 var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
1331                         port = ( "port" in settings ? settings : $.ajaxSettings ).port;
1332                 if ( mode === "abort" ) {
1333                         if ( pendingRequests[port] ) {
1334                                 pendingRequests[port].abort();
1335                         }
1336                         pendingRequests[port] = ajax.apply(this, arguments);
1337                         return pendingRequests[port];
1338                 }
1339                 return ajax.apply(this, arguments);
1340         };
1341 }
1342
1343 // provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
1344 // handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target
1345
1346 $.extend($.fn, {
1347         validateDelegate: function( delegate, type, handler ) {
1348                 return this.bind(type, function( event ) {
1349                         var target = $(event.target);
1350                         if ( target.is(delegate) ) {
1351                                 return handler.apply(target, arguments);
1352                         }
1353                 });
1354         }
1355 });
1356
1357 }));