<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[41233] trunk/src/wp-includes: External Libraries: Update jQuery Form (unused in core) to the latest version, 4.2.1.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/41233">41233</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/41233","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>DrewAPicture</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2017-08-05 12:59:12 +0000 (Sat, 05 Aug 2017)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>External Libraries: Update jQuery Form (unused in core) to the latest version, 4.2.1.

Fixes <a href="https://core.trac.wordpress.org/ticket/41565">#41565</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpincludesjsjqueryjqueryformjs">trunk/src/wp-includes/js/jquery/jquery.form.js</a></li>
<li><a href="#trunksrcwpincludesjsjqueryjqueryformminjs">trunk/src/wp-includes/js/jquery/jquery.form.min.js</a></li>
<li><a href="#trunksrcwpincludesscriptloaderphp">trunk/src/wp-includes/script-loader.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpincludesjsjqueryjqueryformjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/js/jquery/jquery.form.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/js/jquery/jquery.form.js    2017-08-04 23:00:50 UTC (rev 41232)
+++ trunk/src/wp-includes/js/jquery/jquery.form.js      2017-08-05 12:59:12 UTC (rev 41233)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,1193 +1,1520 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /*!
</span><span class="cx" style="display: block; padding: 0 10px">  * jQuery Form Plugin
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * version: 3.37.0-2013.07.11
- * @requires jQuery v1.5 or later
- * Copyright (c) 2013 M. Alsup
- * Examples and documentation at: http://malsup.com/jquery/form/
- * Project repository: https://github.com/malsup/form
- * Dual licensed under the MIT and GPL licenses.
- * https://github.com/malsup/form#copyright-and-license
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * version: 4.2.1
+ * Requires jQuery v1.7 or later
+ * Copyright 2017 Kevin Morris
+ * Copyright 2006 M. Alsup
+ * Project repository: https://github.com/jquery-form/form
+ * Dual licensed under the MIT and LGPLv3 licenses.
+ * https://github.com/jquery-form/form#license
</ins><span class="cx" style="display: block; padding: 0 10px">  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/*global ActiveXObject */
-;(function($) {
-"use strict";
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/* global ActiveXObject */
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/*
-    Usage Note:
-    -----------
-    Do not use both ajaxSubmit and ajaxForm on the same form.  These
-    functions are mutually exclusive.  Use ajaxSubmit if you want
-    to bind your own submit handler to the form.  For example,
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/* eslint-disable */
+(function (factory) {
+       if (typeof define === 'function' && define.amd) {
+               // AMD. Register as an anonymous module.
+               define(['jquery'], factory);
+       } else if (typeof module === 'object' && module.exports) {
+               // Node/CommonJS
+               module.exports = function( root, jQuery ) {
+                       if (typeof jQuery === 'undefined') {
+                               // require('jQuery') returns a factory that requires window to build a jQuery instance, we normalize how we use modules
+                               // that require this pattern but the window provided is a noop if it's defined (how jquery works)
+                               if (typeof window !== 'undefined') {
+                                       jQuery = require('jquery');
+                               }
+                               else {
+                                       jQuery = require('jquery')(root);
+                               }
+                       }
+                       factory(jQuery);
+                       return jQuery;
+               };
+       } else {
+               // Browser globals
+               factory(jQuery);
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    $(document).ready(function() {
-        $('#myForm').on('submit', function(e) {
-            e.preventDefault(); // <-- important
-            $(this).ajaxSubmit({
-                target: '#output'
-            });
-        });
-    });
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+}(function ($) {
+/* eslint-enable */
+       'use strict';
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    Use ajaxForm when you want the plugin to manage all the event binding
-    for you.  For example,
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /*
+               Usage Note:
+               -----------
+               Do not use both ajaxSubmit and ajaxForm on the same form. These
+               functions are mutually exclusive. Use ajaxSubmit if you want
+               to bind your own submit handler to the form. For example,
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    $(document).ready(function() {
-        $('#myForm').ajaxForm({
-            target: '#output'
-        });
-    });
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $(document).ready(function() {
+                       $('#myForm').on('submit', function(e) {
+                               e.preventDefault(); // <-- important
+                               $(this).ajaxSubmit({
+                                       target: '#output'
+                               });
+                       });
+               });
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    You can also use ajaxForm with delegation (requires jQuery v1.7+), so the
-    form does not have to exist when you invoke ajaxForm:
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         Use ajaxForm when you want the plugin to manage all the event binding
+               for you. For example,
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    $('#myForm').ajaxForm({
-        delegation: true,
-        target: '#output'
-    });
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $(document).ready(function() {
+                       $('#myForm').ajaxForm({
+                               target: '#output'
+                       });
+               });
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    When using ajaxForm, the ajaxSubmit function will be invoked for you
-    at the appropriate time.
-*/
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         You can also use ajaxForm with delegation (requires jQuery v1.7+), so the
+               form does not have to exist when you invoke ajaxForm:
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/**
- * Feature detection
- */
-var feature = {};
-feature.fileapi = $("<input type='file'/>").get(0).files !== undefined;
-feature.formdata = window.FormData !== undefined;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $('#myForm').ajaxForm({
+                       delegation: true,
+                       target: '#output'
+               });
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-var hasProp = !!$.fn.prop;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         When using ajaxForm, the ajaxSubmit function will be invoked for you
+               at the appropriate time.
+       */
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-// attr2 uses prop when it can but checks the return type for
-// an expected string.  this accounts for the case where a form 
-// contains inputs with names like "action" or "method"; in those
-// cases "prop" returns the element
-$.fn.attr2 = function() {
-    if ( ! hasProp )
-        return this.attr.apply(this, arguments);
-    var val = this.prop.apply(this, arguments);
-    if ( ( val && val.jquery ) || typeof val === 'string' )
-        return val;
-    return this.attr.apply(this, arguments);
-};
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ var rCRLF = /\r?\n/g;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/**
- * ajaxSubmit() provides a mechanism for immediately submitting
- * an HTML form using AJAX.
- */
-$.fn.ajaxSubmit = function(options) {
-    /*jshint scripturl:true */
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+        * Feature detection
+        */
+       var feature = {};
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
-    if (!this.length) {
-        log('ajaxSubmit: skipping submit process - no element selected');
-        return this;
-    }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ feature.fileapi = $('<input type="file">').get(0).files !== undefined;
+       feature.formdata = (typeof window.FormData !== 'undefined');
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    var method, action, url, $form = this;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ var hasProp = !!$.fn.prop;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    if (typeof options == 'function') {
-        options = { success: options };
-    }
-    else if ( options === undefined ) {
-        options = {};
-    }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // attr2 uses prop when it can but checks the return type for
+       // an expected string. This accounts for the case where a form
+       // contains inputs with names like "action" or "method"; in those
+       // cases "prop" returns the element
+       $.fn.attr2 = function() {
+               if (!hasProp) {
+                       return this.attr.apply(this, arguments);
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    method = options.type || this.attr2('method');
-    action = options.url  || this.attr2('action');
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         var val = this.prop.apply(this, arguments);
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    url = (typeof action === 'string') ? $.trim(action) : '';
-    url = url || window.location.href || '';
-    if (url) {
-        // clean url (don't include hash vaue)
-        url = (url.match(/^([^#]+)/)||[])[1];
-    }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ((val && val.jquery) || typeof val === 'string') {
+                       return val;
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    options = $.extend(true, {
-        url:  url,
-        success: $.ajaxSettings.success,
-        type: method || 'GET',
-        iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
-    }, options);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         return this.attr.apply(this, arguments);
+       };
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    // hook for manipulating the form data before it is extracted;
-    // convenient for use with rich editors like tinyMCE or FCKEditor
-    var veto = {};
-    this.trigger('form-pre-serialize', [this, options, veto]);
-    if (veto.veto) {
-        log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
-        return this;
-    }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+        * ajaxSubmit() provides a mechanism for immediately submitting
+        * an HTML form using AJAX.
+        *
+        * @param       {object|string} options         jquery.form.js parameters or custom url for submission
+        * @param       {object}                data            extraData
+        * @param       {string}                dataType        ajax dataType
+        * @param       {function}              onSuccess       ajax success callback function
+        */
+       $.fn.ajaxSubmit = function(options, data, dataType, onSuccess) {
+               // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
+               if (!this.length) {
+                       log('ajaxSubmit: skipping submit process - no element selected');
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    // provide opportunity to alter form data before it is serialized
-    if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
-        log('ajaxSubmit: submit aborted via beforeSerialize callback');
-        return this;
-    }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 return this;
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    var traditional = options.traditional;
-    if ( traditional === undefined ) {
-        traditional = $.ajaxSettings.traditional;
-    }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         /* eslint consistent-this: ["error", "$form"] */
+               var method, action, url, $form = this;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    var elements = [];
-    var qx, a = this.formToArray(options.semantic, elements);
-    if (options.data) {
-        options.extraData = options.data;
-        qx = $.param(options.data, traditional);
-    }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if (typeof options === 'function') {
+                       options = {success: options};
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    // give pre-submit callback an opportunity to abort the submit
-    if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
-        log('ajaxSubmit: submit aborted via beforeSubmit callback');
-        return this;
-    }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         } else if (typeof options === 'string' || (options === false && arguments.length > 0)) {
+                       options = {
+                               'url'      : options,
+                               'data'     : data,
+                               'dataType' : dataType
+                       };
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    // fire vetoable 'validate' event
-    this.trigger('form-submit-validate', [a, this, options, veto]);
-    if (veto.veto) {
-        log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
-        return this;
-    }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 if (typeof onSuccess === 'function') {
+                               options.success = onSuccess;
+                       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    var q = $.param(a, traditional);
-    if (qx) {
-        q = ( q ? (q + '&' + qx) : qx );
-    }
-    if (options.type.toUpperCase() == 'GET') {
-        options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
-        options.data = null;  // data is null for 'get'
-    }
-    else {
-        options.data = q; // data is the query string for 'post'
-    }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         } else if (typeof options === 'undefined') {
+                       options = {};
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    var callbacks = [];
-    if (options.resetForm) {
-        callbacks.push(function() { $form.resetForm(); });
-    }
-    if (options.clearForm) {
-        callbacks.push(function() { $form.clearForm(options.includeHidden); });
-    }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         method = options.method || options.type || this.attr2('method');
+               action = options.url || this.attr2('action');
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    // perform a load on the target only if dataType is not provided
-    if (!options.dataType && options.target) {
-        var oldSuccess = options.success || function(){};
-        callbacks.push(function(data) {
-            var fn = options.replaceTarget ? 'replaceWith' : 'html';
-            $(options.target)[fn](data).each(oldSuccess, arguments);
-        });
-    }
-    else if (options.success) {
-        callbacks.push(options.success);
-    }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         url = (typeof action === 'string') ? $.trim(action) : '';
+               url = url || window.location.href || '';
+               if (url) {
+                       // clean url (don't include hash vaue)
+                       url = (url.match(/^([^#]+)/) || [])[1];
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
-        var context = options.context || this ;    // jQuery 1.4+ supports scope context
-        for (var i=0, max=callbacks.length; i < max; i++) {
-            callbacks[i].apply(context, [data, status, xhr || $form, $form]);
-        }
-    };
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         options = $.extend(true, {
+                       url       : url,
+                       success   : $.ajaxSettings.success,
+                       type      : method || $.ajaxSettings.type,
+                       iframeSrc : /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'             // eslint-disable-line no-script-url
+               }, options);
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    if (options.error) {
-        var oldError = options.error;
-        options.error = function(xhr, status, error) {
-            var context = options.context || this;
-            oldError.apply(context, [xhr, status, error, $form]);
-        };
-    }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // hook for manipulating the form data before it is extracted;
+               // convenient for use with rich editors like tinyMCE or FCKEditor
+               var veto = {};
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-     if (options.complete) {
-        var oldComplete = options.complete;
-        options.complete = function(xhr, status) {
-            var context = options.context || this;
-            oldComplete.apply(context, [xhr, status, $form]);
-        };
-    }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         this.trigger('form-pre-serialize', [this, options, veto]);
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    // are there files to upload?
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if (veto.veto) {
+                       log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    // [value] (issue #113), also see comment:
-    // https://github.com/malsup/form/commit/588306aedba1de01388032d5f42a60159eea9228#commitcomment-2180219
-    var fileInputs = $('input[type=file]:enabled[value!=""]', this);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 return this;
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    var hasFileInputs = fileInputs.length > 0;
-    var mp = 'multipart/form-data';
-    var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // provide opportunity to alter form data before it is serialized
+               if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
+                       log('ajaxSubmit: submit aborted via beforeSerialize callback');
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    var fileAPI = feature.fileapi && feature.formdata;
-    log("fileAPI :" + fileAPI);
-    var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 return this;
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    var jqxhr;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         var traditional = options.traditional;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    // options.iframe allows user to force iframe mode
-    // 06-NOV-09: now defaulting to iframe mode if file input is detected
-    if (options.iframe !== false && (options.iframe || shouldUseFrame)) {
-        // hack to fix Safari hang (thanks to Tim Molendijk for this)
-        // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
-        if (options.closeKeepAlive) {
-            $.get(options.closeKeepAlive, function() {
-                jqxhr = fileUploadIframe(a);
-            });
-        }
-        else {
-            jqxhr = fileUploadIframe(a);
-        }
-    }
-    else if ((hasFileInputs || multipart) && fileAPI) {
-        jqxhr = fileUploadXhr(a);
-    }
-    else {
-        jqxhr = $.ajax(options);
-    }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if (typeof traditional === 'undefined') {
+                       traditional = $.ajaxSettings.traditional;
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    $form.removeData('jqxhr').data('jqxhr', jqxhr);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         var elements = [];
+               var qx, a = this.formToArray(options.semantic, elements, options.filtering);
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    // clear element array
-    for (var k=0; k < elements.length; k++)
-        elements[k] = null;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if (options.data) {
+                       var optionsData = $.isFunction(options.data) ? options.data(a) : options.data;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    // fire 'notify' event
-    this.trigger('form-submit-notify', [this, options]);
-    return this;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 options.extraData = optionsData;
+                       qx = $.param(optionsData, traditional);
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    // utility fn for deep serialization
-    function deepSerialize(extraData){
-        var serialized = $.param(extraData, options.traditional).split('&');
-        var len = serialized.length;
-        var result = [];
-        var i, part;
-        for (i=0; i < len; i++) {
-            // #252; undo param space replacement
-            serialized[i] = serialized[i].replace(/\+/g,' ');
-            part = serialized[i].split('=');
-            // #278; use array instead of object storage, favoring array serializations
-            result.push([decodeURIComponent(part[0]), decodeURIComponent(part[1])]);
-        }
-        return result;
-    }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // give pre-submit callback an opportunity to abort the submit
+               if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
+                       log('ajaxSubmit: submit aborted via beforeSubmit callback');
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-     // XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz)
-    function fileUploadXhr(a) {
-        var formdata = new FormData();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 return this;
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        for (var i=0; i < a.length; i++) {
-            formdata.append(a[i].name, a[i].value);
-        }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // fire vetoable 'validate' event
+               this.trigger('form-submit-validate', [a, this, options, veto]);
+               if (veto.veto) {
+                       log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        if (options.extraData) {
-            var serializedData = deepSerialize(options.extraData);
-            for (i=0; i < serializedData.length; i++)
-                if (serializedData[i])
-                    formdata.append(serializedData[i][0], serializedData[i][1]);
-        }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 return this;
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        options.data = null;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         var q = $.param(a, traditional);
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        var s = $.extend(true, {}, $.ajaxSettings, options, {
-            contentType: false,
-            processData: false,
-            cache: false,
-            type: method || 'POST'
-        });
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if (qx) {
+                       q = (q ? (q + '&' + qx) : qx);
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        if (options.uploadProgress) {
-            // workaround because jqXHR does not expose upload property
-            s.xhr = function() {
-                var xhr = $.ajaxSettings.xhr();
-                if (xhr.upload) {
-                    xhr.upload.addEventListener('progress', function(event) {
-                        var percent = 0;
-                        var position = event.loaded || event.position; /*event.position is deprecated*/
-                        var total = event.total;
-                        if (event.lengthComputable) {
-                            percent = Math.ceil(position / total * 100);
-                        }
-                        options.uploadProgress(event, position, total, percent);
-                    }, false);
-                }
-                return xhr;
-            };
-        }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if (options.type.toUpperCase() === 'GET') {
+                       options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
+                       options.data = null;    // data is null for 'get'
+               } else {
+                       options.data = q;               // data is the query string for 'post'
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        s.data = null;
-            var beforeSend = s.beforeSend;
-            s.beforeSend = function(xhr, o) {
-                o.data = formdata;
-                if(beforeSend)
-                    beforeSend.call(this, xhr, o);
-        };
-        return $.ajax(s);
-    }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         var callbacks = [];
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    // private function for handling file uploads (hat tip to YAHOO!)
-    function fileUploadIframe(a) {
-        var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle;
-        var deferred = $.Deferred();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if (options.resetForm) {
+                       callbacks.push(function() {
+                               $form.resetForm();
+                       });
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        if (a) {
-            // ensure that every serialized input is still enabled
-            for (i=0; i < elements.length; i++) {
-                el = $(elements[i]);
-                if ( hasProp )
-                    el.prop('disabled', false);
-                else
-                    el.removeAttr('disabled');
-            }
-        }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if (options.clearForm) {
+                       callbacks.push(function() {
+                               $form.clearForm(options.includeHidden);
+                       });
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        s = $.extend(true, {}, $.ajaxSettings, options);
-        s.context = s.context || s;
-        id = 'jqFormIO' + (new Date().getTime());
-        if (s.iframeTarget) {
-            $io = $(s.iframeTarget);
-            n = $io.attr2('name');
-            if (!n)
-                 $io.attr2('name', id);
-            else
-                id = n;
-        }
-        else {
-            $io = $('<iframe name="' + id + '" src="'+ s.iframeSrc +'" />');
-            $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
-        }
-        io = $io[0];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // perform a load on the target only if dataType is not provided
+               if (!options.dataType && options.target) {
+                       var oldSuccess = options.success || function(){};
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        callbacks.push(function(data, textStatus, jqXHR) {
+                               var successArguments = arguments,
+                                       fn = options.replaceTarget ? 'replaceWith' : 'html';
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        xhr = { // mock object
-            aborted: 0,
-            responseText: null,
-            responseXML: null,
-            status: 0,
-            statusText: 'n/a',
-            getAllResponseHeaders: function() {},
-            getResponseHeader: function() {},
-            setRequestHeader: function() {},
-            abort: function(status) {
-                var e = (status === 'timeout' ? 'timeout' : 'aborted');
-                log('aborting upload... ' + e);
-                this.aborted = 1;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         $(options.target)[fn](data).each(function(){
+                                       oldSuccess.apply(this, successArguments);
+                               });
+                       });
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                try { // #214, #257
-                    if (io.contentWindow.document.execCommand) {
-                        io.contentWindow.document.execCommand('Stop');
-                    }
-                }
-                catch(ignore) {}
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         } else if (options.success) {
+                       if ($.isArray(options.success)) {
+                               $.merge(callbacks, options.success);
+                       } else {
+                               callbacks.push(options.success);
+                       }
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $io.attr('src', s.iframeSrc); // abort op in progress
-                xhr.error = e;
-                if (s.error)
-                    s.error.call(s.context, xhr, e, status);
-                if (g)
-                    $.event.trigger("ajaxError", [xhr, s, e]);
-                if (s.complete)
-                    s.complete.call(s.context, xhr, e);
-            }
-        };
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
+                       var context = options.context || this;          // jQuery 1.4+ supports scope context
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        g = s.global;
-        // trigger ajax global events so that activity/block indicators work like normal
-        if (g && 0 === $.active++) {
-            $.event.trigger("ajaxStart");
-        }
-        if (g) {
-            $.event.trigger("ajaxSend", [xhr, s]);
-        }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 for (var i = 0, max = callbacks.length; i < max; i++) {
+                               callbacks[i].apply(context, [data, status, xhr || $form, $form]);
+                       }
+               };
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
-            if (s.global) {
-                $.active--;
-            }
-            deferred.reject();
-            return deferred;
-        }
-        if (xhr.aborted) {
-            deferred.reject();
-            return deferred;
-        }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if (options.error) {
+                       var oldError = options.error;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        // add submitting element to data if we know it
-        sub = form.clk;
-        if (sub) {
-            n = sub.name;
-            if (n && !sub.disabled) {
-                s.extraData = s.extraData || {};
-                s.extraData[n] = sub.value;
-                if (sub.type == "image") {
-                    s.extraData[n+'.x'] = form.clk_x;
-                    s.extraData[n+'.y'] = form.clk_y;
-                }
-            }
-        }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 options.error = function(xhr, status, error) {
+                               var context = options.context || this;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        var CLIENT_TIMEOUT_ABORT = 1;
-        var SERVER_ABORT = 2;
-                
-        function getDoc(frame) {
-            /* it looks like contentWindow or contentDocument do not
-             * carry the protocol property in ie8, when running under ssl
-             * frame.document is the only valid response document, since
-             * the protocol is know but not on the other two objects. strange?
-             * "Same origin policy" http://en.wikipedia.org/wiki/Same_origin_policy
-             */
-            
-            var doc = null;
-            
-            // IE8 cascading access check
-            try {
-                if (frame.contentWindow) {
-                    doc = frame.contentWindow.document;
-                }
-            } catch(err) {
-                // IE8 access denied under ssl & missing protocol
-                log('cannot get iframe.contentWindow document: ' + err);
-            }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         oldError.apply(context, [xhr, status, error, $form]);
+                       };
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-            if (doc) { // successful getting content
-                return doc;
-            }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if (options.complete) {
+                       var oldComplete = options.complete;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-            try { // simply checking may throw in ie8 under ssl or mismatched protocol
-                doc = frame.contentDocument ? frame.contentDocument : frame.document;
-            } catch(err) {
-                // last attempt
-                log('cannot get iframe.contentDocument: ' + err);
-                doc = frame.document;
-            }
-            return doc;
-        }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 options.complete = function(xhr, status) {
+                               var context = options.context || this;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        // Rails CSRF hack (thanks to Yvan Barthelemy)
-        var csrf_token = $('meta[name=csrf-token]').attr('content');
-        var csrf_param = $('meta[name=csrf-param]').attr('content');
-        if (csrf_param && csrf_token) {
-            s.extraData = s.extraData || {};
-            s.extraData[csrf_param] = csrf_token;
-        }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         oldComplete.apply(context, [xhr, status, $form]);
+                       };
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        // take a breath so that pending repaints get some cpu time before the upload starts
-        function doSubmit() {
-            // make sure form attrs are set
-            var t = $form.attr2('target'), a = $form.attr2('action');
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // are there files to upload?
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-            // update form attrs in IE friendly way
-            form.setAttribute('target',id);
-            if (!method) {
-                form.setAttribute('method', 'POST');
-            }
-            if (a != s.url) {
-                form.setAttribute('action', s.url);
-            }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // [value] (issue #113), also see comment:
+               // https://github.com/malsup/form/commit/588306aedba1de01388032d5f42a60159eea9228#commitcomment-2180219
+               var fileInputs = $('input[type=file]:enabled', this).filter(function() {
+                       return $(this).val() !== '';
+               });
+               var hasFileInputs = fileInputs.length > 0;
+               var mp = 'multipart/form-data';
+               var multipart = ($form.attr('enctype') === mp || $form.attr('encoding') === mp);
+               var fileAPI = feature.fileapi && feature.formdata;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-            // ie borks in some cases when setting encoding
-            if (! s.skipEncodingOverride && (!method || /post/i.test(method))) {
-                $form.attr({
-                    encoding: 'multipart/form-data',
-                    enctype:  'multipart/form-data'
-                });
-            }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         log('fileAPI :' + fileAPI);
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-            // support timout
-            if (s.timeout) {
-                timeoutHandle = setTimeout(function() { timedOut = true; cb(CLIENT_TIMEOUT_ABORT); }, s.timeout);
-            }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI;
+               var jqxhr;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-            // look for server aborts
-            function checkState() {
-                try {
-                    var state = getDoc(io).readyState;
-                    log('state = ' + state);
-                    if (state && state.toLowerCase() == 'uninitialized')
-                        setTimeout(checkState,50);
-                }
-                catch(e) {
-                    log('Server abort: ' , e, ' (', e.name, ')');
-                    cb(SERVER_ABORT);
-                    if (timeoutHandle)
-                        clearTimeout(timeoutHandle);
-                    timeoutHandle = undefined;
-                }
-            }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // options.iframe allows user to force iframe mode
+               // 06-NOV-09: now defaulting to iframe mode if file input is detected
+               if (options.iframe !== false && (options.iframe || shouldUseFrame)) {
+                       // hack to fix Safari hang (thanks to Tim Molendijk for this)
+                       // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
+                       if (options.closeKeepAlive) {
+                               $.get(options.closeKeepAlive, function() {
+                                       jqxhr = fileUploadIframe(a);
+                               });
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-            // add "extra" data to form if provided in options
-            var extraInputs = [];
-            try {
-                if (s.extraData) {
-                    for (var n in s.extraData) {
-                        if (s.extraData.hasOwnProperty(n)) {
-                           // if using the $.param format that allows for multiple values with the same name
-                           if($.isPlainObject(s.extraData[n]) && s.extraData[n].hasOwnProperty('name') && s.extraData[n].hasOwnProperty('value')) {
-                               extraInputs.push(
-                               $('<input type="hidden" name="'+s.extraData[n].name+'">').val(s.extraData[n].value)
-                                   .appendTo(form)[0]);
-                           } else {
-                               extraInputs.push(
-                               $('<input type="hidden" name="'+n+'">').val(s.extraData[n])
-                                   .appendTo(form)[0]);
-                           }
-                        }
-                    }
-                }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 } else {
+                               jqxhr = fileUploadIframe(a);
+                       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                if (!s.iframeTarget) {
-                    // add iframe to doc and submit the form
-                    $io.appendTo('body');
-                    if (io.attachEvent)
-                        io.attachEvent('onload', cb);
-                    else
-                        io.addEventListener('load', cb, false);
-                }
-                setTimeout(checkState,15);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         } else if ((hasFileInputs || multipart) && fileAPI) {
+                       jqxhr = fileUploadXhr(a);
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                try {
-                    form.submit();
-                } catch(err) {
-                    // just in case form has element with name/id of 'submit'
-                    var submitFn = document.createElement('form').submit;
-                    submitFn.apply(form);
-                }
-            }
-            finally {
-                // reset attrs and remove "extra" input elements
-                form.setAttribute('action',a);
-                if(t) {
-                    form.setAttribute('target', t);
-                } else {
-                    $form.removeAttr('target');
-                }
-                $(extraInputs).remove();
-            }
-        }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         } else {
+                       jqxhr = $.ajax(options);
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        if (s.forceSync) {
-            doSubmit();
-        }
-        else {
-            setTimeout(doSubmit, 10); // this lets dom updates render
-        }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $form.removeData('jqxhr').data('jqxhr', jqxhr);
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        var data, doc, domCheckCount = 50, callbackProcessed;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // clear element array
+               for (var k = 0; k < elements.length; k++) {
+                       elements[k] = null;
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        function cb(e) {
-            if (xhr.aborted || callbackProcessed) {
-                return;
-            }
-            
-            doc = getDoc(io);
-            if(!doc) {
-                log('cannot access response document');
-                e = SERVER_ABORT;
-            }
-            if (e === CLIENT_TIMEOUT_ABORT && xhr) {
-                xhr.abort('timeout');
-                deferred.reject(xhr, 'timeout');
-                return;
-            }
-            else if (e == SERVER_ABORT && xhr) {
-                xhr.abort('server abort');
-                deferred.reject(xhr, 'error', 'server abort');
-                return;
-            }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // fire 'notify' event
+               this.trigger('form-submit-notify', [this, options]);
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-            if (!doc || doc.location.href == s.iframeSrc) {
-                // response not received yet
-                if (!timedOut)
-                    return;
-            }
-            if (io.detachEvent)
-                io.detachEvent('onload', cb);
-            else
-                io.removeEventListener('load', cb, false);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         return this;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-            var status = 'success', errMsg;
-            try {
-                if (timedOut) {
-                    throw 'timeout';
-                }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // utility fn for deep serialization
+               function deepSerialize(extraData) {
+                       var serialized = $.param(extraData, options.traditional).split('&');
+                       var len = serialized.length;
+                       var result = [];
+                       var i, part;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
-                log('isXml='+isXml);
-                if (!isXml && window.opera && (doc.body === null || !doc.body.innerHTML)) {
-                    if (--domCheckCount) {
-                        // in some browsers (Opera) the iframe DOM is not always traversable when
-                        // the onload callback fires, so we loop a bit to accommodate
-                        log('requeing onLoad callback, DOM not available');
-                        setTimeout(cb, 250);
-                        return;
-                    }
-                    // let this fall through because server response could be an empty document
-                    //log('Could not access iframe DOM after mutiple tries.');
-                    //throw 'DOMException: not available';
-                }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 for (i = 0; i < len; i++) {
+                               // #252; undo param space replacement
+                               serialized[i] = serialized[i].replace(/\+/g, ' ');
+                               part = serialized[i].split('=');
+                               // #278; use array instead of object storage, favoring array serializations
+                               result.push([decodeURIComponent(part[0]), decodeURIComponent(part[1])]);
+                       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                //log('response detected');
-                var docRoot = doc.body ? doc.body : doc.documentElement;
-                xhr.responseText = docRoot ? docRoot.innerHTML : null;
-                xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
-                if (isXml)
-                    s.dataType = 'xml';
-                xhr.getResponseHeader = function(header){
-                    var headers = {'content-type': s.dataType};
-                    return headers[header];
-                };
-                // support for XHR 'status' & 'statusText' emulation :
-                if (docRoot) {
-                    xhr.status = Number( docRoot.getAttribute('status') ) || xhr.status;
-                    xhr.statusText = docRoot.getAttribute('statusText') || xhr.statusText;
-                }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 return result;
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                var dt = (s.dataType || '').toLowerCase();
-                var scr = /(json|script|text)/.test(dt);
-                if (scr || s.textarea) {
-                    // see if user embedded response in textarea
-                    var ta = doc.getElementsByTagName('textarea')[0];
-                    if (ta) {
-                        xhr.responseText = ta.value;
-                        // support for XHR 'status' & 'statusText' emulation :
-                        xhr.status = Number( ta.getAttribute('status') ) || xhr.status;
-                        xhr.statusText = ta.getAttribute('statusText') || xhr.statusText;
-                    }
-                    else if (scr) {
-                        // account for browsers injecting pre around json response
-                        var pre = doc.getElementsByTagName('pre')[0];
-                        var b = doc.getElementsByTagName('body')[0];
-                        if (pre) {
-                            xhr.responseText = pre.textContent ? pre.textContent : pre.innerText;
-                        }
-                        else if (b) {
-                            xhr.responseText = b.textContent ? b.textContent : b.innerText;
-                        }
-                    }
-                }
-                else if (dt == 'xml' && !xhr.responseXML && xhr.responseText) {
-                    xhr.responseXML = toXml(xhr.responseText);
-                }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz)
+               function fileUploadXhr(a) {
+                       var formdata = new FormData();
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                try {
-                    data = httpData(xhr, dt, s);
-                }
-                catch (err) {
-                    status = 'parsererror';
-                    xhr.error = errMsg = (err || status);
-                }
-            }
-            catch (err) {
-                log('error caught: ',err);
-                status = 'error';
-                xhr.error = errMsg = (err || status);
-            }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 for (var i = 0; i < a.length; i++) {
+                               formdata.append(a[i].name, a[i].value);
+                       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-            if (xhr.aborted) {
-                log('upload aborted');
-                status = null;
-            }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 if (options.extraData) {
+                               var serializedData = deepSerialize(options.extraData);
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-            if (xhr.status) { // we've set xhr.status
-                status = (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) ? 'success' : 'error';
-            }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         for (i = 0; i < serializedData.length; i++) {
+                                       if (serializedData[i]) {
+                                               formdata.append(serializedData[i][0], serializedData[i][1]);
+                                       }
+                               }
+                       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-            // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
-            if (status === 'success') {
-                if (s.success)
-                    s.success.call(s.context, data, 'success', xhr);
-                deferred.resolve(xhr.responseText, 'success', xhr);
-                if (g)
-                    $.event.trigger("ajaxSuccess", [xhr, s]);
-            }
-            else if (status) {
-                if (errMsg === undefined)
-                    errMsg = xhr.statusText;
-                if (s.error)
-                    s.error.call(s.context, xhr, status, errMsg);
-                deferred.reject(xhr, 'error', errMsg);
-                if (g)
-                    $.event.trigger("ajaxError", [xhr, s, errMsg]);
-            }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 options.data = null;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-            if (g)
-                $.event.trigger("ajaxComplete", [xhr, s]);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 var s = $.extend(true, {}, $.ajaxSettings, options, {
+                               contentType : false,
+                               processData : false,
+                               cache       : false,
+                               type        : method || 'POST'
+                       });
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-            if (g && ! --$.active) {
-                $.event.trigger("ajaxStop");
-            }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 if (options.uploadProgress) {
+                               // workaround because jqXHR does not expose upload property
+                               s.xhr = function() {
+                                       var xhr = $.ajaxSettings.xhr();
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-            if (s.complete)
-                s.complete.call(s.context, xhr, status);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 if (xhr.upload) {
+                                               xhr.upload.addEventListener('progress', function(event) {
+                                                       var percent = 0;
+                                                       var position = event.loaded || event.position;                  /* event.position is deprecated */
+                                                       var total = event.total;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-            callbackProcessed = true;
-            if (s.timeout)
-                clearTimeout(timeoutHandle);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                 if (event.lengthComputable) {
+                                                               percent = Math.ceil(position / total * 100);
+                                                       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-            // clean up
-            setTimeout(function() {
-                if (!s.iframeTarget)
-                    $io.remove();
-                xhr.responseXML = null;
-            }, 100);
-        }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                 options.uploadProgress(event, position, total, percent);
+                                               }, false);
+                                       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+)
-            if (window.ActiveXObject) {
-                doc = new ActiveXObject('Microsoft.XMLDOM');
-                doc.async = 'false';
-                doc.loadXML(s);
-            }
-            else {
-                doc = (new DOMParser()).parseFromString(s, 'text/xml');
-            }
-            return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null;
-        };
-        var parseJSON = $.parseJSON || function(s) {
-            /*jslint evil:true */
-            return window['eval']('(' + s + ')');
-        };
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 return xhr;
+                               };
+                       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 s.data = null;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-            var ct = xhr.getResponseHeader('content-type') || '',
-                xml = type === 'xml' || !type && ct.indexOf('xml') >= 0,
-                data = xml ? xhr.responseXML : xhr.responseText;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 var beforeSend = s.beforeSend;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-            if (xml && data.documentElement.nodeName === 'parsererror') {
-                if ($.error)
-                    $.error('parsererror');
-            }
-            if (s && s.dataFilter) {
-                data = s.dataFilter(data, type);
-            }
-            if (typeof data === 'string') {
-                if (type === 'json' || !type && ct.indexOf('json') >= 0) {
-                    data = parseJSON(data);
-                } else if (type === "script" || !type && ct.indexOf("javascript") >= 0) {
-                    $.globalEval(data);
-                }
-            }
-            return data;
-        };
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 s.beforeSend = function(xhr, o) {
+                               // Send FormData() provided by user
+                               if (options.formData) {
+                                       o.data = options.formData;
+                               } else {
+                                       o.data = formdata;
+                               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        return deferred;
-    }
-};
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         if (beforeSend) {
+                                       beforeSend.call(this, xhr, o);
+                               }
+                       };
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/**
- * ajaxForm() provides a mechanism for fully automating form submission.
- *
- * The advantages of using this method instead of ajaxSubmit() are:
- *
- * 1: This method will include coordinates for <input type="image" /> elements (if the element
- *    is used to submit the form).
- * 2. This method will include the submit element's name/value data (for the element that was
- *    used to submit the form).
- * 3. This method binds the submit() method to the form for you.
- *
- * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely
- * passes the options argument along after properly binding events for submit elements and
- * the form itself.
- */
-$.fn.ajaxForm = function(options) {
-    options = options || {};
-    options.delegation = options.delegation && $.isFunction($.fn.on);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 return $.ajax(s);
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    // in jQuery 1.3+ we can fix mistakes with the ready state
-    if (!options.delegation && this.length === 0) {
-        var o = { s: this.selector, c: this.context };
-        if (!$.isReady && o.s) {
-            log('DOM not ready, queuing ajaxForm');
-            $(function() {
-                $(o.s,o.c).ajaxForm(options);
-            });
-            return this;
-        }
-        // is your DOM ready?  http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
-        log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
-        return this;
-    }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // private function for handling file uploads (hat tip to YAHOO!)
+               function fileUploadIframe(a) {
+                       var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle;
+                       var deferred = $.Deferred();
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    if ( options.delegation ) {
-        $(document)
-            .off('submit.form-plugin', this.selector, doAjaxSubmit)
-            .off('click.form-plugin', this.selector, captureSubmittingElement)
-            .on('submit.form-plugin', this.selector, options, doAjaxSubmit)
-            .on('click.form-plugin', this.selector, options, captureSubmittingElement);
-        return this;
-    }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 // #341
+                       deferred.abort = function(status) {
+                               xhr.abort(status);
+                       };
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    return this.ajaxFormUnbind()
-        .bind('submit.form-plugin', options, doAjaxSubmit)
-        .bind('click.form-plugin', options, captureSubmittingElement);
-};
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 if (a) {
+                               // ensure that every serialized input is still enabled
+                               for (i = 0; i < elements.length; i++) {
+                                       el = $(elements[i]);
+                                       if (hasProp) {
+                                               el.prop('disabled', false);
+                                       } else {
+                                               el.removeAttr('disabled');
+                                       }
+                               }
+                       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-// private event handlers
-function doAjaxSubmit(e) {
-    /*jshint validthis:true */
-    var options = e.data;
-    if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
-        e.preventDefault();
-        $(this).ajaxSubmit(options);
-    }
-}
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 s = $.extend(true, {}, $.ajaxSettings, options);
+                       s.context = s.context || s;
+                       id = 'jqFormIO' + new Date().getTime();
+                       var ownerDocument = form.ownerDocument;
+                       var $body = $form.closest('body');
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-function captureSubmittingElement(e) {
-    /*jshint validthis:true */
-    var target = e.target;
-    var $el = $(target);
-    if (!($el.is("[type=submit],[type=image]"))) {
-        // is this a child element of the submit el?  (ex: a span within a button)
-        var t = $el.closest('[type=submit]');
-        if (t.length === 0) {
-            return;
-        }
-        target = t[0];
-    }
-    var form = this;
-    form.clk = target;
-    if (target.type == 'image') {
-        if (e.offsetX !== undefined) {
-            form.clk_x = e.offsetX;
-            form.clk_y = e.offsetY;
-        } else if (typeof $.fn.offset == 'function') {
-            var offset = $el.offset();
-            form.clk_x = e.pageX - offset.left;
-            form.clk_y = e.pageY - offset.top;
-        } else {
-            form.clk_x = e.pageX - target.offsetLeft;
-            form.clk_y = e.pageY - target.offsetTop;
-        }
-    }
-    // clear form vars
-    setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
-}
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 if (s.iframeTarget) {
+                               $io = $(s.iframeTarget, ownerDocument);
+                               n = $io.attr2('name');
+                               if (!n) {
+                                       $io.attr2('name', id);
+                               } else {
+                                       id = n;
+                               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        } else {
+                               $io = $('<iframe name="' + id + '" src="' + s.iframeSrc + '" />', ownerDocument);
+                               $io.css({position: 'absolute', top: '-1000px', left: '-1000px'});
+                       }
+                       io = $io[0];
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
-$.fn.ajaxFormUnbind = function() {
-    return this.unbind('submit.form-plugin click.form-plugin');
-};
</del><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/**
- * formToArray() gathers form element data into an array of objects that can
- * be passed to any of the following ajax functions: $.get, $.post, or load.
- * Each object in the array has both a 'name' and 'value' property.  An example of
- * an array for a simple login form might be:
- *
- * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
- *
- * It is this array that is passed to pre-submit callback functions provided to the
- * ajaxSubmit() and ajaxForm() methods.
- */
-$.fn.formToArray = function(semantic, elements) {
-    var a = [];
-    if (this.length === 0) {
-        return a;
-    }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 xhr = { // mock object
+                               aborted               : 0,
+                               responseText          : null,
+                               responseXML           : null,
+                               status                : 0,
+                               statusText            : 'n/a',
+                               getAllResponseHeaders : function() {},
+                               getResponseHeader     : function() {},
+                               setRequestHeader      : function() {},
+                               abort                 : function(status) {
+                                       var e = (status === 'timeout' ? 'timeout' : 'aborted');
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    var form = this[0];
-    var els = semantic ? form.getElementsByTagName('*') : form.elements;
-    if (!els) {
-        return a;
-    }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 log('aborting upload... ' + e);
+                                       this.aborted = 1;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    var i,j,n,v,el,max,jmax;
-    for(i=0, max=els.length; i < max; i++) {
-        el = els[i];
-        n = el.name;
-        if (!n || el.disabled) {
-            continue;
-        }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 try { // #214, #257
+                                               if (io.contentWindow.document.execCommand) {
+                                                       io.contentWindow.document.execCommand('Stop');
+                                               }
+                                       } catch (ignore) {}
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        if (semantic && form.clk && el.type == "image") {
-            // handle image inputs on the fly when semantic == true
-            if(form.clk == el) {
-                a.push({name: n, value: $(el).val(), type: el.type });
-                a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
-            }
-            continue;
-        }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 $io.attr('src', s.iframeSrc); // abort op in progress
+                                       xhr.error = e;
+                                       if (s.error) {
+                                               s.error.call(s.context, xhr, e, status);
+                                       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        v = $.fieldValue(el, true);
-        if (v && v.constructor == Array) {
-            if (elements)
-                elements.push(el);
-            for(j=0, jmax=v.length; j < jmax; j++) {
-                a.push({name: n, value: v[j]});
-            }
-        }
-        else if (feature.fileapi && el.type == 'file') {
-            if (elements)
-                elements.push(el);
-            var files = el.files;
-            if (files.length) {
-                for (j=0; j < files.length; j++) {
-                    a.push({name: n, value: files[j], type: el.type});
-                }
-            }
-            else {
-                // #180
-                a.push({ name: n, value: '', type: el.type });
-            }
-        }
-        else if (v !== null && typeof v != 'undefined') {
-            if (elements)
-                elements.push(el);
-            a.push({name: n, value: v, type: el.type, required: el.required});
-        }
-    }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 if (g) {
+                                               $.event.trigger('ajaxError', [xhr, s, e]);
+                                       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    if (!semantic && form.clk) {
-        // input type=='image' are not found in elements array! handle it here
-        var $input = $(form.clk), input = $input[0];
-        n = input.name;
-        if (n && !input.disabled && input.type == 'image') {
-            a.push({name: n, value: $input.val()});
-            a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
-        }
-    }
-    return a;
-};
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 if (s.complete) {
+                                               s.complete.call(s.context, xhr, e);
+                                       }
+                               }
+                       };
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/**
- * Serializes form data into a 'submittable' string. This method will return a string
- * in the format: name1=value1&amp;name2=value2
- */
-$.fn.formSerialize = function(semantic) {
-    //hand off to jQuery.param for proper encoding
-    return $.param(this.formToArray(semantic));
-};
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 g = s.global;
+                       // trigger ajax global events so that activity/block indicators work like normal
+                       if (g && $.active++ === 0) {
+                               $.event.trigger('ajaxStart');
+                       }
+                       if (g) {
+                               $.event.trigger('ajaxSend', [xhr, s]);
+                       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/**
- * Serializes all field elements in the jQuery object into a query string.
- * This method will return a string in the format: name1=value1&amp;name2=value2
- */
-$.fn.fieldSerialize = function(successful) {
-    var a = [];
-    this.each(function() {
-        var n = this.name;
-        if (!n) {
-            return;
-        }
-        var v = $.fieldValue(this, successful);
-        if (v && v.constructor == Array) {
-            for (var i=0,max=v.length; i < max; i++) {
-                a.push({name: n, value: v[i]});
-            }
-        }
-        else if (v !== null && typeof v != 'undefined') {
-            a.push({name: this.name, value: v});
-        }
-    });
-    //hand off to jQuery.param for proper encoding
-    return $.param(a);
-};
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
+                               if (s.global) {
+                                       $.active--;
+                               }
+                               deferred.reject();
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/**
- * Returns the value(s) of the element in the matched set.  For example, consider the following form:
- *
- *  <form><fieldset>
- *      <input name="A" type="text" />
- *      <input name="A" type="text" />
- *      <input name="B" type="checkbox" value="B1" />
- *      <input name="B" type="checkbox" value="B2"/>
- *      <input name="C" type="radio" value="C1" />
- *      <input name="C" type="radio" value="C2" />
- *  </fieldset></form>
- *
- *  var v = $('input[type=text]').fieldValue();
- *  // if no values are entered into the text inputs
- *  v == ['','']
- *  // if values entered into the text inputs are 'foo' and 'bar'
- *  v == ['foo','bar']
- *
- *  var v = $('input[type=checkbox]').fieldValue();
- *  // if neither checkbox is checked
- *  v === undefined
- *  // if both checkboxes are checked
- *  v == ['B1', 'B2']
- *
- *  var v = $('input[type=radio]').fieldValue();
- *  // if neither radio is checked
- *  v === undefined
- *  // if first radio is checked
- *  v == ['C1']
- *
- * The successful argument controls whether or not the field element must be 'successful'
- * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
- * The default value of the successful argument is true.  If this value is false the value(s)
- * for each element is returned.
- *
- * Note: This method *always* returns an array.  If no valid value can be determined the
- *    array will be empty, otherwise it will contain one or more values.
- */
-$.fn.fieldValue = function(successful) {
-    for (var val=[], i=0, max=this.length; i < max; i++) {
-        var el = this[i];
-        var v = $.fieldValue(el, successful);
-        if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) {
-            continue;
-        }
-        if (v.constructor == Array)
-            $.merge(val, v);
-        else
-            val.push(v);
-    }
-    return val;
-};
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         return deferred;
+                       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/**
- * Returns the value of the field element.
- */
-$.fieldValue = function(el, successful) {
-    var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
-    if (successful === undefined) {
-        successful = true;
-    }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 if (xhr.aborted) {
+                               deferred.reject();
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
-        (t == 'checkbox' || t == 'radio') && !el.checked ||
-        (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
-        tag == 'select' && el.selectedIndex == -1)) {
-            return null;
-    }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         return deferred;
+                       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    if (tag == 'select') {
-        var index = el.selectedIndex;
-        if (index < 0) {
-            return null;
-        }
-        var a = [], ops = el.options;
-        var one = (t == 'select-one');
-        var max = (one ? index+1 : ops.length);
-        for(var i=(one ? index : 0); i < max; i++) {
-            var op = ops[i];
-            if (op.selected) {
-                var v = op.value;
-                if (!v) { // extra pain for IE...
-                    v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
-                }
-                if (one) {
-                    return v;
-                }
-                a.push(v);
-            }
-        }
-        return a;
-    }
-    return $(el).val();
-};
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 // add submitting element to data if we know it
+                       sub = form.clk;
+                       if (sub) {
+                               n = sub.name;
+                               if (n && !sub.disabled) {
+                                       s.extraData = s.extraData || {};
+                                       s.extraData[n] = sub.value;
+                                       if (sub.type === 'image') {
+                                               s.extraData[n + '.x'] = form.clk_x;
+                                               s.extraData[n + '.y'] = form.clk_y;
+                                       }
+                               }
+                       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/**
- * Clears the form data.  Takes the following actions on the form's input fields:
- *  - input text fields will have their 'value' property set to the empty string
- *  - select elements will have their 'selectedIndex' property set to -1
- *  - checkbox and radio inputs will have their 'checked' property set to false
- *  - inputs of type submit, button, reset, and hidden will *not* be effected
- *  - button elements will *not* be effected
- */
-$.fn.clearForm = function(includeHidden) {
-    return this.each(function() {
-        $('input,select,textarea', this).clearFields(includeHidden);
-    });
-};
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 var CLIENT_TIMEOUT_ABORT = 1;
+                       var SERVER_ABORT = 2;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/**
- * Clears the selected form elements.
- */
-$.fn.clearFields = $.fn.clearInputs = function(includeHidden) {
-    var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list
-    return this.each(function() {
-        var t = this.type, tag = this.tagName.toLowerCase();
-        if (re.test(t) || tag == 'textarea') {
-            this.value = '';
-        }
-        else if (t == 'checkbox' || t == 'radio') {
-            this.checked = false;
-        }
-        else if (tag == 'select') {
-            this.selectedIndex = -1;
-        }
-               else if (t == "file") {
-                       if (/MSIE/.test(navigator.userAgent)) {
-                               $(this).replaceWith($(this).clone(true));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 function getDoc(frame) {
+                               /* it looks like contentWindow or contentDocument do not
+                                * carry the protocol property in ie8, when running under ssl
+                                * frame.document is the only valid response document, since
+                                * the protocol is know but not on the other two objects. strange?
+                                * "Same origin policy" http://en.wikipedia.org/wiki/Same_origin_policy
+                                */
+
+                               var doc = null;
+
+                               // IE8 cascading access check
+                               try {
+                                       if (frame.contentWindow) {
+                                               doc = frame.contentWindow.document;
+                                       }
+                               } catch (err) {
+                                       // IE8 access denied under ssl & missing protocol
+                                       log('cannot get iframe.contentWindow document: ' + err);
+                               }
+
+                               if (doc) { // successful getting content
+                                       return doc;
+                               }
+
+                               try { // simply checking may throw in ie8 under ssl or mismatched protocol
+                                       doc = frame.contentDocument ? frame.contentDocument : frame.document;
+                               } catch (err) {
+                                       // last attempt
+                                       log('cannot get iframe.contentDocument: ' + err);
+                                       doc = frame.document;
+                               }
+
+                               return doc;
+                       }
+
+                       // Rails CSRF hack (thanks to Yvan Barthelemy)
+                       var csrf_token = $('meta[name=csrf-token]').attr('content');
+                       var csrf_param = $('meta[name=csrf-param]').attr('content');
+
+                       if (csrf_param && csrf_token) {
+                               s.extraData = s.extraData || {};
+                               s.extraData[csrf_param] = csrf_token;
+                       }
+
+                       // take a breath so that pending repaints get some cpu time before the upload starts
+                       function doSubmit() {
+                               // make sure form attrs are set
+                               var t = $form.attr2('target'),
+                                       a = $form.attr2('action'),
+                                       mp = 'multipart/form-data',
+                                       et = $form.attr('enctype') || $form.attr('encoding') || mp;
+
+                               // update form attrs in IE friendly way
+                               form.setAttribute('target', id);
+                               if (!method || /post/i.test(method)) {
+                                       form.setAttribute('method', 'POST');
+                               }
+                               if (a !== s.url) {
+                                       form.setAttribute('action', s.url);
+                               }
+
+                               // ie borks in some cases when setting encoding
+                               if (!s.skipEncodingOverride && (!method || /post/i.test(method))) {
+                                       $form.attr({
+                                               encoding : 'multipart/form-data',
+                                               enctype  : 'multipart/form-data'
+                                       });
+                               }
+
+                               // support timout
+                               if (s.timeout) {
+                                       timeoutHandle = setTimeout(function() {
+                                               timedOut = true; cb(CLIENT_TIMEOUT_ABORT);
+                                       }, s.timeout);
+                               }
+
+                               // look for server aborts
+                               function checkState() {
+                                       try {
+                                               var state = getDoc(io).readyState;
+
+                                               log('state = ' + state);
+                                               if (state && state.toLowerCase() === 'uninitialized') {
+                                                       setTimeout(checkState, 50);
+                                               }
+
+                                       } catch (e) {
+                                               log('Server abort: ', e, ' (', e.name, ')');
+                                               cb(SERVER_ABORT);                               // eslint-disable-line callback-return
+                                               if (timeoutHandle) {
+                                                       clearTimeout(timeoutHandle);
+                                               }
+                                               timeoutHandle = undefined;
+                                       }
+                               }
+
+                               // add "extra" data to form if provided in options
+                               var extraInputs = [];
+
+                               try {
+                                       if (s.extraData) {
+                                               for (var n in s.extraData) {
+                                                       if (s.extraData.hasOwnProperty(n)) {
+                                                               // if using the $.param format that allows for multiple values with the same name
+                                                               if ($.isPlainObject(s.extraData[n]) && s.extraData[n].hasOwnProperty('name') && s.extraData[n].hasOwnProperty('value')) {
+                                                                       extraInputs.push(
+                                                                       $('<input type="hidden" name="' + s.extraData[n].name + '">', ownerDocument).val(s.extraData[n].value)
+                                                                               .appendTo(form)[0]);
+                                                               } else {
+                                                                       extraInputs.push(
+                                                                       $('<input type="hidden" name="' + n + '">', ownerDocument).val(s.extraData[n])
+                                                                               .appendTo(form)[0]);
+                                                               }
+                                                       }
+                                               }
+                                       }
+
+                                       if (!s.iframeTarget) {
+                                               // add iframe to doc and submit the form
+                                               $io.appendTo($body);
+                                       }
+
+                                       if (io.attachEvent) {
+                                               io.attachEvent('onload', cb);
+                                       } else {
+                                               io.addEventListener('load', cb, false);
+                                       }
+
+                                       setTimeout(checkState, 15);
+
+                                       try {
+                                               form.submit();
+
+                                       } catch (err) {
+                                               // just in case form has element with name/id of 'submit'
+                                               var submitFn = document.createElement('form').submit;
+
+                                               submitFn.apply(form);
+                                       }
+
+                               } finally {
+                                       // reset attrs and remove "extra" input elements
+                                       form.setAttribute('action', a);
+                                       form.setAttribute('enctype', et); // #380
+                                       if (t) {
+                                               form.setAttribute('target', t);
+                                       } else {
+                                               $form.removeAttr('target');
+                                       }
+                                       $(extraInputs).remove();
+                               }
+                       }
+
+                       if (s.forceSync) {
+                               doSubmit();
</ins><span class="cx" style="display: block; padding: 0 10px">                         } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                $(this).val('');
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         setTimeout(doSubmit, 10); // this lets dom updates render
</ins><span class="cx" style="display: block; padding: 0 10px">                         }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+                       var data, doc, domCheckCount = 50, callbackProcessed;
+
+                       function cb(e) {
+                               if (xhr.aborted || callbackProcessed) {
+                                       return;
+                               }
+
+                               doc = getDoc(io);
+                               if (!doc) {
+                                       log('cannot access response document');
+                                       e = SERVER_ABORT;
+                               }
+                               if (e === CLIENT_TIMEOUT_ABORT && xhr) {
+                                       xhr.abort('timeout');
+                                       deferred.reject(xhr, 'timeout');
+
+                                       return;
+
+                               } else if (e === SERVER_ABORT && xhr) {
+                                       xhr.abort('server abort');
+                                       deferred.reject(xhr, 'error', 'server abort');
+
+                                       return;
+                               }
+
+                               if (!doc || doc.location.href === s.iframeSrc) {
+                                       // response not received yet
+                                       if (!timedOut) {
+                                               return;
+                                       }
+                               }
+
+                               if (io.detachEvent) {
+                                       io.detachEvent('onload', cb);
+                               } else {
+                                       io.removeEventListener('load', cb, false);
+                               }
+
+                               var status = 'success', errMsg;
+
+                               try {
+                                       if (timedOut) {
+                                               throw 'timeout';
+                                       }
+
+                                       var isXml = s.dataType === 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
+
+                                       log('isXml=' + isXml);
+
+                                       if (!isXml && window.opera && (doc.body === null || !doc.body.innerHTML)) {
+                                               if (--domCheckCount) {
+                                                       // in some browsers (Opera) the iframe DOM is not always traversable when
+                                                       // the onload callback fires, so we loop a bit to accommodate
+                                                       log('requeing onLoad callback, DOM not available');
+                                                       setTimeout(cb, 250);
+
+                                                       return;
+                                               }
+                                               // let this fall through because server response could be an empty document
+                                               // log('Could not access iframe DOM after mutiple tries.');
+                                               // throw 'DOMException: not available';
+                                       }
+
+                                       // log('response detected');
+                                       var docRoot = doc.body ? doc.body : doc.documentElement;
+
+                                       xhr.responseText = docRoot ? docRoot.innerHTML : null;
+                                       xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
+                                       if (isXml) {
+                                               s.dataType = 'xml';
+                                       }
+                                       xhr.getResponseHeader = function(header){
+                                               var headers = {'content-type': s.dataType};
+
+                                               return headers[header.toLowerCase()];
+                                       };
+                                       // support for XHR 'status' & 'statusText' emulation :
+                                       if (docRoot) {
+                                               xhr.status = Number(docRoot.getAttribute('status')) || xhr.status;
+                                               xhr.statusText = docRoot.getAttribute('statusText') || xhr.statusText;
+                                       }
+
+                                       var dt = (s.dataType || '').toLowerCase();
+                                       var scr = /(json|script|text)/.test(dt);
+
+                                       if (scr || s.textarea) {
+                                               // see if user embedded response in textarea
+                                               var ta = doc.getElementsByTagName('textarea')[0];
+
+                                               if (ta) {
+                                                       xhr.responseText = ta.value;
+                                                       // support for XHR 'status' & 'statusText' emulation :
+                                                       xhr.status = Number(ta.getAttribute('status')) || xhr.status;
+                                                       xhr.statusText = ta.getAttribute('statusText') || xhr.statusText;
+
+                                               } else if (scr) {
+                                                       // account for browsers injecting pre around json response
+                                                       var pre = doc.getElementsByTagName('pre')[0];
+                                                       var b = doc.getElementsByTagName('body')[0];
+
+                                                       if (pre) {
+                                                               xhr.responseText = pre.textContent ? pre.textContent : pre.innerText;
+                                                       } else if (b) {
+                                                               xhr.responseText = b.textContent ? b.textContent : b.innerText;
+                                                       }
+                                               }
+
+                                       } else if (dt === 'xml' && !xhr.responseXML && xhr.responseText) {
+                                               xhr.responseXML = toXml(xhr.responseText);                      // eslint-disable-line no-use-before-define
+                                       }
+
+                                       try {
+                                               data = httpData(xhr, dt, s);                                            // eslint-disable-line no-use-before-define
+
+                                       } catch (err) {
+                                               status = 'parsererror';
+                                               xhr.error = errMsg = (err || status);
+                                       }
+
+                               } catch (err) {
+                                       log('error caught: ', err);
+                                       status = 'error';
+                                       xhr.error = errMsg = (err || status);
+                               }
+
+                               if (xhr.aborted) {
+                                       log('upload aborted');
+                                       status = null;
+                               }
+
+                               if (xhr.status) { // we've set xhr.status
+                                       status = ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) ? 'success' : 'error';
+                               }
+
+                               // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
+                               if (status === 'success') {
+                                       if (s.success) {
+                                               s.success.call(s.context, data, 'success', xhr);
+                                       }
+
+                                       deferred.resolve(xhr.responseText, 'success', xhr);
+
+                                       if (g) {
+                                               $.event.trigger('ajaxSuccess', [xhr, s]);
+                                       }
+
+                               } else if (status) {
+                                       if (typeof errMsg === 'undefined') {
+                                               errMsg = xhr.statusText;
+                                       }
+                                       if (s.error) {
+                                               s.error.call(s.context, xhr, status, errMsg);
+                                       }
+                                       deferred.reject(xhr, 'error', errMsg);
+                                       if (g) {
+                                               $.event.trigger('ajaxError', [xhr, s, errMsg]);
+                                       }
+                               }
+
+                               if (g) {
+                                       $.event.trigger('ajaxComplete', [xhr, s]);
+                               }
+
+                               if (g && !--$.active) {
+                                       $.event.trigger('ajaxStop');
+                               }
+
+                               if (s.complete) {
+                                       s.complete.call(s.context, xhr, status);
+                               }
+
+                               callbackProcessed = true;
+                               if (s.timeout) {
+                                       clearTimeout(timeoutHandle);
+                               }
+
+                               // clean up
+                               setTimeout(function() {
+                                       if (!s.iframeTarget) {
+                                               $io.remove();
+                                       } else { // adding else to clean up existing iframe response.
+                                               $io.attr('src', s.iframeSrc);
+                                       }
+                                       xhr.responseXML = null;
+                               }, 100);
+                       }
+
+                       var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+)
+                               if (window.ActiveXObject) {
+                                       doc = new ActiveXObject('Microsoft.XMLDOM');
+                                       doc.async = 'false';
+                                       doc.loadXML(s);
+
+                               } else {
+                                       doc = (new DOMParser()).parseFromString(s, 'text/xml');
+                               }
+
+                               return (doc && doc.documentElement && doc.documentElement.nodeName !== 'parsererror') ? doc : null;
+                       };
+                       var parseJSON = $.parseJSON || function(s) {
+                               /* jslint evil:true */
+                               return window['eval']('(' + s + ')');                   // eslint-disable-line dot-notation
+                       };
+
+                       var httpData = function(xhr, type, s) { // mostly lifted from jq1.4.4
+
+                               var ct = xhr.getResponseHeader('content-type') || '',
+                                       xml = ((type === 'xml' || !type) && ct.indexOf('xml') >= 0),
+                                       data = xml ? xhr.responseXML : xhr.responseText;
+
+                               if (xml && data.documentElement.nodeName === 'parsererror') {
+                                       if ($.error) {
+                                               $.error('parsererror');
+                                       }
+                               }
+                               if (s && s.dataFilter) {
+                                       data = s.dataFilter(data, type);
+                               }
+                               if (typeof data === 'string') {
+                                       if ((type === 'json' || !type) && ct.indexOf('json') >= 0) {
+                                               data = parseJSON(data);
+                                       } else if ((type === 'script' || !type) && ct.indexOf('javascript') >= 0) {
+                                               $.globalEval(data);
+                                       }
+                               }
+
+                               return data;
+                       };
+
+                       return deferred;
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        else if (includeHidden) {
-            // includeHidden can be the value true, or it can be a selector string
-            // indicating a special test; for example:
-            //  $('#myForm').clearForm('.special:hidden')
-            // the above would clean hidden inputs that have the class of 'special'
-            if ( (includeHidden === true && /hidden/.test(t)) ||
-                 (typeof includeHidden == 'string' && $(this).is(includeHidden)) )
-                this.value = '';
-        }
-    });
-};
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ };
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/**
- * Resets the form data.  Causes all form elements to be reset to their original value.
- */
-$.fn.resetForm = function() {
-    return this.each(function() {
-        // guard against an input with the name of 'reset'
-        // note that IE reports the reset function as an 'object'
-        if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) {
-            this.reset();
-        }
-    });
-};
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+        * ajaxForm() provides a mechanism for fully automating form submission.
+        *
+        * The advantages of using this method instead of ajaxSubmit() are:
+        *
+        * 1: This method will include coordinates for <input type="image"> elements (if the element
+        *      is used to submit the form).
+        * 2. This method will include the submit element's name/value data (for the element that was
+        *      used to submit the form).
+        * 3. This method binds the submit() method to the form for you.
+        *
+        * The options argument for ajaxForm works exactly as it does for ajaxSubmit. ajaxForm merely
+        * passes the options argument along after properly binding events for submit elements and
+        * the form itself.
+        */
+       $.fn.ajaxForm = function(options, data, dataType, onSuccess) {
+               if (typeof options === 'string' || (options === false && arguments.length > 0)) {
+                       options = {
+                               'url'      : options,
+                               'data'     : data,
+                               'dataType' : dataType
+                       };
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/**
- * Enables or disables any matching elements.
- */
-$.fn.enable = function(b) {
-    if (b === undefined) {
-        b = true;
-    }
-    return this.each(function() {
-        this.disabled = !b;
-    });
-};
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 if (typeof onSuccess === 'function') {
+                               options.success = onSuccess;
+                       }
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/**
- * Checks/unchecks any matching checkboxes or radio buttons and
- * selects/deselects and matching option elements.
- */
-$.fn.selected = function(select) {
-    if (select === undefined) {
-        select = true;
-    }
-    return this.each(function() {
-        var t = this.type;
-        if (t == 'checkbox' || t == 'radio') {
-            this.checked = select;
-        }
-        else if (this.tagName.toLowerCase() == 'option') {
-            var $sel = $(this).parent('select');
-            if (select && $sel[0] && $sel[0].type == 'select-one') {
-                // deselect all other options
-                $sel.find('option').selected(false);
-            }
-            this.selected = select;
-        }
-    });
-};
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         options = options || {};
+               options.delegation = options.delegation && $.isFunction($.fn.on);
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-// expose debug var
-$.fn.ajaxSubmit.debug = false;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // in jQuery 1.3+ we can fix mistakes with the ready state
+               if (!options.delegation && this.length === 0) {
+                       var o = {s: this.selector, c: this.context};
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-// helper fn for console logging
-function log() {
-    if (!$.fn.ajaxSubmit.debug)
-        return;
-    var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
-    if (window.console && window.console.log) {
-        window.console.log(msg);
-    }
-    else if (window.opera && window.opera.postError) {
-        window.opera.postError(msg);
-    }
-}
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 if (!$.isReady && o.s) {
+                               log('DOM not ready, queuing ajaxForm');
+                               $(function() {
+                                       $(o.s, o.c).ajaxForm(options);
+                               });
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-})(jQuery);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         return this;
+                       }
+
+                       // is your DOM ready?  http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
+                       log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
+
+                       return this;
+               }
+
+               if (options.delegation) {
+                       $(document)
+                               .off('submit.form-plugin', this.selector, doAjaxSubmit)
+                               .off('click.form-plugin', this.selector, captureSubmittingElement)
+                               .on('submit.form-plugin', this.selector, options, doAjaxSubmit)
+                               .on('click.form-plugin', this.selector, options, captureSubmittingElement);
+
+                       return this;
+               }
+
+               return this.ajaxFormUnbind()
+                       .on('submit.form-plugin', options, doAjaxSubmit)
+                       .on('click.form-plugin', options, captureSubmittingElement);
+       };
+
+       // private event handlers
+       function doAjaxSubmit(e) {
+               /* jshint validthis:true */
+               var options = e.data;
+
+               if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
+                       e.preventDefault();
+                       $(e.target).closest('form').ajaxSubmit(options); // #365
+               }
+       }
+
+       function captureSubmittingElement(e) {
+               /* jshint validthis:true */
+               var target = e.target;
+               var $el = $(target);
+
+               if (!$el.is('[type=submit],[type=image]')) {
+                       // is this a child element of the submit el?  (ex: a span within a button)
+                       var t = $el.closest('[type=submit]');
+
+                       if (t.length === 0) {
+                               return;
+                       }
+                       target = t[0];
+               }
+
+               var form = target.form;
+
+               form.clk = target;
+
+               if (target.type === 'image') {
+                       if (typeof e.offsetX !== 'undefined') {
+                               form.clk_x = e.offsetX;
+                               form.clk_y = e.offsetY;
+
+                       } else if (typeof $.fn.offset === 'function') {
+                               var offset = $el.offset();
+
+                               form.clk_x = e.pageX - offset.left;
+                               form.clk_y = e.pageY - offset.top;
+
+                       } else {
+                               form.clk_x = e.pageX - target.offsetLeft;
+                               form.clk_y = e.pageY - target.offsetTop;
+                       }
+               }
+               // clear form vars
+               setTimeout(function() {
+                       form.clk = form.clk_x = form.clk_y = null;
+               }, 100);
+       }
+
+
+       // ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
+       $.fn.ajaxFormUnbind = function() {
+               return this.off('submit.form-plugin click.form-plugin');
+       };
+
+       /**
+        * formToArray() gathers form element data into an array of objects that can
+        * be passed to any of the following ajax functions: $.get, $.post, or load.
+        * Each object in the array has both a 'name' and 'value' property. An example of
+        * an array for a simple login form might be:
+        *
+        * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
+        *
+        * It is this array that is passed to pre-submit callback functions provided to the
+        * ajaxSubmit() and ajaxForm() methods.
+        */
+       $.fn.formToArray = function(semantic, elements, filtering) {
+               var a = [];
+
+               if (this.length === 0) {
+                       return a;
+               }
+
+               var form = this[0];
+               var formId = this.attr('id');
+               var els = (semantic || typeof form.elements === 'undefined') ? form.getElementsByTagName('*') : form.elements;
+               var els2;
+
+               if (els) {
+                       els = $.makeArray(els); // convert to standard array
+               }
+
+               // #386; account for inputs outside the form which use the 'form' attribute
+               // FinesseRus: in non-IE browsers outside fields are already included in form.elements.
+               if (formId && (semantic || /(Edge|Trident)\//.test(navigator.userAgent))) {
+                       els2 = $(':input[form="' + formId + '"]').get(); // hat tip @thet
+                       if (els2.length) {
+                               els = (els || []).concat(els2);
+                       }
+               }
+
+               if (!els || !els.length) {
+                       return a;
+               }
+
+               if ($.isFunction(filtering)) {
+                       els = $.map(els, filtering);
+               }
+
+               var i, j, n, v, el, max, jmax;
+
+               for (i = 0, max = els.length; i < max; i++) {
+                       el = els[i];
+                       n = el.name;
+                       if (!n || el.disabled) {
+                               continue;
+                       }
+
+                       if (semantic && form.clk && el.type === 'image') {
+                               // handle image inputs on the fly when semantic == true
+                               if (form.clk === el) {
+                                       a.push({name: n, value: $(el).val(), type: el.type});
+                                       a.push({name: n + '.x', value: form.clk_x}, {name: n + '.y', value: form.clk_y});
+                               }
+                               continue;
+                       }
+
+                       v = $.fieldValue(el, true);
+                       if (v && v.constructor === Array) {
+                               if (elements) {
+                                       elements.push(el);
+                               }
+                               for (j = 0, jmax = v.length; j < jmax; j++) {
+                                       a.push({name: n, value: v[j]});
+                               }
+
+                       } else if (feature.fileapi && el.type === 'file') {
+                               if (elements) {
+                                       elements.push(el);
+                               }
+
+                               var files = el.files;
+
+                               if (files.length) {
+                                       for (j = 0; j < files.length; j++) {
+                                               a.push({name: n, value: files[j], type: el.type});
+                                       }
+                               } else {
+                                       // #180
+                                       a.push({name: n, value: '', type: el.type});
+                               }
+
+                       } else if (v !== null && typeof v !== 'undefined') {
+                               if (elements) {
+                                       elements.push(el);
+                               }
+                               a.push({name: n, value: v, type: el.type, required: el.required});
+                       }
+               }
+
+               if (!semantic && form.clk) {
+                       // input type=='image' are not found in elements array! handle it here
+                       var $input = $(form.clk), input = $input[0];
+
+                       n = input.name;
+
+                       if (n && !input.disabled && input.type === 'image') {
+                               a.push({name: n, value: $input.val()});
+                               a.push({name: n + '.x', value: form.clk_x}, {name: n + '.y', value: form.clk_y});
+                       }
+               }
+
+               return a;
+       };
+
+       /**
+        * Serializes form data into a 'submittable' string. This method will return a string
+        * in the format: name1=value1&amp;name2=value2
+        */
+       $.fn.formSerialize = function(semantic) {
+               // hand off to jQuery.param for proper encoding
+               return $.param(this.formToArray(semantic));
+       };
+
+       /**
+        * Serializes all field elements in the jQuery object into a query string.
+        * This method will return a string in the format: name1=value1&amp;name2=value2
+        */
+       $.fn.fieldSerialize = function(successful) {
+               var a = [];
+
+               this.each(function() {
+                       var n = this.name;
+
+                       if (!n) {
+                               return;
+                       }
+
+                       var v = $.fieldValue(this, successful);
+
+                       if (v && v.constructor === Array) {
+                               for (var i = 0, max = v.length; i < max; i++) {
+                                       a.push({name: n, value: v[i]});
+                               }
+
+                       } else if (v !== null && typeof v !== 'undefined') {
+                               a.push({name: this.name, value: v});
+                       }
+               });
+
+               // hand off to jQuery.param for proper encoding
+               return $.param(a);
+       };
+
+       /**
+        * Returns the value(s) of the element in the matched set. For example, consider the following form:
+        *
+        *      <form><fieldset>
+        *              <input name="A" type="text">
+        *              <input name="A" type="text">
+        *              <input name="B" type="checkbox" value="B1">
+        *              <input name="B" type="checkbox" value="B2">
+        *              <input name="C" type="radio" value="C1">
+        *              <input name="C" type="radio" value="C2">
+        *      </fieldset></form>
+        *
+        *      var v = $('input[type=text]').fieldValue();
+        *      // if no values are entered into the text inputs
+        *      v === ['','']
+        *      // if values entered into the text inputs are 'foo' and 'bar'
+        *      v === ['foo','bar']
+        *
+        *      var v = $('input[type=checkbox]').fieldValue();
+        *      // if neither checkbox is checked
+        *      v === undefined
+        *      // if both checkboxes are checked
+        *      v === ['B1', 'B2']
+        *
+        *      var v = $('input[type=radio]').fieldValue();
+        *      // if neither radio is checked
+        *      v === undefined
+        *      // if first radio is checked
+        *      v === ['C1']
+        *
+        * The successful argument controls whether or not the field element must be 'successful'
+        * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
+        * The default value of the successful argument is true. If this value is false the value(s)
+        * for each element is returned.
+        *
+        * Note: This method *always* returns an array. If no valid value can be determined the
+        *      array will be empty, otherwise it will contain one or more values.
+        */
+       $.fn.fieldValue = function(successful) {
+               for (var val = [], i = 0, max = this.length; i < max; i++) {
+                       var el = this[i];
+                       var v = $.fieldValue(el, successful);
+
+                       if (v === null || typeof v === 'undefined' || (v.constructor === Array && !v.length)) {
+                               continue;
+                       }
+
+                       if (v.constructor === Array) {
+                               $.merge(val, v);
+                       } else {
+                               val.push(v);
+                       }
+               }
+
+               return val;
+       };
+
+       /**
+        * Returns the value of the field element.
+        */
+       $.fieldValue = function(el, successful) {
+               var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
+
+               if (typeof successful === 'undefined') {
+                       successful = true;
+               }
+
+               /* eslint-disable no-mixed-operators */
+               if (successful && (!n || el.disabled || t === 'reset' || t === 'button' ||
+                       (t === 'checkbox' || t === 'radio') && !el.checked ||
+                       (t === 'submit' || t === 'image') && el.form && el.form.clk !== el ||
+                       tag === 'select' && el.selectedIndex === -1)) {
+               /* eslint-enable no-mixed-operators */
+                       return null;
+               }
+
+               if (tag === 'select') {
+                       var index = el.selectedIndex;
+
+                       if (index < 0) {
+                               return null;
+                       }
+
+                       var a = [], ops = el.options;
+                       var one = (t === 'select-one');
+                       var max = (one ? index + 1 : ops.length);
+
+                       for (var i = (one ? index : 0); i < max; i++) {
+                               var op = ops[i];
+
+                               if (op.selected && !op.disabled) {
+                                       var v = op.value;
+
+                                       if (!v) { // extra pain for IE...
+                                               v = (op.attributes && op.attributes.value && !(op.attributes.value.specified)) ? op.text : op.value;
+                                       }
+
+                                       if (one) {
+                                               return v;
+                                       }
+
+                                       a.push(v);
+                               }
+                       }
+
+                       return a;
+               }
+
+               return $(el).val().replace(rCRLF, '\r\n');
+       };
+
+       /**
+        * Clears the form data. Takes the following actions on the form's input fields:
+        *  - input text fields will have their 'value' property set to the empty string
+        *  - select elements will have their 'selectedIndex' property set to -1
+        *  - checkbox and radio inputs will have their 'checked' property set to false
+        *  - inputs of type submit, button, reset, and hidden will *not* be effected
+        *  - button elements will *not* be effected
+        */
+       $.fn.clearForm = function(includeHidden) {
+               return this.each(function() {
+                       $('input,select,textarea', this).clearFields(includeHidden);
+               });
+       };
+
+       /**
+        * Clears the selected form elements.
+        */
+       $.fn.clearFields = $.fn.clearInputs = function(includeHidden) {
+               var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list
+
+               return this.each(function() {
+                       var t = this.type, tag = this.tagName.toLowerCase();
+
+                       if (re.test(t) || tag === 'textarea') {
+                               this.value = '';
+
+                       } else if (t === 'checkbox' || t === 'radio') {
+                               this.checked = false;
+
+                       } else if (tag === 'select') {
+                               this.selectedIndex = -1;
+
+                       } else if (t === 'file') {
+                               if (/MSIE/.test(navigator.userAgent)) {
+                                       $(this).replaceWith($(this).clone(true));
+                               } else {
+                                       $(this).val('');
+                               }
+
+                       } else if (includeHidden) {
+                               // includeHidden can be the value true, or it can be a selector string
+                               // indicating a special test; for example:
+                               // $('#myForm').clearForm('.special:hidden')
+                               // the above would clean hidden inputs that have the class of 'special'
+                               if ((includeHidden === true && /hidden/.test(t)) ||
+                                       (typeof includeHidden === 'string' && $(this).is(includeHidden))) {
+                                       this.value = '';
+                               }
+                       }
+               });
+       };
+
+
+       /**
+        * Resets the form data or individual elements. Takes the following actions
+        * on the selected tags:
+        * - all fields within form elements will be reset to their original value
+        * - input / textarea / select fields will be reset to their original value
+        * - option / optgroup fields (for multi-selects) will defaulted individually
+        * - non-multiple options will find the right select to default
+        * - label elements will be searched against its 'for' attribute
+        * - all others will be searched for appropriate children to default
+        */
+       $.fn.resetForm = function() {
+               return this.each(function() {
+                       var el = $(this);
+                       var tag = this.tagName.toLowerCase();
+
+                       switch (tag) {
+                       case 'input':
+                               this.checked = this.defaultChecked;
+                                       // fall through
+
+                       case 'textarea':
+                               this.value = this.defaultValue;
+
+                               return true;
+
+                       case 'option':
+                       case 'optgroup':
+                               var select = el.parents('select');
+
+                               if (select.length && select[0].multiple) {
+                                       if (tag === 'option') {
+                                               this.selected = this.defaultSelected;
+                                       } else {
+                                               el.find('option').resetForm();
+                                       }
+                               } else {
+                                       select.resetForm();
+                               }
+
+                               return true;
+
+                       case 'select':
+                               el.find('option').each(function(i) {                            // eslint-disable-line consistent-return
+                                       this.selected = this.defaultSelected;
+                                       if (this.defaultSelected && !el[0].multiple) {
+                                               el[0].selectedIndex = i;
+
+                                               return false;
+                                       }
+                               });
+
+                               return true;
+
+                       case 'label':
+                               var forEl = $(el.attr('for'));
+                               var list = el.find('input,select,textarea');
+
+                               if (forEl[0]) {
+                                       list.unshift(forEl[0]);
+                               }
+
+                               list.resetForm();
+
+                               return true;
+
+                       case 'form':
+                                       // guard against an input with the name of 'reset'
+                                       // note that IE reports the reset function as an 'object'
+                               if (typeof this.reset === 'function' || (typeof this.reset === 'object' && !this.reset.nodeType)) {
+                                       this.reset();
+                               }
+
+                               return true;
+
+                       default:
+                               el.find('form,input,label,select,textarea').resetForm();
+
+                               return true;
+                       }
+               });
+       };
+
+       /**
+        * Enables or disables any matching elements.
+        */
+       $.fn.enable = function(b) {
+               if (typeof b === 'undefined') {
+                       b = true;
+               }
+
+               return this.each(function() {
+                       this.disabled = !b;
+               });
+       };
+
+       /**
+        * Checks/unchecks any matching checkboxes or radio buttons and
+        * selects/deselects and matching option elements.
+        */
+       $.fn.selected = function(select) {
+               if (typeof select === 'undefined') {
+                       select = true;
+               }
+
+               return this.each(function() {
+                       var t = this.type;
+
+                       if (t === 'checkbox' || t === 'radio') {
+                               this.checked = select;
+
+                       } else if (this.tagName.toLowerCase() === 'option') {
+                               var $sel = $(this).parent('select');
+
+                               if (select && $sel[0] && $sel[0].type === 'select-one') {
+                                       // deselect all other options
+                                       $sel.find('option').selected(false);
+                               }
+
+                               this.selected = select;
+                       }
+               });
+       };
+
+       // expose debug var
+       $.fn.ajaxSubmit.debug = false;
+
+       // helper fn for console logging
+       function log() {
+               if (!$.fn.ajaxSubmit.debug) {
+                       return;
+               }
+
+               var msg = '[jquery.form] ' + Array.prototype.join.call(arguments, '');
+
+               if (window.console && window.console.log) {
+                       window.console.log(msg);
+
+               } else if (window.opera && window.opera.postError) {
+                       window.opera.postError(msg);
+               }
+       }
+}));
</ins></span></pre></div>
<a id="trunksrcwpincludesjsjqueryjqueryformminjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/js/jquery/jquery.form.min.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/js/jquery/jquery.form.min.js        2017-08-04 23:00:50 UTC (rev 41232)
+++ trunk/src/wp-includes/js/jquery/jquery.form.min.js  2017-08-05 12:59:12 UTC (rev 41233)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,11 +1,12 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /*!
</span><span class="cx" style="display: block; padding: 0 10px">  * jQuery Form Plugin
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * version: 3.37.0-2013.07.11
- * @requires jQuery v1.5 or later
- * Copyright (c) 2013 M. Alsup
- * Examples and documentation at: http://malsup.com/jquery/form/
- * Project repository: https://github.com/malsup/form
- * Dual licensed under the MIT and GPL licenses.
- * https://github.com/malsup/form#copyright-and-license
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * version: 4.2.1
+ * Requires jQuery v1.7 or later
+ * Copyright 2017 Kevin Morris
+ * Copyright 2006 M. Alsup
+ * Project repository: https://github.com/jquery-form/form
+ * Dual licensed under the MIT and LGPLv3 licenses.
+ * https://github.com/jquery-form/form#license
</ins><span class="cx" style="display: block; padding: 0 10px">  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-!function(a){"use strict";function b(b){var c=b.data;b.isDefaultPrevented()||(b.preventDefault(),a(this).ajaxSubmit(c))}function c(b){var c=b.target,d=a(c);if(!d.is("[type=submit],[type=image]")){var e=d.closest("[type=submit]");if(0===e.length)return;c=e[0]}var f=this;if(f.clk=c,"image"==c.type)if(void 0!==b.offsetX)f.clk_x=b.offsetX,f.clk_y=b.offsetY;else if("function"==typeof a.fn.offset){var g=d.offset();f.clk_x=b.pageX-g.left,f.clk_y=b.pageY-g.top}else f.clk_x=b.pageX-c.offsetLeft,f.clk_y=b.pageY-c.offsetTop;setTimeout(function(){f.clk=f.clk_x=f.clk_y=null},100)}function d(){if(a.fn.ajaxSubmit.debug){var b="[jquery.form] "+Array.prototype.join.call(arguments,"");window.console&&window.console.log?window.console.log(b):window.opera&&window.opera.postError&&window.opera.postError(b)}}var e={}
 ;e.fileapi=void 0!==a("<input type='file'/>").get(0).files,e.formdata=void 0!==window.FormData;var f=!!a.fn.prop;a.fn.attr2=function(){if(!f)return this.attr.apply(this,arguments);var a=this.prop.apply(this,arguments);return a&&a.jquery||"string"==typeof a?a:this.attr.apply(this,arguments)},a.fn.ajaxSubmit=function(b){function c(c){var d,e,f=a.param(c,b.traditional).split("&"),g=f.length,h=[];for(d=0;g>d;d++)f[d]=f[d].replace(/\+/g," "),e=f[d].split("="),h.push([decodeURIComponent(e[0]),decodeURIComponent(e[1])]);return h}function g(d){for(var e=new FormData,f=0;f<d.length;f++)e.append(d[f].name,d[f].value);if(b.extraData){var g=c(b.extraData);for(f=0;f<g.length;f++)g[f]&&e.append(g[f][0],g[f][1])}b.data=null;var h=a.extend(!0,{},a.ajaxSettings,b,{contentType:!1,processData:!1,cache:!1,type:i||"POST"});b.uploadProgress&&(h.xhr=function(){var c=a.ajaxSettings.xhr();return c.upload&a
 mp;&c.upload.addEventListener("progress",function(a){var c=0,d=a.loaded||a.position,e=a.total;a.lengthComputable&&(c=Math.ceil(100*(d/e))),b.uploadProgress(a,d,e,c)},!1),c}),h.data=null;var j=h.beforeSend;return h.beforeSend=function(a,b){b.data=e,j&&j.call(this,a,b)},a.ajax(h)}function h(c){function e(a){var b=null;try{a.contentWindow&&(b=a.contentWindow.document)}catch(c){d("cannot get iframe.contentWindow document: "+c)}if(b)return b;try{b=a.contentDocument?a.contentDocument:a.document}catch(c){d("cannot get iframe.contentDocument: "+c),b=a.document}return b}function g(){function b(){try{var a=e(r).readyState;d("state = "+a),a&&"uninitialized"==a.toLowerCase()&&setTimeout(b,50)}catch(c){d("Server abort: ",c," (",c.name,")"),h(A),w&&clearTimeout(w),w=void 0}}var c=l.attr2("target"),f=l.attr2("action");x.setAttribute("target&qu
 ot;,o),i||x.setAttribute("method","POST"),f!=m.url&&x.setAttribute("action",m.url),m.skipEncodingOverride||i&&!/post/i.test(i)||l.attr({encoding:"multipart/form-data",enctype:"multipart/form-data"}),m.timeout&&(w=setTimeout(function(){v=!0,h(z)},m.timeout));var g=[];try{if(m.extraData)for(var j in m.extraData)m.extraData.hasOwnProperty(j)&&(a.isPlainObject(m.extraData[j])&&m.extraData[j].hasOwnProperty("name")&&m.extraData[j].hasOwnProperty("value")?g.push(a('<input type="hidden" name="'+m.extraData[j].name+'">').val(m.extraData[j].value).appendTo(x)[0]):g.push(a('<input type="hidden" name="'+j+'">').val(m.extraData[j]).appendTo(x)[0]));m.iframeTarget||(q.appendTo("body"),r.attachEvent?r.attachEvent("onload",h):r.addEventListener("load",h,!1)),setTimeout(b,15);try{x.submit()}catch(k){va
 r n=document.createElement("form").submit;n.apply(x)}}finally{x.setAttribute("action",f),c?x.setAttribute("target",c):l.removeAttr("target"),a(g).remove()}}function h(b){if(!s.aborted&&!F){if(E=e(r),E||(d("cannot access response document"),b=A),b===z&&s)return s.abort("timeout"),y.reject(s,"timeout"),void 0;if(b==A&&s)return s.abort("server abort"),y.reject(s,"error","server abort"),void 0;if(E&&E.location.href!=m.iframeSrc||v){r.detachEvent?r.detachEvent("onload",h):r.removeEventListener("load",h,!1);var c,f="success";try{if(v)throw"timeout";var g="xml"==m.dataType||E.XMLDocument||a.isXMLDoc(E);if(d("isXml="+g),!g&&window.opera&&(null===E.body||!E.body.innerHTML)&&--G)return d("requeing onLoad callback, DOM not available"),setTimeout(h,250),void 0;var i=E.body
 ?E.body:E.documentElement;s.responseText=i?i.innerHTML:null,s.responseXML=E.XMLDocument?E.XMLDocument:E,g&&(m.dataType="xml"),s.getResponseHeader=function(a){var b={"content-type":m.dataType};return b[a]},i&&(s.status=Number(i.getAttribute("status"))||s.status,s.statusText=i.getAttribute("statusText")||s.statusText);var j=(m.dataType||"").toLowerCase(),k=/(json|script|text)/.test(j);if(k||m.textarea){var l=E.getElementsByTagName("textarea")[0];if(l)s.responseText=l.value,s.status=Number(l.getAttribute("status"))||s.status,s.statusText=l.getAttribute("statusText")||s.statusText;else if(k){var o=E.getElementsByTagName("pre")[0],p=E.getElementsByTagName("body")[0];o?s.responseText=o.textContent?o.textContent:o.innerText:p&&(s.responseText=p.textContent?p.textContent:p.innerText)}}else"xml"==j&&!s.responseXML&&s.responseText&&(s.re
 sponseXML=H(s.responseText));try{D=J(s,j,m)}catch(t){f="parsererror",s.error=c=t||f}}catch(t){d("error caught: ",t),f="error",s.error=c=t||f}s.aborted&&(d("upload aborted"),f=null),s.status&&(f=s.status>=200&&s.status<300||304===s.status?"success":"error"),"success"===f?(m.success&&m.success.call(m.context,D,"success",s),y.resolve(s.responseText,"success",s),n&&a.event.trigger("ajaxSuccess",[s,m])):f&&(void 0===c&&(c=s.statusText),m.error&&m.error.call(m.context,s,f,c),y.reject(s,"error",c),n&&a.event.trigger("ajaxError",[s,m,c])),n&&a.event.trigger("ajaxComplete",[s,m]),n&&!--a.active&&a.event.trigger("ajaxStop"),m.complete&&m.complete.call(m.context,s,f),F=!0,m.timeout&&clearTimeout(w),setTimeout(function(){m.iframeTarget||q.re
 move(),s.responseXML=null},100)}}}var j,k,m,n,o,q,r,s,t,u,v,w,x=l[0],y=a.Deferred();if(c)for(k=0;k<p.length;k++)j=a(p[k]),f?j.prop("disabled",!1):j.removeAttr("disabled");if(m=a.extend(!0,{},a.ajaxSettings,b),m.context=m.context||m,o="jqFormIO"+(new Date).getTime(),m.iframeTarget?(q=a(m.iframeTarget),u=q.attr2("name"),u?o=u:q.attr2("name",o)):(q=a('<iframe name="'+o+'" src="'+m.iframeSrc+'" />'),q.css({position:"absolute",top:"-1000px",left:"-1000px"})),r=q[0],s={aborted:0,responseText:null,responseXML:null,status:0,statusText:"n/a",getAllResponseHeaders:function(){},getResponseHeader:function(){},setRequestHeader:function(){},abort:function(b){var c="timeout"===b?"timeout":"aborted";d("aborting upload... "+c),this.aborted=1;try{r.contentWindow.document.execCommand&&r.contentWindow.document.execCommand("Stop"
 )}catch(e){}q.attr("src",m.iframeSrc),s.error=c,m.error&&m.error.call(m.context,s,c,b),n&&a.event.trigger("ajaxError",[s,m,c]),m.complete&&m.complete.call(m.context,s,c)}},n=m.global,n&&0===a.active++&&a.event.trigger("ajaxStart"),n&&a.event.trigger("ajaxSend",[s,m]),m.beforeSend&&m.beforeSend.call(m.context,s,m)===!1)return m.global&&a.active--,y.reject(),y;if(s.aborted)return y.reject(),y;t=x.clk,t&&(u=t.name,u&&!t.disabled&&(m.extraData=m.extraData||{},m.extraData[u]=t.value,"image"==t.type&&(m.extraData[u+".x"]=x.clk_x,m.extraData[u+".y"]=x.clk_y)));var z=1,A=2,B=a("meta[name=csrf-token]").attr("content"),C=a("meta[name=csrf-param]").attr("content");C&&B&&(m.extraData=m.extraData||{},m.extraData[C]=B),m.forceSync?g():setTimeout(g,10);var D,E,F,G=50,H=a.parseXML
 ||function(a,b){return window.ActiveXObject?(b=new ActiveXObject("Microsoft.XMLDOM"),b.async="false",b.loadXML(a)):b=(new DOMParser).parseFromString(a,"text/xml"),b&&b.documentElement&&"parsererror"!=b.documentElement.nodeName?b:null},I=a.parseJSON||function(a){return window.eval("("+a+")")},J=function(b,c,d){var e=b.getResponseHeader("content-type")||"",f="xml"===c||!c&&e.indexOf("xml")>=0,g=f?b.responseXML:b.responseText;return f&&"parsererror"===g.documentElement.nodeName&&a.error&&a.error("parsererror"),d&&d.dataFilter&&(g=d.dataFilter(g,c)),"string"==typeof g&&("json"===c||!c&&e.indexOf("json")>=0?g=I(g):("script"===c||!c&&e.indexOf("javascript")>=0)&&a.globalEval(g)),g};return y}if(!this.length)return d(&qu
 ot;ajaxSubmit: skipping submit process - no element selected"),this;var i,j,k,l=this;"function"==typeof b?b={success:b}:void 0===b&&(b={}),i=b.type||this.attr2("method"),j=b.url||this.attr2("action"),k="string"==typeof j?a.trim(j):"",k=k||window.location.href||"",k&&(k=(k.match(/^([^#]+)/)||[])[1]),b=a.extend(!0,{url:k,success:a.ajaxSettings.success,type:i||"GET",iframeSrc:/^https/i.test(window.location.href||"")?"javascript:false":"about:blank"},b);var m={};if(this.trigger("form-pre-serialize",[this,b,m]),m.veto)return d("ajaxSubmit: submit vetoed via form-pre-serialize trigger"),this;if(b.beforeSerialize&&b.beforeSerialize(this,b)===!1)return d("ajaxSubmit: submit aborted via beforeSerialize callback"),this;var n=b.traditional;void 0===n&&(n=a.ajaxSettings.traditional);var o,p=[],q=this.formToArray(b.semantic,p);if(b
 .data&&(b.extraData=b.data,o=a.param(b.data,n)),b.beforeSubmit&&b.beforeSubmit(q,this,b)===!1)return d("ajaxSubmit: submit aborted via beforeSubmit callback"),this;if(this.trigger("form-submit-validate",[q,this,b,m]),m.veto)return d("ajaxSubmit: submit vetoed via form-submit-validate trigger"),this;var r=a.param(q,n);o&&(r=r?r+"&"+o:o),"GET"==b.type.toUpperCase()?(b.url+=(b.url.indexOf("?")>=0?"&":"?")+r,b.data=null):b.data=r;var s=[];if(b.resetForm&&s.push(function(){l.resetForm()}),b.clearForm&&s.push(function(){l.clearForm(b.includeHidden)}),!b.dataType&&b.target){var t=b.success||function(){};s.push(function(c){var d=b.replaceTarget?"replaceWith":"html";a(b.target)[d](c).each(t,arguments)})}else b.success&&s.push(b.success);if(b.success=function(a,c,d){for(var e=b.context||this,f=0,g=s.length;g>f;f++)s[f].apply(
 e,[a,c,d||l,l])},b.error){var u=b.error;b.error=function(a,c,d){var e=b.context||this;u.apply(e,[a,c,d,l])}}if(b.complete){var v=b.complete;b.complete=function(a,c){var d=b.context||this;v.apply(d,[a,c,l])}}var w=a('input[type=file]:enabled[value!=""]',this),x=w.length>0,y="multipart/form-data",z=l.attr("enctype")==y||l.attr("encoding")==y,A=e.fileapi&&e.formdata;d("fileAPI :"+A);var B,C=(x||z)&&!A;b.iframe!==!1&&(b.iframe||C)?b.closeKeepAlive?a.get(b.closeKeepAlive,function(){B=h(q)}):B=h(q):B=(x||z)&&A?g(q):a.ajax(b),l.removeData("jqxhr").data("jqxhr",B);for(var D=0;D<p.length;D++)p[D]=null;return this.trigger("form-submit-notify",[this,b]),this},a.fn.ajaxForm=function(e){if(e=e||{},e.delegation=e.delegation&&a.isFunction(a.fn.on),!e.delegation&&0===this.length){var f={s:this.selector,c:this.context};return!a.isReady&&f.s?(d("DOM not re
 ady, queuing ajaxForm"),a(function(){a(f.s,f.c).ajaxForm(e)}),this):(d("terminating; zero elements found by selector"+(a.isReady?"":" (DOM not ready)")),this)}return e.delegation?(a(document).off("submit.form-plugin",this.selector,b).off("click.form-plugin",this.selector,c).on("submit.form-plugin",this.selector,e,b).on("click.form-plugin",this.selector,e,c),this):this.ajaxFormUnbind().bind("submit.form-plugin",e,b).bind("click.form-plugin",e,c)},a.fn.ajaxFormUnbind=function(){return this.unbind("submit.form-plugin click.form-plugin")},a.fn.formToArray=function(b,c){var d=[];if(0===this.length)return d;var f=this[0],g=b?f.getElementsByTagName("*"):f.elements;if(!g)return d;var h,i,j,k,l,m,n;for(h=0,m=g.length;m>h;h++)if(l=g[h],j=l.name,j&&!l.disabled)if(b&&f.clk&&"image"==l.type)f.clk==l&&(d.push({name:j,value:a(l).val(),type:
 l.type}),d.push({name:j+".x",value:f.clk_x},{name:j+".y",value:f.clk_y}));else if(k=a.fieldValue(l,!0),k&&k.constructor==Array)for(c&&c.push(l),i=0,n=k.length;n>i;i++)d.push({name:j,value:k[i]});else if(e.fileapi&&"file"==l.type){c&&c.push(l);var o=l.files;if(o.length)for(i=0;i<o.length;i++)d.push({name:j,value:o[i],type:l.type});else d.push({name:j,value:"",type:l.type})}else null!==k&&"undefined"!=typeof k&&(c&&c.push(l),d.push({name:j,value:k,type:l.type,required:l.required}));if(!b&&f.clk){var p=a(f.clk),q=p[0];j=q.name,j&&!q.disabled&&"image"==q.type&&(d.push({name:j,value:p.val()}),d.push({name:j+".x",value:f.clk_x},{name:j+".y",value:f.clk_y}))}return d},a.fn.formSerialize=function(b){return a.param(this.formToArray(b))},a.fn.fieldSerialize=function(b){var c=[];return this.each(function(){var d=this.name;
 if(d){var e=a.fieldValue(this,b);if(e&&e.constructor==Array)for(var f=0,g=e.length;g>f;f++)c.push({name:d,value:e[f]});else null!==e&&"undefined"!=typeof e&&c.push({name:this.name,value:e})}}),a.param(c)},a.fn.fieldValue=function(b){for(var c=[],d=0,e=this.length;e>d;d++){var f=this[d],g=a.fieldValue(f,b);null===g||"undefined"==typeof g||g.constructor==Array&&!g.length||(g.constructor==Array?a.merge(c,g):c.push(g))}return c},a.fieldValue=function(b,c){var d=b.name,e=b.type,f=b.tagName.toLowerCase();if(void 0===c&&(c=!0),c&&(!d||b.disabled||"reset"==e||"button"==e||("checkbox"==e||"radio"==e)&&!b.checked||("submit"==e||"image"==e)&&b.form&&b.form.clk!=b||"select"==f&&-1==b.selectedIndex))return null;if("select"==f){var g=b.selectedIndex;if(0>g)return null;for(var h=[],i=b.options,j="select-one
 "==e,k=j?g+1:i.length,l=j?g:0;k>l;l++){var m=i[l];if(m.selected){var n=m.value;if(n||(n=m.attributes&&m.attributes.value&&!m.attributes.value.specified?m.text:m.value),j)return n;h.push(n)}}return h}return a(b).val()},a.fn.clearForm=function(b){return this.each(function(){a("input,select,textarea",this).clearFields(b)})},a.fn.clearFields=a.fn.clearInputs=function(b){var c=/^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i;return this.each(function(){var d=this.type,e=this.tagName.toLowerCase();c.test(d)||"textarea"==e?this.value="":"checkbox"==d||"radio"==d?this.checked=!1:"select"==e?this.selectedIndex=-1:"file"==d?/MSIE/.test(navigator.userAgent)?a(this).replaceWith(a(this).clone(!0)):a(this).val(""):b&&(b===!0&&/hidden/.test(d)||"string"==typeof b&&a(this).is(b))&&(this.value="")})},a.
 fn.resetForm=function(){return this.each(function(){("function"==typeof this.reset||"object"==typeof this.reset&&!this.reset.nodeType)&&this.reset()})},a.fn.enable=function(a){return void 0===a&&(a=!0),this.each(function(){this.disabled=!a})},a.fn.selected=function(b){return void 0===b&&(b=!0),this.each(function(){var c=this.type;if("checkbox"==c||"radio"==c)this.checked=b;else if("option"==this.tagName.toLowerCase()){var d=a(this).parent("select");b&&d[0]&&"select-one"==d[0].type&&d.find("option").selected(!1),this.selected=b}})},a.fn.ajaxSubmit.debug=!1}(jQuery);
</del><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of file
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof module&&module.exports?module.exports=function(b,c){return void 0===c&&(c="undefined"!=typeof window?require("jquery"):require("jquery")(b)),a(c),c}:a(jQuery)}(function(a){"use strict";function b(b){var c=b.data;b.isDefaultPrevented()||(b.preventDefault(),a(b.target).closest("form").ajaxSubmit(c))}function c(b){var c=b.target,d=a(c);if(!d.is("[type=submit],[type=image]")){var e=d.closest("[type=submit]");if(0===e.length)return;c=e[0]}var f=c.form;if(f.clk=c,"image"===c.type)if(void 0!==b.offsetX)f.clk_x=b.offsetX,f.clk_y=b.offsetY;else if("function"==typeof a.fn.offset){var g=d.offset();f.clk_x=b.pageX-g.left,f.clk_y=b.pageY-g.top}else f.clk_x=b.pageX-c.offse
 tLeft,f.clk_y=b.pageY-c.offsetTop;setTimeout(function(){f.clk=f.clk_x=f.clk_y=null},100)}function d(){if(a.fn.ajaxSubmit.debug){var b="[jquery.form] "+Array.prototype.join.call(arguments,"");window.console&&window.console.log?window.console.log(b):window.opera&&window.opera.postError&&window.opera.postError(b)}}var e={};e.fileapi=void 0!==a('<input type="file">').get(0).files,e.formdata=void 0!==window.FormData;var f=!!a.fn.prop;a.fn.attr2=function(){if(!f)return this.attr.apply(this,arguments);var a=this.prop.apply(this,arguments);return a&&a.jquery||"string"==typeof a?a:this.attr.apply(this,arguments)},a.fn.ajaxSubmit=function(b,c,g,h){function i(c){var d,e,f=a.param(c,b.traditional).split("&"),g=f.length,h=[];for(d=0;d<g;d++)f[d]=f[d].replace(/\+/g," "),e=f[d].split("="),h.push([decodeURIComponent(e[0]),decodeURIComponent(e[1])]);return h}function j(c){for(var d=new 
 FormData,e=0;e<c.length;e++)d.append(c[e].name,c[e].value);if(b.extraData){var f=i(b.extraData);for(e=0;e<f.length;e++)f[e]&&d.append(f[e][0],f[e][1])}b.data=null;var g=a.extend(!0,{},a.ajaxSettings,b,{contentType:!1,processData:!1,cache:!1,type:l||"POST"});b.uploadProgress&&(g.xhr=function(){var c=a.ajaxSettings.xhr();return c.upload&&c.upload.addEventListener("progress",function(a){var c=0,d=a.loaded||a.position,e=a.total;a.lengthComputable&&(c=Math.ceil(d/e*100)),b.uploadProgress(a,d,e,c)},!1),c}),g.data=null;var h=g.beforeSend;return g.beforeSend=function(a,c){b.formData?c.data=b.formData:c.data=d,h&&h.call(this,a,c)},a.ajax(g)}function k(c){function e(a){var b=null;try{a.contentWindow&&(b=a.contentWindow.document)}catch(a){d("cannot get iframe.contentWindow document: "+a)}if(b)return b;try{b=a.contentDocument?a.contentDocument:a.document}catch(c){d("cannot get iframe.contentDocument: "
 +c),b=a.document}return b}function g(){function b(){try{var a=e(q).readyState;d("state = "+a),a&&"uninitialized"===a.toLowerCase()&&setTimeout(b,50)}catch(a){d("Server abort: ",a," (",a.name,")"),h(2),w&&clearTimeout(w),w=void 0}}var c=o.attr2("target"),f=o.attr2("action"),g=o.attr("enctype")||o.attr("encoding")||"multipart/form-data";x.setAttribute("target",n),l&&!/post/i.test(l)||x.setAttribute("method","POST"),f!==k.url&&x.setAttribute("action",k.url),k.skipEncodingOverride||l&&!/post/i.test(l)||o.attr({encoding:"multipart/form-data",enctype:"multipart/form-data"}),k.timeout&&(w=setTimeout(function(){v=!0,h(1)},k.timeout));var i=[];try{if(k.extraData)for(var j in k.extraData)k.extraData.hasOwnProperty(j)&&(a.isPlainObject(k.extraData[j])&&k.extraData[j
 ].hasOwnProperty("name")&&k.extraData[j].hasOwnProperty("value")?i.push(a('<input type="hidden" name="'+k.extraData[j].name+'">',z).val(k.extraData[j].value).appendTo(x)[0]):i.push(a('<input type="hidden" name="'+j+'">',z).val(k.extraData[j]).appendTo(x)[0]));k.iframeTarget||p.appendTo(A),q.attachEvent?q.attachEvent("onload",h):q.addEventListener("load",h,!1),setTimeout(b,15);try{x.submit()}catch(a){var m=document.createElement("form").submit;m.apply(x)}}finally{x.setAttribute("action",f),x.setAttribute("enctype",g),c?x.setAttribute("target",c):o.removeAttr("target"),a(i).remove()}}function h(b){if(!r.aborted&&!F){if(E=e(q),E||(d("cannot access response document"),b=2),1===b&&r)return r.abort("timeout"),void y.reject(r,"timeout");if(2===b&&r)return r.abort("server abort"),
 void y.reject(r,"error","server abort");if(E&&E.location.href!==k.iframeSrc||v){q.detachEvent?q.detachEvent("onload",h):q.removeEventListener("load",h,!1);var c,f="success";try{if(v)throw"timeout";var g="xml"===k.dataType||E.XMLDocument||a.isXMLDoc(E);if(d("isXml="+g),!g&&window.opera&&(null===E.body||!E.body.innerHTML)&&--G)return d("requeing onLoad callback, DOM not available"),void setTimeout(h,250);var i=E.body?E.body:E.documentElement;r.responseText=i?i.innerHTML:null,r.responseXML=E.XMLDocument?E.XMLDocument:E,g&&(k.dataType="xml"),r.getResponseHeader=function(a){return{"content-type":k.dataType}[a.toLowerCase()]},i&&(r.status=Number(i.getAttribute("status"))||r.status,r.statusText=i.getAttribute("statusText")||r.statusText);var j=(k.dataType||"").toLowerCase(),l=/(json|script|text)/.test(j);
 if(l||k.textarea){var n=E.getElementsByTagName("textarea")[0];if(n)r.responseText=n.value,r.status=Number(n.getAttribute("status"))||r.status,r.statusText=n.getAttribute("statusText")||r.statusText;else if(l){var o=E.getElementsByTagName("pre")[0],s=E.getElementsByTagName("body")[0];o?r.responseText=o.textContent?o.textContent:o.innerText:s&&(r.responseText=s.textContent?s.textContent:s.innerText)}}else"xml"===j&&!r.responseXML&&r.responseText&&(r.responseXML=H(r.responseText));try{D=J(r,j,k)}catch(a){f="parsererror",r.error=c=a||f}}catch(a){d("error caught: ",a),f="error",r.error=c=a||f}r.aborted&&(d("upload aborted"),f=null),r.status&&(f=r.status>=200&&r.status<300||304===r.status?"success":"error"),"success"===f?(k.success&&k.success.call(k.context,D,"success",r),y.resolve(
 r.responseText,"success",r),m&&a.event.trigger("ajaxSuccess",[r,k])):f&&(void 0===c&&(c=r.statusText),k.error&&k.error.call(k.context,r,f,c),y.reject(r,"error",c),m&&a.event.trigger("ajaxError",[r,k,c])),m&&a.event.trigger("ajaxComplete",[r,k]),m&&!--a.active&&a.event.trigger("ajaxStop"),k.complete&&k.complete.call(k.context,r,f),F=!0,k.timeout&&clearTimeout(w),setTimeout(function(){k.iframeTarget?p.attr("src",k.iframeSrc):p.remove(),r.responseXML=null},100)}}}var i,j,k,m,n,p,q,r,t,u,v,w,x=o[0],y=a.Deferred();if(y.abort=function(a){r.abort(a)},c)for(j=0;j<s.length;j++)i=a(s[j]),f?i.prop("disabled",!1):i.removeAttr("disabled");k=a.extend(!0,{},a.ajaxSettings,b),k.context=k.context||k,n="jqFormIO"+(new Date).getTime();var z=x.ownerDocument,A=o.closest("body");if(k.iframeTarget?(p=a(k.iframeTarge
 t,z),u=p.attr2("name"),u?n=u:p.attr2("name",n)):(p=a('<iframe name="'+n+'" src="'+k.iframeSrc+'" />',z),p.css({position:"absolute",top:"-1000px",left:"-1000px"})),q=p[0],r={aborted:0,responseText:null,responseXML:null,status:0,statusText:"n/a",getAllResponseHeaders:function(){},getResponseHeader:function(){},setRequestHeader:function(){},abort:function(b){var c="timeout"===b?"timeout":"aborted";d("aborting upload... "+c),this.aborted=1;try{q.contentWindow.document.execCommand&&q.contentWindow.document.execCommand("Stop")}catch(a){}p.attr("src",k.iframeSrc),r.error=c,k.error&&k.error.call(k.context,r,c,b),m&&a.event.trigger("ajaxError",[r,k,c]),k.complete&&k.complete.call(k.context,r,c)}},m=k.global,m&&0==a.active++&&a.event.trigger("ajaxStart"),m&&a.event.trigger(&
 quot;ajaxSend",[r,k]),k.beforeSend&&k.beforeSend.call(k.context,r,k)===!1)return k.global&&a.active--,y.reject(),y;if(r.aborted)return y.reject(),y;(t=x.clk)&&(u=t.name)&&!t.disabled&&(k.extraData=k.extraData||{},k.extraData[u]=t.value,"image"===t.type&&(k.extraData[u+".x"]=x.clk_x,k.extraData[u+".y"]=x.clk_y));var B=a("meta[name=csrf-token]").attr("content"),C=a("meta[name=csrf-param]").attr("content");C&&B&&(k.extraData=k.extraData||{},k.extraData[C]=B),k.forceSync?g():setTimeout(g,10);var D,E,F,G=50,H=a.parseXML||function(a,b){return window.ActiveXObject?(b=new ActiveXObject("Microsoft.XMLDOM"),b.async="false",b.loadXML(a)):b=(new DOMParser).parseFromString(a,"text/xml"),b&&b.documentElement&&"parsererror"!==b.documentElement.nodeName?b:null},I=a.parseJSON||function(a){return window.eval(
 "("+a+")")},J=function(b,c,d){var e=b.getResponseHeader("content-type")||"",f=("xml"===c||!c)&&e.indexOf("xml")>=0,g=f?b.responseXML:b.responseText;return f&&"parsererror"===g.documentElement.nodeName&&a.error&&a.error("parsererror"),d&&d.dataFilter&&(g=d.dataFilter(g,c)),"string"==typeof g&&(("json"===c||!c)&&e.indexOf("json")>=0?g=I(g):("script"===c||!c)&&e.indexOf("javascript")>=0&&a.globalEval(g)),g};return y}if(!this.length)return d("ajaxSubmit: skipping submit process - no element selected"),this;var l,m,n,o=this;"function"==typeof b?b={success:b}:"string"==typeof b||b===!1&&arguments.length>0?(b={url:b,data:c,dataType:g},"function"==typeof h&&(b.success=h)):void 0===b&&(b={}),l=b.method||b.type|
 |this.attr2("method"),m=b.url||this.attr2("action"),n="string"==typeof m?a.trim(m):"",n=n||window.location.href||"",n&&(n=(n.match(/^([^#]+)/)||[])[1]),b=a.extend(!0,{url:n,success:a.ajaxSettings.success,type:l||a.ajaxSettings.type,iframeSrc:/^https/i.test(window.location.href||"")?"javascript:false":"about:blank"},b);var p={};if(this.trigger("form-pre-serialize",[this,b,p]),p.veto)return d("ajaxSubmit: submit vetoed via form-pre-serialize trigger"),this;if(b.beforeSerialize&&b.beforeSerialize(this,b)===!1)return d("ajaxSubmit: submit aborted via beforeSerialize callback"),this;var q=b.traditional;void 0===q&&(q=a.ajaxSettings.traditional);var r,s=[],t=this.formToArray(b.semantic,s,b.filtering);if(b.data){var u=a.isFunction(b.data)?b.data(t):b.data;b.extraData=u,r=a.param(u,q)}if(b.beforeSubmit&&b.beforeSubmit(t,this,b)===!1)return d("aja
 xSubmit: submit aborted via beforeSubmit callback"),this;if(this.trigger("form-submit-validate",[t,this,b,p]),p.veto)return d("ajaxSubmit: submit vetoed via form-submit-validate trigger"),this;var v=a.param(t,q);r&&(v=v?v+"&"+r:r),"GET"===b.type.toUpperCase()?(b.url+=(b.url.indexOf("?")>=0?"&":"?")+v,b.data=null):b.data=v;var w=[];if(b.resetForm&&w.push(function(){o.resetForm()}),b.clearForm&&w.push(function(){o.clearForm(b.includeHidden)}),!b.dataType&&b.target){var x=b.success||function(){};w.push(function(c,d,e){var f=arguments,g=b.replaceTarget?"replaceWith":"html";a(b.target)[g](c).each(function(){x.apply(this,f)})})}else b.success&&(a.isArray(b.success)?a.merge(w,b.success):w.push(b.success));if(b.success=function(a,c,d){for(var e=b.context||this,f=0,g=w.length;f<g;f++)w[f].apply(e,[a,c,d||o,o])},b.error){var y=b.error;b.error=fun
 ction(a,c,d){var e=b.context||this;y.apply(e,[a,c,d,o])}}if(b.complete){var z=b.complete;b.complete=function(a,c){var d=b.context||this;z.apply(d,[a,c,o])}}var A=a("input[type=file]:enabled",this).filter(function(){return""!==a(this).val()}),B=A.length>0,C="multipart/form-data",D=o.attr("enctype")===C||o.attr("encoding")===C,E=e.fileapi&&e.formdata;d("fileAPI :"+E);var F,G=(B||D)&&!E;b.iframe!==!1&&(b.iframe||G)?b.closeKeepAlive?a.get(b.closeKeepAlive,function(){F=k(t)}):F=k(t):F=(B||D)&&E?j(t):a.ajax(b),o.removeData("jqxhr").data("jqxhr",F);for(var H=0;H<s.length;H++)s[H]=null;return this.trigger("form-submit-notify",[this,b]),this},a.fn.ajaxForm=function(e,f,g,h){if(("string"==typeof e||e===!1&&arguments.length>0)&&(e={url:e,data:f,dataType:g},"function"==typeof h&&(e.success=h)),e=e||{},e.delegation=e.delega
 tion&&a.isFunction(a.fn.on),!e.delegation&&0===this.length){var i={s:this.selector,c:this.context};return!a.isReady&&i.s?(d("DOM not ready, queuing ajaxForm"),a(function(){a(i.s,i.c).ajaxForm(e)}),this):(d("terminating; zero elements found by selector"+(a.isReady?"":" (DOM not ready)")),this)}return e.delegation?(a(document).off("submit.form-plugin",this.selector,b).off("click.form-plugin",this.selector,c).on("submit.form-plugin",this.selector,e,b).on("click.form-plugin",this.selector,e,c),this):this.ajaxFormUnbind().on("submit.form-plugin",e,b).on("click.form-plugin",e,c)},a.fn.ajaxFormUnbind=function(){return this.off("submit.form-plugin click.form-plugin")},a.fn.formToArray=function(b,c,d){var f=[];if(0===this.length)return f;var g,h=this[0],i=this.attr("id"),j=b||void 0===h.elements?h.getElementsByTagName("*"):h.elements;if(j&a
 mp;&(j=a.makeArray(j)),i&&(b||/(Edge|Trident)\//.test(navigator.userAgent))&&(g=a(':input[form="'+i+'"]').get(),g.length&&(j=(j||[]).concat(g))),!j||!j.length)return f;a.isFunction(d)&&(j=a.map(j,d));var k,l,m,n,o,p,q;for(k=0,p=j.length;k<p;k++)if(o=j[k],(m=o.name)&&!o.disabled)if(b&&h.clk&&"image"===o.type)h.clk===o&&(f.push({name:m,value:a(o).val(),type:o.type}),f.push({name:m+".x",value:h.clk_x},{name:m+".y",value:h.clk_y}));else if((n=a.fieldValue(o,!0))&&n.constructor===Array)for(c&&c.push(o),l=0,q=n.length;l<q;l++)f.push({name:m,value:n[l]});else if(e.fileapi&&"file"===o.type){c&&c.push(o);var r=o.files;if(r.length)for(l=0;l<r.length;l++)f.push({name:m,value:r[l],type:o.type});else f.push({name:m,value:"",type:o.type})}else null!==n&&void 0!==n&&(c&&c.push(o),f.push({name:m,value:n,type:
 o.type,required:o.required}));if(!b&&h.clk){var s=a(h.clk),t=s[0];m=t.name,m&&!t.disabled&&"image"===t.type&&(f.push({name:m,value:s.val()}),f.push({name:m+".x",value:h.clk_x},{name:m+".y",value:h.clk_y}))}return f},a.fn.formSerialize=function(b){return a.param(this.formToArray(b))},a.fn.fieldSerialize=function(b){var c=[];return this.each(function(){var d=this.name;if(d){var e=a.fieldValue(this,b);if(e&&e.constructor===Array)for(var f=0,g=e.length;f<g;f++)c.push({name:d,value:e[f]});else null!==e&&void 0!==e&&c.push({name:this.name,value:e})}}),a.param(c)},a.fn.fieldValue=function(b){for(var c=[],d=0,e=this.length;d<e;d++){var f=this[d],g=a.fieldValue(f,b);null===g||void 0===g||g.constructor===Array&&!g.length||(g.constructor===Array?a.merge(c,g):c.push(g))}return c},a.fieldValue=function(b,c){var d=b.name,e=b.type,f=b.tagName.toLowerCase();if(void 0===c&&(c=!0),c&&(!
 d||b.disabled||"reset"===e||"button"===e||("checkbox"===e||"radio"===e)&&!b.checked||("submit"===e||"image"===e)&&b.form&&b.form.clk!==b||"select"===f&&b.selectedIndex===-1))return null;if("select"===f){var g=b.selectedIndex;if(g<0)return null;for(var h=[],i=b.options,j="select-one"===e,k=j?g+1:i.length,l=j?g:0;l<k;l++){var m=i[l];if(m.selected&&!m.disabled){var n=m.value;if(n||(n=m.attributes&&m.attributes.value&&!m.attributes.value.specified?m.text:m.value),j)return n;h.push(n)}}return h}return a(b).val().replace(/\r?\n/g,"\r\n")},a.fn.clearForm=function(b){return this.each(function(){a("input,select,textarea",this).clearFields(b)})},a.fn.clearFields=a.fn.clearInputs=function(b){var c=/^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i;return this.each(function(){var d=th
 is.type,e=this.tagName.toLowerCase();c.test(d)||"textarea"===e?this.value="":"checkbox"===d||"radio"===d?this.checked=!1:"select"===e?this.selectedIndex=-1:"file"===d?/MSIE/.test(navigator.userAgent)?a(this).replaceWith(a(this).clone(!0)):a(this).val(""):b&&(b===!0&&/hidden/.test(d)||"string"==typeof b&&a(this).is(b))&&(this.value="")})},a.fn.resetForm=function(){return this.each(function(){var b=a(this),c=this.tagName.toLowerCase();switch(c){case"input":this.checked=this.defaultChecked;case"textarea":return this.value=this.defaultValue,!0;case"option":case"optgroup":var d=b.parents("select");return d.length&&d[0].multiple?"option"===c?this.selected=this.defaultSelected:b.find("option").resetForm():d.resetForm(),!0;case"select":return b.find("option").each(function(a
 ){if(this.selected=this.defaultSelected,this.defaultSelected&&!b[0].multiple)return b[0].selectedIndex=a,!1}),!0;case"label":var e=a(b.attr("for")),f=b.find("input,select,textarea");return e[0]&&f.unshift(e[0]),f.resetForm(),!0;case"form":return("function"==typeof this.reset||"object"==typeof this.reset&&!this.reset.nodeType)&&this.reset(),!0;default:return b.find("form,input,label,select,textarea").resetForm(),!0}})},a.fn.enable=function(a){return void 0===a&&(a=!0),this.each(function(){this.disabled=!a})},a.fn.selected=function(b){return void 0===b&&(b=!0),this.each(function(){var c=this.type;if("checkbox"===c||"radio"===c)this.checked=b;else if("option"===this.tagName.toLowerCase()){var d=a(this).parent("select");b&&d[0]&&"select-one"===d[0].type&&d.find("option").selected(!1),this
 .selected=b}})},a.fn.ajaxSubmit.debug=!1});
+//# sourceMappingURL=jquery.form.min.js.map
</ins></span></pre></div>
<a id="trunksrcwpincludesscriptloaderphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/script-loader.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/script-loader.php   2017-08-04 23:00:50 UTC (rev 41232)
+++ trunk/src/wp-includes/script-loader.php     2017-08-05 12:59:12 UTC (rev 41233)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -248,7 +248,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">        ) );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        // deprecated, not used in core, most functionality is included in jQuery 1.3
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $scripts->add( 'jquery-form', "/wp-includes/js/jquery/jquery.form$suffix.js", array('jquery'), '3.37.0', 1 );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $scripts->add( 'jquery-form', "/wp-includes/js/jquery/jquery.form$suffix.js", array('jquery'), '4.2.1', 1 );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        // jQuery plugins
</span><span class="cx" style="display: block; padding: 0 10px">        $scripts->add( 'jquery-color', "/wp-includes/js/jquery/jquery.color.min.js", array('jquery'), '2.1.1', 1 );
</span></span></pre>
</div>
</div>

</body>
</html>