PageSourceSearch

https://www.ataxia.org/wp-content/themes/ataxia/js/validate.js?ver=1.0

js ataxia.org collected 2026-09-24 08:42:34 UTC 82,398 bytes, 2,526 lines download raw bytes

1/*!
2 * jQuery Form Plugin
3 * version: 3.32.0-2013.04.09
4 * @requires jQuery v1.5 or later
5 * Copyright (c) 2013 M. Alsup
6 * Examples and documentation at: http://malsup.com/jquery/form/
7 * Project repository: https://github.com/malsup/form
8 * Dual licensed under the MIT and GPL licenses.
9 * https://github.com/malsup/form#copyright-and-license
10 */
11/*global ActiveXObject */
12;(function($) {
13"use strict";
14
15/*
16    Usage Note:
17    -----------
18    Do not use both ajaxSubmit and ajaxForm on the same form.  These
19    functions are mutually exclusive.  Use ajaxSubmit if you want
20    to bind your own submit handler to the form.  For example,
21
22    $(document).ready(function() {
23        $('#myForm').on('submit', function(e) {
24            e.preventDefault(); // <-- important
25            $(this).ajaxSubmit({
26                target: '#output'
27            });
28        });
29    });
30
31    Use ajaxForm when you want the plugin to manage all the event binding
32    for you.  For example,
33
34    $(document).ready(function() {
35        $('#myForm').ajaxForm({
36            target: '#output'
37        });
38    });
39
40    You can also use ajaxForm with delegation (requires jQuery v1.7+), so the
41    form does not have to exist when you invoke ajaxForm:
42
43    $('#myForm').ajaxForm({
44        delegation: true,
45        target: '#output'
46    });
47
48    When using ajaxForm, the ajaxSubmit function will be invoked for you
49    at the appropriate time.
50*/
51
52/**
53 * Feature detection
54 */
55var feature = {};
56feature.fileapi = $("<input type='file'/>").get(0).files !== undefined;
57feature.formdata = window.FormData !== undefined;
58
59var hasProp = !!$.fn.prop;
60
61// attr2 uses prop when it can but checks the return type for
62// an expected string.  this accounts for the case where a form 
63// contains inputs with names like "action" or "method"; in those
64// cases "prop" returns the element
65$.fn.attr2 = function() {
66    if ( ! hasProp )
67        return this.attr.apply(this, arguments);
68    var val = this.prop.apply(this, arguments);
69    if ( ( val && val.jquery ) || typeof val === 'string' )
70        return val;
71    return this.attr.apply(this, arguments);
72};
73
74/**
75 * ajaxSubmit() provides a mechanism for immediately submitting
76 * an HTML form using AJAX.
77 */
78$.fn.ajaxSubmit = function(options) {
79    /*jshint scripturl:true */
80
81    // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
82    if (!this.length) {
83        log('ajaxSubmit: skipping submit process - no element selected');
84        return this;
85    }
86
87    var method, action, url, $form = this;
88
89    if (typeof options == 'function') {
90        options = { success: options };
91    }
92
93    method = this.attr2('method');
94    action = this.attr2('action');
95
96    url = (typeof action === 'string') ? $.trim(action) : '';
97    url = url || window.location.href || '';
98    if (url) {
99        // clean url (don't include hash vaue)
100        url = (url.match(/^([^#]+)/)||[])[1];
101    }
102
103    options = $.extend(true, {
104        url:  url,
105        success: $.ajaxSettings.success,
106        type: method || 'GET',
107        iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
108    }, options);
109
110    // hook for manipulating the form data before it is extracted;
111    // convenient for use with rich editors like tinyMCE or FCKEditor
112    var veto = {};
113    this.trigger('form-pre-serialize', [this, options, veto]);
114    if (veto.veto) {
115        log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
116        return this;
117    }
118
119    // provide opportunity to alter form data before it is serialized
120    if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
121        log('ajaxSubmit: submit aborted via beforeSerialize callback');
122        return this;
123    }
124
125    var traditional = options.traditional;
126    if ( traditional === undefined ) {
127        traditional = $.ajaxSettings.traditional;
128    }
129
130    var elements = [];
131    var qx, a = this.formToArray(options.semantic, elements);
132    if (options.data) {
133        options.extraData = options.data;
134        qx = $.param(options.data, traditional);
135    }
136
137    // give pre-submit callback an opportunity to abort the submit
138    if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
139        log('ajaxSubmit: submit aborted via beforeSubmit callback');
140        return this;
141    }
142
143    // fire vetoable 'validate' event
144    this.trigger('form-submit-validate', [a, this, options, veto]);
145    if (veto.veto) {
146        log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
147        return this;
148    }
149
150    var q = $.param(a, traditional);
151    if (qx) {
152        q = ( q ? (q + '&' + qx) : qx );
153    }
154    if (options.type.toUpperCase() == 'GET') {
155        options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
156        options.data = null;  // data is null for 'get'
157    }
158    else {
159        options.data = q; // data is the query string for 'post'
160    }
161
162    var callbacks = [];
163    if (options.resetForm) {
164        callbacks.push(function() { $form.resetForm(); });
165    }
166    if (options.clearForm) {
167        callbacks.push(function() { $form.clearForm(options.includeHidden); });
168    }
169
170    // perform a load on the target only if dataType is not provided
171    if (!options.dataType && options.target) {
172        var oldSuccess = options.success || function(){};
173        callbacks.push(function(data) {
174            var fn = options.replaceTarget ? 'replaceWith' : 'html';
175            $(options.target)[fn](data).each(oldSuccess, arguments);
176        });
177    }
178    else if (options.success) {
179        callbacks.push(options.success);
180    }
181
182    options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
183        var context = options.context || this ;    // jQuery 1.4+ supports scope context
184        for (var i=0, max=callbacks.length; i < max; i++) {
185            callbacks[i].apply(context, [data, status, xhr || $form, $form]);
186        }
187    };
188
189    // are there files to upload?
190
191    // [value] (issue #113), also see comment:
192    // https://github.com/malsup/form/commit/588306aedba1de01388032d5f42a60159eea9228#commitcomment-2180219
193    var fileInputs = $('input[type=file]:enabled[value!=""]', this);
194
195    var hasFileInputs = fileInputs.length > 0;
196    var mp = 'multipart/form-data';
197    var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);
198
199    var fileAPI = feature.fileapi && feature.formdata;
200    log("fileAPI :" + fileAPI);
201    var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI;
202
203    var jqxhr;
204
205    // options.iframe allows user to force iframe mode
206    // 06-NOV-09: now defaulting to iframe mode if file input is detected
207    if (options.iframe !== false && (options.iframe || shouldUseFrame)) {
208        // hack to fix Safari hang (thanks to Tim Molendijk for this)
209        // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
210        if (options.closeKeepAlive) {
211            $.get(options.closeKeepAlive, function() {
212                jqxhr = fileUploadIframe(a);
213            });
214        }
215        else {
216            jqxhr = fileUploadIframe(a);
217        }
218    }
219    else if ((hasFileInputs || multipart) && fileAPI) {
220        jqxhr = fileUploadXhr(a);
221    }
222    else {
223        jqxhr = $.ajax(options);
224    }
225
226    $form.removeData('jqxhr').data('jqxhr', jqxhr);
227
228    // clear element array
229    for (var k=0; k < elements.length; k++)
230        elements[k] = null;
231
232    // fire 'notify' event
233    this.trigger('form-submit-notify', [this, options]);
234    return this;
235
236    // utility fn for deep serialization
237    function deepSerialize(extraData){
238        var serialized = $.param(extraData).split('&');
239        var len = serialized.length;
240        var result = [];
241        var i, part;
242        for (i=0; i < len; i++) {
243            // #252; undo param space replacement
244            serialized[i] = serialized[i].replace(/\+/g,' ');
245            part = serialized[i].split('=');
246            // #278; use array instead of object storage, favoring array serializations
247            result.push([decodeURIComponent(part[0]), decodeURIComponent(part[1])]);
248        }
249        return result;
250    }
251
252     // XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz)
253    function fileUploadXhr(a) {
254        var formdata = new FormData();
255
256        for (var i=0; i < a.length; i++) {
257            formdata.append(a[i].name, a[i].value);
258        }
259
260        if (options.extraData) {
261            var serializedData = deepSerialize(options.extraData);
262            for (i=0; i < serializedData.length; i++)
263                if (serializedData[i])
264                    formdata.append(serializedData[i][0], serializedData[i][1]);
265        }
266
267        options.data = null;
268
269        var s = $.extend(true, {}, $.ajaxSettings, options, {
270            contentType: false,
271            processData: false,
272            cache: false,
273            type: method || 'POST'
274        });
275
276        if (options.uploadProgress) {
277            // workaround because jqXHR does not expose upload property
278            s.xhr = function() {
279                var xhr = jQuery.ajaxSettings.xhr();
280                if (xhr.upload) {
281                    xhr.upload.addEventListener('progress', function(event) {
282                        var percent = 0;
283                        var position = event.loaded || event.position; /*event.position is deprecated*/
284                        var total = event.total;
285                        if (event.lengthComputable) {
286                            percent = Math.ceil(position / total * 100);
287                        }
288                        options.uploadProgress(event, position, total, percent);
289                    }, false);
290                }
291                return xhr;
292            };
293        }
294
295        s.data = null;
296            var beforeSend = s.beforeSend;
297            s.beforeSend = function(xhr, o) {
298                o.data = formdata;
299                if(beforeSend)
300                    beforeSend.call(this, xhr, o);
301        };
302        return $.ajax(s);
303    }
304
305    // private function for handling file uploads (hat tip to YAHOO!)
306    function fileUploadIframe(a) {
307        var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle;
308        var deferred = $.Deferred();
309
310        if (a) {
311            // ensure that every serialized input is still enabled
312            for (i=0; i < elements.length; i++) {
313                el = $(elements[i]);
314                if ( hasProp )
315                    el.prop('disabled', false);
316                else
317                    el.removeAttr('disabled');
318            }
319        }
320
321        s = $.extend(true, {}, $.ajaxSettings, options);
322        s.context = s.context || s;
323        id = 'jqFormIO' + (new Date().getTime());
324        if (s.iframeTarget) {
325            $io = $(s.iframeTarget);
326            n = $io.attr2('name');
327            if (!n)
328                 $io.attr2('name', id);
329            else
330                id = n;
331        }
332        else {
333            $io = $('<iframe name="' + id + '" src="'+ s.iframeSrc +'" />');
334            $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
335        }
336        io = $io[0];
337
338
339        xhr = { // mock object
340            aborted: 0,
341            responseText: null,
342            responseXML: null,
343            status: 0,
344            statusText: 'n/a',
345            getAllResponseHeaders: function() {},
346            getResponseHeader: function() {},
347            setRequestHeader: function() {},
348            abort: function(status) {
349                var e = (status === 'timeout' ? 'timeout' : 'aborted');
350                log('aborting upload... ' + e);
351                this.aborted = 1;
352
353                try { // #214, #257
354                    if (io.contentWindow.document.execCommand) {
355                        io.contentWindow.document.execCommand('Stop');
356                    }
357                }
358                catch(ignore) {}
359
360                $io.attr('src', s.iframeSrc); // abort op in progress
361                xhr.error = e;
362                if (s.error)
363                    s.error.call(s.context, xhr, e, status);
364                if (g)
365                    $.event.trigger("ajaxError", [xhr, s, e]);
366                if (s.complete)
367                    s.complete.call(s.context, xhr, e);
368            }
369        };
370
371        g = s.global;
372        // trigger ajax global events so that activity/block indicators work like normal
373        if (g && 0 === $.active++) {
374            $.event.trigger("ajaxStart");
375        }
376        if (g) {
377            $.event.trigger("ajaxSend", [xhr, s]);
378        }
379
380        if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
381            if (s.global) {
382                $.active--;
383            }
384            deferred.reject();
385            return deferred;
386        }
387        if (xhr.aborted) {
388            deferred.reject();
389            return deferred;
390        }
391
392        // add submitting element to data if we know it
393        sub = form.clk;
394        if (sub) {
395            n = sub.name;
396            if (n && !sub.disabled) {
397                s.extraData = s.extraData || {};
398                s.extraData[n] = sub.value;
399                if (sub.type == "image") {
400                    s.extraData[n+'.x'] = form.clk_x;
401                    s.extraData[n+'.y'] = form.clk_y;
402                }
403            }
404        }
405
406        var CLIENT_TIMEOUT_ABORT = 1;
407        var SERVER_ABORT = 2;
408                
409        function getDoc(frame) {
410            /* it looks like contentWindow or contentDocument do not
411             * carry the protocol property in ie8, when running under ssl
412             * frame.document is the only valid response document, since
413             * the protocol is know but not on the other two objects. strange?
414             * "Same origin policy" http://en.wikipedia.org/wiki/Same_origin_policy
415             */
416            
417            var doc = null;
418            
419            // IE8 cascading access check
420            try {
421                if (frame.contentWindow) {
422                    doc = frame.contentWindow.document;
423                }
424            } catch(err) {
425                // IE8 access denied under ssl & missing protocol
426                log('cannot get iframe.contentWindow document: ' + err);
427            }
428
429            if (doc) { // successful getting content
430                return doc;
431            }
432
433            try { // simply checking may throw in ie8 under ssl or mismatched protocol
434                doc = frame.contentDocument ? frame.contentDocument : frame.document;
435            } catch(err) {
436                // last attempt
437                log('cannot get iframe.contentDocument: ' + err);
438                doc = frame.document;
439            }
440            return doc;
441        }
442
443        // Rails CSRF hack (thanks to Yvan Barthelemy)
444        var csrf_token = $('meta[name=csrf-token]').attr('content');
445        var csrf_param = $('meta[name=csrf-param]').attr('content');
446        if (csrf_param && csrf_token) {
447            s.extraData = s.extraData || {};
448            s.extraData[csrf_param] = csrf_token;
449        }
450
451        // take a breath so that pending repaints get some cpu time before the upload starts
452        function doSubmit() {
453            // make sure form attrs are set
454            var t = $form.attr2('target'), a = $form.attr2('action');
455
456            // update form attrs in IE friendly way
457            form.setAttribute('target',id);
458            if (!method) {
459                form.setAttribute('method', 'POST');
460            }
461            if (a != s.url) {
462                form.setAttribute('action', s.url);
463            }
464
465            // ie borks in some cases when setting encoding
466            if (! s.skipEncodingOverride && (!method || /post/i.test(method))) {
467                $form.attr({
468                    encoding: 'multipart/form-data',
469                    enctype:  'multipart/form-data'
470                });
471            }
472
473            // support timout
474            if (s.timeout) {
475                timeoutHandle = setTimeout(function() { timedOut = true; cb(CLIENT_TIMEOUT_ABORT); }, s.timeout);
476            }
477
478            // look for server aborts
479            function checkState() {
480                try {
481                    var state = getDoc(io).readyState;
482                    log('state = ' + state);
483                    if (state && state.toLowerCase() == 'uninitialized')
484                        setTimeout(checkState,50);
485                }
486                catch(e) {
487                    log('Server abort: ' , e, ' (', e.name, ')');
488                    cb(SERVER_ABORT);
489                    if (timeoutHandle)
490                        clearTimeout(timeoutHandle);
491                    timeoutHandle = undefined;
492                }
493            }
494
495            // add "extra" data to form if provided in options
496            var extraInputs = [];
497            try {
498                if (s.extraData) {
499                    for (var n in s.extraData) {
500                        if (s.extraData.hasOwnProperty(n)) {
501                           // if using the $.param format that allows for multiple values with the same name
502                           if($.isPlainObject(s.extraData[n]) && s.extraData[n].hasOwnProperty('name') && s.extraData[n].hasOwnProperty('value')) {
503                               extraInputs.push(
504                               $('<input type="hidden" name="'+s.extraData[n].name+'">').val(s.extraData[n].value)
505                                   .appendTo(form)[0]);
506                           } else {
507                               extraInputs.push(
508                               $('<input type="hidden" name="'+n+'">').val(s.extraData[n])
509                                   .appendTo(form)[0]);
510                           }
511                        }
512                    }
513                }
514
515                if (!s.iframeTarget) {
516                    // add iframe to doc and submit the form
517                    $io.appendTo('body');
518                    if (io.attachEvent)
519                        io.attachEvent('onload', cb);
520                    else
521                        io.addEventListener('load', cb, false);
522                }
523                setTimeout(checkState,15);
524
525                try {
526                    form.submit();
527                } catch(err) {
528                    // just in case form has element with name/id of 'submit'
529                    var submitFn = document.createElement('form').submit;
530                    submitFn.apply(form);
531                }
532            }
533            finally {
534                // reset attrs and remove "extra" input elements
535                form.setAttribute('action',a);
536                if(t) {
537                    form.setAttribute('target', t);
538                } else {
539                    $form.removeAttr('target');
540                }
541                $(extraInputs).remove();
542            }
543        }
544
545        if (s.forceSync) {
546            doSubmit();
547        }
548        else {
549            setTimeout(doSubmit, 10); // this lets dom updates render
550        }
551
552        var data, doc, domCheckCount = 50, callbackProcessed;
553
554        function cb(e) {
555            if (xhr.aborted || callbackProcessed) {
556                return;
557            }
558            
559            doc = getDoc(io);
560            if(!doc) {
561                log('cannot access response document');
562                e = SERVER_ABORT;
563            }
564            if (e === CLIENT_TIMEOUT_ABORT && xhr) {
565                xhr.abort('timeout');
566                deferred.reject(xhr, 'timeout');
567                return;
568            }
569            else if (e == SERVER_ABORT && xhr) {
570                xhr.abort('server abort');
571                deferred.reject(xhr, 'error', 'server abort');
572                return;
573            }
574
575            if (!doc || doc.location.href == s.iframeSrc) {
576                // response not received yet
577                if (!timedOut)
578                    return;
579            }
580            if (io.detachEvent)
581                io.detachEvent('onload', cb);
582            else
583                io.removeEventListener('load', cb, false);
584
585            var status = 'success', errMsg;
586            try {
587                if (timedOut) {
588                    throw 'timeout';
589                }
590
591                var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
592                log('isXml='+isXml);
593                if (!isXml && window.opera && (doc.body === null || !doc.body.innerHTML)) {
594                    if (--domCheckCount) {
595                        // in some browsers (Opera) the iframe DOM is not always traversable when
596                        // the onload callback fires, so we loop a bit to accommodate
597                        log('requeing onLoad callback, DOM not available');
598                        setTimeout(cb, 250);
599                        return;
600                    }
601                    // let this fall through because server response could be an empty document
602                    //log('Could not access iframe DOM after mutiple tries.');
603                    //throw 'DOMException: not available';
604                }
605
606                //log('response detected');
607                var docRoot = doc.body ? doc.body : doc.documentElement;
608                xhr.responseText = docRoot ? docRoot.innerHTML : null;
609                xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
610                if (isXml)
611                    s.dataType = 'xml';
612                xhr.getResponseHeader = function(header){
613                    var headers = {'content-type': s.dataType};
614                    return headers[header];
615                };
616                // support for XHR 'status' & 'statusText' emulation :
617                if (docRoot) {
618                    xhr.status = Number( docRoot.getAttribute('status') ) || xhr.status;
619                    xhr.statusText = docRoot.getAttribute('statusText') || xhr.statusText;
620                }
621
622                var dt = (s.dataType || '').toLowerCase();
623                var scr = /(json|script|text)/.test(dt);
624                if (scr || s.textarea) {
625                    // see if user embedded response in textarea
626                    var ta = doc.getElementsByTagName('textarea')[0];
627                    if (ta) {
628                        xhr.responseText = ta.value;
629                        // support for XHR 'status' & 'statusText' emulation :
630                        xhr.status = Number( ta.getAttribute('status') ) || xhr.status;
631                        xhr.statusText = ta.getAttribute('statusText') || xhr.statusText;
632                    }
633                    else if (scr) {
634                        // account for browsers injecting pre around json response
635                        var pre = doc.getElementsByTagName('pre')[0];
636                        var b = doc.getElementsByTagName('body')[0];
637                        if (pre) {
638                            xhr.responseText = pre.textContent ? pre.textContent : pre.innerText;
639                        }
640                        else if (b) {
641                            xhr.responseText = b.textContent ? b.textContent : b.innerText;
642                        }
643                    }
644                }
645                else if (dt == 'xml' && !xhr.responseXML && xhr.responseText) {
646                    xhr.responseXML = toXml(xhr.responseText);
647                }
648
649                try {
650                    data = httpData(xhr, dt, s);
651                }
652                catch (err) {
653                    status = 'parsererror';
654                    xhr.error = errMsg = (err || status);
655                }
656            }
657            catch (err) {
658                log('error caught: ',err);
659                status = 'error';
660                xhr.error = errMsg = (err || status);
661            }
662
663            if (xhr.aborted) {
664                log('upload aborted');
665                status = null;
666            }
667
668            if (xhr.status) { // we've set xhr.status
669                status = (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) ? 'success' : 'error';
670            }
671
672            // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
673            if (status === 'success') {
674                if (s.success)
675                    s.success.call(s.context, data, 'success', xhr);
676                deferred.resolve(xhr.responseText, 'success', xhr);
677                if (g)
678                    $.event.trigger("ajaxSuccess", [xhr, s]);
679            }
680            else if (status) {
681                if (errMsg === undefined)
682                    errMsg = xhr.statusText;
683                if (s.error)
684                    s.error.call(s.context, xhr, status, errMsg);
685                deferred.reject(xhr, 'error', errMsg);
686                if (g)
687                    $.event.trigger("ajaxError", [xhr, s, errMsg]);
688            }
689
690            if (g)
691                $.event.trigger("ajaxComplete", [xhr, s]);
692
693            if (g && ! --$.active) {
694                $.event.trigger("ajaxStop");
695            }
696
697            if (s.complete)
698                s.complete.call(s.context, xhr, status);
699
700            callbackProcessed = true;
701            if (s.timeout)
702                clearTimeout(timeoutHandle);
703
704            // clean up
705            setTimeout(function() {
706                if (!s.iframeTarget)
707                    $io.remove();
708                xhr.responseXML = null;
709            }, 100);
710        }
711
712        var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+)
713            if (window.ActiveXObject) {
714                doc = new ActiveXObject('Microsoft.XMLDOM');
715                doc.async = 'false';
716                doc.loadXML(s);
717            }
718            else {
719                doc = (new DOMParser()).parseFromString(s, 'text/xml');
720            }
721            return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null;
722        };
723        var parseJSON = $.parseJSON || function(s) {
724            /*jslint evil:true */
725            return window['eval']('(' + s + ')');
726        };
727
728        var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4
729
730            var ct = xhr.getResponseHeader('content-type') || '',
731                xml = type === 'xml' || !type && ct.indexOf('xml') >= 0,
732                data = xml ? xhr.responseXML : xhr.responseText;
733
734            if (xml && data.documentElement.nodeName === 'parsererror') {
735                if ($.error)
736                    $.error('parsererror');
737            }
738            if (s && s.dataFilter) {
739                data = s.dataFilter(data, type);
740            }
741            if (typeof data === 'string') {
742                if (type === 'json' || !type && ct.indexOf('json') >= 0) {
743                    data = parseJSON(data);
744                } else if (type === "script" || !type && ct.indexOf("javascript") >= 0) {
745                    $.globalEval(data);
746                }
747            }
748            return data;
749        };
750
751        return deferred;
752    }
753};
754
755/**
756 * ajaxForm() provides a mechanism for fully automating form submission.
757 *
758 * The advantages of using this method instead of ajaxSubmit() are:
759 *
760 * 1: This method will include coordinates for <input type="image" /> elements (if the element
761 *    is used to submit the form).
762 * 2. This method will include the submit element's name/value data (for the element that was
763 *    used to submit the form).
764 * 3. This method binds the submit() method to the form for you.
765 *
766 * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely
767 * passes the options argument along after properly binding events for submit elements and
768 * the form itself.
769 */
770$.fn.ajaxForm = function(options) {
771    options = options || {};
772    options.delegation = options.delegation && $.isFunction($.fn.on);
773
774    // in jQuery 1.3+ we can fix mistakes with the ready state
775    if (!options.delegation && this.length === 0) {
776        var o = { s: this.selector, c: this.context };
777        if (!$.isReady && o.s) {
778            log('DOM not ready, queuing ajaxForm');
779            $(function() {
780                $(o.s,o.c).ajaxForm(options);
781            });
782            return this;
783        }
784        // is your DOM ready?  http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
785        log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
786        return this;
787    }
788
789    if ( options.delegation ) {
790        $(document)
791            .off('submit.form-plugin', this.selector, doAjaxSubmit)
792            .off('click.form-plugin', this.selector, captureSubmittingElement)
793            .on('submit.form-plugin', this.selector, options, doAjaxSubmit)
794            .on('click.form-plugin', this.selector, options, captureSubmittingElement);
795        return this;
796    }
797
798    return this.ajaxFormUnbind()
799        .bind('submit.form-plugin', options, doAjaxSubmit)
800        .bind('click.form-plugin', options, captureSubmittingElement);
801};
802
803// private event handlers
804function doAjaxSubmit(e) {
805    /*jshint validthis:true */
806    var options = e.data;
807    if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
808        e.preventDefault();
809        $(this).ajaxSubmit(options);
810    }
811}
812
813function captureSubmittingElement(e) {
814    /*jshint validthis:true */
815    var target = e.target;
816    var $el = $(target);
817    if (!($el.is("[type=submit],[type=image]"))) {
818        // is this a child element of the submit el?  (ex: a span within a button)
819        var t = $el.closest('[type=submit]');
820        if (t.length === 0) {
821            return;
822        }
823        target = t[0];
824    }
825    var form = this;
826    form.clk = target;
827    if (target.type == 'image') {
828        if (e.offsetX !== undefined) {
829            form.clk_x = e.offsetX;
830            form.clk_y = e.offsetY;
831        } else if (typeof $.fn.offset == 'function') {
832            var offset = $el.offset();
833            form.clk_x = e.pageX - offset.left;
834            form.clk_y = e.pageY - offset.top;
835        } else {
836            form.clk_x = e.pageX - target.offsetLeft;
837            form.clk_y = e.pageY - target.offsetTop;
838        }
839    }
840    // clear form vars
841    setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
842}
843
844
845// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
846$.fn.ajaxFormUnbind = function() {
847    return this.unbind('submit.form-plugin click.form-plugin');
848};
849
850/**
851 * formToArray() gathers form element data into an array of objects that can
852 * be passed to any of the following ajax functions: $.get, $.post, or load.
853 * Each object in the array has both a 'name' and 'value' property.  An example of
854 * an array for a simple login form might be:
855 *
856 * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
857 *
858 * It is this array that is passed to pre-submit callback functions provided to the
859 * ajaxSubmit() and ajaxForm() methods.
860 */
861$.fn.formToArray = function(semantic, elements) {
862    var a = [];
863    if (this.length === 0) {
864        return a;
865    }
866
867    var form = this[0];
868    var els = semantic ? form.getElementsByTagName('*') : form.elements;
869    if (!els) {
870        return a;
871    }
872
873    var i,j,n,v,el,max,jmax;
874    for(i=0, max=els.length; i < max; i++) {
875        el = els[i];
876        n = el.name;
877        if (!n || el.disabled) {
878            continue;
879        }
880
881        if (semantic && form.clk && el.type == "image") {
882            // handle image inputs on the fly when semantic == true
883            if(form.clk == el) {
884                a.push({name: n, value: $(el).val(), type: el.type });
885                a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
886            }
887            continue;
888        }
889
890        v = $.fieldValue(el, true);
891        if (v && v.constructor == Array) {
892            if (elements)
893                elements.push(el);
894            for(j=0, jmax=v.length; j < jmax; j++) {
895                a.push({name: n, value: v[j]});
896            }
897        }
898        else if (feature.fileapi && el.type == 'file') {
899            if (elements)
900                elements.push(el);
901            var files = el.files;
902            if (files.length) {
903                for (j=0; j < files.length; j++) {
904                    a.push({name: n, value: files[j], type: el.type});
905                }
906            }
907            else {
908                // #180
909                a.push({ name: n, value: '', type: el.type });
910            }
911        }
912        else if (v !== null && typeof v != 'undefined') {
913            if (elements)
914                elements.push(el);
915            a.push({name: n, value: v, type: el.type, required: el.required});
916        }
917    }
918
919    if (!semantic && form.clk) {
920        // input type=='image' are not found in elements array! handle it here
921        var $input = $(form.clk), input = $input[0];
922        n = input.name;
923        if (n && !input.disabled && input.type == 'image') {
924            a.push({name: n, value: $input.val()});
925            a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
926        }
927    }
928    return a;
929};
930
931/**
932 * Serializes form data into a 'submittable' string. This method will return a string
933 * in the format: name1=value1&amp;name2=value2
934 */
935$.fn.formSerialize = function(semantic) {
936    //hand off to jQuery.param for proper encoding
937    return $.param(this.formToArray(semantic));
938};
939
940/**
941 * Serializes all field elements in the jQuery object into a query string.
942 * This method will return a string in the format: name1=value1&amp;name2=value2
943 */
944$.fn.fieldSerialize = function(successful) {
945    var a = [];
946    this.each(function() {
947        var n = this.name;
948        if (!n) {
949            return;
950        }
951        var v = $.fieldValue(this, successful);
952        if (v && v.constructor == Array) {
953            for (var i=0,max=v.length; i < max; i++) {
954                a.push({name: n, value: v[i]});
955            }
956        }
957        else if (v !== null && typeof v != 'undefined') {
958            a.push({name: this.name, value: v});
959        }
960    });
961    //hand off to jQuery.param for proper encoding
962    return $.param(a);
963};
964
965/**
966 * Returns the value(s) of the element in the matched set.  For example, consider the following form:
967 *
968 *  <form><fieldset>
969 *      <input name="A" type="text" />
970 *      <input name="A" type="text" />
971 *      <input name="B" type="checkbox" value="B1" />
972 *      <input name="B" type="checkbox" value="B2"/>
973 *      <input name="C" type="radio" value="C1" />
974 *      <input name="C" type="radio" value="C2" />
975 *  </fieldset></form>
976 *
977 *  var v = $('input[type=text]').fieldValue();
978 *  // if no values are entered into the text inputs
979 *  v == ['','']
980 *  // if values entered into the text inputs are 'foo' and 'bar'
981 *  v == ['foo','bar']
982 *
983 *  var v = $('input[type=checkbox]').fieldValue();
984 *  // if neither checkbox is checked
985 *  v === undefined
986 *  // if both checkboxes are checked
987 *  v == ['B1', 'B2']
988 *
989 *  var v = $('input[type=radio]').fieldValue();
990 *  // if neither radio is checked
991 *  v === undefined
992 *  // if first radio is checked
993 *  v == ['C1']
994 *
995 * The successful argument controls whether or not the field element must be 'successful'
996 * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
997 * The default value of the successful argument is true.  If this value is false the value(s)
998 * for each element is returned.
999 *
1000 * Note: This method *always* returns an array.  If no valid value can be determined the
1001 *    array will be empty, otherwise it will contain one or more values.
1002 */
1003$.fn.fieldValue = function(successful) {
1004    for (var val=[], i=0, max=this.length; i < max; i++) {
1005        var el = this[i];
1006        var v = $.fieldValue(el, successful);
1007        if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) {
1008            continue;
1009        }
1010        if (v.constructor == Array)
1011            $.merge(val, v);
1012        else
1013            val.push(v);
1014    }
1015    return val;
1016};
1017
1018/**
1019 * Returns the value of the field element.
1020 */
1021$.fieldValue = function(el, successful) {
1022    var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
1023    if (successful === undefined) {
1024        successful = true;
1025    }
1026
1027    if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
1028        (t == 'checkbox' || t == 'radio') && !el.checked ||
1029        (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
1030        tag == 'select' && el.selectedIndex == -1)) {
1031            return null;
1032    }
1033
1034    if (tag == 'select') {
1035        var index = el.selectedIndex;
1036        if (index < 0) {
1037            return null;
1038        }
1039        var a = [], ops = el.options;
1040        var one = (t == 'select-one');
1041        var max = (one ? index+1 : ops.length);
1042        for(var i=(one ? index : 0); i < max; i++) {
1043            var op = ops[i];
1044            if (op.selected) {
1045                var v = op.value;
1046                if (!v) { // extra pain for IE...
1047                    v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
1048                }
1049                if (one) {
1050                    return v;
1051                }
1052                a.push(v);
1053            }
1054        }
1055        return a;
1056    }
1057    return $(el).val();
1058};
1059
1060/**
1061 * Clears the form data.  Takes the following actions on the form's input fields:
1062 *  - input text fields will have their 'value' property set to the empty string
1063 *  - select elements will have their 'selectedIndex' property set to -1
1064 *  - checkbox and radio inputs will have their 'checked' property set to false
1065 *  - inputs of type submit, button, reset, and hidden will *not* be effected
1066 *  - button elements will *not* be effected
1067 */
1068$.fn.clearForm = function(includeHidden) {
1069    return this.each(function() {
1070        $('input,select,textarea', this).clearFields(includeHidden);
1071    });
1072};
1073
1074/**
1075 * Clears the selected form elements.
1076 */
1077$.fn.clearFields = $.fn.clearInputs = function(includeHidden) {
1078    var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list
1079    return this.each(function() {
1080        var t = this.type, tag = this.tagName.toLowerCase();
1081        if (re.test(t) || tag == 'textarea') {
1082            this.value = '';
1083        }
1084        else if (t == 'checkbox' || t == 'radio') {
1085            this.checked = false;
1086        }
1087        else if (tag == 'select') {
1088            this.selectedIndex = -1;
1089        }
1090		else if (t == "file") {
1091			if (/MSIE/.test(navigator.userAgent)) {
1092				$(this).replaceWith($(this).clone(true));
1093			} else {
1094				$(this).val('');
1095			}
1096		}
1097        else if (includeHidden) {
1098            // includeHidden can be the value true, or it can be a selector string
1099            // indicating a special test; for example:
1100            //  $('#myForm').clearForm('.special:hidden')
1101            // the above would clean hidden inputs that have the class of 'special'
1102            if ( (includeHidden === true && /hidden/.test(t)) ||
1103                 (typeof includeHidden == 'string' && $(this).is(includeHidden)) )
1104                this.value = '';
1105        }
1106    });
1107};
1108
1109/**
1110 * Resets the form data.  Causes all form elements to be reset to their original value.
1111 */
1112$.fn.resetForm = function() {
1113    return this.each(function() {
1114        // guard against an input with the name of 'reset'
1115        // note that IE reports the reset function as an 'object'
1116        if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) {
1117            this.reset();
1118        }
1119    });
1120};
1121
1122/**
1123 * Enables or disables any matching elements.
1124 */
1125$.fn.enable = function(b) {
1126    if (b === undefined) {
1127        b = true;
1128    }
1129    return this.each(function() {
1130        this.disabled = !b;
1131    });
1132};
1133
1134/**
1135 * Checks/unchecks any matching checkboxes or radio buttons and
1136 * selects/deselects and matching option elements.
1137 */
1138$.fn.selected = function(select) {
1139    if (select === undefined) {
1140        select = true;
1141    }
1142    return this.each(function() {
1143        var t = this.type;
1144        if (t == 'checkbox' || t == 'radio') {
1145            this.checked = select;
1146        }
1147        else if (this.tagName.toLowerCase() == 'option') {
1148            var $sel = $(this).parent('select');
1149            if (select && $sel[0] && $sel[0].type == 'select-one') {
1150                // deselect all other options
1151                $sel.find('option').selected(false);
1152            }
1153            this.selected = select;
1154        }
1155    });
1156};
1157
1158// expose debug var
1159$.fn.ajaxSubmit.debug = false;
1160
1161// helper fn for console logging
1162function log() {
1163    if (!$.fn.ajaxSubmit.debug)
1164        return;
1165    var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
1166    if (window.console && window.console.log) {
1167        window.console.log(msg);
1168    }
1169    else if (window.opera && window.opera.postError) {
1170        window.opera.postError(msg);
1171    }
1172}
1173
1174})(jQuery);
1175
1176
1177
1178
1179/*!
1180 * jQuery Validation Plugin v1.12.0
1181 *
1182 * http://jqueryvalidation.org/
1183 *
1184 * Copyright (c) 2014 Jörn Zaefferer
1185 * Released under the MIT license
1186 */
1187(function($) {
1188
1189$.extend($.fn, {
1190	// http://jqueryvalidation.org/validate/
1191	validate: function( options ) {
1192
1193		// if nothing is selected, return nothing; can't chain anyway
1194		if ( !this.length ) {
1195			if ( options && options.debug && window.console ) {
1196				console.warn( "Nothing selected, can't validate, returning nothing." );
1197			}
1198			return;
1199		}
1200
1201		// check if a validator for this form was already created
1202		var validator = $.data( this[0], "validator" );
1203		if ( validator ) {
1204			return validator;
1205		}
1206
1207		// Add novalidate tag if HTML5.
1208		this.attr( "novalidate", "novalidate" );
1209
1210		validator = new $.validator( options, this[0] );
1211		$.data( this[0], "validator", validator );
1212
1213		if ( validator.settings.onsubmit ) {
1214
1215			this.validateDelegate( ":submit", "click", function( event ) {
1216				if ( validator.settings.submitHandler ) {
1217					validator.submitButton = event.target;
1218				}
1219				// allow suppressing validation by adding a cancel class to the submit button
1220				if ( $(event.target).hasClass("cancel") ) {
1221					validator.cancelSubmit = true;
1222				}
1223
1224				// allow suppressing validation by adding the html5 formnovalidate attribute to the submit button
1225				if ( $(event.target).attr("formnovalidate") !== undefined ) {
1226					validator.cancelSubmit = true;
1227				}
1228			});
1229
1230			// validate the form on submit
1231			this.submit( function( event ) {
1232				if ( validator.settings.debug ) {
1233					// prevent form submit to be able to see console output
1234					event.preventDefault();
1235				}
1236				function handle() {
1237					var hidden;
1238					if ( validator.settings.submitHandler ) {
1239						if ( validator.submitButton ) {
1240							// insert a hidden input as a replacement for the missing submit button
1241							hidden = $("<input type='hidden'/>").attr("name", validator.submitButton.name).val( $(validator.submitButton).val() ).appendTo(validator.currentForm);
1242						}
1243						validator.settings.submitHandler.call( validator, validator.currentForm, event );
1244						if ( validator.submitButton ) {
1245							// and clean up afterwards; thanks to no-block-scope, hidden can be referenced
1246							hidden.remove();
1247						}
1248						return false;
1249					}
1250					return true;
1251				}
1252
1253				// prevent submit for invalid forms or custom submit handlers
1254				if ( validator.cancelSubmit ) {
1255					validator.cancelSubmit = false;
1256					return handle();
1257				}
1258				if ( validator.form() ) {
1259					if ( validator.pendingRequest ) {
1260						validator.formSubmitted = true;
1261						return false;
1262					}
1263					return handle();
1264				} else {
1265					validator.focusInvalid();
1266					return false;
1267				}
1268			});
1269		}
1270
1271		return validator;
1272	},
1273	// http://jqueryvalidation.org/valid/
1274	valid: function() {
1275		var valid, validator;
1276
1277		if ( $(this[0]).is("form")) {
1278			valid = this.validate().form();
1279		} else {
1280			valid = true;
1281			validator = $(this[0].form).validate();
1282			this.each(function() {
1283				valid = validator.element(this) && valid;
1284			});
1285		}
1286		return valid;
1287	},
1288	// attributes: space separated list of attributes to retrieve and remove
1289	removeAttrs: function( attributes ) {
1290		var result = {},
1291			$element = this;
1292		$.each(attributes.split(/\s/), function( index, value ) {
1293			result[value] = $element.attr(value);
1294			$element.removeAttr(value);
1295		});
1296		return result;
1297	},
1298	// http://jqueryvalidation.org/rules/
1299	rules: function( command, argument ) {
1300		var element = this[0],
1301			settings, staticRules, existingRules, data, param, filtered;
1302
1303		if ( command ) {
1304			settings = $.data(element.form, "validator").settings;
1305			staticRules = settings.rules;
1306			existingRules = $.validator.staticRules(element);
1307			switch (command) {
1308			case "add":
1309				$.extend(existingRules, $.validator.normalizeRule(argument));
1310				// remove messages from rules, but allow them to be set separately
1311				delete existingRules.messages;
1312				staticRules[element.name] = existingRules;
1313				if ( argument.messages ) {
1314					settings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages );
1315				}
1316				break;
1317			case "remove":
1318				if ( !argument ) {
1319					delete staticRules[element.name];
1320					return existingRules;
1321				}
1322				filtered = {};
1323				$.each(argument.split(/\s/), function( index, method ) {
1324					filtered[method] = existingRules[method];
1325					delete existingRules[method];
1326					if ( method === "required" ) {
1327						$(element).removeAttr("aria-required");
1328					}
1329				});
1330				return filtered;
1331			}
1332		}
1333
1334		data = $.validator.normalizeRules(
1335		$.extend(
1336			{},
1337			$.validator.classRules(element),
1338			$.validator.attributeRules(element),
1339			$.validator.dataRules(element),
1340			$.validator.staticRules(element)
1341		), element);
1342
1343		// make sure required is at front
1344		if ( data.required ) {
1345			param = data.required;
1346			delete data.required;
1347			data = $.extend({ required: param }, data );
1348			$(element).attr( "aria-required", "true" );
1349		}
1350
1351		// make sure remote is at back
1352		if ( data.remote ) {
1353			param = data.remote;
1354			delete data.remote;
1355			data = $.extend( data, { remote: param });
1356		}
1357
1358		return data;
1359	}
1360});
1361
1362// Custom selectors
1363$.extend($.expr[":"], {
1364	// http://jqueryvalidation.org/blank-selector/
1365	blank: function( a ) { return !$.trim("" + $(a).val()); },
1366	// http://jqueryvalidation.org/filled-selector/
1367	filled: function( a ) { return !!$.trim("" + $(a).val()); },
1368	// http://jqueryvalidation.org/unchecked-selector/
1369	unchecked: function( a ) { return !$(a).prop("checked"); }
1370});
1371
1372// constructor for validator
1373$.validator = function( options, form ) {
1374	this.settings = $.extend( true, {}, $.validator.defaults, options );
1375	this.currentForm = form;
1376	this.init();
1377};
1378
1379// http://jqueryvalidation.org/jQuery.validator.format/
1380$.validator.format = function( source, params ) {
1381	if ( arguments.length === 1 ) {
1382		return function() {
1383			var args = $.makeArray(arguments);
1384			args.unshift(source);
1385			return $.validator.format.apply( this, args );
1386		};
1387	}
1388	if ( arguments.length > 2 && params.constructor !== Array  ) {
1389		params = $.makeArray(arguments).slice(1);
1390	}
1391	if ( params.constructor !== Array ) {
1392		params = [ params ];
1393	}
1394	$.each(params, function( i, n ) {
1395		source = source.replace( new RegExp("\\{" + i + "\\}", "g"), function() {
1396			return n;
1397		});
1398	});
1399	return source;
1400};
1401
1402$.extend($.validator, {
1403
1404	defaults: {
1405		messages: {},
1406		groups: {},
1407		rules: {},
1408		errorClass: "error",
1409		validClass: "valid",
1410		errorElement: "label",
1411		focusInvalid: true,
1412		errorContainer: $([]),
1413		errorLabelContainer: $([]),
1414		onsubmit: true,
1415		ignore: ":hidden",
1416		ignoreTitle: false,
1417		onfocusin: function( element ) {
1418			this.lastActive = element;
1419
1420			// hide error label and remove error class on focus if enabled
1421			if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {
1422				if ( this.settings.unhighlight ) {
1423					this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.val
1423idClass );
1424				}
1425				this.addWrapper(this.errorsFor(element)).hide();
1426			}
1427		},
1428		onfocusout: function( element ) {
1429			if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) {
1430				this.element(element);
1431			}
1432		},
1433		onkeyup: function( element, event ) {
1434			if ( event.which === 9 && this.elementValue(element) === "" ) {
1435				return;
1436			} else if ( element.name in this.submitted || element === this.lastElement ) {
1437				this.element(element);
1438			}
1439		},
1440		onclick: function( element ) {
1441			// click on selects, radiobuttons and checkboxes
1442			if ( element.name in this.submitted ) {
1443				this.element(element);
1444
1445			// or option elements, check parent select in that case
1446			} else if ( element.parentNode.name in this.submitted ) {
1447				this.element(element.parentNode);
1448			}
1449		},
1450		highlight: function( element, errorClass, validClass ) {
1451			if ( element.type === "radio" ) {
1452				this.findByName(element.name).addClass(errorClass).removeClass(validClass);
1453			} else {
1454				$(element).addClass(errorClass).removeClass(validClass);
1455			}
1456		},
1457		unhighlight: function( element, errorClass, validClass ) {
1458			if ( element.type === "radio" ) {
1459				this.findByName(element.name).removeClass(errorClass).addClass(validClass);
1460			} else {
1461				$(element).removeClass(errorClass).addClass(validClass);
1462			}
1463		}
1464	},
1465
1466	// http://jqueryvalidation.org/jQuery.validator.setDefaults/
1467	setDefaults: function( settings ) {
1468		$.extend( $.validator.defaults, settings );
1469	},
1470
1471	messages: {
1472		required: "This field is required.",
1473		remote: "Please fix this field.",
1474		email: "Please enter a valid email address.",
1475		url: "Please enter a valid URL.",
1476		date: "Please enter a valid date.",
1477		dateISO: "Please enter a valid date (ISO).",
1478		number: "Please enter a valid number.",
1479		digits: "Please enter only digits.",
1480		creditcard: "Please enter a valid credit card number.",
1481		equalTo: "Please enter the same value again.",
1482		maxlength: $.validator.format("Please enter no more than {0} characters."),
1483		minlength: $.validator.format("Please enter at least {0} characters."),
1484		rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."),
1485		range: $.validator.format("Please enter a value between {0} and {1}."),
1486		max: $.validator.format("Please enter a value less than or equal to {0}."),
1487		min: $.validator.format("Please enter a value greater than or equal to {0}.")
1488	},
1489
1490	autoCreateRanges: false,
1491
1492	prototype: {
1493
1494		init: function() {
1495			this.labelContainer = $(this.settings.errorLabelContainer);
1496			this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm);
1497			this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer );
1498			this.submitted = {};
1499			this.valueCache = {};
1500			this.pendingRequest = 0;
1501			this.pending = {};
1502			this.invalid = {};
1503			this.reset();
1504
1505			var groups = (this.groups = {}),
1506				rules;
1507			$.each(this.settings.groups, function( key, value ) {
1508				if ( typeof value === "string" ) {
1509					value = value.split(/\s/);
1510				}
1511				$.each(value, function( index, name ) {
1512					groups[name] = key;
1513				});
1514			});
1515			rules = this.settings.rules;
1516			$.each(rules, function( key, value ) {
1517				rules[key] = $.validator.normalizeRule(value);
1518			});
1519
1520			function delegate(event) {
1521				var validator = $.data(this[0].form, "validator"),
1522					eventType = "on" + event.type.replace(/^validate/, ""),
1523					settings = validator.settings;
1524				if ( settings[eventType] && !this.is( settings.ignore ) ) {
1525					settings[eventType].call(validator, this[0], event);
1526				}
1527			}
1528			$(this.currentForm)
1529				.validateDelegate(":text, [type='password'], [type='file'], select, textarea, " +
1530					"[type='number'], [type='search'] ,[type='tel'], [type='url'], " +
1531					"[type='email'], [type='datetime'], [type='date'], [type='month'], " +
1532					"[type='week'], [type='time'], [type='datetime-local'], " +
1533					"[type='range'], [type='color'] ",
1534					"focusin focusout keyup", delegate)
1535				.validateDelegate("[type='radio'], [type='checkbox'], select, option", "click", delegate);
1536
1537			if ( this.settings.invalidHandler ) {
1538				$(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);
1539			}
1540
1541			// Add aria-required to any Static/Data/Class required fields before first validation
1542			// Screen readers require this attribute to be present before the initial submission http://www.w3.org/TR/WCAG-TECHS/ARIA2.html
1543			$(this.currentForm).find("[required], [data-rule-required], .required").attr("aria-required", "true");
1544		},
1545
1546		// http://jqueryvalidation.org/Validator.form/
1547		form: function() {
1548			this.checkForm();
1549			$.extend(this.submitted, this.errorMap);
1550			this.invalid = $.extend({}, this.errorMap);
1551			if ( !this.valid() ) {
1552				$(this.currentForm).triggerHandler("invalid-form", [ this ]);
1553			}
1554			this.showErrors();
1555			return this.valid();
1556		},
1557
1558		checkForm: function() {
1559			this.prepareForm();
1560			for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) {
1561				this.check( elements[i] );
1562			}
1563			return this.valid();
1564		},
1565
1566		// http://jqueryvalidation.org/Validator.element/
1567		element: function( element ) {
1568			var cleanElement = this.clean( element ),
1569				checkElement = this.validationTargetFor( cleanElement ),
1570				result = true;
1571
1572			this.lastElement = checkElement;
1573
1574			if ( checkElement === undefined ) {
1575				delete this.invalid[ cleanElement.name ];
1576			} else {
1577				this.prepareElement( checkElement );
1578				this.currentElements = $( checkElement );
1579
1580				result = this.check( checkElement ) !== false;
1581				if (result) {
1582					delete this.invalid[checkElement.name];
1583				} else {
1584					this.invalid[checkElement.name] = true;
1585				}
1586			}
1587			// Add aria-invalid status for screen readers
1588			$( element ).attr( "aria-invalid", !result );
1589
1590			if ( !this.numberOfInvalids() ) {
1591				// Hide error containers on last error
1592				this.toHide = this.toHide.add( this.containers );
1593			}
1594			this.showErrors();
1595			return result;
1596		},
1597
1598		// http://jqueryvalidation.org/Validator.showErrors/
1599		showErrors: function( errors ) {
1600			if ( errors ) {
1601				// add items to error list and map
1602				$.extend( this.errorMap, errors );
1603				this.errorList = [];
1604				for ( var name in errors ) {
1605					this.errorList.push({
1606						message: errors[name],
1607						element: this.findByName(name)[0]
1608					});
1609				}
1610				// remove items from success list
1611				this.successList = $.grep( this.successList, function( element ) {
1612					return !(element.name in errors);
1613				});
1614			}
1615			if ( this.settings.showErrors ) {
1616				this.settings.showErrors.call( this, this.errorMap, this.errorList );
1617			} else {
1618				this.defaultShowErrors();
1619			}
1620		},
1621
1622		// http://jqueryvalidation.org/Validator.resetForm/
1623		resetForm: function() {
1624			if ( $.fn.resetForm ) {
1625				$(this.currentForm).resetForm();
1626			}
1627			this.submitted = {};
1628			this.lastElement = null;
1629			this.prepareForm();
1630			this.hideErrors();
1631			this.elements()
1632					.removeClass( this.settings.errorClass )
1633					.removeData( "previousValue" )
1634					.removeAttr( "aria-invalid" );
1635		},
1636
1637		numberOfInvalids: function() {
1638			return this.objectLength(this.invalid);
1639		},
1640
1641		objectLength: function( obj ) {
1642			/* jshint unused: false */
1643			var count = 0,
1644				i;
1645			for ( i in obj ) {
1646				count++;
1647			}
1648			return count;
1649		},
1650
1651		hideErrors: function() {
1652			this.addWrapper( this.toHide ).hide();
1653		},
1654
1655		valid: function() {
1656			return this.size() === 0;
1657		},
1658
1659		size: function() {
1660			return this.errorList.length;
1661		},
1662
1663		focusInvalid: function() {
1664			if ( this.settings.focusInvalid ) {
1665				try {
1666					$(this.findLastActive() || this.errorList.length && this.errorList[0].element || [])
1667					.filter(":visible")
1668					.focus()
1669					// manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
1670					.trigger("focusin");
1671				} catch(e) {
1672					// ignore IE throwing errors when focusing hidden elements
1673				}
1674			}
1675		},
1676
1677		findLastActive: function() {
1678			var lastActive = this.lastActive;
1679			return lastActive && $.grep(this.errorList, function( n ) {
1680				return n.element.name === lastActive.name;
1681			}).length === 1 && lastActive;
1682		},
1683
1684		elements: function() {
1685			var validator = this,
1686				rulesCache = {};
1687
1688			// select all valid inputs inside the form (no submit or reset buttons)
1689			return $(this.currentForm)
1690			.find("input, select, textarea")
1691			.not(":submit, :reset, :image, [disabled]")
1692			.not( this.settings.ignore )
1693			.filter(function() {
1694				if ( !this.name && validator.settings.debug && window.console ) {
1695					console.error( "%o has no name assigned", this);
1696				}
1697
1698				// select only the first element for each name, and only those with rules specified
1699				if ( this.name in rulesCache || !validator.objectLength($(this).rules()) ) {
1700					return false;
1701				}
1702
1703				rulesCache[this.name] = true;
1704				return true;
1705			});
1706		},
1707
1708		clean: function( selector ) {
1709			return $(selector)[0];
1710		},
1711
1712		errors: function() {
1713			var errorClass = this.settings.errorClass.split(" ").join(".");
1714			return $(this.settings.errorElement + "." + errorClass, this.errorContext);
1715		},
1716
1717		reset: function() {
1718			this.successList = [];
1719			this.errorList = [];
1720			this.errorMap = {};
1721			this.toShow = $([]);
1722			this.toHide = $([]);
1723			this.currentElements = $([]);
1724		},
1725
1726		prepareForm: function() {
1727			this.reset();
1728			this.toHide = this.errors().add( this.containers );
1729		},
1730
1731		prepareElement: function( element ) {
1732			this.reset();
1733			this.toHide = this.errorsFor(element);
1734		},
1735
1736		elementValue: function( element ) {
1737			var val,
1738				$element = $(element),
1739				type = $element.attr("type");
1740
1741			if ( type === "radio" || type === "checkbox" ) {
1742				return $("input[name='" + $element.attr("name") + "']:checked").val();
1743			}
1744
1745			val = $element.val();
1746			if ( typeof val === "string" ) {
1747				return val.replace(/\r/g, "");
1748			}
1749			return val;
1750		},
1751
1752		check: function( element ) {
1753			element = this.validationTargetFor( this.clean( element ) );
1754
1755			var rules = $(element).rules(),
1756				rulesCount = $.map( rules, function(n, i) {
1757					return i;
1758				}).length,
1759				dependencyMismatch = false,
1760				val = this.elementValue(element),
1761				result, method, rule;
1762
1763			for (method in rules ) {
1764				rule = { method: method, parameters: rules[method] };
1765				try {
1766
1767					result = $.validator.methods[method].call( this, val, element, rule.parameters );
1768
1769					// if a method indicates that the field is optional and therefore valid,
1770					// don't mark it as valid when there are no other rules
1771					if ( result === "dependency-mismatch" && rulesCount === 1 ) {
1772						dependencyMismatch = true;
1773						continue;
1774					}
1775					dependencyMismatch = false;
1776
1777					if ( result === "pending" ) {
1778						this.toHide = this.toHide.not( this.errorsFor(element) );
1779						return;
1780					}
1781
1782					if ( !result ) {
1783						this.formatAndAdd( element, rule );
1784						return false;
1785					}
1786				} catch(e) {
1787					if ( this.settings.debug && window.console ) {
1788						console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e );
1789					}
1790					throw e;
1791				}
1792			}
1793			if ( dependencyMismatch ) {
1794				return;
1795			}
1796			if ( this.objectLength(rules) ) {
1797				this.successList.push(element);
1798			}
1799			return true;
1800		},
1801
1802		// return the custom message for the given element and validation method
1803		// specified in the element's HTML5 data attribute
1804		// return the generic message if present and no method specific message is present
1805		customDataMessage: function( element, method ) {
1806			return $( element ).data( "msg" + method[ 0 ].toUpperCase() +
1807				method.substring( 1 ).toLowerCase() ) || $( element ).data("msg");
1808		},
1809
1810		// return the custom message for the given element name and validation method
1811		customMessage: function( name, method ) {
1812			var m = this.settings.messages[name];
1813			return m && (m.constructor === String ? m : m[method]);
1814		},
1815
1816		// return the first defined argument, allowing empty strings
1817		findDefined: function() {
1818			for (var i = 0; i < arguments.length; i++) {
1819				if ( arguments[i] !== undefined ) {
1820					return arguments[i];
1821				}
1822			}
1823			return undefined;
1824		},
1825
1826		defaultMessage: function( element, method ) {
1827			return this.findDefined(
1828				this.customMessage( element.name, method ),
1829				this.customDataMessage( element, method ),
1830				// title is never undefined, so handle empty string as undefined
1831				!this.settings.ignoreTitle && element.title || undefined,
1832				$.validator.messages[method],
1833				"<strong>Warning: No message defined for " + element.name + "</strong>"
1834			);
1835		},
1836
1837		formatAndAdd: function( element, rule ) {
1838			var message = this.defaultMessage( element, rule.method ),
1839				theregex = /\$?\{(\d+)\}/g;
1840			if ( typeof message === "function" ) {
1841				message = message.call(this, rule.parameters, element);
1842			} else if (theregex.test(message)) {
1843				message = $.validator.format(message.replace(theregex, "{$1}"), rule.parameters);
1844			}
1845			this.errorList.push({
1846				message: message,
1847				element: element,
1848				method: rule.method
1849			});
1850
1851			this.errorMap[element.name] = message;
1852			this.submitted[element.name] = message;
1853		},
1854
1855		addWrapper: function( toToggle ) {
1856			if ( this.settings.wrapper ) {
1857				toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
1858			}
1859			return toToggle;
1860		},
1861
1862		defaultShowErrors: function() {
1863			var i, elements, error;
1864			for ( i = 0; this.errorList[i]; i++ ) {
1865				error = this.errorList[i];
1866				if ( this.settings.highlight ) {
1867					this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.val
1867idClass );
1868				}
1869				this.showLabel( error.element, error.message );
1870			}
1871			if ( this.errorList.length ) {
1872				this.toShow = this.toShow.add( this.containers );
1873			}
1874			if ( this.settings.success ) {
1875				for ( i = 0; this.successList[i]; i++ ) {
1876					this.showLabel( this.successList[i] );
1877				}
1878			}
1879			if ( this.settings.unhighlight ) {
1880				for ( i = 0, elements = this.validElements(); elements[i]; i++ ) {
1881					this.settings.unhighlight.call( this, elements[i], this.settings.errorClass, this.settings.validClass );
1882				}
1883			}
1884			this.toHide = this.toHide.not( this.toShow );
1885			this.hideErrors();
1886			this.addWrapper( this.toShow ).show();
1887		},
1888
1889		validElements: function() {
1890			return this.currentElements.not(this.invalidElements());
1891		},
1892
1893		invalidElements: function() {
1894			return $(this.errorList).map(function() {
1895				return this.element;
1896			});
1897		},
1898
1899		showLabel: function( element, message ) {
1900			var label = this.errorsFor( element );
1901			if ( label.length ) {
1902				// refresh error/success class
1903				label.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );
1904				// replace message on existing label
1905				label.html(message);
1906			} else {
1907				// create label
1908				label = $("<" + this.settings.errorElement + ">")
1909					.attr("for", this.idOrName(element))
1910					.addClass(this.settings.errorClass)
1911					.html(message || "");
1912				if ( this.settings.wrapper ) {
1913					// make sure the element is visible, even in IE
1914					// actually showing the wrapped element is handled elsewhere
1915					label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
1916				}
1917				if ( !this.labelContainer.append(label).length ) {
1918					if ( this.settings.errorPlacement ) {
1919						this.settings.errorPlacement(label, $(element) );
1920					} else {
1921						label.insertAfter(element);
1922					}
1923				}
1924			}
1925			if ( !message && this.settings.success ) {
1926				label.text("");
1927				if ( typeof this.settings.success === "string" ) {
1928					label.addClass( this.settings.success );
1929				} else {
1930					this.settings.success( label, element );
1931				}
1932			}
1933			this.toShow = this.toShow.add(label);
1934		},
1935
1936		errorsFor: function( element ) {
1937			var name = this.idOrName(element);
1938			return this.errors().filter(function() {
1939				return $(this).attr("for") === name;
1940			});
1941		},
1942
1943		idOrName: function( element ) {
1944			return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name);
1945		},
1946
1947		validationTargetFor: function( element ) {
1948			// if radio/checkbox, validate first element in group instead
1949			if ( this.checkable(element) ) {
1950				element = this.findByName( element.name ).not(this.settings.ignore)[0];
1951			}
1952			return element;
1953		},
1954
1955		checkable: function( element ) {
1956			return (/radio|checkbox/i).test(element.type);
1957		},
1958
1959		findByName: function( name ) {
1960			return $(this.currentForm).find("[name='" + name + "']");
1961		},
1962
1963		getLength: function( value, element ) {
1964			switch ( element.nodeName.toLowerCase() ) {
1965			case "select":
1966				return $("option:selected", element).length;
1967			case "input":
1968				if ( this.checkable( element) ) {
1969					return this.findByName(element.name).filter(":checked").length;
1970				}
1971			}
1972			return value.length;
1973		},
1974
1975		depend: function( param, element ) {
1976			return this.dependTypes[typeof param] ? this.dependTypes[typeof param](param, element) : true;
1977		},
1978
1979		dependTypes: {
1980			"boolean": function( param ) {
1981				return param;
1982			},
1983			"string": function( param, element ) {
1984				return !!$(param, element.form).length;
1985			},
1986			"function": function( param, element ) {
1987				return param(element);
1988			}
1989		},
1990
1991		optional: function( element ) {
1992			var val = this.elementValue(element);
1993			return !$.validator.methods.required.call(this, val, element) && "dependency-mismatch";
1994		},
1995
1996		startRequest: function( element ) {
1997			if ( !this.pending[element.name] ) {
1998				this.pendingRequest++;
1999				this.pending[element.name] = true;
2000			}
2001		},
2002
2003		stopRequest: function( element, valid ) {
2004			this.pendingRequest--;
2005			// sometimes synchronization fails, make sure pendingRequest is never < 0
2006			if ( this.pendingRequest < 0 ) {
2007				this.pendingRequest = 0;
2008			}
2009			delete this.pending[element.name];
2010			if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) {
2011				$(this.currentForm).submit();
2012				this.formSubmitted = false;
vendor: 9,086 bytes, lines 2013-2278
2013			} else if (!valid && this.pendingRequest === 0 && this.formSubmitted) {
2014				$(this.currentForm).triggerHandler("invalid-form", [ this ]);
2015				this.formSubmitted = false;
2016			}
2017		},
2018
2019		previousValue: function( element ) {
2020			return $.data(element, "previousValue") || $.data(element, "previousValue", {
2021				old: null,
2022				valid: true,
2023				message: this.defaultMessage( element, "remote" )
2024			});
2025		}
2026
2027	},
2028
2029	classRuleSettings: {
2030		required: { required: true },
2031		email: { email: true },
2032		url: { url: true },
2033		date: { date: true },
2034		dateISO: { dateISO: true },
2035		number: { number: true },
2036		digits: { digits: true },
2037		creditcard: { creditcard: true }
2038	},
2039
2040	addClassRules: function( className, rules ) {
2041		if ( className.constructor === String ) {
2042			this.classRuleSettings[className] = rules;
2043		} else {
2044			$.extend(this.classRuleSettings, className);
2045		}
2046	},
2047
2048	classRules: function( element ) {
2049		var rules = {},
2050			classes = $(element).attr("class");
2051
2052		if ( classes ) {
2053			$.each(classes.split(" "), function() {
2054				if ( this in $.validator.classRuleSettings ) {
2055					$.extend(rules, $.validator.classRuleSettings[this]);
2056				}
2057			});
2058		}
2059		return rules;
2060	},
2061
2062	attributeRules: function( element ) {
2063		var rules = {},
2064			$element = $(element),
2065			type = element.getAttribute("type"),
2066			method, value;
2067
2068		for (method in $.validator.methods) {
2069
2070			// support for <input required> in both html5 and older browsers
2071			if ( method === "required" ) {
2072				value = element.getAttribute(method);
2073				// Some browsers return an empty string for the required attribute
2074				// and non-HTML5 browsers might have required="" markup
2075				if ( value === "" ) {
2076					value = true;
2077				}
2078				// force non-HTML5 browsers to return bool
2079				value = !!value;
2080			} else {
2081				value = $element.attr(method);
2082			}
2083
2084			// convert the value to a number for number inputs, and for text for backwards compability
2085			// allows type="date" and others to be compared as strings
2086			if ( /min|max/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) {
2087				value = Number(value);
2088			}
2089
2090			if ( value || value === 0 ) {
2091				rules[method] = value;
2092			} else if ( type === method && type !== "range" ) {
2093				// exception: the jquery validate 'range' method
2094				// does not test for the html5 'range' type
2095				rules[method] = true;
2096			}
2097		}
2098
2099		// maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs
2100		if ( rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength) ) {
2101			delete rules.maxlength;
2102		}
2103
2104		return rules;
2105	},
2106
2107	dataRules: function( element ) {
2108		var method, value,
2109			rules = {}, $element = $( element );
2110		for ( method in $.validator.methods ) {
2111			value = $element.data( "rule" + method[ 0 ].toUpperCase() + method.substring( 1 ).toLowerCase() );
2112			if ( value !== undefined ) {
2113				rules[ method ] = value;
2114			}
2115		}
2116		return rules;
2117	},
2118
2119	staticRules: function( element ) {
2120		var rules = {},
2121			validator = $.data(element.form, "validator");
2122
2123		if ( validator.settings.rules ) {
2124			rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {};
2125		}
2126		return rules;
2127	},
2128
2129	normalizeRules: function( rules, element ) {
2130		// handle dependency check
2131		$.each(rules, function( prop, val ) {
2132			// ignore rule when param is explicitly false, eg. required:false
2133			if ( val === false ) {
2134				delete rules[prop];
2135				return;
2136			}
2137			if ( val.param || val.depends ) {
2138				var keepRule = true;
2139				switch (typeof val.depends) {
2140				case "string":
2141					keepRule = !!$(val.depends, element.form).length;
2142					break;
2143				case "function":
2144					keepRule = val.depends.call(element, element);
2145					break;
2146				}
2147				if ( keepRule ) {
2148					rules[prop] = val.param !== undefined ? val.param : true;
2149				} else {
2150					delete rules[prop];
2151				}
2152			}
2153		});
2154
2155		// evaluate parameters
2156		$.each(rules, function( rule, parameter ) {
2157			rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter;
2158		});
2159
2160		// clean number parameters
2161		$.each([ "minlength", "maxlength" ], function() {
2162			if ( rules[this] ) {
2163				rules[this] = Number(rules[this]);
2164			}
2165		});
2166		$.each([ "rangelength", "range" ], function() {
2167			var parts;
2168			if ( rules[this] ) {
2169				if ( $.isArray(rules[this]) ) {
2170					rules[this] = [ Number(rules[this][0]), Number(rules[this][1]) ];
2171				} else if ( typeof rules[this] === "string" ) {
2172					parts = rules[this].split(/[\s,]+/);
2173					rules[this] = [ Number(parts[0]), Number(parts[1]) ];
2174				}
2175			}
2176		});
2177
2178		if ( $.validator.autoCreateRanges ) {
2179			// auto-create ranges
2180			if ( rules.min && rules.max ) {
2181				rules.range = [ rules.min, rules.max ];
2182				delete rules.min;
2183				delete rules.max;
2184			}
2185			if ( rules.minlength && rules.maxlength ) {
2186				rules.rangelength = [ rules.minlength, rules.maxlength ];
2187				delete rules.minlength;
2188				delete rules.maxlength;
2189			}
2190		}
2191
2192		return rules;
2193	},
2194
2195	// Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
2196	normalizeRule: function( data ) {
2197		if ( typeof data === "string" ) {
2198			var transformed = {};
2199			$.each(data.split(/\s/), function() {
2200				transformed[this] = true;
2201			});
2202			data = transformed;
2203		}
2204		return data;
2205	},
2206
2207	// http://jqueryvalidation.org/jQuery.validator.addMethod/
2208	addMethod: function( name, method, message ) {
2209		$.validator.methods[name] = method;
2210		$.validator.messages[name] = message !== undefined ? message : $.validator.messages[name];
2211		if ( method.length < 3 ) {
2212			$.validator.addClassRules(name, $.validator.normalizeRule(name));
2213		}
2214	},
2215
2216	methods: {
2217
2218		// http://jqueryvalidation.org/required-method/
2219		required: function( value, element, param ) {
2220			// check if dependency is met
2221			if ( !this.depend(param, element) ) {
2222				return "dependency-mismatch";
2223			}
2224			if ( element.nodeName.toLowerCase() === "select" ) {
2225				// could be an array for select-multiple or a string, both are fine this way
2226				var val = $(element).val();
2227				return val && val.length > 0;
2228			}
2229			if ( this.checkable(element) ) {
2230				return this.getLength(value, element) > 0;
2231			}
2232			return $.trim(value).length > 0;
2233		},
2234
2235		// http://jqueryvalidation.org/email-method/
2236		email: function( value, element ) {
2237			// From http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#e-mail-state-%28type=email%29
2238			// Retrieved 2014-01-14
2239			// If you have a problem with this implementation, report a bug against the above spec
2240			// Or use custom methods to implement your own email validation
2241			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);
2242		},
2243
2244		// http://jqueryvalidation.org/url-method/
2245		url: function( value, element ) {
2246			// contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
2247			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);
2248		},
2249
2250		// http://jqueryvalidation.org/date-method/
2251		date: function( value, element ) {
2252			return this.optional(element) || !/Invalid|NaN/.test(new Date(value).toString());
2253		},
2254
2255		// http://jqueryvalidation.org/dateISO-method/
2256		dateISO: function( value, element ) {
2257			return this.optional(element) || /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(value);
2258		},
2259
2260		// http://jqueryvalidation.org/number-method/
2261		number: function( value, element ) {
2262			return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value);
2263		},
2264
2265		// http://jqueryvalidation.org/digits-method/
2266		digits: function( value, element ) {
2267			return this.optional(element) || /^\d+$/.test(value);
2268		},
2269
2270		// http://jqueryvalidation.org/creditcard-method/
2271		// based on http://en.wikipedia.org/wiki/Luhn/
2272		creditcard: function( value, element ) {
2273			if ( this.optional(element) ) {
2274				return "dependency-mismatch";
2275			}
2276			// accept only spaces, digits and dashes
2277			if ( /[^0-9 \-]+/.test(value) ) {
2278				return false;
2279			}
2280			var nCheck = 0,
2281				nDigit = 0,
2282				bEven = false,
2283				n, cDigit;
2284
2285			value = value.replace(/\D/g, "");
2286
2287			// Basing min and max length on
2288			// http://developer.ean.com/general_info/Valid_Credit_Card_Types
2289			if ( value.length < 13 || value.length > 19 ) {
2290				return false;
2291			}
2292
2293			for ( n = value.length - 1; n >= 0; n--) {
2294				cDigit = value.charAt(n);
2295				nDigit = parseInt(cDigit, 10);
2296				if ( bEven ) {
2297					if ( (nDigit *= 2) > 9 ) {
2298						nDigit -= 9;
2299					}
2300				}
2301				nCheck += nDigit;
2302				bEven = !bEven;
2303			}
2304
2305			return (nCheck % 10) === 0;
2306		},
2307
2308		// http://jqueryvalidation.org/minlength-method/
2309		minlength: function( value, element, param ) {
2310			var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element);
2311			return this.optional(element) || length >= param;
2312		},
2313
2314		// http://jqueryvalidation.org/maxlength-method/
2315		maxlength: function( value, element, param ) {
2316			var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element);
2317			return this.optional(element) || length <= param;
2318		},
2319
2320		// http://jqueryvalidation.org/rangelength-method/
2321		rangelength: function( value, element, param ) {
2322			var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element);
2323			return this.optional(element) || ( length >= param[0] && length <= param[1] );
2324		},
2325
2326		// http://jqueryvalidation.org/min-method/
2327		min: function( value, element, param ) {
2328			return this.optional(element) || value >= param;
2329		},
2330
2331		// http://jqueryvalidation.org/max-method/
2332		max: function( value, element, param ) {
2333			return this.optional(element) || value <= param;
2334		},
2335
2336		// http://jqueryvalidation.org/range-method/
2337		range: function( value, element, param ) {
2338			return this.optional(element) || ( value >= param[0] && value <= param[1] );
2339		},
2340
2341		// http://jqueryvalidation.org/equalTo-method/
2342		equalTo: function( value, element, param ) {
2343			// bind to the blur event of the target in order to revalidate whenever the target field is updated
2344			// TODO find a way to bind the event just once, avoiding the unbind-rebind overhead
2345			var target = $(param);
2346			if ( this.settings.onfocusout ) {
2347				target.unbind(".validate-equalTo").bind("blur.validate-equalTo", function() {
2348					$(element).valid();
2349				});
2350			}
2351			return value === target.val();
2352		},
2353
2354		// http://jqueryvalidation.org/remote-method/
2355		remote: function( value, element, param ) {
2356			if ( this.optional(element) ) {
2357				return "dependency-mismatch";
2358			}
2359
2360			var previous = this.previousValue(element),
2361				validator, data;
2362
2363			if (!this.settings.messages[element.name] ) {
2364				this.settings.messages[element.name] = {};
2365			}
2366			previous.originalMessage = this.settings.messages[element.name].remote;
2367			this.settings.messages[element.name].remote = previous.message;
2368
2369			param = typeof param === "string" && { url: param } || param;
2370
2371			if ( previous.old === value ) {
2372				return previous.valid;
2373			}
2374
2375			previous.old = value;
2376			validator = this;
2377			this.startRequest(element);
2378			data = {};
2379			data[element.name] = value;
2380			$.ajax($.extend(true, {
2381				url: param,
2382				mode: "abort",
2383				port: "validate" + element.name,
2384				dataType: "json",
2385				data: data,
2386				context: validator.currentForm,
2387				success: function( response ) {
2388					var valid = response === true || response === "true",
2389						errors, message, submitted;
2390
2391					validator.settings.messages[element.name].remote = previous.originalMessage;
2392					if ( valid ) {
2393						submitted = validator.formSubmitted;
2394						validator.prepareElement(element);
2395						validator.formSubmitted = submitted;
2396						validator.successList.push(element);
2397						delete validator.invalid[element.name];
2398						validator.showErrors();
2399					} else {
2400						errors = {};
2401						message = response || validator.defaultMessage( element, "remote" );
2402						errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message;
2403						validator.invalid[element.name] = true;
2404						validator.showErrors(errors);
2405					}
2406					previous.valid = valid;
2407					validator.stopRequest(element, valid);
2408				}
2409			}, param));
2410			return "pending";
2411		}
2412
2413	}
2414
2415});
2416
2417$.format = function deprecated() {
2418	throw "$.format has been deprecated. Please use $.validator.format instead.";
2419};
2420
2421}(jQuery));
2422
2423// ajax mode: abort
2424// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
2425// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
2426(function($) {
2427	var pendingRequests = {},
2428		ajax;
2429	// Use a prefilter if available (1.5+)
2430	if ( $.ajaxPrefilter ) {
2431		$.ajaxPrefilter(function( settings, _, xhr ) {
2432			var port = settings.port;
2433			if ( settings.mode === "abort" ) {
2434				if ( pendingRequests[port] ) {
2435					pendingRequests[port].abort();
2436				}
2437				pendingRequests[port] = xhr;
2438			}
2439		});
2440	} else {
2441		// Proxy ajax
2442		ajax = $.ajax;
2443		$.ajax = function( settings ) {
2444			var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
2445				port = ( "port" in settings ? settings : $.ajaxSettings ).port;
2446			if ( mode === "abort" ) {
2447				if ( pendingRequests[port] ) {
2448					pendingRequests[port].abort();
2449				}
2450				pendingRequests[port] = ajax.apply(this, arguments);
2451				return pendingRequests[port];
2452			}
2453			return ajax.apply(this, arguments);
2454		};
2455	}
2456}(jQuery));
2457
2458// provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
2459// handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target
2460(function($) {
2461	$.extend($.fn, {
2462		validateDelegate: function( delegate, type, handler ) {
2463			return this.bind(type, function( event ) {
2464				var target = $(event.target);
2465				if ( target.is(delegate) ) {
2466					return handler.apply(target, arguments);
2467				}
2468			});
2469		}
2470	});
2471}(jQuery));
2472
2473
2474
2475
2476
2477(function($) {
2478    $('#contact').validate({
2479        rules: {
2480            name: {
2481                required: true,
2482                minlength: 2
2483            },
2484            email: {
2485                required: true,
2486                email: true
2487            },
2488            message: {
2489                required: true
2490            }
2491        },
2492        messages: {
2493            name: {
2494                required: "Please, add your name.",
2495                minlength: "Your name must consist of at least 2 characters"
2496            },
2497            email: {
2498                required: "Please, add your e-mail address."
2499            },
2500            message: {
2501                required: "Please, add your message.",
2502                minlength: "Your message is too short."
2503            }
2504        },
2505        submitHandler: function(form) {
2506            $(form).ajaxSubmit({
2507                type:"POST",
2508                data: $(form).serialize(),
2509                url:"process.php",
2510                success: function() {
2511                    $('#contact :input').attr('disabled', 'disabled');
2512                    $('#contact').fadeTo( "slow", 0.15, function() {
2513                        $(this).find(':input').attr('disabled', 'disabled');
2514                        $(this).find('label').css('cursor','default');
2515                        $('#success').fadeIn();
2516                    });
2517                },
2518                error: function() {
2519                    $('#contact').fadeTo( "slow", 0.15, function() {
2520                        $('#error').fadeIn();
2521                    });
2522                }
2523            });
2524        }
2525    });
2526})(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.