Security update for Core, with self-updated composer
[yaffs-website] / web / core / assets / vendor / jquery / jquery.js
index 5c3c456ac484e2f7244a7e8d16578d77eb218373..d2d8ca4790e52b0537f3cbb7dcd766099b789583 100644 (file)
@@ -1,20 +1,22 @@
 /*!
- * jQuery JavaScript Library v2.2.4
- * http://jquery.com/
+ * jQuery JavaScript Library v3.2.1
+ * https://jquery.com/
  *
  * Includes Sizzle.js
- * http://sizzlejs.com/
+ * https://sizzlejs.com/
  *
- * Copyright jQuery Foundation and other contributors
+ * Copyright JS Foundation and other contributors
  * Released under the MIT license
- * http://jquery.org/license
+ * https://jquery.org/license
  *
- * Date: 2016-05-20T17:23Z
+ * Date: 2017-03-20T18:59Z
  */
+( function( global, factory ) {
 
-(function( global, factory ) {
+       "use strict";
 
        if ( typeof module === "object" && typeof module.exports === "object" ) {
+
                // For CommonJS and CommonJS-like environments where a proper `window`
                // is present, execute the factory and get jQuery.
                // For environments that do not have a `window` with a `document`
        }
 
 // Pass this if window is not defined yet
-}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
+} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
+
+// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
+// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
+// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
+// enough that all such attempts are guarded in a try block.
+"use strict";
 
-// Support: Firefox 18+
-// Can't be in strict mode, several libs including ASP.NET trace
-// the stack via arguments.caller.callee and Firefox dies if
-// you try to trace through "use strict" call chains. (#13335)
-//"use strict";
 var arr = [];
 
 var document = window.document;
 
+var getProto = Object.getPrototypeOf;
+
 var slice = arr.slice;
 
 var concat = arr.concat;
@@ -60,12 +65,30 @@ var toString = class2type.toString;
 
 var hasOwn = class2type.hasOwnProperty;
 
+var fnToString = hasOwn.toString;
+
+var ObjectFunctionString = fnToString.call( Object );
+
 var support = {};
 
 
 
+       function DOMEval( code, doc ) {
+               doc = doc || document;
+
+               var script = doc.createElement( "script" );
+
+               script.text = code;
+               doc.head.appendChild( script ).parentNode.removeChild( script );
+       }
+/* global Symbol */
+// Defining this global in .eslintrc.json would create a danger of using the global
+// unguarded in another place, it seems safer to define global only for this module
+
+
+
 var
-       version = "2.2.4",
+       version = "3.2.1",
 
        // Define a local copy of jQuery
        jQuery = function( selector, context ) {
@@ -75,13 +98,13 @@ var
                return new jQuery.fn.init( selector, context );
        },
 
-       // Support: Android<4.1
+       // Support: Android <=4.0 only
        // Make sure we trim BOM and NBSP
        rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
 
        // Matches dashed string for camelizing
        rmsPrefix = /^-ms-/,
-       rdashAlpha = /-([\da-z])/gi,
+       rdashAlpha = /-([a-z])/g,
 
        // Used by jQuery.camelCase as callback to replace()
        fcamelCase = function( all, letter ) {
@@ -95,9 +118,6 @@ jQuery.fn = jQuery.prototype = {
 
        constructor: jQuery,
 
-       // Start with an empty selector
-       selector: "",
-
        // The default length of a jQuery object is 0
        length: 0,
 
@@ -108,13 +128,14 @@ jQuery.fn = jQuery.prototype = {
        // Get the Nth element in the matched element set OR
        // Get the whole matched element set as a clean array
        get: function( num ) {
-               return num != null ?
 
-                       // Return just the one element from the set
-                       ( num < 0 ? this[ num + this.length ] : this[ num ] ) :
+               // Return all the elements in a clean array
+               if ( num == null ) {
+                       return slice.call( this );
+               }
 
-                       // Return all the elements in a clean array
-                       slice.call( this );
+               // Return just the one element from the set
+               return num < 0 ? this[ num + this.length ] : this[ num ];
        },
 
        // Take an array of elements and push it onto the stack
@@ -126,7 +147,6 @@ jQuery.fn = jQuery.prototype = {
 
                // Add the old object onto the stack (as a reference)
                ret.prevObject = this;
-               ret.context = this.context;
 
                // Return the newly-formed element set
                return ret;
@@ -216,11 +236,11 @@ jQuery.extend = jQuery.fn.extend = function() {
 
                                // Recurse if we're merging plain objects or arrays
                                if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
-                                       ( copyIsArray = jQuery.isArray( copy ) ) ) ) {
+                                       ( copyIsArray = Array.isArray( copy ) ) ) ) {
 
                                        if ( copyIsArray ) {
                                                copyIsArray = false;
-                                               clone = src && jQuery.isArray( src ) ? src : [];
+                                               clone = src && Array.isArray( src ) ? src : [];
 
                                        } else {
                                                clone = src && jQuery.isPlainObject( src ) ? src : {};
@@ -259,49 +279,51 @@ jQuery.extend( {
                return jQuery.type( obj ) === "function";
        },
 
-       isArray: Array.isArray,
-
        isWindow: function( obj ) {
                return obj != null && obj === obj.window;
        },
 
        isNumeric: function( obj ) {
 
-               // parseFloat NaNs numeric-cast false positives (null|true|false|"")
-               // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
-               // subtraction forces infinities to NaN
-               // adding 1 corrects loss of precision from parseFloat (#15100)
-               var realStringObj = obj && obj.toString();
-               return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;
+               // As of jQuery 3.0, isNumeric is limited to
+               // strings and numbers (primitives or objects)
+               // that can be coerced to finite numbers (gh-2662)
+               var type = jQuery.type( obj );
+               return ( type === "number" || type === "string" ) &&
+
+                       // parseFloat NaNs numeric-cast false positives ("")
+                       // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
+                       // subtraction forces infinities to NaN
+                       !isNaN( obj - parseFloat( obj ) );
        },
 
        isPlainObject: function( obj ) {
-               var key;
+               var proto, Ctor;
 
-               // Not plain objects:
-               // - Any object or value whose internal [[Class]] property is not "[object Object]"
-               // - DOM nodes
-               // - window
-               if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
+               // Detect obvious negatives
+               // Use toString instead of jQuery.type to catch host objects
+               if ( !obj || toString.call( obj ) !== "[object Object]" ) {
                        return false;
                }
 
-               // Not own constructor property must be Object
-               if ( obj.constructor &&
-                               !hasOwn.call( obj, "constructor" ) &&
-                               !hasOwn.call( obj.constructor.prototype || {}, "isPrototypeOf" ) ) {
-                       return false;
-               }
+               proto = getProto( obj );
 
-               // Own properties are enumerated firstly, so to speed up,
-               // if last one is own, then all properties are own
-               for ( key in obj ) {}
+               // Objects with no prototype (e.g., `Object.create( null )`) are plain
+               if ( !proto ) {
+                       return true;
+               }
 
-               return key === undefined || hasOwn.call( obj, key );
+               // Objects with prototype are plain iff they were constructed by a global Object function
+               Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
+               return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
        },
 
        isEmptyObject: function( obj ) {
+
+               /* eslint-disable no-unused-vars */
+               // See https://github.com/eslint/eslint/issues/6125
                var name;
+
                for ( name in obj ) {
                        return false;
                }
@@ -313,7 +335,7 @@ jQuery.extend( {
                        return obj + "";
                }
 
-               // Support: Android<4.0, iOS<6 (functionish RegExp)
+               // Support: Android <=2.3 only (functionish RegExp)
                return typeof obj === "object" || typeof obj === "function" ?
                        class2type[ toString.call( obj ) ] || "object" :
                        typeof obj;
@@ -321,41 +343,16 @@ jQuery.extend( {
 
        // Evaluates a script in a global context
        globalEval: function( code ) {
-               var script,
-                       indirect = eval;
-
-               code = jQuery.trim( code );
-
-               if ( code ) {
-
-                       // If the code includes a valid, prologue position
-                       // strict mode pragma, execute code by injecting a
-                       // script tag into the document.
-                       if ( code.indexOf( "use strict" ) === 1 ) {
-                               script = document.createElement( "script" );
-                               script.text = code;
-                               document.head.appendChild( script ).parentNode.removeChild( script );
-                       } else {
-
-                               // Otherwise, avoid the DOM node creation, insertion
-                               // and removal by using an indirect global eval
-
-                               indirect( code );
-                       }
-               }
+               DOMEval( code );
        },
 
        // Convert dashed to camelCase; used by the css and data modules
-       // Support: IE9-11+
+       // Support: IE <=9 - 11, Edge 12 - 13
        // Microsoft forgot to hump their vendor prefix (#9572)
        camelCase: function( string ) {
                return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
        },
 
-       nodeName: function( elem, name ) {
-               return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
-       },
-
        each: function( obj, callback ) {
                var length, i = 0;
 
@@ -377,7 +374,7 @@ jQuery.extend( {
                return obj;
        },
 
-       // Support: Android<4.1
+       // Support: Android <=4.0 only
        trim: function( text ) {
                return text == null ?
                        "" :
@@ -406,6 +403,8 @@ jQuery.extend( {
                return arr == null ? -1 : indexOf.call( arr, elem, i );
        },
 
+       // Support: Android <=4.0 only, PhantomJS 1 only
+       // push.apply(_, arraylike) throws on ancient WebKit
        merge: function( first, second ) {
                var len = +second.length,
                        j = 0,
@@ -510,15 +509,9 @@ jQuery.extend( {
        support: support
 } );
 
-// JSHint would error on this code due to the Symbol not being defined in ES5.
-// Defining this global in .jshintrc would create a danger of using the global
-// unguarded in another place, it seems safer to just disable JSHint for these
-// three lines.
-/* jshint ignore: start */
 if ( typeof Symbol === "function" ) {
        jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
 }
-/* jshint ignore: end */
 
 // Populate the class2type map
 jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
@@ -528,7 +521,7 @@ function( i, name ) {
 
 function isArrayLike( obj ) {
 
-       // Support: iOS 8.2 (not reproducible in simulator)
+       // Support: real iOS 8.2 only (not reproducible in simulator)
        // `in` check used to prevent JIT error (gh-2145)
        // hasOwn isn't used here due to false negatives
        // regarding Nodelist length in IE
@@ -544,14 +537,14 @@ function isArrayLike( obj ) {
 }
 var Sizzle =
 /*!
- * Sizzle CSS Selector Engine v2.2.1
- * http://sizzlejs.com/
+ * Sizzle CSS Selector Engine v2.3.3
+ * https://sizzlejs.com/
  *
  * Copyright jQuery Foundation and other contributors
  * Released under the MIT license
  * http://jquery.org/license
  *
- * Date: 2015-10-17
+ * Date: 2016-08-08
  */
 (function( window ) {
 
@@ -592,9 +585,6 @@ var i,
                return 0;
        },
 
-       // General-purpose constants
-       MAX_NEGATIVE = 1 << 31,
-
        // Instance methods
        hasOwn = ({}).hasOwnProperty,
        arr = [],
@@ -603,7 +593,7 @@ var i,
        push = arr.push,
        slice = arr.slice,
        // Use a stripped-down indexOf as it's faster than native
-       // http://jsperf.com/thor-indexof-vs-for/5
+       // https://jsperf.com/thor-indexof-vs-for/5
        indexOf = function( list, elem ) {
                var i = 0,
                        len = list.length;
@@ -623,7 +613,7 @@ var i,
        whitespace = "[\\x20\\t\\r\\n\\f]",
 
        // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
-       identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
+       identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+",
 
        // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
        attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
@@ -680,9 +670,9 @@ var i,
        rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
 
        rsibling = /[+~]/,
-       rescape = /'|\\/g,
 
-       // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
+       // CSS escapes
+       // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
        runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
        funescape = function( _, escaped, escapedWhitespace ) {
                var high = "0x" + escaped - 0x10000;
@@ -698,13 +688,39 @@ var i,
                                String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
        },
 
+       // CSS string/identifier serialization
+       // https://drafts.csswg.org/cssom/#common-serializing-idioms
+       rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
+       fcssescape = function( ch, asCodePoint ) {
+               if ( asCodePoint ) {
+
+                       // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
+                       if ( ch === "\0" ) {
+                               return "\uFFFD";
+                       }
+
+                       // Control characters and (dependent upon position) numbers get escaped as code points
+                       return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
+               }
+
+               // Other potentially-special ASCII characters get backslash-escaped
+               return "\\" + ch;
+       },
+
        // Used for iframes
        // See setDocument()
        // Removing the function wrapper causes a "Permission Denied"
        // error in IE
        unloadHandler = function() {
                setDocument();
-       };
+       },
+
+       disabledAncestor = addCombinator(
+               function( elem ) {
+                       return elem.disabled === true && ("form" in elem || "label" in elem);
+               },
+               { dir: "parentNode", next: "legend" }
+       );
 
 // Optimize for push.apply( _, NodeList )
 try {
@@ -736,7 +752,7 @@ try {
 }
 
 function Sizzle( selector, context, results, seed ) {
-       var m, i, elem, nid, nidselect, match, groups, newSelector,
+       var m, i, elem, nid, match, groups, newSelector,
                newContext = context && context.ownerDocument,
 
                // nodeType defaults to 9, since context defaults to document
@@ -829,7 +845,7 @@ function Sizzle( selector, context, results, seed ) {
 
                                        // Capture the context ID, setting it first if necessary
                                        if ( (nid = context.getAttribute( "id" )) ) {
-                                               nid = nid.replace( rescape, "\\$&" );
+                                               nid = nid.replace( rcssescape, fcssescape );
                                        } else {
                                                context.setAttribute( "id", (nid = expando) );
                                        }
@@ -837,9 +853,8 @@ function Sizzle( selector, context, results, seed ) {
                                        // Prefix every selector in the list
                                        groups = tokenize( selector );
                                        i = groups.length;
-                                       nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']";
                                        while ( i-- ) {
-                                               groups[i] = nidselect + " " + toSelector( groups[i] );
+                                               groups[i] = "#" + nid + " " + toSelector( groups[i] );
                                        }
                                        newSelector = groups.join( "," );
 
@@ -900,22 +915,22 @@ function markFunction( fn ) {
 
 /**
  * Support testing using an element
- * @param {Function} fn Passed the created div and expects a boolean result
+ * @param {Function} fn Passed the created element and returns a boolean result
  */
 function assert( fn ) {
-       var div = document.createElement("div");
+       var el = document.createElement("fieldset");
 
        try {
-               return !!fn( div );
+               return !!fn( el );
        } catch (e) {
                return false;
        } finally {
                // Remove from its parent by default
-               if ( div.parentNode ) {
-                       div.parentNode.removeChild( div );
+               if ( el.parentNode ) {
+                       el.parentNode.removeChild( el );
                }
                // release memory in IE
-               div = null;
+               el = null;
        }
 }
 
@@ -942,8 +957,7 @@ function addHandle( attrs, handler ) {
 function siblingCheck( a, b ) {
        var cur = b && a,
                diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
-                       ( ~b.sourceIndex || MAX_NEGATIVE ) -
-                       ( ~a.sourceIndex || MAX_NEGATIVE );
+                       a.sourceIndex - b.sourceIndex;
 
        // Use IE sourceIndex if available on both nodes
        if ( diff ) {
@@ -984,6 +998,62 @@ function createButtonPseudo( type ) {
        };
 }
 
+/**
+ * Returns a function to use in pseudos for :enabled/:disabled
+ * @param {Boolean} disabled true for :disabled; false for :enabled
+ */
+function createDisabledPseudo( disabled ) {
+
+       // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
+       return function( elem ) {
+
+               // Only certain elements can match :enabled or :disabled
+               // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
+               // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
+               if ( "form" in elem ) {
+
+                       // Check for inherited disabledness on relevant non-disabled elements:
+                       // * listed form-associated elements in a disabled fieldset
+                       //   https://html.spec.whatwg.org/multipage/forms.html#category-listed
+                       //   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
+                       // * option elements in a disabled optgroup
+                       //   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
+                       // All such elements have a "form" property.
+                       if ( elem.parentNode && elem.disabled === false ) {
+
+                               // Option elements defer to a parent optgroup if present
+                               if ( "label" in elem ) {
+                                       if ( "label" in elem.parentNode ) {
+                                               return elem.parentNode.disabled === disabled;
+                                       } else {
+                                               return elem.disabled === disabled;
+                                       }
+                               }
+
+                               // Support: IE 6 - 11
+                               // Use the isDisabled shortcut property to check for disabled fieldset ancestors
+                               return elem.isDisabled === disabled ||
+
+                                       // Where there is no isDisabled, check manually
+                                       /* jshint -W018 */
+                                       elem.isDisabled !== !disabled &&
+                                               disabledAncestor( elem ) === disabled;
+                       }
+
+                       return elem.disabled === disabled;
+
+               // Try to winnow out elements that can't be disabled before trusting the disabled property.
+               // Some victims get caught in our net (label, legend, menu, track), but it shouldn't
+               // even exist on them, let alone have a boolean value.
+               } else if ( "label" in elem ) {
+                       return elem.disabled === disabled;
+               }
+
+               // Remaining elements are neither :enabled nor :disabled
+               return false;
+       };
+}
+
 /**
  * Returns a function to use in pseudos for positionals
  * @param {Function} fn
@@ -1036,7 +1106,7 @@ isXML = Sizzle.isXML = function( elem ) {
  * @returns {Object} Returns the current document
  */
 setDocument = Sizzle.setDocument = function( node ) {
-       var hasCompare, parent,
+       var hasCompare, subWindow,
                doc = node ? node.ownerDocument || node : preferredDoc;
 
        // Return early if doc is invalid or already selected
@@ -1051,14 +1121,16 @@ setDocument = Sizzle.setDocument = function( node ) {
 
        // Support: IE 9-11, Edge
        // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
-       if ( (parent = document.defaultView) && parent.top !== parent ) {
-               // Support: IE 11
-               if ( parent.addEventListener ) {
-                       parent.addEventListener( "unload", unloadHandler, false );
+       if ( preferredDoc !== document &&
+               (subWindow = document.defaultView) && subWindow.top !== subWindow ) {
+
+               // Support: IE 11, Edge
+               if ( subWindow.addEventListener ) {
+                       subWindow.addEventListener( "unload", unloadHandler, false );
 
                // Support: IE 9 - 10 only
-               } else if ( parent.attachEvent ) {
-                       parent.attachEvent( "onunload", unloadHandler );
+               } else if ( subWindow.attachEvent ) {
+                       subWindow.attachEvent( "onunload", unloadHandler );
                }
        }
 
@@ -1068,18 +1140,18 @@ setDocument = Sizzle.setDocument = function( node ) {
        // Support: IE<8
        // Verify that getAttribute really returns attributes and not properties
        // (excepting IE8 booleans)
-       support.attributes = assert(function( div ) {
-               div.className = "i";
-               return !div.getAttribute("className");
+       support.attributes = assert(function( el ) {
+               el.className = "i";
+               return !el.getAttribute("className");
        });
 
        /* getElement(s)By*
        ---------------------------------------------------------------------- */
 
        // Check if getElementsByTagName("*") returns only elements
-       support.getElementsByTagName = assert(function( div ) {
-               div.appendChild( document.createComment("") );
-               return !div.getElementsByTagName("*").length;
+       support.getElementsByTagName = assert(function( el ) {
+               el.appendChild( document.createComment("") );
+               return !el.getElementsByTagName("*").length;
        });
 
        // Support: IE<9
@@ -1087,32 +1159,28 @@ setDocument = Sizzle.setDocument = function( node ) {
 
        // Support: IE<10
        // Check if getElementById returns elements by name
-       // The broken getElementById methods don't pick up programatically-set names,
+       // The broken getElementById methods don't pick up programmatically-set names,
        // so use a roundabout getElementsByName test
-       support.getById = assert(function( div ) {
-               docElem.appendChild( div ).id = expando;
+       support.getById = assert(function( el ) {
+               docElem.appendChild( el ).id = expando;
                return !document.getElementsByName || !document.getElementsByName( expando ).length;
        });
 
-       // ID find and filter
+       // ID filter and find
        if ( support.getById ) {
-               Expr.find["ID"] = function( id, context ) {
-                       if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
-                               var m = context.getElementById( id );
-                               return m ? [ m ] : [];
-                       }
-               };
                Expr.filter["ID"] = function( id ) {
                        var attrId = id.replace( runescape, funescape );
                        return function( elem ) {
                                return elem.getAttribute("id") === attrId;
                        };
                };
+               Expr.find["ID"] = function( id, context ) {
+                       if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
+                               var elem = context.getElementById( id );
+                               return elem ? [ elem ] : [];
+                       }
+               };
        } else {
-               // Support: IE6/7
-               // getElementById is not reliable as a find shortcut
-               delete Expr.find["ID"];
-
                Expr.filter["ID"] =  function( id ) {
                        var attrId = id.replace( runescape, funescape );
                        return function( elem ) {
@@ -1121,6 +1189,36 @@ setDocument = Sizzle.setDocument = function( node ) {
                                return node && node.value === attrId;
                        };
                };
+
+               // Support: IE 6 - 7 only
+               // getElementById is not reliable as a find shortcut
+               Expr.find["ID"] = function( id, context ) {
+                       if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
+                               var node, i, elems,
+                                       elem = context.getElementById( id );
+
+                               if ( elem ) {
+
+                                       // Verify the id attribute
+                                       node = elem.getAttributeNode("id");
+                                       if ( node && node.value === id ) {
+                                               return [ elem ];
+                                       }
+
+                                       // Fall back on getElementsByName
+                                       elems = context.getElementsByName( id );
+                                       i = 0;
+                                       while ( (elem = elems[i++]) ) {
+                                               node = elem.getAttributeNode("id");
+                                               if ( node && node.value === id ) {
+                                                       return [ elem ];
+                                               }
+                                       }
+                               }
+
+                               return [];
+                       }
+               };
        }
 
        // Tag
@@ -1174,77 +1272,87 @@ setDocument = Sizzle.setDocument = function( node ) {
        // We allow this because of a bug in IE8/9 that throws an error
        // whenever `document.activeElement` is accessed on an iframe
        // So, we allow :focus to pass through QSA all the time to avoid the IE error
-       // See http://bugs.jquery.com/ticket/13378
+       // See https://bugs.jquery.com/ticket/13378
        rbuggyQSA = [];
 
        if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
                // Build QSA regex
                // Regex strategy adopted from Diego Perini
-               assert(function( div ) {
+               assert(function( el ) {
                        // Select is set to empty string on purpose
                        // This is to test IE's treatment of not explicitly
                        // setting a boolean content attribute,
                        // since its presence should be enough
-                       // http://bugs.jquery.com/ticket/12359
-                       docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
+                       // https://bugs.jquery.com/ticket/12359
+                       docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
                                "<select id='" + expando + "-\r\\' msallowcapture=''>" +
                                "<option selected=''></option></select>";
 
                        // Support: IE8, Opera 11-12.16
                        // Nothing should be selected when empty strings follow ^= or $= or *=
                        // The test attribute must be unknown in Opera but "safe" for WinRT
-                       // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
-                       if ( div.querySelectorAll("[msallowcapture^='']").length ) {
+                       // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
+                       if ( el.querySelectorAll("[msallowcapture^='']").length ) {
                                rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
                        }
 
                        // Support: IE8
                        // Boolean attributes and "value" are not treated correctly
-                       if ( !div.querySelectorAll("[selected]").length ) {
+                       if ( !el.querySelectorAll("[selected]").length ) {
                                rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
                        }
 
                        // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
-                       if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
+                       if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
                                rbuggyQSA.push("~=");
                        }
 
                        // Webkit/Opera - :checked should return selected option elements
                        // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
                        // IE8 throws error here and will not see later tests
-                       if ( !div.querySelectorAll(":checked").length ) {
+                       if ( !el.querySelectorAll(":checked").length ) {
                                rbuggyQSA.push(":checked");
                        }
 
                        // Support: Safari 8+, iOS 8+
                        // https://bugs.webkit.org/show_bug.cgi?id=136851
-                       // In-page `selector#id sibing-combinator selector` fails
-                       if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
+                       // In-page `selector#id sibling-combinator selector` fails
+                       if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
                                rbuggyQSA.push(".#.+[+~]");
                        }
                });
 
-               assert(function( div ) {
+               assert(function( el ) {
+                       el.innerHTML = "<a href='' disabled='disabled'></a>" +
+                               "<select disabled='disabled'><option/></select>";
+
                        // Support: Windows 8 Native Apps
                        // The type and name attributes are restricted during .innerHTML assignment
                        var input = document.createElement("input");
                        input.setAttribute( "type", "hidden" );
-                       div.appendChild( input ).setAttribute( "name", "D" );
+                       el.appendChild( input ).setAttribute( "name", "D" );
 
                        // Support: IE8
                        // Enforce case-sensitivity of name attribute
-                       if ( div.querySelectorAll("[name=d]").length ) {
+                       if ( el.querySelectorAll("[name=d]").length ) {
                                rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
                        }
 
                        // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
                        // IE8 throws error here and will not see later tests
-                       if ( !div.querySelectorAll(":enabled").length ) {
+                       if ( el.querySelectorAll(":enabled").length !== 2 ) {
+                               rbuggyQSA.push( ":enabled", ":disabled" );
+                       }
+
+                       // Support: IE9-11+
+                       // IE's :disabled selector does not pick up the children of disabled fieldsets
+                       docElem.appendChild( el ).disabled = true;
+                       if ( el.querySelectorAll(":disabled").length !== 2 ) {
                                rbuggyQSA.push( ":enabled", ":disabled" );
                        }
 
                        // Opera 10-11 does not throw on post-comma invalid pseudos
-                       div.querySelectorAll("*,:x");
+                       el.querySelectorAll("*,:x");
                        rbuggyQSA.push(",.*:");
                });
        }
@@ -1255,14 +1363,14 @@ setDocument = Sizzle.setDocument = function( node ) {
                docElem.oMatchesSelector ||
                docElem.msMatchesSelector) )) ) {
 
-               assert(function( div ) {
+               assert(function( el ) {
                        // Check to see if it's possible to do matchesSelector
                        // on a disconnected node (IE 9)
-                       support.disconnectedMatch = matches.call( div, "div" );
+                       support.disconnectedMatch = matches.call( el, "*" );
 
                        // This should fail with an exception
                        // Gecko does not error, returns false instead
-                       matches.call( div, "[s!='']:x" );
+                       matches.call( el, "[s!='']:x" );
                        rbuggyMatches.push( "!=", pseudos );
                });
        }
@@ -1464,6 +1572,10 @@ Sizzle.attr = function( elem, name ) {
                                null;
 };
 
+Sizzle.escape = function( sel ) {
+       return (sel + "").replace( rcssescape, fcssescape );
+};
+
 Sizzle.error = function( msg ) {
        throw new Error( "Syntax error, unrecognized expression: " + msg );
 };
@@ -1931,13 +2043,8 @@ Expr = Sizzle.selectors = {
                },
 
                // Boolean properties
-               "enabled": function( elem ) {
-                       return elem.disabled === false;
-               },
-
-               "disabled": function( elem ) {
-                       return elem.disabled === true;
-               },
+               "enabled": createDisabledPseudo( false ),
+               "disabled": createDisabledPseudo( true ),
 
                "checked": function( elem ) {
                        // In CSS3, :checked should return both checked and selected elements
@@ -2139,7 +2246,9 @@ function toSelector( tokens ) {
 
 function addCombinator( matcher, combinator, base ) {
        var dir = combinator.dir,
-               checkNonElements = base && dir === "parentNode",
+               skip = combinator.next,
+               key = skip || dir,
+               checkNonElements = base && key === "parentNode",
                doneName = done++;
 
        return combinator.first ?
@@ -2150,6 +2259,7 @@ function addCombinator( matcher, combinator, base ) {
                                        return matcher( elem, context, xml );
                                }
                        }
+                       return false;
                } :
 
                // Check against all ancestor/preceding elements
@@ -2175,14 +2285,16 @@ function addCombinator( matcher, combinator, base ) {
                                                // Defend against cloned attroperties (jQuery gh-1709)
                                                uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
 
-                                               if ( (oldCache = uniqueCache[ dir ]) &&
+                                               if ( skip && skip === elem.nodeName.toLowerCase() ) {
+                                                       elem = elem[ dir ] || elem;
+                                               } else if ( (oldCache = uniqueCache[ key ]) &&
                                                        oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
 
                                                        // Assign to newCache so results back-propagate to previous elements
                                                        return (newCache[ 2 ] = oldCache[ 2 ]);
                                                } else {
                                                        // Reuse newcache so results back-propagate to previous elements
-                                                       uniqueCache[ dir ] = newCache;
+                                                       uniqueCache[ key ] = newCache;
 
                                                        // A match means we're done; a fail means we have to keep checking
                                                        if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
@@ -2192,6 +2304,7 @@ function addCombinator( matcher, combinator, base ) {
                                        }
                                }
                        }
+                       return false;
                };
 }
 
@@ -2554,8 +2667,7 @@ select = Sizzle.select = function( selector, context, results, seed ) {
                // Reduce context if the leading compound selector is an ID
                tokens = match[0] = match[0].slice( 0 );
                if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
-                               support.getById && context.nodeType === 9 && documentIsHTML &&
-                               Expr.relative[ tokens[1].type ] ) {
+                               context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {
 
                        context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
                        if ( !context ) {
@@ -2625,17 +2737,17 @@ setDocument();
 
 // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
 // Detached nodes confoundingly follow *each other*
-support.sortDetached = assert(function( div1 ) {
+support.sortDetached = assert(function( el ) {
        // Should return 1, but returns 4 (following)
-       return div1.compareDocumentPosition( document.createElement("div") ) & 1;
+       return el.compareDocumentPosition( document.createElement("fieldset") ) & 1;
 });
 
 // Support: IE<8
 // Prevent attribute/property "interpolation"
-// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
-if ( !assert(function( div ) {
-       div.innerHTML = "<a href='#'></a>";
-       return div.firstChild.getAttribute("href") === "#" ;
+// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+if ( !assert(function( el ) {
+       el.innerHTML = "<a href='#'></a>";
+       return el.firstChild.getAttribute("href") === "#" ;
 }) ) {
        addHandle( "type|href|height|width", function( elem, name, isXML ) {
                if ( !isXML ) {
@@ -2646,10 +2758,10 @@ if ( !assert(function( div ) {
 
 // Support: IE<9
 // Use defaultValue in place of getAttribute("value")
-if ( !support.attributes || !assert(function( div ) {
-       div.innerHTML = "<input/>";
-       div.firstChild.setAttribute( "value", "" );
-       return div.firstChild.getAttribute( "value" ) === "";
+if ( !support.attributes || !assert(function( el ) {
+       el.innerHTML = "<input/>";
+       el.firstChild.setAttribute( "value", "" );
+       return el.firstChild.getAttribute( "value" ) === "";
 }) ) {
        addHandle( "value", function( elem, name, isXML ) {
                if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
@@ -2660,8 +2772,8 @@ if ( !support.attributes || !assert(function( div ) {
 
 // Support: IE<9
 // Use getAttributeNode to fetch booleans when getAttribute lies
-if ( !assert(function( div ) {
-       return div.getAttribute("disabled") == null;
+if ( !assert(function( el ) {
+       return el.getAttribute("disabled") == null;
 }) ) {
        addHandle( booleans, function( elem, name, isXML ) {
                var val;
@@ -2682,11 +2794,15 @@ return Sizzle;
 
 jQuery.find = Sizzle;
 jQuery.expr = Sizzle.selectors;
+
+// Deprecated
 jQuery.expr[ ":" ] = jQuery.expr.pseudos;
 jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
 jQuery.text = Sizzle.getText;
 jQuery.isXMLDoc = Sizzle.isXML;
 jQuery.contains = Sizzle.contains;
+jQuery.escapeSelector = Sizzle.escape;
+
 
 
 
@@ -2721,7 +2837,14 @@ var siblings = function( n, elem ) {
 
 var rneedsContext = jQuery.expr.match.needsContext;
 
-var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );
+
+
+function nodeName( elem, name ) {
+
+  return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
+
+};
+var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
 
 
 
@@ -2731,29 +2854,33 @@ var risSimple = /^.[^:#\[\.,]*$/;
 function winnow( elements, qualifier, not ) {
        if ( jQuery.isFunction( qualifier ) ) {
                return jQuery.grep( elements, function( elem, i ) {
-                       /* jshint -W018 */
                        return !!qualifier.call( elem, i, elem ) !== not;
                } );
-
        }
 
+       // Single element
        if ( qualifier.nodeType ) {
                return jQuery.grep( elements, function( elem ) {
                        return ( elem === qualifier ) !== not;
                } );
-
        }
 
-       if ( typeof qualifier === "string" ) {
-               if ( risSimple.test( qualifier ) ) {
-                       return jQuery.filter( qualifier, elements, not );
-               }
+       // Arraylike of elements (jQuery, arguments, Array)
+       if ( typeof qualifier !== "string" ) {
+               return jQuery.grep( elements, function( elem ) {
+                       return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
+               } );
+       }
 
-               qualifier = jQuery.filter( qualifier, elements );
+       // Simple selector that can be filtered directly, removing non-Elements
+       if ( risSimple.test( qualifier ) ) {
+               return jQuery.filter( qualifier, elements, not );
        }
 
+       // Complex selector, compare the two sets, removing non-Elements
+       qualifier = jQuery.filter( qualifier, elements );
        return jQuery.grep( elements, function( elem ) {
-               return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
+               return ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1;
        } );
 }
 
@@ -2764,18 +2891,19 @@ jQuery.filter = function( expr, elems, not ) {
                expr = ":not(" + expr + ")";
        }
 
-       return elems.length === 1 && elem.nodeType === 1 ?
-               jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
-               jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
-                       return elem.nodeType === 1;
-               } ) );
+       if ( elems.length === 1 && elem.nodeType === 1 ) {
+               return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
+       }
+
+       return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
+               return elem.nodeType === 1;
+       } ) );
 };
 
 jQuery.fn.extend( {
        find: function( selector ) {
-               var i,
+               var i, ret,
                        len = this.length,
-                       ret = [],
                        self = this;
 
                if ( typeof selector !== "string" ) {
@@ -2788,14 +2916,13 @@ jQuery.fn.extend( {
                        } ) );
                }
 
+               ret = this.pushStack( [] );
+
                for ( i = 0; i < len; i++ ) {
                        jQuery.find( selector, self[ i ], ret );
                }
 
-               // Needed because $( selector, context ) becomes $( context ).find( selector )
-               ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
-               ret.selector = this.selector ? this.selector + " " + selector : selector;
-               return ret;
+               return len > 1 ? jQuery.uniqueSort( ret ) : ret;
        },
        filter: function( selector ) {
                return this.pushStack( winnow( this, selector || [], false ) );
@@ -2827,7 +2954,8 @@ var rootjQuery,
        // A simple way to check for HTML strings
        // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
        // Strict HTML recognition (#11290: must start with <)
-       rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
+       // Shortcut simple #id case for speed
+       rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
 
        init = jQuery.fn.init = function( selector, context, root ) {
                var match, elem;
@@ -2890,17 +3018,12 @@ var rootjQuery,
                                } else {
                                        elem = document.getElementById( match[ 2 ] );
 
-                                       // Support: Blackberry 4.6
-                                       // gEBID returns nodes no longer in the document (#6963)
-                                       if ( elem && elem.parentNode ) {
+                                       if ( elem ) {
 
                                                // Inject the element directly into the jQuery object
-                                               this.length = 1;
                                                this[ 0 ] = elem;
+                                               this.length = 1;
                                        }
-
-                                       this.context = document;
-                                       this.selector = selector;
                                        return this;
                                }
 
@@ -2916,7 +3039,7 @@ var rootjQuery,
 
                // HANDLE: $(DOMElement)
                } else if ( selector.nodeType ) {
-                       this.context = this[ 0 ] = selector;
+                       this[ 0 ] = selector;
                        this.length = 1;
                        return this;
 
@@ -2930,11 +3053,6 @@ var rootjQuery,
                                selector( jQuery );
                }
 
-               if ( selector.selector !== undefined ) {
-                       this.selector = selector.selector;
-                       this.context = selector.context;
-               }
-
                return jQuery.makeArray( selector, this );
        };
 
@@ -2975,23 +3093,24 @@ jQuery.fn.extend( {
                        i = 0,
                        l = this.length,
                        matched = [],
-                       pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
-                               jQuery( selectors, context || this.context ) :
-                               0;
+                       targets = typeof selectors !== "string" && jQuery( selectors );
 
-               for ( ; i < l; i++ ) {
-                       for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
+               // Positional selectors never match, since there's no _selection_ context
+               if ( !rneedsContext.test( selectors ) ) {
+                       for ( ; i < l; i++ ) {
+                               for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
 
-                               // Always skip document fragments
-                               if ( cur.nodeType < 11 && ( pos ?
-                                       pos.index( cur ) > -1 :
+                                       // Always skip document fragments
+                                       if ( cur.nodeType < 11 && ( targets ?
+                                               targets.index( cur ) > -1 :
 
-                                       // Don't pass non-elements to Sizzle
-                                       cur.nodeType === 1 &&
-                                               jQuery.find.matchesSelector( cur, selectors ) ) ) {
+                                               // Don't pass non-elements to Sizzle
+                                               cur.nodeType === 1 &&
+                                                       jQuery.find.matchesSelector( cur, selectors ) ) ) {
 
-                                       matched.push( cur );
-                                       break;
+                                               matched.push( cur );
+                                               break;
+                                       }
                                }
                        }
                }
@@ -3076,7 +3195,18 @@ jQuery.each( {
                return siblings( elem.firstChild );
        },
        contents: function( elem ) {
-               return elem.contentDocument || jQuery.merge( [], elem.childNodes );
+        if ( nodeName( elem, "iframe" ) ) {
+            return elem.contentDocument;
+        }
+
+        // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
+        // Treat the template element as a regular one in browsers that
+        // don't support it.
+        if ( nodeName( elem, "template" ) ) {
+            elem = elem.content || elem;
+        }
+
+        return jQuery.merge( [], elem.childNodes );
        }
 }, function( name, fn ) {
        jQuery.fn[ name ] = function( until, selector ) {
@@ -3106,14 +3236,14 @@ jQuery.each( {
                return this.pushStack( matched );
        };
 } );
-var rnotwhite = ( /\S+/g );
+var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
 
 
 
 // Convert String-formatted options into Object-formatted ones
 function createOptions( options ) {
        var object = {};
-       jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
+       jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
                object[ flag ] = true;
        } );
        return object;
@@ -3174,7 +3304,7 @@ jQuery.Callbacks = function( options ) {
                fire = function() {
 
                        // Enforce single-firing
-                       locked = options.once;
+                       locked = locked || options.once;
 
                        // Execute callbacks for all pending executions,
                        // respecting firingIndex overrides and runtime changes
@@ -3298,7 +3428,7 @@ jQuery.Callbacks = function( options ) {
                        // Abort any pending executions
                        lock: function() {
                                locked = queue = [];
-                               if ( !memory ) {
+                               if ( !memory && !firing ) {
                                        list = memory = "";
                                }
                                return this;
@@ -3336,15 +3466,59 @@ jQuery.Callbacks = function( options ) {
 };
 
 
+function Identity( v ) {
+       return v;
+}
+function Thrower( ex ) {
+       throw ex;
+}
+
+function adoptValue( value, resolve, reject, noValue ) {
+       var method;
+
+       try {
+
+               // Check for promise aspect first to privilege synchronous behavior
+               if ( value && jQuery.isFunction( ( method = value.promise ) ) ) {
+                       method.call( value ).done( resolve ).fail( reject );
+
+               // Other thenables
+               } else if ( value && jQuery.isFunction( ( method = value.then ) ) ) {
+                       method.call( value, resolve, reject );
+
+               // Other non-thenables
+               } else {
+
+                       // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
+                       // * false: [ value ].slice( 0 ) => resolve( value )
+                       // * true: [ value ].slice( 1 ) => resolve()
+                       resolve.apply( undefined, [ value ].slice( noValue ) );
+               }
+
+       // For Promises/A+, convert exceptions into rejections
+       // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
+       // Deferred#then to conditionally suppress rejection.
+       } catch ( value ) {
+
+               // Support: Android 4.0 only
+               // Strict mode functions invoked without .call/.apply get global-object context
+               reject.apply( undefined, [ value ] );
+       }
+}
+
 jQuery.extend( {
 
        Deferred: function( func ) {
                var tuples = [
 
-                               // action, add listener, listener list, final state
-                               [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ],
-                               [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ],
-                               [ "notify", "progress", jQuery.Callbacks( "memory" ) ]
+                               // action, add listener, callbacks,
+                               // ... .then handlers, argument index, [final state]
+                               [ "notify", "progress", jQuery.Callbacks( "memory" ),
+                                       jQuery.Callbacks( "memory" ), 2 ],
+                               [ "resolve", "done", jQuery.Callbacks( "once memory" ),
+                                       jQuery.Callbacks( "once memory" ), 0, "resolved" ],
+                               [ "reject", "fail", jQuery.Callbacks( "once memory" ),
+                                       jQuery.Callbacks( "once memory" ), 1, "rejected" ]
                        ],
                        state = "pending",
                        promise = {
@@ -3355,13 +3529,23 @@ jQuery.extend( {
                                        deferred.done( arguments ).fail( arguments );
                                        return this;
                                },
-                               then: function( /* fnDone, fnFail, fnProgress */ ) {
+                               "catch": function( fn ) {
+                                       return promise.then( null, fn );
+                               },
+
+                               // Keep pipe for back-compat
+                               pipe: function( /* fnDone, fnFail, fnProgress */ ) {
                                        var fns = arguments;
+
                                        return jQuery.Deferred( function( newDefer ) {
                                                jQuery.each( tuples, function( i, tuple ) {
-                                                       var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
 
-                                                       // deferred[ done | fail | progress ] for forwarding actions to newDefer
+                                                       // Map tuples (progress, done, fail) to arguments (done, fail, progress)
+                                                       var fn = jQuery.isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
+
+                                                       // deferred.progress(function() { bind to newDefer or newDefer.notify })
+                                                       // deferred.done(function() { bind to newDefer or newDefer.resolve })
+                                                       // deferred.fail(function() { bind to newDefer or newDefer.reject })
                                                        deferred[ tuple[ 1 ] ]( function() {
                                                                var returned = fn && fn.apply( this, arguments );
                                                                if ( returned && jQuery.isFunction( returned.promise ) ) {
@@ -3371,7 +3555,7 @@ jQuery.extend( {
                                                                                .fail( newDefer.reject );
                                                                } else {
                                                                        newDefer[ tuple[ 0 ] + "With" ](
-                                                                               this === promise ? newDefer.promise() : this,
+                                                                               this,
                                                                                fn ? [ returned ] : arguments
                                                                        );
                                                                }
@@ -3380,6 +3564,170 @@ jQuery.extend( {
                                                fns = null;
                                        } ).promise();
                                },
+                               then: function( onFulfilled, onRejected, onProgress ) {
+                                       var maxDepth = 0;
+                                       function resolve( depth, deferred, handler, special ) {
+                                               return function() {
+                                                       var that = this,
+                                                               args = arguments,
+                                                               mightThrow = function() {
+                                                                       var returned, then;
+
+                                                                       // Support: Promises/A+ section 2.3.3.3.3
+                                                                       // https://promisesaplus.com/#point-59
+                                                                       // Ignore double-resolution attempts
+                                                                       if ( depth < maxDepth ) {
+                                                                               return;
+                                                                       }
+
+                                                                       returned = handler.apply( that, args );
+
+                                                                       // Support: Promises/A+ section 2.3.1
+                                                                       // https://promisesaplus.com/#point-48
+                                                                       if ( returned === deferred.promise() ) {
+                                                                               throw new TypeError( "Thenable self-resolution" );
+                                                                       }
+
+                                                                       // Support: Promises/A+ sections 2.3.3.1, 3.5
+                                                                       // https://promisesaplus.com/#point-54
+                                                                       // https://promisesaplus.com/#point-75
+                                                                       // Retrieve `then` only once
+                                                                       then = returned &&
+
+                                                                               // Support: Promises/A+ section 2.3.4
+                                                                               // https://promisesaplus.com/#point-64
+                                                                               // Only check objects and functions for thenability
+                                                                               ( typeof returned === "object" ||
+                                                                                       typeof returned === "function" ) &&
+                                                                               returned.then;
+
+                                                                       // Handle a returned thenable
+                                                                       if ( jQuery.isFunction( then ) ) {
+
+                                                                               // Special processors (notify) just wait for resolution
+                                                                               if ( special ) {
+                                                                                       then.call(
+                                                                                               returned,
+                                                                                               resolve( maxDepth, deferred, Identity, special ),
+                                                                                               resolve( maxDepth, deferred, Thrower, special )
+                                                                                       );
+
+                                                                               // Normal processors (resolve) also hook into progress
+                                                                               } else {
+
+                                                                                       // ...and disregard older resolution values
+                                                                                       maxDepth++;
+
+                                                                                       then.call(
+                                                                                               returned,
+                                                                                               resolve( maxDepth, deferred, Identity, special ),
+                                                                                               resolve( maxDepth, deferred, Thrower, special ),
+                                                                                               resolve( maxDepth, deferred, Identity,
+                                                                                                       deferred.notifyWith )
+                                                                                       );
+                                                                               }
+
+                                                                       // Handle all other returned values
+                                                                       } else {
+
+                                                                               // Only substitute handlers pass on context
+                                                                               // and multiple values (non-spec behavior)
+                                                                               if ( handler !== Identity ) {
+                                                                                       that = undefined;
+                                                                                       args = [ returned ];
+                                                                               }
+
+                                                                               // Process the value(s)
+                                                                               // Default process is resolve
+                                                                               ( special || deferred.resolveWith )( that, args );
+                                                                       }
+                                                               },
+
+                                                               // Only normal processors (resolve) catch and reject exceptions
+                                                               process = special ?
+                                                                       mightThrow :
+                                                                       function() {
+                                                                               try {
+                                                                                       mightThrow();
+                                                                               } catch ( e ) {
+
+                                                                                       if ( jQuery.Deferred.exceptionHook ) {
+                                                                                               jQuery.Deferred.exceptionHook( e,
+                                                                                                       process.stackTrace );
+                                                                                       }
+
+                                                                                       // Support: Promises/A+ section 2.3.3.3.4.1
+                                                                                       // https://promisesaplus.com/#point-61
+                                                                                       // Ignore post-resolution exceptions
+                                                                                       if ( depth + 1 >= maxDepth ) {
+
+                                                                                               // Only substitute handlers pass on context
+                                                                                               // and multiple values (non-spec behavior)
+                                                                                               if ( handler !== Thrower ) {
+                                                                                                       that = undefined;
+                                                                                                       args = [ e ];
+                                                                                               }
+
+                                                                                               deferred.rejectWith( that, args );
+                                                                                       }
+                                                                               }
+                                                                       };
+
+                                                       // Support: Promises/A+ section 2.3.3.3.1
+                                                       // https://promisesaplus.com/#point-57
+                                                       // Re-resolve promises immediately to dodge false rejection from
+                                                       // subsequent errors
+                                                       if ( depth ) {
+                                                               process();
+                                                       } else {
+
+                                                               // Call an optional hook to record the stack, in case of exception
+                                                               // since it's otherwise lost when execution goes async
+                                                               if ( jQuery.Deferred.getStackHook ) {
+                                                                       process.stackTrace = jQuery.Deferred.getStackHook();
+                                                               }
+                                                               window.setTimeout( process );
+                                                       }
+                                               };
+                                       }
+
+                                       return jQuery.Deferred( function( newDefer ) {
+
+                                               // progress_handlers.add( ... )
+                                               tuples[ 0 ][ 3 ].add(
+                                                       resolve(
+                                                               0,
+                                                               newDefer,
+                                                               jQuery.isFunction( onProgress ) ?
+                                                                       onProgress :
+                                                                       Identity,
+                                                               newDefer.notifyWith
+                                                       )
+                                               );
+
+                                               // fulfilled_handlers.add( ... )
+                                               tuples[ 1 ][ 3 ].add(
+                                                       resolve(
+                                                               0,
+                                                               newDefer,
+                                                               jQuery.isFunction( onFulfilled ) ?
+                                                                       onFulfilled :
+                                                                       Identity
+                                                       )
+                                               );
+
+                                               // rejected_handlers.add( ... )
+                                               tuples[ 2 ][ 3 ].add(
+                                                       resolve(
+                                                               0,
+                                                               newDefer,
+                                                               jQuery.isFunction( onRejected ) ?
+                                                                       onRejected :
+                                                                       Thrower
+                                                       )
+                                               );
+                                       } ).promise();
+                               },
 
                                // Get a promise for this deferred
                                // If obj is provided, the promise aspect is added to the object
@@ -3389,33 +3737,51 @@ jQuery.extend( {
                        },
                        deferred = {};
 
-               // Keep pipe for back-compat
-               promise.pipe = promise.then;
-
                // Add list-specific methods
                jQuery.each( tuples, function( i, tuple ) {
                        var list = tuple[ 2 ],
-                               stateString = tuple[ 3 ];
+                               stateString = tuple[ 5 ];
 
-                       // promise[ done | fail | progress ] = list.add
+                       // promise.progress = list.add
+                       // promise.done = list.add
+                       // promise.fail = list.add
                        promise[ tuple[ 1 ] ] = list.add;
 
                        // Handle state
                        if ( stateString ) {
-                               list.add( function() {
+                               list.add(
+                                       function() {
+
+                                               // state = "resolved" (i.e., fulfilled)
+                                               // state = "rejected"
+                                               state = stateString;
+                                       },
 
-                                       // state = [ resolved | rejected ]
-                                       state = stateString;
+                                       // rejected_callbacks.disable
+                                       // fulfilled_callbacks.disable
+                                       tuples[ 3 - i ][ 2 ].disable,
 
-                               // [ reject_list | resolve_list ].disable; progress_list.lock
-                               }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
+                                       // progress_callbacks.lock
+                                       tuples[ 0 ][ 2 ].lock
+                               );
                        }
 
-                       // deferred[ resolve | reject | notify ]
+                       // progress_handlers.fire
+                       // fulfilled_handlers.fire
+                       // rejected_handlers.fire
+                       list.add( tuple[ 3 ].fire );
+
+                       // deferred.notify = function() { deferred.notifyWith(...) }
+                       // deferred.resolve = function() { deferred.resolveWith(...) }
+                       // deferred.reject = function() { deferred.rejectWith(...) }
                        deferred[ tuple[ 0 ] ] = function() {
-                               deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
+                               deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
                                return this;
                        };
+
+                       // deferred.notifyWith = list.fireWith
+                       // deferred.resolveWith = list.fireWith
+                       // deferred.rejectWith = list.fireWith
                        deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
                } );
 
@@ -3432,68 +3798,95 @@ jQuery.extend( {
        },
 
        // Deferred helper
-       when: function( subordinate /* , ..., subordinateN */ ) {
-               var i = 0,
-                       resolveValues = slice.call( arguments ),
-                       length = resolveValues.length,
+       when: function( singleValue ) {
+               var
+
+                       // count of uncompleted subordinates
+                       remaining = arguments.length,
 
-                       // the count of uncompleted subordinates
-                       remaining = length !== 1 ||
-                               ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
+                       // count of unprocessed arguments
+                       i = remaining,
+
+                       // subordinate fulfillment data
+                       resolveContexts = Array( i ),
+                       resolveValues = slice.call( arguments ),
 
-                       // the master Deferred.
-                       // If resolveValues consist of only a single Deferred, just use that.
-                       deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
+                       // the master Deferred
+                       master = jQuery.Deferred(),
 
-                       // Update function for both resolve and progress values
-                       updateFunc = function( i, contexts, values ) {
+                       // subordinate callback factory
+                       updateFunc = function( i ) {
                                return function( value ) {
-                                       contexts[ i ] = this;
-                                       values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
-                                       if ( values === progressValues ) {
-                                               deferred.notifyWith( contexts, values );
-                                       } else if ( !( --remaining ) ) {
-                                               deferred.resolveWith( contexts, values );
+                                       resolveContexts[ i ] = this;
+                                       resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
+                                       if ( !( --remaining ) ) {
+                                               master.resolveWith( resolveContexts, resolveValues );
                                        }
                                };
-                       },
+                       };
 
-                       progressValues, progressContexts, resolveContexts;
+               // Single- and empty arguments are adopted like Promise.resolve
+               if ( remaining <= 1 ) {
+                       adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
+                               !remaining );
 
-               // Add listeners to Deferred subordinates; treat others as resolved
-               if ( length > 1 ) {
-                       progressValues = new Array( length );
-                       progressContexts = new Array( length );
-                       resolveContexts = new Array( length );
-                       for ( ; i < length; i++ ) {
-                               if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
-                                       resolveValues[ i ].promise()
-                                               .progress( updateFunc( i, progressContexts, progressValues ) )
-                                               .done( updateFunc( i, resolveContexts, resolveValues ) )
-                                               .fail( deferred.reject );
-                               } else {
-                                       --remaining;
-                               }
+                       // Use .then() to unwrap secondary thenables (cf. gh-3000)
+                       if ( master.state() === "pending" ||
+                               jQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
+
+                               return master.then();
                        }
                }
 
-               // If we're not waiting on anything, resolve the master
-               if ( !remaining ) {
-                       deferred.resolveWith( resolveContexts, resolveValues );
+               // Multiple arguments are aggregated like Promise.all array elements
+               while ( i-- ) {
+                       adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
                }
 
-               return deferred.promise();
+               return master.promise();
        }
 } );
 
 
+// These usually indicate a programmer mistake during development,
+// warn about them ASAP rather than swallowing them by default.
+var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
+
+jQuery.Deferred.exceptionHook = function( error, stack ) {
+
+       // Support: IE 8 - 9 only
+       // Console exists when dev tools are open, which can happen at any time
+       if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
+               window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
+       }
+};
+
+
+
+
+jQuery.readyException = function( error ) {
+       window.setTimeout( function() {
+               throw error;
+       } );
+};
+
+
+
+
 // The deferred used on DOM ready
-var readyList;
+var readyList = jQuery.Deferred();
 
 jQuery.fn.ready = function( fn ) {
 
-       // Add the callback
-       jQuery.ready.promise().done( fn );
+       readyList
+               .then( fn )
+
+               // Wrap jQuery.readyException in a function so that the lookup
+               // happens at the time of error handling instead of callback
+               // registration.
+               .catch( function( error ) {
+                       jQuery.readyException( error );
+               } );
 
        return this;
 };
@@ -3507,15 +3900,6 @@ jQuery.extend( {
        // the ready event fires. See #6781
        readyWait: 1,
 
-       // Hold (or release) the ready event
-       holdReady: function( hold ) {
-               if ( hold ) {
-                       jQuery.readyWait++;
-               } else {
-                       jQuery.ready( true );
-               }
-       },
-
        // Handle when the DOM is ready
        ready: function( wait ) {
 
@@ -3534,53 +3918,36 @@ jQuery.extend( {
 
                // If there are functions bound, to execute
                readyList.resolveWith( document, [ jQuery ] );
-
-               // Trigger any bound ready events
-               if ( jQuery.fn.triggerHandler ) {
-                       jQuery( document ).triggerHandler( "ready" );
-                       jQuery( document ).off( "ready" );
-               }
        }
 } );
 
-/**
- * The ready event handler and self cleanup method
- */
+jQuery.ready.then = readyList.then;
+
+// The ready event handler and self cleanup method
 function completed() {
        document.removeEventListener( "DOMContentLoaded", completed );
        window.removeEventListener( "load", completed );
        jQuery.ready();
 }
 
-jQuery.ready.promise = function( obj ) {
-       if ( !readyList ) {
-
-               readyList = jQuery.Deferred();
-
-               // Catch cases where $(document).ready() is called
-               // after the browser event has already occurred.
-               // Support: IE9-10 only
-               // Older IE sometimes signals "interactive" too soon
-               if ( document.readyState === "complete" ||
-                       ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
-
-                       // Handle it asynchronously to allow scripts the opportunity to delay ready
-                       window.setTimeout( jQuery.ready );
+// Catch cases where $(document).ready() is called
+// after the browser event has already occurred.
+// Support: IE <=9 - 10 only
+// Older IE sometimes signals "interactive" too soon
+if ( document.readyState === "complete" ||
+       ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
 
-               } else {
+       // Handle it asynchronously to allow scripts the opportunity to delay ready
+       window.setTimeout( jQuery.ready );
 
-                       // Use the handy event callback
-                       document.addEventListener( "DOMContentLoaded", completed );
+} else {
 
-                       // A fallback to window.onload, that will always work
-                       window.addEventListener( "load", completed );
-               }
-       }
-       return readyList.promise( obj );
-};
+       // Use the handy event callback
+       document.addEventListener( "DOMContentLoaded", completed );
 
-// Kick off the DOM ready check even if the user does not
-jQuery.ready.promise();
+       // A fallback to window.onload, that will always work
+       window.addEventListener( "load", completed );
+}
 
 
 
@@ -3634,13 +4001,16 @@ var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
                }
        }
 
-       return chainable ?
-               elems :
+       if ( chainable ) {
+               return elems;
+       }
+
+       // Gets
+       if ( bulk ) {
+               return fn.call( elems );
+       }
 
-               // Gets
-               bulk ?
-                       fn.call( elems ) :
-                       len ? fn( elems[ 0 ], key ) : emptyGet;
+       return len ? fn( elems[ 0 ], key ) : emptyGet;
 };
 var acceptData = function( owner ) {
 
@@ -3650,7 +4020,6 @@ var acceptData = function( owner ) {
        //    - Node.DOCUMENT_NODE
        //  - Object
        //    - Any
-       /* jshint -W018 */
        return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
 };
 
@@ -3665,35 +4034,8 @@ Data.uid = 1;
 
 Data.prototype = {
 
-       register: function( owner, initial ) {
-               var value = initial || {};
-
-               // If it is a node unlikely to be stringify-ed or looped over
-               // use plain assignment
-               if ( owner.nodeType ) {
-                       owner[ this.expando ] = value;
-
-               // Otherwise secure it in a non-enumerable, non-writable property
-               // configurability must be true to allow the property to be
-               // deleted with the delete operator
-               } else {
-                       Object.defineProperty( owner, this.expando, {
-                               value: value,
-                               writable: true,
-                               configurable: true
-                       } );
-               }
-               return owner[ this.expando ];
-       },
        cache: function( owner ) {
 
-               // We can accept data for non-element nodes in modern browsers,
-               // but we should not, see #8335.
-               // Always return an empty object.
-               if ( !acceptData( owner ) ) {
-                       return {};
-               }
-
                // Check if the owner object already has a cache
                var value = owner[ this.expando ];
 
@@ -3730,15 +4072,16 @@ Data.prototype = {
                        cache = this.cache( owner );
 
                // Handle: [ owner, key, value ] args
+               // Always use camelCase key (gh-2257)
                if ( typeof data === "string" ) {
-                       cache[ data ] = value;
+                       cache[ jQuery.camelCase( data ) ] = value;
 
                // Handle: [ owner, { properties } ] args
                } else {
 
                        // Copy the properties one-by-one to the cache object
                        for ( prop in data ) {
-                               cache[ prop ] = data[ prop ];
+                               cache[ jQuery.camelCase( prop ) ] = data[ prop ];
                        }
                }
                return cache;
@@ -3746,10 +4089,11 @@ Data.prototype = {
        get: function( owner, key ) {
                return key === undefined ?
                        this.cache( owner ) :
-                       owner[ this.expando ] && owner[ this.expando ][ key ];
+
+                       // Always use camelCase key (gh-2257)
+                       owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ];
        },
        access: function( owner, key, value ) {
-               var stored;
 
                // In cases where either:
                //
@@ -3765,10 +4109,7 @@ Data.prototype = {
                if ( key === undefined ||
                                ( ( key && typeof key === "string" ) && value === undefined ) ) {
 
-                       stored = this.get( owner, key );
-
-                       return stored !== undefined ?
-                               stored : this.get( owner, jQuery.camelCase( key ) );
+                       return this.get( owner, key );
                }
 
                // When the key is not a string, or both a key and value
@@ -3784,58 +4125,45 @@ Data.prototype = {
                return value !== undefined ? value : key;
        },
        remove: function( owner, key ) {
-               var i, name, camel,
+               var i,
                        cache = owner[ this.expando ];
 
                if ( cache === undefined ) {
                        return;
                }
 
-               if ( key === undefined ) {
-                       this.register( owner );
-
-               } else {
+               if ( key !== undefined ) {
 
                        // Support array or space separated string of keys
-                       if ( jQuery.isArray( key ) ) {
-
-                               // If "name" is an array of keys...
-                               // When data is initially created, via ("key", "val") signature,
-                               // keys will be converted to camelCase.
-                               // Since there is no way to tell _how_ a key was added, remove
-                               // both plain key and camelCase key. #12786
-                               // This will only penalize the array argument path.
-                               name = key.concat( key.map( jQuery.camelCase ) );
-                       } else {
-                               camel = jQuery.camelCase( key );
+                       if ( Array.isArray( key ) ) {
 
-                               // Try the string as a key before any manipulation
-                               if ( key in cache ) {
-                                       name = [ key, camel ];
-                               } else {
+                               // If key is an array of keys...
+                               // We always set camelCase keys, so remove that.
+                               key = key.map( jQuery.camelCase );
+                       } else {
+                               key = jQuery.camelCase( key );
 
-                                       // If a key with the spaces exists, use it.
-                                       // Otherwise, create an array by matching non-whitespace
-                                       name = camel;
-                                       name = name in cache ?
-                                               [ name ] : ( name.match( rnotwhite ) || [] );
-                               }
+                               // If a key with the spaces exists, use it.
+                               // Otherwise, create an array by matching non-whitespace
+                               key = key in cache ?
+                                       [ key ] :
+                                       ( key.match( rnothtmlwhite ) || [] );
                        }
 
-                       i = name.length;
+                       i = key.length;
 
                        while ( i-- ) {
-                               delete cache[ name[ i ] ];
+                               delete cache[ key[ i ] ];
                        }
                }
 
                // Remove the expando if there's no more data
                if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
 
-                       // Support: Chrome <= 35-45+
+                       // Support: Chrome <=35 - 45
                        // Webkit & Blink performance suffers when deleting properties
                        // from DOM nodes, so set to undefined instead
-                       // https://code.google.com/p/chromium/issues/detail?id=378607
+                       // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
                        if ( owner.nodeType ) {
                                owner[ this.expando ] = undefined;
                        } else {
@@ -3867,8 +4195,33 @@ var dataUser = new Data();
 var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
        rmultiDash = /[A-Z]/g;
 
-function dataAttr( elem, key, data ) {
-       var name;
+function getData( data ) {
+       if ( data === "true" ) {
+               return true;
+       }
+
+       if ( data === "false" ) {
+               return false;
+       }
+
+       if ( data === "null" ) {
+               return null;
+       }
+
+       // Only convert to a number if it doesn't change the string
+       if ( data === +data + "" ) {
+               return +data;
+       }
+
+       if ( rbrace.test( data ) ) {
+               return JSON.parse( data );
+       }
+
+       return data;
+}
+
+function dataAttr( elem, key, data ) {
+       var name;
 
        // If nothing was found internally, try to fetch any
        // data from the HTML5 data-* attribute
@@ -3878,14 +4231,7 @@ function dataAttr( elem, key, data ) {
 
                if ( typeof data === "string" ) {
                        try {
-                               data = data === "true" ? true :
-                                       data === "false" ? false :
-                                       data === "null" ? null :
-
-                                       // Only convert to a number if it doesn't change the string
-                                       +data + "" === data ? +data :
-                                       rbrace.test( data ) ? jQuery.parseJSON( data ) :
-                                       data;
+                               data = getData( data );
                        } catch ( e ) {}
 
                        // Make sure we set the data so it isn't changed later
@@ -3936,7 +4282,7 @@ jQuery.fn.extend( {
                                        i = attrs.length;
                                        while ( i-- ) {
 
-                                               // Support: IE11+
+                                               // Support: IE 11 only
                                                // The attrs elements can be null (#14894)
                                                if ( attrs[ i ] ) {
                                                        name = attrs[ i ].name;
@@ -3961,7 +4307,7 @@ jQuery.fn.extend( {
                }
 
                return access( this, function( value ) {
-                       var data, camelKey;
+                       var data;
 
                        // The calling jQuery object (element matches) is not empty
                        // (and therefore has an element appears at this[ 0 ]) and the
@@ -3971,29 +4317,15 @@ jQuery.fn.extend( {
                        if ( elem && value === undefined ) {
 
                                // Attempt to get data from the cache
-                               // with the key as-is
-                               data = dataUser.get( elem, key ) ||
-
-                                       // Try to find dashed key if it exists (gh-2779)
-                                       // This is for 2.2.x only
-                                       dataUser.get( elem, key.replace( rmultiDash, "-$&" ).toLowerCase() );
-
-                               if ( data !== undefined ) {
-                                       return data;
-                               }
-
-                               camelKey = jQuery.camelCase( key );
-
-                               // Attempt to get data from the cache
-                               // with the key camelized
-                               data = dataUser.get( elem, camelKey );
+                               // The key will always be camelCased in Data
+                               data = dataUser.get( elem, key );
                                if ( data !== undefined ) {
                                        return data;
                                }
 
                                // Attempt to "discover" the data in
                                // HTML5 custom data-* attrs
-                               data = dataAttr( elem, camelKey, undefined );
+                               data = dataAttr( elem, key );
                                if ( data !== undefined ) {
                                        return data;
                                }
@@ -4003,24 +4335,10 @@ jQuery.fn.extend( {
                        }
 
                        // Set the data...
-                       camelKey = jQuery.camelCase( key );
                        this.each( function() {
 
-                               // First, attempt to store a copy or reference of any
-                               // data that might've been store with a camelCased key.
-                               var data = dataUser.get( this, camelKey );
-
-                               // For HTML5 data-* attribute interop, we have to
-                               // store property names with dashes in a camelCase form.
-                               // This might not apply to all properties...*
-                               dataUser.set( this, camelKey, value );
-
-                               // *... In the case of properties that might _actually_
-                               // have dashes, we need to also store a copy of that
-                               // unchanged property.
-                               if ( key.indexOf( "-" ) > -1 && data !== undefined ) {
-                                       dataUser.set( this, key, value );
-                               }
+                               // We always store the camelCased key
+                               dataUser.set( this, key, value );
                        } );
                }, null, value, arguments.length > 1, null, true );
        },
@@ -4043,7 +4361,7 @@ jQuery.extend( {
 
                        // Speed up dequeue by getting out quickly if this is just a lookup
                        if ( data ) {
-                               if ( !queue || jQuery.isArray( data ) ) {
+                               if ( !queue || Array.isArray( data ) ) {
                                        queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
                                } else {
                                        queue.push( data );
@@ -4173,15 +4491,46 @@ var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
 
 var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
 
-var isHidden = function( elem, el ) {
+var isHiddenWithinTree = function( elem, el ) {
 
-               // isHidden might be called from jQuery#filter function;
+               // isHiddenWithinTree might be called from jQuery#filter function;
                // in that case, element will be second argument
                elem = el || elem;
-               return jQuery.css( elem, "display" ) === "none" ||
-                       !jQuery.contains( elem.ownerDocument, elem );
+
+               // Inline style trumps all
+               return elem.style.display === "none" ||
+                       elem.style.display === "" &&
+
+                       // Otherwise, check computed style
+                       // Support: Firefox <=43 - 45
+                       // Disconnected elements can have computed display: none, so first confirm that elem is
+                       // in the document.
+                       jQuery.contains( elem.ownerDocument, elem ) &&
+
+                       jQuery.css( elem, "display" ) === "none";
        };
 
+var swap = function( elem, options, callback, args ) {
+       var ret, name,
+               old = {};
+
+       // Remember the old values, and insert the new ones
+       for ( name in options ) {
+               old[ name ] = elem.style[ name ];
+               elem.style[ name ] = options[ name ];
+       }
+
+       ret = callback.apply( elem, args || [] );
+
+       // Revert the old values
+       for ( name in options ) {
+               elem.style[ name ] = old[ name ];
+       }
+
+       return ret;
+};
+
+
 
 
 function adjustCSS( elem, prop, valueParts, tween ) {
@@ -4189,8 +4538,12 @@ function adjustCSS( elem, prop, valueParts, tween ) {
                scale = 1,
                maxIterations = 20,
                currentValue = tween ?
-                       function() { return tween.cur(); } :
-                       function() { return jQuery.css( elem, prop, "" ); },
+                       function() {
+                               return tween.cur();
+                       } :
+                       function() {
+                               return jQuery.css( elem, prop, "" );
+                       },
                initial = currentValue(),
                unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
 
@@ -4241,9 +4594,105 @@ function adjustCSS( elem, prop, valueParts, tween ) {
        }
        return adjusted;
 }
+
+
+var defaultDisplayMap = {};
+
+function getDefaultDisplay( elem ) {
+       var temp,
+               doc = elem.ownerDocument,
+               nodeName = elem.nodeName,
+               display = defaultDisplayMap[ nodeName ];
+
+       if ( display ) {
+               return display;
+       }
+
+       temp = doc.body.appendChild( doc.createElement( nodeName ) );
+       display = jQuery.css( temp, "display" );
+
+       temp.parentNode.removeChild( temp );
+
+       if ( display === "none" ) {
+               display = "block";
+       }
+       defaultDisplayMap[ nodeName ] = display;
+
+       return display;
+}
+
+function showHide( elements, show ) {
+       var display, elem,
+               values = [],
+               index = 0,
+               length = elements.length;
+
+       // Determine new display value for elements that need to change
+       for ( ; index < length; index++ ) {
+               elem = elements[ index ];
+               if ( !elem.style ) {
+                       continue;
+               }
+
+               display = elem.style.display;
+               if ( show ) {
+
+                       // Since we force visibility upon cascade-hidden elements, an immediate (and slow)
+                       // check is required in this first loop unless we have a nonempty display value (either
+                       // inline or about-to-be-restored)
+                       if ( display === "none" ) {
+                               values[ index ] = dataPriv.get( elem, "display" ) || null;
+                               if ( !values[ index ] ) {
+                                       elem.style.display = "";
+                               }
+                       }
+                       if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
+                               values[ index ] = getDefaultDisplay( elem );
+                       }
+               } else {
+                       if ( display !== "none" ) {
+                               values[ index ] = "none";
+
+                               // Remember what we're overwriting
+                               dataPriv.set( elem, "display", display );
+                       }
+               }
+       }
+
+       // Set the display of the elements in a second loop to avoid constant reflow
+       for ( index = 0; index < length; index++ ) {
+               if ( values[ index ] != null ) {
+                       elements[ index ].style.display = values[ index ];
+               }
+       }
+
+       return elements;
+}
+
+jQuery.fn.extend( {
+       show: function() {
+               return showHide( this, true );
+       },
+       hide: function() {
+               return showHide( this );
+       },
+       toggle: function( state ) {
+               if ( typeof state === "boolean" ) {
+                       return state ? this.show() : this.hide();
+               }
+
+               return this.each( function() {
+                       if ( isHiddenWithinTree( this ) ) {
+                               jQuery( this ).show();
+                       } else {
+                               jQuery( this ).hide();
+                       }
+               } );
+       }
+} );
 var rcheckableType = ( /^(?:checkbox|radio)$/i );
 
-var rtagName = ( /<([\w:-]+)/ );
+var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i );
 
 var rscriptType = ( /^$|\/(?:java|ecma)script/i );
 
@@ -4252,7 +4701,7 @@ var rscriptType = ( /^$|\/(?:java|ecma)script/i );
 // We have to close these tags to support XHTML (#13200)
 var wrapMap = {
 
-       // Support: IE9
+       // Support: IE <=9 only
        option: [ 1, "<select multiple='multiple'>", "</select>" ],
 
        // XHTML parsers do not magically insert elements in the
@@ -4266,7 +4715,7 @@ var wrapMap = {
        _default: [ 0, "", "" ]
 };
 
-// Support: IE9
+// Support: IE <=9 only
 wrapMap.optgroup = wrapMap.option;
 
 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
@@ -4275,17 +4724,25 @@ wrapMap.th = wrapMap.td;
 
 function getAll( context, tag ) {
 
-       // Support: IE9-11+
+       // Support: IE <=9 - 11 only
        // Use typeof to avoid zero-argument method invocation on host objects (#15151)
-       var ret = typeof context.getElementsByTagName !== "undefined" ?
-                       context.getElementsByTagName( tag || "*" ) :
-                       typeof context.querySelectorAll !== "undefined" ?
-                               context.querySelectorAll( tag || "*" ) :
-                       [];
-
-       return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
-               jQuery.merge( [ context ], ret ) :
-               ret;
+       var ret;
+
+       if ( typeof context.getElementsByTagName !== "undefined" ) {
+               ret = context.getElementsByTagName( tag || "*" );
+
+       } else if ( typeof context.querySelectorAll !== "undefined" ) {
+               ret = context.querySelectorAll( tag || "*" );
+
+       } else {
+               ret = [];
+       }
+
+       if ( tag === undefined || tag && nodeName( context, tag ) ) {
+               return jQuery.merge( [ context ], ret );
+       }
+
+       return ret;
 }
 
 
@@ -4321,7 +4778,7 @@ function buildFragment( elems, context, scripts, selection, ignored ) {
                        // Add nodes directly
                        if ( jQuery.type( elem ) === "object" ) {
 
-                               // Support: Android<4.1, PhantomJS<2
+                               // Support: Android <=4.0 only, PhantomJS 1 only
                                // push.apply(_, arraylike) throws on ancient WebKit
                                jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
 
@@ -4344,7 +4801,7 @@ function buildFragment( elems, context, scripts, selection, ignored ) {
                                        tmp = tmp.lastChild;
                                }
 
-                               // Support: Android<4.1, PhantomJS<2
+                               // Support: Android <=4.0 only, PhantomJS 1 only
                                // push.apply(_, arraylike) throws on ancient WebKit
                                jQuery.merge( nodes, tmp.childNodes );
 
@@ -4401,7 +4858,7 @@ function buildFragment( elems, context, scripts, selection, ignored ) {
                div = fragment.appendChild( document.createElement( "div" ) ),
                input = document.createElement( "input" );
 
-       // Support: Android 4.0-4.3, Safari<=5.1
+       // Support: Android 4.0 - 4.3 only
        // Check state lost if the name is set (#11217)
        // Support: Windows Web Apps (WWA)
        // `name` and `type` must use .setAttribute for WWA (#14901)
@@ -4411,15 +4868,17 @@ function buildFragment( elems, context, scripts, selection, ignored ) {
 
        div.appendChild( input );
 
-       // Support: Safari<=5.1, Android<4.2
+       // Support: Android <=4.1 only
        // Older WebKit doesn't clone checked state correctly in fragments
        support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
 
-       // Support: IE<=11+
+       // Support: IE <=11 only
        // Make sure textarea (and checkbox) defaultValue is properly cloned
        div.innerHTML = "<textarea>x</textarea>";
        support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
 } )();
+var documentElement = document.documentElement;
+
 
 
 var
@@ -4435,7 +4894,7 @@ function returnFalse() {
        return false;
 }
 
-// Support: IE9
+// Support: IE <=9 only
 // See #13393 for more info
 function safeActiveElement() {
        try {
@@ -4531,6 +4990,12 @@ jQuery.event = {
                        selector = handleObjIn.selector;
                }
 
+               // Ensure that invalid selectors throw exceptions at attach time
+               // Evaluate against documentElement in case elem is a non-element node (e.g., document)
+               if ( selector ) {
+                       jQuery.find.matchesSelector( documentElement, selector );
+               }
+
                // Make sure that the handler has a unique ID, used to find/remove it later
                if ( !handler.guid ) {
                        handler.guid = jQuery.guid++;
@@ -4551,7 +5016,7 @@ jQuery.event = {
                }
 
                // Handle multiple events separated by a space
-               types = ( types || "" ).match( rnotwhite ) || [ "" ];
+               types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
                t = types.length;
                while ( t-- ) {
                        tmp = rtypenamespace.exec( types[ t ] ) || [];
@@ -4633,7 +5098,7 @@ jQuery.event = {
                }
 
                // Once for each type.namespace in types; type may be omitted
-               types = ( types || "" ).match( rnotwhite ) || [ "" ];
+               types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
                t = types.length;
                while ( t-- ) {
                        tmp = rtypenamespace.exec( types[ t ] ) || [];
@@ -4694,19 +5159,23 @@ jQuery.event = {
                }
        },
 
-       dispatch: function( event ) {
+       dispatch: function( nativeEvent ) {
 
                // Make a writable jQuery.Event from the native event object
-               event = jQuery.event.fix( event );
+               var event = jQuery.event.fix( nativeEvent );
 
-               var i, j, ret, matched, handleObj,
-                       handlerQueue = [],
-                       args = slice.call( arguments ),
+               var i, j, ret, matched, handleObj, handlerQueue,
+                       args = new Array( arguments.length ),
                        handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
                        special = jQuery.event.special[ event.type ] || {};
 
                // Use the fix-ed jQuery.Event rather than the (read-only) native event
                args[ 0 ] = event;
+
+               for ( i = 1; i < arguments.length; i++ ) {
+                       args[ i ] = arguments[ i ];
+               }
+
                event.delegateTarget = this;
 
                // Call the preDispatch hook for the mapped type, and let it bail if desired
@@ -4755,146 +5224,95 @@ jQuery.event = {
        },
 
        handlers: function( event, handlers ) {
-               var i, matches, sel, handleObj,
+               var i, handleObj, sel, matchedHandlers, matchedSelectors,
                        handlerQueue = [],
                        delegateCount = handlers.delegateCount,
                        cur = event.target;
 
-               // Support (at least): Chrome, IE9
                // Find delegate handlers
-               // Black-hole SVG <use> instance trees (#13180)
-               //
-               // Support: Firefox<=42+
-               // Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)
-               if ( delegateCount && cur.nodeType &&
-                       ( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) {
+               if ( delegateCount &&
+
+                       // Support: IE <=9
+                       // Black-hole SVG <use> instance trees (trac-13180)
+                       cur.nodeType &&
+
+                       // Support: Firefox <=42
+                       // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
+                       // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
+                       // Support: IE 11 only
+                       // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
+                       !( event.type === "click" && event.button >= 1 ) ) {
 
                        for ( ; cur !== this; cur = cur.parentNode || this ) {
 
                                // Don't check non-elements (#13208)
                                // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
-                               if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) {
-                                       matches = [];
+                               if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
+                                       matchedHandlers = [];
+                                       matchedSelectors = {};
                                        for ( i = 0; i < delegateCount; i++ ) {
                                                handleObj = handlers[ i ];
 
                                                // Don't conflict with Object.prototype properties (#13203)
                                                sel = handleObj.selector + " ";
 
-                                               if ( matches[ sel ] === undefined ) {
-                                                       matches[ sel ] = handleObj.needsContext ?
+                                               if ( matchedSelectors[ sel ] === undefined ) {
+                                                       matchedSelectors[ sel ] = handleObj.needsContext ?
                                                                jQuery( sel, this ).index( cur ) > -1 :
                                                                jQuery.find( sel, this, null, [ cur ] ).length;
                                                }
-                                               if ( matches[ sel ] ) {
-                                                       matches.push( handleObj );
+                                               if ( matchedSelectors[ sel ] ) {
+                                                       matchedHandlers.push( handleObj );
                                                }
                                        }
-                                       if ( matches.length ) {
-                                               handlerQueue.push( { elem: cur, handlers: matches } );
+                                       if ( matchedHandlers.length ) {
+                                               handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
                                        }
                                }
                        }
                }
 
                // Add the remaining (directly-bound) handlers
+               cur = this;
                if ( delegateCount < handlers.length ) {
-                       handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } );
+                       handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
                }
 
                return handlerQueue;
        },
 
-       // Includes some event props shared by KeyEvent and MouseEvent
-       props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " +
-               "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ),
-
-       fixHooks: {},
-
-       keyHooks: {
-               props: "char charCode key keyCode".split( " " ),
-               filter: function( event, original ) {
-
-                       // Add which for key events
-                       if ( event.which == null ) {
-                               event.which = original.charCode != null ? original.charCode : original.keyCode;
-                       }
-
-                       return event;
-               }
-       },
-
-       mouseHooks: {
-               props: ( "button buttons clientX clientY offsetX offsetY pageX pageY " +
-                       "screenX screenY toElement" ).split( " " ),
-               filter: function( event, original ) {
-                       var eventDoc, doc, body,
-                               button = original.button;
-
-                       // Calculate pageX/Y if missing and clientX/Y available
-                       if ( event.pageX == null && original.clientX != null ) {
-                               eventDoc = event.target.ownerDocument || document;
-                               doc = eventDoc.documentElement;
-                               body = eventDoc.body;
+       addProp: function( name, hook ) {
+               Object.defineProperty( jQuery.Event.prototype, name, {
+                       enumerable: true,
+                       configurable: true,
 
-                               event.pageX = original.clientX +
-                                       ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) -
-                                       ( doc && doc.clientLeft || body && body.clientLeft || 0 );
-                               event.pageY = original.clientY +
-                                       ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) -
-                                       ( doc && doc.clientTop  || body && body.clientTop  || 0 );
-                       }
+                       get: jQuery.isFunction( hook ) ?
+                               function() {
+                                       if ( this.originalEvent ) {
+                                                       return hook( this.originalEvent );
+                                       }
+                               } :
+                               function() {
+                                       if ( this.originalEvent ) {
+                                                       return this.originalEvent[ name ];
+                                       }
+                               },
 
-                       // Add which for click: 1 === left; 2 === middle; 3 === right
-                       // Note: button is not normalized, so don't use it
-                       if ( !event.which && button !== undefined ) {
-                               event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
+                       set: function( value ) {
+                               Object.defineProperty( this, name, {
+                                       enumerable: true,
+                                       configurable: true,
+                                       writable: true,
+                                       value: value
+                               } );
                        }
-
-                       return event;
-               }
+               } );
        },
 
-       fix: function( event ) {
-               if ( event[ jQuery.expando ] ) {
-                       return event;
-               }
-
-               // Create a writable copy of the event object and normalize some properties
-               var i, prop, copy,
-                       type = event.type,
-                       originalEvent = event,
-                       fixHook = this.fixHooks[ type ];
-
-               if ( !fixHook ) {
-                       this.fixHooks[ type ] = fixHook =
-                               rmouseEvent.test( type ) ? this.mouseHooks :
-                               rkeyEvent.test( type ) ? this.keyHooks :
-                               {};
-               }
-               copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
-
-               event = new jQuery.Event( originalEvent );
-
-               i = copy.length;
-               while ( i-- ) {
-                       prop = copy[ i ];
-                       event[ prop ] = originalEvent[ prop ];
-               }
-
-               // Support: Cordova 2.5 (WebKit) (#13255)
-               // All events should have a target; Cordova deviceready doesn't
-               if ( !event.target ) {
-                       event.target = document;
-               }
-
-               // Support: Safari 6.0+, Chrome<28
-               // Target should not be a text node (#504, #13143)
-               if ( event.target.nodeType === 3 ) {
-                       event.target = event.target.parentNode;
-               }
-
-               return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
+       fix: function( originalEvent ) {
+               return originalEvent[ jQuery.expando ] ?
+                       originalEvent :
+                       new jQuery.Event( originalEvent );
        },
 
        special: {
@@ -4927,7 +5345,7 @@ jQuery.event = {
 
                        // For checkbox, fire native event so checked state will be right
                        trigger: function() {
-                               if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
+                               if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) {
                                        this.click();
                                        return false;
                                }
@@ -4935,7 +5353,7 @@ jQuery.event = {
 
                        // For cross-browser consistency, don't fire native .click() on links
                        _default: function( event ) {
-                               return jQuery.nodeName( event.target, "a" );
+                               return nodeName( event.target, "a" );
                        }
                },
 
@@ -4977,11 +5395,21 @@ jQuery.Event = function( src, props ) {
                this.isDefaultPrevented = src.defaultPrevented ||
                                src.defaultPrevented === undefined &&
 
-                               // Support: Android<4.0
+                               // Support: Android <=2.3 only
                                src.returnValue === false ?
                        returnTrue :
                        returnFalse;
 
+               // Create target properties
+               // Support: Safari <=6 - 7 only
+               // Target should not be a text node (#504, #13143)
+               this.target = ( src.target && src.target.nodeType === 3 ) ?
+                       src.target.parentNode :
+                       src.target;
+
+               this.currentTarget = src.currentTarget;
+               this.relatedTarget = src.relatedTarget;
+
        // Event type
        } else {
                this.type = src;
@@ -5000,7 +5428,7 @@ jQuery.Event = function( src, props ) {
 };
 
 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
-// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
 jQuery.Event.prototype = {
        constructor: jQuery.Event,
        isDefaultPrevented: returnFalse,
@@ -5039,13 +5467,74 @@ jQuery.Event.prototype = {
        }
 };
 
+// Includes all common event props including KeyEvent and MouseEvent specific props
+jQuery.each( {
+       altKey: true,
+       bubbles: true,
+       cancelable: true,
+       changedTouches: true,
+       ctrlKey: true,
+       detail: true,
+       eventPhase: true,
+       metaKey: true,
+       pageX: true,
+       pageY: true,
+       shiftKey: true,
+       view: true,
+       "char": true,
+       charCode: true,
+       key: true,
+       keyCode: true,
+       button: true,
+       buttons: true,
+       clientX: true,
+       clientY: true,
+       offsetX: true,
+       offsetY: true,
+       pointerId: true,
+       pointerType: true,
+       screenX: true,
+       screenY: true,
+       targetTouches: true,
+       toElement: true,
+       touches: true,
+
+       which: function( event ) {
+               var button = event.button;
+
+               // Add which for key events
+               if ( event.which == null && rkeyEvent.test( event.type ) ) {
+                       return event.charCode != null ? event.charCode : event.keyCode;
+               }
+
+               // Add which for click: 1 === left; 2 === middle; 3 === right
+               if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
+                       if ( button & 1 ) {
+                               return 1;
+                       }
+
+                       if ( button & 2 ) {
+                               return 3;
+                       }
+
+                       if ( button & 4 ) {
+                               return 2;
+                       }
+
+                       return 0;
+               }
+
+               return event.which;
+       }
+}, jQuery.event.addProp );
+
 // Create mouseenter/leave events using mouseover/out and event-time checks
 // so that event delegation works in jQuery.
 // Do the same for pointerenter/pointerleave and pointerover/pointerout
 //
 // Support: Safari 7 only
 // Safari sends mouseenter too often; see:
-// https://code.google.com/p/chromium/issues/detail?id=470258
+// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
 // for the description of the bug (it existed in older Chrome versions as well).
 jQuery.each( {
        mouseenter: "mouseover",
@@ -5076,6 +5565,7 @@ jQuery.each( {
 } );
 
 jQuery.fn.extend( {
+
        on: function( types, selector, data, fn ) {
                return on( this, types, selector, data, fn );
        },
@@ -5122,9 +5612,15 @@ jQuery.fn.extend( {
 
 
 var
-       rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,
 
-       // Support: IE 10-11, Edge 10240+
+       /* eslint-disable max-len */
+
+       // See https://github.com/eslint/eslint/issues/3229
+       rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
+
+       /* eslint-enable */
+
+       // Support: IE <=10 - 11, Edge 12 - 13
        // In IE/Edge using regex groups here causes severe slowdowns.
        // See https://connect.microsoft.com/IE/feedback/details/1736512/
        rnoInnerhtml = /<script|<style|<link/i,
@@ -5134,14 +5630,15 @@ var
        rscriptTypeMasked = /^true\/(.*)/,
        rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
 
-// Manipulating tables requires a tbody
+// Prefer a tbody over its parent table for containing new rows
 function manipulationTarget( elem, content ) {
-       return jQuery.nodeName( elem, "table" ) &&
-               jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
+       if ( nodeName( elem, "table" ) &&
+               nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
 
-               elem.getElementsByTagName( "tbody" )[ 0 ] ||
-                       elem.appendChild( elem.ownerDocument.createElement( "tbody" ) ) :
-               elem;
+               return jQuery( ">tbody", elem )[ 0 ] || elem;
+       }
+
+       return elem;
 }
 
 // Replace/restore the type attribute of script elements for safe DOM manipulation
@@ -5259,7 +5756,7 @@ function domManip( collection, args, callback, ignored ) {
                                        // Keep references to cloned scripts for later restoration
                                        if ( hasScripts ) {
 
-                                               // Support: Android<4.1, PhantomJS<2
+                                               // Support: Android <=4.0 only, PhantomJS 1 only
                                                // push.apply(_, arraylike) throws on ancient WebKit
                                                jQuery.merge( scripts, getAll( node, "script" ) );
                                        }
@@ -5288,7 +5785,7 @@ function domManip( collection, args, callback, ignored ) {
                                                                jQuery._evalUrl( node.src );
                                                        }
                                                } else {
-                                                       jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) );
+                                                       DOMEval( node.textContent.replace( rcleanScript, "" ), doc );
                                                }
                                        }
                                }
@@ -5334,7 +5831,7 @@ jQuery.extend( {
                if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
                                !jQuery.isXMLDoc( elem ) ) {
 
-                       // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
+                       // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
                        destElements = getAll( clone );
                        srcElements = getAll( elem );
 
@@ -5387,13 +5884,13 @@ jQuery.extend( {
                                                }
                                        }
 
-                                       // Support: Chrome <= 35-45+
+                                       // Support: Chrome <=35 - 45+
                                        // Assign undefined instead of using delete, see Data#remove
                                        elem[ dataPriv.expando ] = undefined;
                                }
                                if ( elem[ dataUser.expando ] ) {
 
-                                       // Support: Chrome <= 35-45+
+                                       // Support: Chrome <=35 - 45+
                                        // Assign undefined instead of using delete, see Data#remove
                                        elem[ dataUser.expando ] = undefined;
                                }
@@ -5403,10 +5900,6 @@ jQuery.extend( {
 } );
 
 jQuery.fn.extend( {
-
-       // Keep domManip exposed until 3.0 (gh-2225)
-       domManip: domManip,
-
        detach: function( selector ) {
                return remove( this, selector, true );
        },
@@ -5564,86 +6057,21 @@ jQuery.each( {
                        elems = i === last ? this : this.clone( true );
                        jQuery( insert[ i ] )[ original ]( elems );
 
-                       // Support: QtWebKit
-                       // .get() because push.apply(_, arraylike) throws
+                       // Support: Android <=4.0 only, PhantomJS 1 only
+                       // .get() because push.apply(_, arraylike) throws on ancient WebKit
                        push.apply( ret, elems.get() );
                }
 
                return this.pushStack( ret );
        };
 } );
-
-
-var iframe,
-       elemdisplay = {
-
-               // Support: Firefox
-               // We have to pre-define these values for FF (#10227)
-               HTML: "block",
-               BODY: "block"
-       };
-
-/**
- * Retrieve the actual display of a element
- * @param {String} name nodeName of the element
- * @param {Object} doc Document object
- */
-
-// Called only from within defaultDisplay
-function actualDisplay( name, doc ) {
-       var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
-
-               display = jQuery.css( elem[ 0 ], "display" );
-
-       // We don't have any data stored on the element,
-       // so use "detach" method as fast way to get rid of the element
-       elem.detach();
-
-       return display;
-}
-
-/**
- * Try to determine the default display value of an element
- * @param {String} nodeName
- */
-function defaultDisplay( nodeName ) {
-       var doc = document,
-               display = elemdisplay[ nodeName ];
-
-       if ( !display ) {
-               display = actualDisplay( nodeName, doc );
-
-               // If the simple way fails, read from inside an iframe
-               if ( display === "none" || !display ) {
-
-                       // Use the already-created iframe if possible
-                       iframe = ( iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" ) )
-                               .appendTo( doc.documentElement );
-
-                       // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
-                       doc = iframe[ 0 ].contentDocument;
-
-                       // Support: IE
-                       doc.write();
-                       doc.close();
-
-                       display = actualDisplay( nodeName, doc );
-                       iframe.detach();
-               }
-
-               // Store the correct default display
-               elemdisplay[ nodeName ] = display;
-       }
-
-       return display;
-}
 var rmargin = ( /^margin/ );
 
 var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
 
 var getStyles = function( elem ) {
 
-               // Support: IE<=11+, Firefox<=30+ (#15098, #14150)
+               // Support: IE <=11 only, Firefox <=30 (#15098, #14150)
                // IE throws on elements created in popups
                // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
                var view = elem.ownerDocument.defaultView;
@@ -5655,59 +6083,21 @@ var getStyles = function( elem ) {
                return view.getComputedStyle( elem );
        };
 
-var swap = function( elem, options, callback, args ) {
-       var ret, name,
-               old = {};
-
-       // Remember the old values, and insert the new ones
-       for ( name in options ) {
-               old[ name ] = elem.style[ name ];
-               elem.style[ name ] = options[ name ];
-       }
-
-       ret = callback.apply( elem, args || [] );
-
-       // Revert the old values
-       for ( name in options ) {
-               elem.style[ name ] = old[ name ];
-       }
-
-       return ret;
-};
-
-
-var documentElement = document.documentElement;
-
 
 
 ( function() {
-       var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
-               container = document.createElement( "div" ),
-               div = document.createElement( "div" );
-
-       // Finish early in limited (non-browser) environments
-       if ( !div.style ) {
-               return;
-       }
-
-       // Support: IE9-11+
-       // Style of cloned element affects source element cloned (#8908)
-       div.style.backgroundClip = "content-box";
-       div.cloneNode( true ).style.backgroundClip = "";
-       support.clearCloneStyle = div.style.backgroundClip === "content-box";
-
-       container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
-               "padding:0;margin-top:1px;position:absolute";
-       container.appendChild( div );
 
        // Executing both pixelPosition & boxSizingReliable tests require only one layout
        // so they're executed at the same time to save the second computation.
        function computeStyleTests() {
-               div.style.cssText =
 
-                       // Support: Firefox<29, Android 2.3
-                       // Vendor-prefix box-sizing
-                       "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;" +
+               // This is a singleton, we need to execute it only once
+               if ( !div ) {
+                       return;
+               }
+
+               div.style.cssText =
+                       "box-sizing:border-box;" +
                        "position:relative;display:block;" +
                        "margin:auto;border:1px;padding:1px;" +
                        "top:1%;width:50%";
@@ -5716,6 +6106,8 @@ var documentElement = document.documentElement;
 
                var divStyle = window.getComputedStyle( div );
                pixelPositionVal = divStyle.top !== "1%";
+
+               // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
                reliableMarginLeftVal = divStyle.marginLeft === "2px";
                boxSizingReliableVal = divStyle.width === "4px";
 
@@ -5725,68 +6117,47 @@ var documentElement = document.documentElement;
                pixelMarginRightVal = divStyle.marginRight === "4px";
 
                documentElement.removeChild( container );
+
+               // Nullify the div so it wouldn't be stored in the memory and
+               // it will also be a sign that checks already performed
+               div = null;
        }
 
+       var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
+               container = document.createElement( "div" ),
+               div = document.createElement( "div" );
+
+       // Finish early in limited (non-browser) environments
+       if ( !div.style ) {
+               return;
+       }
+
+       // Support: IE <=9 - 11 only
+       // Style of cloned element affects source element cloned (#8908)
+       div.style.backgroundClip = "content-box";
+       div.cloneNode( true ).style.backgroundClip = "";
+       support.clearCloneStyle = div.style.backgroundClip === "content-box";
+
+       container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
+               "padding:0;margin-top:1px;position:absolute";
+       container.appendChild( div );
+
        jQuery.extend( support, {
                pixelPosition: function() {
-
-                       // This test is executed only once but we still do memoizing
-                       // since we can use the boxSizingReliable pre-computing.
-                       // No need to check if the test was already performed, though.
                        computeStyleTests();
                        return pixelPositionVal;
                },
                boxSizingReliable: function() {
-                       if ( boxSizingReliableVal == null ) {
-                               computeStyleTests();
-                       }
+                       computeStyleTests();
                        return boxSizingReliableVal;
                },
                pixelMarginRight: function() {
-
-                       // Support: Android 4.0-4.3
-                       // We're checking for boxSizingReliableVal here instead of pixelMarginRightVal
-                       // since that compresses better and they're computed together anyway.
-                       if ( boxSizingReliableVal == null ) {
-                               computeStyleTests();
-                       }
+                       computeStyleTests();
                        return pixelMarginRightVal;
                },
                reliableMarginLeft: function() {
-
-                       // Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37
-                       if ( boxSizingReliableVal == null ) {
-                               computeStyleTests();
-                       }
+                       computeStyleTests();
                        return reliableMarginLeftVal;
-               },
-               reliableMarginRight: function() {
-
-                       // Support: Android 2.3
-                       // Check if div with explicit width and no margin-right incorrectly
-                       // gets computed margin-right based on width of container. (#3333)
-                       // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
-                       // This support function is only executed once so no memoizing is needed.
-                       var ret,
-                               marginDiv = div.appendChild( document.createElement( "div" ) );
-
-                       // Reset CSS: box-sizing; display; margin; border; padding
-                       marginDiv.style.cssText = div.style.cssText =
-
-                               // Support: Android 2.3
-                               // Vendor-prefix box-sizing
-                               "-webkit-box-sizing:content-box;box-sizing:content-box;" +
-                               "display:block;margin:0;border:0;padding:0";
-                       marginDiv.style.marginRight = marginDiv.style.width = "0";
-                       div.style.width = "1px";
-                       documentElement.appendChild( container );
-
-                       ret = !parseFloat( window.getComputedStyle( marginDiv ).marginRight );
-
-                       documentElement.removeChild( container );
-                       div.removeChild( marginDiv );
-
-                       return ret;
                }
        } );
 } )();
@@ -5794,27 +6165,30 @@ var documentElement = document.documentElement;
 
 function curCSS( elem, name, computed ) {
        var width, minWidth, maxWidth, ret,
+
+               // Support: Firefox 51+
+               // Retrieving style before computed somehow
+               // fixes an issue with getting wrong values
+               // on detached elements
                style = elem.style;
 
        computed = computed || getStyles( elem );
-       ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;
 
-       // Support: Opera 12.1x only
-       // Fall back to style even without computed
-       // computed is undefined for elems on document fragments
-       if ( ( ret === "" || ret === undefined ) && !jQuery.contains( elem.ownerDocument, elem ) ) {
-               ret = jQuery.style( elem, name );
-       }
-
-       // Support: IE9
-       // getPropertyValue is only needed for .css('filter') (#12537)
+       // getPropertyValue is needed for:
+       //   .css('filter') (IE 9 only, #12537)
+       //   .css('--customProperty) (#3144)
        if ( computed ) {
+               ret = computed.getPropertyValue( name ) || computed[ name ];
+
+               if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
+                       ret = jQuery.style( elem, name );
+               }
 
                // A tribute to the "awesome hack by Dean Edwards"
                // Android Browser returns percentage for some values,
                // but width seems to be reliably pixels.
                // This is against the CSSOM draft spec:
-               // http://dev.w3.org/csswg/cssom/#resolved-values
+               // https://drafts.csswg.org/cssom/#resolved-values
                if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
 
                        // Remember the original values
@@ -5835,7 +6209,7 @@ function curCSS( elem, name, computed ) {
 
        return ret !== undefined ?
 
-               // Support: IE9-11+
+               // Support: IE <=9 - 11 only
                // IE returns zIndex value as an integer.
                ret + "" :
                ret;
@@ -5868,14 +6242,14 @@ var
        // except "table", "table-cell", or "table-caption"
        // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
        rdisplayswap = /^(none|table(?!-c[ea]).+)/,
-
+       rcustomProp = /^--/,
        cssShow = { position: "absolute", visibility: "hidden", display: "block" },
        cssNormalTransform = {
                letterSpacing: "0",
                fontWeight: "400"
        },
 
-       cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
+       cssPrefixes = [ "Webkit", "Moz", "ms" ],
        emptyStyle = document.createElement( "div" ).style;
 
 // Return a css property mapped to a potentially vendor prefixed property
@@ -5898,6 +6272,16 @@ function vendorPropName( name ) {
        }
 }
 
+// Return a property mapped along what jQuery.cssProps suggests or to
+// a vendor prefixed property.
+function finalPropName( name ) {
+       var ret = jQuery.cssProps[ name ];
+       if ( !ret ) {
+               ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name;
+       }
+       return ret;
+}
+
 function setPositiveNumber( elem, value, subtract ) {
 
        // Any relative (+/-) values have already been
@@ -5911,15 +6295,17 @@ function setPositiveNumber( elem, value, subtract ) {
 }
 
 function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
-       var i = extra === ( isBorderBox ? "border" : "content" ) ?
-
-               // If we already have the right measurement, avoid augmentation
-               4 :
+       var i,
+               val = 0;
 
-               // Otherwise initialize for horizontal or vertical properties
-               name === "width" ? 1 : 0,
+       // If we already have the right measurement, avoid augmentation
+       if ( extra === ( isBorderBox ? "border" : "content" ) ) {
+               i = 4;
 
-               val = 0;
+       // Otherwise initialize for horizontal or vertical properties
+       } else {
+               i = name === "width" ? 1 : 0;
+       }
 
        for ( ; i < 4; i += 2 ) {
 
@@ -5956,107 +6342,41 @@ function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
 
 function getWidthOrHeight( elem, name, extra ) {
 
-       // Start with offset property, which is equivalent to the border-box value
-       var valueIsBorderBox = true,
-               val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
+       // Start with computed style
+       var valueIsBorderBox,
                styles = getStyles( elem ),
+               val = curCSS( elem, name, styles ),
                isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
 
-       // Some non-html elements return undefined for offsetWidth, so check for null/undefined
-       // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
-       // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
-       if ( val <= 0 || val == null ) {
-
-               // Fall back to computed then uncomputed css if necessary
-               val = curCSS( elem, name, styles );
-               if ( val < 0 || val == null ) {
-                       val = elem.style[ name ];
-               }
-
-               // Computed unit is not pixels. Stop here and return.
-               if ( rnumnonpx.test( val ) ) {
-                       return val;
-               }
-
-               // Check for style in case a browser which returns unreliable values
-               // for getComputedStyle silently falls back to the reliable elem.style
-               valueIsBorderBox = isBorderBox &&
-                       ( support.boxSizingReliable() || val === elem.style[ name ] );
-
-               // Normalize "", auto, and prepare for extra
-               val = parseFloat( val ) || 0;
-       }
-
-       // Use the active box-sizing model to add/subtract irrelevant styles
-       return ( val +
-               augmentWidthOrHeight(
-                       elem,
-                       name,
-                       extra || ( isBorderBox ? "border" : "content" ),
-                       valueIsBorderBox,
-                       styles
-               )
-       ) + "px";
-}
-
-function showHide( elements, show ) {
-       var display, elem, hidden,
-               values = [],
-               index = 0,
-               length = elements.length;
-
-       for ( ; index < length; index++ ) {
-               elem = elements[ index ];
-               if ( !elem.style ) {
-                       continue;
-               }
-
-               values[ index ] = dataPriv.get( elem, "olddisplay" );
-               display = elem.style.display;
-               if ( show ) {
-
-                       // Reset the inline display of this element to learn if it is
-                       // being hidden by cascaded rules or not
-                       if ( !values[ index ] && display === "none" ) {
-                               elem.style.display = "";
-                       }
-
-                       // Set elements which have been overridden with display: none
-                       // in a stylesheet to whatever the default browser style is
-                       // for such an element
-                       if ( elem.style.display === "" && isHidden( elem ) ) {
-                               values[ index ] = dataPriv.access(
-                                       elem,
-                                       "olddisplay",
-                                       defaultDisplay( elem.nodeName )
-                               );
-                       }
-               } else {
-                       hidden = isHidden( elem );
-
-                       if ( display !== "none" || !hidden ) {
-                               dataPriv.set(
-                                       elem,
-                                       "olddisplay",
-                                       hidden ? display : jQuery.css( elem, "display" )
-                               );
-                       }
-               }
+       // Computed unit is not pixels. Stop here and return.
+       if ( rnumnonpx.test( val ) ) {
+               return val;
        }
 
-       // Set the display of most of the elements in a second loop
-       // to avoid the constant reflow
-       for ( index = 0; index < length; index++ ) {
-               elem = elements[ index ];
-               if ( !elem.style ) {
-                       continue;
-               }
-               if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
-                       elem.style.display = show ? values[ index ] || "" : "none";
-               }
+       // Check for style in case a browser which returns unreliable values
+       // for getComputedStyle silently falls back to the reliable elem.style
+       valueIsBorderBox = isBorderBox &&
+               ( support.boxSizingReliable() || val === elem.style[ name ] );
+
+       // Fall back to offsetWidth/Height when value is "auto"
+       // This happens for inline elements with no explicit setting (gh-3571)
+       if ( val === "auto" ) {
+               val = elem[ "offset" + name[ 0 ].toUpperCase() + name.slice( 1 ) ];
        }
 
-       return elements;
+       // Normalize "", auto, and prepare for extra
+       val = parseFloat( val ) || 0;
+
+       // Use the active box-sizing model to add/subtract irrelevant styles
+       return ( val +
+               augmentWidthOrHeight(
+                       elem,
+                       name,
+                       extra || ( isBorderBox ? "border" : "content" ),
+                       valueIsBorderBox,
+                       styles
+               )
+       ) + "px";
 }
 
 jQuery.extend( {
@@ -6110,10 +6430,15 @@ jQuery.extend( {
                // Make sure that we're working with the right name
                var ret, type, hooks,
                        origName = jQuery.camelCase( name ),
+                       isCustomProp = rcustomProp.test( name ),
                        style = elem.style;
 
-               name = jQuery.cssProps[ origName ] ||
-                       ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
+               // Make sure that we're working with the right name. We don't
+               // want to query the value if it is a CSS custom property
+               // since they are user-defined.
+               if ( !isCustomProp ) {
+                       name = finalPropName( origName );
+               }
 
                // Gets hook for the prefixed version, then unprefixed version
                hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
@@ -6140,7 +6465,6 @@ jQuery.extend( {
                                value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
                        }
 
-                       // Support: IE9-11+
                        // background-* props affect original clone's values
                        if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
                                style[ name ] = "inherit";
@@ -6150,7 +6474,11 @@ jQuery.extend( {
                        if ( !hooks || !( "set" in hooks ) ||
                                ( value = hooks.set( elem, value, extra ) ) !== undefined ) {
 
-                               style[ name ] = value;
+                               if ( isCustomProp ) {
+                                       style.setProperty( name, value );
+                               } else {
+                                       style[ name ] = value;
+                               }
                        }
 
                } else {
@@ -6169,11 +6497,15 @@ jQuery.extend( {
 
        css: function( elem, name, extra, styles ) {
                var val, num, hooks,
-                       origName = jQuery.camelCase( name );
+                       origName = jQuery.camelCase( name ),
+                       isCustomProp = rcustomProp.test( name );
 
-               // Make sure that we're working with the right name
-               name = jQuery.cssProps[ origName ] ||
-                       ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
+               // Make sure that we're working with the right name. We don't
+               // want to modify the value if it is a CSS custom property
+               // since they are user-defined.
+               if ( !isCustomProp ) {
+                       name = finalPropName( origName );
+               }
 
                // Try prefixed name followed by the unprefixed name
                hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
@@ -6198,6 +6530,7 @@ jQuery.extend( {
                        num = parseFloat( val );
                        return extra === true || isFinite( num ) ? num || 0 : val;
                }
+
                return val;
        }
 } );
@@ -6210,7 +6543,14 @@ jQuery.each( [ "height", "width" ], function( i, name ) {
                                // Certain elements can have dimension info if we invisibly show them
                                // but it must have a current display style that would benefit
                                return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
-                                       elem.offsetWidth === 0 ?
+
+                                       // Support: Safari 8+
+                                       // Table columns in Safari have non-zero offsetWidth & zero
+                                       // getBoundingClientRect().width unless display is changed.
+                                       // Support: IE <=11 only
+                                       // Running getBoundingClientRect on a disconnected node
+                                       // in IE throws an error.
+                                       ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
                                                swap( elem, cssShow, function() {
                                                        return getWidthOrHeight( elem, name, extra );
                                                } ) :
@@ -6255,16 +6595,6 @@ jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
        }
 );
 
-// Support: Android 2.3
-jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
-       function( elem, computed ) {
-               if ( computed ) {
-                       return swap( elem, { "display": "inline-block" },
-                               curCSS, [ elem, "marginRight" ] );
-               }
-       }
-);
-
 // These hooks are used by animate to expand properties
 jQuery.each( {
        margin: "",
@@ -6300,7 +6630,7 @@ jQuery.fn.extend( {
                                map = {},
                                i = 0;
 
-                       if ( jQuery.isArray( name ) ) {
+                       if ( Array.isArray( name ) ) {
                                styles = getStyles( elem );
                                len = name.length;
 
@@ -6315,25 +6645,6 @@ jQuery.fn.extend( {
                                jQuery.style( elem, name, value ) :
                                jQuery.css( elem, name );
                }, name, value, arguments.length > 1 );
-       },
-       show: function() {
-               return showHide( this, true );
-       },
-       hide: function() {
-               return showHide( this );
-       },
-       toggle: function( state ) {
-               if ( typeof state === "boolean" ) {
-                       return state ? this.show() : this.hide();
-               }
-
-               return this.each( function() {
-                       if ( isHidden( this ) ) {
-                               jQuery( this ).show();
-                       } else {
-                               jQuery( this ).hide();
-                       }
-               } );
        }
 } );
 
@@ -6428,7 +6739,7 @@ Tween.propHooks = {
        }
 };
 
-// Support: IE9
+// Support: IE <=9 only
 // Panic based approach to setting things on disconnected nodes
 Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
        set: function( tween ) {
@@ -6450,17 +6761,29 @@ jQuery.easing = {
 
 jQuery.fx = Tween.prototype.init;
 
-// Back Compat <1.8 extension point
+// Back compat <1.8 extension point
 jQuery.fx.step = {};
 
 
 
 
 var
-       fxNow, timerId,
+       fxNow, inProgress,
        rfxtypes = /^(?:toggle|show|hide)$/,
        rrun = /queueHooks$/;
 
+function schedule() {
+       if ( inProgress ) {
+               if ( document.hidden === false && window.requestAnimationFrame ) {
+                       window.requestAnimationFrame( schedule );
+               } else {
+                       window.setTimeout( schedule, jQuery.fx.interval );
+               }
+
+               jQuery.fx.tick();
+       }
+}
+
 // Animations created synchronously will run synchronously
 function createFxNow() {
        window.setTimeout( function() {
@@ -6478,7 +6801,7 @@ function genFx( type, includeWidth ) {
        // If we include width, step value is 1 to do all cssExpand values,
        // otherwise step value is 2 to skip over Left and Right
        includeWidth = includeWidth ? 1 : 0;
-       for ( ; i < 4 ; i += 2 - includeWidth ) {
+       for ( ; i < 4; i += 2 - includeWidth ) {
                which = cssExpand[ i ];
                attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
        }
@@ -6505,15 +6828,15 @@ function createTween( value, prop, animation ) {
 }
 
 function defaultPrefilter( elem, props, opts ) {
-       /* jshint validthis: true */
-       var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
+       var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
+               isBox = "width" in props || "height" in props,
                anim = this,
                orig = {},
                style = elem.style,
-               hidden = elem.nodeType && isHidden( elem ),
+               hidden = elem.nodeType && isHiddenWithinTree( elem ),
                dataShow = dataPriv.get( elem, "fxshow" );
 
-       // Handle queue: false promises
+       // Queue-skipping animations hijack the fx hooks
        if ( !opts.queue ) {
                hooks = jQuery._queueHooks( elem, "fx" );
                if ( hooks.unqueued == null ) {
@@ -6539,25 +6862,77 @@ function defaultPrefilter( elem, props, opts ) {
                } );
        }
 
-       // Height/width overflow pass
-       if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
+       // Detect show/hide animations
+       for ( prop in props ) {
+               value = props[ prop ];
+               if ( rfxtypes.test( value ) ) {
+                       delete props[ prop ];
+                       toggle = toggle || value === "toggle";
+                       if ( value === ( hidden ? "hide" : "show" ) ) {
+
+                               // Pretend to be hidden if this is a "show" and
+                               // there is still data from a stopped show/hide
+                               if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
+                                       hidden = true;
+
+                               // Ignore all other no-op show/hide data
+                               } else {
+                                       continue;
+                               }
+                       }
+                       orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
+               }
+       }
+
+       // Bail out if this is a no-op like .hide().hide()
+       propTween = !jQuery.isEmptyObject( props );
+       if ( !propTween && jQuery.isEmptyObject( orig ) ) {
+               return;
+       }
+
+       // Restrict "overflow" and "display" styles during box animations
+       if ( isBox && elem.nodeType === 1 ) {
 
-               // Make sure that nothing sneaks out
-               // Record all 3 overflow attributes because IE9-10 do not
-               // change the overflow attribute when overflowX and
-               // overflowY are set to the same value
+               // Support: IE <=9 - 11, Edge 12 - 13
+               // Record all 3 overflow attributes because IE does not infer the shorthand
+               // from identically-valued overflowX and overflowY
                opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
 
-               // Set display property to inline-block for height/width
-               // animations on inline elements that are having width/height animated
+               // Identify a display type, preferring old show/hide data over the CSS cascade
+               restoreDisplay = dataShow && dataShow.display;
+               if ( restoreDisplay == null ) {
+                       restoreDisplay = dataPriv.get( elem, "display" );
+               }
                display = jQuery.css( elem, "display" );
+               if ( display === "none" ) {
+                       if ( restoreDisplay ) {
+                               display = restoreDisplay;
+                       } else {
+
+                               // Get nonempty value(s) by temporarily forcing visibility
+                               showHide( [ elem ], true );
+                               restoreDisplay = elem.style.display || restoreDisplay;
+                               display = jQuery.css( elem, "display" );
+                               showHide( [ elem ] );
+                       }
+               }
 
-               // Test default display if display is currently "none"
-               checkDisplay = display === "none" ?
-                       dataPriv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
+               // Animate inline elements as inline-block
+               if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
+                       if ( jQuery.css( elem, "float" ) === "none" ) {
 
-               if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
-                       style.display = "inline-block";
+                               // Restore the original display value at the end of pure show/hide animations
+                               if ( !propTween ) {
+                                       anim.done( function() {
+                                               style.display = restoreDisplay;
+                                       } );
+                                       if ( restoreDisplay == null ) {
+                                               display = style.display;
+                                               restoreDisplay = display === "none" ? "" : display;
+                                       }
+                               }
+                               style.display = "inline-block";
+                       }
                }
        }
 
@@ -6570,73 +6945,56 @@ function defaultPrefilter( elem, props, opts ) {
                } );
        }
 
-       // show/hide pass
-       for ( prop in props ) {
-               value = props[ prop ];
-               if ( rfxtypes.exec( value ) ) {
-                       delete props[ prop ];
-                       toggle = toggle || value === "toggle";
-                       if ( value === ( hidden ? "hide" : "show" ) ) {
+       // Implement show/hide animations
+       propTween = false;
+       for ( prop in orig ) {
 
-                               // If there is dataShow left over from a stopped hide or show
-                               // and we are going to proceed with show, we should pretend to be hidden
-                               if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
-                                       hidden = true;
-                               } else {
-                                       continue;
+               // General show/hide setup for this element animation
+               if ( !propTween ) {
+                       if ( dataShow ) {
+                               if ( "hidden" in dataShow ) {
+                                       hidden = dataShow.hidden;
                                }
+                       } else {
+                               dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
                        }
-                       orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
 
-               // Any non-fx value stops us from restoring the original display value
-               } else {
-                       display = undefined;
-               }
-       }
+                       // Store hidden/visible for toggle so `.stop().toggle()` "reverses"
+                       if ( toggle ) {
+                               dataShow.hidden = !hidden;
+                       }
 
-       if ( !jQuery.isEmptyObject( orig ) ) {
-               if ( dataShow ) {
-                       if ( "hidden" in dataShow ) {
-                               hidden = dataShow.hidden;
+                       // Show elements before animating them
+                       if ( hidden ) {
+                               showHide( [ elem ], true );
                        }
-               } else {
-                       dataShow = dataPriv.access( elem, "fxshow", {} );
-               }
 
-               // Store state if its toggle - enables .stop().toggle() to "reverse"
-               if ( toggle ) {
-                       dataShow.hidden = !hidden;
-               }
-               if ( hidden ) {
-                       jQuery( elem ).show();
-               } else {
+                       /* eslint-disable no-loop-func */
+
                        anim.done( function() {
-                               jQuery( elem ).hide();
-                       } );
-               }
-               anim.done( function() {
-                       var prop;
 
-                       dataPriv.remove( elem, "fxshow" );
-                       for ( prop in orig ) {
-                               jQuery.style( elem, prop, orig[ prop ] );
-                       }
-               } );
-               for ( prop in orig ) {
-                       tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
+                       /* eslint-enable no-loop-func */
 
-                       if ( !( prop in dataShow ) ) {
-                               dataShow[ prop ] = tween.start;
-                               if ( hidden ) {
-                                       tween.end = tween.start;
-                                       tween.start = prop === "width" || prop === "height" ? 1 : 0;
+                               // The final step of a "hide" animation is actually hiding the element
+                               if ( !hidden ) {
+                                       showHide( [ elem ] );
                                }
-                       }
+                               dataPriv.remove( elem, "fxshow" );
+                               for ( prop in orig ) {
+                                       jQuery.style( elem, prop, orig[ prop ] );
+                               }
+                       } );
                }
 
-       // If this is a noop like .hide().hide(), restore an overwritten display value
-       } else if ( ( display === "none" ? defaultDisplay( elem.nodeName ) : display ) === "inline" ) {
-               style.display = display;
+               // Per-property setup
+               propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
+               if ( !( prop in dataShow ) ) {
+                       dataShow[ prop ] = propTween.start;
+                       if ( hidden ) {
+                               propTween.end = propTween.start;
+                               propTween.start = 0;
+                       }
+               }
        }
 }
 
@@ -6648,7 +7006,7 @@ function propFilter( props, specialEasing ) {
                name = jQuery.camelCase( index );
                easing = specialEasing[ name ];
                value = props[ index ];
-               if ( jQuery.isArray( value ) ) {
+               if ( Array.isArray( value ) ) {
                        easing = value[ 1 ];
                        value = props[ index ] = value[ 0 ];
                }
@@ -6694,25 +7052,32 @@ function Animation( elem, properties, options ) {
                        var currentTime = fxNow || createFxNow(),
                                remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
 
-                               // Support: Android 2.3
+                               // Support: Android 2.3 only
                                // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
                                temp = remaining / animation.duration || 0,
                                percent = 1 - temp,
                                index = 0,
                                length = animation.tweens.length;
 
-                       for ( ; index < length ; index++ ) {
+                       for ( ; index < length; index++ ) {
                                animation.tweens[ index ].run( percent );
                        }
 
                        deferred.notifyWith( elem, [ animation, percent, remaining ] );
 
+                       // If there's more to do, yield
                        if ( percent < 1 && length ) {
                                return remaining;
-                       } else {
-                               deferred.resolveWith( elem, [ animation ] );
-                               return false;
                        }
+
+                       // If this was an empty animation, synthesize a final progress notification
+                       if ( !length ) {
+                               deferred.notifyWith( elem, [ animation, 1, 0 ] );
+                       }
+
+                       // Resolve the animation and report its conclusion
+                       deferred.resolveWith( elem, [ animation ] );
+                       return false;
                },
                animation = deferred.promise( {
                        elem: elem,
@@ -6742,7 +7107,7 @@ function Animation( elem, properties, options ) {
                                        return this;
                                }
                                stopped = true;
-                               for ( ; index < length ; index++ ) {
+                               for ( ; index < length; index++ ) {
                                        animation.tweens[ index ].run( 1 );
                                }
 
@@ -6760,7 +7125,7 @@ function Animation( elem, properties, options ) {
 
        propFilter( props, animation.opts.specialEasing );
 
-       for ( ; index < length ; index++ ) {
+       for ( ; index < length; index++ ) {
                result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
                if ( result ) {
                        if ( jQuery.isFunction( result.stop ) ) {
@@ -6777,6 +7142,13 @@ function Animation( elem, properties, options ) {
                animation.opts.start.call( elem, animation );
        }
 
+       // Attach callbacks from options
+       animation
+               .progress( animation.opts.progress )
+               .done( animation.opts.done, animation.opts.complete )
+               .fail( animation.opts.fail )
+               .always( animation.opts.always );
+
        jQuery.fx.timer(
                jQuery.extend( tick, {
                        elem: elem,
@@ -6785,14 +7157,11 @@ function Animation( elem, properties, options ) {
                } )
        );
 
-       // attach callbacks from options
-       return animation.progress( animation.opts.progress )
-               .done( animation.opts.done, animation.opts.complete )
-               .fail( animation.opts.fail )
-               .always( animation.opts.always );
+       return animation;
 }
 
 jQuery.Animation = jQuery.extend( Animation, {
+
        tweeners: {
                "*": [ function( prop, value ) {
                        var tween = this.createTween( prop, value );
@@ -6806,14 +7175,14 @@ jQuery.Animation = jQuery.extend( Animation, {
                        callback = props;
                        props = [ "*" ];
                } else {
-                       props = props.match( rnotwhite );
+                       props = props.match( rnothtmlwhite );
                }
 
                var prop,
                        index = 0,
                        length = props.length;
 
-               for ( ; index < length ; index++ ) {
+               for ( ; index < length; index++ ) {
                        prop = props[ index ];
                        Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
                        Animation.tweeners[ prop ].unshift( callback );
@@ -6839,9 +7208,20 @@ jQuery.speed = function( speed, easing, fn ) {
                easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
        };
 
-       opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ?
-               opt.duration : opt.duration in jQuery.fx.speeds ?
-                       jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
+       // Go to the end state if fx are off
+       if ( jQuery.fx.off ) {
+               opt.duration = 0;
+
+       } else {
+               if ( typeof opt.duration !== "number" ) {
+                       if ( opt.duration in jQuery.fx.speeds ) {
+                               opt.duration = jQuery.fx.speeds[ opt.duration ];
+
+                       } else {
+                               opt.duration = jQuery.fx.speeds._default;
+                       }
+               }
+       }
 
        // Normalize opt.queue - true/undefined/null -> "fx"
        if ( opt.queue == null || opt.queue === true ) {
@@ -6868,7 +7248,7 @@ jQuery.fn.extend( {
        fadeTo: function( speed, to, easing, callback ) {
 
                // Show any hidden elements after setting opacity to 0
-               return this.filter( isHidden ).css( "opacity", 0 ).show()
+               return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
 
                        // Animate to the value specified
                        .end().animate( { opacity: to }, speed, easing, callback );
@@ -7021,7 +7401,7 @@ jQuery.fx.tick = function() {
        for ( ; i < timers.length; i++ ) {
                timer = timers[ i ];
 
-               // Checks the timer has not already been removed
+               // Run the timer and safely remove it when done (allowing for external removal)
                if ( !timer() && timers[ i ] === timer ) {
                        timers.splice( i--, 1 );
                }
@@ -7035,24 +7415,21 @@ jQuery.fx.tick = function() {
 
 jQuery.fx.timer = function( timer ) {
        jQuery.timers.push( timer );
-       if ( timer() ) {
-               jQuery.fx.start();
-       } else {
-               jQuery.timers.pop();
-       }
+       jQuery.fx.start();
 };
 
 jQuery.fx.interval = 13;
 jQuery.fx.start = function() {
-       if ( !timerId ) {
-               timerId = window.setInterval( jQuery.fx.tick, jQuery.fx.interval );
+       if ( inProgress ) {
+               return;
        }
+
+       inProgress = true;
+       schedule();
 };
 
 jQuery.fx.stop = function() {
-       window.clearInterval( timerId );
-
-       timerId = null;
+       inProgress = null;
 };
 
 jQuery.fx.speeds = {
@@ -7065,7 +7442,7 @@ jQuery.fx.speeds = {
 
 
 // Based off of the plugin by Clint Helfers, with permission.
-// http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
+// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
 jQuery.fn.delay = function( time, type ) {
        time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
        type = type || "fx";
@@ -7086,20 +7463,15 @@ jQuery.fn.delay = function( time, type ) {
 
        input.type = "checkbox";
 
-       // Support: iOS<=5.1, Android<=4.2+
+       // Support: Android <=4.3 only
        // Default value for a checkbox should be "on"
        support.checkOn = input.value !== "";
 
-       // Support: IE<=11+
+       // Support: IE <=11 only
        // Must access selectedIndex to make default options select
        support.optSelected = opt.selected;
 
-       // Support: Android<=2.3
-       // Options inside disabled selects are incorrectly marked as disabled
-       select.disabled = true;
-       support.optDisabled = !opt.disabled;
-
-       // Support: IE<=11+
+       // Support: IE <=11 only
        // An input loses its value after becoming a radio
        input = document.createElement( "input" );
        input.value = "t";
@@ -7138,11 +7510,10 @@ jQuery.extend( {
                        return jQuery.prop( elem, name, value );
                }
 
-               // All attributes are lowercase
+               // Attribute hooks are determined by the lowercase version
                // Grab necessary hook if one is defined
                if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
-                       name = name.toLowerCase();
-                       hooks = jQuery.attrHooks[ name ] ||
+                       hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
                                ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
                }
 
@@ -7175,7 +7546,7 @@ jQuery.extend( {
                type: {
                        set: function( elem, value ) {
                                if ( !support.radioValue && value === "radio" &&
-                                       jQuery.nodeName( elem, "input" ) ) {
+                                       nodeName( elem, "input" ) ) {
                                        var val = elem.value;
                                        elem.setAttribute( "type", value );
                                        if ( val ) {
@@ -7188,21 +7559,15 @@ jQuery.extend( {
        },
 
        removeAttr: function( elem, value ) {
-               var name, propName,
+               var name,
                        i = 0,
-                       attrNames = value && value.match( rnotwhite );
+
+                       // Attribute names can contain non-HTML whitespace characters
+                       // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
+                       attrNames = value && value.match( rnothtmlwhite );
 
                if ( attrNames && elem.nodeType === 1 ) {
                        while ( ( name = attrNames[ i++ ] ) ) {
-                               propName = jQuery.propFix[ name ] || name;
-
-                               // Boolean attributes get special treatment (#10870)
-                               if ( jQuery.expr.match.bool.test( name ) ) {
-
-                                       // Set corresponding property to false
-                                       elem[ propName ] = false;
-                               }
-
                                elem.removeAttribute( name );
                        }
                }
@@ -7222,20 +7587,23 @@ boolHook = {
                return name;
        }
 };
+
 jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
        var getter = attrHandle[ name ] || jQuery.find.attr;
 
        attrHandle[ name ] = function( elem, name, isXML ) {
-               var ret, handle;
+               var ret, handle,
+                       lowercaseName = name.toLowerCase();
+
                if ( !isXML ) {
 
                        // Avoid an infinite loop by temporarily removing this function from the getter
-                       handle = attrHandle[ name ];
-                       attrHandle[ name ] = ret;
+                       handle = attrHandle[ lowercaseName ];
+                       attrHandle[ lowercaseName ] = ret;
                        ret = getter( elem, name, isXML ) != null ?
-                               name.toLowerCase() :
+                               lowercaseName :
                                null;
-                       attrHandle[ name ] = handle;
+                       attrHandle[ lowercaseName ] = handle;
                }
                return ret;
        };
@@ -7296,18 +7664,26 @@ jQuery.extend( {
                tabIndex: {
                        get: function( elem ) {
 
+                               // Support: IE <=9 - 11 only
                                // elem.tabIndex doesn't always return the
                                // correct value when it hasn't been explicitly set
-                               // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+                               // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
                                // Use proper attribute retrieval(#12072)
                                var tabindex = jQuery.find.attr( elem, "tabindex" );
 
-                               return tabindex ?
-                                       parseInt( tabindex, 10 ) :
+                               if ( tabindex ) {
+                                       return parseInt( tabindex, 10 );
+                               }
+
+                               if (
                                        rfocusable.test( elem.nodeName ) ||
-                                               rclickable.test( elem.nodeName ) && elem.href ?
-                                                       0 :
-                                                       -1;
+                                       rclickable.test( elem.nodeName ) &&
+                                       elem.href
+                               ) {
+                                       return 0;
+                               }
+
+                               return -1;
                        }
                }
        },
@@ -7324,9 +7700,14 @@ jQuery.extend( {
 // on the option
 // The getter ensures a default option is selected
 // when in an optgroup
+// eslint rule "no-unused-expressions" is disabled for this code
+// since it considers such accessions noop
 if ( !support.optSelected ) {
        jQuery.propHooks.selected = {
                get: function( elem ) {
+
+                       /* eslint no-unused-expressions: "off" */
+
                        var parent = elem.parentNode;
                        if ( parent && parent.parentNode ) {
                                parent.parentNode.selectedIndex;
@@ -7334,6 +7715,9 @@ if ( !support.optSelected ) {
                        return null;
                },
                set: function( elem ) {
+
+                       /* eslint no-unused-expressions: "off" */
+
                        var parent = elem.parentNode;
                        if ( parent ) {
                                parent.selectedIndex;
@@ -7364,7 +7748,13 @@ jQuery.each( [
 
 
 
-var rclass = /[\t\r\n\f]/g;
+       // Strip and collapse whitespace according to HTML spec
+       // https://html.spec.whatwg.org/multipage/infrastructure.html#strip-and-collapse-whitespace
+       function stripAndCollapse( value ) {
+               var tokens = value.match( rnothtmlwhite ) || [];
+               return tokens.join( " " );
+       }
+
 
 function getClass( elem ) {
        return elem.getAttribute && elem.getAttribute( "class" ) || "";
@@ -7382,12 +7772,11 @@ jQuery.fn.extend( {
                }
 
                if ( typeof value === "string" && value ) {
-                       classes = value.match( rnotwhite ) || [];
+                       classes = value.match( rnothtmlwhite ) || [];
 
                        while ( ( elem = this[ i++ ] ) ) {
                                curValue = getClass( elem );
-                               cur = elem.nodeType === 1 &&
-                                       ( " " + curValue + " " ).replace( rclass, " " );
+                               cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
 
                                if ( cur ) {
                                        j = 0;
@@ -7398,7 +7787,7 @@ jQuery.fn.extend( {
                                        }
 
                                        // Only assign if different to avoid unneeded rendering.
-                                       finalValue = jQuery.trim( cur );
+                                       finalValue = stripAndCollapse( cur );
                                        if ( curValue !== finalValue ) {
                                                elem.setAttribute( "class", finalValue );
                                        }
@@ -7424,14 +7813,13 @@ jQuery.fn.extend( {
                }
 
                if ( typeof value === "string" && value ) {
-                       classes = value.match( rnotwhite ) || [];
+                       classes = value.match( rnothtmlwhite ) || [];
 
                        while ( ( elem = this[ i++ ] ) ) {
                                curValue = getClass( elem );
 
                                // This expression is here for better compressibility (see addClass)
-                               cur = elem.nodeType === 1 &&
-                                       ( " " + curValue + " " ).replace( rclass, " " );
+                               cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
 
                                if ( cur ) {
                                        j = 0;
@@ -7444,7 +7832,7 @@ jQuery.fn.extend( {
                                        }
 
                                        // Only assign if different to avoid unneeded rendering.
-                                       finalValue = jQuery.trim( cur );
+                                       finalValue = stripAndCollapse( cur );
                                        if ( curValue !== finalValue ) {
                                                elem.setAttribute( "class", finalValue );
                                        }
@@ -7479,7 +7867,7 @@ jQuery.fn.extend( {
                                // Toggle individual class names
                                i = 0;
                                self = jQuery( this );
-                               classNames = value.match( rnotwhite ) || [];
+                               classNames = value.match( rnothtmlwhite ) || [];
 
                                while ( ( className = classNames[ i++ ] ) ) {
 
@@ -7522,10 +7910,8 @@ jQuery.fn.extend( {
                className = " " + selector + " ";
                while ( ( elem = this[ i++ ] ) ) {
                        if ( elem.nodeType === 1 &&
-                               ( " " + getClass( elem ) + " " ).replace( rclass, " " )
-                                       .indexOf( className ) > -1
-                       ) {
-                               return true;
+                               ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
+                                       return true;
                        }
                }
 
@@ -7536,8 +7922,7 @@ jQuery.fn.extend( {
 
 
 
-var rreturn = /\r/g,
-       rspaces = /[\x20\t\r\n\f]+/g;
+var rreturn = /\r/g;
 
 jQuery.fn.extend( {
        val: function( value ) {
@@ -7558,13 +7943,13 @@ jQuery.fn.extend( {
 
                                ret = elem.value;
 
-                               return typeof ret === "string" ?
-
-                                       // Handle most common string cases
-                                       ret.replace( rreturn, "" ) :
+                               // Handle most common string cases
+                               if ( typeof ret === "string" ) {
+                                       return ret.replace( rreturn, "" );
+                               }
 
-                                       // Handle cases where value is null/undef or number
-                                       ret == null ? "" : ret;
+                               // Handle cases where value is null/undef or number
+                               return ret == null ? "" : ret;
                        }
 
                        return;
@@ -7592,7 +7977,7 @@ jQuery.fn.extend( {
                        } else if ( typeof val === "number" ) {
                                val += "";
 
-                       } else if ( jQuery.isArray( val ) ) {
+                       } else if ( Array.isArray( val ) ) {
                                val = jQuery.map( val, function( value ) {
                                        return value == null ? "" : value + "";
                                } );
@@ -7617,37 +8002,41 @@ jQuery.extend( {
                                return val != null ?
                                        val :
 
-                                       // Support: IE10-11+
+                                       // Support: IE <=10 - 11 only
                                        // option.text throws exceptions (#14686, #14858)
                                        // Strip and collapse whitespace
                                        // https://html.spec.whatwg.org/#strip-and-collapse-whitespace
-                                       jQuery.trim( jQuery.text( elem ) ).replace( rspaces, " " );
+                                       stripAndCollapse( jQuery.text( elem ) );
                        }
                },
                select: {
                        get: function( elem ) {
-                               var value, option,
+                               var value, option, i,
                                        options = elem.options,
                                        index = elem.selectedIndex,
-                                       one = elem.type === "select-one" || index < 0,
+                                       one = elem.type === "select-one",
                                        values = one ? null : [],
-                                       max = one ? index + 1 : options.length,
-                                       i = index < 0 ?
-                                               max :
-                                               one ? index : 0;
+                                       max = one ? index + 1 : options.length;
+
+                               if ( index < 0 ) {
+                                       i = max;
+
+                               } else {
+                                       i = one ? index : 0;
+                               }
 
                                // Loop through all the selected options
                                for ( ; i < max; i++ ) {
                                        option = options[ i ];
 
+                                       // Support: IE <=9 only
                                        // IE8-9 doesn't update selected after form reset (#2551)
                                        if ( ( option.selected || i === index ) &&
 
                                                        // Don't return options that are disabled or in a disabled optgroup
-                                                       ( support.optDisabled ?
-                                                               !option.disabled : option.getAttribute( "disabled" ) === null ) &&
+                                                       !option.disabled &&
                                                        ( !option.parentNode.disabled ||
-                                                               !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
+                                                               !nodeName( option.parentNode, "optgroup" ) ) ) {
 
                                                // Get the specific value for the option
                                                value = jQuery( option ).val();
@@ -7673,11 +8062,16 @@ jQuery.extend( {
 
                                while ( i-- ) {
                                        option = options[ i ];
+
+                                       /* eslint-disable no-cond-assign */
+
                                        if ( option.selected =
                                                jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
                                        ) {
                                                optionSet = true;
                                        }
+
+                                       /* eslint-enable no-cond-assign */
                                }
 
                                // Force browsers to behave consistently when non-matching value is set
@@ -7694,7 +8088,7 @@ jQuery.extend( {
 jQuery.each( [ "radio", "checkbox" ], function() {
        jQuery.valHooks[ this ] = {
                set: function( elem, value ) {
-                       if ( jQuery.isArray( value ) ) {
+                       if ( Array.isArray( value ) ) {
                                return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
                        }
                }
@@ -7825,7 +8219,7 @@ jQuery.extend( jQuery.event, {
                                special._default.apply( eventPath.pop(), data ) === false ) &&
                                acceptData( elem ) ) {
 
-                               // Call a native DOM method on the target with the same name name as the event.
+                               // Call a native DOM method on the target with the same name as the event.
                                // Don't do default actions on window, that's where global variables be (#6170)
                                if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
 
@@ -7884,9 +8278,9 @@ jQuery.fn.extend( {
 } );
 
 
-jQuery.each( ( "blur focus focusin focusout load resize scroll unload click dblclick " +
+jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +
        "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
-       "change select submit keydown keypress keyup error contextmenu" ).split( " " ),
+       "change select submit keydown keypress keyup contextmenu" ).split( " " ),
        function( i, name ) {
 
        // Handle event binding
@@ -7909,14 +8303,14 @@ jQuery.fn.extend( {
 support.focusin = "onfocusin" in window;
 
 
-// Support: Firefox
+// Support: Firefox <=44
 // Firefox doesn't have focus(in | out) events
 // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
 //
-// Support: Chrome, Safari
+// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
 // focus(in | out) events fire after focus & blur events,
 // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
-// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857
+// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
 if ( !support.focusin ) {
        jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
 
@@ -7930,65 +8324,179 @@ if ( !support.focusin ) {
                                var doc = this.ownerDocument || this,
                                        attaches = dataPriv.access( doc, fix );
 
-                               if ( !attaches ) {
-                                       doc.addEventListener( orig, handler, true );
-                               }
-                               dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
-                       },
-                       teardown: function() {
-                               var doc = this.ownerDocument || this,
-                                       attaches = dataPriv.access( doc, fix ) - 1;
+                               if ( !attaches ) {
+                                       doc.addEventListener( orig, handler, true );
+                               }
+                               dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
+                       },
+                       teardown: function() {
+                               var doc = this.ownerDocument || this,
+                                       attaches = dataPriv.access( doc, fix ) - 1;
+
+                               if ( !attaches ) {
+                                       doc.removeEventListener( orig, handler, true );
+                                       dataPriv.remove( doc, fix );
+
+                               } else {
+                                       dataPriv.access( doc, fix, attaches );
+                               }
+                       }
+               };
+       } );
+}
+var location = window.location;
+
+var nonce = jQuery.now();
+
+var rquery = ( /\?/ );
+
+
+
+// Cross-browser xml parsing
+jQuery.parseXML = function( data ) {
+       var xml;
+       if ( !data || typeof data !== "string" ) {
+               return null;
+       }
+
+       // Support: IE 9 - 11 only
+       // IE throws on parseFromString with invalid input.
+       try {
+               xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
+       } catch ( e ) {
+               xml = undefined;
+       }
+
+       if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
+               jQuery.error( "Invalid XML: " + data );
+       }
+       return xml;
+};
+
+
+var
+       rbracket = /\[\]$/,
+       rCRLF = /\r?\n/g,
+       rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
+       rsubmittable = /^(?:input|select|textarea|keygen)/i;
+
+function buildParams( prefix, obj, traditional, add ) {
+       var name;
+
+       if ( Array.isArray( obj ) ) {
+
+               // Serialize array item.
+               jQuery.each( obj, function( i, v ) {
+                       if ( traditional || rbracket.test( prefix ) ) {
+
+                               // Treat each array item as a scalar.
+                               add( prefix, v );
+
+                       } else {
+
+                               // Item is non-scalar (array or object), encode its numeric index.
+                               buildParams(
+                                       prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
+                                       v,
+                                       traditional,
+                                       add
+                               );
+                       }
+               } );
+
+       } else if ( !traditional && jQuery.type( obj ) === "object" ) {
+
+               // Serialize object item.
+               for ( name in obj ) {
+                       buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
+               }
+
+       } else {
+
+               // Serialize scalar item.
+               add( prefix, obj );
+       }
+}
+
+// Serialize an array of form elements or a set of
+// key/values into a query string
+jQuery.param = function( a, traditional ) {
+       var prefix,
+               s = [],
+               add = function( key, valueOrFunction ) {
 
-                               if ( !attaches ) {
-                                       doc.removeEventListener( orig, handler, true );
-                                       dataPriv.remove( doc, fix );
+                       // If value is a function, invoke it and use its return value
+                       var value = jQuery.isFunction( valueOrFunction ) ?
+                               valueOrFunction() :
+                               valueOrFunction;
 
-                               } else {
-                                       dataPriv.access( doc, fix, attaches );
-                               }
-                       }
+                       s[ s.length ] = encodeURIComponent( key ) + "=" +
+                               encodeURIComponent( value == null ? "" : value );
                };
-       } );
-}
-var location = window.location;
 
-var nonce = jQuery.now();
+       // If an array was passed in, assume that it is an array of form elements.
+       if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
 
-var rquery = ( /\?/ );
+               // Serialize the form elements
+               jQuery.each( a, function() {
+                       add( this.name, this.value );
+               } );
 
+       } else {
 
+               // If traditional, encode the "old" way (the way 1.3.2 or older
+               // did it), otherwise encode params recursively.
+               for ( prefix in a ) {
+                       buildParams( prefix, a[ prefix ], traditional, add );
+               }
+       }
 
-// Support: Android 2.3
-// Workaround failure to string-cast null input
-jQuery.parseJSON = function( data ) {
-       return JSON.parse( data + "" );
+       // Return the resulting serialization
+       return s.join( "&" );
 };
 
+jQuery.fn.extend( {
+       serialize: function() {
+               return jQuery.param( this.serializeArray() );
+       },
+       serializeArray: function() {
+               return this.map( function() {
 
-// Cross-browser xml parsing
-jQuery.parseXML = function( data ) {
-       var xml;
-       if ( !data || typeof data !== "string" ) {
-               return null;
-       }
+                       // Can add propHook for "elements" to filter or add form elements
+                       var elements = jQuery.prop( this, "elements" );
+                       return elements ? jQuery.makeArray( elements ) : this;
+               } )
+               .filter( function() {
+                       var type = this.type;
 
-       // Support: IE9
-       try {
-               xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
-       } catch ( e ) {
-               xml = undefined;
-       }
+                       // Use .is( ":disabled" ) so that fieldset[disabled] works
+                       return this.name && !jQuery( this ).is( ":disabled" ) &&
+                               rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
+                               ( this.checked || !rcheckableType.test( type ) );
+               } )
+               .map( function( i, elem ) {
+                       var val = jQuery( this ).val();
 
-       if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
-               jQuery.error( "Invalid XML: " + data );
+                       if ( val == null ) {
+                               return null;
+                       }
+
+                       if ( Array.isArray( val ) ) {
+                               return jQuery.map( val, function( val ) {
+                                       return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+                               } );
+                       }
+
+                       return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+               } ).get();
        }
-       return xml;
-};
+} );
 
 
 var
+       r20 = /%20/g,
        rhash = /#.*$/,
-       rts = /([?&])_=[^&]*/,
+       rantiCache = /([?&])_=[^&]*/,
        rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
 
        // #7653, #8125, #8152: local protocol detection
@@ -8034,7 +8542,7 @@ function addToPrefiltersOrTransports( structure ) {
 
                var dataType,
                        i = 0,
-                       dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
+                       dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
 
                if ( jQuery.isFunction( func ) ) {
 
@@ -8196,7 +8704,7 @@ function ajaxConvert( s, response, jqXHR, isSuccess ) {
 
                if ( current ) {
 
-               // There's only work to do if current dataType is non-auto
+                       // There's only work to do if current dataType is non-auto
                        if ( current === "*" ) {
 
                                current = prev;
@@ -8276,6 +8784,7 @@ jQuery.extend( {
                processData: true,
                async: true,
                contentType: "application/x-www-form-urlencoded; charset=UTF-8",
+
                /*
                timeout: 0,
                data: null,
@@ -8319,7 +8828,7 @@ jQuery.extend( {
                        "text html": true,
 
                        // Evaluate text as a json expression
-                       "text json": jQuery.parseJSON,
+                       "text json": JSON.parse,
 
                        // Parse text as xml
                        "text xml": jQuery.parseXML
@@ -8378,12 +8887,18 @@ jQuery.extend( {
                        // Url cleanup var
                        urlAnchor,
 
+                       // Request state (becomes false upon send and true upon completion)
+                       completed,
+
                        // To know if global events are to be dispatched
                        fireGlobals,
 
                        // Loop variable
                        i,
 
+                       // uncached part of the url
+                       uncached,
+
                        // Create the final options object
                        s = jQuery.ajaxSetup( {}, options ),
 
@@ -8407,9 +8922,6 @@ jQuery.extend( {
                        requestHeaders = {},
                        requestHeadersNames = {},
 
-                       // The jqXHR state
-                       state = 0,
-
                        // Default abort message
                        strAbort = "canceled",
 
@@ -8420,7 +8932,7 @@ jQuery.extend( {
                                // Builds headers hashtable if needed
                                getResponseHeader: function( key ) {
                                        var match;
-                                       if ( state === 2 ) {
+                                       if ( completed ) {
                                                if ( !responseHeaders ) {
                                                        responseHeaders = {};
                                                        while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
@@ -8434,14 +8946,14 @@ jQuery.extend( {
 
                                // Raw string
                                getAllResponseHeaders: function() {
-                                       return state === 2 ? responseHeadersString : null;
+                                       return completed ? responseHeadersString : null;
                                },
 
                                // Caches the header
                                setRequestHeader: function( name, value ) {
-                                       var lname = name.toLowerCase();
-                                       if ( !state ) {
-                                               name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
+                                       if ( completed == null ) {
+                                               name = requestHeadersNames[ name.toLowerCase() ] =
+                                                       requestHeadersNames[ name.toLowerCase() ] || name;
                                                requestHeaders[ name ] = value;
                                        }
                                        return this;
@@ -8449,7 +8961,7 @@ jQuery.extend( {
 
                                // Overrides response content-type header
                                overrideMimeType: function( type ) {
-                                       if ( !state ) {
+                                       if ( completed == null ) {
                                                s.mimeType = type;
                                        }
                                        return this;
@@ -8459,16 +8971,16 @@ jQuery.extend( {
                                statusCode: function( map ) {
                                        var code;
                                        if ( map ) {
-                                               if ( state < 2 ) {
-                                                       for ( code in map ) {
-
-                                                               // Lazy-add the new callback in a way that preserves old ones
-                                                               statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
-                                                       }
-                                               } else {
+                                               if ( completed ) {
 
                                                        // Execute the appropriate callbacks
                                                        jqXHR.always( map[ jqXHR.status ] );
+                                               } else {
+
+                                                       // Lazy-add the new callbacks in a way that preserves old ones
+                                                       for ( code in map ) {
+                                                               statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
+                                                       }
                                                }
                                        }
                                        return this;
@@ -8486,33 +8998,31 @@ jQuery.extend( {
                        };
 
                // Attach deferreds
-               deferred.promise( jqXHR ).complete = completeDeferred.add;
-               jqXHR.success = jqXHR.done;
-               jqXHR.error = jqXHR.fail;
+               deferred.promise( jqXHR );
 
-               // Remove hash character (#7531: and string promotion)
                // Add protocol if not provided (prefilters might expect it)
                // Handle falsy url in the settings object (#10093: consistency with old signature)
                // We also use the url parameter if available
-               s.url = ( ( url || s.url || location.href ) + "" ).replace( rhash, "" )
+               s.url = ( ( url || s.url || location.href ) + "" )
                        .replace( rprotocol, location.protocol + "//" );
 
                // Alias method option to type as per ticket #12004
                s.type = options.method || options.type || s.method || s.type;
 
                // Extract dataTypes list
-               s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
+               s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
 
                // A cross-domain request is in order when the origin doesn't match the current origin.
                if ( s.crossDomain == null ) {
                        urlAnchor = document.createElement( "a" );
 
-                       // Support: IE8-11+
-                       // IE throws exception if url is malformed, e.g. http://example.com:80x/
+                       // Support: IE <=8 - 11, Edge 12 - 13
+                       // IE throws exception on accessing the href property if url is malformed,
+                       // e.g. http://example.com:80x/
                        try {
                                urlAnchor.href = s.url;
 
-                               // Support: IE8-11+
+                               // Support: IE <=8 - 11 only
                                // Anchor's host property isn't correctly set when s.url is relative
                                urlAnchor.href = urlAnchor.href;
                                s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
@@ -8534,7 +9044,7 @@ jQuery.extend( {
                inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
 
                // If request was aborted inside a prefilter, stop there
-               if ( state === 2 ) {
+               if ( completed ) {
                        return jqXHR;
                }
 
@@ -8555,29 +9065,36 @@ jQuery.extend( {
 
                // Save the URL in case we're toying with the If-Modified-Since
                // and/or If-None-Match header later on
-               cacheURL = s.url;
+               // Remove hash to simplify url manipulation
+               cacheURL = s.url.replace( rhash, "" );
 
                // More options handling for requests with no content
                if ( !s.hasContent ) {
 
+                       // Remember the hash so we can put it back
+                       uncached = s.url.slice( cacheURL.length );
+
                        // If data is available, append data to url
                        if ( s.data ) {
-                               cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
+                               cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
 
                                // #9682: remove data so that it's not used in an eventual retry
                                delete s.data;
                        }
 
-                       // Add anti-cache in url if needed
+                       // Add or update anti-cache param if needed
                        if ( s.cache === false ) {
-                               s.url = rts.test( cacheURL ) ?
+                               cacheURL = cacheURL.replace( rantiCache, "$1" );
+                               uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached;
+                       }
 
-                                       // If there is already a '_' parameter, set its value
-                                       cacheURL.replace( rts, "$1_=" + nonce++ ) :
+                       // Put hash and anti-cache on the URL that will be requested (gh-1732)
+                       s.url = cacheURL + uncached;
 
-                                       // Otherwise add one to the end
-                                       cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
-                       }
+               // Change '%20' to '+' if this is encoded form body content (gh-2658)
+               } else if ( s.data && s.processData &&
+                       ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
+                       s.data = s.data.replace( r20, "+" );
                }
 
                // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
@@ -8611,7 +9128,7 @@ jQuery.extend( {
 
                // Allow custom headers/mimetypes and early abort
                if ( s.beforeSend &&
-                       ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
+                       ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
 
                        // Abort if not done already and return
                        return jqXHR.abort();
@@ -8621,9 +9138,9 @@ jQuery.extend( {
                strAbort = "abort";
 
                // Install callbacks on deferreds
-               for ( i in { success: 1, error: 1, complete: 1 } ) {
-                       jqXHR[ i ]( s[ i ] );
-               }
+               completeDeferred.add( s.complete );
+               jqXHR.done( s.success );
+               jqXHR.fail( s.error );
 
                // Get transport
                transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
@@ -8640,7 +9157,7 @@ jQuery.extend( {
                        }
 
                        // If request was aborted inside ajaxSend, stop there
-                       if ( state === 2 ) {
+                       if ( completed ) {
                                return jqXHR;
                        }
 
@@ -8652,18 +9169,17 @@ jQuery.extend( {
                        }
 
                        try {
-                               state = 1;
+                               completed = false;
                                transport.send( requestHeaders, done );
                        } catch ( e ) {
 
-                               // Propagate exception as error if not done
-                               if ( state < 2 ) {
-                                       done( -1, e );
-
-                               // Simply rethrow otherwise
-                               } else {
+                               // Rethrow post-completion exceptions
+                               if ( completed ) {
                                        throw e;
                                }
+
+                               // Propagate others as results
+                               done( -1, e );
                        }
                }
 
@@ -8672,13 +9188,12 @@ jQuery.extend( {
                        var isSuccess, success, error, response, modified,
                                statusText = nativeStatusText;
 
-                       // Called once
-                       if ( state === 2 ) {
+                       // Ignore repeat invocations
+                       if ( completed ) {
                                return;
                        }
 
-                       // State is "done" now
-                       state = 2;
+                       completed = true;
 
                        // Clear timeout if it exists
                        if ( timeoutTimer ) {
@@ -8822,6 +9337,7 @@ jQuery._evalUrl = function( url ) {
                // Make this explicit, since user can override this through ajaxSetup (#11264)
                type: "GET",
                dataType: "script",
+               cache: true,
                async: false,
                global: false,
                "throws": true
@@ -8833,13 +9349,10 @@ jQuery.fn.extend( {
        wrapAll: function( html ) {
                var wrap;
 
-               if ( jQuery.isFunction( html ) ) {
-                       return this.each( function( i ) {
-                               jQuery( this ).wrapAll( html.call( this, i ) );
-                       } );
-               }
-
                if ( this[ 0 ] ) {
+                       if ( jQuery.isFunction( html ) ) {
+                               html = html.call( this[ 0 ] );
+                       }
 
                        // The elements to wrap the target around
                        wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
@@ -8890,145 +9403,23 @@ jQuery.fn.extend( {
                } );
        },
 
-       unwrap: function() {
-               return this.parent().each( function() {
-                       if ( !jQuery.nodeName( this, "body" ) ) {
-                               jQuery( this ).replaceWith( this.childNodes );
-                       }
-               } ).end();
+       unwrap: function( selector ) {
+               this.parent( selector ).not( "body" ).each( function() {
+                       jQuery( this ).replaceWith( this.childNodes );
+               } );
+               return this;
        }
 } );
 
 
-jQuery.expr.filters.hidden = function( elem ) {
-       return !jQuery.expr.filters.visible( elem );
-};
-jQuery.expr.filters.visible = function( elem ) {
-
-       // Support: Opera <= 12.12
-       // Opera reports offsetWidths and offsetHeights less than zero on some elements
-       // Use OR instead of AND as the element is not visible if either is true
-       // See tickets #10406 and #13132
-       return elem.offsetWidth > 0 || elem.offsetHeight > 0 || elem.getClientRects().length > 0;
+jQuery.expr.pseudos.hidden = function( elem ) {
+       return !jQuery.expr.pseudos.visible( elem );
 };
-
-
-
-
-var r20 = /%20/g,
-       rbracket = /\[\]$/,
-       rCRLF = /\r?\n/g,
-       rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
-       rsubmittable = /^(?:input|select|textarea|keygen)/i;
-
-function buildParams( prefix, obj, traditional, add ) {
-       var name;
-
-       if ( jQuery.isArray( obj ) ) {
-
-               // Serialize array item.
-               jQuery.each( obj, function( i, v ) {
-                       if ( traditional || rbracket.test( prefix ) ) {
-
-                               // Treat each array item as a scalar.
-                               add( prefix, v );
-
-                       } else {
-
-                               // Item is non-scalar (array or object), encode its numeric index.
-                               buildParams(
-                                       prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
-                                       v,
-                                       traditional,
-                                       add
-                               );
-                       }
-               } );
-
-       } else if ( !traditional && jQuery.type( obj ) === "object" ) {
-
-               // Serialize object item.
-               for ( name in obj ) {
-                       buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
-               }
-
-       } else {
-
-               // Serialize scalar item.
-               add( prefix, obj );
-       }
-}
-
-// Serialize an array of form elements or a set of
-// key/values into a query string
-jQuery.param = function( a, traditional ) {
-       var prefix,
-               s = [],
-               add = function( key, value ) {
-
-                       // If value is a function, invoke it and return its value
-                       value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
-                       s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
-               };
-
-       // Set traditional to true for jQuery <= 1.3.2 behavior.
-       if ( traditional === undefined ) {
-               traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
-       }
-
-       // If an array was passed in, assume that it is an array of form elements.
-       if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
-
-               // Serialize the form elements
-               jQuery.each( a, function() {
-                       add( this.name, this.value );
-               } );
-
-       } else {
-
-               // If traditional, encode the "old" way (the way 1.3.2 or older
-               // did it), otherwise encode params recursively.
-               for ( prefix in a ) {
-                       buildParams( prefix, a[ prefix ], traditional, add );
-               }
-       }
-
-       // Return the resulting serialization
-       return s.join( "&" ).replace( r20, "+" );
+jQuery.expr.pseudos.visible = function( elem ) {
+       return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
 };
 
-jQuery.fn.extend( {
-       serialize: function() {
-               return jQuery.param( this.serializeArray() );
-       },
-       serializeArray: function() {
-               return this.map( function() {
-
-                       // Can add propHook for "elements" to filter or add form elements
-                       var elements = jQuery.prop( this, "elements" );
-                       return elements ? jQuery.makeArray( elements ) : this;
-               } )
-               .filter( function() {
-                       var type = this.type;
-
-                       // Use .is( ":disabled" ) so that fieldset[disabled] works
-                       return this.name && !jQuery( this ).is( ":disabled" ) &&
-                               rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
-                               ( this.checked || !rcheckableType.test( type ) );
-               } )
-               .map( function( i, elem ) {
-                       var val = jQuery( this ).val();
 
-                       return val == null ?
-                               null :
-                               jQuery.isArray( val ) ?
-                                       jQuery.map( val, function( val ) {
-                                               return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
-                                       } ) :
-                                       { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
-               } ).get();
-       }
-} );
 
 
 jQuery.ajaxSettings.xhr = function() {
@@ -9042,7 +9433,7 @@ var xhrSuccessStatus = {
                // File protocol always yields status code 0, assume 200
                0: 200,
 
-               // Support: IE9
+               // Support: IE <=9 only
                // #1450: sometimes IE returns 1223 when it should be 204
                1223: 204
        },
@@ -9106,7 +9497,7 @@ jQuery.ajaxTransport( function( options ) {
                                                                xhr.abort();
                                                        } else if ( type === "error" ) {
 
-                                                               // Support: IE9
+                                                               // Support: IE <=9 only
                                                                // On a manual native abort, IE9 throws
                                                                // errors on any property access that is not readyState
                                                                if ( typeof xhr.status !== "number" ) {
@@ -9124,7 +9515,7 @@ jQuery.ajaxTransport( function( options ) {
                                                                        xhrSuccessStatus[ xhr.status ] || xhr.status,
                                                                        xhr.statusText,
 
-                                                                       // Support: IE9 only
+                                                                       // Support: IE <=9 only
                                                                        // IE9 has no XHR2 but throws on binary (trac-11426)
                                                                        // For XHR2 non-text, let the caller handle it (gh-2498)
                                                                        ( xhr.responseType || "text" ) !== "text"  ||
@@ -9142,7 +9533,7 @@ jQuery.ajaxTransport( function( options ) {
                                xhr.onload = callback();
                                errorCallback = xhr.onerror = callback( "error" );
 
-                               // Support: IE9
+                               // Support: IE 9 only
                                // Use onreadystatechange to replace onabort
                                // to handle uncaught aborts
                                if ( xhr.onabort !== undefined ) {
@@ -9194,6 +9585,13 @@ jQuery.ajaxTransport( function( options ) {
 
 
 
+// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
+jQuery.ajaxPrefilter( function( s ) {
+       if ( s.crossDomain ) {
+               s.contents.script = false;
+       }
+} );
+
 // Install script dataType
 jQuery.ajaxSetup( {
        accepts: {
@@ -9353,22 +9751,53 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
 
 
 
+// Support: Safari 8 only
+// In Safari 8 documents created via document.implementation.createHTMLDocument
+// collapse sibling forms: the second one becomes a child of the first one.
+// Because of that, this security measure has to be disabled in Safari 8.
+// https://bugs.webkit.org/show_bug.cgi?id=137337
+support.createHTMLDocument = ( function() {
+       var body = document.implementation.createHTMLDocument( "" ).body;
+       body.innerHTML = "<form></form><form></form>";
+       return body.childNodes.length === 2;
+} )();
+
+
 // Argument "data" should be string of html
 // context (optional): If specified, the fragment will be created in this context,
 // defaults to document
 // keepScripts (optional): If true, will include scripts passed in the html string
 jQuery.parseHTML = function( data, context, keepScripts ) {
-       if ( !data || typeof data !== "string" ) {
-               return null;
+       if ( typeof data !== "string" ) {
+               return [];
        }
        if ( typeof context === "boolean" ) {
                keepScripts = context;
                context = false;
        }
-       context = context || document;
 
-       var parsed = rsingleTag.exec( data ),
-               scripts = !keepScripts && [];
+       var base, parsed, scripts;
+
+       if ( !context ) {
+
+               // Stop scripts or inline event handlers from being executed immediately
+               // by using document.implementation
+               if ( support.createHTMLDocument ) {
+                       context = document.implementation.createHTMLDocument( "" );
+
+                       // Set the base href for the created document
+                       // so any parsed elements with URLs
+                       // are based on the document's URL (gh-2965)
+                       base = context.createElement( "base" );
+                       base.href = document.location.href;
+                       context.head.appendChild( base );
+               } else {
+                       context = document;
+               }
+       }
+
+       parsed = rsingleTag.exec( data );
+       scripts = !keepScripts && [];
 
        // Single tag
        if ( parsed ) {
@@ -9385,23 +9814,16 @@ jQuery.parseHTML = function( data, context, keepScripts ) {
 };
 
 
-// Keep a copy of the old load method
-var _load = jQuery.fn.load;
-
 /**
  * Load a url into a page
  */
 jQuery.fn.load = function( url, params, callback ) {
-       if ( typeof url !== "string" && _load ) {
-               return _load.apply( this, arguments );
-       }
-
        var selector, type, response,
                self = this,
                off = url.indexOf( " " );
 
        if ( off > -1 ) {
-               selector = jQuery.trim( url.slice( off ) );
+               selector = stripAndCollapse( url.slice( off ) );
                url = url.slice( 0, off );
        }
 
@@ -9475,7 +9897,7 @@ jQuery.each( [
 
 
 
-jQuery.expr.filters.animated = function( elem ) {
+jQuery.expr.pseudos.animated = function( elem ) {
        return jQuery.grep( jQuery.timers, function( fn ) {
                return elem === fn.elem;
        } ).length;
@@ -9484,13 +9906,6 @@ jQuery.expr.filters.animated = function( elem ) {
 
 
 
-/**
- * Gets a window from an element
- */
-function getWindow( elem ) {
-       return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
-}
-
 jQuery.offset = {
        setOffset: function( elem, options, i ) {
                var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
@@ -9545,6 +9960,8 @@ jQuery.offset = {
 
 jQuery.fn.extend( {
        offset: function( options ) {
+
+               // Preserve chaining for setter
                if ( arguments.length ) {
                        return options === undefined ?
                                this :
@@ -9553,27 +9970,30 @@ jQuery.fn.extend( {
                                } );
                }
 
-               var docElem, win,
-                       elem = this[ 0 ],
-                       box = { top: 0, left: 0 },
-                       doc = elem && elem.ownerDocument;
+               var doc, docElem, rect, win,
+                       elem = this[ 0 ];
 
-               if ( !doc ) {
+               if ( !elem ) {
                        return;
                }
 
-               docElem = doc.documentElement;
-
-               // Make sure it's not a disconnected DOM node
-               if ( !jQuery.contains( docElem, elem ) ) {
-                       return box;
+               // Return zeros for disconnected and hidden (display: none) elements (gh-2310)
+               // Support: IE <=11 only
+               // Running getBoundingClientRect on a
+               // disconnected node in IE throws an error
+               if ( !elem.getClientRects().length ) {
+                       return { top: 0, left: 0 };
                }
 
-               box = elem.getBoundingClientRect();
-               win = getWindow( doc );
+               rect = elem.getBoundingClientRect();
+
+               doc = elem.ownerDocument;
+               docElem = doc.documentElement;
+               win = doc.defaultView;
+
                return {
-                       top: box.top + win.pageYOffset - docElem.clientTop,
-                       left: box.left + win.pageXOffset - docElem.clientLeft
+                       top: rect.top + win.pageYOffset - docElem.clientTop,
+                       left: rect.left + win.pageXOffset - docElem.clientLeft
                };
        },
 
@@ -9600,13 +10020,15 @@ jQuery.fn.extend( {
 
                        // Get correct offsets
                        offset = this.offset();
-                       if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
+                       if ( !nodeName( offsetParent[ 0 ], "html" ) ) {
                                parentOffset = offsetParent.offset();
                        }
 
                        // Add offsetParent borders
-                       parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
-                       parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
+                       parentOffset = {
+                               top: parentOffset.top + jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ),
+                               left: parentOffset.left + jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true )
+                       };
                }
 
                // Subtract parent offsets and element margins
@@ -9645,7 +10067,14 @@ jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function(
 
        jQuery.fn[ method ] = function( val ) {
                return access( this, function( elem, method, val ) {
-                       var win = getWindow( elem );
+
+                       // Coalesce documents and windows
+                       var win;
+                       if ( jQuery.isWindow( elem ) ) {
+                               win = elem;
+                       } else if ( elem.nodeType === 9 ) {
+                               win = elem.defaultView;
+                       }
 
                        if ( val === undefined ) {
                                return win ? win[ prop ] : elem[ method ];
@@ -9664,10 +10093,10 @@ jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function(
        };
 } );
 
-// Support: Safari<7-8+, Chrome<37-44+
+// Support: Safari <=7 - 9.1, Chrome <=37 - 49
 // Add the top/left cssHooks using jQuery.fn.position
 // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
-// Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280
+// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
 // getComputedStyle returns percent when specified for top/left/bottom/right;
 // rather than make the css module depend on the offset module, just check for it here
 jQuery.each( [ "top", "left" ], function( i, prop ) {
@@ -9701,10 +10130,10 @@ jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
 
                                if ( jQuery.isWindow( elem ) ) {
 
-                                       // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
-                                       // isn't a whole lot we can do. See pull request at this URL for discussion:
-                                       // https://github.com/jquery/jquery/pull/764
-                                       return elem.document.documentElement[ "client" + name ];
+                                       // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
+                                       return funcName.indexOf( "outer" ) === 0 ?
+                                               elem[ "inner" + name ] :
+                                               elem.document.documentElement[ "client" + name ];
                                }
 
                                // Get document width or height
@@ -9727,7 +10156,7 @@ jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
 
                                        // Set width or height on the element
                                        jQuery.style( elem, type, value, extra );
-                       }, type, chainable ? margin : undefined, chainable, null );
+                       }, type, chainable ? margin : undefined, chainable );
                };
        } );
 } );
@@ -9751,13 +10180,19 @@ jQuery.fn.extend( {
                return arguments.length === 1 ?
                        this.off( selector, "**" ) :
                        this.off( types, selector || "**", fn );
-       },
-       size: function() {
-               return this.length;
        }
 } );
 
-jQuery.fn.andSelf = jQuery.fn.addBack;
+jQuery.holdReady = function( hold ) {
+       if ( hold ) {
+               jQuery.readyWait++;
+       } else {
+               jQuery.ready( true );
+       }
+};
+jQuery.isArray = Array.isArray;
+jQuery.parseJSON = JSON.parse;
+jQuery.nodeName = nodeName;
 
 
 
@@ -9783,6 +10218,7 @@ if ( typeof define === "function" && define.amd ) {
 
 
 
+
 var
 
        // Map over jQuery in case of overwrite
@@ -9810,5 +10246,8 @@ if ( !noGlobal ) {
        window.jQuery = window.$ = jQuery;
 }
 
+
+
+
 return jQuery;
-}));
+} );