Changeset 103620 in spip-zone


Ignore:
Timestamp:
Mar 27, 2017, 7:29:59 PM (3 years ago)
Author:
real3t@…
Message:

Petite mise à jour de jQuery (1.11.3 à 1.12.4) et jquery.form.js (3.51 à 4.10)

Location:
_plugins_/crayons
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • _plugins_/crayons/js/jquery.form.js

    r90326 r103620  
    11/*!
    22 * jQuery Form Plugin
    3  * version: 3.51.0-2014.06.20
    4  * Requires jQuery v1.5 or later
    5  * Copyright (c) 2014 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
     3 * version: 4.1.0
     4 * Requires jQuery v1.7 or later
     5 * Copyright 2017 Kevin Morris
     6 * Copyright 2006 M. Alsup
     7 * Project repository: https://github.com/jquery-form/form
     8 * Dual licensed under the MIT and LGPLv3 licenses.
     9 * https://github.com/jquery-form/form#license
    1010 */
    11 /*global ActiveXObject */
    12 
    13 // AMD support
     11/* global ActiveXObject */
     12
     13/* eslint-disable */
    1414(function (factory) {
    15     "use strict";
    16     if (typeof define === 'function' && define.amd) {
    17         // using AMD; register as anon module
    18         define(['jquery'], factory);
    19     } else {
    20         // no AMD; invoke directly
    21         factory( (typeof(jQuery) != 'undefined') ? jQuery : window.Zepto );
    22     }
    23 }
    24 
    25 (function($) {
    26 "use strict";
    27 
    28 /*
    29     Usage Note:
    30     -----------
    31     Do not use both ajaxSubmit and ajaxForm on the same form.  These
    32     functions are mutually exclusive.  Use ajaxSubmit if you want
    33     to bind your own submit handler to the form.  For example,
    34 
    35     $(document).ready(function() {
    36         $('#myForm').on('submit', function(e) {
    37             e.preventDefault(); // <-- important
    38             $(this).ajaxSubmit({
    39                 target: '#output'
    40             });
    41         });
    42     });
    43 
    44     Use ajaxForm when you want the plugin to manage all the event binding
    45     for you.  For example,
    46 
    47     $(document).ready(function() {
    48         $('#myForm').ajaxForm({
    49             target: '#output'
    50         });
    51     });
    52 
    53     You can also use ajaxForm with delegation (requires jQuery v1.7+), so the
    54     form does not have to exist when you invoke ajaxForm:
    55 
    56     $('#myForm').ajaxForm({
    57         delegation: true,
    58         target: '#output'
    59     });
    60 
    61     When using ajaxForm, the ajaxSubmit function will be invoked for you
    62     at the appropriate time.
    63 */
    64 
    65 /**
    66  * Feature detection
    67  */
    68 var feature = {};
    69 feature.fileapi = $("<input type='file'/>").get(0).files !== undefined;
    70 feature.formdata = window.FormData !== undefined;
    71 
    72 var hasProp = !!$.fn.prop;
    73 
    74 // attr2 uses prop when it can but checks the return type for
    75 // an expected string.  this accounts for the case where a form
    76 // contains inputs with names like "action" or "method"; in those
    77 // cases "prop" returns the element
    78 $.fn.attr2 = function() {
    79     if ( ! hasProp ) {
    80         return this.attr.apply(this, arguments);
    81     }
    82     var val = this.prop.apply(this, arguments);
    83     if ( ( val && val.jquery ) || typeof val === 'string' ) {
    84         return val;
    85     }
    86     return this.attr.apply(this, arguments);
    87 };
    88 
    89 /**
    90  * ajaxSubmit() provides a mechanism for immediately submitting
    91  * an HTML form using AJAX.
    92  */
    93 $.fn.ajaxSubmit = function(options) {
    94     /*jshint scripturl:true */
    95 
    96     // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
    97     if (!this.length) {
    98         log('ajaxSubmit: skipping submit process - no element selected');
    99         return this;
    100     }
    101 
    102     var method, action, url, $form = this;
    103 
    104     if (typeof options == 'function') {
    105         options = { success: options };
    106     }
    107     else if ( options === undefined ) {
    108         options = {};
    109     }
    110 
    111     method = options.type || this.attr2('method');
    112     action = options.url  || this.attr2('action');
    113 
    114     url = (typeof action === 'string') ? $.trim(action) : '';
    115     url = url || window.location.href || '';
    116     if (url) {
    117         // clean url (don't include hash vaue)
    118         url = (url.match(/^([^#]+)/)||[])[1];
    119     }
    120 
    121     options = $.extend(true, {
    122         url:  url,
    123         success: $.ajaxSettings.success,
    124         type: method || $.ajaxSettings.type,
    125         iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
    126     }, options);
    127 
    128     // hook for manipulating the form data before it is extracted;
    129     // convenient for use with rich editors like tinyMCE or FCKEditor
    130     var veto = {};
    131     this.trigger('form-pre-serialize', [this, options, veto]);
    132     if (veto.veto) {
    133         log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
    134         return this;
    135     }
    136 
    137     // provide opportunity to alter form data before it is serialized
    138     if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
    139         log('ajaxSubmit: submit aborted via beforeSerialize callback');
    140         return this;
    141     }
    142 
    143     var traditional = options.traditional;
    144     if ( traditional === undefined ) {
    145         traditional = $.ajaxSettings.traditional;
    146     }
    147 
    148     var elements = [];
    149     var qx, a = this.formToArray(options.semantic, elements);
    150     if (options.data) {
    151         options.extraData = options.data;
    152         qx = $.param(options.data, traditional);
    153     }
    154 
    155     // give pre-submit callback an opportunity to abort the submit
    156     if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
    157         log('ajaxSubmit: submit aborted via beforeSubmit callback');
    158         return this;
    159     }
    160 
    161     // fire vetoable 'validate' event
    162     this.trigger('form-submit-validate', [a, this, options, veto]);
    163     if (veto.veto) {
    164         log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
    165         return this;
    166     }
    167 
    168     var q = $.param(a, traditional);
    169     if (qx) {
    170         q = ( q ? (q + '&' + qx) : qx );
    171     }
    172     if (options.type.toUpperCase() == 'GET') {
    173         options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
    174         options.data = null;  // data is null for 'get'
    175     }
    176     else {
    177         options.data = q; // data is the query string for 'post'
    178     }
    179 
    180     var callbacks = [];
    181     if (options.resetForm) {
    182         callbacks.push(function() { $form.resetForm(); });
    183     }
    184     if (options.clearForm) {
    185         callbacks.push(function() { $form.clearForm(options.includeHidden); });
    186     }
    187 
    188     // perform a load on the target only if dataType is not provided
    189     if (!options.dataType && options.target) {
    190         var oldSuccess = options.success || function(){};
    191         callbacks.push(function(data) {
    192             var fn = options.replaceTarget ? 'replaceWith' : 'html';
    193             $(options.target)[fn](data).each(oldSuccess, arguments);
    194         });
    195     }
    196     else if (options.success) {
    197         callbacks.push(options.success);
    198     }
    199 
    200     options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
    201         var context = options.context || this ;    // jQuery 1.4+ supports scope context
    202         for (var i=0, max=callbacks.length; i < max; i++) {
    203             callbacks[i].apply(context, [data, status, xhr || $form, $form]);
    204         }
    205     };
    206 
    207     if (options.error) {
    208         var oldError = options.error;
    209         options.error = function(xhr, status, error) {
    210             var context = options.context || this;
    211             oldError.apply(context, [xhr, status, error, $form]);
    212         };
    213     }
    214 
    215      if (options.complete) {
    216         var oldComplete = options.complete;
    217         options.complete = function(xhr, status) {
    218             var context = options.context || this;
    219             oldComplete.apply(context, [xhr, status, $form]);
    220         };
    221     }
    222 
    223     // are there files to upload?
    224 
    225     // [value] (issue #113), also see comment:
    226     // https://github.com/malsup/form/commit/588306aedba1de01388032d5f42a60159eea9228#commitcomment-2180219
    227     var fileInputs = $('input[type=file]:enabled', this).filter(function() { return $(this).val() !== ''; });
    228 
    229     var hasFileInputs = fileInputs.length > 0;
    230     var mp = 'multipart/form-data';
    231     var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);
    232 
    233     var fileAPI = feature.fileapi && feature.formdata;
    234     log("fileAPI :" + fileAPI);
    235     var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI;
    236 
    237     var jqxhr;
    238 
    239     // options.iframe allows user to force iframe mode
    240     // 06-NOV-09: now defaulting to iframe mode if file input is detected
    241     if (options.iframe !== false && (options.iframe || shouldUseFrame)) {
    242         // hack to fix Safari hang (thanks to Tim Molendijk for this)
    243         // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
    244         if (options.closeKeepAlive) {
    245             $.get(options.closeKeepAlive, function() {
    246                 jqxhr = fileUploadIframe(a);
    247             });
    248         }
    249         else {
    250             jqxhr = fileUploadIframe(a);
    251         }
    252     }
    253     else if ((hasFileInputs || multipart) && fileAPI) {
    254         jqxhr = fileUploadXhr(a);
    255     }
    256     else {
    257         jqxhr = $.ajax(options);
    258     }
    259 
    260     $form.removeData('jqxhr').data('jqxhr', jqxhr);
    261 
    262     // clear element array
    263     for (var k=0; k < elements.length; k++) {
    264         elements[k] = null;
    265     }
    266 
    267     // fire 'notify' event
    268     this.trigger('form-submit-notify', [this, options]);
    269     return this;
    270 
    271     // utility fn for deep serialization
    272     function deepSerialize(extraData){
    273         var serialized = $.param(extraData, options.traditional).split('&');
    274         var len = serialized.length;
    275         var result = [];
    276         var i, part;
    277         for (i=0; i < len; i++) {
    278             // #252; undo param space replacement
    279             serialized[i] = serialized[i].replace(/\+/g,' ');
    280             part = serialized[i].split('=');
    281             // #278; use array instead of object storage, favoring array serializations
    282             result.push([decodeURIComponent(part[0]), decodeURIComponent(part[1])]);
    283         }
    284         return result;
    285     }
    286 
    287      // XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz)
    288     function fileUploadXhr(a) {
    289         var formdata = new FormData();
    290 
    291         for (var i=0; i < a.length; i++) {
    292             formdata.append(a[i].name, a[i].value);
    293         }
    294 
    295         if (options.extraData) {
    296             var serializedData = deepSerialize(options.extraData);
    297             for (i=0; i < serializedData.length; i++) {
    298                 if (serializedData[i]) {
    299                     formdata.append(serializedData[i][0], serializedData[i][1]);
    300                 }
    301             }
    302         }
    303 
    304         options.data = null;
    305 
    306         var s = $.extend(true, {}, $.ajaxSettings, options, {
    307             contentType: false,
    308             processData: false,
    309             cache: false,
    310             type: method || 'POST'
    311         });
    312 
    313         if (options.uploadProgress) {
    314             // workaround because jqXHR does not expose upload property
    315             s.xhr = function() {
    316                 var xhr = $.ajaxSettings.xhr();
    317                 if (xhr.upload) {
    318                     xhr.upload.addEventListener('progress', function(event) {
    319                         var percent = 0;
    320                         var position = event.loaded || event.position; /*event.position is deprecated*/
    321                         var total = event.total;
    322                         if (event.lengthComputable) {
    323                             percent = Math.ceil(position / total * 100);
    324                         }
    325                         options.uploadProgress(event, position, total, percent);
    326                     }, false);
    327                 }
    328                 return xhr;
    329             };
    330         }
    331 
    332         s.data = null;
    333         var beforeSend = s.beforeSend;
    334         s.beforeSend = function(xhr, o) {
    335             //Send FormData() provided by user
    336             if (options.formData) {
    337                 o.data = options.formData;
    338             }
    339             else {
    340                 o.data = formdata;
    341             }
    342             if(beforeSend) {
    343                 beforeSend.call(this, xhr, o);
    344             }
    345         };
    346         return $.ajax(s);
    347     }
    348 
    349     // private function for handling file uploads (hat tip to YAHOO!)
    350     function fileUploadIframe(a) {
    351         var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle;
    352         var deferred = $.Deferred();
    353 
    354         // #341
    355         deferred.abort = function(status) {
    356             xhr.abort(status);
    357         };
    358 
    359         if (a) {
    360             // ensure that every serialized input is still enabled
    361             for (i=0; i < elements.length; i++) {
    362                 el = $(elements[i]);
    363                 if ( hasProp ) {
    364                     el.prop('disabled', false);
    365                 }
    366                 else {
    367                     el.removeAttr('disabled');
    368                 }
    369             }
    370         }
    371 
    372         s = $.extend(true, {}, $.ajaxSettings, options);
    373         s.context = s.context || s;
    374         id = 'jqFormIO' + (new Date().getTime());
    375         if (s.iframeTarget) {
    376             $io = $(s.iframeTarget);
    377             n = $io.attr2('name');
    378             if (!n) {
    379                 $io.attr2('name', id);
    380             }
    381             else {
    382                 id = n;
    383             }
    384         }
    385         else {
    386             $io = $('<iframe name="' + id + '" src="'+ s.iframeSrc +'" />');
    387             $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
    388         }
    389         io = $io[0];
    390 
    391 
    392         xhr = { // mock object
    393             aborted: 0,
    394             responseText: null,
    395             responseXML: null,
    396             status: 0,
    397             statusText: 'n/a',
    398             getAllResponseHeaders: function() {},
    399             getResponseHeader: function() {},
    400             setRequestHeader: function() {},
    401             abort: function(status) {
    402                 var e = (status === 'timeout' ? 'timeout' : 'aborted');
    403                 log('aborting upload... ' + e);
    404                 this.aborted = 1;
    405 
    406                 try { // #214, #257
    407                     if (io.contentWindow.document.execCommand) {
    408                         io.contentWindow.document.execCommand('Stop');
    409                     }
    410                 }
    411                 catch(ignore) {}
    412 
    413                 $io.attr('src', s.iframeSrc); // abort op in progress
    414                 xhr.error = e;
    415                 if (s.error) {
    416                     s.error.call(s.context, xhr, e, status);
    417                 }
    418                 if (g) {
    419                     $.event.trigger("ajaxError", [xhr, s, e]);
    420                 }
    421                 if (s.complete) {
    422                     s.complete.call(s.context, xhr, e);
    423                 }
    424             }
    425         };
    426 
    427         g = s.global;
    428         // trigger ajax global events so that activity/block indicators work like normal
    429         if (g && 0 === $.active++) {
    430             $.event.trigger("ajaxStart");
    431         }
    432         if (g) {
    433             $.event.trigger("ajaxSend", [xhr, s]);
    434         }
    435 
    436         if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
    437             if (s.global) {
    438                 $.active--;
    439             }
    440             deferred.reject();
    441             return deferred;
    442         }
    443         if (xhr.aborted) {
    444             deferred.reject();
    445             return deferred;
    446         }
    447 
    448         // add submitting element to data if we know it
    449         sub = form.clk;
    450         if (sub) {
    451             n = sub.name;
    452             if (n && !sub.disabled) {
    453                 s.extraData = s.extraData || {};
    454                 s.extraData[n] = sub.value;
    455                 if (sub.type == "image") {
    456                     s.extraData[n+'.x'] = form.clk_x;
    457                     s.extraData[n+'.y'] = form.clk_y;
    458                 }
    459             }
    460         }
    461 
    462         var CLIENT_TIMEOUT_ABORT = 1;
    463         var SERVER_ABORT = 2;
    464                
    465         function getDoc(frame) {
    466             /* it looks like contentWindow or contentDocument do not
    467              * carry the protocol property in ie8, when running under ssl
    468              * frame.document is the only valid response document, since
    469              * the protocol is know but not on the other two objects. strange?
    470              * "Same origin policy" http://en.wikipedia.org/wiki/Same_origin_policy
    471              */
    472            
    473             var doc = null;
    474            
    475             // IE8 cascading access check
    476             try {
    477                 if (frame.contentWindow) {
    478                     doc = frame.contentWindow.document;
    479                 }
    480             } catch(err) {
    481                 // IE8 access denied under ssl & missing protocol
    482                 log('cannot get iframe.contentWindow document: ' + err);
    483             }
    484 
    485             if (doc) { // successful getting content
    486                 return doc;
    487             }
    488 
    489             try { // simply checking may throw in ie8 under ssl or mismatched protocol
    490                 doc = frame.contentDocument ? frame.contentDocument : frame.document;
    491             } catch(err) {
    492                 // last attempt
    493                 log('cannot get iframe.contentDocument: ' + err);
    494                 doc = frame.document;
    495             }
    496             return doc;
    497         }
    498 
    499         // Rails CSRF hack (thanks to Yvan Barthelemy)
    500         var csrf_token = $('meta[name=csrf-token]').attr('content');
    501         var csrf_param = $('meta[name=csrf-param]').attr('content');
    502         if (csrf_param && csrf_token) {
    503             s.extraData = s.extraData || {};
    504             s.extraData[csrf_param] = csrf_token;
    505         }
    506 
    507         // take a breath so that pending repaints get some cpu time before the upload starts
    508         function doSubmit() {
    509             // make sure form attrs are set
    510             var t = $form.attr2('target'),
    511                 a = $form.attr2('action'),
    512                 mp = 'multipart/form-data',
    513                 et = $form.attr('enctype') || $form.attr('encoding') || mp;
    514 
    515             // update form attrs in IE friendly way
    516             form.setAttribute('target',id);
    517             if (!method || /post/i.test(method) ) {
    518                 form.setAttribute('method', 'POST');
    519             }
    520             if (a != s.url) {
    521                 form.setAttribute('action', s.url);
    522             }
    523 
    524             // ie borks in some cases when setting encoding
    525             if (! s.skipEncodingOverride && (!method || /post/i.test(method))) {
    526                 $form.attr({
    527                     encoding: 'multipart/form-data',
    528                     enctype:  'multipart/form-data'
    529                 });
    530             }
    531 
    532             // support timout
    533             if (s.timeout) {
    534                 timeoutHandle = setTimeout(function() { timedOut = true; cb(CLIENT_TIMEOUT_ABORT); }, s.timeout);
    535             }
    536 
    537             // look for server aborts
    538             function checkState() {
    539                 try {
    540                     var state = getDoc(io).readyState;
    541                     log('state = ' + state);
    542                     if (state && state.toLowerCase() == 'uninitialized') {
    543                         setTimeout(checkState,50);
    544                     }
    545                 }
    546                 catch(e) {
    547                     log('Server abort: ' , e, ' (', e.name, ')');
    548                     cb(SERVER_ABORT);
    549                     if (timeoutHandle) {
    550                         clearTimeout(timeoutHandle);
    551                     }
    552                     timeoutHandle = undefined;
    553                 }
    554             }
    555 
    556             // add "extra" data to form if provided in options
    557             var extraInputs = [];
    558             try {
    559                 if (s.extraData) {
    560                     for (var n in s.extraData) {
    561                         if (s.extraData.hasOwnProperty(n)) {
    562                            // if using the $.param format that allows for multiple values with the same name
    563                            if($.isPlainObject(s.extraData[n]) && s.extraData[n].hasOwnProperty('name') && s.extraData[n].hasOwnProperty('value')) {
    564                                extraInputs.push(
    565                                $('<input type="hidden" name="'+s.extraData[n].name+'">').val(s.extraData[n].value)
    566                                    .appendTo(form)[0]);
    567                            } else {
    568                                extraInputs.push(
    569                                $('<input type="hidden" name="'+n+'">').val(s.extraData[n])
    570                                    .appendTo(form)[0]);
    571                            }
    572                         }
    573                     }
    574                 }
    575 
    576                 if (!s.iframeTarget) {
    577                     // add iframe to doc and submit the form
    578                     $io.appendTo('body');
    579                 }
    580                 if (io.attachEvent) {
    581                     io.attachEvent('onload', cb);
    582                 }
    583                 else {
    584                     io.addEventListener('load', cb, false);
    585                 }
    586                 setTimeout(checkState,15);
    587 
    588                 try {
    589                     form.submit();
    590                 } catch(err) {
    591                     // just in case form has element with name/id of 'submit'
    592                     var submitFn = document.createElement('form').submit;
    593                     submitFn.apply(form);
    594                 }
    595             }
    596             finally {
    597                 // reset attrs and remove "extra" input elements
    598                 form.setAttribute('action',a);
    599                 form.setAttribute('enctype', et); // #380
    600                 if(t) {
    601                     form.setAttribute('target', t);
    602                 } else {
    603                     $form.removeAttr('target');
    604                 }
    605                 $(extraInputs).remove();
    606             }
    607         }
    608 
    609         if (s.forceSync) {
    610             doSubmit();
    611         }
    612         else {
    613             setTimeout(doSubmit, 10); // this lets dom updates render
    614         }
    615 
    616         var data, doc, domCheckCount = 50, callbackProcessed;
    617 
    618         function cb(e) {
    619             if (xhr.aborted || callbackProcessed) {
    620                 return;
    621             }
    622            
    623             doc = getDoc(io);
    624             if(!doc) {
    625                 log('cannot access response document');
    626                 e = SERVER_ABORT;
    627             }
    628             if (e === CLIENT_TIMEOUT_ABORT && xhr) {
    629                 xhr.abort('timeout');
    630                 deferred.reject(xhr, 'timeout');
    631                 return;
    632             }
    633             else if (e == SERVER_ABORT && xhr) {
    634                 xhr.abort('server abort');
    635                 deferred.reject(xhr, 'error', 'server abort');
    636                 return;
    637             }
    638 
    639             if (!doc || doc.location.href == s.iframeSrc) {
    640                 // response not received yet
    641                 if (!timedOut) {
    642                     return;
    643                 }
    644             }
    645             if (io.detachEvent) {
    646                 io.detachEvent('onload', cb);
    647             }
    648             else {
    649                 io.removeEventListener('load', cb, false);
    650             }
    651 
    652             var status = 'success', errMsg;
    653             try {
    654                 if (timedOut) {
    655                     throw 'timeout';
    656                 }
    657 
    658                 var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
    659                 log('isXml='+isXml);
    660                 if (!isXml && window.opera && (doc.body === null || !doc.body.innerHTML)) {
    661                     if (--domCheckCount) {
    662                         // in some browsers (Opera) the iframe DOM is not always traversable when
    663                         // the onload callback fires, so we loop a bit to accommodate
    664                         log('requeing onLoad callback, DOM not available');
    665                         setTimeout(cb, 250);
    666                         return;
    667                     }
    668                     // let this fall through because server response could be an empty document
    669                     //log('Could not access iframe DOM after mutiple tries.');
    670                     //throw 'DOMException: not available';
    671                 }
    672 
    673                 //log('response detected');
    674                 var docRoot = doc.body ? doc.body : doc.documentElement;
    675                 xhr.responseText = docRoot ? docRoot.innerHTML : null;
    676                 xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
    677                 if (isXml) {
    678                     s.dataType = 'xml';
    679                 }
    680                 xhr.getResponseHeader = function(header){
    681                     var headers = {'content-type': s.dataType};
    682                     return headers[header.toLowerCase()];
    683                 };
    684                 // support for XHR 'status' & 'statusText' emulation :
    685                 if (docRoot) {
    686                     xhr.status = Number( docRoot.getAttribute('status') ) || xhr.status;
    687                     xhr.statusText = docRoot.getAttribute('statusText') || xhr.statusText;
    688                 }
    689 
    690                 var dt = (s.dataType || '').toLowerCase();
    691                 var scr = /(json|script|text)/.test(dt);
    692                 if (scr || s.textarea) {
    693                     // see if user embedded response in textarea
    694                     var ta = doc.getElementsByTagName('textarea')[0];
    695                     if (ta) {
    696                         xhr.responseText = ta.value;
    697                         // support for XHR 'status' & 'statusText' emulation :
    698                         xhr.status = Number( ta.getAttribute('status') ) || xhr.status;
    699                         xhr.statusText = ta.getAttribute('statusText') || xhr.statusText;
    700                     }
    701                     else if (scr) {
    702                         // account for browsers injecting pre around json response
    703                         var pre = doc.getElementsByTagName('pre')[0];
    704                         var b = doc.getElementsByTagName('body')[0];
    705                         if (pre) {
    706                             xhr.responseText = pre.textContent ? pre.textContent : pre.innerText;
    707                         }
    708                         else if (b) {
    709                             xhr.responseText = b.textContent ? b.textContent : b.innerText;
    710                         }
    711                     }
    712                 }
    713                 else if (dt == 'xml' && !xhr.responseXML && xhr.responseText) {
    714                     xhr.responseXML = toXml(xhr.responseText);
    715                 }
    716 
    717                 try {
    718                     data = httpData(xhr, dt, s);
    719                 }
    720                 catch (err) {
    721                     status = 'parsererror';
    722                     xhr.error = errMsg = (err || status);
    723                 }
    724             }
    725             catch (err) {
    726                 log('error caught: ',err);
    727                 status = 'error';
    728                 xhr.error = errMsg = (err || status);
    729             }
    730 
    731             if (xhr.aborted) {
    732                 log('upload aborted');
    733                 status = null;
    734             }
    735 
    736             if (xhr.status) { // we've set xhr.status
    737                 status = (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) ? 'success' : 'error';
    738             }
    739 
    740             // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
    741             if (status === 'success') {
    742                 if (s.success) {
    743                     s.success.call(s.context, data, 'success', xhr);
    744                 }
    745                 deferred.resolve(xhr.responseText, 'success', xhr);
    746                 if (g) {
    747                     $.event.trigger("ajaxSuccess", [xhr, s]);
    748                 }
    749             }
    750             else if (status) {
    751                 if (errMsg === undefined) {
    752                     errMsg = xhr.statusText;
    753                 }
    754                 if (s.error) {
    755                     s.error.call(s.context, xhr, status, errMsg);
    756                 }
    757                 deferred.reject(xhr, 'error', errMsg);
    758                 if (g) {
    759                     $.event.trigger("ajaxError", [xhr, s, errMsg]);
    760                 }
    761             }
    762 
    763             if (g) {
    764                 $.event.trigger("ajaxComplete", [xhr, s]);
    765             }
    766 
    767             if (g && ! --$.active) {
    768                 $.event.trigger("ajaxStop");
    769             }
    770 
    771             if (s.complete) {
    772                 s.complete.call(s.context, xhr, status);
    773             }
    774 
    775             callbackProcessed = true;
    776             if (s.timeout) {
    777                 clearTimeout(timeoutHandle);
    778             }
    779 
    780             // clean up
    781             setTimeout(function() {
    782                 if (!s.iframeTarget) {
    783                     $io.remove();
    784                 }
    785                 else { //adding else to clean up existing iframe response.
    786                     $io.attr('src', s.iframeSrc);
    787                 }
    788                 xhr.responseXML = null;
    789             }, 100);
    790         }
    791 
    792         var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+)
    793             if (window.ActiveXObject) {
    794                 doc = new ActiveXObject('Microsoft.XMLDOM');
    795                 doc.async = 'false';
    796                 doc.loadXML(s);
    797             }
    798             else {
    799                 doc = (new DOMParser()).parseFromString(s, 'text/xml');
    800             }
    801             return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null;
    802         };
    803         var parseJSON = $.parseJSON || function(s) {
    804             /*jslint evil:true */
    805             return window['eval']('(' + s + ')');
    806         };
    807 
    808         var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4
    809 
    810             var ct = xhr.getResponseHeader('content-type') || '',
    811                 xml = type === 'xml' || !type && ct.indexOf('xml') >= 0,
    812                 data = xml ? xhr.responseXML : xhr.responseText;
    813 
    814             if (xml && data.documentElement.nodeName === 'parsererror') {
    815                 if ($.error) {
    816                     $.error('parsererror');
    817                 }
    818             }
    819             if (s && s.dataFilter) {
    820                 data = s.dataFilter(data, type);
    821             }
    822             if (typeof data === 'string') {
    823                 if (type === 'json' || !type && ct.indexOf('json') >= 0) {
    824                     data = parseJSON(data);
    825                 } else if (type === "script" || !type && ct.indexOf("javascript") >= 0) {
    826                     $.globalEval(data);
    827                 }
    828             }
    829             return data;
    830         };
    831 
    832         return deferred;
    833     }
    834 };
    835 
    836 /**
    837  * ajaxForm() provides a mechanism for fully automating form submission.
    838  *
    839  * The advantages of using this method instead of ajaxSubmit() are:
    840  *
    841  * 1: This method will include coordinates for <input type="image" /> elements (if the element
    842  *    is used to submit the form).
    843  * 2. This method will include the submit element's name/value data (for the element that was
    844  *    used to submit the form).
    845  * 3. This method binds the submit() method to the form for you.
    846  *
    847  * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely
    848  * passes the options argument along after properly binding events for submit elements and
    849  * the form itself.
    850  */
    851 $.fn.ajaxForm = function(options) {
    852     options = options || {};
    853     options.delegation = options.delegation && $.isFunction($.fn.on);
    854 
    855     // in jQuery 1.3+ we can fix mistakes with the ready state
    856     if (!options.delegation && this.length === 0) {
    857         var o = { s: this.selector, c: this.context };
    858         if (!$.isReady && o.s) {
    859             log('DOM not ready, queuing ajaxForm');
    860             $(function() {
    861                 $(o.s,o.c).ajaxForm(options);
    862             });
    863             return this;
    864         }
    865         // is your DOM ready?  http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
    866         log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
    867         return this;
    868     }
    869 
    870     if ( options.delegation ) {
    871         $(document)
    872             .off('submit.form-plugin', this.selector, doAjaxSubmit)
    873             .off('click.form-plugin', this.selector, captureSubmittingElement)
    874             .on('submit.form-plugin', this.selector, options, doAjaxSubmit)
    875             .on('click.form-plugin', this.selector, options, captureSubmittingElement);
    876         return this;
    877     }
    878 
    879     return this.ajaxFormUnbind()
    880         .bind('submit.form-plugin', options, doAjaxSubmit)
    881         .bind('click.form-plugin', options, captureSubmittingElement);
    882 };
    883 
    884 // private event handlers
    885 function doAjaxSubmit(e) {
    886     /*jshint validthis:true */
    887     var options = e.data;
    888     if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
    889         e.preventDefault();
    890         $(e.target).ajaxSubmit(options); // #365
    891     }
    892 }
    893 
    894 function captureSubmittingElement(e) {
    895     /*jshint validthis:true */
    896     var target = e.target;
    897     var $el = $(target);
    898     if (!($el.is("[type=submit],[type=image]"))) {
    899         // is this a child element of the submit el?  (ex: a span within a button)
    900         var t = $el.closest('[type=submit]');
    901         if (t.length === 0) {
    902             return;
    903         }
    904         target = t[0];
    905     }
    906     var form = this;
    907     form.clk = target;
    908     if (target.type == 'image') {
    909         if (e.offsetX !== undefined) {
    910             form.clk_x = e.offsetX;
    911             form.clk_y = e.offsetY;
    912         } else if (typeof $.fn.offset == 'function') {
    913             var offset = $el.offset();
    914             form.clk_x = e.pageX - offset.left;
    915             form.clk_y = e.pageY - offset.top;
    916         } else {
    917             form.clk_x = e.pageX - target.offsetLeft;
    918             form.clk_y = e.pageY - target.offsetTop;
    919         }
    920     }
    921     // clear form vars
    922     setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
    923 }
    924 
    925 
    926 // ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
    927 $.fn.ajaxFormUnbind = function() {
    928     return this.unbind('submit.form-plugin click.form-plugin');
    929 };
    930 
    931 /**
    932  * formToArray() gathers form element data into an array of objects that can
    933  * be passed to any of the following ajax functions: $.get, $.post, or load.
    934  * Each object in the array has both a 'name' and 'value' property.  An example of
    935  * an array for a simple login form might be:
    936  *
    937  * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
    938  *
    939  * It is this array that is passed to pre-submit callback functions provided to the
    940  * ajaxSubmit() and ajaxForm() methods.
    941  */
    942 $.fn.formToArray = function(semantic, elements) {
    943     var a = [];
    944     if (this.length === 0) {
    945         return a;
    946     }
    947 
    948     var form = this[0];
    949     var formId = this.attr('id');
    950     var els = semantic ? form.getElementsByTagName('*') : form.elements;
    951     var els2;
    952 
    953     if (els && !/MSIE [678]/.test(navigator.userAgent)) { // #390
    954         els = $(els).get();  // convert to standard array
    955     }
    956 
    957     // #386; account for inputs outside the form which use the 'form' attribute
    958     if ( formId ) {
    959         els2 = $(':input[form="' + formId + '"]').get(); // hat tip @thet
    960         if ( els2.length ) {
    961             els = (els || []).concat(els2);
    962         }
    963     }
    964 
    965     if (!els || !els.length) {
    966         return a;
    967     }
    968 
    969     var i,j,n,v,el,max,jmax;
    970     for(i=0, max=els.length; i < max; i++) {
    971         el = els[i];
    972         n = el.name;
    973         if (!n || el.disabled) {
    974             continue;
    975         }
    976 
    977         if (semantic && form.clk && el.type == "image") {
    978             // handle image inputs on the fly when semantic == true
    979             if(form.clk == el) {
    980                 a.push({name: n, value: $(el).val(), type: el.type });
    981                 a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
    982             }
    983             continue;
    984         }
    985 
    986         v = $.fieldValue(el, true);
    987         if (v && v.constructor == Array) {
    988             if (elements) {
    989                 elements.push(el);
    990             }
    991             for(j=0, jmax=v.length; j < jmax; j++) {
    992                 a.push({name: n, value: v[j]});
    993             }
    994         }
    995         else if (feature.fileapi && el.type == 'file') {
    996             if (elements) {
    997                 elements.push(el);
    998             }
    999             var files = el.files;
    1000             if (files.length) {
    1001                 for (j=0; j < files.length; j++) {
    1002                     a.push({name: n, value: files[j], type: el.type});
    1003                 }
    1004             }
    1005             else {
    1006                 // #180
    1007                 a.push({ name: n, value: '', type: el.type });
    1008             }
    1009         }
    1010         else if (v !== null && typeof v != 'undefined') {
    1011             if (elements) {
    1012                 elements.push(el);
    1013             }
    1014             a.push({name: n, value: v, type: el.type, required: el.required});
    1015         }
    1016     }
    1017 
    1018     if (!semantic && form.clk) {
    1019         // input type=='image' are not found in elements array! handle it here
    1020         var $input = $(form.clk), input = $input[0];
    1021         n = input.name;
    1022         if (n && !input.disabled && input.type == 'image') {
    1023             a.push({name: n, value: $input.val()});
    1024             a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
    1025         }
    1026     }
    1027     return a;
    1028 };
    1029 
    1030 /**
    1031  * Serializes form data into a 'submittable' string. This method will return a string
    1032  * in the format: name1=value1&amp;name2=value2
    1033  */
    1034 $.fn.formSerialize = function(semantic) {
    1035     //hand off to jQuery.param for proper encoding
    1036     return $.param(this.formToArray(semantic));
    1037 };
    1038 
    1039 /**
    1040  * Serializes all field elements in the jQuery object into a query string.
    1041  * This method will return a string in the format: name1=value1&amp;name2=value2
    1042  */
    1043 $.fn.fieldSerialize = function(successful) {
    1044     var a = [];
    1045     this.each(function() {
    1046         var n = this.name;
    1047         if (!n) {
    1048             return;
    1049         }
    1050         var v = $.fieldValue(this, successful);
    1051         if (v && v.constructor == Array) {
    1052             for (var i=0,max=v.length; i < max; i++) {
    1053                 a.push({name: n, value: v[i]});
    1054             }
    1055         }
    1056         else if (v !== null && typeof v != 'undefined') {
    1057             a.push({name: this.name, value: v});
    1058         }
    1059     });
    1060     //hand off to jQuery.param for proper encoding
    1061     return $.param(a);
    1062 };
    1063 
    1064 /**
    1065  * Returns the value(s) of the element in the matched set.  For example, consider the following form:
    1066  *
    1067  *  <form><fieldset>
    1068  *      <input name="A" type="text" />
    1069  *      <input name="A" type="text" />
    1070  *      <input name="B" type="checkbox" value="B1" />
    1071  *      <input name="B" type="checkbox" value="B2"/>
    1072  *      <input name="C" type="radio" value="C1" />
    1073  *      <input name="C" type="radio" value="C2" />
    1074  *  </fieldset></form>
    1075  *
    1076  *  var v = $('input[type=text]').fieldValue();
    1077  *  // if no values are entered into the text inputs
    1078  *  v == ['','']
    1079  *  // if values entered into the text inputs are 'foo' and 'bar'
    1080  *  v == ['foo','bar']
    1081  *
    1082  *  var v = $('input[type=checkbox]').fieldValue();
    1083  *  // if neither checkbox is checked
    1084  *  v === undefined
    1085  *  // if both checkboxes are checked
    1086  *  v == ['B1', 'B2']
    1087  *
    1088  *  var v = $('input[type=radio]').fieldValue();
    1089  *  // if neither radio is checked
    1090  *  v === undefined
    1091  *  // if first radio is checked
    1092  *  v == ['C1']
    1093  *
    1094  * The successful argument controls whether or not the field element must be 'successful'
    1095  * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
    1096  * The default value of the successful argument is true.  If this value is false the value(s)
    1097  * for each element is returned.
    1098  *
    1099  * Note: This method *always* returns an array.  If no valid value can be determined the
    1100  *    array will be empty, otherwise it will contain one or more values.
    1101  */
    1102 $.fn.fieldValue = function(successful) {
    1103     for (var val=[], i=0, max=this.length; i < max; i++) {
    1104         var el = this[i];
    1105         var v = $.fieldValue(el, successful);
    1106         if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) {
    1107             continue;
    1108         }
    1109         if (v.constructor == Array) {
    1110             $.merge(val, v);
    1111         }
    1112         else {
    1113             val.push(v);
    1114         }
    1115     }
    1116     return val;
    1117 };
    1118 
    1119 /**
    1120  * Returns the value of the field element.
    1121  */
    1122 $.fieldValue = function(el, successful) {
    1123     var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
    1124     if (successful === undefined) {
    1125         successful = true;
    1126     }
    1127 
    1128     if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
    1129         (t == 'checkbox' || t == 'radio') && !el.checked ||
    1130         (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
    1131         tag == 'select' && el.selectedIndex == -1)) {
    1132             return null;
    1133     }
    1134 
    1135     if (tag == 'select') {
    1136         var index = el.selectedIndex;
    1137         if (index < 0) {
    1138             return null;
    1139         }
    1140         var a = [], ops = el.options;
    1141         var one = (t == 'select-one');
    1142         var max = (one ? index+1 : ops.length);
    1143         for(var i=(one ? index : 0); i < max; i++) {
    1144             var op = ops[i];
    1145             if (op.selected) {
    1146                 var v = op.value;
    1147                 if (!v) { // extra pain for IE...
    1148                     v = (op.attributes && op.attributes.value && !(op.attributes.value.specified)) ? op.text : op.value;
    1149                 }
    1150                 if (one) {
    1151                     return v;
    1152                 }
    1153                 a.push(v);
    1154             }
    1155         }
    1156         return a;
    1157     }
    1158     return $(el).val();
    1159 };
    1160 
    1161 /**
    1162  * Clears the form data.  Takes the following actions on the form's input fields:
    1163  *  - input text fields will have their 'value' property set to the empty string
    1164  *  - select elements will have their 'selectedIndex' property set to -1
    1165  *  - checkbox and radio inputs will have their 'checked' property set to false
    1166  *  - inputs of type submit, button, reset, and hidden will *not* be effected
    1167  *  - button elements will *not* be effected
    1168  */
    1169 $.fn.clearForm = function(includeHidden) {
    1170     return this.each(function() {
    1171         $('input,select,textarea', this).clearFields(includeHidden);
    1172     });
    1173 };
    1174 
    1175 /**
    1176  * Clears the selected form elements.
    1177  */
    1178 $.fn.clearFields = $.fn.clearInputs = function(includeHidden) {
    1179     var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list
    1180     return this.each(function() {
    1181         var t = this.type, tag = this.tagName.toLowerCase();
    1182         if (re.test(t) || tag == 'textarea') {
    1183             this.value = '';
    1184         }
    1185         else if (t == 'checkbox' || t == 'radio') {
    1186             this.checked = false;
    1187         }
    1188         else if (tag == 'select') {
    1189             this.selectedIndex = -1;
    1190         }
    1191         else if (t == "file") {
    1192             if (/MSIE/.test(navigator.userAgent)) {
    1193                 $(this).replaceWith($(this).clone(true));
    1194             } else {
    1195                 $(this).val('');
    1196             }
    1197         }
    1198         else if (includeHidden) {
    1199             // includeHidden can be the value true, or it can be a selector string
    1200             // indicating a special test; for example:
    1201             //  $('#myForm').clearForm('.special:hidden')
    1202             // the above would clean hidden inputs that have the class of 'special'
    1203             if ( (includeHidden === true && /hidden/.test(t)) ||
    1204                  (typeof includeHidden == 'string' && $(this).is(includeHidden)) ) {
    1205                 this.value = '';
    1206             }
    1207         }
    1208     });
    1209 };
    1210 
    1211 /**
    1212  * Resets the form data.  Causes all form elements to be reset to their original value.
    1213  */
    1214 $.fn.resetForm = function() {
    1215     return this.each(function() {
    1216         // guard against an input with the name of 'reset'
    1217         // note that IE reports the reset function as an 'object'
    1218         if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) {
    1219             this.reset();
    1220         }
    1221     });
    1222 };
    1223 
    1224 /**
    1225  * Enables or disables any matching elements.
    1226  */
    1227 $.fn.enable = function(b) {
    1228     if (b === undefined) {
    1229         b = true;
    1230     }
    1231     return this.each(function() {
    1232         this.disabled = !b;
    1233     });
    1234 };
    1235 
    1236 /**
    1237  * Checks/unchecks any matching checkboxes or radio buttons and
    1238  * selects/deselects and matching option elements.
    1239  */
    1240 $.fn.selected = function(select) {
    1241     if (select === undefined) {
    1242         select = true;
    1243     }
    1244     return this.each(function() {
    1245         var t = this.type;
    1246         if (t == 'checkbox' || t == 'radio') {
    1247             this.checked = select;
    1248         }
    1249         else if (this.tagName.toLowerCase() == 'option') {
    1250             var $sel = $(this).parent('select');
    1251             if (select && $sel[0] && $sel[0].type == 'select-one') {
    1252                 // deselect all other options
    1253                 $sel.find('option').selected(false);
    1254             }
    1255             this.selected = select;
    1256         }
    1257     });
    1258 };
    1259 
    1260 // expose debug var
    1261 $.fn.ajaxSubmit.debug = false;
    1262 
    1263 // helper fn for console logging
    1264 function log() {
    1265     if (!$.fn.ajaxSubmit.debug) {
    1266         return;
    1267     }
    1268     var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
    1269     if (window.console && window.console.log) {
    1270         window.console.log(msg);
    1271     }
    1272     else if (window.opera && window.opera.postError) {
    1273         window.opera.postError(msg);
    1274     }
    1275 }
    1276 
     15        if (typeof define === 'function' && define.amd) {
     16                // AMD. Register as an anonymous module.
     17                define(['jquery'], factory);
     18        } else if (typeof module === 'object' && module.exports) {
     19                // Node/CommonJS
     20                module.exports = function( root, jQuery ) {
     21                        if (typeof jQuery === 'undefined') {
     22                                // require('jQuery') returns a factory that requires window to build a jQuery instance, we normalize how we use modules
     23                                // that require this pattern but the window provided is a noop if it's defined (how jquery works)
     24                                if (typeof window !== 'undefined') {
     25                                        jQuery = require('jquery');
     26                                }
     27                                else {
     28                                        jQuery = require('jquery')(root);
     29                                }
     30                        }
     31                        factory(jQuery);
     32                        return jQuery;
     33                };
     34        } else {
     35                // Browser globals
     36                factory(jQuery);
     37        }
     38
     39}(function ($) {
     40/* eslint-enable */
     41        'use strict';
     42
     43        /*
     44                Usage Note:
     45                -----------
     46                Do not use both ajaxSubmit and ajaxForm on the same form. These
     47                functions are mutually exclusive. Use ajaxSubmit if you want
     48                to bind your own submit handler to the form. For example,
     49
     50                $(document).ready(function() {
     51                        $('#myForm').on('submit', function(e) {
     52                                e.preventDefault(); // <-- important
     53                                $(this).ajaxSubmit({
     54                                        target: '#output'
     55                                });
     56                        });
     57                });
     58
     59                Use ajaxForm when you want the plugin to manage all the event binding
     60                for you. For example,
     61
     62                $(document).ready(function() {
     63                        $('#myForm').ajaxForm({
     64                                target: '#output'
     65                        });
     66                });
     67
     68                You can also use ajaxForm with delegation (requires jQuery v1.7+), so the
     69                form does not have to exist when you invoke ajaxForm:
     70
     71                $('#myForm').ajaxForm({
     72                        delegation: true,
     73                        target: '#output'
     74                });
     75
     76                When using ajaxForm, the ajaxSubmit function will be invoked for you
     77                at the appropriate time.
     78        */
     79
     80        var rCRLF = /\r?\n/g;
     81
     82        /**
     83         * Feature detection
     84         */
     85        var feature = {};
     86
     87        feature.fileapi = $('<input type="file">').get(0).files !== undefined;
     88        feature.formdata = (typeof window.FormData !== 'undefined');
     89
     90        var hasProp = !!$.fn.prop;
     91
     92        // attr2 uses prop when it can but checks the return type for
     93        // an expected string. This accounts for the case where a form
     94        // contains inputs with names like "action" or "method"; in those
     95        // cases "prop" returns the element
     96        $.fn.attr2 = function() {
     97                if (!hasProp) {
     98                        return this.attr.apply(this, arguments);
     99                }
     100
     101                var val = this.prop.apply(this, arguments);
     102
     103                if ((val && val.jquery) || typeof val === 'string') {
     104                        return val;
     105                }
     106
     107                return this.attr.apply(this, arguments);
     108        };
     109
     110        /**
     111         * ajaxSubmit() provides a mechanism for immediately submitting
     112         * an HTML form using AJAX.
     113         *
     114         * @param       {object|string} options         jquery.form.js parameters or custom url for submission
     115         * @param       {object}                data            extraData
     116         * @param       {string}                dataType        ajax dataType
     117         * @param       {function}              onSuccess       ajax success callback function
     118         */
     119        $.fn.ajaxSubmit = function(options, data, dataType, onSuccess) {
     120                // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
     121                if (!this.length) {
     122                        log('ajaxSubmit: skipping submit process - no element selected');
     123
     124                        return this;
     125                }
     126
     127                /* eslint consistent-this: ["error", "$form"] */
     128                var method, action, url, $form = this;
     129
     130                if (typeof options === 'function') {
     131                        options = {success: options};
     132
     133                } else if (typeof options === 'string' || (options === false && arguments.length > 0)) {
     134                        options = {
     135                                'url'      : options,
     136                                'data'     : data,
     137                                'dataType' : dataType
     138                        };
     139
     140                        if (typeof onSuccess === 'function') {
     141                                options.success = onSuccess;
     142                        }
     143
     144                } else if (typeof options === 'undefined') {
     145                        options = {};
     146                }
     147
     148                method = options.type || this.attr2('method');
     149                action = options.url || this.attr2('action');
     150
     151                url = (typeof action === 'string') ? $.trim(action) : '';
     152                url = url || window.location.href || '';
     153                if (url) {
     154                        // clean url (don't include hash vaue)
     155                        url = (url.match(/^([^#]+)/) || [])[1];
     156                }
     157
     158                options = $.extend(true, {
     159                        url       : url,
     160                        success   : $.ajaxSettings.success,
     161                        type      : method || $.ajaxSettings.type,
     162                        iframeSrc : /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'             // eslint-disable-line no-script-url
     163                }, options);
     164
     165                // hook for manipulating the form data before it is extracted;
     166                // convenient for use with rich editors like tinyMCE or FCKEditor
     167                var veto = {};
     168
     169                this.trigger('form-pre-serialize', [this, options, veto]);
     170
     171                if (veto.veto) {
     172                        log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
     173
     174                        return this;
     175                }
     176
     177                // provide opportunity to alter form data before it is serialized
     178                if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
     179                        log('ajaxSubmit: submit aborted via beforeSerialize callback');
     180
     181                        return this;
     182                }
     183
     184                var traditional = options.traditional;
     185
     186                if (typeof traditional === 'undefined') {
     187                        traditional = $.ajaxSettings.traditional;
     188                }
     189
     190                var elements = [];
     191                var qx, a = this.formToArray(options.semantic, elements, options.filtering);
     192
     193                if (options.data) {
     194                        var optionsData = $.isFunction(options.data) ? options.data(a) : options.data;
     195
     196                        options.extraData = optionsData;
     197                        qx = $.param(optionsData, traditional);
     198                }
     199
     200                // give pre-submit callback an opportunity to abort the submit
     201                if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
     202                        log('ajaxSubmit: submit aborted via beforeSubmit callback');
     203
     204                        return this;
     205                }
     206
     207                // fire vetoable 'validate' event
     208                this.trigger('form-submit-validate', [a, this, options, veto]);
     209                if (veto.veto) {
     210                        log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
     211
     212                        return this;
     213                }
     214
     215                var q = $.param(a, traditional);
     216
     217                if (qx) {
     218                        q = (q ? (q + '&' + qx) : qx);
     219                }
     220
     221                if (options.type.toUpperCase() === 'GET') {
     222                        options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
     223                        options.data = null;    // data is null for 'get'
     224                } else {
     225                        options.data = q;               // data is the query string for 'post'
     226                }
     227
     228                var callbacks = [];
     229
     230                if (options.resetForm) {
     231                        callbacks.push(function() {
     232                                $form.resetForm();
     233                        });
     234                }
     235
     236                if (options.clearForm) {
     237                        callbacks.push(function() {
     238                                $form.clearForm(options.includeHidden);
     239                        });
     240                }
     241
     242                // perform a load on the target only if dataType is not provided
     243                if (!options.dataType && options.target) {
     244                        var oldSuccess = options.success || function(){};
     245
     246                        callbacks.push(function(data) {
     247                                var fn = options.replaceTarget ? 'replaceWith' : 'html';
     248
     249                                $(options.target)[fn](data).each(oldSuccess, arguments);
     250                        });
     251
     252                } else if (options.success) {
     253                        if ($.isArray(options.success)) {
     254                                $.merge(callbacks, options.success);
     255                        } else {
     256                                callbacks.push(options.success);
     257                        }
     258                }
     259
     260                options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
     261                        var context = options.context || this;          // jQuery 1.4+ supports scope context
     262
     263                        for (var i = 0, max = callbacks.length; i < max; i++) {
     264                                callbacks[i].apply(context, [data, status, xhr || $form, $form]);
     265                        }
     266                };
     267
     268                if (options.error) {
     269                        var oldError = options.error;
     270
     271                        options.error = function(xhr, status, error) {
     272                                var context = options.context || this;
     273
     274                                oldError.apply(context, [xhr, status, error, $form]);
     275                        };
     276                }
     277
     278                if (options.complete) {
     279                        var oldComplete = options.complete;
     280
     281                        options.complete = function(xhr, status) {
     282                                var context = options.context || this;
     283
     284                                oldComplete.apply(context, [xhr, status, $form]);
     285                        };
     286                }
     287
     288                // are there files to upload?
     289
     290                // [value] (issue #113), also see comment:
     291                // https://github.com/malsup/form/commit/588306aedba1de01388032d5f42a60159eea9228#commitcomment-2180219
     292                var fileInputs = $('input[type=file]:enabled', this).filter(function() {
     293                        return $(this).val() !== '';
     294                });
     295                var hasFileInputs = fileInputs.length > 0;
     296                var mp = 'multipart/form-data';
     297                var multipart = ($form.attr('enctype') === mp || $form.attr('encoding') === mp);
     298                var fileAPI = feature.fileapi && feature.formdata;
     299
     300                log('fileAPI :' + fileAPI);
     301
     302                var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI;
     303                var jqxhr;
     304
     305                // options.iframe allows user to force iframe mode
     306                // 06-NOV-09: now defaulting to iframe mode if file input is detected
     307                if (options.iframe !== false && (options.iframe || shouldUseFrame)) {
     308                        // hack to fix Safari hang (thanks to Tim Molendijk for this)
     309                        // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
     310                        if (options.closeKeepAlive) {
     311                                $.get(options.closeKeepAlive, function() {
     312                                        jqxhr = fileUploadIframe(a);
     313                                });
     314
     315                        } else {
     316                                jqxhr = fileUploadIframe(a);
     317                        }
     318
     319                } else if ((hasFileInputs || multipart) && fileAPI) {
     320                        jqxhr = fileUploadXhr(a);
     321
     322                } else {
     323                        jqxhr = $.ajax(options);
     324                }
     325
     326                $form.removeData('jqxhr').data('jqxhr', jqxhr);
     327
     328                // clear element array
     329                for (var k = 0; k < elements.length; k++) {
     330                        elements[k] = null;
     331                }
     332
     333                // fire 'notify' event
     334                this.trigger('form-submit-notify', [this, options]);
     335
     336                return this;
     337
     338                // utility fn for deep serialization
     339                function deepSerialize(extraData) {
     340                        var serialized = $.param(extraData, options.traditional).split('&');
     341                        var len = serialized.length;
     342                        var result = [];
     343                        var i, part;
     344
     345                        for (i = 0; i < len; i++) {
     346                                part = serialized[i].split('=');
     347                                // #278; use array instead of object storage, favoring array serializations
     348                                result.push([decodeURIComponent(part[0]), decodeURIComponent(part[1])]);
     349                        }
     350
     351                        return result;
     352                }
     353
     354                // XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz)
     355                function fileUploadXhr(a) {
     356                        var formdata = new FormData();
     357
     358                        for (var i = 0; i < a.length; i++) {
     359                                formdata.append(a[i].name, a[i].value);
     360                        }
     361
     362                        if (options.extraData) {
     363                                var serializedData = deepSerialize(options.extraData);
     364
     365                                for (i = 0; i < serializedData.length; i++) {
     366                                        if (serializedData[i]) {
     367                                                formdata.append(serializedData[i][0], serializedData[i][1]);
     368                                        }
     369                                }
     370                        }
     371
     372                        options.data = null;
     373
     374                        var s = $.extend(true, {}, $.ajaxSettings, options, {
     375                                contentType : false,
     376                                processData : false,
     377                                cache       : false,
     378                                type        : method || 'POST'
     379                        });
     380
     381                        if (options.uploadProgress) {
     382                                // workaround because jqXHR does not expose upload property
     383                                s.xhr = function() {
     384                                        var xhr = $.ajaxSettings.xhr();
     385
     386                                        if (xhr.upload) {
     387                                                xhr.upload.addEventListener('progress', function(event) {
     388                                                        var percent = 0;
     389                                                        var position = event.loaded || event.position;                  /* event.position is deprecated */
     390                                                        var total = event.total;
     391
     392                                                        if (event.lengthComputable) {
     393                                                                percent = Math.ceil(position / total * 100);
     394                                                        }
     395
     396                                                        options.uploadProgress(event, position, total, percent);
     397                                                }, false);
     398                                        }
     399
     400                                        return xhr;
     401                                };
     402                        }
     403
     404                        s.data = null;
     405
     406                        var beforeSend = s.beforeSend;
     407
     408                        s.beforeSend = function(xhr, o) {
     409                                // Send FormData() provided by user
     410                                if (options.formData) {
     411                                        o.data = options.formData;
     412                                } else {
     413                                        o.data = formdata;
     414                                }
     415
     416                                if (beforeSend) {
     417                                        beforeSend.call(this, xhr, o);
     418                                }
     419                        };
     420
     421                        return $.ajax(s);
     422                }
     423
     424                // private function for handling file uploads (hat tip to YAHOO!)
     425                function fileUploadIframe(a) {
     426                        var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle;
     427                        var deferred = $.Deferred();
     428
     429                        // #341
     430                        deferred.abort = function(status) {
     431                                xhr.abort(status);
     432                        };
     433
     434                        if (a) {
     435                                // ensure that every serialized input is still enabled
     436                                for (i = 0; i < elements.length; i++) {
     437                                        el = $(elements[i]);
     438                                        if (hasProp) {
     439                                                el.prop('disabled', false);
     440                                        } else {
     441                                                el.removeAttr('disabled');
     442                                        }
     443                                }
     444                        }
     445
     446                        s = $.extend(true, {}, $.ajaxSettings, options);
     447                        s.context = s.context || s;
     448                        id = 'jqFormIO' + new Date().getTime();
     449                        var ownerDocument = form.ownerDocument;
     450                        var $body = $form.closest('body');
     451
     452                        if (s.iframeTarget) {
     453                                $io = $(s.iframeTarget, ownerDocument);
     454                                n = $io.attr2('name');
     455                                if (!n) {
     456                                        $io.attr2('name', id);
     457                                } else {
     458                                        id = n;
     459                                }
     460
     461                        } else {
     462                                $io = $('<iframe name="' + id + '" src="' + s.iframeSrc + '" />', ownerDocument);
     463                                $io.css({position: 'absolute', top: '-1000px', left: '-1000px'});
     464                        }
     465                        io = $io[0];
     466
     467
     468                        xhr = { // mock object
     469                                aborted               : 0,
     470                                responseText          : null,
     471                                responseXML           : null,
     472                                status                : 0,
     473                                statusText            : 'n/a',
     474                                getAllResponseHeaders : function() {},
     475                                getResponseHeader     : function() {},
     476                                setRequestHeader      : function() {},
     477                                abort                 : function(status) {
     478                                        var e = (status === 'timeout' ? 'timeout' : 'aborted');
     479
     480                                        log('aborting upload... ' + e);
     481                                        this.aborted = 1;
     482
     483                                        try { // #214, #257
     484                                                if (io.contentWindow.document.execCommand) {
     485                                                        io.contentWindow.document.execCommand('Stop');
     486                                                }
     487                                        } catch (ignore) {}
     488
     489                                        $io.attr('src', s.iframeSrc); // abort op in progress
     490                                        xhr.error = e;
     491                                        if (s.error) {
     492                                                s.error.call(s.context, xhr, e, status);
     493                                        }
     494
     495                                        if (g) {
     496                                                $.event.trigger('ajaxError', [xhr, s, e]);
     497                                        }
     498
     499                                        if (s.complete) {
     500                                                s.complete.call(s.context, xhr, e);
     501                                        }
     502                                }
     503                        };
     504
     505                        g = s.global;
     506                        // trigger ajax global events so that activity/block indicators work like normal
     507                        if (g && $.active++ === 0) {
     508                                $.event.trigger('ajaxStart');
     509                        }
     510                        if (g) {
     511                                $.event.trigger('ajaxSend', [xhr, s]);
     512                        }
     513
     514                        if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
     515                                if (s.global) {
     516                                        $.active--;
     517                                }
     518                                deferred.reject();
     519
     520                                return deferred;
     521                        }
     522
     523                        if (xhr.aborted) {
     524                                deferred.reject();
     525
     526                                return deferred;
     527                        }
     528
     529                        // add submitting element to data if we know it
     530                        sub = form.clk;
     531                        if (sub) {
     532                                n = sub.name;
     533                                if (n && !sub.disabled) {
     534                                        s.extraData = s.extraData || {};
     535                                        s.extraData[n] = sub.value;
     536                                        if (sub.type === 'image') {
     537                                                s.extraData[n + '.x'] = form.clk_x;
     538                                                s.extraData[n + '.y'] = form.clk_y;
     539                                        }
     540                                }
     541                        }
     542
     543                        var CLIENT_TIMEOUT_ABORT = 1;
     544                        var SERVER_ABORT = 2;
     545
     546                        function getDoc(frame) {
     547                                /* it looks like contentWindow or contentDocument do not
     548                                 * carry the protocol property in ie8, when running under ssl
     549                                 * frame.document is the only valid response document, since
     550                                 * the protocol is know but not on the other two objects. strange?
     551                                 * "Same origin policy" http://en.wikipedia.org/wiki/Same_origin_policy
     552                                 */
     553
     554                                var doc = null;
     555
     556                                // IE8 cascading access check
     557                                try {
     558                                        if (frame.contentWindow) {
     559                                                doc = frame.contentWindow.document;
     560                                        }
     561                                } catch (err) {
     562                                        // IE8 access denied under ssl & missing protocol
     563                                        log('cannot get iframe.contentWindow document: ' + err);
     564                                }
     565
     566                                if (doc) { // successful getting content
     567                                        return doc;
     568                                }
     569
     570                                try { // simply checking may throw in ie8 under ssl or mismatched protocol
     571                                        doc = frame.contentDocument ? frame.contentDocument : frame.document;
     572                                } catch (err) {
     573                                        // last attempt
     574                                        log('cannot get iframe.contentDocument: ' + err);
     575                                        doc = frame.document;
     576                                }
     577
     578                                return doc;
     579                        }
     580
     581                        // Rails CSRF hack (thanks to Yvan Barthelemy)
     582                        var csrf_token = $('meta[name=csrf-token]').attr('content');
     583                        var csrf_param = $('meta[name=csrf-param]').attr('content');
     584
     585                        if (csrf_param && csrf_token) {
     586                                s.extraData = s.extraData || {};
     587                                s.extraData[csrf_param] = csrf_token;
     588                        }
     589
     590                        // take a breath so that pending repaints get some cpu time before the upload starts
     591                        function doSubmit() {
     592                                // make sure form attrs are set
     593                                var t = $form.attr2('target'),
     594                                        a = $form.attr2('action'),
     595                                        mp = 'multipart/form-data',
     596                                        et = $form.attr('enctype') || $form.attr('encoding') || mp;
     597
     598                                // update form attrs in IE friendly way
     599                                form.setAttribute('target', id);
     600                                if (!method || /post/i.test(method)) {
     601                                        form.setAttribute('method', 'POST');
     602                                }
     603                                if (a !== s.url) {
     604                                        form.setAttribute('action', s.url);
     605                                }
     606
     607                                // ie borks in some cases when setting encoding
     608                                if (!s.skipEncodingOverride && (!method || /post/i.test(method))) {
     609                                        $form.attr({
     610                                                encoding : 'multipart/form-data',
     611                                                enctype  : 'multipart/form-data'
     612                                        });
     613                                }
     614
     615                                // support timout
     616                                if (s.timeout) {
     617                                        timeoutHandle = setTimeout(function() {
     618                                                timedOut = true; cb(CLIENT_TIMEOUT_ABORT);
     619                                        }, s.timeout);
     620                                }
     621
     622                                // look for server aborts
     623                                function checkState() {
     624                                        try {
     625                                                var state = getDoc(io).readyState;
     626
     627                                                log('state = ' + state);
     628                                                if (state && state.toLowerCase() === 'uninitialized') {
     629                                                        setTimeout(checkState, 50);
     630                                                }
     631
     632                                        } catch (e) {
     633                                                log('Server abort: ', e, ' (', e.name, ')');
     634                                                cb(SERVER_ABORT);                               // eslint-disable-line callback-return
     635                                                if (timeoutHandle) {
     636                                                        clearTimeout(timeoutHandle);
     637                                                }
     638                                                timeoutHandle = undefined;
     639                                        }
     640                                }
     641
     642                                // add "extra" data to form if provided in options
     643                                var extraInputs = [];
     644
     645                                try {
     646                                        if (s.extraData) {
     647                                                for (var n in s.extraData) {
     648                                                        if (s.extraData.hasOwnProperty(n)) {
     649                                                                // if using the $.param format that allows for multiple values with the same name
     650                                                                if ($.isPlainObject(s.extraData[n]) && s.extraData[n].hasOwnProperty('name') && s.extraData[n].hasOwnProperty('value')) {
     651                                                                        extraInputs.push(
     652                                                                        $('<input type="hidden" name="' + s.extraData[n].name + '">', ownerDocument).val(s.extraData[n].value)
     653                                                                                .appendTo(form)[0]);
     654                                                                } else {
     655                                                                        extraInputs.push(
     656                                                                        $('<input type="hidden" name="' + n + '">', ownerDocument).val(s.extraData[n])
     657                                                                                .appendTo(form)[0]);
     658                                                                }
     659                                                        }
     660                                                }
     661                                        }
     662
     663                                        if (!s.iframeTarget) {
     664                                                // add iframe to doc and submit the form
     665                                                $io.appendTo($body);
     666                                        }
     667
     668                                        if (io.attachEvent) {
     669                                                io.attachEvent('onload', cb);
     670                                        } else {
     671                                                io.addEventListener('load', cb, false);
     672                                        }
     673
     674                                        setTimeout(checkState, 15);
     675
     676                                        try {
     677                                                form.submit();
     678
     679                                        } catch (err) {
     680                                                // just in case form has element with name/id of 'submit'
     681                                                var submitFn = document.createElement('form').submit;
     682
     683                                                submitFn.apply(form);
     684                                        }
     685
     686                                } finally {
     687                                        // reset attrs and remove "extra" input elements
     688                                        form.setAttribute('action', a);
     689                                        form.setAttribute('enctype', et); // #380
     690                                        if (t) {
     691                                                form.setAttribute('target', t);
     692                                        } else {
     693                                                $form.removeAttr('target');
     694                                        }
     695                                        $(extraInputs).remove();
     696                                }
     697                        }
     698
     699                        if (s.forceSync) {
     700                                doSubmit();
     701                        } else {
     702                                setTimeout(doSubmit, 10); // this lets dom updates render
     703                        }
     704
     705                        var data, doc, domCheckCount = 50, callbackProcessed;
     706
     707                        function cb(e) {
     708                                if (xhr.aborted || callbackProcessed) {
     709                                        return;
     710                                }
     711
     712                                doc = getDoc(io);
     713                                if (!doc) {
     714                                        log('cannot access response document');
     715                                        e = SERVER_ABORT;
     716                                }
     717                                if (e === CLIENT_TIMEOUT_ABORT && xhr) {
     718                                        xhr.abort('timeout');
     719                                        deferred.reject(xhr, 'timeout');
     720
     721                                        return;
     722
     723                                } else if (e === SERVER_ABORT && xhr) {
     724                                        xhr.abort('server abort');
     725                                        deferred.reject(xhr, 'error', 'server abort');
     726
     727                                        return;
     728                                }
     729
     730                                if (!doc || doc.location.href === s.iframeSrc) {
     731                                        // response not received yet
     732                                        if (!timedOut) {
     733                                                return;
     734                                        }
     735                                }
     736
     737                                if (io.detachEvent) {
     738                                        io.detachEvent('onload', cb);
     739                                } else {
     740                                        io.removeEventListener('load', cb, false);
     741                                }
     742
     743                                var status = 'success', errMsg;
     744
     745                                try {
     746                                        if (timedOut) {
     747                                                throw 'timeout';
     748                                        }
     749
     750                                        var isXml = s.dataType === 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
     751
     752                                        log('isXml=' + isXml);
     753
     754                                        if (!isXml && window.opera && (doc.body === null || !doc.body.innerHTML)) {
     755                                                if (--domCheckCount) {
     756                                                        // in some browsers (Opera) the iframe DOM is not always traversable when
     757                                                        // the onload callback fires, so we loop a bit to accommodate
     758                                                        log('requeing onLoad callback, DOM not available');
     759                                                        setTimeout(cb, 250);
     760
     761                                                        return;
     762                                                }
     763                                                // let this fall through because server response could be an empty document
     764                                                // log('Could not access iframe DOM after mutiple tries.');
     765                                                // throw 'DOMException: not available';
     766                                        }
     767
     768                                        // log('response detected');
     769                                        var docRoot = doc.body ? doc.body : doc.documentElement;
     770
     771                                        xhr.responseText = docRoot ? docRoot.innerHTML : null;
     772                                        xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
     773                                        if (isXml) {
     774                                                s.dataType = 'xml';
     775                                        }
     776                                        xhr.getResponseHeader = function(header){
     777                                                var headers = {'content-type': s.dataType};
     778
     779                                                return headers[header.toLowerCase()];
     780                                        };
     781                                        // support for XHR 'status' & 'statusText' emulation :
     782                                        if (docRoot) {
     783                                                xhr.status = Number(docRoot.getAttribute('status')) || xhr.status;
     784                                                xhr.statusText = docRoot.getAttribute('statusText') || xhr.statusText;
     785                                        }
     786
     787                                        var dt = (s.dataType || '').toLowerCase();
     788                                        var scr = /(json|script|text)/.test(dt);
     789
     790                                        if (scr || s.textarea) {
     791                                                // see if user embedded response in textarea
     792                                                var ta = doc.getElementsByTagName('textarea')[0];
     793
     794                                                if (ta) {
     795                                                        xhr.responseText = ta.value;
     796                                                        // support for XHR 'status' & 'statusText' emulation :
     797                                                        xhr.status = Number(ta.getAttribute('status')) || xhr.status;
     798                                                        xhr.statusText = ta.getAttribute('statusText') || xhr.statusText;
     799
     800                                                } else if (scr) {
     801                                                        // account for browsers injecting pre around json response
     802                                                        var pre = doc.getElementsByTagName('pre')[0];
     803                                                        var b = doc.getElementsByTagName('body')[0];
     804
     805                                                        if (pre) {
     806                                                                xhr.responseText = pre.textContent ? pre.textContent : pre.innerText;
     807                                                        } else if (b) {
     808                                                                xhr.responseText = b.textContent ? b.textContent : b.innerText;
     809                                                        }
     810                                                }
     811
     812                                        } else if (dt === 'xml' && !xhr.responseXML && xhr.responseText) {
     813                                                xhr.responseXML = toXml(xhr.responseText);                      // eslint-disable-line no-use-before-define
     814                                        }
     815
     816                                        try {
     817                                                data = httpData(xhr, dt, s);                                            // eslint-disable-line no-use-before-define
     818
     819                                        } catch (err) {
     820                                                status = 'parsererror';
     821                                                xhr.error = errMsg = (err || status);
     822                                        }
     823
     824                                } catch (err) {
     825                                        log('error caught: ', err);
     826                                        status = 'error';
     827                                        xhr.error = errMsg = (err || status);
     828                                }
     829
     830                                if (xhr.aborted) {
     831                                        log('upload aborted');
     832                                        status = null;
     833                                }
     834
     835                                if (xhr.status) { // we've set xhr.status
     836                                        status = ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) ? 'success' : 'error';
     837                                }
     838
     839                                // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
     840                                if (status === 'success') {
     841                                        if (s.success) {
     842                                                s.success.call(s.context, data, 'success', xhr);
     843                                        }
     844
     845                                        deferred.resolve(xhr.responseText, 'success', xhr);
     846
     847                                        if (g) {
     848                                                $.event.trigger('ajaxSuccess', [xhr, s]);
     849                                        }
     850
     851                                } else if (status) {
     852                                        if (typeof errMsg === 'undefined') {
     853                                                errMsg = xhr.statusText;
     854                                        }
     855                                        if (s.error) {
     856                                                s.error.call(s.context, xhr, status, errMsg);
     857                                        }
     858                                        deferred.reject(xhr, 'error', errMsg);
     859                                        if (g) {
     860                                                $.event.trigger('ajaxError', [xhr, s, errMsg]);
     861                                        }
     862                                }
     863
     864                                if (g) {
     865                                        $.event.trigger('ajaxComplete', [xhr, s]);
     866                                }
     867
     868                                if (g && !--$.active) {
     869                                        $.event.trigger('ajaxStop');
     870                                }
     871
     872                                if (s.complete) {
     873                                        s.complete.call(s.context, xhr, status);
     874                                }
     875
     876                                callbackProcessed = true;
     877                                if (s.timeout) {
     878                                        clearTimeout(timeoutHandle);
     879                                }
     880
     881                                // clean up
     882                                setTimeout(function() {
     883                                        if (!s.iframeTarget) {
     884                                                $io.remove();
     885                                        } else { // adding else to clean up existing iframe response.
     886                                                $io.attr('src', s.iframeSrc);
     887                                        }
     888                                        xhr.responseXML = null;
     889                                }, 100);
     890                        }
     891
     892                        var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+)
     893                                if (window.ActiveXObject) {
     894                                        doc = new ActiveXObject('Microsoft.XMLDOM');
     895                                        doc.async = 'false';
     896                                        doc.loadXML(s);
     897
     898                                } else {
     899                                        doc = (new DOMParser()).parseFromString(s, 'text/xml');
     900                                }
     901
     902                                return (doc && doc.documentElement && doc.documentElement.nodeName !== 'parsererror') ? doc : null;
     903                        };
     904                        var parseJSON = $.parseJSON || function(s) {
     905                                /* jslint evil:true */
     906                                return window['eval']('(' + s + ')');                   // eslint-disable-line dot-notation
     907                        };
     908
     909                        var httpData = function(xhr, type, s) { // mostly lifted from jq1.4.4
     910
     911                                var ct = xhr.getResponseHeader('content-type') || '',
     912                                        xml = ((type === 'xml' || !type) && ct.indexOf('xml') >= 0),
     913                                        data = xml ? xhr.responseXML : xhr.responseText;
     914
     915                                if (xml && data.documentElement.nodeName === 'parsererror') {
     916                                        if ($.error) {
     917                                                $.error('parsererror');
     918                                        }
     919                                }
     920                                if (s && s.dataFilter) {
     921                                        data = s.dataFilter(data, type);
     922                                }
     923                                if (typeof data === 'string') {
     924                                        if ((type === 'json' || !type) && ct.indexOf('json') >= 0) {
     925                                                data = parseJSON(data);
     926                                        } else if ((type === 'script' || !type) && ct.indexOf('javascript') >= 0) {
     927                                                $.globalEval(data);
     928                                        }
     929                                }
     930
     931                                return data;
     932                        };
     933
     934                        return deferred;
     935                }
     936        };
     937
     938        /**
     939         * ajaxForm() provides a mechanism for fully automating form submission.
     940         *
     941         * The advantages of using this method instead of ajaxSubmit() are:
     942         *
     943         * 1: This method will include coordinates for <input type="image"> elements (if the element
     944         *      is used to submit the form).
     945         * 2. This method will include the submit element's name/value data (for the element that was
     946         *      used to submit the form).
     947         * 3. This method binds the submit() method to the form for you.
     948         *
     949         * The options argument for ajaxForm works exactly as it does for ajaxSubmit. ajaxForm merely
     950         * passes the options argument along after properly binding events for submit elements and
     951         * the form itself.
     952         */
     953        $.fn.ajaxForm = function(options, data, dataType, onSuccess) {
     954                if (typeof options === 'string' || (options === false && arguments.length > 0)) {
     955                        options = {
     956                                'url'      : options,
     957                                'data'     : data,
     958                                'dataType' : dataType
     959                        };
     960
     961                        if (typeof onSuccess === 'function') {
     962                                options.success = onSuccess;
     963                        }
     964                }
     965
     966                options = options || {};
     967                options.delegation = options.delegation && $.isFunction($.fn.on);
     968
     969                // in jQuery 1.3+ we can fix mistakes with the ready state
     970                if (!options.delegation && this.length === 0) {
     971                        var o = {s: this.selector, c: this.context};
     972
     973                        if (!$.isReady && o.s) {
     974                                log('DOM not ready, queuing ajaxForm');
     975                                $(function() {
     976                                        $(o.s, o.c).ajaxForm(options);
     977                                });
     978
     979                                return this;
     980                        }
     981
     982                        // is your DOM ready?  http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
     983                        log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
     984
     985                        return this;
     986                }
     987
     988                if (options.delegation) {
     989                        $(document)
     990                                .off('submit.form-plugin', this.selector, doAjaxSubmit)
     991                                .off('click.form-plugin', this.selector, captureSubmittingElement)
     992                                .on('submit.form-plugin', this.selector, options, doAjaxSubmit)
     993                                .on('click.form-plugin', this.selector, options, captureSubmittingElement);
     994
     995                        return this;
     996                }
     997
     998                return this.ajaxFormUnbind()
     999                        .on('submit.form-plugin', options, doAjaxSubmit)
     1000                        .on('click.form-plugin', options, captureSubmittingElement);
     1001        };
     1002
     1003        // private event handlers
     1004        function doAjaxSubmit(e) {
     1005                /* jshint validthis:true */
     1006                var options = e.data;
     1007
     1008                if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
     1009                        e.preventDefault();
     1010                        $(e.target).closest('form').ajaxSubmit(options); // #365
     1011                }
     1012        }
     1013
     1014        function captureSubmittingElement(e) {
     1015                /* jshint validthis:true */
     1016                var target = e.target;
     1017                var $el = $(target);
     1018
     1019                if (!$el.is('[type=submit],[type=image]')) {
     1020                        // is this a child element of the submit el?  (ex: a span within a button)
     1021                        var t = $el.closest('[type=submit]');
     1022
     1023                        if (t.length === 0) {
     1024                                return;
     1025                        }
     1026                        target = t[0];
     1027                }
     1028
     1029                var form = target.form;
     1030
     1031                form.clk = target;
     1032
     1033                if (target.type === 'image') {
     1034                        if (typeof e.offsetX !== 'undefined') {
     1035                                form.clk_x = e.offsetX;
     1036                                form.clk_y = e.offsetY;
     1037
     1038                        } else if (typeof $.fn.offset === 'function') {
     1039                                var offset = $el.offset();
     1040
     1041                                form.clk_x = e.pageX - offset.left;
     1042                                form.clk_y = e.pageY - offset.top;
     1043
     1044                        } else {
     1045                                form.clk_x = e.pageX - target.offsetLeft;
     1046                                form.clk_y = e.pageY - target.offsetTop;
     1047                        }
     1048                }
     1049                // clear form vars
     1050                setTimeout(function() {
     1051                        form.clk = form.clk_x = form.clk_y = null;
     1052                }, 100);
     1053        }
     1054
     1055
     1056        // ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
     1057        $.fn.ajaxFormUnbind = function() {
     1058                return this.off('submit.form-plugin click.form-plugin');
     1059        };
     1060
     1061        /**
     1062         * formToArray() gathers form element data into an array of objects that can
     1063         * be passed to any of the following ajax functions: $.get, $.post, or load.
     1064         * Each object in the array has both a 'name' and 'value' property. An example of
     1065         * an array for a simple login form might be:
     1066         *
     1067         * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
     1068         *
     1069         * It is this array that is passed to pre-submit callback functions provided to the
     1070         * ajaxSubmit() and ajaxForm() methods.
     1071         */
     1072        $.fn.formToArray = function(semantic, elements, filtering) {
     1073                var a = [];
     1074
     1075                if (this.length === 0) {
     1076                        return a;
     1077                }
     1078
     1079                var form = this[0];
     1080                var formId = this.attr('id');
     1081                var els = (semantic || typeof form.elements === 'undefined') ? form.getElementsByTagName('*') : form.elements;
     1082                var els2;
     1083
     1084                if (els) {
     1085                        els = $.makeArray(els); // convert to standard array
     1086                }
     1087
     1088                // #386; account for inputs outside the form which use the 'form' attribute
     1089                // FinesseRus: in non-IE browsers outside fields are already included in form.elements.
     1090                if (formId && (semantic || /(Edge|Trident)\//.test(navigator.userAgent))) {
     1091                        els2 = $(':input[form="' + formId + '"]').get(); // hat tip @thet
     1092                        if (els2.length) {
     1093                                els = (els || []).concat(els2);
     1094                        }
     1095                }
     1096
     1097                if (!els || !els.length) {
     1098                        return a;
     1099                }
     1100
     1101                if ($.isFunction(filtering)) {
     1102                        els = $.map(els, filtering);
     1103                }
     1104
     1105                var i, j, n, v, el, max, jmax;
     1106
     1107                for (i = 0, max = els.length; i < max; i++) {
     1108                        el = els[i];
     1109                        n = el.name;
     1110                        if (!n || el.disabled) {
     1111                                continue;
     1112                        }
     1113
     1114                        if (semantic && form.clk && el.type === 'image') {
     1115                                // handle image inputs on the fly when semantic == true
     1116                                if (form.clk === el) {
     1117                                        a.push({name: n, value: $(el).val(), type: el.type});
     1118                                        a.push({name: n + '.x', value: form.clk_x}, {name: n + '.y', value: form.clk_y});
     1119                                }
     1120                                continue;
     1121                        }
     1122
     1123                        v = $.fieldValue(el, true);
     1124                        if (v && v.constructor === Array) {
     1125                                if (elements) {
     1126                                        elements.push(el);
     1127                                }
     1128                                for (j = 0, jmax = v.length; j < jmax; j++) {
     1129                                        a.push({name: n, value: v[j]});
     1130                                }
     1131
     1132                        } else if (feature.fileapi && el.type === 'file') {
     1133                                if (elements) {
     1134                                        elements.push(el);
     1135                                }
     1136
     1137                                var files = el.files;
     1138
     1139                                if (files.length) {
     1140                                        for (j = 0; j < files.length; j++) {
     1141                                                a.push({name: n, value: files[j], type: el.type});
     1142                                        }
     1143                                } else {
     1144                                        // #180
     1145                                        a.push({name: n, value: '', type: el.type});
     1146                                }
     1147
     1148                        } else if (v !== null && typeof v !== 'undefined') {
     1149                                if (elements) {
     1150                                        elements.push(el);
     1151                                }
     1152                                a.push({name: n, value: v, type: el.type, required: el.required});
     1153                        }
     1154                }
     1155
     1156                if (!semantic && form.clk) {
     1157                        // input type=='image' are not found in elements array! handle it here
     1158                        var $input = $(form.clk), input = $input[0];
     1159
     1160                        n = input.name;
     1161
     1162                        if (n && !input.disabled && input.type === 'image') {
     1163                                a.push({name: n, value: $input.val()});
     1164                                a.push({name: n + '.x', value: form.clk_x}, {name: n + '.y', value: form.clk_y});
     1165                        }
     1166                }
     1167
     1168                return a;
     1169        };
     1170
     1171        /**
     1172         * Serializes form data into a 'submittable' string. This method will return a string
     1173         * in the format: name1=value1&amp;name2=value2
     1174         */
     1175        $.fn.formSerialize = function(semantic) {
     1176                // hand off to jQuery.param for proper encoding
     1177                return $.param(this.formToArray(semantic));
     1178        };
     1179
     1180        /**
     1181         * Serializes all field elements in the jQuery object into a query string.
     1182         * This method will return a string in the format: name1=value1&amp;name2=value2
     1183         */
     1184        $.fn.fieldSerialize = function(successful) {
     1185                var a = [];
     1186
     1187                this.each(function() {
     1188                        var n = this.name;
     1189
     1190                        if (!n) {
     1191                                return;
     1192                        }
     1193
     1194                        var v = $.fieldValue(this, successful);
     1195
     1196                        if (v && v.constructor === Array) {
     1197                                for (var i = 0, max = v.length; i < max; i++) {
     1198                                        a.push({name: n, value: v[i]});
     1199                                }
     1200
     1201                        } else if (v !== null && typeof v !== 'undefined') {
     1202                                a.push({name: this.name, value: v});
     1203                        }
     1204                });
     1205
     1206                // hand off to jQuery.param for proper encoding
     1207                return $.param(a);
     1208        };
     1209
     1210        /**
     1211         * Returns the value(s) of the element in the matched set. For example, consider the following form:
     1212         *
     1213         *      <form><fieldset>
     1214         *              <input name="A" type="text">
     1215         *              <input name="A" type="text">
     1216         *              <input name="B" type="checkbox" value="B1">
     1217         *              <input name="B" type="checkbox" value="B2">
     1218         *              <input name="C" type="radio" value="C1">
     1219         *              <input name="C" type="radio" value="C2">
     1220         *      </fieldset></form>
     1221         *
     1222         *      var v = $('input[type=text]').fieldValue();
     1223         *      // if no values are entered into the text inputs
     1224         *      v === ['','']
     1225         *      // if values entered into the text inputs are 'foo' and 'bar'
     1226         *      v === ['foo','bar']
     1227         *
     1228         *      var v = $('input[type=checkbox]').fieldValue();
     1229         *      // if neither checkbox is checked
     1230         *      v === undefined
     1231         *      // if both checkboxes are checked
     1232         *      v === ['B1', 'B2']
     1233         *
     1234         *      var v = $('input[type=radio]').fieldValue();
     1235         *      // if neither radio is checked
     1236         *      v === undefined
     1237         *      // if first radio is checked
     1238         *      v === ['C1']
     1239         *
     1240         * The successful argument controls whether or not the field element must be 'successful'
     1241         * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
     1242         * The default value of the successful argument is true. If this value is false the value(s)
     1243         * for each element is returned.
     1244         *
     1245         * Note: This method *always* returns an array. If no valid value can be determined the
     1246         *      array will be empty, otherwise it will contain one or more values.
     1247         */
     1248        $.fn.fieldValue = function(successful) {
     1249                for (var val = [], i = 0, max = this.length; i < max; i++) {
     1250                        var el = this[i];
     1251                        var v = $.fieldValue(el, successful);
     1252
     1253                        if (v === null || typeof v === 'undefined' || (v.constructor === Array && !v.length)) {
     1254                                continue;
     1255                        }
     1256
     1257                        if (v.constructor === Array) {
     1258                                $.merge(val, v);
     1259                        } else {
     1260                                val.push(v);
     1261                        }
     1262                }
     1263
     1264                return val;
     1265        };
     1266
     1267        /**
     1268         * Returns the value of the field element.
     1269         */
     1270        $.fieldValue = function(el, successful) {
     1271                var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
     1272
     1273                if (typeof successful === 'undefined') {
     1274                        successful = true;
     1275                }
     1276
     1277                /* eslint-disable no-mixed-operators */
     1278                if (successful && (!n || el.disabled || t === 'reset' || t === 'button' ||
     1279                        (t === 'checkbox' || t === 'radio') && !el.checked ||
     1280                        (t === 'submit' || t === 'image') && el.form && el.form.clk !== el ||
     1281                        tag === 'select' && el.selectedIndex === -1)) {
     1282                /* eslint-enable no-mixed-operators */
     1283                        return null;
     1284                }
     1285
     1286                if (tag === 'select') {
     1287                        var index = el.selectedIndex;
     1288
     1289                        if (index < 0) {
     1290                                return null;
     1291                        }
     1292
     1293                        var a = [], ops = el.options;
     1294                        var one = (t === 'select-one');
     1295                        var max = (one ? index + 1 : ops.length);
     1296
     1297                        for (var i = (one ? index : 0); i < max; i++) {
     1298                                var op = ops[i];
     1299
     1300                                if (op.selected && !op.disabled) {
     1301                                        var v = op.value;
     1302
     1303                                        if (!v) { // extra pain for IE...
     1304                                                v = (op.attributes && op.attributes.value && !(op.attributes.value.specified)) ? op.text : op.value;
     1305                                        }
     1306
     1307                                        if (one) {
     1308                                                return v;
     1309                                        }
     1310
     1311                                        a.push(v);
     1312                                }
     1313                        }
     1314
     1315                        return a;
     1316                }
     1317
     1318                return $(el).val().replace(rCRLF, '\r\n');
     1319        };
     1320
     1321        /**
     1322         * Clears the form data. Takes the following actions on the form's input fields:
     1323         *  - input text fields will have their 'value' property set to the empty string
     1324         *  - select elements will have their 'selectedIndex' property set to -1
     1325         *  - checkbox and radio inputs will have their 'checked' property set to false
     1326         *  - inputs of type submit, button, reset, and hidden will *not* be effected
     1327         *  - button elements will *not* be effected
     1328         */
     1329        $.fn.clearForm = function(includeHidden) {
     1330                return this.each(function() {
     1331                        $('input,select,textarea', this).clearFields(includeHidden);
     1332                });
     1333        };
     1334
     1335        /**
     1336         * Clears the selected form elements.
     1337         */
     1338        $.fn.clearFields = $.fn.clearInputs = function(includeHidden) {
     1339                var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list
     1340
     1341                return this.each(function() {
     1342                        var t = this.type, tag = this.tagName.toLowerCase();
     1343
     1344                        if (re.test(t) || tag === 'textarea') {
     1345                                this.value = '';
     1346
     1347                        } else if (t === 'checkbox' || t === 'radio') {
     1348                                this.checked = false;
     1349
     1350                        } else if (tag === 'select') {
     1351                                this.selectedIndex = -1;
     1352
     1353                        } else if (t === 'file') {
     1354                                if (/MSIE/.test(navigator.userAgent)) {
     1355                                        $(this).replaceWith($(this).clone(true));
     1356                                } else {
     1357                                        $(this).val('');
     1358                                }
     1359
     1360                        } else if (includeHidden) {
     1361                                // includeHidden can be the value true, or it can be a selector string
     1362                                // indicating a special test; for example:
     1363                                // $('#myForm').clearForm('.special:hidden')
     1364                                // the above would clean hidden inputs that have the class of 'special'
     1365                                if ((includeHidden === true && /hidden/.test(t)) ||
     1366                                        (typeof includeHidden === 'string' && $(this).is(includeHidden))) {
     1367                                        this.value = '';
     1368                                }
     1369                        }
     1370                });
     1371        };
     1372
     1373
     1374        /**
     1375         * Resets the form data or individual elements. Takes the following actions
     1376         * on the selected tags:
     1377         * - all fields within form elements will be reset to their original value
     1378         * - input / textarea / select fields will be reset to their original value
     1379         * - option / optgroup fields (for multi-selects) will defaulted individually
     1380         * - non-multiple options will find the right select to default
     1381         * - label elements will be searched against its 'for' attribute
     1382         * - all others will be searched for appropriate children to default
     1383         */
     1384        $.fn.resetForm = function() {
     1385                return this.each(function() {
     1386                        var el = $(this);
     1387                        var tag = this.tagName.toLowerCase();
     1388
     1389                        switch (tag) {
     1390                        case 'input':
     1391                                this.checked = this.defaultChecked;
     1392                                        // fall through
     1393
     1394                        case 'textarea':
     1395                                this.value = this.defaultValue;
     1396
     1397                                return true;
     1398
     1399                        case 'option':
     1400                        case 'optgroup':
     1401                                var select = el.parents('select');
     1402
     1403                                if (select.length && select[0].multiple) {
     1404                                        if (tag === 'option') {
     1405                                                this.selected = this.defaultSelected;
     1406                                        } else {
     1407                                                el.find('option').resetForm();
     1408                                        }
     1409                                } else {
     1410                                        select.resetForm();
     1411                                }
     1412
     1413                                return true;
     1414
     1415                        case 'select':
     1416                                el.find('option').each(function(i) {                            // eslint-disable-line consistent-return
     1417                                        this.selected = this.defaultSelected;
     1418                                        if (this.defaultSelected && !el[0].multiple) {
     1419                                                el[0].selectedIndex = i;
     1420
     1421                                                return false;
     1422                                        }
     1423                                });
     1424
     1425                                return true;
     1426
     1427                        case 'label':
     1428                                var forEl = $(el.attr('for'));
     1429                                var list = el.find('input,select,textarea');
     1430
     1431                                if (forEl[0]) {
     1432                                        list.unshift(forEl[0]);
     1433                                }
     1434
     1435                                list.resetForm();
     1436
     1437                                return true;
     1438
     1439                        case 'form':
     1440                                        // guard against an input with the name of 'reset'
     1441                                        // note that IE reports the reset function as an 'object'
     1442                                if (typeof this.reset === 'function' || (typeof this.reset === 'object' && !this.reset.nodeType)) {
     1443                                        this.reset();
     1444                                }
     1445
     1446                                return true;
     1447
     1448                        default:
     1449                                el.find('form,input,label,select,textarea').resetForm();
     1450
     1451                                return true;
     1452                        }
     1453                });
     1454        };
     1455
     1456        /**
     1457         * Enables or disables any matching elements.
     1458         */
     1459        $.fn.enable = function(b) {
     1460                if (typeof b === 'undefined') {
     1461                        b = true;
     1462                }
     1463
     1464                return this.each(function() {
     1465                        this.disabled = !b;
     1466                });
     1467        };
     1468
     1469        /**
     1470         * Checks/unchecks any matching checkboxes or radio buttons and
     1471         * selects/deselects and matching option elements.
     1472         */
     1473        $.fn.selected = function(select) {
     1474                if (typeof select === 'undefined') {
     1475                        select = true;
     1476                }
     1477
     1478                return this.each(function() {
     1479                        var t = this.type;
     1480
     1481                        if (t === 'checkbox' || t === 'radio') {
     1482                                this.checked = select;
     1483
     1484                        } else if (this.tagName.toLowerCase() === 'option') {
     1485                                var $sel = $(this).parent('select');
     1486
     1487                                if (select && $sel[0] && $sel[0].type === 'select-one') {
     1488                                        // deselect all other options
     1489                                        $sel.find('option').selected(false);
     1490                                }
     1491
     1492                                this.selected = select;
     1493                        }
     1494                });
     1495        };
     1496
     1497        // expose debug var
     1498        $.fn.ajaxSubmit.debug = false;
     1499
     1500        // helper fn for console logging
     1501        function log() {
     1502                if (!$.fn.ajaxSubmit.debug) {
     1503                        return;
     1504                }
     1505
     1506                var msg = '[jquery.form] ' + Array.prototype.join.call(arguments, '');
     1507
     1508                if (window.console && window.console.log) {
     1509                        window.console.log(msg);
     1510
     1511                } else if (window.opera && window.opera.postError) {
     1512                        window.opera.postError(msg);
     1513                }
     1514        }
    12771515}));
  • _plugins_/crayons/js/jquery.js

    r90326 r103620  
    11/*!
    2  * jQuery JavaScript Library v1.11.3
     2 * jQuery JavaScript Library v1.12.4
    33 * http://jquery.com/
    44 *
     
    66 * http://sizzlejs.com/
    77 *
    8  * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
     8 * Copyright jQuery Foundation and other contributors
    99 * Released under the MIT license
    1010 * http://jquery.org/license
    1111 *
    12  * Date: 2015-04-28T16:19Z
     12 * Date: 2016-05-20T17:17Z
    1313 */
    1414
     
    1616
    1717        if ( typeof module === "object" && typeof module.exports === "object" ) {
    18                 // For CommonJS and CommonJS-like environments where a proper window is present,
    19                 // execute the factory and get jQuery
    20                 // For environments that do not inherently posses a window with a document
    21                 // (such as Node.js), expose a jQuery-making factory as module.exports
    22                 // This accentuates the need for the creation of a real window
     18                // For CommonJS and CommonJS-like environments where a proper `window`
     19                // is present, execute the factory and get jQuery.
     20                // For environments that do not have a `window` with a `document`
     21                // (such as Node.js), expose a factory as module.exports.
     22                // This accentuates the need for the creation of a real `window`.
    2323                // e.g. var jQuery = require("jquery")(window);
    24                 // See ticket #14549 for more info
     24                // See ticket #14549 for more info.
    2525                module.exports = global.document ?
    2626                        factory( global, true ) :
     
    3838}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
    3939
    40 // Can't do this because several apps including ASP.NET trace
     40// Support: Firefox 18+
     41// Can't be in strict mode, several libs including ASP.NET trace
    4142// the stack via arguments.caller.callee and Firefox dies if
    4243// you try to trace through "use strict" call chains. (#13335)
    43 // Support: Firefox 18+
    44 //
    45 
     44//"use strict";
    4645var deletedIds = [];
    4746
     47var document = window.document;
     48
    4849var slice = deletedIds.slice;
    4950
     
    6566
    6667var
    67         version = "1.11.3",
     68        version = "1.12.4",
    6869
    6970        // Define a local copy of jQuery
    7071        jQuery = function( selector, context ) {
     72
    7173                // The jQuery object is actually just the init constructor 'enhanced'
    7274                // Need init if jQuery is called (just allow error to be thrown if not included)
     
    8890
    8991jQuery.fn = jQuery.prototype = {
     92
    9093        // The current version of jQuery being used
    9194        jquery: version,
     
    131134
    132135        // Execute a callback for every element in the matched set.
    133         // (You can seed the arguments with an array of args, but this is
    134         // only used internally.)
    135         each: function( callback, args ) {
    136                 return jQuery.each( this, callback, args );
     136        each: function( callback ) {
     137                return jQuery.each( this, callback );
    137138        },
    138139
    139140        map: function( callback ) {
    140                 return this.pushStack( jQuery.map(this, function( elem, i ) {
     141                return this.pushStack( jQuery.map( this, function( elem, i ) {
    141142                        return callback.call( elem, i, elem );
    142                 }));
     143                } ) );
    143144        },
    144145
     
    158159                var len = this.length,
    159160                        j = +i + ( i < 0 ? len : 0 );
    160                 return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
     161                return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
    161162        },
    162163
    163164        end: function() {
    164                 return this.prevObject || this.constructor(null);
     165                return this.prevObject || this.constructor();
    165166        },
    166167
     
    174175jQuery.extend = jQuery.fn.extend = function() {
    175176        var src, copyIsArray, copy, name, options, clone,
    176                 target = arguments[0] || {},
     177                target = arguments[ 0 ] || {},
    177178                i = 1,
    178179                length = arguments.length,
     
    189190
    190191        // Handle case when target is a string or something (possible in deep copy)
    191         if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
     192        if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
    192193                target = {};
    193194        }
     
    200201
    201202        for ( ; i < length; i++ ) {
     203
    202204                // Only deal with non-null/undefined values
    203                 if ( (options = arguments[ i ]) != null ) {
     205                if ( ( options = arguments[ i ] ) != null ) {
     206
    204207                        // Extend the base object
    205208                        for ( name in options ) {
     
    213216
    214217                                // Recurse if we're merging plain objects or arrays
    215                                 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
     218                                if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
     219                                        ( copyIsArray = jQuery.isArray( copy ) ) ) ) {
     220
    216221                                        if ( copyIsArray ) {
    217222                                                copyIsArray = false;
    218                                                 clone = src && jQuery.isArray(src) ? src : [];
     223                                                clone = src && jQuery.isArray( src ) ? src : [];
    219224
    220225                                        } else {
    221                                                 clone = src && jQuery.isPlainObject(src) ? src : {};
     226                                                clone = src && jQuery.isPlainObject( src ) ? src : {};
    222227                                        }
    223228
     
    237242};
    238243
    239 jQuery.extend({
     244jQuery.extend( {
     245
    240246        // Unique for each copy of jQuery on the page
    241247        expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
     
    254260        // aren't supported. They return false on IE (#2968).
    255261        isFunction: function( obj ) {
    256                 return jQuery.type(obj) === "function";
     262                return jQuery.type( obj ) === "function";
    257263        },
    258264
    259265        isArray: Array.isArray || function( obj ) {
    260                 return jQuery.type(obj) === "array";
     266                return jQuery.type( obj ) === "array";
    261267        },
    262268
     
    267273
    268274        isNumeric: function( obj ) {
     275
    269276                // parseFloat NaNs numeric-cast false positives (null|true|false|"")
    270277                // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
    271278                // subtraction forces infinities to NaN
    272279                // adding 1 corrects loss of precision from parseFloat (#15100)
    273                 return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;
     280                var realStringObj = obj && obj.toString();
     281                return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;
    274282        },
    275283
     
    288296                // Because of IE, we also have to check the presence of the constructor property.
    289297                // Make sure that DOM nodes and window objects don't pass through, as well
    290                 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
     298                if ( !obj || jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
    291299                        return false;
    292300                }
    293301
    294302                try {
     303
    295304                        // Not own constructor property must be Object
    296305                        if ( obj.constructor &&
    297                                 !hasOwn.call(obj, "constructor") &&
    298                                 !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
     306                                !hasOwn.call( obj, "constructor" ) &&
     307                                !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
    299308                                return false;
    300309                        }
    301310                } catch ( e ) {
     311
    302312                        // IE8,9 Will throw exceptions on certain host objects #9897
    303313                        return false;
     
    306316                // Support: IE<9
    307317                // Handle iteration over inherited properties before own properties.
    308                 if ( support.ownLast ) {
     318                if ( !support.ownFirst ) {
    309319                        for ( key in obj ) {
    310320                                return hasOwn.call( obj, key );
     
    324334                }
    325335                return typeof obj === "object" || typeof obj === "function" ?
    326                         class2type[ toString.call(obj) ] || "object" :
     336                        class2type[ toString.call( obj ) ] || "object" :
    327337                        typeof obj;
    328338        },
    329339
    330         // Evaluates a script in a global context
    331340        // Workarounds based on findings by Jim Driscoll
    332341        // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
    333342        globalEval: function( data ) {
    334343                if ( data && jQuery.trim( data ) ) {
     344
    335345                        // We use execScript on Internet Explorer
    336346                        // We use an anonymous function so that context is window
    337347                        // rather than jQuery in Firefox
    338348                        ( window.execScript || function( data ) {
    339                                 window[ "eval" ].call( window, data );
     349                                window[ "eval" ].call( window, data ); // jscs:ignore requireDotNotation
    340350                        } )( data );
    341351                }
     
    352362        },
    353363
    354         // args is for internal usage only
    355         each: function( obj, callback, args ) {
    356                 var value,
    357                         i = 0,
    358                         length = obj.length,
    359                         isArray = isArraylike( obj );
    360 
    361                 if ( args ) {
    362                         if ( isArray ) {
    363                                 for ( ; i < length; i++ ) {
    364                                         value = callback.apply( obj[ i ], args );
    365 
    366                                         if ( value === false ) {
    367                                                 break;
    368                                         }
    369                                 }
    370                         } else {
    371                                 for ( i in obj ) {
    372                                         value = callback.apply( obj[ i ], args );
    373 
    374                                         if ( value === false ) {
    375                                                 break;
    376                                         }
    377                                 }
    378                         }
    379 
    380                 // A special, fast, case for the most common use of each
     364        each: function( obj, callback ) {
     365                var length, i = 0;
     366
     367                if ( isArrayLike( obj ) ) {
     368                        length = obj.length;
     369                        for ( ; i < length; i++ ) {
     370                                if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
     371                                        break;
     372                                }
     373                        }
    381374                } else {
    382                         if ( isArray ) {
    383                                 for ( ; i < length; i++ ) {
    384                                         value = callback.call( obj[ i ], i, obj[ i ] );
    385 
    386                                         if ( value === false ) {
    387                                                 break;
    388                                         }
    389                                 }
    390                         } else {
    391                                 for ( i in obj ) {
    392                                         value = callback.call( obj[ i ], i, obj[ i ] );
    393 
    394                                         if ( value === false ) {
    395                                                 break;
    396                                         }
     375                        for ( i in obj ) {
     376                                if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
     377                                        break;
    397378                                }
    398379                        }
     
    414395
    415396                if ( arr != null ) {
    416                         if ( isArraylike( Object(arr) ) ) {
     397                        if ( isArrayLike( Object( arr ) ) ) {
    417398                                jQuery.merge( ret,
    418399                                        typeof arr === "string" ?
     
    439420
    440421                        for ( ; i < len; i++ ) {
     422
    441423                                // Skip accessing in sparse arrays
    442424                                if ( i in arr && arr[ i ] === elem ) {
     
    461443                // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
    462444                if ( len !== len ) {
    463                         while ( second[j] !== undefined ) {
     445                        while ( second[ j ] !== undefined ) {
    464446                                first[ i++ ] = second[ j++ ];
    465447                        }
     
    492474        // arg is for internal usage only
    493475        map: function( elems, callback, arg ) {
    494                 var value,
     476                var length, value,
    495477                        i = 0,
    496                         length = elems.length,
    497                         isArray = isArraylike( elems ),
    498478                        ret = [];
    499479
    500480                // Go through the array, translating each of the items to their new values
    501                 if ( isArray ) {
     481                if ( isArrayLike( elems ) ) {
     482                        length = elems.length;
    502483                        for ( ; i < length; i++ ) {
    503484                                value = callback( elems[ i ], i, arg );
     
    562543        // properties to it so it needs to exist.
    563544        support: support
    564 });
     545} );
     546
     547// JSHint would error on this code due to the Symbol not being defined in ES5.
     548// Defining this global in .jshintrc would create a danger of using the global
     549// unguarded in another place, it seems safer to just disable JSHint for these
     550// three lines.
     551/* jshint ignore: start */
     552if ( typeof Symbol === "function" ) {
     553        jQuery.fn[ Symbol.iterator ] = deletedIds[ Symbol.iterator ];
     554}
     555/* jshint ignore: end */
    565556
    566557// Populate the class2type map
    567 jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
     558jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
     559function( i, name ) {
    568560        class2type[ "[object " + name + "]" ] = name.toLowerCase();
    569 });
    570 
    571 function isArraylike( obj ) {
     561} );
     562
     563function isArrayLike( obj ) {
    572564
    573565        // Support: iOS 8.2 (not reproducible in simulator)
     
    575567        // hasOwn isn't used here due to false negatives
    576568        // regarding Nodelist length in IE
    577         var length = "length" in obj && obj.length,
     569        var length = !!obj && "length" in obj && obj.length,
    578570                type = jQuery.type( obj );
    579571
    580572        if ( type === "function" || jQuery.isWindow( obj ) ) {
    581573                return false;
    582         }
    583 
    584         if ( obj.nodeType === 1 && length ) {
    585                 return true;
    586574        }
    587575
     
    591579var Sizzle =
    592580/*!
    593  * Sizzle CSS Selector Engine v2.2.0-pre
     581 * Sizzle CSS Selector Engine v2.2.1
    594582 * http://sizzlejs.com/
    595583 *
    596  * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors
     584 * Copyright jQuery Foundation and other contributors
    597585 * Released under the MIT license
    598586 * http://jquery.org/license
    599587 *
    600  * Date: 2014-12-16
     588 * Date: 2015-10-17
    601589 */
    602590(function( window ) {
     
    666654        // Regular expressions
    667655
    668         // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
     656        // http://www.w3.org/TR/css3-selectors/#whitespace
    669657        whitespace = "[\\x20\\t\\r\\n\\f]",
    670         // http://www.w3.org/TR/css3-syntax/#characters
    671         characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
    672 
    673         // Loosely modeled on CSS identifier characters
    674         // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
    675         // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
    676         identifier = characterEncoding.replace( "w", "w#" ),
     658
     659        // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
     660        identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
    677661
    678662        // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
    679         attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace +
     663        attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
    680664                // Operator (capture 2)
    681665                "*([*^$|!~]?=)" + whitespace +
     
    684668                "*\\]",
    685669
    686         pseudos = ":(" + characterEncoding + ")(?:\\((" +
     670        pseudos = ":(" + identifier + ")(?:\\((" +
    687671                // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
    688672                // 1. quoted (capture 3; capture 4 or capture 5)
     
    707691
    708692        matchExpr = {
    709                 "ID": new RegExp( "^#(" + characterEncoding + ")" ),
    710                 "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
    711                 "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
     693                "ID": new RegExp( "^#(" + identifier + ")" ),
     694                "CLASS": new RegExp( "^\\.(" + identifier + ")" ),
     695                "TAG": new RegExp( "^(" + identifier + "|[*])" ),
    712696                "ATTR": new RegExp( "^" + attributes ),
    713697                "PSEUDO": new RegExp( "^" + pseudos ),
     
    787771
    788772function Sizzle( selector, context, results, seed ) {
    789         var match, elem, m, nodeType,
    790                 // QSA vars
    791                 i, groups, old, nid, newContext, newSelector;
    792 
    793         if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
    794                 setDocument( context );
    795         }
    796 
    797         context = context || document;
     773        var m, i, elem, nid, nidselect, match, groups, newSelector,
     774                newContext = context && context.ownerDocument,
     775
     776                // nodeType defaults to 9, since context defaults to document
     777                nodeType = context ? context.nodeType : 9;
     778
    798779        results = results || [];
    799         nodeType = context.nodeType;
    800 
     780
     781        // Return early from calls with invalid selector or context
    801782        if ( typeof selector !== "string" || !selector ||
    802783                nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
     
    805786        }
    806787
    807         if ( !seed && documentIsHTML ) {
    808 
    809                 // Try to shortcut find operations when possible (e.g., not under DocumentFragment)
    810                 if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
    811                         // Speed-up: Sizzle("#ID")
    812                         if ( (m = match[1]) ) {
    813                                 if ( nodeType === 9 ) {
    814                                         elem = context.getElementById( m );
    815                                         // Check parentNode to catch when Blackberry 4.6 returns
    816                                         // nodes that are no longer in the document (jQuery #6963)
    817                                         if ( elem && elem.parentNode ) {
    818                                                 // Handle the case where IE, Opera, and Webkit return items
    819                                                 // by name instead of ID
    820                                                 if ( elem.id === m ) {
     788        // Try to shortcut find operations (as opposed to filters) in HTML documents
     789        if ( !seed ) {
     790
     791                if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
     792                        setDocument( context );
     793                }
     794                context = context || document;
     795
     796                if ( documentIsHTML ) {
     797
     798                        // If the selector is sufficiently simple, try using a "get*By*" DOM method
     799                        // (excepting DocumentFragment context, where the methods don't exist)
     800                        if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
     801
     802                                // ID selector
     803                                if ( (m = match[1]) ) {
     804
     805                                        // Document context
     806                                        if ( nodeType === 9 ) {
     807                                                if ( (elem = context.getElementById( m )) ) {
     808
     809                                                        // Support: IE, Opera, Webkit
     810                                                        // TODO: identify versions
     811                                                        // getElementById can match elements by name instead of ID
     812                                                        if ( elem.id === m ) {
     813                                                                results.push( elem );
     814                                                                return results;
     815                                                        }
     816                                                } else {
     817                                                        return results;
     818                                                }
     819
     820                                        // Element context
     821                                        } else {
     822
     823                                                // Support: IE, Opera, Webkit
     824                                                // TODO: identify versions
     825                                                // getElementById can match elements by name instead of ID
     826                                                if ( newContext && (elem = newContext.getElementById( m )) &&
     827                                                        contains( context, elem ) &&
     828                                                        elem.id === m ) {
     829
    821830                                                        results.push( elem );
    822831                                                        return results;
    823832                                                }
     833                                        }
     834
     835                                // Type selector
     836                                } else if ( match[2] ) {
     837                                        push.apply( results, context.getElementsByTagName( selector ) );
     838                                        return results;
     839
     840                                // Class selector
     841                                } else if ( (m = match[3]) && support.getElementsByClassName &&
     842                                        context.getElementsByClassName ) {
     843
     844                                        push.apply( results, context.getElementsByClassName( m ) );
     845                                        return results;
     846                                }
     847                        }
     848
     849                        // Take advantage of querySelectorAll
     850                        if ( support.qsa &&
     851                                !compilerCache[ selector + " " ] &&
     852                                (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
     853
     854                                if ( nodeType !== 1 ) {
     855                                        newContext = context;
     856                                        newSelector = selector;
     857
     858                                // qSA looks outside Element context, which is not what we want
     859                                // Thanks to Andrew Dupont for this workaround technique
     860                                // Support: IE <=8
     861                                // Exclude object elements
     862                                } else if ( context.nodeName.toLowerCase() !== "object" ) {
     863
     864                                        // Capture the context ID, setting it first if necessary
     865                                        if ( (nid = context.getAttribute( "id" )) ) {
     866                                                nid = nid.replace( rescape, "\\$&" );
    824867                                        } else {
     868                                                context.setAttribute( "id", (nid = expando) );
     869                                        }
     870
     871                                        // Prefix every selector in the list
     872                                        groups = tokenize( selector );
     873                                        i = groups.length;
     874                                        nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']";
     875                                        while ( i-- ) {
     876                                                groups[i] = nidselect + " " + toSelector( groups[i] );
     877                                        }
     878                                        newSelector = groups.join( "," );
     879
     880                                        // Expand context for sibling selectors
     881                                        newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
     882                                                context;
     883                                }
     884
     885                                if ( newSelector ) {
     886                                        try {
     887                                                push.apply( results,
     888                                                        newContext.querySelectorAll( newSelector )
     889                                                );
    825890                                                return results;
    826                                         }
    827                                 } else {
    828                                         // Context is not a document
    829                                         if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
    830                                                 contains( context, elem ) && elem.id === m ) {
    831                                                 results.push( elem );
    832                                                 return results;
    833                                         }
    834                                 }
    835 
    836                         // Speed-up: Sizzle("TAG")
    837                         } else if ( match[2] ) {
    838                                 push.apply( results, context.getElementsByTagName( selector ) );
    839                                 return results;
    840 
    841                         // Speed-up: Sizzle(".CLASS")
    842                         } else if ( (m = match[3]) && support.getElementsByClassName ) {
    843                                 push.apply( results, context.getElementsByClassName( m ) );
    844                                 return results;
    845                         }
    846                 }
    847 
    848                 // QSA path
    849                 if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
    850                         nid = old = expando;
    851                         newContext = context;
    852                         newSelector = nodeType !== 1 && selector;
    853 
    854                         // qSA works strangely on Element-rooted queries
    855                         // We can work around this by specifying an extra ID on the root
    856                         // and working up from there (Thanks to Andrew Dupont for the technique)
    857                         // IE 8 doesn't work on object elements
    858                         if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
    859                                 groups = tokenize( selector );
    860 
    861                                 if ( (old = context.getAttribute("id")) ) {
    862                                         nid = old.replace( rescape, "\\$&" );
    863                                 } else {
    864                                         context.setAttribute( "id", nid );
    865                                 }
    866                                 nid = "[id='" + nid + "'] ";
    867 
    868                                 i = groups.length;
    869                                 while ( i-- ) {
    870                                         groups[i] = nid + toSelector( groups[i] );
    871                                 }
    872                                 newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
    873                                 newSelector = groups.join(",");
    874                         }
    875 
    876                         if ( newSelector ) {
    877                                 try {
    878                                         push.apply( results,
    879                                                 newContext.querySelectorAll( newSelector )
    880                                         );
    881                                         return results;
    882                                 } catch(qsaError) {
    883                                 } finally {
    884                                         if ( !old ) {
    885                                                 context.removeAttribute("id");
     891                                        } catch ( qsaError ) {
     892                                        } finally {
     893                                                if ( nid === expando ) {
     894                                                        context.removeAttribute( "id" );
     895                                                }
    886896                                        }
    887897                                }
     
    896906/**
    897907 * Create key-value caches of limited size
    898  * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
     908 * @returns {function(string, object)} Returns the Object data after storing it on itself with
    899909 *      property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
    900910 *      deleting the oldest entry
     
    951961function addHandle( attrs, handler ) {
    952962        var arr = attrs.split("|"),
    953                 i = attrs.length;
     963                i = arr.length;
    954964
    955965        while ( i-- ) {
     
    10641074                doc = node ? node.ownerDocument || node : preferredDoc;
    10651075
    1066         // If no document and documentElement is available, return
     1076        // Return early if doc is invalid or already selected
    10671077        if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
    10681078                return document;
    10691079        }
    10701080
    1071         // Set our document
     1081        // Update global variables
    10721082        document = doc;
    1073         docElem = doc.documentElement;
    1074         parent = doc.defaultView;
    1075 
    1076         // Support: IE>8
    1077         // If iframe document is assigned to "document" variable and if iframe has been reloaded,
    1078         // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
    1079         // IE6-8 do not support the defaultView property so parent will be undefined
    1080         if ( parent && parent !== parent.top ) {
    1081                 // IE11 does not have attachEvent, so all must suffer
     1083        docElem = document.documentElement;
     1084        documentIsHTML = !isXML( document );
     1085
     1086        // Support: IE 9-11, Edge
     1087        // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
     1088        if ( (parent = document.defaultView) && parent.top !== parent ) {
     1089                // Support: IE 11
    10821090                if ( parent.addEventListener ) {
    10831091                        parent.addEventListener( "unload", unloadHandler, false );
     1092
     1093                // Support: IE 9 - 10 only
    10841094                } else if ( parent.attachEvent ) {
    10851095                        parent.attachEvent( "onunload", unloadHandler );
    10861096                }
    10871097        }
    1088 
    1089         /* Support tests
    1090         ---------------------------------------------------------------------- */
    1091         documentIsHTML = !isXML( doc );
    10921098
    10931099        /* Attributes
     
    11071113        // Check if getElementsByTagName("*") returns only elements
    11081114        support.getElementsByTagName = assert(function( div ) {
    1109                 div.appendChild( doc.createComment("") );
     1115                div.appendChild( document.createComment("") );
    11101116                return !div.getElementsByTagName("*").length;
    11111117        });
    11121118
    11131119        // Support: IE<9
    1114         support.getElementsByClassName = rnative.test( doc.getElementsByClassName );
     1120        support.getElementsByClassName = rnative.test( document.getElementsByClassName );
    11151121
    11161122        // Support: IE<10
     
    11201126        support.getById = assert(function( div ) {
    11211127                docElem.appendChild( div ).id = expando;
    1122                 return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
     1128                return !document.getElementsByName || !document.getElementsByName( expando ).length;
    11231129        });
    11241130
     
    11281134                        if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
    11291135                                var m = context.getElementById( id );
    1130                                 // Check parentNode to catch when Blackberry 4.6 returns
    1131                                 // nodes that are no longer in the document #6963
    1132                                 return m && m.parentNode ? [ m ] : [];
     1136                                return m ? [ m ] : [];
    11331137                        }
    11341138                };
     
    11471151                        var attrId = id.replace( runescape, funescape );
    11481152                        return function( elem ) {
    1149                                 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
     1153                                var node = typeof elem.getAttributeNode !== "undefined" &&
     1154                                        elem.getAttributeNode("id");
    11501155                                return node && node.value === attrId;
    11511156                        };
     
    11871192        // Class
    11881193        Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
    1189                 if ( documentIsHTML ) {
     1194                if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
    11901195                        return context.getElementsByClassName( className );
    11911196                }
     
    12071212        rbuggyQSA = [];
    12081213
    1209         if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
     1214        if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
    12101215                // Build QSA regex
    12111216                // Regex strategy adopted from Diego Perini
     
    12171222                        // http://bugs.jquery.com/ticket/12359
    12181223                        docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
    1219                                 "<select id='" + expando + "-\f]' msallowcapture=''>" +
     1224                                "<select id='" + expando + "-\r\\' msallowcapture=''>" +
    12201225                                "<option selected=''></option></select>";
    12211226
     
    12341239                        }
    12351240
    1236                         // Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+
     1241                        // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
    12371242                        if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
    12381243                                rbuggyQSA.push("~=");
     
    12571262                        // Support: Windows 8 Native Apps
    12581263                        // The type and name attributes are restricted during .innerHTML assignment
    1259                         var input = doc.createElement("input");
     1264                        var input = document.createElement("input");
    12601265                        input.setAttribute( "type", "hidden" );
    12611266                        div.appendChild( input ).setAttribute( "name", "D" );
     
    13051310
    13061311        // Element contains another
    1307         // Purposefully does not implement inclusive descendent
     1312        // Purposefully self-exclusive
    13081313        // As in, an element does not contain itself
    13091314        contains = hasCompare || rnative.test( docElem.contains ) ?
     
    13591364
    13601365                        // Choose the first element that is related to our preferred document
    1361                         if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
     1366                        if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
    13621367                                return -1;
    13631368                        }
    1364                         if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
     1369                        if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
    13651370                                return 1;
    13661371                        }
     
    13901395                // Parentless nodes are either documents or disconnected
    13911396                if ( !aup || !bup ) {
    1392                         return a === doc ? -1 :
    1393                                 b === doc ? 1 :
     1397                        return a === document ? -1 :
     1398                                b === document ? 1 :
    13941399                                aup ? -1 :
    13951400                                bup ? 1 :
     
    14281433        };
    14291434
    1430         return doc;
     1435        return document;
    14311436};
    14321437
     
    14451450
    14461451        if ( support.matchesSelector && documentIsHTML &&
     1452                !compilerCache[ expr + " " ] &&
    14471453                ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
    14481454                ( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
     
    17181724
    17191725                                function( elem, context, xml ) {
    1720                                         var cache, outerCache, node, diff, nodeIndex, start,
     1726                                        var cache, uniqueCache, outerCache, node, nodeIndex, start,
    17211727                                                dir = simple !== forward ? "nextSibling" : "previousSibling",
    17221728                                                parent = elem.parentNode,
    17231729                                                name = ofType && elem.nodeName.toLowerCase(),
    1724                                                 useCache = !xml && !ofType;
     1730                                                useCache = !xml && !ofType,
     1731                                                diff = false;
    17251732
    17261733                                        if ( parent ) {
     
    17311738                                                                node = elem;
    17321739                                                                while ( (node = node[ dir ]) ) {
    1733                                                                         if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
     1740                                                                        if ( ofType ?
     1741                                                                                node.nodeName.toLowerCase() === name :
     1742                                                                                node.nodeType === 1 ) {
     1743
    17341744                                                                                return false;
    17351745                                                                        }
     
    17451755                                                // non-xml :nth-child(...) stores cache data on `parent`
    17461756                                                if ( forward && useCache ) {
     1757
    17471758                                                        // Seek `elem` from a previously-cached index
    1748                                                         outerCache = parent[ expando ] || (parent[ expando ] = {});
    1749                                                         cache = outerCache[ type ] || [];
    1750                                                         nodeIndex = cache[0] === dirruns && cache[1];
    1751                                                         diff = cache[0] === dirruns && cache[2];
     1759
     1760                                                        // ...in a gzip-friendly way
     1761                                                        node = parent;
     1762                                                        outerCache = node[ expando ] || (node[ expando ] = {});
     1763
     1764                                                        // Support: IE <9 only
     1765                                                        // Defend against cloned attroperties (jQuery gh-1709)
     1766                                                        uniqueCache = outerCache[ node.uniqueID ] ||
     1767                                                                (outerCache[ node.uniqueID ] = {});
     1768
     1769                                                        cache = uniqueCache[ type ] || [];
     1770                                                        nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
     1771                                                        diff = nodeIndex && cache[ 2 ];
    17521772                                                        node = nodeIndex && parent.childNodes[ nodeIndex ];
    17531773
     
    17591779                                                                // When found, cache indexes on `parent` and break
    17601780                                                                if ( node.nodeType === 1 && ++diff && node === elem ) {
    1761                                                                         outerCache[ type ] = [ dirruns, nodeIndex, diff ];
     1781                                                                        uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
    17621782                                                                        break;
    17631783                                                                }
    17641784                                                        }
    17651785
    1766                                                 // Use previously-cached element index if available
    1767                                                 } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
    1768                                                         diff = cache[1];
    1769 
    1770                                                 // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
    17711786                                                } else {
    1772                                                         // Use the same loop as above to seek `elem` from the start
    1773                                                         while ( (node = ++nodeIndex && node && node[ dir ] ||
    1774                                                                 (diff = nodeIndex = 0) || start.pop()) ) {
    1775 
    1776                                                                 if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
    1777                                                                         // Cache the index of each encountered element
    1778                                                                         if ( useCache ) {
    1779                                                                                 (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
    1780                                                                         }
    1781 
    1782                                                                         if ( node === elem ) {
    1783                                                                                 break;
     1787                                                        // Use previously-cached element index if available
     1788                                                        if ( useCache ) {
     1789                                                                // ...in a gzip-friendly way
     1790                                                                node = elem;
     1791                                                                outerCache = node[ expando ] || (node[ expando ] = {});
     1792
     1793                                                                // Support: IE <9 only
     1794                                                                // Defend against cloned attroperties (jQuery gh-1709)
     1795                                                                uniqueCache = outerCache[ node.uniqueID ] ||
     1796                                                                        (outerCache[ node.uniqueID ] = {});
     1797
     1798                                                                cache = uniqueCache[ type ] || [];
     1799                                                                nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
     1800                                                                diff = nodeIndex;
     1801                                                        }
     1802
     1803                                                        // xml :nth-child(...)
     1804                                                        // or :nth-last-child(...) or :nth(-last)?-of-type(...)
     1805                                                        if ( diff === false ) {
     1806                                                                // Use the same loop as above to seek `elem` from the start
     1807                                                                while ( (node = ++nodeIndex && node && node[ dir ] ||
     1808                                                                        (diff = nodeIndex = 0) || start.pop()) ) {
     1809
     1810                                                                        if ( ( ofType ?
     1811                                                                                node.nodeName.toLowerCase() === name :
     1812                                                                                node.nodeType === 1 ) &&
     1813                                                                                ++diff ) {
     1814
     1815                                                                                // Cache the index of each encountered element
     1816                                                                                if ( useCache ) {
     1817                                                                                        outerCache = node[ expando ] || (node[ expando ] = {});
     1818
     1819                                                                                        // Support: IE <9 only
     1820                                                                                        // Defend against cloned attroperties (jQuery gh-1709)
     1821                                                                                        uniqueCache = outerCache[ node.uniqueID ] ||
     1822                                                                                                (outerCache[ node.uniqueID ] = {});
     1823
     1824                                                                                        uniqueCache[ type ] = [ dirruns, diff ];
     1825                                                                                }
     1826
     1827                                                                                if ( node === elem ) {
     1828                                                                                        break;
     1829                                                                                }
    17841830                                                                        }
    17851831                                                                }
     
    21432189                // Check against all ancestor/preceding elements
    21442190                function( elem, context, xml ) {
    2145                         var oldCache, outerCache,
     2191                        var oldCache, uniqueCache, outerCache,
    21462192                                newCache = [ dirruns, doneName ];
    21472193
    2148                         // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
     2194                        // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
    21492195                        if ( xml ) {
    21502196                                while ( (elem = elem[ dir ]) ) {
     
    21592205                                        if ( elem.nodeType === 1 || checkNonElements ) {
    21602206                                                outerCache = elem[ expando ] || (elem[ expando ] = {});
    2161                                                 if ( (oldCache = outerCache[ dir ]) &&
     2207
     2208                                                // Support: IE <9 only
     2209                                                // Defend against cloned attroperties (jQuery gh-1709)
     2210                                                uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
     2211
     2212                                                if ( (oldCache = uniqueCache[ dir ]) &&
    21622213                                                        oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
    21632214
     
    21662217                                                } else {
    21672218                                                        // Reuse newcache so results back-propagate to previous elements
    2168                                                         outerCache[ dir ] = newCache;
     2219                                                        uniqueCache[ dir ] = newCache;
    21692220
    21702221                                                        // A match means we're done; a fail means we have to keep checking
     
    23912442
    23922443                        if ( outermost ) {
    2393                                 outermostContext = context !== document && context;
     2444                                outermostContext = context === document || context || outermost;
    23942445                        }
    23952446
    23962447                        // Add elements passing elementMatchers directly to results
    2397                         // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
    23982448                        // Support: IE<9, Safari
    23992449                        // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
     
    24012451                                if ( byElement && elem ) {
    24022452                                        j = 0;
     2453                                        if ( !context && elem.ownerDocument !== document ) {
     2454                                                setDocument( elem );
     2455                                                xml = !documentIsHTML;
     2456                                        }
    24032457                                        while ( (matcher = elementMatchers[j++]) ) {
    2404                                                 if ( matcher( elem, context, xml ) ) {
     2458                                                if ( matcher( elem, context || document, xml) ) {
    24052459                                                        results.push( elem );
    24062460                                                        break;
     
    24262480                        }
    24272481
     2482                        // `i` is now the count of elements visited above, and adding it to `matchedCount`
     2483                        // makes the latter nonnegative.
     2484                        matchedCount += i;
     2485
    24282486                        // Apply set filters to unmatched elements
    2429                         matchedCount += i;
     2487                        // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
     2488                        // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
     2489                        // no element matchers and no seed.
     2490                        // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
     2491                        // case, which will result in a "00" `matchedCount` that differs from `i` but is also
     2492                        // numerically zero.
    24302493                        if ( bySet && i !== matchedCount ) {
    24312494                                j = 0;
     
    25192582        results = results || [];
    25202583
    2521         // Try to minimize operations if there is no seed and only one group
     2584        // Try to minimize operations if there is only one selector in the list and no seed
     2585        // (the latter of which guarantees us context)
    25222586        if ( match.length === 1 ) {
    25232587
    2524                 // Take a shortcut and set the context if the root selector is an ID
     2588                // Reduce context if the leading compound selector is an ID
    25252589                tokens = match[0] = match[0].slice( 0 );
    25262590                if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
     
    25772641                !documentIsHTML,
    25782642                results,
    2579                 rsibling.test( selector ) && testContext( context.parentNode ) || context
     2643                !context || rsibling.test( selector ) && testContext( context.parentNode ) || context
    25802644        );
    25812645        return results;
     
    26532717jQuery.find = Sizzle;
    26542718jQuery.expr = Sizzle.selectors;
    2655 jQuery.expr[":"] = jQuery.expr.pseudos;
    2656 jQuery.unique = Sizzle.uniqueSort;
     2719jQuery.expr[ ":" ] = jQuery.expr.pseudos;
     2720jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
    26572721jQuery.text = Sizzle.getText;
    26582722jQuery.isXMLDoc = Sizzle.isXML;
     
    26612725
    26622726
     2727var dir = function( elem, dir, until ) {
     2728        var matched = [],
     2729                truncate = until !== undefined;
     2730
     2731        while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
     2732                if ( elem.nodeType === 1 ) {
     2733                        if ( truncate && jQuery( elem ).is( until ) ) {
     2734                                break;
     2735                        }
     2736                        matched.push( elem );
     2737                }
     2738        }
     2739        return matched;
     2740};
     2741
     2742
     2743var siblings = function( n, elem ) {
     2744        var matched = [];
     2745
     2746        for ( ; n; n = n.nextSibling ) {
     2747                if ( n.nodeType === 1 && n !== elem ) {
     2748                        matched.push( n );
     2749                }
     2750        }
     2751
     2752        return matched;
     2753};
     2754
     2755
    26632756var rneedsContext = jQuery.expr.match.needsContext;
    26642757
    2665 var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/);
     2758var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );
    26662759
    26672760
     
    26752768                        /* jshint -W018 */
    26762769                        return !!qualifier.call( elem, i, elem ) !== not;
    2677                 });
     2770                } );
    26782771
    26792772        }
     
    26822775                return jQuery.grep( elements, function( elem ) {
    26832776                        return ( elem === qualifier ) !== not;
    2684                 });
     2777                } );
    26852778
    26862779        }
     
    26952788
    26962789        return jQuery.grep( elements, function( elem ) {
    2697                 return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;
    2698         });
     2790                return ( jQuery.inArray( elem, qualifier ) > -1 ) !== not;
     2791        } );
    26992792}
    27002793
     
    27102803                jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
    27112804                        return elem.nodeType === 1;
    2712                 }));
     2805                } ) );
    27132806};
    27142807
    2715 jQuery.fn.extend({
     2808jQuery.fn.extend( {
    27162809        find: function( selector ) {
    27172810                var i,
     
    27212814
    27222815                if ( typeof selector !== "string" ) {
    2723                         return this.pushStack( jQuery( selector ).filter(function() {
     2816                        return this.pushStack( jQuery( selector ).filter( function() {
    27242817                                for ( i = 0; i < len; i++ ) {
    27252818                                        if ( jQuery.contains( self[ i ], this ) ) {
     
    27272820                                        }
    27282821                                }
    2729                         }) );
     2822                        } ) );
    27302823                }
    27312824
     
    27402833        },
    27412834        filter: function( selector ) {
    2742                 return this.pushStack( winnow(this, selector || [], false) );
     2835                return this.pushStack( winnow( this, selector || [], false ) );
    27432836        },
    27442837        not: function( selector ) {
    2745                 return this.pushStack( winnow(this, selector || [], true) );
     2838                return this.pushStack( winnow( this, selector || [], true ) );
    27462839        },
    27472840        is: function( selector ) {
     
    27572850                ).length;
    27582851        }
    2759 });
     2852} );
    27602853
    27612854
     
    27652858// A central reference to the root jQuery(document)
    27662859var rootjQuery,
    2767 
    2768         // Use the correct document accordingly with window argument (sandbox)
    2769         document = window.document,
    27702860
    27712861        // A simple way to check for HTML strings
     
    27742864        rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
    27752865
    2776         init = jQuery.fn.init = function( selector, context ) {
     2866        init = jQuery.fn.init = function( selector, context, root ) {
    27772867                var match, elem;
    27782868
     
    27822872                }
    27832873
     2874                // init accepts an alternate rootjQuery
     2875                // so migrate can support jQuery.sub (gh-2101)
     2876                root = root || rootjQuery;
     2877
    27842878                // Handle HTML strings
    27852879                if ( typeof selector === "string" ) {
    2786                         if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
     2880                        if ( selector.charAt( 0 ) === "<" &&
     2881                                selector.charAt( selector.length - 1 ) === ">" &&
     2882                                selector.length >= 3 ) {
     2883
    27872884                                // Assume that strings that start and end with <> are HTML and skip the regex check
    27882885                                match = [ null, selector, null ];
     
    27932890
    27942891                        // Match html or make sure no context is specified for #id
    2795                         if ( match && (match[1] || !context) ) {
     2892                        if ( match && ( match[ 1 ] || !context ) ) {
    27962893
    27972894                                // HANDLE: $(html) -> $(array)
    2798                                 if ( match[1] ) {
    2799                                         context = context instanceof jQuery ? context[0] : context;
     2895                                if ( match[ 1 ] ) {
     2896                                        context = context instanceof jQuery ? context[ 0 ] : context;
    28002897
    28012898                                        // scripts is true for back-compat
    28022899                                        // Intentionally let the error be thrown if parseHTML is not present
    28032900                                        jQuery.merge( this, jQuery.parseHTML(
    2804                                                 match[1],
     2901                                                match[ 1 ],
    28052902                                                context && context.nodeType ? context.ownerDocument || context : document,
    28062903                                                true
     
    28082905
    28092906                                        // HANDLE: $(html, props)
    2810                                         if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
     2907                                        if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
    28112908                                                for ( match in context ) {
     2909
    28122910                                                        // Properties of context are called as methods if possible
    28132911                                                        if ( jQuery.isFunction( this[ match ] ) ) {
     
    28252923                                // HANDLE: $(#id)
    28262924                                } else {
    2827                                         elem = document.getElementById( match[2] );
     2925                                        elem = document.getElementById( match[ 2 ] );
    28282926
    28292927                                        // Check parentNode to catch when Blackberry 4.6 returns
    28302928                                        // nodes that are no longer in the document #6963
    28312929                                        if ( elem && elem.parentNode ) {
     2930
    28322931                                                // Handle the case where IE and Opera return items
    28332932                                                // by name instead of ID
    2834                                                 if ( elem.id !== match[2] ) {
     2933                                                if ( elem.id !== match[ 2 ] ) {
    28352934                                                        return rootjQuery.find( selector );
    28362935                                                }
     
    28382937                                                // Otherwise, we inject the element directly into the jQuery object
    28392938                                                this.length = 1;
    2840                                                 this[0] = elem;
     2939                                                this[ 0 ] = elem;
    28412940                                        }
    28422941
     
    28482947                        // HANDLE: $(expr, $(...))
    28492948                        } else if ( !context || context.jquery ) {
    2850                                 return ( context || rootjQuery ).find( selector );
     2949                                return ( context || root ).find( selector );
    28512950
    28522951                        // HANDLE: $(expr, context)
     
    28582957                // HANDLE: $(DOMElement)
    28592958                } else if ( selector.nodeType ) {
    2860                         this.context = this[0] = selector;
     2959                        this.context = this[ 0 ] = selector;
    28612960                        this.length = 1;
    28622961                        return this;
     
    28652964                // Shortcut for document ready
    28662965                } else if ( jQuery.isFunction( selector ) ) {
    2867                         return typeof rootjQuery.ready !== "undefined" ?
    2868                                 rootjQuery.ready( selector ) :
     2966                        return typeof root.ready !== "undefined" ?
     2967                                root.ready( selector ) :
     2968
    28692969                                // Execute immediately if ready is not present
    28702970                                selector( jQuery );
     
    28872987
    28882988var rparentsprev = /^(?:parents|prev(?:Until|All))/,
     2989
    28892990        // methods guaranteed to produce a unique set when starting from a unique set
    28902991        guaranteedUnique = {
     
    28952996        };
    28962997
    2897 jQuery.extend({
    2898         dir: function( elem, dir, until ) {
    2899                 var matched = [],
    2900                         cur = elem[ dir ];
    2901 
    2902                 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
    2903                         if ( cur.nodeType === 1 ) {
    2904                                 matched.push( cur );
    2905                         }
    2906                         cur = cur[dir];
    2907                 }
    2908                 return matched;
    2909         },
    2910 
    2911         sibling: function( n, elem ) {
    2912                 var r = [];
    2913 
    2914                 for ( ; n; n = n.nextSibling ) {
    2915                         if ( n.nodeType === 1 && n !== elem ) {
    2916                                 r.push( n );
    2917                         }
    2918                 }
    2919 
    2920                 return r;
    2921         }
    2922 });
    2923 
    2924 jQuery.fn.extend({
     2998jQuery.fn.extend( {
    29252999        has: function( target ) {
    29263000                var i,
     
    29283002                        len = targets.length;
    29293003
    2930                 return this.filter(function() {
     3004                return this.filter( function() {
    29313005                        for ( i = 0; i < len; i++ ) {
    2932                                 if ( jQuery.contains( this, targets[i] ) ) {
     3006                                if ( jQuery.contains( this, targets[ i ] ) ) {
    29333007                                        return true;
    29343008                                }
    29353009                        }
    2936                 });
     3010                } );
    29373011        },
    29383012
     
    29473021
    29483022                for ( ; i < l; i++ ) {
    2949                         for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
     3023                        for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
     3024
    29503025                                // Always skip document fragments
    2951                                 if ( cur.nodeType < 11 && (pos ?
    2952                                         pos.index(cur) > -1 :
     3026                                if ( cur.nodeType < 11 && ( pos ?
     3027                                        pos.index( cur ) > -1 :
    29533028
    29543029                                        // Don't pass non-elements to Sizzle
    29553030                                        cur.nodeType === 1 &&
    2956                                                 jQuery.find.matchesSelector(cur, selectors)) ) {
     3031                                                jQuery.find.matchesSelector( cur, selectors ) ) ) {
    29573032
    29583033                                        matched.push( cur );
     
    29623037                }
    29633038
    2964                 return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
     3039                return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
    29653040        },
    29663041
     
    29713046                // No argument, return index in parent
    29723047                if ( !elem ) {
    2973                         return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;
     3048                        return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
    29743049                }
    29753050
    29763051                // index in selector
    29773052                if ( typeof elem === "string" ) {
    2978                         return jQuery.inArray( this[0], jQuery( elem ) );
     3053                        return jQuery.inArray( this[ 0 ], jQuery( elem ) );
    29793054                }
    29803055
    29813056                // Locate the position of the desired element
    29823057                return jQuery.inArray(
     3058
    29833059                        // If it receives a jQuery object, the first element is used
    2984                         elem.jquery ? elem[0] : elem, this );
     3060                        elem.jquery ? elem[ 0 ] : elem, this );
    29853061        },
    29863062
    29873063        add: function( selector, context ) {
    29883064                return this.pushStack(
    2989                         jQuery.unique(
     3065                        jQuery.uniqueSort(
    29903066                                jQuery.merge( this.get(), jQuery( selector, context ) )
    29913067                        )
     
    29953071        addBack: function( selector ) {
    29963072                return this.add( selector == null ?
    2997                         this.prevObject : this.prevObject.filter(selector)
     3073                        this.prevObject : this.prevObject.filter( selector )
    29983074                );
    29993075        }
    3000 });
     3076} );
    30013077
    30023078function sibling( cur, dir ) {
     
    30083084}
    30093085
    3010 jQuery.each({
     3086jQuery.each( {
    30113087        parent: function( elem ) {
    30123088                var parent = elem.parentNode;
     
    30143090        },
    30153091        parents: function( elem ) {
    3016                 return jQuery.dir( elem, "parentNode" );
     3092                return dir( elem, "parentNode" );
    30173093        },
    30183094        parentsUntil: function( elem, i, until ) {
    3019                 return jQuery.dir( elem, "parentNode", until );
     3095                return dir( elem, "parentNode", until );
    30203096        },
    30213097        next: function( elem ) {
     
    30263102        },
    30273103        nextAll: function( elem ) {
    3028                 return jQuery.dir( elem, "nextSibling" );
     3104                return dir( elem, "nextSibling" );
    30293105        },
    30303106        prevAll: function( elem ) {
    3031                 return jQuery.dir( elem, "previousSibling" );
     3107                return dir( elem, "previousSibling" );
    30323108        },
    30333109        nextUntil: function( elem, i, until ) {
    3034                 return jQuery.dir( elem, "nextSibling", until );
     3110                return dir( elem, "nextSibling", until );
    30353111        },
    30363112        prevUntil: function( elem, i, until ) {
    3037                 return jQuery.dir( elem, "previousSibling", until );
     3113                return dir( elem, "previousSibling", until );
    30383114        },
    30393115        siblings: function( elem ) {
    3040                 return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
     3116                return siblings( ( elem.parentNode || {} ).firstChild, elem );
    30413117        },
    30423118        children: function( elem ) {
    3043                 return jQuery.sibling( elem.firstChild );
     3119                return siblings( elem.firstChild );
    30443120        },
    30453121        contents: function( elem ) {
     
    30613137
    30623138                if ( this.length > 1 ) {
     3139
    30633140                        // Remove duplicates
    30643141                        if ( !guaranteedUnique[ name ] ) {
    3065                                 ret = jQuery.unique( ret );
     3142                                ret = jQuery.uniqueSort( ret );
    30663143                        }
    30673144
     
    30743151                return this.pushStack( ret );
    30753152        };
    3076 });
    3077 var rnotwhite = (/\S+/g);
    3078 
    3079 
    3080 
    3081 // String to Object options format cache
    3082 var optionsCache = {};
    3083 
    3084 // Convert String-formatted options into Object-formatted ones and store in cache
     3153} );
     3154var rnotwhite = ( /\S+/g );
     3155
     3156
     3157
     3158// Convert String-formatted options into Object-formatted ones
    30853159function createOptions( options ) {
    3086         var object = optionsCache[ options ] = {};
     3160        var object = {};
    30873161        jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
    30883162                object[ flag ] = true;
    3089         });
     3163        } );
    30903164        return object;
    30913165}
     
    31183192        // (we check in cache first)
    31193193        options = typeof options === "string" ?
    3120                 ( optionsCache[ options ] || createOptions( options ) ) :
     3194                createOptions( options ) :
    31213195                jQuery.extend( {}, options );
    31223196
    31233197        var // Flag to know if list is currently firing
    31243198                firing,
    3125                 // Last fire value (for non-forgettable lists)
     3199
     3200                // Last fire value for non-forgettable lists
    31263201                memory,
     3202
    31273203                // Flag to know if list was already fired
    31283204                fired,
    3129                 // End of the loop when firing
    3130                 firingLength,
    3131                 // Index of currently firing callback (modified by remove if needed)
    3132                 firingIndex,
    3133                 // First callback to fire (used internally by add and fireWith)
    3134                 firingStart,
     3205
     3206                // Flag to prevent firing
     3207                locked,
     3208
    31353209                // Actual callback list
    31363210                list = [],
    3137                 // Stack of fire calls for repeatable lists
    3138                 stack = !options.once && [],
     3211
     3212                // Queue of execution data for repeatable lists
     3213                queue = [],
     3214
     3215                // Index of currently firing callback (modified by add/remove as needed)
     3216                firingIndex = -1,
     3217
    31393218                // Fire callbacks
    3140                 fire = function( data ) {
    3141                         memory = options.memory && data;
    3142                         fired = true;
    3143                         firingIndex = firingStart || 0;
    3144                         firingStart = 0;
    3145                         firingLength = list.length;
    3146                         firing = true;
    3147                         for ( ; list && firingIndex < firingLength; firingIndex++ ) {
    3148                                 if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
    3149                                         memory = false; // To prevent further calls using add
    3150                                         break;
    3151                                 }
    3152                         }
     3219                fire = function() {
     3220
     3221                        // Enforce single-firing
     3222                        locked = options.once;
     3223
     3224                        // Execute callbacks for all pending executions,
     3225                        // respecting firingIndex overrides and runtime changes
     3226                        fired = firing = true;
     3227                        for ( ; queue.length; firingIndex = -1 ) {
     3228                                memory = queue.shift();
     3229                                while ( ++firingIndex < list.length ) {
     3230
     3231                                        // Run callback and check for early termination
     3232                                        if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
     3233                                                options.stopOnFalse ) {
     3234
     3235                                                // Jump to end and forget the data so .add doesn't re-fire
     3236                                                firingIndex = list.length;
     3237                                                memory = false;
     3238                                        }
     3239                                }
     3240                        }
     3241
     3242                        // Forget the data if we're done with it
     3243                        if ( !options.memory ) {
     3244                                memory = false;
     3245                        }
     3246
    31533247                        firing = false;
    3154                         if ( list ) {
    3155                                 if ( stack ) {
    3156                                         if ( stack.length ) {
    3157                                                 fire( stack.shift() );
    3158                                         }
    3159                                 } else if ( memory ) {
     3248
     3249                        // Clean up if we're done firing for good
     3250                        if ( locked ) {
     3251
     3252                                // Keep an empty list if we have data for future add calls
     3253                                if ( memory ) {
    31603254                                        list = [];
     3255
     3256                                // Otherwise, this object is spent
    31613257                                } else {
    3162                                         self.disable();
     3258                                        list = "";
    31633259                                }
    31643260                        }
    31653261                },
     3262
    31663263                // Actual Callbacks object
    31673264                self = {
     3265
    31683266                        // Add a callback or a collection of callbacks to the list
    31693267                        add: function() {
    31703268                                if ( list ) {
    3171                                         // First, we save the current length
    3172                                         var start = list.length;
    3173                                         (function add( args ) {
     3269
     3270                                        // If we have memory from a past run, we should fire after adding
     3271                                        if ( memory && !firing ) {
     3272                                                firingIndex = list.length - 1;
     3273                                                queue.push( memory );
     3274                                        }
     3275
     3276                                        ( function add( args ) {
    31743277                                                jQuery.each( args, function( _, arg ) {
    3175                                                         var type = jQuery.type( arg );
    3176                                                         if ( type === "function" ) {
     3278                                                        if ( jQuery.isFunction( arg ) ) {
    31773279                                                                if ( !options.unique || !self.has( arg ) ) {
    31783280                                                                        list.push( arg );
    31793281                                                                }
    3180                                                         } else if ( arg && arg.length && type !== "string" ) {
     3282                                                        } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
     3283
    31813284                                                                // Inspect recursively
    31823285                                                                add( arg );
    31833286                                                        }
    3184                                                 });
    3185                                         })( arguments );
    3186                                         // Do we need to add the callbacks to the
    3187                                         // current firing batch?
    3188                                         if ( firing ) {
    3189                                                 firingLength = list.length;
    3190                                         // With memory, if we're not firing then
    3191                                         // we should call right away
    3192                                         } else if ( memory ) {
    3193                                                 firingStart = start;
    3194                                                 fire( memory );
     3287                                                } );
     3288                                        } )( arguments );
     3289
     3290                                        if ( memory && !firing ) {
     3291                                                fire();
    31953292                                        }
    31963293                                }
    31973294                                return this;
    31983295                        },
     3296
    31993297                        // Remove a callback from the list
    32003298                        remove: function() {
    3201                                 if ( list ) {
    3202                                         jQuery.each( arguments, function( _, arg ) {
    3203                                                 var index;
    3204                                                 while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
    3205                                                         list.splice( index, 1 );
    3206                                                         // Handle firing indexes
    3207                                                         if ( firing ) {
    3208                                                                 if ( index <= firingLength ) {
    3209                                                                         firingLength--;
    3210                                                                 }
    3211                                                                 if ( index <= firingIndex ) {
    3212                                                                         firingIndex--;
    3213                                                                 }
    3214                                                         }
     3299                                jQuery.each( arguments, function( _, arg ) {
     3300                                        var index;
     3301                                        while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
     3302                                                list.splice( index, 1 );
     3303
     3304                                                // Handle firing indexes
     3305                                                if ( index <= firingIndex ) {
     3306                                                        firingIndex--;
    32153307                                                }
    3216                                         });
    3217                                 }
     3308                                        }
     3309                                } );
    32183310                                return this;
    32193311                        },
     3312
    32203313                        // Check if a given callback is in the list.
    32213314                        // If no argument is given, return whether or not list has callbacks attached.
    32223315                        has: function( fn ) {
    3223                                 return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
     3316                                return fn ?
     3317                                        jQuery.inArray( fn, list ) > -1 :
     3318                                        list.length > 0;
    32243319                        },
     3320
    32253321                        // Remove all callbacks from the list
    32263322                        empty: function() {
    3227                                 list = [];
    3228                                 firingLength = 0;
     3323                                if ( list ) {
     3324                                        list = [];
     3325                                }
    32293326                                return this;
    32303327                        },
    3231                         // Have the list do nothing anymore
     3328
     3329                        // Disable .fire and .add
     3330                        // Abort any current/pending executions
     3331                        // Clear all callbacks and values
    32323332                        disable: function() {
    3233                                 list = stack = memory = undefined;
     3333                                locked = queue = [];
     3334                                list = memory = "";
    32343335                                return this;
    32353336                        },
    3236                         // Is it disabled?
    32373337                        disabled: function() {
    32383338                                return !list;
    32393339                        },
    3240                         // Lock the list in its current state
     3340
     3341                        // Disable .fire
     3342                        // Also disable .add unless we have memory (since it would have no effect)
     3343                        // Abort any pending executions
    32413344                        lock: function() {
    3242                                 stack = undefined;
     3345                                locked = true;
    32433346                                if ( !memory ) {
    32443347                                        self.disable();
     
    32463349                                return this;
    32473350                        },
    3248                         // Is it locked?
    32493351                        locked: function() {
    3250                                 return !stack;
     3352                                return !!locked;
    32513353                        },
     3354
    32523355                        // Call all callbacks with the given context and arguments
    32533356                        fireWith: function( context, args ) {
    3254                                 if ( list && ( !fired || stack ) ) {
     3357                                if ( !locked ) {
    32553358                                        args = args || [];
    32563359                                        args = [ context, args.slice ? args.slice() : args ];
    3257                                         if ( firing ) {
    3258                                                 stack.push( args );
    3259                                         } else {
    3260                                                 fire( args );
     3360                                        queue.push( args );
     3361                                        if ( !firing ) {
     3362                                                fire();
    32613363                                        }
    32623364                                }
    32633365                                return this;
    32643366                        },
     3367
    32653368                        // Call all the callbacks with the given arguments
    32663369                        fire: function() {
     
    32683371                                return this;
    32693372                        },
     3373
    32703374                        // To know if the callbacks have already been called at least once
    32713375                        fired: function() {
     
    32783382
    32793383
    3280 jQuery.extend({
     3384jQuery.extend( {
    32813385
    32823386        Deferred: function( func ) {
    32833387                var tuples = [
     3388
    32843389                                // action, add listener, listener list, final state
    3285                                 [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
    3286                                 [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
    3287                                 [ "notify", "progress", jQuery.Callbacks("memory") ]
     3390                                [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ],
     3391                                [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ],
     3392                                [ "notify", "progress", jQuery.Callbacks( "memory" ) ]
    32883393                        ],
    32893394                        state = "pending",
     
    32983403                                then: function( /* fnDone, fnFail, fnProgress */ ) {
    32993404                                        var fns = arguments;
    3300                                         return jQuery.Deferred(function( newDefer ) {
     3405                                        return jQuery.Deferred( function( newDefer ) {
    33013406                                                jQuery.each( tuples, function( i, tuple ) {
    33023407                                                        var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
     3408
    33033409                                                        // deferred[ done | fail | progress ] for forwarding actions to newDefer
    3304                                                         deferred[ tuple[1] ](function() {
     3410                                                        deferred[ tuple[ 1 ] ]( function() {
    33053411                                                                var returned = fn && fn.apply( this, arguments );
    33063412                                                                if ( returned && jQuery.isFunction( returned.promise ) ) {
    33073413                                                                        returned.promise()
     3414                                                                                .progress( newDefer.notify )
    33083415                                                                                .done( newDefer.resolve )
    3309                                                                                 .fail( newDefer.reject )
    3310                                                                                 .progress( newDefer.notify );
     3416                                                                                .fail( newDefer.reject );
    33113417                                                                } else {
    3312                                                                         newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
     3418                                                                        newDefer[ tuple[ 0 ] + "With" ](
     3419                                                                                this === promise ? newDefer.promise() : this,
     3420                                                                                fn ? [ returned ] : arguments
     3421                                                                        );
    33133422                                                                }
    3314                                                         });
    3315                                                 });
     3423                                                        } );
     3424                                                } );
    33163425                                                fns = null;
    3317                                         }).promise();
     3426                                        } ).promise();
    33183427                                },
     3428
    33193429                                // Get a promise for this deferred
    33203430                                // If obj is provided, the promise aspect is added to the object
     
    33343444
    33353445                        // promise[ done | fail | progress ] = list.add
    3336                         promise[ tuple[1] ] = list.add;
     3446                        promise[ tuple[ 1 ] ] = list.add;
    33373447
    33383448                        // Handle state
    33393449                        if ( stateString ) {
    3340                                 list.add(function() {
     3450                                list.add( function() {
     3451
    33413452                                        // state = [ resolved | rejected ]
    33423453                                        state = stateString;
     
    33473458
    33483459                        // deferred[ resolve | reject | notify ]
    3349                         deferred[ tuple[0] ] = function() {
    3350                                 deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
     3460                        deferred[ tuple[ 0 ] ] = function() {
     3461                                deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
    33513462                                return this;
    33523463                        };
    3353                         deferred[ tuple[0] + "With" ] = list.fireWith;
    3354                 });
     3464                        deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
     3465                } );
    33553466
    33563467                // Make the deferred a promise
     
    33733484
    33743485                        // the count of uncompleted subordinates
    3375                         remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
    3376 
    3377                         // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
     3486                        remaining = length !== 1 ||
     3487                                ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
     3488
     3489                        // the master Deferred.
     3490                        // If resolveValues consist of only a single Deferred, just use that.
    33783491                        deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
    33793492
     
    33863499                                                deferred.notifyWith( contexts, values );
    33873500
    3388                                         } else if ( !(--remaining) ) {
     3501                                        } else if ( !( --remaining ) ) {
    33893502                                                deferred.resolveWith( contexts, values );
    33903503                                        }
     
    34023515                                if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
    34033516                                        resolveValues[ i ].promise()
     3517                                                .progress( updateFunc( i, progressContexts, progressValues ) )
    34043518                                                .done( updateFunc( i, resolveContexts, resolveValues ) )
    3405                                                 .fail( deferred.reject )
    3406                                                 .progress( updateFunc( i, progressContexts, progressValues ) );
     3519                                                .fail( deferred.reject );
    34073520                                } else {
    34083521                                        --remaining;
     
    34183531                return deferred.promise();
    34193532        }
    3420 });
     3533} );
    34213534
    34223535
     
    34253538
    34263539jQuery.fn.ready = function( fn ) {
     3540
    34273541        // Add the callback
    34283542        jQuery.ready.promise().done( fn );
     
    34313545};
    34323546
    3433 jQuery.extend({
     3547jQuery.extend( {
     3548
    34343549        // Is the DOM ready to be used? Set to true once it occurs.
    34353550        isReady: false,
     
    34563571                }
    34573572
    3458                 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
    3459                 if ( !document.body ) {
    3460                         return setTimeout( jQuery.ready );
    3461                 }
    3462 
    34633573                // Remember that the DOM is ready
    34643574                jQuery.isReady = true;
     
    34783588                }
    34793589        }
    3480 });
     3590} );
    34813591
    34823592/**
     
    34853595function detach() {
    34863596        if ( document.addEventListener ) {
    3487                 document.removeEventListener( "DOMContentLoaded", completed, false );
    3488                 window.removeEventListener( "load", completed, false );
     3597                document.removeEventListener( "DOMContentLoaded", completed );
     3598                window.removeEventListener( "load", completed );
    34893599
    34903600        } else {
     
    34983608 */
    34993609function completed() {
     3610
    35003611        // readyState === "complete" is good enough for us to call the dom ready in oldIE
    3501         if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
     3612        if ( document.addEventListener ||
     3613                window.event.type === "load" ||
     3614                document.readyState === "complete" ) {
     3615
    35023616                detach();
    35033617                jQuery.ready();
     
    35103624                readyList = jQuery.Deferred();
    35113625
    3512                 // Catch cases where $(document).ready() is called after the browser event has already occurred.
    3513                 // we once tried to use readyState "interactive" here, but it caused issues like the one
    3514                 // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
    3515                 if ( document.readyState === "complete" ) {
     3626                // Catch cases where $(document).ready() is called
     3627                // after the browser event has already occurred.
     3628                // Support: IE6-10
     3629                // Older IE sometimes signals "interactive" too soon
     3630                if ( document.readyState === "complete" ||
     3631                        ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
     3632
    35163633                        // Handle it asynchronously to allow scripts the opportunity to delay ready
    3517                         setTimeout( jQuery.ready );
     3634                        window.setTimeout( jQuery.ready );
    35183635
    35193636                // Standards-based browsers support DOMContentLoaded
    35203637                } else if ( document.addEventListener ) {
     3638
    35213639                        // Use the handy event callback
    3522                         document.addEventListener( "DOMContentLoaded", completed, false );
     3640                        document.addEventListener( "DOMContentLoaded", completed );
    35233641
    35243642                        // A fallback to window.onload, that will always work
    3525                         window.addEventListener( "load", completed, false );
     3643                        window.addEventListener( "load", completed );
    35263644
    35273645                // If IE event model is used
    35283646                } else {
     3647
    35293648                        // Ensure firing before onload, maybe late but safe also for iframes
    35303649                        document.attachEvent( "onreadystatechange", completed );
     
    35393658                        try {
    35403659                                top = window.frameElement == null && document.documentElement;
    3541                         } catch(e) {}
     3660                        } catch ( e ) {}
    35423661
    35433662                        if ( top && top.doScroll ) {
    3544                                 (function doScrollCheck() {
     3663                                ( function doScrollCheck() {
    35453664                                        if ( !jQuery.isReady ) {
    35463665
    35473666                                                try {
     3667
    35483668                                                        // Use the trick by Diego Perini
    35493669                                                        // http://javascript.nwbox.com/IEContentLoaded/
    3550                                                         top.doScroll("left");
    3551                                                 } catch(e) {
    3552                                                         return setTimeout( doScrollCheck, 50 );
     3670                                                        top.doScroll( "left" );
     3671                                                } catch ( e ) {
     3672                                                        return window.setTimeout( doScrollCheck, 50 );
    35533673                                                }
    35543674
     
    35593679                                                jQuery.ready();
    35603680                                        }
    3561                                 })();
     3681                                } )();
    35623682                        }
    35633683                }
     
    35663686};
    35673687
    3568 
    3569 var strundefined = typeof undefined;
     3688// Kick off the DOM ready check even if the user does not
     3689jQuery.ready.promise();
     3690
    35703691
    35713692
     
    35773698        break;
    35783699}
    3579 support.ownLast = i !== "0";
     3700support.ownFirst = i === "0";
    35803701
    35813702// Note: most support tests are defined in their respective modules.
     
    35843705
    35853706// Execute ASAP in case we need to set body.style.zoom
    3586 jQuery(function() {
     3707jQuery( function() {
     3708
    35873709        // Minified: var a,b,c,d
    35883710        var val, div, body, container;
     
    35903712        body = document.getElementsByTagName( "body" )[ 0 ];
    35913713        if ( !body || !body.style ) {
     3714
    35923715                // Return for frameset docs that don't have a body
    35933716                return;
     
    36003723  &