github.com/mweagle/Sparta@v1.15.0/docs_source/static/external/jquery/jquery-2.2.0.js (about)

     1  /*!
     2   * jQuery JavaScript Library v2.2.0
     3   * http://jquery.com/
     4   *
     5   * Includes Sizzle.js
     6   * http://sizzlejs.com/
     7   *
     8   * Copyright jQuery Foundation and other contributors
     9   * Released under the MIT license
    10   * http://jquery.org/license
    11   *
    12   * Date: 2016-01-08T20:02Z
    13   */
    14  
    15  (function( global, factory ) {
    16  
    17  	if ( typeof module === "object" && typeof module.exports === "object" ) {
    18  		// For CommonJS and CommonJS-like environments where a proper `window`
    19  		// is present, execute the factory and get jQuery.
    20  		// For environments that do not have a `window` with a `document`
    21  		// (such as Node.js), expose a factory as module.exports.
    22  		// This accentuates the need for the creation of a real `window`.
    23  		// e.g. var jQuery = require("jquery")(window);
    24  		// See ticket #14549 for more info.
    25  		module.exports = global.document ?
    26  			factory( global, true ) :
    27  			function( w ) {
    28  				if ( !w.document ) {
    29  					throw new Error( "jQuery requires a window with a document" );
    30  				}
    31  				return factory( w );
    32  			};
    33  	} else {
    34  		factory( global );
    35  	}
    36  
    37  // Pass this if window is not defined yet
    38  }(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
    39  
    40  // Support: Firefox 18+
    41  // Can't be in strict mode, several libs including ASP.NET trace
    42  // the stack via arguments.caller.callee and Firefox dies if
    43  // you try to trace through "use strict" call chains. (#13335)
    44  //"use strict";
    45  var arr = [];
    46  
    47  var document = window.document;
    48  
    49  var slice = arr.slice;
    50  
    51  var concat = arr.concat;
    52  
    53  var push = arr.push;
    54  
    55  var indexOf = arr.indexOf;
    56  
    57  var class2type = {};
    58  
    59  var toString = class2type.toString;
    60  
    61  var hasOwn = class2type.hasOwnProperty;
    62  
    63  var support = {};
    64  
    65  
    66  
    67  var
    68  	version = "2.2.0",
    69  
    70  	// Define a local copy of jQuery
    71  	jQuery = function( selector, context ) {
    72  
    73  		// The jQuery object is actually just the init constructor 'enhanced'
    74  		// Need init if jQuery is called (just allow error to be thrown if not included)
    75  		return new jQuery.fn.init( selector, context );
    76  	},
    77  
    78  	// Support: Android<4.1
    79  	// Make sure we trim BOM and NBSP
    80  	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
    81  
    82  	// Matches dashed string for camelizing
    83  	rmsPrefix = /^-ms-/,
    84  	rdashAlpha = /-([\da-z])/gi,
    85  
    86  	// Used by jQuery.camelCase as callback to replace()
    87  	fcamelCase = function( all, letter ) {
    88  		return letter.toUpperCase();
    89  	};
    90  
    91  jQuery.fn = jQuery.prototype = {
    92  
    93  	// The current version of jQuery being used
    94  	jquery: version,
    95  
    96  	constructor: jQuery,
    97  
    98  	// Start with an empty selector
    99  	selector: "",
   100  
   101  	// The default length of a jQuery object is 0
   102  	length: 0,
   103  
   104  	toArray: function() {
   105  		return slice.call( this );
   106  	},
   107  
   108  	// Get the Nth element in the matched element set OR
   109  	// Get the whole matched element set as a clean array
   110  	get: function( num ) {
   111  		return num != null ?
   112  
   113  			// Return just the one element from the set
   114  			( num < 0 ? this[ num + this.length ] : this[ num ] ) :
   115  
   116  			// Return all the elements in a clean array
   117  			slice.call( this );
   118  	},
   119  
   120  	// Take an array of elements and push it onto the stack
   121  	// (returning the new matched element set)
   122  	pushStack: function( elems ) {
   123  
   124  		// Build a new jQuery matched element set
   125  		var ret = jQuery.merge( this.constructor(), elems );
   126  
   127  		// Add the old object onto the stack (as a reference)
   128  		ret.prevObject = this;
   129  		ret.context = this.context;
   130  
   131  		// Return the newly-formed element set
   132  		return ret;
   133  	},
   134  
   135  	// Execute a callback for every element in the matched set.
   136  	each: function( callback ) {
   137  		return jQuery.each( this, callback );
   138  	},
   139  
   140  	map: function( callback ) {
   141  		return this.pushStack( jQuery.map( this, function( elem, i ) {
   142  			return callback.call( elem, i, elem );
   143  		} ) );
   144  	},
   145  
   146  	slice: function() {
   147  		return this.pushStack( slice.apply( this, arguments ) );
   148  	},
   149  
   150  	first: function() {
   151  		return this.eq( 0 );
   152  	},
   153  
   154  	last: function() {
   155  		return this.eq( -1 );
   156  	},
   157  
   158  	eq: function( i ) {
   159  		var len = this.length,
   160  			j = +i + ( i < 0 ? len : 0 );
   161  		return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
   162  	},
   163  
   164  	end: function() {
   165  		return this.prevObject || this.constructor();
   166  	},
   167  
   168  	// For internal use only.
   169  	// Behaves like an Array's method, not like a jQuery method.
   170  	push: push,
   171  	sort: arr.sort,
   172  	splice: arr.splice
   173  };
   174  
   175  jQuery.extend = jQuery.fn.extend = function() {
   176  	var options, name, src, copy, copyIsArray, clone,
   177  		target = arguments[ 0 ] || {},
   178  		i = 1,
   179  		length = arguments.length,
   180  		deep = false;
   181  
   182  	// Handle a deep copy situation
   183  	if ( typeof target === "boolean" ) {
   184  		deep = target;
   185  
   186  		// Skip the boolean and the target
   187  		target = arguments[ i ] || {};
   188  		i++;
   189  	}
   190  
   191  	// Handle case when target is a string or something (possible in deep copy)
   192  	if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
   193  		target = {};
   194  	}
   195  
   196  	// Extend jQuery itself if only one argument is passed
   197  	if ( i === length ) {
   198  		target = this;
   199  		i--;
   200  	}
   201  
   202  	for ( ; i < length; i++ ) {
   203  
   204  		// Only deal with non-null/undefined values
   205  		if ( ( options = arguments[ i ] ) != null ) {
   206  
   207  			// Extend the base object
   208  			for ( name in options ) {
   209  				src = target[ name ];
   210  				copy = options[ name ];
   211  
   212  				// Prevent never-ending loop
   213  				if ( target === copy ) {
   214  					continue;
   215  				}
   216  
   217  				// Recurse if we're merging plain objects or arrays
   218  				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
   219  					( copyIsArray = jQuery.isArray( copy ) ) ) ) {
   220  
   221  					if ( copyIsArray ) {
   222  						copyIsArray = false;
   223  						clone = src && jQuery.isArray( src ) ? src : [];
   224  
   225  					} else {
   226  						clone = src && jQuery.isPlainObject( src ) ? src : {};
   227  					}
   228  
   229  					// Never move original objects, clone them
   230  					target[ name ] = jQuery.extend( deep, clone, copy );
   231  
   232  				// Don't bring in undefined values
   233  				} else if ( copy !== undefined ) {
   234  					target[ name ] = copy;
   235  				}
   236  			}
   237  		}
   238  	}
   239  
   240  	// Return the modified object
   241  	return target;
   242  };
   243  
   244  jQuery.extend( {
   245  
   246  	// Unique for each copy of jQuery on the page
   247  	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
   248  
   249  	// Assume jQuery is ready without the ready module
   250  	isReady: true,
   251  
   252  	error: function( msg ) {
   253  		throw new Error( msg );
   254  	},
   255  
   256  	noop: function() {},
   257  
   258  	isFunction: function( obj ) {
   259  		return jQuery.type( obj ) === "function";
   260  	},
   261  
   262  	isArray: Array.isArray,
   263  
   264  	isWindow: function( obj ) {
   265  		return obj != null && obj === obj.window;
   266  	},
   267  
   268  	isNumeric: function( obj ) {
   269  
   270  		// parseFloat NaNs numeric-cast false positives (null|true|false|"")
   271  		// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
   272  		// subtraction forces infinities to NaN
   273  		// adding 1 corrects loss of precision from parseFloat (#15100)
   274  		var realStringObj = obj && obj.toString();
   275  		return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;
   276  	},
   277  
   278  	isPlainObject: function( obj ) {
   279  
   280  		// Not plain objects:
   281  		// - Any object or value whose internal [[Class]] property is not "[object Object]"
   282  		// - DOM nodes
   283  		// - window
   284  		if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
   285  			return false;
   286  		}
   287  
   288  		if ( obj.constructor &&
   289  				!hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
   290  			return false;
   291  		}
   292  
   293  		// If the function hasn't returned already, we're confident that
   294  		// |obj| is a plain object, created by {} or constructed with new Object
   295  		return true;
   296  	},
   297  
   298  	isEmptyObject: function( obj ) {
   299  		var name;
   300  		for ( name in obj ) {
   301  			return false;
   302  		}
   303  		return true;
   304  	},
   305  
   306  	type: function( obj ) {
   307  		if ( obj == null ) {
   308  			return obj + "";
   309  		}
   310  
   311  		// Support: Android<4.0, iOS<6 (functionish RegExp)
   312  		return typeof obj === "object" || typeof obj === "function" ?
   313  			class2type[ toString.call( obj ) ] || "object" :
   314  			typeof obj;
   315  	},
   316  
   317  	// Evaluates a script in a global context
   318  	globalEval: function( code ) {
   319  		var script,
   320  			indirect = eval;
   321  
   322  		code = jQuery.trim( code );
   323  
   324  		if ( code ) {
   325  
   326  			// If the code includes a valid, prologue position
   327  			// strict mode pragma, execute code by injecting a
   328  			// script tag into the document.
   329  			if ( code.indexOf( "use strict" ) === 1 ) {
   330  				script = document.createElement( "script" );
   331  				script.text = code;
   332  				document.head.appendChild( script ).parentNode.removeChild( script );
   333  			} else {
   334  
   335  				// Otherwise, avoid the DOM node creation, insertion
   336  				// and removal by using an indirect global eval
   337  
   338  				indirect( code );
   339  			}
   340  		}
   341  	},
   342  
   343  	// Convert dashed to camelCase; used by the css and data modules
   344  	// Support: IE9-11+
   345  	// Microsoft forgot to hump their vendor prefix (#9572)
   346  	camelCase: function( string ) {
   347  		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
   348  	},
   349  
   350  	nodeName: function( elem, name ) {
   351  		return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
   352  	},
   353  
   354  	each: function( obj, callback ) {
   355  		var length, i = 0;
   356  
   357  		if ( isArrayLike( obj ) ) {
   358  			length = obj.length;
   359  			for ( ; i < length; i++ ) {
   360  				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
   361  					break;
   362  				}
   363  			}
   364  		} else {
   365  			for ( i in obj ) {
   366  				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
   367  					break;
   368  				}
   369  			}
   370  		}
   371  
   372  		return obj;
   373  	},
   374  
   375  	// Support: Android<4.1
   376  	trim: function( text ) {
   377  		return text == null ?
   378  			"" :
   379  			( text + "" ).replace( rtrim, "" );
   380  	},
   381  
   382  	// results is for internal usage only
   383  	makeArray: function( arr, results ) {
   384  		var ret = results || [];
   385  
   386  		if ( arr != null ) {
   387  			if ( isArrayLike( Object( arr ) ) ) {
   388  				jQuery.merge( ret,
   389  					typeof arr === "string" ?
   390  					[ arr ] : arr
   391  				);
   392  			} else {
   393  				push.call( ret, arr );
   394  			}
   395  		}
   396  
   397  		return ret;
   398  	},
   399  
   400  	inArray: function( elem, arr, i ) {
   401  		return arr == null ? -1 : indexOf.call( arr, elem, i );
   402  	},
   403  
   404  	merge: function( first, second ) {
   405  		var len = +second.length,
   406  			j = 0,
   407  			i = first.length;
   408  
   409  		for ( ; j < len; j++ ) {
   410  			first[ i++ ] = second[ j ];
   411  		}
   412  
   413  		first.length = i;
   414  
   415  		return first;
   416  	},
   417  
   418  	grep: function( elems, callback, invert ) {
   419  		var callbackInverse,
   420  			matches = [],
   421  			i = 0,
   422  			length = elems.length,
   423  			callbackExpect = !invert;
   424  
   425  		// Go through the array, only saving the items
   426  		// that pass the validator function
   427  		for ( ; i < length; i++ ) {
   428  			callbackInverse = !callback( elems[ i ], i );
   429  			if ( callbackInverse !== callbackExpect ) {
   430  				matches.push( elems[ i ] );
   431  			}
   432  		}
   433  
   434  		return matches;
   435  	},
   436  
   437  	// arg is for internal usage only
   438  	map: function( elems, callback, arg ) {
   439  		var length, value,
   440  			i = 0,
   441  			ret = [];
   442  
   443  		// Go through the array, translating each of the items to their new values
   444  		if ( isArrayLike( elems ) ) {
   445  			length = elems.length;
   446  			for ( ; i < length; i++ ) {
   447  				value = callback( elems[ i ], i, arg );
   448  
   449  				if ( value != null ) {
   450  					ret.push( value );
   451  				}
   452  			}
   453  
   454  		// Go through every key on the object,
   455  		} else {
   456  			for ( i in elems ) {
   457  				value = callback( elems[ i ], i, arg );
   458  
   459  				if ( value != null ) {
   460  					ret.push( value );
   461  				}
   462  			}
   463  		}
   464  
   465  		// Flatten any nested arrays
   466  		return concat.apply( [], ret );
   467  	},
   468  
   469  	// A global GUID counter for objects
   470  	guid: 1,
   471  
   472  	// Bind a function to a context, optionally partially applying any
   473  	// arguments.
   474  	proxy: function( fn, context ) {
   475  		var tmp, args, proxy;
   476  
   477  		if ( typeof context === "string" ) {
   478  			tmp = fn[ context ];
   479  			context = fn;
   480  			fn = tmp;
   481  		}
   482  
   483  		// Quick check to determine if target is callable, in the spec
   484  		// this throws a TypeError, but we will just return undefined.
   485  		if ( !jQuery.isFunction( fn ) ) {
   486  			return undefined;
   487  		}
   488  
   489  		// Simulated bind
   490  		args = slice.call( arguments, 2 );
   491  		proxy = function() {
   492  			return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
   493  		};
   494  
   495  		// Set the guid of unique handler to the same of original handler, so it can be removed
   496  		proxy.guid = fn.guid = fn.guid || jQuery.guid++;
   497  
   498  		return proxy;
   499  	},
   500  
   501  	now: Date.now,
   502  
   503  	// jQuery.support is not used in Core but other projects attach their
   504  	// properties to it so it needs to exist.
   505  	support: support
   506  } );
   507  
   508  // JSHint would error on this code due to the Symbol not being defined in ES5.
   509  // Defining this global in .jshintrc would create a danger of using the global
   510  // unguarded in another place, it seems safer to just disable JSHint for these
   511  // three lines.
   512  /* jshint ignore: start */
   513  if ( typeof Symbol === "function" ) {
   514  	jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
   515  }
   516  /* jshint ignore: end */
   517  
   518  // Populate the class2type map
   519  jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
   520  function( i, name ) {
   521  	class2type[ "[object " + name + "]" ] = name.toLowerCase();
   522  } );
   523  
   524  function isArrayLike( obj ) {
   525  
   526  	// Support: iOS 8.2 (not reproducible in simulator)
   527  	// `in` check used to prevent JIT error (gh-2145)
   528  	// hasOwn isn't used here due to false negatives
   529  	// regarding Nodelist length in IE
   530  	var length = !!obj && "length" in obj && obj.length,
   531  		type = jQuery.type( obj );
   532  
   533  	if ( type === "function" || jQuery.isWindow( obj ) ) {
   534  		return false;
   535  	}
   536  
   537  	return type === "array" || length === 0 ||
   538  		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
   539  }
   540  var Sizzle =
   541  /*!
   542   * Sizzle CSS Selector Engine v2.2.1
   543   * http://sizzlejs.com/
   544   *
   545   * Copyright jQuery Foundation and other contributors
   546   * Released under the MIT license
   547   * http://jquery.org/license
   548   *
   549   * Date: 2015-10-17
   550   */
   551  (function( window ) {
   552  
   553  var i,
   554  	support,
   555  	Expr,
   556  	getText,
   557  	isXML,
   558  	tokenize,
   559  	compile,
   560  	select,
   561  	outermostContext,
   562  	sortInput,
   563  	hasDuplicate,
   564  
   565  	// Local document vars
   566  	setDocument,
   567  	document,
   568  	docElem,
   569  	documentIsHTML,
   570  	rbuggyQSA,
   571  	rbuggyMatches,
   572  	matches,
   573  	contains,
   574  
   575  	// Instance-specific data
   576  	expando = "sizzle" + 1 * new Date(),
   577  	preferredDoc = window.document,
   578  	dirruns = 0,
   579  	done = 0,
   580  	classCache = createCache(),
   581  	tokenCache = createCache(),
   582  	compilerCache = createCache(),
   583  	sortOrder = function( a, b ) {
   584  		if ( a === b ) {
   585  			hasDuplicate = true;
   586  		}
   587  		return 0;
   588  	},
   589  
   590  	// General-purpose constants
   591  	MAX_NEGATIVE = 1 << 31,
   592  
   593  	// Instance methods
   594  	hasOwn = ({}).hasOwnProperty,
   595  	arr = [],
   596  	pop = arr.pop,
   597  	push_native = arr.push,
   598  	push = arr.push,
   599  	slice = arr.slice,
   600  	// Use a stripped-down indexOf as it's faster than native
   601  	// http://jsperf.com/thor-indexof-vs-for/5
   602  	indexOf = function( list, elem ) {
   603  		var i = 0,
   604  			len = list.length;
   605  		for ( ; i < len; i++ ) {
   606  			if ( list[i] === elem ) {
   607  				return i;
   608  			}
   609  		}
   610  		return -1;
   611  	},
   612  
   613  	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
   614  
   615  	// Regular expressions
   616  
   617  	// http://www.w3.org/TR/css3-selectors/#whitespace
   618  	whitespace = "[\\x20\\t\\r\\n\\f]",
   619  
   620  	// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
   621  	identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
   622  
   623  	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
   624  	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
   625  		// Operator (capture 2)
   626  		"*([*^$|!~]?=)" + whitespace +
   627  		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
   628  		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
   629  		"*\\]",
   630  
   631  	pseudos = ":(" + identifier + ")(?:\\((" +
   632  		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
   633  		// 1. quoted (capture 3; capture 4 or capture 5)
   634  		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
   635  		// 2. simple (capture 6)
   636  		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
   637  		// 3. anything else (capture 2)
   638  		".*" +
   639  		")\\)|)",
   640  
   641  	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
   642  	rwhitespace = new RegExp( whitespace + "+", "g" ),
   643  	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
   644  
   645  	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
   646  	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
   647  
   648  	rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
   649  
   650  	rpseudo = new RegExp( pseudos ),
   651  	ridentifier = new RegExp( "^" + identifier + "$" ),
   652  
   653  	matchExpr = {
   654  		"ID": new RegExp( "^#(" + identifier + ")" ),
   655  		"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
   656  		"TAG": new RegExp( "^(" + identifier + "|[*])" ),
   657  		"ATTR": new RegExp( "^" + attributes ),
   658  		"PSEUDO": new RegExp( "^" + pseudos ),
   659  		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
   660  			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
   661  			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
   662  		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
   663  		// For use in libraries implementing .is()
   664  		// We use this for POS matching in `select`
   665  		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
   666  			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
   667  	},
   668  
   669  	rinputs = /^(?:input|select|textarea|button)$/i,
   670  	rheader = /^h\d$/i,
   671  
   672  	rnative = /^[^{]+\{\s*\[native \w/,
   673  
   674  	// Easily-parseable/retrievable ID or TAG or CLASS selectors
   675  	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
   676  
   677  	rsibling = /[+~]/,
   678  	rescape = /'|\\/g,
   679  
   680  	// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
   681  	runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
   682  	funescape = function( _, escaped, escapedWhitespace ) {
   683  		var high = "0x" + escaped - 0x10000;
   684  		// NaN means non-codepoint
   685  		// Support: Firefox<24
   686  		// Workaround erroneous numeric interpretation of +"0x"
   687  		return high !== high || escapedWhitespace ?
   688  			escaped :
   689  			high < 0 ?
   690  				// BMP codepoint
   691  				String.fromCharCode( high + 0x10000 ) :
   692  				// Supplemental Plane codepoint (surrogate pair)
   693  				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
   694  	},
   695  
   696  	// Used for iframes
   697  	// See setDocument()
   698  	// Removing the function wrapper causes a "Permission Denied"
   699  	// error in IE
   700  	unloadHandler = function() {
   701  		setDocument();
   702  	};
   703  
   704  // Optimize for push.apply( _, NodeList )
   705  try {
   706  	push.apply(
   707  		(arr = slice.call( preferredDoc.childNodes )),
   708  		preferredDoc.childNodes
   709  	);
   710  	// Support: Android<4.0
   711  	// Detect silently failing push.apply
   712  	arr[ preferredDoc.childNodes.length ].nodeType;
   713  } catch ( e ) {
   714  	push = { apply: arr.length ?
   715  
   716  		// Leverage slice if possible
   717  		function( target, els ) {
   718  			push_native.apply( target, slice.call(els) );
   719  		} :
   720  
   721  		// Support: IE<9
   722  		// Otherwise append directly
   723  		function( target, els ) {
   724  			var j = target.length,
   725  				i = 0;
   726  			// Can't trust NodeList.length
   727  			while ( (target[j++] = els[i++]) ) {}
   728  			target.length = j - 1;
   729  		}
   730  	};
   731  }
   732  
   733  function Sizzle( selector, context, results, seed ) {
   734  	var m, i, elem, nid, nidselect, match, groups, newSelector,
   735  		newContext = context && context.ownerDocument,
   736  
   737  		// nodeType defaults to 9, since context defaults to document
   738  		nodeType = context ? context.nodeType : 9;
   739  
   740  	results = results || [];
   741  
   742  	// Return early from calls with invalid selector or context
   743  	if ( typeof selector !== "string" || !selector ||
   744  		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
   745  
   746  		return results;
   747  	}
   748  
   749  	// Try to shortcut find operations (as opposed to filters) in HTML documents
   750  	if ( !seed ) {
   751  
   752  		if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
   753  			setDocument( context );
   754  		}
   755  		context = context || document;
   756  
   757  		if ( documentIsHTML ) {
   758  
   759  			// If the selector is sufficiently simple, try using a "get*By*" DOM method
   760  			// (excepting DocumentFragment context, where the methods don't exist)
   761  			if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
   762  
   763  				// ID selector
   764  				if ( (m = match[1]) ) {
   765  
   766  					// Document context
   767  					if ( nodeType === 9 ) {
   768  						if ( (elem = context.getElementById( m )) ) {
   769  
   770  							// Support: IE, Opera, Webkit
   771  							// TODO: identify versions
   772  							// getElementById can match elements by name instead of ID
   773  							if ( elem.id === m ) {
   774  								results.push( elem );
   775  								return results;
   776  							}
   777  						} else {
   778  							return results;
   779  						}
   780  
   781  					// Element context
   782  					} else {
   783  
   784  						// Support: IE, Opera, Webkit
   785  						// TODO: identify versions
   786  						// getElementById can match elements by name instead of ID
   787  						if ( newContext && (elem = newContext.getElementById( m )) &&
   788  							contains( context, elem ) &&
   789  							elem.id === m ) {
   790  
   791  							results.push( elem );
   792  							return results;
   793  						}
   794  					}
   795  
   796  				// Type selector
   797  				} else if ( match[2] ) {
   798  					push.apply( results, context.getElementsByTagName( selector ) );
   799  					return results;
   800  
   801  				// Class selector
   802  				} else if ( (m = match[3]) && support.getElementsByClassName &&
   803  					context.getElementsByClassName ) {
   804  
   805  					push.apply( results, context.getElementsByClassName( m ) );
   806  					return results;
   807  				}
   808  			}
   809  
   810  			// Take advantage of querySelectorAll
   811  			if ( support.qsa &&
   812  				!compilerCache[ selector + " " ] &&
   813  				(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
   814  
   815  				if ( nodeType !== 1 ) {
   816  					newContext = context;
   817  					newSelector = selector;
   818  
   819  				// qSA looks outside Element context, which is not what we want
   820  				// Thanks to Andrew Dupont for this workaround technique
   821  				// Support: IE <=8
   822  				// Exclude object elements
   823  				} else if ( context.nodeName.toLowerCase() !== "object" ) {
   824  
   825  					// Capture the context ID, setting it first if necessary
   826  					if ( (nid = context.getAttribute( "id" )) ) {
   827  						nid = nid.replace( rescape, "\\$&" );
   828  					} else {
   829  						context.setAttribute( "id", (nid = expando) );
   830  					}
   831  
   832  					// Prefix every selector in the list
   833  					groups = tokenize( selector );
   834  					i = groups.length;
   835  					nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']";
   836  					while ( i-- ) {
   837  						groups[i] = nidselect + " " + toSelector( groups[i] );
   838  					}
   839  					newSelector = groups.join( "," );
   840  
   841  					// Expand context for sibling selectors
   842  					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
   843  						context;
   844  				}
   845  
   846  				if ( newSelector ) {
   847  					try {
   848  						push.apply( results,
   849  							newContext.querySelectorAll( newSelector )
   850  						);
   851  						return results;
   852  					} catch ( qsaError ) {
   853  					} finally {
   854  						if ( nid === expando ) {
   855  							context.removeAttribute( "id" );
   856  						}
   857  					}
   858  				}
   859  			}
   860  		}
   861  	}
   862  
   863  	// All others
   864  	return select( selector.replace( rtrim, "$1" ), context, results, seed );
   865  }
   866  
   867  /**
   868   * Create key-value caches of limited size
   869   * @returns {function(string, object)} Returns the Object data after storing it on itself with
   870   *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
   871   *	deleting the oldest entry
   872   */
   873  function createCache() {
   874  	var keys = [];
   875  
   876  	function cache( key, value ) {
   877  		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
   878  		if ( keys.push( key + " " ) > Expr.cacheLength ) {
   879  			// Only keep the most recent entries
   880  			delete cache[ keys.shift() ];
   881  		}
   882  		return (cache[ key + " " ] = value);
   883  	}
   884  	return cache;
   885  }
   886  
   887  /**
   888   * Mark a function for special use by Sizzle
   889   * @param {Function} fn The function to mark
   890   */
   891  function markFunction( fn ) {
   892  	fn[ expando ] = true;
   893  	return fn;
   894  }
   895  
   896  /**
   897   * Support testing using an element
   898   * @param {Function} fn Passed the created div and expects a boolean result
   899   */
   900  function assert( fn ) {
   901  	var div = document.createElement("div");
   902  
   903  	try {
   904  		return !!fn( div );
   905  	} catch (e) {
   906  		return false;
   907  	} finally {
   908  		// Remove from its parent by default
   909  		if ( div.parentNode ) {
   910  			div.parentNode.removeChild( div );
   911  		}
   912  		// release memory in IE
   913  		div = null;
   914  	}
   915  }
   916  
   917  /**
   918   * Adds the same handler for all of the specified attrs
   919   * @param {String} attrs Pipe-separated list of attributes
   920   * @param {Function} handler The method that will be applied
   921   */
   922  function addHandle( attrs, handler ) {
   923  	var arr = attrs.split("|"),
   924  		i = arr.length;
   925  
   926  	while ( i-- ) {
   927  		Expr.attrHandle[ arr[i] ] = handler;
   928  	}
   929  }
   930  
   931  /**
   932   * Checks document order of two siblings
   933   * @param {Element} a
   934   * @param {Element} b
   935   * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
   936   */
   937  function siblingCheck( a, b ) {
   938  	var cur = b && a,
   939  		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
   940  			( ~b.sourceIndex || MAX_NEGATIVE ) -
   941  			( ~a.sourceIndex || MAX_NEGATIVE );
   942  
   943  	// Use IE sourceIndex if available on both nodes
   944  	if ( diff ) {
   945  		return diff;
   946  	}
   947  
   948  	// Check if b follows a
   949  	if ( cur ) {
   950  		while ( (cur = cur.nextSibling) ) {
   951  			if ( cur === b ) {
   952  				return -1;
   953  			}
   954  		}
   955  	}
   956  
   957  	return a ? 1 : -1;
   958  }
   959  
   960  /**
   961   * Returns a function to use in pseudos for input types
   962   * @param {String} type
   963   */
   964  function createInputPseudo( type ) {
   965  	return function( elem ) {
   966  		var name = elem.nodeName.toLowerCase();
   967  		return name === "input" && elem.type === type;
   968  	};
   969  }
   970  
   971  /**
   972   * Returns a function to use in pseudos for buttons
   973   * @param {String} type
   974   */
   975  function createButtonPseudo( type ) {
   976  	return function( elem ) {
   977  		var name = elem.nodeName.toLowerCase();
   978  		return (name === "input" || name === "button") && elem.type === type;
   979  	};
   980  }
   981  
   982  /**
   983   * Returns a function to use in pseudos for positionals
   984   * @param {Function} fn
   985   */
   986  function createPositionalPseudo( fn ) {
   987  	return markFunction(function( argument ) {
   988  		argument = +argument;
   989  		return markFunction(function( seed, matches ) {
   990  			var j,
   991  				matchIndexes = fn( [], seed.length, argument ),
   992  				i = matchIndexes.length;
   993  
   994  			// Match elements found at the specified indexes
   995  			while ( i-- ) {
   996  				if ( seed[ (j = matchIndexes[i]) ] ) {
   997  					seed[j] = !(matches[j] = seed[j]);
   998  				}
   999  			}
  1000  		});
  1001  	});
  1002  }
  1003  
  1004  /**
  1005   * Checks a node for validity as a Sizzle context
  1006   * @param {Element|Object=} context
  1007   * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
  1008   */
  1009  function testContext( context ) {
  1010  	return context && typeof context.getElementsByTagName !== "undefined" && context;
  1011  }
  1012  
  1013  // Expose support vars for convenience
  1014  support = Sizzle.support = {};
  1015  
  1016  /**
  1017   * Detects XML nodes
  1018   * @param {Element|Object} elem An element or a document
  1019   * @returns {Boolean} True iff elem is a non-HTML XML node
  1020   */
  1021  isXML = Sizzle.isXML = function( elem ) {
  1022  	// documentElement is verified for cases where it doesn't yet exist
  1023  	// (such as loading iframes in IE - #4833)
  1024  	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
  1025  	return documentElement ? documentElement.nodeName !== "HTML" : false;
  1026  };
  1027  
  1028  /**
  1029   * Sets document-related variables once based on the current document
  1030   * @param {Element|Object} [doc] An element or document object to use to set the document
  1031   * @returns {Object} Returns the current document
  1032   */
  1033  setDocument = Sizzle.setDocument = function( node ) {
  1034  	var hasCompare, parent,
  1035  		doc = node ? node.ownerDocument || node : preferredDoc;
  1036  
  1037  	// Return early if doc is invalid or already selected
  1038  	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
  1039  		return document;
  1040  	}
  1041  
  1042  	// Update global variables
  1043  	document = doc;
  1044  	docElem = document.documentElement;
  1045  	documentIsHTML = !isXML( document );
  1046  
  1047  	// Support: IE 9-11, Edge
  1048  	// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
  1049  	if ( (parent = document.defaultView) && parent.top !== parent ) {
  1050  		// Support: IE 11
  1051  		if ( parent.addEventListener ) {
  1052  			parent.addEventListener( "unload", unloadHandler, false );
  1053  
  1054  		// Support: IE 9 - 10 only
  1055  		} else if ( parent.attachEvent ) {
  1056  			parent.attachEvent( "onunload", unloadHandler );
  1057  		}
  1058  	}
  1059  
  1060  	/* Attributes
  1061  	---------------------------------------------------------------------- */
  1062  
  1063  	// Support: IE<8
  1064  	// Verify that getAttribute really returns attributes and not properties
  1065  	// (excepting IE8 booleans)
  1066  	support.attributes = assert(function( div ) {
  1067  		div.className = "i";
  1068  		return !div.getAttribute("className");
  1069  	});
  1070  
  1071  	/* getElement(s)By*
  1072  	---------------------------------------------------------------------- */
  1073  
  1074  	// Check if getElementsByTagName("*") returns only elements
  1075  	support.getElementsByTagName = assert(function( div ) {
  1076  		div.appendChild( document.createComment("") );
  1077  		return !div.getElementsByTagName("*").length;
  1078  	});
  1079  
  1080  	// Support: IE<9
  1081  	support.getElementsByClassName = rnative.test( document.getElementsByClassName );
  1082  
  1083  	// Support: IE<10
  1084  	// Check if getElementById returns elements by name
  1085  	// The broken getElementById methods don't pick up programatically-set names,
  1086  	// so use a roundabout getElementsByName test
  1087  	support.getById = assert(function( div ) {
  1088  		docElem.appendChild( div ).id = expando;
  1089  		return !document.getElementsByName || !document.getElementsByName( expando ).length;
  1090  	});
  1091  
  1092  	// ID find and filter
  1093  	if ( support.getById ) {
  1094  		Expr.find["ID"] = function( id, context ) {
  1095  			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
  1096  				var m = context.getElementById( id );
  1097  				return m ? [ m ] : [];
  1098  			}
  1099  		};
  1100  		Expr.filter["ID"] = function( id ) {
  1101  			var attrId = id.replace( runescape, funescape );
  1102  			return function( elem ) {
  1103  				return elem.getAttribute("id") === attrId;
  1104  			};
  1105  		};
  1106  	} else {
  1107  		// Support: IE6/7
  1108  		// getElementById is not reliable as a find shortcut
  1109  		delete Expr.find["ID"];
  1110  
  1111  		Expr.filter["ID"] =  function( id ) {
  1112  			var attrId = id.replace( runescape, funescape );
  1113  			return function( elem ) {
  1114  				var node = typeof elem.getAttributeNode !== "undefined" &&
  1115  					elem.getAttributeNode("id");
  1116  				return node && node.value === attrId;
  1117  			};
  1118  		};
  1119  	}
  1120  
  1121  	// Tag
  1122  	Expr.find["TAG"] = support.getElementsByTagName ?
  1123  		function( tag, context ) {
  1124  			if ( typeof context.getElementsByTagName !== "undefined" ) {
  1125  				return context.getElementsByTagName( tag );
  1126  
  1127  			// DocumentFragment nodes don't have gEBTN
  1128  			} else if ( support.qsa ) {
  1129  				return context.querySelectorAll( tag );
  1130  			}
  1131  		} :
  1132  
  1133  		function( tag, context ) {
  1134  			var elem,
  1135  				tmp = [],
  1136  				i = 0,
  1137  				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
  1138  				results = context.getElementsByTagName( tag );
  1139  
  1140  			// Filter out possible comments
  1141  			if ( tag === "*" ) {
  1142  				while ( (elem = results[i++]) ) {
  1143  					if ( elem.nodeType === 1 ) {
  1144  						tmp.push( elem );
  1145  					}
  1146  				}
  1147  
  1148  				return tmp;
  1149  			}
  1150  			return results;
  1151  		};
  1152  
  1153  	// Class
  1154  	Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
  1155  		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
  1156  			return context.getElementsByClassName( className );
  1157  		}
  1158  	};
  1159  
  1160  	/* QSA/matchesSelector
  1161  	---------------------------------------------------------------------- */
  1162  
  1163  	// QSA and matchesSelector support
  1164  
  1165  	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
  1166  	rbuggyMatches = [];
  1167  
  1168  	// qSa(:focus) reports false when true (Chrome 21)
  1169  	// We allow this because of a bug in IE8/9 that throws an error
  1170  	// whenever `document.activeElement` is accessed on an iframe
  1171  	// So, we allow :focus to pass through QSA all the time to avoid the IE error
  1172  	// See http://bugs.jquery.com/ticket/13378
  1173  	rbuggyQSA = [];
  1174  
  1175  	if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
  1176  		// Build QSA regex
  1177  		// Regex strategy adopted from Diego Perini
  1178  		assert(function( div ) {
  1179  			// Select is set to empty string on purpose
  1180  			// This is to test IE's treatment of not explicitly
  1181  			// setting a boolean content attribute,
  1182  			// since its presence should be enough
  1183  			// http://bugs.jquery.com/ticket/12359
  1184  			docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
  1185  				"<select id='" + expando + "-\r\\' msallowcapture=''>" +
  1186  				"<option selected=''></option></select>";
  1187  
  1188  			// Support: IE8, Opera 11-12.16
  1189  			// Nothing should be selected when empty strings follow ^= or $= or *=
  1190  			// The test attribute must be unknown in Opera but "safe" for WinRT
  1191  			// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
  1192  			if ( div.querySelectorAll("[msallowcapture^='']").length ) {
  1193  				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
  1194  			}
  1195  
  1196  			// Support: IE8
  1197  			// Boolean attributes and "value" are not treated correctly
  1198  			if ( !div.querySelectorAll("[selected]").length ) {
  1199  				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
  1200  			}
  1201  
  1202  			// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
  1203  			if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
  1204  				rbuggyQSA.push("~=");
  1205  			}
  1206  
  1207  			// Webkit/Opera - :checked should return selected option elements
  1208  			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
  1209  			// IE8 throws error here and will not see later tests
  1210  			if ( !div.querySelectorAll(":checked").length ) {
  1211  				rbuggyQSA.push(":checked");
  1212  			}
  1213  
  1214  			// Support: Safari 8+, iOS 8+
  1215  			// https://bugs.webkit.org/show_bug.cgi?id=136851
  1216  			// In-page `selector#id sibing-combinator selector` fails
  1217  			if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
  1218  				rbuggyQSA.push(".#.+[+~]");
  1219  			}
  1220  		});
  1221  
  1222  		assert(function( div ) {
  1223  			// Support: Windows 8 Native Apps
  1224  			// The type and name attributes are restricted during .innerHTML assignment
  1225  			var input = document.createElement("input");
  1226  			input.setAttribute( "type", "hidden" );
  1227  			div.appendChild( input ).setAttribute( "name", "D" );
  1228  
  1229  			// Support: IE8
  1230  			// Enforce case-sensitivity of name attribute
  1231  			if ( div.querySelectorAll("[name=d]").length ) {
  1232  				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
  1233  			}
  1234  
  1235  			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
  1236  			// IE8 throws error here and will not see later tests
  1237  			if ( !div.querySelectorAll(":enabled").length ) {
  1238  				rbuggyQSA.push( ":enabled", ":disabled" );
  1239  			}
  1240  
  1241  			// Opera 10-11 does not throw on post-comma invalid pseudos
  1242  			div.querySelectorAll("*,:x");
  1243  			rbuggyQSA.push(",.*:");
  1244  		});
  1245  	}
  1246  
  1247  	if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
  1248  		docElem.webkitMatchesSelector ||
  1249  		docElem.mozMatchesSelector ||
  1250  		docElem.oMatchesSelector ||
  1251  		docElem.msMatchesSelector) )) ) {
  1252  
  1253  		assert(function( div ) {
  1254  			// Check to see if it's possible to do matchesSelector
  1255  			// on a disconnected node (IE 9)
  1256  			support.disconnectedMatch = matches.call( div, "div" );
  1257  
  1258  			// This should fail with an exception
  1259  			// Gecko does not error, returns false instead
  1260  			matches.call( div, "[s!='']:x" );
  1261  			rbuggyMatches.push( "!=", pseudos );
  1262  		});
  1263  	}
  1264  
  1265  	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
  1266  	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
  1267  
  1268  	/* Contains
  1269  	---------------------------------------------------------------------- */
  1270  	hasCompare = rnative.test( docElem.compareDocumentPosition );
  1271  
  1272  	// Element contains another
  1273  	// Purposefully self-exclusive
  1274  	// As in, an element does not contain itself
  1275  	contains = hasCompare || rnative.test( docElem.contains ) ?
  1276  		function( a, b ) {
  1277  			var adown = a.nodeType === 9 ? a.documentElement : a,
  1278  				bup = b && b.parentNode;
  1279  			return a === bup || !!( bup && bup.nodeType === 1 && (
  1280  				adown.contains ?
  1281  					adown.contains( bup ) :
  1282  					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
  1283  			));
  1284  		} :
  1285  		function( a, b ) {
  1286  			if ( b ) {
  1287  				while ( (b = b.parentNode) ) {
  1288  					if ( b === a ) {
  1289  						return true;
  1290  					}
  1291  				}
  1292  			}
  1293  			return false;
  1294  		};
  1295  
  1296  	/* Sorting
  1297  	---------------------------------------------------------------------- */
  1298  
  1299  	// Document order sorting
  1300  	sortOrder = hasCompare ?
  1301  	function( a, b ) {
  1302  
  1303  		// Flag for duplicate removal
  1304  		if ( a === b ) {
  1305  			hasDuplicate = true;
  1306  			return 0;
  1307  		}
  1308  
  1309  		// Sort on method existence if only one input has compareDocumentPosition
  1310  		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
  1311  		if ( compare ) {
  1312  			return compare;
  1313  		}
  1314  
  1315  		// Calculate position if both inputs belong to the same document
  1316  		compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
  1317  			a.compareDocumentPosition( b ) :
  1318  
  1319  			// Otherwise we know they are disconnected
  1320  			1;
  1321  
  1322  		// Disconnected nodes
  1323  		if ( compare & 1 ||
  1324  			(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
  1325  
  1326  			// Choose the first element that is related to our preferred document
  1327  			if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
  1328  				return -1;
  1329  			}
  1330  			if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
  1331  				return 1;
  1332  			}
  1333  
  1334  			// Maintain original order
  1335  			return sortInput ?
  1336  				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
  1337  				0;
  1338  		}
  1339  
  1340  		return compare & 4 ? -1 : 1;
  1341  	} :
  1342  	function( a, b ) {
  1343  		// Exit early if the nodes are identical
  1344  		if ( a === b ) {
  1345  			hasDuplicate = true;
  1346  			return 0;
  1347  		}
  1348  
  1349  		var cur,
  1350  			i = 0,
  1351  			aup = a.parentNode,
  1352  			bup = b.parentNode,
  1353  			ap = [ a ],
  1354  			bp = [ b ];
  1355  
  1356  		// Parentless nodes are either documents or disconnected
  1357  		if ( !aup || !bup ) {
  1358  			return a === document ? -1 :
  1359  				b === document ? 1 :
  1360  				aup ? -1 :
  1361  				bup ? 1 :
  1362  				sortInput ?
  1363  				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
  1364  				0;
  1365  
  1366  		// If the nodes are siblings, we can do a quick check
  1367  		} else if ( aup === bup ) {
  1368  			return siblingCheck( a, b );
  1369  		}
  1370  
  1371  		// Otherwise we need full lists of their ancestors for comparison
  1372  		cur = a;
  1373  		while ( (cur = cur.parentNode) ) {
  1374  			ap.unshift( cur );
  1375  		}
  1376  		cur = b;
  1377  		while ( (cur = cur.parentNode) ) {
  1378  			bp.unshift( cur );
  1379  		}
  1380  
  1381  		// Walk down the tree looking for a discrepancy
  1382  		while ( ap[i] === bp[i] ) {
  1383  			i++;
  1384  		}
  1385  
  1386  		return i ?
  1387  			// Do a sibling check if the nodes have a common ancestor
  1388  			siblingCheck( ap[i], bp[i] ) :
  1389  
  1390  			// Otherwise nodes in our document sort first
  1391  			ap[i] === preferredDoc ? -1 :
  1392  			bp[i] === preferredDoc ? 1 :
  1393  			0;
  1394  	};
  1395  
  1396  	return document;
  1397  };
  1398  
  1399  Sizzle.matches = function( expr, elements ) {
  1400  	return Sizzle( expr, null, null, elements );
  1401  };
  1402  
  1403  Sizzle.matchesSelector = function( elem, expr ) {
  1404  	// Set document vars if needed
  1405  	if ( ( elem.ownerDocument || elem ) !== document ) {
  1406  		setDocument( elem );
  1407  	}
  1408  
  1409  	// Make sure that attribute selectors are quoted
  1410  	expr = expr.replace( rattributeQuotes, "='$1']" );
  1411  
  1412  	if ( support.matchesSelector && documentIsHTML &&
  1413  		!compilerCache[ expr + " " ] &&
  1414  		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
  1415  		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
  1416  
  1417  		try {
  1418  			var ret = matches.call( elem, expr );
  1419  
  1420  			// IE 9's matchesSelector returns false on disconnected nodes
  1421  			if ( ret || support.disconnectedMatch ||
  1422  					// As well, disconnected nodes are said to be in a document
  1423  					// fragment in IE 9
  1424  					elem.document && elem.document.nodeType !== 11 ) {
  1425  				return ret;
  1426  			}
  1427  		} catch (e) {}
  1428  	}
  1429  
  1430  	return Sizzle( expr, document, null, [ elem ] ).length > 0;
  1431  };
  1432  
  1433  Sizzle.contains = function( context, elem ) {
  1434  	// Set document vars if needed
  1435  	if ( ( context.ownerDocument || context ) !== document ) {
  1436  		setDocument( context );
  1437  	}
  1438  	return contains( context, elem );
  1439  };
  1440  
  1441  Sizzle.attr = function( elem, name ) {
  1442  	// Set document vars if needed
  1443  	if ( ( elem.ownerDocument || elem ) !== document ) {
  1444  		setDocument( elem );
  1445  	}
  1446  
  1447  	var fn = Expr.attrHandle[ name.toLowerCase() ],
  1448  		// Don't get fooled by Object.prototype properties (jQuery #13807)
  1449  		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
  1450  			fn( elem, name, !documentIsHTML ) :
  1451  			undefined;
  1452  
  1453  	return val !== undefined ?
  1454  		val :
  1455  		support.attributes || !documentIsHTML ?
  1456  			elem.getAttribute( name ) :
  1457  			(val = elem.getAttributeNode(name)) && val.specified ?
  1458  				val.value :
  1459  				null;
  1460  };
  1461  
  1462  Sizzle.error = function( msg ) {
  1463  	throw new Error( "Syntax error, unrecognized expression: " + msg );
  1464  };
  1465  
  1466  /**
  1467   * Document sorting and removing duplicates
  1468   * @param {ArrayLike} results
  1469   */
  1470  Sizzle.uniqueSort = function( results ) {
  1471  	var elem,
  1472  		duplicates = [],
  1473  		j = 0,
  1474  		i = 0;
  1475  
  1476  	// Unless we *know* we can detect duplicates, assume their presence
  1477  	hasDuplicate = !support.detectDuplicates;
  1478  	sortInput = !support.sortStable && results.slice( 0 );
  1479  	results.sort( sortOrder );
  1480  
  1481  	if ( hasDuplicate ) {
  1482  		while ( (elem = results[i++]) ) {
  1483  			if ( elem === results[ i ] ) {
  1484  				j = duplicates.push( i );
  1485  			}
  1486  		}
  1487  		while ( j-- ) {
  1488  			results.splice( duplicates[ j ], 1 );
  1489  		}
  1490  	}
  1491  
  1492  	// Clear input after sorting to release objects
  1493  	// See https://github.com/jquery/sizzle/pull/225
  1494  	sortInput = null;
  1495  
  1496  	return results;
  1497  };
  1498  
  1499  /**
  1500   * Utility function for retrieving the text value of an array of DOM nodes
  1501   * @param {Array|Element} elem
  1502   */
  1503  getText = Sizzle.getText = function( elem ) {
  1504  	var node,
  1505  		ret = "",
  1506  		i = 0,
  1507  		nodeType = elem.nodeType;
  1508  
  1509  	if ( !nodeType ) {
  1510  		// If no nodeType, this is expected to be an array
  1511  		while ( (node = elem[i++]) ) {
  1512  			// Do not traverse comment nodes
  1513  			ret += getText( node );
  1514  		}
  1515  	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
  1516  		// Use textContent for elements
  1517  		// innerText usage removed for consistency of new lines (jQuery #11153)
  1518  		if ( typeof elem.textContent === "string" ) {
  1519  			return elem.textContent;
  1520  		} else {
  1521  			// Traverse its children
  1522  			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
  1523  				ret += getText( elem );
  1524  			}
  1525  		}
  1526  	} else if ( nodeType === 3 || nodeType === 4 ) {
  1527  		return elem.nodeValue;
  1528  	}
  1529  	// Do not include comment or processing instruction nodes
  1530  
  1531  	return ret;
  1532  };
  1533  
  1534  Expr = Sizzle.selectors = {
  1535  
  1536  	// Can be adjusted by the user
  1537  	cacheLength: 50,
  1538  
  1539  	createPseudo: markFunction,
  1540  
  1541  	match: matchExpr,
  1542  
  1543  	attrHandle: {},
  1544  
  1545  	find: {},
  1546  
  1547  	relative: {
  1548  		">": { dir: "parentNode", first: true },
  1549  		" ": { dir: "parentNode" },
  1550  		"+": { dir: "previousSibling", first: true },
  1551  		"~": { dir: "previousSibling" }
  1552  	},
  1553  
  1554  	preFilter: {
  1555  		"ATTR": function( match ) {
  1556  			match[1] = match[1].replace( runescape, funescape );
  1557  
  1558  			// Move the given value to match[3] whether quoted or unquoted
  1559  			match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
  1560  
  1561  			if ( match[2] === "~=" ) {
  1562  				match[3] = " " + match[3] + " ";
  1563  			}
  1564  
  1565  			return match.slice( 0, 4 );
  1566  		},
  1567  
  1568  		"CHILD": function( match ) {
  1569  			/* matches from matchExpr["CHILD"]
  1570  				1 type (only|nth|...)
  1571  				2 what (child|of-type)
  1572  				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
  1573  				4 xn-component of xn+y argument ([+-]?\d*n|)
  1574  				5 sign of xn-component
  1575  				6 x of xn-component
  1576  				7 sign of y-component
  1577  				8 y of y-component
  1578  			*/
  1579  			match[1] = match[1].toLowerCase();
  1580  
  1581  			if ( match[1].slice( 0, 3 ) === "nth" ) {
  1582  				// nth-* requires argument
  1583  				if ( !match[3] ) {
  1584  					Sizzle.error( match[0] );
  1585  				}
  1586  
  1587  				// numeric x and y parameters for Expr.filter.CHILD
  1588  				// remember that false/true cast respectively to 0/1
  1589  				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
  1590  				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
  1591  
  1592  			// other types prohibit arguments
  1593  			} else if ( match[3] ) {
  1594  				Sizzle.error( match[0] );
  1595  			}
  1596  
  1597  			return match;
  1598  		},
  1599  
  1600  		"PSEUDO": function( match ) {
  1601  			var excess,
  1602  				unquoted = !match[6] && match[2];
  1603  
  1604  			if ( matchExpr["CHILD"].test( match[0] ) ) {
  1605  				return null;
  1606  			}
  1607  
  1608  			// Accept quoted arguments as-is
  1609  			if ( match[3] ) {
  1610  				match[2] = match[4] || match[5] || "";
  1611  
  1612  			// Strip excess characters from unquoted arguments
  1613  			} else if ( unquoted && rpseudo.test( unquoted ) &&
  1614  				// Get excess from tokenize (recursively)
  1615  				(excess = tokenize( unquoted, true )) &&
  1616  				// advance to the next closing parenthesis
  1617  				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
  1618  
  1619  				// excess is a negative index
  1620  				match[0] = match[0].slice( 0, excess );
  1621  				match[2] = unquoted.slice( 0, excess );
  1622  			}
  1623  
  1624  			// Return only captures needed by the pseudo filter method (type and argument)
  1625  			return match.slice( 0, 3 );
  1626  		}
  1627  	},
  1628  
  1629  	filter: {
  1630  
  1631  		"TAG": function( nodeNameSelector ) {
  1632  			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
  1633  			return nodeNameSelector === "*" ?
  1634  				function() { return true; } :
  1635  				function( elem ) {
  1636  					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
  1637  				};
  1638  		},
  1639  
  1640  		"CLASS": function( className ) {
  1641  			var pattern = classCache[ className + " " ];
  1642  
  1643  			return pattern ||
  1644  				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
  1645  				classCache( className, function( elem ) {
  1646  					return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
  1647  				});
  1648  		},
  1649  
  1650  		"ATTR": function( name, operator, check ) {
  1651  			return function( elem ) {
  1652  				var result = Sizzle.attr( elem, name );
  1653  
  1654  				if ( result == null ) {
  1655  					return operator === "!=";
  1656  				}
  1657  				if ( !operator ) {
  1658  					return true;
  1659  				}
  1660  
  1661  				result += "";
  1662  
  1663  				return operator === "=" ? result === check :
  1664  					operator === "!=" ? result !== check :
  1665  					operator === "^=" ? check && result.indexOf( check ) === 0 :
  1666  					operator === "*=" ? check && result.indexOf( check ) > -1 :
  1667  					operator === "$=" ? check && result.slice( -check.length ) === check :
  1668  					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
  1669  					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
  1670  					false;
  1671  			};
  1672  		},
  1673  
  1674  		"CHILD": function( type, what, argument, first, last ) {
  1675  			var simple = type.slice( 0, 3 ) !== "nth",
  1676  				forward = type.slice( -4 ) !== "last",
  1677  				ofType = what === "of-type";
  1678  
  1679  			return first === 1 && last === 0 ?
  1680  
  1681  				// Shortcut for :nth-*(n)
  1682  				function( elem ) {
  1683  					return !!elem.parentNode;
  1684  				} :
  1685  
  1686  				function( elem, context, xml ) {
  1687  					var cache, uniqueCache, outerCache, node, nodeIndex, start,
  1688  						dir = simple !== forward ? "nextSibling" : "previousSibling",
  1689  						parent = elem.parentNode,
  1690  						name = ofType && elem.nodeName.toLowerCase(),
  1691  						useCache = !xml && !ofType,
  1692  						diff = false;
  1693  
  1694  					if ( parent ) {
  1695  
  1696  						// :(first|last|only)-(child|of-type)
  1697  						if ( simple ) {
  1698  							while ( dir ) {
  1699  								node = elem;
  1700  								while ( (node = node[ dir ]) ) {
  1701  									if ( ofType ?
  1702  										node.nodeName.toLowerCase() === name :
  1703  										node.nodeType === 1 ) {
  1704  
  1705  										return false;
  1706  									}
  1707  								}
  1708  								// Reverse direction for :only-* (if we haven't yet done so)
  1709  								start = dir = type === "only" && !start && "nextSibling";
  1710  							}
  1711  							return true;
  1712  						}
  1713  
  1714  						start = [ forward ? parent.firstChild : parent.lastChild ];
  1715  
  1716  						// non-xml :nth-child(...) stores cache data on `parent`
  1717  						if ( forward && useCache ) {
  1718  
  1719  							// Seek `elem` from a previously-cached index
  1720  
  1721  							// ...in a gzip-friendly way
  1722  							node = parent;
  1723  							outerCache = node[ expando ] || (node[ expando ] = {});
  1724  
  1725  							// Support: IE <9 only
  1726  							// Defend against cloned attroperties (jQuery gh-1709)
  1727  							uniqueCache = outerCache[ node.uniqueID ] ||
  1728  								(outerCache[ node.uniqueID ] = {});
  1729  
  1730  							cache = uniqueCache[ type ] || [];
  1731  							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
  1732  							diff = nodeIndex && cache[ 2 ];
  1733  							node = nodeIndex && parent.childNodes[ nodeIndex ];
  1734  
  1735  							while ( (node = ++nodeIndex && node && node[ dir ] ||
  1736  
  1737  								// Fallback to seeking `elem` from the start
  1738  								(diff = nodeIndex = 0) || start.pop()) ) {
  1739  
  1740  								// When found, cache indexes on `parent` and break
  1741  								if ( node.nodeType === 1 && ++diff && node === elem ) {
  1742  									uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
  1743  									break;
  1744  								}
  1745  							}
  1746  
  1747  						} else {
  1748  							// Use previously-cached element index if available
  1749  							if ( useCache ) {
  1750  								// ...in a gzip-friendly way
  1751  								node = elem;
  1752  								outerCache = node[ expando ] || (node[ expando ] = {});
  1753  
  1754  								// Support: IE <9 only
  1755  								// Defend against cloned attroperties (jQuery gh-1709)
  1756  								uniqueCache = outerCache[ node.uniqueID ] ||
  1757  									(outerCache[ node.uniqueID ] = {});
  1758  
  1759  								cache = uniqueCache[ type ] || [];
  1760  								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
  1761  								diff = nodeIndex;
  1762  							}
  1763  
  1764  							// xml :nth-child(...)
  1765  							// or :nth-last-child(...) or :nth(-last)?-of-type(...)
  1766  							if ( diff === false ) {
  1767  								// Use the same loop as above to seek `elem` from the start
  1768  								while ( (node = ++nodeIndex && node && node[ dir ] ||
  1769  									(diff = nodeIndex = 0) || start.pop()) ) {
  1770  
  1771  									if ( ( ofType ?
  1772  										node.nodeName.toLowerCase() === name :
  1773  										node.nodeType === 1 ) &&
  1774  										++diff ) {
  1775  
  1776  										// Cache the index of each encountered element
  1777  										if ( useCache ) {
  1778  											outerCache = node[ expando ] || (node[ expando ] = {});
  1779  
  1780  											// Support: IE <9 only
  1781  											// Defend against cloned attroperties (jQuery gh-1709)
  1782  											uniqueCache = outerCache[ node.uniqueID ] ||
  1783  												(outerCache[ node.uniqueID ] = {});
  1784  
  1785  											uniqueCache[ type ] = [ dirruns, diff ];
  1786  										}
  1787  
  1788  										if ( node === elem ) {
  1789  											break;
  1790  										}
  1791  									}
  1792  								}
  1793  							}
  1794  						}
  1795  
  1796  						// Incorporate the offset, then check against cycle size
  1797  						diff -= last;
  1798  						return diff === first || ( diff % first === 0 && diff / first >= 0 );
  1799  					}
  1800  				};
  1801  		},
  1802  
  1803  		"PSEUDO": function( pseudo, argument ) {
  1804  			// pseudo-class names are case-insensitive
  1805  			// http://www.w3.org/TR/selectors/#pseudo-classes
  1806  			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
  1807  			// Remember that setFilters inherits from pseudos
  1808  			var args,
  1809  				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
  1810  					Sizzle.error( "unsupported pseudo: " + pseudo );
  1811  
  1812  			// The user may use createPseudo to indicate that
  1813  			// arguments are needed to create the filter function
  1814  			// just as Sizzle does
  1815  			if ( fn[ expando ] ) {
  1816  				return fn( argument );
  1817  			}
  1818  
  1819  			// But maintain support for old signatures
  1820  			if ( fn.length > 1 ) {
  1821  				args = [ pseudo, pseudo, "", argument ];
  1822  				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
  1823  					markFunction(function( seed, matches ) {
  1824  						var idx,
  1825  							matched = fn( seed, argument ),
  1826  							i = matched.length;
  1827  						while ( i-- ) {
  1828  							idx = indexOf( seed, matched[i] );
  1829  							seed[ idx ] = !( matches[ idx ] = matched[i] );
  1830  						}
  1831  					}) :
  1832  					function( elem ) {
  1833  						return fn( elem, 0, args );
  1834  					};
  1835  			}
  1836  
  1837  			return fn;
  1838  		}
  1839  	},
  1840  
  1841  	pseudos: {
  1842  		// Potentially complex pseudos
  1843  		"not": markFunction(function( selector ) {
  1844  			// Trim the selector passed to compile
  1845  			// to avoid treating leading and trailing
  1846  			// spaces as combinators
  1847  			var input = [],
  1848  				results = [],
  1849  				matcher = compile( selector.replace( rtrim, "$1" ) );
  1850  
  1851  			return matcher[ expando ] ?
  1852  				markFunction(function( seed, matches, context, xml ) {
  1853  					var elem,
  1854  						unmatched = matcher( seed, null, xml, [] ),
  1855  						i = seed.length;
  1856  
  1857  					// Match elements unmatched by `matcher`
  1858  					while ( i-- ) {
  1859  						if ( (elem = unmatched[i]) ) {
  1860  							seed[i] = !(matches[i] = elem);
  1861  						}
  1862  					}
  1863  				}) :
  1864  				function( elem, context, xml ) {
  1865  					input[0] = elem;
  1866  					matcher( input, null, xml, results );
  1867  					// Don't keep the element (issue #299)
  1868  					input[0] = null;
  1869  					return !results.pop();
  1870  				};
  1871  		}),
  1872  
  1873  		"has": markFunction(function( selector ) {
  1874  			return function( elem ) {
  1875  				return Sizzle( selector, elem ).length > 0;
  1876  			};
  1877  		}),
  1878  
  1879  		"contains": markFunction(function( text ) {
  1880  			text = text.replace( runescape, funescape );
  1881  			return function( elem ) {
  1882  				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
  1883  			};
  1884  		}),
  1885  
  1886  		// "Whether an element is represented by a :lang() selector
  1887  		// is based solely on the element's language value
  1888  		// being equal to the identifier C,
  1889  		// or beginning with the identifier C immediately followed by "-".
  1890  		// The matching of C against the element's language value is performed case-insensitively.
  1891  		// The identifier C does not have to be a valid language name."
  1892  		// http://www.w3.org/TR/selectors/#lang-pseudo
  1893  		"lang": markFunction( function( lang ) {
  1894  			// lang value must be a valid identifier
  1895  			if ( !ridentifier.test(lang || "") ) {
  1896  				Sizzle.error( "unsupported lang: " + lang );
  1897  			}
  1898  			lang = lang.replace( runescape, funescape ).toLowerCase();
  1899  			return function( elem ) {
  1900  				var elemLang;
  1901  				do {
  1902  					if ( (elemLang = documentIsHTML ?
  1903  						elem.lang :
  1904  						elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
  1905  
  1906  						elemLang = elemLang.toLowerCase();
  1907  						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
  1908  					}
  1909  				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
  1910  				return false;
  1911  			};
  1912  		}),
  1913  
  1914  		// Miscellaneous
  1915  		"target": function( elem ) {
  1916  			var hash = window.location && window.location.hash;
  1917  			return hash && hash.slice( 1 ) === elem.id;
  1918  		},
  1919  
  1920  		"root": function( elem ) {
  1921  			return elem === docElem;
  1922  		},
  1923  
  1924  		"focus": function( elem ) {
  1925  			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
  1926  		},
  1927  
  1928  		// Boolean properties
  1929  		"enabled": function( elem ) {
  1930  			return elem.disabled === false;
  1931  		},
  1932  
  1933  		"disabled": function( elem ) {
  1934  			return elem.disabled === true;
  1935  		},
  1936  
  1937  		"checked": function( elem ) {
  1938  			// In CSS3, :checked should return both checked and selected elements
  1939  			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
  1940  			var nodeName = elem.nodeName.toLowerCase();
  1941  			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
  1942  		},
  1943  
  1944  		"selected": function( elem ) {
  1945  			// Accessing this property makes selected-by-default
  1946  			// options in Safari work properly
  1947  			if ( elem.parentNode ) {
  1948  				elem.parentNode.selectedIndex;
  1949  			}
  1950  
  1951  			return elem.selected === true;
  1952  		},
  1953  
  1954  		// Contents
  1955  		"empty": function( elem ) {
  1956  			// http://www.w3.org/TR/selectors/#empty-pseudo
  1957  			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
  1958  			//   but not by others (comment: 8; processing instruction: 7; etc.)
  1959  			// nodeType < 6 works because attributes (2) do not appear as children
  1960  			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
  1961  				if ( elem.nodeType < 6 ) {
  1962  					return false;
  1963  				}
  1964  			}
  1965  			return true;
  1966  		},
  1967  
  1968  		"parent": function( elem ) {
  1969  			return !Expr.pseudos["empty"]( elem );
  1970  		},
  1971  
  1972  		// Element/input types
  1973  		"header": function( elem ) {
  1974  			return rheader.test( elem.nodeName );
  1975  		},
  1976  
  1977  		"input": function( elem ) {
  1978  			return rinputs.test( elem.nodeName );
  1979  		},
  1980  
  1981  		"button": function( elem ) {
  1982  			var name = elem.nodeName.toLowerCase();
  1983  			return name === "input" && elem.type === "button" || name === "button";
  1984  		},
  1985  
  1986  		"text": function( elem ) {
  1987  			var attr;
  1988  			return elem.nodeName.toLowerCase() === "input" &&
  1989  				elem.type === "text" &&
  1990  
  1991  				// Support: IE<8
  1992  				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
  1993  				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
  1994  		},
  1995  
  1996  		// Position-in-collection
  1997  		"first": createPositionalPseudo(function() {
  1998  			return [ 0 ];
  1999  		}),
  2000  
  2001  		"last": createPositionalPseudo(function( matchIndexes, length ) {
  2002  			return [ length - 1 ];
  2003  		}),
  2004  
  2005  		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
  2006  			return [ argument < 0 ? argument + length : argument ];
  2007  		}),
  2008  
  2009  		"even": createPositionalPseudo(function( matchIndexes, length ) {
  2010  			var i = 0;
  2011  			for ( ; i < length; i += 2 ) {
  2012  				matchIndexes.push( i );
  2013  			}
  2014  			return matchIndexes;
  2015  		}),
  2016  
  2017  		"odd": createPositionalPseudo(function( matchIndexes, length ) {
  2018  			var i = 1;
  2019  			for ( ; i < length; i += 2 ) {
  2020  				matchIndexes.push( i );
  2021  			}
  2022  			return matchIndexes;
  2023  		}),
  2024  
  2025  		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
  2026  			var i = argument < 0 ? argument + length : argument;
  2027  			for ( ; --i >= 0; ) {
  2028  				matchIndexes.push( i );
  2029  			}
  2030  			return matchIndexes;
  2031  		}),
  2032  
  2033  		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
  2034  			var i = argument < 0 ? argument + length : argument;
  2035  			for ( ; ++i < length; ) {
  2036  				matchIndexes.push( i );
  2037  			}
  2038  			return matchIndexes;
  2039  		})
  2040  	}
  2041  };
  2042  
  2043  Expr.pseudos["nth"] = Expr.pseudos["eq"];
  2044  
  2045  // Add button/input type pseudos
  2046  for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
  2047  	Expr.pseudos[ i ] = createInputPseudo( i );
  2048  }
  2049  for ( i in { submit: true, reset: true } ) {
  2050  	Expr.pseudos[ i ] = createButtonPseudo( i );
  2051  }
  2052  
  2053  // Easy API for creating new setFilters
  2054  function setFilters() {}
  2055  setFilters.prototype = Expr.filters = Expr.pseudos;
  2056  Expr.setFilters = new setFilters();
  2057  
  2058  tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
  2059  	var matched, match, tokens, type,
  2060  		soFar, groups, preFilters,
  2061  		cached = tokenCache[ selector + " " ];
  2062  
  2063  	if ( cached ) {
  2064  		return parseOnly ? 0 : cached.slice( 0 );
  2065  	}
  2066  
  2067  	soFar = selector;
  2068  	groups = [];
  2069  	preFilters = Expr.preFilter;
  2070  
  2071  	while ( soFar ) {
  2072  
  2073  		// Comma and first run
  2074  		if ( !matched || (match = rcomma.exec( soFar )) ) {
  2075  			if ( match ) {
  2076  				// Don't consume trailing commas as valid
  2077  				soFar = soFar.slice( match[0].length ) || soFar;
  2078  			}
  2079  			groups.push( (tokens = []) );
  2080  		}
  2081  
  2082  		matched = false;
  2083  
  2084  		// Combinators
  2085  		if ( (match = rcombinators.exec( soFar )) ) {
  2086  			matched = match.shift();
  2087  			tokens.push({
  2088  				value: matched,
  2089  				// Cast descendant combinators to space
  2090  				type: match[0].replace( rtrim, " " )
  2091  			});
  2092  			soFar = soFar.slice( matched.length );
  2093  		}
  2094  
  2095  		// Filters
  2096  		for ( type in Expr.filter ) {
  2097  			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
  2098  				(match = preFilters[ type ]( match ))) ) {
  2099  				matched = match.shift();
  2100  				tokens.push({
  2101  					value: matched,
  2102  					type: type,
  2103  					matches: match
  2104  				});
  2105  				soFar = soFar.slice( matched.length );
  2106  			}
  2107  		}
  2108  
  2109  		if ( !matched ) {
  2110  			break;
  2111  		}
  2112  	}
  2113  
  2114  	// Return the length of the invalid excess
  2115  	// if we're just parsing
  2116  	// Otherwise, throw an error or return tokens
  2117  	return parseOnly ?
  2118  		soFar.length :
  2119  		soFar ?
  2120  			Sizzle.error( selector ) :
  2121  			// Cache the tokens
  2122  			tokenCache( selector, groups ).slice( 0 );
  2123  };
  2124  
  2125  function toSelector( tokens ) {
  2126  	var i = 0,
  2127  		len = tokens.length,
  2128  		selector = "";
  2129  	for ( ; i < len; i++ ) {
  2130  		selector += tokens[i].value;
  2131  	}
  2132  	return selector;
  2133  }
  2134  
  2135  function addCombinator( matcher, combinator, base ) {
  2136  	var dir = combinator.dir,
  2137  		checkNonElements = base && dir === "parentNode",
  2138  		doneName = done++;
  2139  
  2140  	return combinator.first ?
  2141  		// Check against closest ancestor/preceding element
  2142  		function( elem, context, xml ) {
  2143  			while ( (elem = elem[ dir ]) ) {
  2144  				if ( elem.nodeType === 1 || checkNonElements ) {
  2145  					return matcher( elem, context, xml );
  2146  				}
  2147  			}
  2148  		} :
  2149  
  2150  		// Check against all ancestor/preceding elements
  2151  		function( elem, context, xml ) {
  2152  			var oldCache, uniqueCache, outerCache,
  2153  				newCache = [ dirruns, doneName ];
  2154  
  2155  			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
  2156  			if ( xml ) {
  2157  				while ( (elem = elem[ dir ]) ) {
  2158  					if ( elem.nodeType === 1 || checkNonElements ) {
  2159  						if ( matcher( elem, context, xml ) ) {
  2160  							return true;
  2161  						}
  2162  					}
  2163  				}
  2164  			} else {
  2165  				while ( (elem = elem[ dir ]) ) {
  2166  					if ( elem.nodeType === 1 || checkNonElements ) {
  2167  						outerCache = elem[ expando ] || (elem[ expando ] = {});
  2168  
  2169  						// Support: IE <9 only
  2170  						// Defend against cloned attroperties (jQuery gh-1709)
  2171  						uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
  2172  
  2173  						if ( (oldCache = uniqueCache[ dir ]) &&
  2174  							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
  2175  
  2176  							// Assign to newCache so results back-propagate to previous elements
  2177  							return (newCache[ 2 ] = oldCache[ 2 ]);
  2178  						} else {
  2179  							// Reuse newcache so results back-propagate to previous elements
  2180  							uniqueCache[ dir ] = newCache;
  2181  
  2182  							// A match means we're done; a fail means we have to keep checking
  2183  							if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
  2184  								return true;
  2185  							}
  2186  						}
  2187  					}
  2188  				}
  2189  			}
  2190  		};
  2191  }
  2192  
  2193  function elementMatcher( matchers ) {
  2194  	return matchers.length > 1 ?
  2195  		function( elem, context, xml ) {
  2196  			var i = matchers.length;
  2197  			while ( i-- ) {
  2198  				if ( !matchers[i]( elem, context, xml ) ) {
  2199  					return false;
  2200  				}
  2201  			}
  2202  			return true;
  2203  		} :
  2204  		matchers[0];
  2205  }
  2206  
  2207  function multipleContexts( selector, contexts, results ) {
  2208  	var i = 0,
  2209  		len = contexts.length;
  2210  	for ( ; i < len; i++ ) {
  2211  		Sizzle( selector, contexts[i], results );
  2212  	}
  2213  	return results;
  2214  }
  2215  
  2216  function condense( unmatched, map, filter, context, xml ) {
  2217  	var elem,
  2218  		newUnmatched = [],
  2219  		i = 0,
  2220  		len = unmatched.length,
  2221  		mapped = map != null;
  2222  
  2223  	for ( ; i < len; i++ ) {
  2224  		if ( (elem = unmatched[i]) ) {
  2225  			if ( !filter || filter( elem, context, xml ) ) {
  2226  				newUnmatched.push( elem );
  2227  				if ( mapped ) {
  2228  					map.push( i );
  2229  				}
  2230  			}
  2231  		}
  2232  	}
  2233  
  2234  	return newUnmatched;
  2235  }
  2236  
  2237  function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
  2238  	if ( postFilter && !postFilter[ expando ] ) {
  2239  		postFilter = setMatcher( postFilter );
  2240  	}
  2241  	if ( postFinder && !postFinder[ expando ] ) {
  2242  		postFinder = setMatcher( postFinder, postSelector );
  2243  	}
  2244  	return markFunction(function( seed, results, context, xml ) {
  2245  		var temp, i, elem,
  2246  			preMap = [],
  2247  			postMap = [],
  2248  			preexisting = results.length,
  2249  
  2250  			// Get initial elements from seed or context
  2251  			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
  2252  
  2253  			// Prefilter to get matcher input, preserving a map for seed-results synchronization
  2254  			matcherIn = preFilter && ( seed || !selector ) ?
  2255  				condense( elems, preMap, preFilter, context, xml ) :
  2256  				elems,
  2257  
  2258  			matcherOut = matcher ?
  2259  				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
  2260  				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
  2261  
  2262  					// ...intermediate processing is necessary
  2263  					[] :
  2264  
  2265  					// ...otherwise use results directly
  2266  					results :
  2267  				matcherIn;
  2268  
  2269  		// Find primary matches
  2270  		if ( matcher ) {
  2271  			matcher( matcherIn, matcherOut, context, xml );
  2272  		}
  2273  
  2274  		// Apply postFilter
  2275  		if ( postFilter ) {
  2276  			temp = condense( matcherOut, postMap );
  2277  			postFilter( temp, [], context, xml );
  2278  
  2279  			// Un-match failing elements by moving them back to matcherIn
  2280  			i = temp.length;
  2281  			while ( i-- ) {
  2282  				if ( (elem = temp[i]) ) {
  2283  					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
  2284  				}
  2285  			}
  2286  		}
  2287  
  2288  		if ( seed ) {
  2289  			if ( postFinder || preFilter ) {
  2290  				if ( postFinder ) {
  2291  					// Get the final matcherOut by condensing this intermediate into postFinder contexts
  2292  					temp = [];
  2293  					i = matcherOut.length;
  2294  					while ( i-- ) {
  2295  						if ( (elem = matcherOut[i]) ) {
  2296  							// Restore matcherIn since elem is not yet a final match
  2297  							temp.push( (matcherIn[i] = elem) );
  2298  						}
  2299  					}
  2300  					postFinder( null, (matcherOut = []), temp, xml );
  2301  				}
  2302  
  2303  				// Move matched elements from seed to results to keep them synchronized
  2304  				i = matcherOut.length;
  2305  				while ( i-- ) {
  2306  					if ( (elem = matcherOut[i]) &&
  2307  						(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
  2308  
  2309  						seed[temp] = !(results[temp] = elem);
  2310  					}
  2311  				}
  2312  			}
  2313  
  2314  		// Add elements to results, through postFinder if defined
  2315  		} else {
  2316  			matcherOut = condense(
  2317  				matcherOut === results ?
  2318  					matcherOut.splice( preexisting, matcherOut.length ) :
  2319  					matcherOut
  2320  			);
  2321  			if ( postFinder ) {
  2322  				postFinder( null, results, matcherOut, xml );
  2323  			} else {
  2324  				push.apply( results, matcherOut );
  2325  			}
  2326  		}
  2327  	});
  2328  }
  2329  
  2330  function matcherFromTokens( tokens ) {
  2331  	var checkContext, matcher, j,
  2332  		len = tokens.length,
  2333  		leadingRelative = Expr.relative[ tokens[0].type ],
  2334  		implicitRelative = leadingRelative || Expr.relative[" "],
  2335  		i = leadingRelative ? 1 : 0,
  2336  
  2337  		// The foundational matcher ensures that elements are reachable from top-level context(s)
  2338  		matchContext = addCombinator( function( elem ) {
  2339  			return elem === checkContext;
  2340  		}, implicitRelative, true ),
  2341  		matchAnyContext = addCombinator( function( elem ) {
  2342  			return indexOf( checkContext, elem ) > -1;
  2343  		}, implicitRelative, true ),
  2344  		matchers = [ function( elem, context, xml ) {
  2345  			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
  2346  				(checkContext = context).nodeType ?
  2347  					matchContext( elem, context, xml ) :
  2348  					matchAnyContext( elem, context, xml ) );
  2349  			// Avoid hanging onto element (issue #299)
  2350  			checkContext = null;
  2351  			return ret;
  2352  		} ];
  2353  
  2354  	for ( ; i < len; i++ ) {
  2355  		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
  2356  			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
  2357  		} else {
  2358  			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
  2359  
  2360  			// Return special upon seeing a positional matcher
  2361  			if ( matcher[ expando ] ) {
  2362  				// Find the next relative operator (if any) for proper handling
  2363  				j = ++i;
  2364  				for ( ; j < len; j++ ) {
  2365  					if ( Expr.relative[ tokens[j].type ] ) {
  2366  						break;
  2367  					}
  2368  				}
  2369  				return setMatcher(
  2370  					i > 1 && elementMatcher( matchers ),
  2371  					i > 1 && toSelector(
  2372  						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
  2373  						tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
  2374  					).replace( rtrim, "$1" ),
  2375  					matcher,
  2376  					i < j && matcherFromTokens( tokens.slice( i, j ) ),
  2377  					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
  2378  					j < len && toSelector( tokens )
  2379  				);
  2380  			}
  2381  			matchers.push( matcher );
  2382  		}
  2383  	}
  2384  
  2385  	return elementMatcher( matchers );
  2386  }
  2387  
  2388  function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
  2389  	var bySet = setMatchers.length > 0,
  2390  		byElement = elementMatchers.length > 0,
  2391  		superMatcher = function( seed, context, xml, results, outermost ) {
  2392  			var elem, j, matcher,
  2393  				matchedCount = 0,
  2394  				i = "0",
  2395  				unmatched = seed && [],
  2396  				setMatched = [],
  2397  				contextBackup = outermostContext,
  2398  				// We must always have either seed elements or outermost context
  2399  				elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
  2400  				// Use integer dirruns iff this is the outermost matcher
  2401  				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
  2402  				len = elems.length;
  2403  
  2404  			if ( outermost ) {
  2405  				outermostContext = context === document || context || outermost;
  2406  			}
  2407  
  2408  			// Add elements passing elementMatchers directly to results
  2409  			// Support: IE<9, Safari
  2410  			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
  2411  			for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
  2412  				if ( byElement && elem ) {
  2413  					j = 0;
  2414  					if ( !context && elem.ownerDocument !== document ) {
  2415  						setDocument( elem );
  2416  						xml = !documentIsHTML;
  2417  					}
  2418  					while ( (matcher = elementMatchers[j++]) ) {
  2419  						if ( matcher( elem, context || document, xml) ) {
  2420  							results.push( elem );
  2421  							break;
  2422  						}
  2423  					}
  2424  					if ( outermost ) {
  2425  						dirruns = dirrunsUnique;
  2426  					}
  2427  				}
  2428  
  2429  				// Track unmatched elements for set filters
  2430  				if ( bySet ) {
  2431  					// They will have gone through all possible matchers
  2432  					if ( (elem = !matcher && elem) ) {
  2433  						matchedCount--;
  2434  					}
  2435  
  2436  					// Lengthen the array for every element, matched or not
  2437  					if ( seed ) {
  2438  						unmatched.push( elem );
  2439  					}
  2440  				}
  2441  			}
  2442  
  2443  			// `i` is now the count of elements visited above, and adding it to `matchedCount`
  2444  			// makes the latter nonnegative.
  2445  			matchedCount += i;
  2446  
  2447  			// Apply set filters to unmatched elements
  2448  			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
  2449  			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
  2450  			// no element matchers and no seed.
  2451  			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
  2452  			// case, which will result in a "00" `matchedCount` that differs from `i` but is also
  2453  			// numerically zero.
  2454  			if ( bySet && i !== matchedCount ) {
  2455  				j = 0;
  2456  				while ( (matcher = setMatchers[j++]) ) {
  2457  					matcher( unmatched, setMatched, context, xml );
  2458  				}
  2459  
  2460  				if ( seed ) {
  2461  					// Reintegrate element matches to eliminate the need for sorting
  2462  					if ( matchedCount > 0 ) {
  2463  						while ( i-- ) {
  2464  							if ( !(unmatched[i] || setMatched[i]) ) {
  2465  								setMatched[i] = pop.call( results );
  2466  							}
  2467  						}
  2468  					}
  2469  
  2470  					// Discard index placeholder values to get only actual matches
  2471  					setMatched = condense( setMatched );
  2472  				}
  2473  
  2474  				// Add matches to results
  2475  				push.apply( results, setMatched );
  2476  
  2477  				// Seedless set matches succeeding multiple successful matchers stipulate sorting
  2478  				if ( outermost && !seed && setMatched.length > 0 &&
  2479  					( matchedCount + setMatchers.length ) > 1 ) {
  2480  
  2481  					Sizzle.uniqueSort( results );
  2482  				}
  2483  			}
  2484  
  2485  			// Override manipulation of globals by nested matchers
  2486  			if ( outermost ) {
  2487  				dirruns = dirrunsUnique;
  2488  				outermostContext = contextBackup;
  2489  			}
  2490  
  2491  			return unmatched;
  2492  		};
  2493  
  2494  	return bySet ?
  2495  		markFunction( superMatcher ) :
  2496  		superMatcher;
  2497  }
  2498  
  2499  compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
  2500  	var i,
  2501  		setMatchers = [],
  2502  		elementMatchers = [],
  2503  		cached = compilerCache[ selector + " " ];
  2504  
  2505  	if ( !cached ) {
  2506  		// Generate a function of recursive functions that can be used to check each element
  2507  		if ( !match ) {
  2508  			match = tokenize( selector );
  2509  		}
  2510  		i = match.length;
  2511  		while ( i-- ) {
  2512  			cached = matcherFromTokens( match[i] );
  2513  			if ( cached[ expando ] ) {
  2514  				setMatchers.push( cached );
  2515  			} else {
  2516  				elementMatchers.push( cached );
  2517  			}
  2518  		}
  2519  
  2520  		// Cache the compiled function
  2521  		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
  2522  
  2523  		// Save selector and tokenization
  2524  		cached.selector = selector;
  2525  	}
  2526  	return cached;
  2527  };
  2528  
  2529  /**
  2530   * A low-level selection function that works with Sizzle's compiled
  2531   *  selector functions
  2532   * @param {String|Function} selector A selector or a pre-compiled
  2533   *  selector function built with Sizzle.compile
  2534   * @param {Element} context
  2535   * @param {Array} [results]
  2536   * @param {Array} [seed] A set of elements to match against
  2537   */
  2538  select = Sizzle.select = function( selector, context, results, seed ) {
  2539  	var i, tokens, token, type, find,
  2540  		compiled = typeof selector === "function" && selector,
  2541  		match = !seed && tokenize( (selector = compiled.selector || selector) );
  2542  
  2543  	results = results || [];
  2544  
  2545  	// Try to minimize operations if there is only one selector in the list and no seed
  2546  	// (the latter of which guarantees us context)
  2547  	if ( match.length === 1 ) {
  2548  
  2549  		// Reduce context if the leading compound selector is an ID
  2550  		tokens = match[0] = match[0].slice( 0 );
  2551  		if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
  2552  				support.getById && context.nodeType === 9 && documentIsHTML &&
  2553  				Expr.relative[ tokens[1].type ] ) {
  2554  
  2555  			context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
  2556  			if ( !context ) {
  2557  				return results;
  2558  
  2559  			// Precompiled matchers will still verify ancestry, so step up a level
  2560  			} else if ( compiled ) {
  2561  				context = context.parentNode;
  2562  			}
  2563  
  2564  			selector = selector.slice( tokens.shift().value.length );
  2565  		}
  2566  
  2567  		// Fetch a seed set for right-to-left matching
  2568  		i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
  2569  		while ( i-- ) {
  2570  			token = tokens[i];
  2571  
  2572  			// Abort if we hit a combinator
  2573  			if ( Expr.relative[ (type = token.type) ] ) {
  2574  				break;
  2575  			}
  2576  			if ( (find = Expr.find[ type ]) ) {
  2577  				// Search, expanding context for leading sibling combinators
  2578  				if ( (seed = find(
  2579  					token.matches[0].replace( runescape, funescape ),
  2580  					rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
  2581  				)) ) {
  2582  
  2583  					// If seed is empty or no tokens remain, we can return early
  2584  					tokens.splice( i, 1 );
  2585  					selector = seed.length && toSelector( tokens );
  2586  					if ( !selector ) {
  2587  						push.apply( results, seed );
  2588  						return results;
  2589  					}
  2590  
  2591  					break;
  2592  				}
  2593  			}
  2594  		}
  2595  	}
  2596  
  2597  	// Compile and execute a filtering function if one is not provided
  2598  	// Provide `match` to avoid retokenization if we modified the selector above
  2599  	( compiled || compile( selector, match ) )(
  2600  		seed,
  2601  		context,
  2602  		!documentIsHTML,
  2603  		results,
  2604  		!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
  2605  	);
  2606  	return results;
  2607  };
  2608  
  2609  // One-time assignments
  2610  
  2611  // Sort stability
  2612  support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
  2613  
  2614  // Support: Chrome 14-35+
  2615  // Always assume duplicates if they aren't passed to the comparison function
  2616  support.detectDuplicates = !!hasDuplicate;
  2617  
  2618  // Initialize against the default document
  2619  setDocument();
  2620  
  2621  // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
  2622  // Detached nodes confoundingly follow *each other*
  2623  support.sortDetached = assert(function( div1 ) {
  2624  	// Should return 1, but returns 4 (following)
  2625  	return div1.compareDocumentPosition( document.createElement("div") ) & 1;
  2626  });
  2627  
  2628  // Support: IE<8
  2629  // Prevent attribute/property "interpolation"
  2630  // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
  2631  if ( !assert(function( div ) {
  2632  	div.innerHTML = "<a href='#'></a>";
  2633  	return div.firstChild.getAttribute("href") === "#" ;
  2634  }) ) {
  2635  	addHandle( "type|href|height|width", function( elem, name, isXML ) {
  2636  		if ( !isXML ) {
  2637  			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
  2638  		}
  2639  	});
  2640  }
  2641  
  2642  // Support: IE<9
  2643  // Use defaultValue in place of getAttribute("value")
  2644  if ( !support.attributes || !assert(function( div ) {
  2645  	div.innerHTML = "<input/>";
  2646  	div.firstChild.setAttribute( "value", "" );
  2647  	return div.firstChild.getAttribute( "value" ) === "";
  2648  }) ) {
  2649  	addHandle( "value", function( elem, name, isXML ) {
  2650  		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
  2651  			return elem.defaultValue;
  2652  		}
  2653  	});
  2654  }
  2655  
  2656  // Support: IE<9
  2657  // Use getAttributeNode to fetch booleans when getAttribute lies
  2658  if ( !assert(function( div ) {
  2659  	return div.getAttribute("disabled") == null;
  2660  }) ) {
  2661  	addHandle( booleans, function( elem, name, isXML ) {
  2662  		var val;
  2663  		if ( !isXML ) {
  2664  			return elem[ name ] === true ? name.toLowerCase() :
  2665  					(val = elem.getAttributeNode( name )) && val.specified ?
  2666  					val.value :
  2667  				null;
  2668  		}
  2669  	});
  2670  }
  2671  
  2672  return Sizzle;
  2673  
  2674  })( window );
  2675  
  2676  
  2677  
  2678  jQuery.find = Sizzle;
  2679  jQuery.expr = Sizzle.selectors;
  2680  jQuery.expr[ ":" ] = jQuery.expr.pseudos;
  2681  jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
  2682  jQuery.text = Sizzle.getText;
  2683  jQuery.isXMLDoc = Sizzle.isXML;
  2684  jQuery.contains = Sizzle.contains;
  2685  
  2686  
  2687  
  2688  var dir = function( elem, dir, until ) {
  2689  	var matched = [],
  2690  		truncate = until !== undefined;
  2691  
  2692  	while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
  2693  		if ( elem.nodeType === 1 ) {
  2694  			if ( truncate && jQuery( elem ).is( until ) ) {
  2695  				break;
  2696  			}
  2697  			matched.push( elem );
  2698  		}
  2699  	}
  2700  	return matched;
  2701  };
  2702  
  2703  
  2704  var siblings = function( n, elem ) {
  2705  	var matched = [];
  2706  
  2707  	for ( ; n; n = n.nextSibling ) {
  2708  		if ( n.nodeType === 1 && n !== elem ) {
  2709  			matched.push( n );
  2710  		}
  2711  	}
  2712  
  2713  	return matched;
  2714  };
  2715  
  2716  
  2717  var rneedsContext = jQuery.expr.match.needsContext;
  2718  
  2719  var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );
  2720  
  2721  
  2722  
  2723  var risSimple = /^.[^:#\[\.,]*$/;
  2724  
  2725  // Implement the identical functionality for filter and not
  2726  function winnow( elements, qualifier, not ) {
  2727  	if ( jQuery.isFunction( qualifier ) ) {
  2728  		return jQuery.grep( elements, function( elem, i ) {
  2729  			/* jshint -W018 */
  2730  			return !!qualifier.call( elem, i, elem ) !== not;
  2731  		} );
  2732  
  2733  	}
  2734  
  2735  	if ( qualifier.nodeType ) {
  2736  		return jQuery.grep( elements, function( elem ) {
  2737  			return ( elem === qualifier ) !== not;
  2738  		} );
  2739  
  2740  	}
  2741  
  2742  	if ( typeof qualifier === "string" ) {
  2743  		if ( risSimple.test( qualifier ) ) {
  2744  			return jQuery.filter( qualifier, elements, not );
  2745  		}
  2746  
  2747  		qualifier = jQuery.filter( qualifier, elements );
  2748  	}
  2749  
  2750  	return jQuery.grep( elements, function( elem ) {
  2751  		return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
  2752  	} );
  2753  }
  2754  
  2755  jQuery.filter = function( expr, elems, not ) {
  2756  	var elem = elems[ 0 ];
  2757  
  2758  	if ( not ) {
  2759  		expr = ":not(" + expr + ")";
  2760  	}
  2761  
  2762  	return elems.length === 1 && elem.nodeType === 1 ?
  2763  		jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
  2764  		jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
  2765  			return elem.nodeType === 1;
  2766  		} ) );
  2767  };
  2768  
  2769  jQuery.fn.extend( {
  2770  	find: function( selector ) {
  2771  		var i,
  2772  			len = this.length,
  2773  			ret = [],
  2774  			self = this;
  2775  
  2776  		if ( typeof selector !== "string" ) {
  2777  			return this.pushStack( jQuery( selector ).filter( function() {
  2778  				for ( i = 0; i < len; i++ ) {
  2779  					if ( jQuery.contains( self[ i ], this ) ) {
  2780  						return true;
  2781  					}
  2782  				}
  2783  			} ) );
  2784  		}
  2785  
  2786  		for ( i = 0; i < len; i++ ) {
  2787  			jQuery.find( selector, self[ i ], ret );
  2788  		}
  2789  
  2790  		// Needed because $( selector, context ) becomes $( context ).find( selector )
  2791  		ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
  2792  		ret.selector = this.selector ? this.selector + " " + selector : selector;
  2793  		return ret;
  2794  	},
  2795  	filter: function( selector ) {
  2796  		return this.pushStack( winnow( this, selector || [], false ) );
  2797  	},
  2798  	not: function( selector ) {
  2799  		return this.pushStack( winnow( this, selector || [], true ) );
  2800  	},
  2801  	is: function( selector ) {
  2802  		return !!winnow(
  2803  			this,
  2804  
  2805  			// If this is a positional/relative selector, check membership in the returned set
  2806  			// so $("p:first").is("p:last") won't return true for a doc with two "p".
  2807  			typeof selector === "string" && rneedsContext.test( selector ) ?
  2808  				jQuery( selector ) :
  2809  				selector || [],
  2810  			false
  2811  		).length;
  2812  	}
  2813  } );
  2814  
  2815  
  2816  // Initialize a jQuery object
  2817  
  2818  
  2819  // A central reference to the root jQuery(document)
  2820  var rootjQuery,
  2821  
  2822  	// A simple way to check for HTML strings
  2823  	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
  2824  	// Strict HTML recognition (#11290: must start with <)
  2825  	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
  2826  
  2827  	init = jQuery.fn.init = function( selector, context, root ) {
  2828  		var match, elem;
  2829  
  2830  		// HANDLE: $(""), $(null), $(undefined), $(false)
  2831  		if ( !selector ) {
  2832  			return this;
  2833  		}
  2834  
  2835  		// Method init() accepts an alternate rootjQuery
  2836  		// so migrate can support jQuery.sub (gh-2101)
  2837  		root = root || rootjQuery;
  2838  
  2839  		// Handle HTML strings
  2840  		if ( typeof selector === "string" ) {
  2841  			if ( selector[ 0 ] === "<" &&
  2842  				selector[ selector.length - 1 ] === ">" &&
  2843  				selector.length >= 3 ) {
  2844  
  2845  				// Assume that strings that start and end with <> are HTML and skip the regex check
  2846  				match = [ null, selector, null ];
  2847  
  2848  			} else {
  2849  				match = rquickExpr.exec( selector );
  2850  			}
  2851  
  2852  			// Match html or make sure no context is specified for #id
  2853  			if ( match && ( match[ 1 ] || !context ) ) {
  2854  
  2855  				// HANDLE: $(html) -> $(array)
  2856  				if ( match[ 1 ] ) {
  2857  					context = context instanceof jQuery ? context[ 0 ] : context;
  2858  
  2859  					// Option to run scripts is true for back-compat
  2860  					// Intentionally let the error be thrown if parseHTML is not present
  2861  					jQuery.merge( this, jQuery.parseHTML(
  2862  						match[ 1 ],
  2863  						context && context.nodeType ? context.ownerDocument || context : document,
  2864  						true
  2865  					) );
  2866  
  2867  					// HANDLE: $(html, props)
  2868  					if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
  2869  						for ( match in context ) {
  2870  
  2871  							// Properties of context are called as methods if possible
  2872  							if ( jQuery.isFunction( this[ match ] ) ) {
  2873  								this[ match ]( context[ match ] );
  2874  
  2875  							// ...and otherwise set as attributes
  2876  							} else {
  2877  								this.attr( match, context[ match ] );
  2878  							}
  2879  						}
  2880  					}
  2881  
  2882  					return this;
  2883  
  2884  				// HANDLE: $(#id)
  2885  				} else {
  2886  					elem = document.getElementById( match[ 2 ] );
  2887  
  2888  					// Support: Blackberry 4.6
  2889  					// gEBID returns nodes no longer in the document (#6963)
  2890  					if ( elem && elem.parentNode ) {
  2891  
  2892  						// Inject the element directly into the jQuery object
  2893  						this.length = 1;
  2894  						this[ 0 ] = elem;
  2895  					}
  2896  
  2897  					this.context = document;
  2898  					this.selector = selector;
  2899  					return this;
  2900  				}
  2901  
  2902  			// HANDLE: $(expr, $(...))
  2903  			} else if ( !context || context.jquery ) {
  2904  				return ( context || root ).find( selector );
  2905  
  2906  			// HANDLE: $(expr, context)
  2907  			// (which is just equivalent to: $(context).find(expr)
  2908  			} else {
  2909  				return this.constructor( context ).find( selector );
  2910  			}
  2911  
  2912  		// HANDLE: $(DOMElement)
  2913  		} else if ( selector.nodeType ) {
  2914  			this.context = this[ 0 ] = selector;
  2915  			this.length = 1;
  2916  			return this;
  2917  
  2918  		// HANDLE: $(function)
  2919  		// Shortcut for document ready
  2920  		} else if ( jQuery.isFunction( selector ) ) {
  2921  			return root.ready !== undefined ?
  2922  				root.ready( selector ) :
  2923  
  2924  				// Execute immediately if ready is not present
  2925  				selector( jQuery );
  2926  		}
  2927  
  2928  		if ( selector.selector !== undefined ) {
  2929  			this.selector = selector.selector;
  2930  			this.context = selector.context;
  2931  		}
  2932  
  2933  		return jQuery.makeArray( selector, this );
  2934  	};
  2935  
  2936  // Give the init function the jQuery prototype for later instantiation
  2937  init.prototype = jQuery.fn;
  2938  
  2939  // Initialize central reference
  2940  rootjQuery = jQuery( document );
  2941  
  2942  
  2943  var rparentsprev = /^(?:parents|prev(?:Until|All))/,
  2944  
  2945  	// Methods guaranteed to produce a unique set when starting from a unique set
  2946  	guaranteedUnique = {
  2947  		children: true,
  2948  		contents: true,
  2949  		next: true,
  2950  		prev: true
  2951  	};
  2952  
  2953  jQuery.fn.extend( {
  2954  	has: function( target ) {
  2955  		var targets = jQuery( target, this ),
  2956  			l = targets.length;
  2957  
  2958  		return this.filter( function() {
  2959  			var i = 0;
  2960  			for ( ; i < l; i++ ) {
  2961  				if ( jQuery.contains( this, targets[ i ] ) ) {
  2962  					return true;
  2963  				}
  2964  			}
  2965  		} );
  2966  	},
  2967  
  2968  	closest: function( selectors, context ) {
  2969  		var cur,
  2970  			i = 0,
  2971  			l = this.length,
  2972  			matched = [],
  2973  			pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
  2974  				jQuery( selectors, context || this.context ) :
  2975  				0;
  2976  
  2977  		for ( ; i < l; i++ ) {
  2978  			for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
  2979  
  2980  				// Always skip document fragments
  2981  				if ( cur.nodeType < 11 && ( pos ?
  2982  					pos.index( cur ) > -1 :
  2983  
  2984  					// Don't pass non-elements to Sizzle
  2985  					cur.nodeType === 1 &&
  2986  						jQuery.find.matchesSelector( cur, selectors ) ) ) {
  2987  
  2988  					matched.push( cur );
  2989  					break;
  2990  				}
  2991  			}
  2992  		}
  2993  
  2994  		return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
  2995  	},
  2996  
  2997  	// Determine the position of an element within the set
  2998  	index: function( elem ) {
  2999  
  3000  		// No argument, return index in parent
  3001  		if ( !elem ) {
  3002  			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
  3003  		}
  3004  
  3005  		// Index in selector
  3006  		if ( typeof elem === "string" ) {
  3007  			return indexOf.call( jQuery( elem ), this[ 0 ] );
  3008  		}
  3009  
  3010  		// Locate the position of the desired element
  3011  		return indexOf.call( this,
  3012  
  3013  			// If it receives a jQuery object, the first element is used
  3014  			elem.jquery ? elem[ 0 ] : elem
  3015  		);
  3016  	},
  3017  
  3018  	add: function( selector, context ) {
  3019  		return this.pushStack(
  3020  			jQuery.uniqueSort(
  3021  				jQuery.merge( this.get(), jQuery( selector, context ) )
  3022  			)
  3023  		);
  3024  	},
  3025  
  3026  	addBack: function( selector ) {
  3027  		return this.add( selector == null ?
  3028  			this.prevObject : this.prevObject.filter( selector )
  3029  		);
  3030  	}
  3031  } );
  3032  
  3033  function sibling( cur, dir ) {
  3034  	while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
  3035  	return cur;
  3036  }
  3037  
  3038  jQuery.each( {
  3039  	parent: function( elem ) {
  3040  		var parent = elem.parentNode;
  3041  		return parent && parent.nodeType !== 11 ? parent : null;
  3042  	},
  3043  	parents: function( elem ) {
  3044  		return dir( elem, "parentNode" );
  3045  	},
  3046  	parentsUntil: function( elem, i, until ) {
  3047  		return dir( elem, "parentNode", until );
  3048  	},
  3049  	next: function( elem ) {
  3050  		return sibling( elem, "nextSibling" );
  3051  	},
  3052  	prev: function( elem ) {
  3053  		return sibling( elem, "previousSibling" );
  3054  	},
  3055  	nextAll: function( elem ) {
  3056  		return dir( elem, "nextSibling" );
  3057  	},
  3058  	prevAll: function( elem ) {
  3059  		return dir( elem, "previousSibling" );
  3060  	},
  3061  	nextUntil: function( elem, i, until ) {
  3062  		return dir( elem, "nextSibling", until );
  3063  	},
  3064  	prevUntil: function( elem, i, until ) {
  3065  		return dir( elem, "previousSibling", until );
  3066  	},
  3067  	siblings: function( elem ) {
  3068  		return siblings( ( elem.parentNode || {} ).firstChild, elem );
  3069  	},
  3070  	children: function( elem ) {
  3071  		return siblings( elem.firstChild );
  3072  	},
  3073  	contents: function( elem ) {
  3074  		return elem.contentDocument || jQuery.merge( [], elem.childNodes );
  3075  	}
  3076  }, function( name, fn ) {
  3077  	jQuery.fn[ name ] = function( until, selector ) {
  3078  		var matched = jQuery.map( this, fn, until );
  3079  
  3080  		if ( name.slice( -5 ) !== "Until" ) {
  3081  			selector = until;
  3082  		}
  3083  
  3084  		if ( selector && typeof selector === "string" ) {
  3085  			matched = jQuery.filter( selector, matched );
  3086  		}
  3087  
  3088  		if ( this.length > 1 ) {
  3089  
  3090  			// Remove duplicates
  3091  			if ( !guaranteedUnique[ name ] ) {
  3092  				jQuery.uniqueSort( matched );
  3093  			}
  3094  
  3095  			// Reverse order for parents* and prev-derivatives
  3096  			if ( rparentsprev.test( name ) ) {
  3097  				matched.reverse();
  3098  			}
  3099  		}
  3100  
  3101  		return this.pushStack( matched );
  3102  	};
  3103  } );
  3104  var rnotwhite = ( /\S+/g );
  3105  
  3106  
  3107  
  3108  // Convert String-formatted options into Object-formatted ones
  3109  function createOptions( options ) {
  3110  	var object = {};
  3111  	jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
  3112  		object[ flag ] = true;
  3113  	} );
  3114  	return object;
  3115  }
  3116  
  3117  /*
  3118   * Create a callback list using the following parameters:
  3119   *
  3120   *	options: an optional list of space-separated options that will change how
  3121   *			the callback list behaves or a more traditional option object
  3122   *
  3123   * By default a callback list will act like an event callback list and can be
  3124   * "fired" multiple times.
  3125   *
  3126   * Possible options:
  3127   *
  3128   *	once:			will ensure the callback list can only be fired once (like a Deferred)
  3129   *
  3130   *	memory:			will keep track of previous values and will call any callback added
  3131   *					after the list has been fired right away with the latest "memorized"
  3132   *					values (like a Deferred)
  3133   *
  3134   *	unique:			will ensure a callback can only be added once (no duplicate in the list)
  3135   *
  3136   *	stopOnFalse:	interrupt callings when a callback returns false
  3137   *
  3138   */
  3139  jQuery.Callbacks = function( options ) {
  3140  
  3141  	// Convert options from String-formatted to Object-formatted if needed
  3142  	// (we check in cache first)
  3143  	options = typeof options === "string" ?
  3144  		createOptions( options ) :
  3145  		jQuery.extend( {}, options );
  3146  
  3147  	var // Flag to know if list is currently firing
  3148  		firing,
  3149  
  3150  		// Last fire value for non-forgettable lists
  3151  		memory,
  3152  
  3153  		// Flag to know if list was already fired
  3154  		fired,
  3155  
  3156  		// Flag to prevent firing
  3157  		locked,
  3158  
  3159  		// Actual callback list
  3160  		list = [],
  3161  
  3162  		// Queue of execution data for repeatable lists
  3163  		queue = [],
  3164  
  3165  		// Index of currently firing callback (modified by add/remove as needed)
  3166  		firingIndex = -1,
  3167  
  3168  		// Fire callbacks
  3169  		fire = function() {
  3170  
  3171  			// Enforce single-firing
  3172  			locked = options.once;
  3173  
  3174  			// Execute callbacks for all pending executions,
  3175  			// respecting firingIndex overrides and runtime changes
  3176  			fired = firing = true;
  3177  			for ( ; queue.length; firingIndex = -1 ) {
  3178  				memory = queue.shift();
  3179  				while ( ++firingIndex < list.length ) {
  3180  
  3181  					// Run callback and check for early termination
  3182  					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
  3183  						options.stopOnFalse ) {
  3184  
  3185  						// Jump to end and forget the data so .add doesn't re-fire
  3186  						firingIndex = list.length;
  3187  						memory = false;
  3188  					}
  3189  				}
  3190  			}
  3191  
  3192  			// Forget the data if we're done with it
  3193  			if ( !options.memory ) {
  3194  				memory = false;
  3195  			}
  3196  
  3197  			firing = false;
  3198  
  3199  			// Clean up if we're done firing for good
  3200  			if ( locked ) {
  3201  
  3202  				// Keep an empty list if we have data for future add calls
  3203  				if ( memory ) {
  3204  					list = [];
  3205  
  3206  				// Otherwise, this object is spent
  3207  				} else {
  3208  					list = "";
  3209  				}
  3210  			}
  3211  		},
  3212  
  3213  		// Actual Callbacks object
  3214  		self = {
  3215  
  3216  			// Add a callback or a collection of callbacks to the list
  3217  			add: function() {
  3218  				if ( list ) {
  3219  
  3220  					// If we have memory from a past run, we should fire after adding
  3221  					if ( memory && !firing ) {
  3222  						firingIndex = list.length - 1;
  3223  						queue.push( memory );
  3224  					}
  3225  
  3226  					( function add( args ) {
  3227  						jQuery.each( args, function( _, arg ) {
  3228  							if ( jQuery.isFunction( arg ) ) {
  3229  								if ( !options.unique || !self.has( arg ) ) {
  3230  									list.push( arg );
  3231  								}
  3232  							} else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
  3233  
  3234  								// Inspect recursively
  3235  								add( arg );
  3236  							}
  3237  						} );
  3238  					} )( arguments );
  3239  
  3240  					if ( memory && !firing ) {
  3241  						fire();
  3242  					}
  3243  				}
  3244  				return this;
  3245  			},
  3246  
  3247  			// Remove a callback from the list
  3248  			remove: function() {
  3249  				jQuery.each( arguments, function( _, arg ) {
  3250  					var index;
  3251  					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
  3252  						list.splice( index, 1 );
  3253  
  3254  						// Handle firing indexes
  3255  						if ( index <= firingIndex ) {
  3256  							firingIndex--;
  3257  						}
  3258  					}
  3259  				} );
  3260  				return this;
  3261  			},
  3262  
  3263  			// Check if a given callback is in the list.
  3264  			// If no argument is given, return whether or not list has callbacks attached.
  3265  			has: function( fn ) {
  3266  				return fn ?
  3267  					jQuery.inArray( fn, list ) > -1 :
  3268  					list.length > 0;
  3269  			},
  3270  
  3271  			// Remove all callbacks from the list
  3272  			empty: function() {
  3273  				if ( list ) {
  3274  					list = [];
  3275  				}
  3276  				return this;
  3277  			},
  3278  
  3279  			// Disable .fire and .add
  3280  			// Abort any current/pending executions
  3281  			// Clear all callbacks and values
  3282  			disable: function() {
  3283  				locked = queue = [];
  3284  				list = memory = "";
  3285  				return this;
  3286  			},
  3287  			disabled: function() {
  3288  				return !list;
  3289  			},
  3290  
  3291  			// Disable .fire
  3292  			// Also disable .add unless we have memory (since it would have no effect)
  3293  			// Abort any pending executions
  3294  			lock: function() {
  3295  				locked = queue = [];
  3296  				if ( !memory ) {
  3297  					list = memory = "";
  3298  				}
  3299  				return this;
  3300  			},
  3301  			locked: function() {
  3302  				return !!locked;
  3303  			},
  3304  
  3305  			// Call all callbacks with the given context and arguments
  3306  			fireWith: function( context, args ) {
  3307  				if ( !locked ) {
  3308  					args = args || [];
  3309  					args = [ context, args.slice ? args.slice() : args ];
  3310  					queue.push( args );
  3311  					if ( !firing ) {
  3312  						fire();
  3313  					}
  3314  				}
  3315  				return this;
  3316  			},
  3317  
  3318  			// Call all the callbacks with the given arguments
  3319  			fire: function() {
  3320  				self.fireWith( this, arguments );
  3321  				return this;
  3322  			},
  3323  
  3324  			// To know if the callbacks have already been called at least once
  3325  			fired: function() {
  3326  				return !!fired;
  3327  			}
  3328  		};
  3329  
  3330  	return self;
  3331  };
  3332  
  3333  
  3334  jQuery.extend( {
  3335  
  3336  	Deferred: function( func ) {
  3337  		var tuples = [
  3338  
  3339  				// action, add listener, listener list, final state
  3340  				[ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ],
  3341  				[ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ],
  3342  				[ "notify", "progress", jQuery.Callbacks( "memory" ) ]
  3343  			],
  3344  			state = "pending",
  3345  			promise = {
  3346  				state: function() {
  3347  					return state;
  3348  				},
  3349  				always: function() {
  3350  					deferred.done( arguments ).fail( arguments );
  3351  					return this;
  3352  				},
  3353  				then: function( /* fnDone, fnFail, fnProgress */ ) {
  3354  					var fns = arguments;
  3355  					return jQuery.Deferred( function( newDefer ) {
  3356  						jQuery.each( tuples, function( i, tuple ) {
  3357  							var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
  3358  
  3359  							// deferred[ done | fail | progress ] for forwarding actions to newDefer
  3360  							deferred[ tuple[ 1 ] ]( function() {
  3361  								var returned = fn && fn.apply( this, arguments );
  3362  								if ( returned && jQuery.isFunction( returned.promise ) ) {
  3363  									returned.promise()
  3364  										.progress( newDefer.notify )
  3365  										.done( newDefer.resolve )
  3366  										.fail( newDefer.reject );
  3367  								} else {
  3368  									newDefer[ tuple[ 0 ] + "With" ](
  3369  										this === promise ? newDefer.promise() : this,
  3370  										fn ? [ returned ] : arguments
  3371  									);
  3372  								}
  3373  							} );
  3374  						} );
  3375  						fns = null;
  3376  					} ).promise();
  3377  				},
  3378  
  3379  				// Get a promise for this deferred
  3380  				// If obj is provided, the promise aspect is added to the object
  3381  				promise: function( obj ) {
  3382  					return obj != null ? jQuery.extend( obj, promise ) : promise;
  3383  				}
  3384  			},
  3385  			deferred = {};
  3386  
  3387  		// Keep pipe for back-compat
  3388  		promise.pipe = promise.then;
  3389  
  3390  		// Add list-specific methods
  3391  		jQuery.each( tuples, function( i, tuple ) {
  3392  			var list = tuple[ 2 ],
  3393  				stateString = tuple[ 3 ];
  3394  
  3395  			// promise[ done | fail | progress ] = list.add
  3396  			promise[ tuple[ 1 ] ] = list.add;
  3397  
  3398  			// Handle state
  3399  			if ( stateString ) {
  3400  				list.add( function() {
  3401  
  3402  					// state = [ resolved | rejected ]
  3403  					state = stateString;
  3404  
  3405  				// [ reject_list | resolve_list ].disable; progress_list.lock
  3406  				}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
  3407  			}
  3408  
  3409  			// deferred[ resolve | reject | notify ]
  3410  			deferred[ tuple[ 0 ] ] = function() {
  3411  				deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
  3412  				return this;
  3413  			};
  3414  			deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
  3415  		} );
  3416  
  3417  		// Make the deferred a promise
  3418  		promise.promise( deferred );
  3419  
  3420  		// Call given func if any
  3421  		if ( func ) {
  3422  			func.call( deferred, deferred );
  3423  		}
  3424  
  3425  		// All done!
  3426  		return deferred;
  3427  	},
  3428  
  3429  	// Deferred helper
  3430  	when: function( subordinate /* , ..., subordinateN */ ) {
  3431  		var i = 0,
  3432  			resolveValues = slice.call( arguments ),
  3433  			length = resolveValues.length,
  3434  
  3435  			// the count of uncompleted subordinates
  3436  			remaining = length !== 1 ||
  3437  				( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
  3438  
  3439  			// the master Deferred.
  3440  			// If resolveValues consist of only a single Deferred, just use that.
  3441  			deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
  3442  
  3443  			// Update function for both resolve and progress values
  3444  			updateFunc = function( i, contexts, values ) {
  3445  				return function( value ) {
  3446  					contexts[ i ] = this;
  3447  					values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
  3448  					if ( values === progressValues ) {
  3449  						deferred.notifyWith( contexts, values );
  3450  					} else if ( !( --remaining ) ) {
  3451  						deferred.resolveWith( contexts, values );
  3452  					}
  3453  				};
  3454  			},
  3455  
  3456  			progressValues, progressContexts, resolveContexts;
  3457  
  3458  		// Add listeners to Deferred subordinates; treat others as resolved
  3459  		if ( length > 1 ) {
  3460  			progressValues = new Array( length );
  3461  			progressContexts = new Array( length );
  3462  			resolveContexts = new Array( length );
  3463  			for ( ; i < length; i++ ) {
  3464  				if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
  3465  					resolveValues[ i ].promise()
  3466  						.progress( updateFunc( i, progressContexts, progressValues ) )
  3467  						.done( updateFunc( i, resolveContexts, resolveValues ) )
  3468  						.fail( deferred.reject );
  3469  				} else {
  3470  					--remaining;
  3471  				}
  3472  			}
  3473  		}
  3474  
  3475  		// If we're not waiting on anything, resolve the master
  3476  		if ( !remaining ) {
  3477  			deferred.resolveWith( resolveContexts, resolveValues );
  3478  		}
  3479  
  3480  		return deferred.promise();
  3481  	}
  3482  } );
  3483  
  3484  
  3485  // The deferred used on DOM ready
  3486  var readyList;
  3487  
  3488  jQuery.fn.ready = function( fn ) {
  3489  
  3490  	// Add the callback
  3491  	jQuery.ready.promise().done( fn );
  3492  
  3493  	return this;
  3494  };
  3495  
  3496  jQuery.extend( {
  3497  
  3498  	// Is the DOM ready to be used? Set to true once it occurs.
  3499  	isReady: false,
  3500  
  3501  	// A counter to track how many items to wait for before
  3502  	// the ready event fires. See #6781
  3503  	readyWait: 1,
  3504  
  3505  	// Hold (or release) the ready event
  3506  	holdReady: function( hold ) {
  3507  		if ( hold ) {
  3508  			jQuery.readyWait++;
  3509  		} else {
  3510  			jQuery.ready( true );
  3511  		}
  3512  	},
  3513  
  3514  	// Handle when the DOM is ready
  3515  	ready: function( wait ) {
  3516  
  3517  		// Abort if there are pending holds or we're already ready
  3518  		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
  3519  			return;
  3520  		}
  3521  
  3522  		// Remember that the DOM is ready
  3523  		jQuery.isReady = true;
  3524  
  3525  		// If a normal DOM Ready event fired, decrement, and wait if need be
  3526  		if ( wait !== true && --jQuery.readyWait > 0 ) {
  3527  			return;
  3528  		}
  3529  
  3530  		// If there are functions bound, to execute
  3531  		readyList.resolveWith( document, [ jQuery ] );
  3532  
  3533  		// Trigger any bound ready events
  3534  		if ( jQuery.fn.triggerHandler ) {
  3535  			jQuery( document ).triggerHandler( "ready" );
  3536  			jQuery( document ).off( "ready" );
  3537  		}
  3538  	}
  3539  } );
  3540  
  3541  /**
  3542   * The ready event handler and self cleanup method
  3543   */
  3544  function completed() {
  3545  	document.removeEventListener( "DOMContentLoaded", completed );
  3546  	window.removeEventListener( "load", completed );
  3547  	jQuery.ready();
  3548  }
  3549  
  3550  jQuery.ready.promise = function( obj ) {
  3551  	if ( !readyList ) {
  3552  
  3553  		readyList = jQuery.Deferred();
  3554  
  3555  		// Catch cases where $(document).ready() is called
  3556  		// after the browser event has already occurred.
  3557  		// Support: IE9-10 only
  3558  		// Older IE sometimes signals "interactive" too soon
  3559  		if ( document.readyState === "complete" ||
  3560  			( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
  3561  
  3562  			// Handle it asynchronously to allow scripts the opportunity to delay ready
  3563  			window.setTimeout( jQuery.ready );
  3564  
  3565  		} else {
  3566  
  3567  			// Use the handy event callback
  3568  			document.addEventListener( "DOMContentLoaded", completed );
  3569  
  3570  			// A fallback to window.onload, that will always work
  3571  			window.addEventListener( "load", completed );
  3572  		}
  3573  	}
  3574  	return readyList.promise( obj );
  3575  };
  3576  
  3577  // Kick off the DOM ready check even if the user does not
  3578  jQuery.ready.promise();
  3579  
  3580  
  3581  
  3582  
  3583  // Multifunctional method to get and set values of a collection
  3584  // The value/s can optionally be executed if it's a function
  3585  var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
  3586  	var i = 0,
  3587  		len = elems.length,
  3588  		bulk = key == null;
  3589  
  3590  	// Sets many values
  3591  	if ( jQuery.type( key ) === "object" ) {
  3592  		chainable = true;
  3593  		for ( i in key ) {
  3594  			access( elems, fn, i, key[ i ], true, emptyGet, raw );
  3595  		}
  3596  
  3597  	// Sets one value
  3598  	} else if ( value !== undefined ) {
  3599  		chainable = true;
  3600  
  3601  		if ( !jQuery.isFunction( value ) ) {
  3602  			raw = true;
  3603  		}
  3604  
  3605  		if ( bulk ) {
  3606  
  3607  			// Bulk operations run against the entire set
  3608  			if ( raw ) {
  3609  				fn.call( elems, value );
  3610  				fn = null;
  3611  
  3612  			// ...except when executing function values
  3613  			} else {
  3614  				bulk = fn;
  3615  				fn = function( elem, key, value ) {
  3616  					return bulk.call( jQuery( elem ), value );
  3617  				};
  3618  			}
  3619  		}
  3620  
  3621  		if ( fn ) {
  3622  			for ( ; i < len; i++ ) {
  3623  				fn(
  3624  					elems[ i ], key, raw ?
  3625  					value :
  3626  					value.call( elems[ i ], i, fn( elems[ i ], key ) )
  3627  				);
  3628  			}
  3629  		}
  3630  	}
  3631  
  3632  	return chainable ?
  3633  		elems :
  3634  
  3635  		// Gets
  3636  		bulk ?
  3637  			fn.call( elems ) :
  3638  			len ? fn( elems[ 0 ], key ) : emptyGet;
  3639  };
  3640  var acceptData = function( owner ) {
  3641  
  3642  	// Accepts only:
  3643  	//  - Node
  3644  	//    - Node.ELEMENT_NODE
  3645  	//    - Node.DOCUMENT_NODE
  3646  	//  - Object
  3647  	//    - Any
  3648  	/* jshint -W018 */
  3649  	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
  3650  };
  3651  
  3652  
  3653  
  3654  
  3655  function Data() {
  3656  	this.expando = jQuery.expando + Data.uid++;
  3657  }
  3658  
  3659  Data.uid = 1;
  3660  
  3661  Data.prototype = {
  3662  
  3663  	register: function( owner, initial ) {
  3664  		var value = initial || {};
  3665  
  3666  		// If it is a node unlikely to be stringify-ed or looped over
  3667  		// use plain assignment
  3668  		if ( owner.nodeType ) {
  3669  			owner[ this.expando ] = value;
  3670  
  3671  		// Otherwise secure it in a non-enumerable, non-writable property
  3672  		// configurability must be true to allow the property to be
  3673  		// deleted with the delete operator
  3674  		} else {
  3675  			Object.defineProperty( owner, this.expando, {
  3676  				value: value,
  3677  				writable: true,
  3678  				configurable: true
  3679  			} );
  3680  		}
  3681  		return owner[ this.expando ];
  3682  	},
  3683  	cache: function( owner ) {
  3684  
  3685  		// We can accept data for non-element nodes in modern browsers,
  3686  		// but we should not, see #8335.
  3687  		// Always return an empty object.
  3688  		if ( !acceptData( owner ) ) {
  3689  			return {};
  3690  		}
  3691  
  3692  		// Check if the owner object already has a cache
  3693  		var value = owner[ this.expando ];
  3694  
  3695  		// If not, create one
  3696  		if ( !value ) {
  3697  			value = {};
  3698  
  3699  			// We can accept data for non-element nodes in modern browsers,
  3700  			// but we should not, see #8335.
  3701  			// Always return an empty object.
  3702  			if ( acceptData( owner ) ) {
  3703  
  3704  				// If it is a node unlikely to be stringify-ed or looped over
  3705  				// use plain assignment
  3706  				if ( owner.nodeType ) {
  3707  					owner[ this.expando ] = value;
  3708  
  3709  				// Otherwise secure it in a non-enumerable property
  3710  				// configurable must be true to allow the property to be
  3711  				// deleted when data is removed
  3712  				} else {
  3713  					Object.defineProperty( owner, this.expando, {
  3714  						value: value,
  3715  						configurable: true
  3716  					} );
  3717  				}
  3718  			}
  3719  		}
  3720  
  3721  		return value;
  3722  	},
  3723  	set: function( owner, data, value ) {
  3724  		var prop,
  3725  			cache = this.cache( owner );
  3726  
  3727  		// Handle: [ owner, key, value ] args
  3728  		if ( typeof data === "string" ) {
  3729  			cache[ data ] = value;
  3730  
  3731  		// Handle: [ owner, { properties } ] args
  3732  		} else {
  3733  
  3734  			// Copy the properties one-by-one to the cache object
  3735  			for ( prop in data ) {
  3736  				cache[ prop ] = data[ prop ];
  3737  			}
  3738  		}
  3739  		return cache;
  3740  	},
  3741  	get: function( owner, key ) {
  3742  		return key === undefined ?
  3743  			this.cache( owner ) :
  3744  			owner[ this.expando ] && owner[ this.expando ][ key ];
  3745  	},
  3746  	access: function( owner, key, value ) {
  3747  		var stored;
  3748  
  3749  		// In cases where either:
  3750  		//
  3751  		//   1. No key was specified
  3752  		//   2. A string key was specified, but no value provided
  3753  		//
  3754  		// Take the "read" path and allow the get method to determine
  3755  		// which value to return, respectively either:
  3756  		//
  3757  		//   1. The entire cache object
  3758  		//   2. The data stored at the key
  3759  		//
  3760  		if ( key === undefined ||
  3761  				( ( key && typeof key === "string" ) && value === undefined ) ) {
  3762  
  3763  			stored = this.get( owner, key );
  3764  
  3765  			return stored !== undefined ?
  3766  				stored : this.get( owner, jQuery.camelCase( key ) );
  3767  		}
  3768  
  3769  		// When the key is not a string, or both a key and value
  3770  		// are specified, set or extend (existing objects) with either:
  3771  		//
  3772  		//   1. An object of properties
  3773  		//   2. A key and value
  3774  		//
  3775  		this.set( owner, key, value );
  3776  
  3777  		// Since the "set" path can have two possible entry points
  3778  		// return the expected data based on which path was taken[*]
  3779  		return value !== undefined ? value : key;
  3780  	},
  3781  	remove: function( owner, key ) {
  3782  		var i, name, camel,
  3783  			cache = owner[ this.expando ];
  3784  
  3785  		if ( cache === undefined ) {
  3786  			return;
  3787  		}
  3788  
  3789  		if ( key === undefined ) {
  3790  			this.register( owner );
  3791  
  3792  		} else {
  3793  
  3794  			// Support array or space separated string of keys
  3795  			if ( jQuery.isArray( key ) ) {
  3796  
  3797  				// If "name" is an array of keys...
  3798  				// When data is initially created, via ("key", "val") signature,
  3799  				// keys will be converted to camelCase.
  3800  				// Since there is no way to tell _how_ a key was added, remove
  3801  				// both plain key and camelCase key. #12786
  3802  				// This will only penalize the array argument path.
  3803  				name = key.concat( key.map( jQuery.camelCase ) );
  3804  			} else {
  3805  				camel = jQuery.camelCase( key );
  3806  
  3807  				// Try the string as a key before any manipulation
  3808  				if ( key in cache ) {
  3809  					name = [ key, camel ];
  3810  				} else {
  3811  
  3812  					// If a key with the spaces exists, use it.
  3813  					// Otherwise, create an array by matching non-whitespace
  3814  					name = camel;
  3815  					name = name in cache ?
  3816  						[ name ] : ( name.match( rnotwhite ) || [] );
  3817  				}
  3818  			}
  3819  
  3820  			i = name.length;
  3821  
  3822  			while ( i-- ) {
  3823  				delete cache[ name[ i ] ];
  3824  			}
  3825  		}
  3826  
  3827  		// Remove the expando if there's no more data
  3828  		if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
  3829  
  3830  			// Support: Chrome <= 35-45+
  3831  			// Webkit & Blink performance suffers when deleting properties
  3832  			// from DOM nodes, so set to undefined instead
  3833  			// https://code.google.com/p/chromium/issues/detail?id=378607
  3834  			if ( owner.nodeType ) {
  3835  				owner[ this.expando ] = undefined;
  3836  			} else {
  3837  				delete owner[ this.expando ];
  3838  			}
  3839  		}
  3840  	},
  3841  	hasData: function( owner ) {
  3842  		var cache = owner[ this.expando ];
  3843  		return cache !== undefined && !jQuery.isEmptyObject( cache );
  3844  	}
  3845  };
  3846  var dataPriv = new Data();
  3847  
  3848  var dataUser = new Data();
  3849  
  3850  
  3851  
  3852  //	Implementation Summary
  3853  //
  3854  //	1. Enforce API surface and semantic compatibility with 1.9.x branch
  3855  //	2. Improve the module's maintainability by reducing the storage
  3856  //		paths to a single mechanism.
  3857  //	3. Use the same single mechanism to support "private" and "user" data.
  3858  //	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
  3859  //	5. Avoid exposing implementation details on user objects (eg. expando properties)
  3860  //	6. Provide a clear path for implementation upgrade to WeakMap in 2014
  3861  
  3862  var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
  3863  	rmultiDash = /[A-Z]/g;
  3864  
  3865  function dataAttr( elem, key, data ) {
  3866  	var name;
  3867  
  3868  	// If nothing was found internally, try to fetch any
  3869  	// data from the HTML5 data-* attribute
  3870  	if ( data === undefined && elem.nodeType === 1 ) {
  3871  		name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
  3872  		data = elem.getAttribute( name );
  3873  
  3874  		if ( typeof data === "string" ) {
  3875  			try {
  3876  				data = data === "true" ? true :
  3877  					data === "false" ? false :
  3878  					data === "null" ? null :
  3879  
  3880  					// Only convert to a number if it doesn't change the string
  3881  					+data + "" === data ? +data :
  3882  					rbrace.test( data ) ? jQuery.parseJSON( data ) :
  3883  					data;
  3884  			} catch ( e ) {}
  3885  
  3886  			// Make sure we set the data so it isn't changed later
  3887  			dataUser.set( elem, key, data );
  3888  		} else {
  3889  			data = undefined;
  3890  		}
  3891  	}
  3892  	return data;
  3893  }
  3894  
  3895  jQuery.extend( {
  3896  	hasData: function( elem ) {
  3897  		return dataUser.hasData( elem ) || dataPriv.hasData( elem );
  3898  	},
  3899  
  3900  	data: function( elem, name, data ) {
  3901  		return dataUser.access( elem, name, data );
  3902  	},
  3903  
  3904  	removeData: function( elem, name ) {
  3905  		dataUser.remove( elem, name );
  3906  	},
  3907  
  3908  	// TODO: Now that all calls to _data and _removeData have been replaced
  3909  	// with direct calls to dataPriv methods, these can be deprecated.
  3910  	_data: function( elem, name, data ) {
  3911  		return dataPriv.access( elem, name, data );
  3912  	},
  3913  
  3914  	_removeData: function( elem, name ) {
  3915  		dataPriv.remove( elem, name );
  3916  	}
  3917  } );
  3918  
  3919  jQuery.fn.extend( {
  3920  	data: function( key, value ) {
  3921  		var i, name, data,
  3922  			elem = this[ 0 ],
  3923  			attrs = elem && elem.attributes;
  3924  
  3925  		// Gets all values
  3926  		if ( key === undefined ) {
  3927  			if ( this.length ) {
  3928  				data = dataUser.get( elem );
  3929  
  3930  				if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
  3931  					i = attrs.length;
  3932  					while ( i-- ) {
  3933  
  3934  						// Support: IE11+
  3935  						// The attrs elements can be null (#14894)
  3936  						if ( attrs[ i ] ) {
  3937  							name = attrs[ i ].name;
  3938  							if ( name.indexOf( "data-" ) === 0 ) {
  3939  								name = jQuery.camelCase( name.slice( 5 ) );
  3940  								dataAttr( elem, name, data[ name ] );
  3941  							}
  3942  						}
  3943  					}
  3944  					dataPriv.set( elem, "hasDataAttrs", true );
  3945  				}
  3946  			}
  3947  
  3948  			return data;
  3949  		}
  3950  
  3951  		// Sets multiple values
  3952  		if ( typeof key === "object" ) {
  3953  			return this.each( function() {
  3954  				dataUser.set( this, key );
  3955  			} );
  3956  		}
  3957  
  3958  		return access( this, function( value ) {
  3959  			var data, camelKey;
  3960  
  3961  			// The calling jQuery object (element matches) is not empty
  3962  			// (and therefore has an element appears at this[ 0 ]) and the
  3963  			// `value` parameter was not undefined. An empty jQuery object
  3964  			// will result in `undefined` for elem = this[ 0 ] which will
  3965  			// throw an exception if an attempt to read a data cache is made.
  3966  			if ( elem && value === undefined ) {
  3967  
  3968  				// Attempt to get data from the cache
  3969  				// with the key as-is
  3970  				data = dataUser.get( elem, key ) ||
  3971  
  3972  					// Try to find dashed key if it exists (gh-2779)
  3973  					// This is for 2.2.x only
  3974  					dataUser.get( elem, key.replace( rmultiDash, "-$&" ).toLowerCase() );
  3975  
  3976  				if ( data !== undefined ) {
  3977  					return data;
  3978  				}
  3979  
  3980  				camelKey = jQuery.camelCase( key );
  3981  
  3982  				// Attempt to get data from the cache
  3983  				// with the key camelized
  3984  				data = dataUser.get( elem, camelKey );
  3985  				if ( data !== undefined ) {
  3986  					return data;
  3987  				}
  3988  
  3989  				// Attempt to "discover" the data in
  3990  				// HTML5 custom data-* attrs
  3991  				data = dataAttr( elem, camelKey, undefined );
  3992  				if ( data !== undefined ) {
  3993  					return data;
  3994  				}
  3995  
  3996  				// We tried really hard, but the data doesn't exist.
  3997  				return;
  3998  			}
  3999  
  4000  			// Set the data...
  4001  			camelKey = jQuery.camelCase( key );
  4002  			this.each( function() {
  4003  
  4004  				// First, attempt to store a copy or reference of any
  4005  				// data that might've been store with a camelCased key.
  4006  				var data = dataUser.get( this, camelKey );
  4007  
  4008  				// For HTML5 data-* attribute interop, we have to
  4009  				// store property names with dashes in a camelCase form.
  4010  				// This might not apply to all properties...*
  4011  				dataUser.set( this, camelKey, value );
  4012  
  4013  				// *... In the case of properties that might _actually_
  4014  				// have dashes, we need to also store a copy of that
  4015  				// unchanged property.
  4016  				if ( key.indexOf( "-" ) > -1 && data !== undefined ) {
  4017  					dataUser.set( this, key, value );
  4018  				}
  4019  			} );
  4020  		}, null, value, arguments.length > 1, null, true );
  4021  	},
  4022  
  4023  	removeData: function( key ) {
  4024  		return this.each( function() {
  4025  			dataUser.remove( this, key );
  4026  		} );
  4027  	}
  4028  } );
  4029  
  4030  
  4031  jQuery.extend( {
  4032  	queue: function( elem, type, data ) {
  4033  		var queue;
  4034  
  4035  		if ( elem ) {
  4036  			type = ( type || "fx" ) + "queue";
  4037  			queue = dataPriv.get( elem, type );
  4038  
  4039  			// Speed up dequeue by getting out quickly if this is just a lookup
  4040  			if ( data ) {
  4041  				if ( !queue || jQuery.isArray( data ) ) {
  4042  					queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
  4043  				} else {
  4044  					queue.push( data );
  4045  				}
  4046  			}
  4047  			return queue || [];
  4048  		}
  4049  	},
  4050  
  4051  	dequeue: function( elem, type ) {
  4052  		type = type || "fx";
  4053  
  4054  		var queue = jQuery.queue( elem, type ),
  4055  			startLength = queue.length,
  4056  			fn = queue.shift(),
  4057  			hooks = jQuery._queueHooks( elem, type ),
  4058  			next = function() {
  4059  				jQuery.dequeue( elem, type );
  4060  			};
  4061  
  4062  		// If the fx queue is dequeued, always remove the progress sentinel
  4063  		if ( fn === "inprogress" ) {
  4064  			fn = queue.shift();
  4065  			startLength--;
  4066  		}
  4067  
  4068  		if ( fn ) {
  4069  
  4070  			// Add a progress sentinel to prevent the fx queue from being
  4071  			// automatically dequeued
  4072  			if ( type === "fx" ) {
  4073  				queue.unshift( "inprogress" );
  4074  			}
  4075  
  4076  			// Clear up the last queue stop function
  4077  			delete hooks.stop;
  4078  			fn.call( elem, next, hooks );
  4079  		}
  4080  
  4081  		if ( !startLength && hooks ) {
  4082  			hooks.empty.fire();
  4083  		}
  4084  	},
  4085  
  4086  	// Not public - generate a queueHooks object, or return the current one
  4087  	_queueHooks: function( elem, type ) {
  4088  		var key = type + "queueHooks";
  4089  		return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
  4090  			empty: jQuery.Callbacks( "once memory" ).add( function() {
  4091  				dataPriv.remove( elem, [ type + "queue", key ] );
  4092  			} )
  4093  		} );
  4094  	}
  4095  } );
  4096  
  4097  jQuery.fn.extend( {
  4098  	queue: function( type, data ) {
  4099  		var setter = 2;
  4100  
  4101  		if ( typeof type !== "string" ) {
  4102  			data = type;
  4103  			type = "fx";
  4104  			setter--;
  4105  		}
  4106  
  4107  		if ( arguments.length < setter ) {
  4108  			return jQuery.queue( this[ 0 ], type );
  4109  		}
  4110  
  4111  		return data === undefined ?
  4112  			this :
  4113  			this.each( function() {
  4114  				var queue = jQuery.queue( this, type, data );
  4115  
  4116  				// Ensure a hooks for this queue
  4117  				jQuery._queueHooks( this, type );
  4118  
  4119  				if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
  4120  					jQuery.dequeue( this, type );
  4121  				}
  4122  			} );
  4123  	},
  4124  	dequeue: function( type ) {
  4125  		return this.each( function() {
  4126  			jQuery.dequeue( this, type );
  4127  		} );
  4128  	},
  4129  	clearQueue: function( type ) {
  4130  		return this.queue( type || "fx", [] );
  4131  	},
  4132  
  4133  	// Get a promise resolved when queues of a certain type
  4134  	// are emptied (fx is the type by default)
  4135  	promise: function( type, obj ) {
  4136  		var tmp,
  4137  			count = 1,
  4138  			defer = jQuery.Deferred(),
  4139  			elements = this,
  4140  			i = this.length,
  4141  			resolve = function() {
  4142  				if ( !( --count ) ) {
  4143  					defer.resolveWith( elements, [ elements ] );
  4144  				}
  4145  			};
  4146  
  4147  		if ( typeof type !== "string" ) {
  4148  			obj = type;
  4149  			type = undefined;
  4150  		}
  4151  		type = type || "fx";
  4152  
  4153  		while ( i-- ) {
  4154  			tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
  4155  			if ( tmp && tmp.empty ) {
  4156  				count++;
  4157  				tmp.empty.add( resolve );
  4158  			}
  4159  		}
  4160  		resolve();
  4161  		return defer.promise( obj );
  4162  	}
  4163  } );
  4164  var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
  4165  
  4166  var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
  4167  
  4168  
  4169  var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
  4170  
  4171  var isHidden = function( elem, el ) {
  4172  
  4173  		// isHidden might be called from jQuery#filter function;
  4174  		// in that case, element will be second argument
  4175  		elem = el || elem;
  4176  		return jQuery.css( elem, "display" ) === "none" ||
  4177  			!jQuery.contains( elem.ownerDocument, elem );
  4178  	};
  4179  
  4180  
  4181  
  4182  function adjustCSS( elem, prop, valueParts, tween ) {
  4183  	var adjusted,
  4184  		scale = 1,
  4185  		maxIterations = 20,
  4186  		currentValue = tween ?
  4187  			function() { return tween.cur(); } :
  4188  			function() { return jQuery.css( elem, prop, "" ); },
  4189  		initial = currentValue(),
  4190  		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
  4191  
  4192  		// Starting value computation is required for potential unit mismatches
  4193  		initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
  4194  			rcssNum.exec( jQuery.css( elem, prop ) );
  4195  
  4196  	if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
  4197  
  4198  		// Trust units reported by jQuery.css
  4199  		unit = unit || initialInUnit[ 3 ];
  4200  
  4201  		// Make sure we update the tween properties later on
  4202  		valueParts = valueParts || [];
  4203  
  4204  		// Iteratively approximate from a nonzero starting point
  4205  		initialInUnit = +initial || 1;
  4206  
  4207  		do {
  4208  
  4209  			// If previous iteration zeroed out, double until we get *something*.
  4210  			// Use string for doubling so we don't accidentally see scale as unchanged below
  4211  			scale = scale || ".5";
  4212  
  4213  			// Adjust and apply
  4214  			initialInUnit = initialInUnit / scale;
  4215  			jQuery.style( elem, prop, initialInUnit + unit );
  4216  
  4217  		// Update scale, tolerating zero or NaN from tween.cur()
  4218  		// Break the loop if scale is unchanged or perfect, or if we've just had enough.
  4219  		} while (
  4220  			scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
  4221  		);
  4222  	}
  4223  
  4224  	if ( valueParts ) {
  4225  		initialInUnit = +initialInUnit || +initial || 0;
  4226  
  4227  		// Apply relative offset (+=/-=) if specified
  4228  		adjusted = valueParts[ 1 ] ?
  4229  			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
  4230  			+valueParts[ 2 ];
  4231  		if ( tween ) {
  4232  			tween.unit = unit;
  4233  			tween.start = initialInUnit;
  4234  			tween.end = adjusted;
  4235  		}
  4236  	}
  4237  	return adjusted;
  4238  }
  4239  var rcheckableType = ( /^(?:checkbox|radio)$/i );
  4240  
  4241  var rtagName = ( /<([\w:-]+)/ );
  4242  
  4243  var rscriptType = ( /^$|\/(?:java|ecma)script/i );
  4244  
  4245  
  4246  
  4247  // We have to close these tags to support XHTML (#13200)
  4248  var wrapMap = {
  4249  
  4250  	// Support: IE9
  4251  	option: [ 1, "<select multiple='multiple'>", "</select>" ],
  4252  
  4253  	// XHTML parsers do not magically insert elements in the
  4254  	// same way that tag soup parsers do. So we cannot shorten
  4255  	// this by omitting <tbody> or other required elements.
  4256  	thead: [ 1, "<table>", "</table>" ],
  4257  	col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
  4258  	tr: [ 2, "<table><tbody>", "</tbody></table>" ],
  4259  	td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
  4260  
  4261  	_default: [ 0, "", "" ]
  4262  };
  4263  
  4264  // Support: IE9
  4265  wrapMap.optgroup = wrapMap.option;
  4266  
  4267  wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
  4268  wrapMap.th = wrapMap.td;
  4269  
  4270  
  4271  function getAll( context, tag ) {
  4272  
  4273  	// Support: IE9-11+
  4274  	// Use typeof to avoid zero-argument method invocation on host objects (#15151)
  4275  	var ret = typeof context.getElementsByTagName !== "undefined" ?
  4276  			context.getElementsByTagName( tag || "*" ) :
  4277  			typeof context.querySelectorAll !== "undefined" ?
  4278  				context.querySelectorAll( tag || "*" ) :
  4279  			[];
  4280  
  4281  	return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
  4282  		jQuery.merge( [ context ], ret ) :
  4283  		ret;
  4284  }
  4285  
  4286  
  4287  // Mark scripts as having already been evaluated
  4288  function setGlobalEval( elems, refElements ) {
  4289  	var i = 0,
  4290  		l = elems.length;
  4291  
  4292  	for ( ; i < l; i++ ) {
  4293  		dataPriv.set(
  4294  			elems[ i ],
  4295  			"globalEval",
  4296  			!refElements || dataPriv.get( refElements[ i ], "globalEval" )
  4297  		);
  4298  	}
  4299  }
  4300  
  4301  
  4302  var rhtml = /<|&#?\w+;/;
  4303  
  4304  function buildFragment( elems, context, scripts, selection, ignored ) {
  4305  	var elem, tmp, tag, wrap, contains, j,
  4306  		fragment = context.createDocumentFragment(),
  4307  		nodes = [],
  4308  		i = 0,
  4309  		l = elems.length;
  4310  
  4311  	for ( ; i < l; i++ ) {
  4312  		elem = elems[ i ];
  4313  
  4314  		if ( elem || elem === 0 ) {
  4315  
  4316  			// Add nodes directly
  4317  			if ( jQuery.type( elem ) === "object" ) {
  4318  
  4319  				// Support: Android<4.1, PhantomJS<2
  4320  				// push.apply(_, arraylike) throws on ancient WebKit
  4321  				jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
  4322  
  4323  			// Convert non-html into a text node
  4324  			} else if ( !rhtml.test( elem ) ) {
  4325  				nodes.push( context.createTextNode( elem ) );
  4326  
  4327  			// Convert html into DOM nodes
  4328  			} else {
  4329  				tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
  4330  
  4331  				// Deserialize a standard representation
  4332  				tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
  4333  				wrap = wrapMap[ tag ] || wrapMap._default;
  4334  				tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
  4335  
  4336  				// Descend through wrappers to the right content
  4337  				j = wrap[ 0 ];
  4338  				while ( j-- ) {
  4339  					tmp = tmp.lastChild;
  4340  				}
  4341  
  4342  				// Support: Android<4.1, PhantomJS<2
  4343  				// push.apply(_, arraylike) throws on ancient WebKit
  4344  				jQuery.merge( nodes, tmp.childNodes );
  4345  
  4346  				// Remember the top-level container
  4347  				tmp = fragment.firstChild;
  4348  
  4349  				// Ensure the created nodes are orphaned (#12392)
  4350  				tmp.textContent = "";
  4351  			}
  4352  		}
  4353  	}
  4354  
  4355  	// Remove wrapper from fragment
  4356  	fragment.textContent = "";
  4357  
  4358  	i = 0;
  4359  	while ( ( elem = nodes[ i++ ] ) ) {
  4360  
  4361  		// Skip elements already in the context collection (trac-4087)
  4362  		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
  4363  			if ( ignored ) {
  4364  				ignored.push( elem );
  4365  			}
  4366  			continue;
  4367  		}
  4368  
  4369  		contains = jQuery.contains( elem.ownerDocument, elem );
  4370  
  4371  		// Append to fragment
  4372  		tmp = getAll( fragment.appendChild( elem ), "script" );
  4373  
  4374  		// Preserve script evaluation history
  4375  		if ( contains ) {
  4376  			setGlobalEval( tmp );
  4377  		}
  4378  
  4379  		// Capture executables
  4380  		if ( scripts ) {
  4381  			j = 0;
  4382  			while ( ( elem = tmp[ j++ ] ) ) {
  4383  				if ( rscriptType.test( elem.type || "" ) ) {
  4384  					scripts.push( elem );
  4385  				}
  4386  			}
  4387  		}
  4388  	}
  4389  
  4390  	return fragment;
  4391  }
  4392  
  4393  
  4394  ( function() {
  4395  	var fragment = document.createDocumentFragment(),
  4396  		div = fragment.appendChild( document.createElement( "div" ) ),
  4397  		input = document.createElement( "input" );
  4398  
  4399  	// Support: Android 4.0-4.3, Safari<=5.1
  4400  	// Check state lost if the name is set (#11217)
  4401  	// Support: Windows Web Apps (WWA)
  4402  	// `name` and `type` must use .setAttribute for WWA (#14901)
  4403  	input.setAttribute( "type", "radio" );
  4404  	input.setAttribute( "checked", "checked" );
  4405  	input.setAttribute( "name", "t" );
  4406  
  4407  	div.appendChild( input );
  4408  
  4409  	// Support: Safari<=5.1, Android<4.2
  4410  	// Older WebKit doesn't clone checked state correctly in fragments
  4411  	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
  4412  
  4413  	// Support: IE<=11+
  4414  	// Make sure textarea (and checkbox) defaultValue is properly cloned
  4415  	div.innerHTML = "<textarea>x</textarea>";
  4416  	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
  4417  } )();
  4418  
  4419  
  4420  var
  4421  	rkeyEvent = /^key/,
  4422  	rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
  4423  	rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
  4424  
  4425  function returnTrue() {
  4426  	return true;
  4427  }
  4428  
  4429  function returnFalse() {
  4430  	return false;
  4431  }
  4432  
  4433  // Support: IE9
  4434  // See #13393 for more info
  4435  function safeActiveElement() {
  4436  	try {
  4437  		return document.activeElement;
  4438  	} catch ( err ) { }
  4439  }
  4440  
  4441  function on( elem, types, selector, data, fn, one ) {
  4442  	var origFn, type;
  4443  
  4444  	// Types can be a map of types/handlers
  4445  	if ( typeof types === "object" ) {
  4446  
  4447  		// ( types-Object, selector, data )
  4448  		if ( typeof selector !== "string" ) {
  4449  
  4450  			// ( types-Object, data )
  4451  			data = data || selector;
  4452  			selector = undefined;
  4453  		}
  4454  		for ( type in types ) {
  4455  			on( elem, type, selector, data, types[ type ], one );
  4456  		}
  4457  		return elem;
  4458  	}
  4459  
  4460  	if ( data == null && fn == null ) {
  4461  
  4462  		// ( types, fn )
  4463  		fn = selector;
  4464  		data = selector = undefined;
  4465  	} else if ( fn == null ) {
  4466  		if ( typeof selector === "string" ) {
  4467  
  4468  			// ( types, selector, fn )
  4469  			fn = data;
  4470  			data = undefined;
  4471  		} else {
  4472  
  4473  			// ( types, data, fn )
  4474  			fn = data;
  4475  			data = selector;
  4476  			selector = undefined;
  4477  		}
  4478  	}
  4479  	if ( fn === false ) {
  4480  		fn = returnFalse;
  4481  	} else if ( !fn ) {
  4482  		return this;
  4483  	}
  4484  
  4485  	if ( one === 1 ) {
  4486  		origFn = fn;
  4487  		fn = function( event ) {
  4488  
  4489  			// Can use an empty set, since event contains the info
  4490  			jQuery().off( event );
  4491  			return origFn.apply( this, arguments );
  4492  		};
  4493  
  4494  		// Use same guid so caller can remove using origFn
  4495  		fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
  4496  	}
  4497  	return elem.each( function() {
  4498  		jQuery.event.add( this, types, fn, data, selector );
  4499  	} );
  4500  }
  4501  
  4502  /*
  4503   * Helper functions for managing events -- not part of the public interface.
  4504   * Props to Dean Edwards' addEvent library for many of the ideas.
  4505   */
  4506  jQuery.event = {
  4507  
  4508  	global: {},
  4509  
  4510  	add: function( elem, types, handler, data, selector ) {
  4511  
  4512  		var handleObjIn, eventHandle, tmp,
  4513  			events, t, handleObj,
  4514  			special, handlers, type, namespaces, origType,
  4515  			elemData = dataPriv.get( elem );
  4516  
  4517  		// Don't attach events to noData or text/comment nodes (but allow plain objects)
  4518  		if ( !elemData ) {
  4519  			return;
  4520  		}
  4521  
  4522  		// Caller can pass in an object of custom data in lieu of the handler
  4523  		if ( handler.handler ) {
  4524  			handleObjIn = handler;
  4525  			handler = handleObjIn.handler;
  4526  			selector = handleObjIn.selector;
  4527  		}
  4528  
  4529  		// Make sure that the handler has a unique ID, used to find/remove it later
  4530  		if ( !handler.guid ) {
  4531  			handler.guid = jQuery.guid++;
  4532  		}
  4533  
  4534  		// Init the element's event structure and main handler, if this is the first
  4535  		if ( !( events = elemData.events ) ) {
  4536  			events = elemData.events = {};
  4537  		}
  4538  		if ( !( eventHandle = elemData.handle ) ) {
  4539  			eventHandle = elemData.handle = function( e ) {
  4540  
  4541  				// Discard the second event of a jQuery.event.trigger() and
  4542  				// when an event is called after a page has unloaded
  4543  				return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
  4544  					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
  4545  			};
  4546  		}
  4547  
  4548  		// Handle multiple events separated by a space
  4549  		types = ( types || "" ).match( rnotwhite ) || [ "" ];
  4550  		t = types.length;
  4551  		while ( t-- ) {
  4552  			tmp = rtypenamespace.exec( types[ t ] ) || [];
  4553  			type = origType = tmp[ 1 ];
  4554  			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
  4555  
  4556  			// There *must* be a type, no attaching namespace-only handlers
  4557  			if ( !type ) {
  4558  				continue;
  4559  			}
  4560  
  4561  			// If event changes its type, use the special event handlers for the changed type
  4562  			special = jQuery.event.special[ type ] || {};
  4563  
  4564  			// If selector defined, determine special event api type, otherwise given type
  4565  			type = ( selector ? special.delegateType : special.bindType ) || type;
  4566  
  4567  			// Update special based on newly reset type
  4568  			special = jQuery.event.special[ type ] || {};
  4569  
  4570  			// handleObj is passed to all event handlers
  4571  			handleObj = jQuery.extend( {
  4572  				type: type,
  4573  				origType: origType,
  4574  				data: data,
  4575  				handler: handler,
  4576  				guid: handler.guid,
  4577  				selector: selector,
  4578  				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
  4579  				namespace: namespaces.join( "." )
  4580  			}, handleObjIn );
  4581  
  4582  			// Init the event handler queue if we're the first
  4583  			if ( !( handlers = events[ type ] ) ) {
  4584  				handlers = events[ type ] = [];
  4585  				handlers.delegateCount = 0;
  4586  
  4587  				// Only use addEventListener if the special events handler returns false
  4588  				if ( !special.setup ||
  4589  					special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
  4590  
  4591  					if ( elem.addEventListener ) {
  4592  						elem.addEventListener( type, eventHandle );
  4593  					}
  4594  				}
  4595  			}
  4596  
  4597  			if ( special.add ) {
  4598  				special.add.call( elem, handleObj );
  4599  
  4600  				if ( !handleObj.handler.guid ) {
  4601  					handleObj.handler.guid = handler.guid;
  4602  				}
  4603  			}
  4604  
  4605  			// Add to the element's handler list, delegates in front
  4606  			if ( selector ) {
  4607  				handlers.splice( handlers.delegateCount++, 0, handleObj );
  4608  			} else {
  4609  				handlers.push( handleObj );
  4610  			}
  4611  
  4612  			// Keep track of which events have ever been used, for event optimization
  4613  			jQuery.event.global[ type ] = true;
  4614  		}
  4615  
  4616  	},
  4617  
  4618  	// Detach an event or set of events from an element
  4619  	remove: function( elem, types, handler, selector, mappedTypes ) {
  4620  
  4621  		var j, origCount, tmp,
  4622  			events, t, handleObj,
  4623  			special, handlers, type, namespaces, origType,
  4624  			elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
  4625  
  4626  		if ( !elemData || !( events = elemData.events ) ) {
  4627  			return;
  4628  		}
  4629  
  4630  		// Once for each type.namespace in types; type may be omitted
  4631  		types = ( types || "" ).match( rnotwhite ) || [ "" ];
  4632  		t = types.length;
  4633  		while ( t-- ) {
  4634  			tmp = rtypenamespace.exec( types[ t ] ) || [];
  4635  			type = origType = tmp[ 1 ];
  4636  			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
  4637  
  4638  			// Unbind all events (on this namespace, if provided) for the element
  4639  			if ( !type ) {
  4640  				for ( type in events ) {
  4641  					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
  4642  				}
  4643  				continue;
  4644  			}
  4645  
  4646  			special = jQuery.event.special[ type ] || {};
  4647  			type = ( selector ? special.delegateType : special.bindType ) || type;
  4648  			handlers = events[ type ] || [];
  4649  			tmp = tmp[ 2 ] &&
  4650  				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
  4651  
  4652  			// Remove matching events
  4653  			origCount = j = handlers.length;
  4654  			while ( j-- ) {
  4655  				handleObj = handlers[ j ];
  4656  
  4657  				if ( ( mappedTypes || origType === handleObj.origType ) &&
  4658  					( !handler || handler.guid === handleObj.guid ) &&
  4659  					( !tmp || tmp.test( handleObj.namespace ) ) &&
  4660  					( !selector || selector === handleObj.selector ||
  4661  						selector === "**" && handleObj.selector ) ) {
  4662  					handlers.splice( j, 1 );
  4663  
  4664  					if ( handleObj.selector ) {
  4665  						handlers.delegateCount--;
  4666  					}
  4667  					if ( special.remove ) {
  4668  						special.remove.call( elem, handleObj );
  4669  					}
  4670  				}
  4671  			}
  4672  
  4673  			// Remove generic event handler if we removed something and no more handlers exist
  4674  			// (avoids potential for endless recursion during removal of special event handlers)
  4675  			if ( origCount && !handlers.length ) {
  4676  				if ( !special.teardown ||
  4677  					special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
  4678  
  4679  					jQuery.removeEvent( elem, type, elemData.handle );
  4680  				}
  4681  
  4682  				delete events[ type ];
  4683  			}
  4684  		}
  4685  
  4686  		// Remove data and the expando if it's no longer used
  4687  		if ( jQuery.isEmptyObject( events ) ) {
  4688  			dataPriv.remove( elem, "handle events" );
  4689  		}
  4690  	},
  4691  
  4692  	dispatch: function( event ) {
  4693  
  4694  		// Make a writable jQuery.Event from the native event object
  4695  		event = jQuery.event.fix( event );
  4696  
  4697  		var i, j, ret, matched, handleObj,
  4698  			handlerQueue = [],
  4699  			args = slice.call( arguments ),
  4700  			handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
  4701  			special = jQuery.event.special[ event.type ] || {};
  4702  
  4703  		// Use the fix-ed jQuery.Event rather than the (read-only) native event
  4704  		args[ 0 ] = event;
  4705  		event.delegateTarget = this;
  4706  
  4707  		// Call the preDispatch hook for the mapped type, and let it bail if desired
  4708  		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
  4709  			return;
  4710  		}
  4711  
  4712  		// Determine handlers
  4713  		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
  4714  
  4715  		// Run delegates first; they may want to stop propagation beneath us
  4716  		i = 0;
  4717  		while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
  4718  			event.currentTarget = matched.elem;
  4719  
  4720  			j = 0;
  4721  			while ( ( handleObj = matched.handlers[ j++ ] ) &&
  4722  				!event.isImmediatePropagationStopped() ) {
  4723  
  4724  				// Triggered event must either 1) have no namespace, or 2) have namespace(s)
  4725  				// a subset or equal to those in the bound event (both can have no namespace).
  4726  				if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
  4727  
  4728  					event.handleObj = handleObj;
  4729  					event.data = handleObj.data;
  4730  
  4731  					ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
  4732  						handleObj.handler ).apply( matched.elem, args );
  4733  
  4734  					if ( ret !== undefined ) {
  4735  						if ( ( event.result = ret ) === false ) {
  4736  							event.preventDefault();
  4737  							event.stopPropagation();
  4738  						}
  4739  					}
  4740  				}
  4741  			}
  4742  		}
  4743  
  4744  		// Call the postDispatch hook for the mapped type
  4745  		if ( special.postDispatch ) {
  4746  			special.postDispatch.call( this, event );
  4747  		}
  4748  
  4749  		return event.result;
  4750  	},
  4751  
  4752  	handlers: function( event, handlers ) {
  4753  		var i, matches, sel, handleObj,
  4754  			handlerQueue = [],
  4755  			delegateCount = handlers.delegateCount,
  4756  			cur = event.target;
  4757  
  4758  		// Support (at least): Chrome, IE9
  4759  		// Find delegate handlers
  4760  		// Black-hole SVG <use> instance trees (#13180)
  4761  		//
  4762  		// Support: Firefox<=42+
  4763  		// Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)
  4764  		if ( delegateCount && cur.nodeType &&
  4765  			( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) {
  4766  
  4767  			for ( ; cur !== this; cur = cur.parentNode || this ) {
  4768  
  4769  				// Don't check non-elements (#13208)
  4770  				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
  4771  				if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) {
  4772  					matches = [];
  4773  					for ( i = 0; i < delegateCount; i++ ) {
  4774  						handleObj = handlers[ i ];
  4775  
  4776  						// Don't conflict with Object.prototype properties (#13203)
  4777  						sel = handleObj.selector + " ";
  4778  
  4779  						if ( matches[ sel ] === undefined ) {
  4780  							matches[ sel ] = handleObj.needsContext ?
  4781  								jQuery( sel, this ).index( cur ) > -1 :
  4782  								jQuery.find( sel, this, null, [ cur ] ).length;
  4783  						}
  4784  						if ( matches[ sel ] ) {
  4785  							matches.push( handleObj );
  4786  						}
  4787  					}
  4788  					if ( matches.length ) {
  4789  						handlerQueue.push( { elem: cur, handlers: matches } );
  4790  					}
  4791  				}
  4792  			}
  4793  		}
  4794  
  4795  		// Add the remaining (directly-bound) handlers
  4796  		if ( delegateCount < handlers.length ) {
  4797  			handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } );
  4798  		}
  4799  
  4800  		return handlerQueue;
  4801  	},
  4802  
  4803  	// Includes some event props shared by KeyEvent and MouseEvent
  4804  	props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " +
  4805  		"metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ),
  4806  
  4807  	fixHooks: {},
  4808  
  4809  	keyHooks: {
  4810  		props: "char charCode key keyCode".split( " " ),
  4811  		filter: function( event, original ) {
  4812  
  4813  			// Add which for key events
  4814  			if ( event.which == null ) {
  4815  				event.which = original.charCode != null ? original.charCode : original.keyCode;
  4816  			}
  4817  
  4818  			return event;
  4819  		}
  4820  	},
  4821  
  4822  	mouseHooks: {
  4823  		props: ( "button buttons clientX clientY offsetX offsetY pageX pageY " +
  4824  			"screenX screenY toElement" ).split( " " ),
  4825  		filter: function( event, original ) {
  4826  			var eventDoc, doc, body,
  4827  				button = original.button;
  4828  
  4829  			// Calculate pageX/Y if missing and clientX/Y available
  4830  			if ( event.pageX == null && original.clientX != null ) {
  4831  				eventDoc = event.target.ownerDocument || document;
  4832  				doc = eventDoc.documentElement;
  4833  				body = eventDoc.body;
  4834  
  4835  				event.pageX = original.clientX +
  4836  					( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) -
  4837  					( doc && doc.clientLeft || body && body.clientLeft || 0 );
  4838  				event.pageY = original.clientY +
  4839  					( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) -
  4840  					( doc && doc.clientTop  || body && body.clientTop  || 0 );
  4841  			}
  4842  
  4843  			// Add which for click: 1 === left; 2 === middle; 3 === right
  4844  			// Note: button is not normalized, so don't use it
  4845  			if ( !event.which && button !== undefined ) {
  4846  				event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
  4847  			}
  4848  
  4849  			return event;
  4850  		}
  4851  	},
  4852  
  4853  	fix: function( event ) {
  4854  		if ( event[ jQuery.expando ] ) {
  4855  			return event;
  4856  		}
  4857  
  4858  		// Create a writable copy of the event object and normalize some properties
  4859  		var i, prop, copy,
  4860  			type = event.type,
  4861  			originalEvent = event,
  4862  			fixHook = this.fixHooks[ type ];
  4863  
  4864  		if ( !fixHook ) {
  4865  			this.fixHooks[ type ] = fixHook =
  4866  				rmouseEvent.test( type ) ? this.mouseHooks :
  4867  				rkeyEvent.test( type ) ? this.keyHooks :
  4868  				{};
  4869  		}
  4870  		copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
  4871  
  4872  		event = new jQuery.Event( originalEvent );
  4873  
  4874  		i = copy.length;
  4875  		while ( i-- ) {
  4876  			prop = copy[ i ];
  4877  			event[ prop ] = originalEvent[ prop ];
  4878  		}
  4879  
  4880  		// Support: Cordova 2.5 (WebKit) (#13255)
  4881  		// All events should have a target; Cordova deviceready doesn't
  4882  		if ( !event.target ) {
  4883  			event.target = document;
  4884  		}
  4885  
  4886  		// Support: Safari 6.0+, Chrome<28
  4887  		// Target should not be a text node (#504, #13143)
  4888  		if ( event.target.nodeType === 3 ) {
  4889  			event.target = event.target.parentNode;
  4890  		}
  4891  
  4892  		return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
  4893  	},
  4894  
  4895  	special: {
  4896  		load: {
  4897  
  4898  			// Prevent triggered image.load events from bubbling to window.load
  4899  			noBubble: true
  4900  		},
  4901  		focus: {
  4902  
  4903  			// Fire native event if possible so blur/focus sequence is correct
  4904  			trigger: function() {
  4905  				if ( this !== safeActiveElement() && this.focus ) {
  4906  					this.focus();
  4907  					return false;
  4908  				}
  4909  			},
  4910  			delegateType: "focusin"
  4911  		},
  4912  		blur: {
  4913  			trigger: function() {
  4914  				if ( this === safeActiveElement() && this.blur ) {
  4915  					this.blur();
  4916  					return false;
  4917  				}
  4918  			},
  4919  			delegateType: "focusout"
  4920  		},
  4921  		click: {
  4922  
  4923  			// For checkbox, fire native event so checked state will be right
  4924  			trigger: function() {
  4925  				if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
  4926  					this.click();
  4927  					return false;
  4928  				}
  4929  			},
  4930  
  4931  			// For cross-browser consistency, don't fire native .click() on links
  4932  			_default: function( event ) {
  4933  				return jQuery.nodeName( event.target, "a" );
  4934  			}
  4935  		},
  4936  
  4937  		beforeunload: {
  4938  			postDispatch: function( event ) {
  4939  
  4940  				// Support: Firefox 20+
  4941  				// Firefox doesn't alert if the returnValue field is not set.
  4942  				if ( event.result !== undefined && event.originalEvent ) {
  4943  					event.originalEvent.returnValue = event.result;
  4944  				}
  4945  			}
  4946  		}
  4947  	}
  4948  };
  4949  
  4950  jQuery.removeEvent = function( elem, type, handle ) {
  4951  
  4952  	// This "if" is needed for plain objects
  4953  	if ( elem.removeEventListener ) {
  4954  		elem.removeEventListener( type, handle );
  4955  	}
  4956  };
  4957  
  4958  jQuery.Event = function( src, props ) {
  4959  
  4960  	// Allow instantiation without the 'new' keyword
  4961  	if ( !( this instanceof jQuery.Event ) ) {
  4962  		return new jQuery.Event( src, props );
  4963  	}
  4964  
  4965  	// Event object
  4966  	if ( src && src.type ) {
  4967  		this.originalEvent = src;
  4968  		this.type = src.type;
  4969  
  4970  		// Events bubbling up the document may have been marked as prevented
  4971  		// by a handler lower down the tree; reflect the correct value.
  4972  		this.isDefaultPrevented = src.defaultPrevented ||
  4973  				src.defaultPrevented === undefined &&
  4974  
  4975  				// Support: Android<4.0
  4976  				src.returnValue === false ?
  4977  			returnTrue :
  4978  			returnFalse;
  4979  
  4980  	// Event type
  4981  	} else {
  4982  		this.type = src;
  4983  	}
  4984  
  4985  	// Put explicitly provided properties onto the event object
  4986  	if ( props ) {
  4987  		jQuery.extend( this, props );
  4988  	}
  4989  
  4990  	// Create a timestamp if incoming event doesn't have one
  4991  	this.timeStamp = src && src.timeStamp || jQuery.now();
  4992  
  4993  	// Mark it as fixed
  4994  	this[ jQuery.expando ] = true;
  4995  };
  4996  
  4997  // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
  4998  // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
  4999  jQuery.Event.prototype = {
  5000  	constructor: jQuery.Event,
  5001  	isDefaultPrevented: returnFalse,
  5002  	isPropagationStopped: returnFalse,
  5003  	isImmediatePropagationStopped: returnFalse,
  5004  
  5005  	preventDefault: function() {
  5006  		var e = this.originalEvent;
  5007  
  5008  		this.isDefaultPrevented = returnTrue;
  5009  
  5010  		if ( e ) {
  5011  			e.preventDefault();
  5012  		}
  5013  	},
  5014  	stopPropagation: function() {
  5015  		var e = this.originalEvent;
  5016  
  5017  		this.isPropagationStopped = returnTrue;
  5018  
  5019  		if ( e ) {
  5020  			e.stopPropagation();
  5021  		}
  5022  	},
  5023  	stopImmediatePropagation: function() {
  5024  		var e = this.originalEvent;
  5025  
  5026  		this.isImmediatePropagationStopped = returnTrue;
  5027  
  5028  		if ( e ) {
  5029  			e.stopImmediatePropagation();
  5030  		}
  5031  
  5032  		this.stopPropagation();
  5033  	}
  5034  };
  5035  
  5036  // Create mouseenter/leave events using mouseover/out and event-time checks
  5037  // so that event delegation works in jQuery.
  5038  // Do the same for pointerenter/pointerleave and pointerover/pointerout
  5039  //
  5040  // Support: Safari 7 only
  5041  // Safari sends mouseenter too often; see:
  5042  // https://code.google.com/p/chromium/issues/detail?id=470258
  5043  // for the description of the bug (it existed in older Chrome versions as well).
  5044  jQuery.each( {
  5045  	mouseenter: "mouseover",
  5046  	mouseleave: "mouseout",
  5047  	pointerenter: "pointerover",
  5048  	pointerleave: "pointerout"
  5049  }, function( orig, fix ) {
  5050  	jQuery.event.special[ orig ] = {
  5051  		delegateType: fix,
  5052  		bindType: fix,
  5053  
  5054  		handle: function( event ) {
  5055  			var ret,
  5056  				target = this,
  5057  				related = event.relatedTarget,
  5058  				handleObj = event.handleObj;
  5059  
  5060  			// For mouseenter/leave call the handler if related is outside the target.
  5061  			// NB: No relatedTarget if the mouse left/entered the browser window
  5062  			if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
  5063  				event.type = handleObj.origType;
  5064  				ret = handleObj.handler.apply( this, arguments );
  5065  				event.type = fix;
  5066  			}
  5067  			return ret;
  5068  		}
  5069  	};
  5070  } );
  5071  
  5072  jQuery.fn.extend( {
  5073  	on: function( types, selector, data, fn ) {
  5074  		return on( this, types, selector, data, fn );
  5075  	},
  5076  	one: function( types, selector, data, fn ) {
  5077  		return on( this, types, selector, data, fn, 1 );
  5078  	},
  5079  	off: function( types, selector, fn ) {
  5080  		var handleObj, type;
  5081  		if ( types && types.preventDefault && types.handleObj ) {
  5082  
  5083  			// ( event )  dispatched jQuery.Event
  5084  			handleObj = types.handleObj;
  5085  			jQuery( types.delegateTarget ).off(
  5086  				handleObj.namespace ?
  5087  					handleObj.origType + "." + handleObj.namespace :
  5088  					handleObj.origType,
  5089  				handleObj.selector,
  5090  				handleObj.handler
  5091  			);
  5092  			return this;
  5093  		}
  5094  		if ( typeof types === "object" ) {
  5095  
  5096  			// ( types-object [, selector] )
  5097  			for ( type in types ) {
  5098  				this.off( type, selector, types[ type ] );
  5099  			}
  5100  			return this;
  5101  		}
  5102  		if ( selector === false || typeof selector === "function" ) {
  5103  
  5104  			// ( types [, fn] )
  5105  			fn = selector;
  5106  			selector = undefined;
  5107  		}
  5108  		if ( fn === false ) {
  5109  			fn = returnFalse;
  5110  		}
  5111  		return this.each( function() {
  5112  			jQuery.event.remove( this, types, fn, selector );
  5113  		} );
  5114  	}
  5115  } );
  5116  
  5117  
  5118  var
  5119  	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,
  5120  
  5121  	// Support: IE 10-11, Edge 10240+
  5122  	// In IE/Edge using regex groups here causes severe slowdowns.
  5123  	// See https://connect.microsoft.com/IE/feedback/details/1736512/
  5124  	rnoInnerhtml = /<script|<style|<link/i,
  5125  
  5126  	// checked="checked" or checked
  5127  	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
  5128  	rscriptTypeMasked = /^true\/(.*)/,
  5129  	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
  5130  
  5131  function manipulationTarget( elem, content ) {
  5132  	if ( jQuery.nodeName( elem, "table" ) &&
  5133  		jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
  5134  
  5135  		return elem.getElementsByTagName( "tbody" )[ 0 ] || elem;
  5136  	}
  5137  
  5138  	return elem;
  5139  }
  5140  
  5141  // Replace/restore the type attribute of script elements for safe DOM manipulation
  5142  function disableScript( elem ) {
  5143  	elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
  5144  	return elem;
  5145  }
  5146  function restoreScript( elem ) {
  5147  	var match = rscriptTypeMasked.exec( elem.type );
  5148  
  5149  	if ( match ) {
  5150  		elem.type = match[ 1 ];
  5151  	} else {
  5152  		elem.removeAttribute( "type" );
  5153  	}
  5154  
  5155  	return elem;
  5156  }
  5157  
  5158  function cloneCopyEvent( src, dest ) {
  5159  	var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
  5160  
  5161  	if ( dest.nodeType !== 1 ) {
  5162  		return;
  5163  	}
  5164  
  5165  	// 1. Copy private data: events, handlers, etc.
  5166  	if ( dataPriv.hasData( src ) ) {
  5167  		pdataOld = dataPriv.access( src );
  5168  		pdataCur = dataPriv.set( dest, pdataOld );
  5169  		events = pdataOld.events;
  5170  
  5171  		if ( events ) {
  5172  			delete pdataCur.handle;
  5173  			pdataCur.events = {};
  5174  
  5175  			for ( type in events ) {
  5176  				for ( i = 0, l = events[ type ].length; i < l; i++ ) {
  5177  					jQuery.event.add( dest, type, events[ type ][ i ] );
  5178  				}
  5179  			}
  5180  		}
  5181  	}
  5182  
  5183  	// 2. Copy user data
  5184  	if ( dataUser.hasData( src ) ) {
  5185  		udataOld = dataUser.access( src );
  5186  		udataCur = jQuery.extend( {}, udataOld );
  5187  
  5188  		dataUser.set( dest, udataCur );
  5189  	}
  5190  }
  5191  
  5192  // Fix IE bugs, see support tests
  5193  function fixInput( src, dest ) {
  5194  	var nodeName = dest.nodeName.toLowerCase();
  5195  
  5196  	// Fails to persist the checked state of a cloned checkbox or radio button.
  5197  	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
  5198  		dest.checked = src.checked;
  5199  
  5200  	// Fails to return the selected option to the default selected state when cloning options
  5201  	} else if ( nodeName === "input" || nodeName === "textarea" ) {
  5202  		dest.defaultValue = src.defaultValue;
  5203  	}
  5204  }
  5205  
  5206  function domManip( collection, args, callback, ignored ) {
  5207  
  5208  	// Flatten any nested arrays
  5209  	args = concat.apply( [], args );
  5210  
  5211  	var fragment, first, scripts, hasScripts, node, doc,
  5212  		i = 0,
  5213  		l = collection.length,
  5214  		iNoClone = l - 1,
  5215  		value = args[ 0 ],
  5216  		isFunction = jQuery.isFunction( value );
  5217  
  5218  	// We can't cloneNode fragments that contain checked, in WebKit
  5219  	if ( isFunction ||
  5220  			( l > 1 && typeof value === "string" &&
  5221  				!support.checkClone && rchecked.test( value ) ) ) {
  5222  		return collection.each( function( index ) {
  5223  			var self = collection.eq( index );
  5224  			if ( isFunction ) {
  5225  				args[ 0 ] = value.call( this, index, self.html() );
  5226  			}
  5227  			domManip( self, args, callback, ignored );
  5228  		} );
  5229  	}
  5230  
  5231  	if ( l ) {
  5232  		fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
  5233  		first = fragment.firstChild;
  5234  
  5235  		if ( fragment.childNodes.length === 1 ) {
  5236  			fragment = first;
  5237  		}
  5238  
  5239  		// Require either new content or an interest in ignored elements to invoke the callback
  5240  		if ( first || ignored ) {
  5241  			scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
  5242  			hasScripts = scripts.length;
  5243  
  5244  			// Use the original fragment for the last item
  5245  			// instead of the first because it can end up
  5246  			// being emptied incorrectly in certain situations (#8070).
  5247  			for ( ; i < l; i++ ) {
  5248  				node = fragment;
  5249  
  5250  				if ( i !== iNoClone ) {
  5251  					node = jQuery.clone( node, true, true );
  5252  
  5253  					// Keep references to cloned scripts for later restoration
  5254  					if ( hasScripts ) {
  5255  
  5256  						// Support: Android<4.1, PhantomJS<2
  5257  						// push.apply(_, arraylike) throws on ancient WebKit
  5258  						jQuery.merge( scripts, getAll( node, "script" ) );
  5259  					}
  5260  				}
  5261  
  5262  				callback.call( collection[ i ], node, i );
  5263  			}
  5264  
  5265  			if ( hasScripts ) {
  5266  				doc = scripts[ scripts.length - 1 ].ownerDocument;
  5267  
  5268  				// Reenable scripts
  5269  				jQuery.map( scripts, restoreScript );
  5270  
  5271  				// Evaluate executable scripts on first document insertion
  5272  				for ( i = 0; i < hasScripts; i++ ) {
  5273  					node = scripts[ i ];
  5274  					if ( rscriptType.test( node.type || "" ) &&
  5275  						!dataPriv.access( node, "globalEval" ) &&
  5276  						jQuery.contains( doc, node ) ) {
  5277  
  5278  						if ( node.src ) {
  5279  
  5280  							// Optional AJAX dependency, but won't run scripts if not present
  5281  							if ( jQuery._evalUrl ) {
  5282  								jQuery._evalUrl( node.src );
  5283  							}
  5284  						} else {
  5285  							jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) );
  5286  						}
  5287  					}
  5288  				}
  5289  			}
  5290  		}
  5291  	}
  5292  
  5293  	return collection;
  5294  }
  5295  
  5296  function remove( elem, selector, keepData ) {
  5297  	var node,
  5298  		nodes = selector ? jQuery.filter( selector, elem ) : elem,
  5299  		i = 0;
  5300  
  5301  	for ( ; ( node = nodes[ i ] ) != null; i++ ) {
  5302  		if ( !keepData && node.nodeType === 1 ) {
  5303  			jQuery.cleanData( getAll( node ) );
  5304  		}
  5305  
  5306  		if ( node.parentNode ) {
  5307  			if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
  5308  				setGlobalEval( getAll( node, "script" ) );
  5309  			}
  5310  			node.parentNode.removeChild( node );
  5311  		}
  5312  	}
  5313  
  5314  	return elem;
  5315  }
  5316  
  5317  jQuery.extend( {
  5318  	htmlPrefilter: function( html ) {
  5319  		return html.replace( rxhtmlTag, "<$1></$2>" );
  5320  	},
  5321  
  5322  	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
  5323  		var i, l, srcElements, destElements,
  5324  			clone = elem.cloneNode( true ),
  5325  			inPage = jQuery.contains( elem.ownerDocument, elem );
  5326  
  5327  		// Fix IE cloning issues
  5328  		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
  5329  				!jQuery.isXMLDoc( elem ) ) {
  5330  
  5331  			// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
  5332  			destElements = getAll( clone );
  5333  			srcElements = getAll( elem );
  5334  
  5335  			for ( i = 0, l = srcElements.length; i < l; i++ ) {
  5336  				fixInput( srcElements[ i ], destElements[ i ] );
  5337  			}
  5338  		}
  5339  
  5340  		// Copy the events from the original to the clone
  5341  		if ( dataAndEvents ) {
  5342  			if ( deepDataAndEvents ) {
  5343  				srcElements = srcElements || getAll( elem );
  5344  				destElements = destElements || getAll( clone );
  5345  
  5346  				for ( i = 0, l = srcElements.length; i < l; i++ ) {
  5347  					cloneCopyEvent( srcElements[ i ], destElements[ i ] );
  5348  				}
  5349  			} else {
  5350  				cloneCopyEvent( elem, clone );
  5351  			}
  5352  		}
  5353  
  5354  		// Preserve script evaluation history
  5355  		destElements = getAll( clone, "script" );
  5356  		if ( destElements.length > 0 ) {
  5357  			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
  5358  		}
  5359  
  5360  		// Return the cloned set
  5361  		return clone;
  5362  	},
  5363  
  5364  	cleanData: function( elems ) {
  5365  		var data, elem, type,
  5366  			special = jQuery.event.special,
  5367  			i = 0;
  5368  
  5369  		for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
  5370  			if ( acceptData( elem ) ) {
  5371  				if ( ( data = elem[ dataPriv.expando ] ) ) {
  5372  					if ( data.events ) {
  5373  						for ( type in data.events ) {
  5374  							if ( special[ type ] ) {
  5375  								jQuery.event.remove( elem, type );
  5376  
  5377  							// This is a shortcut to avoid jQuery.event.remove's overhead
  5378  							} else {
  5379  								jQuery.removeEvent( elem, type, data.handle );
  5380  							}
  5381  						}
  5382  					}
  5383  
  5384  					// Support: Chrome <= 35-45+
  5385  					// Assign undefined instead of using delete, see Data#remove
  5386  					elem[ dataPriv.expando ] = undefined;
  5387  				}
  5388  				if ( elem[ dataUser.expando ] ) {
  5389  
  5390  					// Support: Chrome <= 35-45+
  5391  					// Assign undefined instead of using delete, see Data#remove
  5392  					elem[ dataUser.expando ] = undefined;
  5393  				}
  5394  			}
  5395  		}
  5396  	}
  5397  } );
  5398  
  5399  jQuery.fn.extend( {
  5400  
  5401  	// Keep domManip exposed until 3.0 (gh-2225)
  5402  	domManip: domManip,
  5403  
  5404  	detach: function( selector ) {
  5405  		return remove( this, selector, true );
  5406  	},
  5407  
  5408  	remove: function( selector ) {
  5409  		return remove( this, selector );
  5410  	},
  5411  
  5412  	text: function( value ) {
  5413  		return access( this, function( value ) {
  5414  			return value === undefined ?
  5415  				jQuery.text( this ) :
  5416  				this.empty().each( function() {
  5417  					if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
  5418  						this.textContent = value;
  5419  					}
  5420  				} );
  5421  		}, null, value, arguments.length );
  5422  	},
  5423  
  5424  	append: function() {
  5425  		return domManip( this, arguments, function( elem ) {
  5426  			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
  5427  				var target = manipulationTarget( this, elem );
  5428  				target.appendChild( elem );
  5429  			}
  5430  		} );
  5431  	},
  5432  
  5433  	prepend: function() {
  5434  		return domManip( this, arguments, function( elem ) {
  5435  			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
  5436  				var target = manipulationTarget( this, elem );
  5437  				target.insertBefore( elem, target.firstChild );
  5438  			}
  5439  		} );
  5440  	},
  5441  
  5442  	before: function() {
  5443  		return domManip( this, arguments, function( elem ) {
  5444  			if ( this.parentNode ) {
  5445  				this.parentNode.insertBefore( elem, this );
  5446  			}
  5447  		} );
  5448  	},
  5449  
  5450  	after: function() {
  5451  		return domManip( this, arguments, function( elem ) {
  5452  			if ( this.parentNode ) {
  5453  				this.parentNode.insertBefore( elem, this.nextSibling );
  5454  			}
  5455  		} );
  5456  	},
  5457  
  5458  	empty: function() {
  5459  		var elem,
  5460  			i = 0;
  5461  
  5462  		for ( ; ( elem = this[ i ] ) != null; i++ ) {
  5463  			if ( elem.nodeType === 1 ) {
  5464  
  5465  				// Prevent memory leaks
  5466  				jQuery.cleanData( getAll( elem, false ) );
  5467  
  5468  				// Remove any remaining nodes
  5469  				elem.textContent = "";
  5470  			}
  5471  		}
  5472  
  5473  		return this;
  5474  	},
  5475  
  5476  	clone: function( dataAndEvents, deepDataAndEvents ) {
  5477  		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
  5478  		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
  5479  
  5480  		return this.map( function() {
  5481  			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
  5482  		} );
  5483  	},
  5484  
  5485  	html: function( value ) {
  5486  		return access( this, function( value ) {
  5487  			var elem = this[ 0 ] || {},
  5488  				i = 0,
  5489  				l = this.length;
  5490  
  5491  			if ( value === undefined && elem.nodeType === 1 ) {
  5492  				return elem.innerHTML;
  5493  			}
  5494  
  5495  			// See if we can take a shortcut and just use innerHTML
  5496  			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
  5497  				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
  5498  
  5499  				value = jQuery.htmlPrefilter( value );
  5500  
  5501  				try {
  5502  					for ( ; i < l; i++ ) {
  5503  						elem = this[ i ] || {};
  5504  
  5505  						// Remove element nodes and prevent memory leaks
  5506  						if ( elem.nodeType === 1 ) {
  5507  							jQuery.cleanData( getAll( elem, false ) );
  5508  							elem.innerHTML = value;
  5509  						}
  5510  					}
  5511  
  5512  					elem = 0;
  5513  
  5514  				// If using innerHTML throws an exception, use the fallback method
  5515  				} catch ( e ) {}
  5516  			}
  5517  
  5518  			if ( elem ) {
  5519  				this.empty().append( value );
  5520  			}
  5521  		}, null, value, arguments.length );
  5522  	},
  5523  
  5524  	replaceWith: function() {
  5525  		var ignored = [];
  5526  
  5527  		// Make the changes, replacing each non-ignored context element with the new content
  5528  		return domManip( this, arguments, function( elem ) {
  5529  			var parent = this.parentNode;
  5530  
  5531  			if ( jQuery.inArray( this, ignored ) < 0 ) {
  5532  				jQuery.cleanData( getAll( this ) );
  5533  				if ( parent ) {
  5534  					parent.replaceChild( elem, this );
  5535  				}
  5536  			}
  5537  
  5538  		// Force callback invocation
  5539  		}, ignored );
  5540  	}
  5541  } );
  5542  
  5543  jQuery.each( {
  5544  	appendTo: "append",
  5545  	prependTo: "prepend",
  5546  	insertBefore: "before",
  5547  	insertAfter: "after",
  5548  	replaceAll: "replaceWith"
  5549  }, function( name, original ) {
  5550  	jQuery.fn[ name ] = function( selector ) {
  5551  		var elems,
  5552  			ret = [],
  5553  			insert = jQuery( selector ),
  5554  			last = insert.length - 1,
  5555  			i = 0;
  5556  
  5557  		for ( ; i <= last; i++ ) {
  5558  			elems = i === last ? this : this.clone( true );
  5559  			jQuery( insert[ i ] )[ original ]( elems );
  5560  
  5561  			// Support: QtWebKit
  5562  			// .get() because push.apply(_, arraylike) throws
  5563  			push.apply( ret, elems.get() );
  5564  		}
  5565  
  5566  		return this.pushStack( ret );
  5567  	};
  5568  } );
  5569  
  5570  
  5571  var iframe,
  5572  	elemdisplay = {
  5573  
  5574  		// Support: Firefox
  5575  		// We have to pre-define these values for FF (#10227)
  5576  		HTML: "block",
  5577  		BODY: "block"
  5578  	};
  5579  
  5580  /**
  5581   * Retrieve the actual display of a element
  5582   * @param {String} name nodeName of the element
  5583   * @param {Object} doc Document object
  5584   */
  5585  
  5586  // Called only from within defaultDisplay
  5587  function actualDisplay( name, doc ) {
  5588  	var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
  5589  
  5590  		display = jQuery.css( elem[ 0 ], "display" );
  5591  
  5592  	// We don't have any data stored on the element,
  5593  	// so use "detach" method as fast way to get rid of the element
  5594  	elem.detach();
  5595  
  5596  	return display;
  5597  }
  5598  
  5599  /**
  5600   * Try to determine the default display value of an element
  5601   * @param {String} nodeName
  5602   */
  5603  function defaultDisplay( nodeName ) {
  5604  	var doc = document,
  5605  		display = elemdisplay[ nodeName ];
  5606  
  5607  	if ( !display ) {
  5608  		display = actualDisplay( nodeName, doc );
  5609  
  5610  		// If the simple way fails, read from inside an iframe
  5611  		if ( display === "none" || !display ) {
  5612  
  5613  			// Use the already-created iframe if possible
  5614  			iframe = ( iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" ) )
  5615  				.appendTo( doc.documentElement );
  5616  
  5617  			// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
  5618  			doc = iframe[ 0 ].contentDocument;
  5619  
  5620  			// Support: IE
  5621  			doc.write();
  5622  			doc.close();
  5623  
  5624  			display = actualDisplay( nodeName, doc );
  5625  			iframe.detach();
  5626  		}
  5627  
  5628  		// Store the correct default display
  5629  		elemdisplay[ nodeName ] = display;
  5630  	}
  5631  
  5632  	return display;
  5633  }
  5634  var rmargin = ( /^margin/ );
  5635  
  5636  var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
  5637  
  5638  var getStyles = function( elem ) {
  5639  
  5640  		// Support: IE<=11+, Firefox<=30+ (#15098, #14150)
  5641  		// IE throws on elements created in popups
  5642  		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
  5643  		var view = elem.ownerDocument.defaultView;
  5644  
  5645  		if ( !view.opener ) {
  5646  			view = window;
  5647  		}
  5648  
  5649  		return view.getComputedStyle( elem );
  5650  	};
  5651  
  5652  var swap = function( elem, options, callback, args ) {
  5653  	var ret, name,
  5654  		old = {};
  5655  
  5656  	// Remember the old values, and insert the new ones
  5657  	for ( name in options ) {
  5658  		old[ name ] = elem.style[ name ];
  5659  		elem.style[ name ] = options[ name ];
  5660  	}
  5661  
  5662  	ret = callback.apply( elem, args || [] );
  5663  
  5664  	// Revert the old values
  5665  	for ( name in options ) {
  5666  		elem.style[ name ] = old[ name ];
  5667  	}
  5668  
  5669  	return ret;
  5670  };
  5671  
  5672  
  5673  var documentElement = document.documentElement;
  5674  
  5675  
  5676  
  5677  ( function() {
  5678  	var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
  5679  		container = document.createElement( "div" ),
  5680  		div = document.createElement( "div" );
  5681  
  5682  	// Finish early in limited (non-browser) environments
  5683  	if ( !div.style ) {
  5684  		return;
  5685  	}
  5686  
  5687  	// Support: IE9-11+
  5688  	// Style of cloned element affects source element cloned (#8908)
  5689  	div.style.backgroundClip = "content-box";
  5690  	div.cloneNode( true ).style.backgroundClip = "";
  5691  	support.clearCloneStyle = div.style.backgroundClip === "content-box";
  5692  
  5693  	container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
  5694  		"padding:0;margin-top:1px;position:absolute";
  5695  	container.appendChild( div );
  5696  
  5697  	// Executing both pixelPosition & boxSizingReliable tests require only one layout
  5698  	// so they're executed at the same time to save the second computation.
  5699  	function computeStyleTests() {
  5700  		div.style.cssText =
  5701  
  5702  			// Support: Firefox<29, Android 2.3
  5703  			// Vendor-prefix box-sizing
  5704  			"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;" +
  5705  			"position:relative;display:block;" +
  5706  			"margin:auto;border:1px;padding:1px;" +
  5707  			"top:1%;width:50%";
  5708  		div.innerHTML = "";
  5709  		documentElement.appendChild( container );
  5710  
  5711  		var divStyle = window.getComputedStyle( div );
  5712  		pixelPositionVal = divStyle.top !== "1%";
  5713  		reliableMarginLeftVal = divStyle.marginLeft === "2px";
  5714  		boxSizingReliableVal = divStyle.width === "4px";
  5715  
  5716  		// Support: Android 4.0 - 4.3 only
  5717  		// Some styles come back with percentage values, even though they shouldn't
  5718  		div.style.marginRight = "50%";
  5719  		pixelMarginRightVal = divStyle.marginRight === "4px";
  5720  
  5721  		documentElement.removeChild( container );
  5722  	}
  5723  
  5724  	jQuery.extend( support, {
  5725  		pixelPosition: function() {
  5726  
  5727  			// This test is executed only once but we still do memoizing
  5728  			// since we can use the boxSizingReliable pre-computing.
  5729  			// No need to check if the test was already performed, though.
  5730  			computeStyleTests();
  5731  			return pixelPositionVal;
  5732  		},
  5733  		boxSizingReliable: function() {
  5734  			if ( boxSizingReliableVal == null ) {
  5735  				computeStyleTests();
  5736  			}
  5737  			return boxSizingReliableVal;
  5738  		},
  5739  		pixelMarginRight: function() {
  5740  
  5741  			// Support: Android 4.0-4.3
  5742  			// We're checking for boxSizingReliableVal here instead of pixelMarginRightVal
  5743  			// since that compresses better and they're computed together anyway.
  5744  			if ( boxSizingReliableVal == null ) {
  5745  				computeStyleTests();
  5746  			}
  5747  			return pixelMarginRightVal;
  5748  		},
  5749  		reliableMarginLeft: function() {
  5750  
  5751  			// Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37
  5752  			if ( boxSizingReliableVal == null ) {
  5753  				computeStyleTests();
  5754  			}
  5755  			return reliableMarginLeftVal;
  5756  		},
  5757  		reliableMarginRight: function() {
  5758  
  5759  			// Support: Android 2.3
  5760  			// Check if div with explicit width and no margin-right incorrectly
  5761  			// gets computed margin-right based on width of container. (#3333)
  5762  			// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
  5763  			// This support function is only executed once so no memoizing is needed.
  5764  			var ret,
  5765  				marginDiv = div.appendChild( document.createElement( "div" ) );
  5766  
  5767  			// Reset CSS: box-sizing; display; margin; border; padding
  5768  			marginDiv.style.cssText = div.style.cssText =
  5769  
  5770  				// Support: Android 2.3
  5771  				// Vendor-prefix box-sizing
  5772  				"-webkit-box-sizing:content-box;box-sizing:content-box;" +
  5773  				"display:block;margin:0;border:0;padding:0";
  5774  			marginDiv.style.marginRight = marginDiv.style.width = "0";
  5775  			div.style.width = "1px";
  5776  			documentElement.appendChild( container );
  5777  
  5778  			ret = !parseFloat( window.getComputedStyle( marginDiv ).marginRight );
  5779  
  5780  			documentElement.removeChild( container );
  5781  			div.removeChild( marginDiv );
  5782  
  5783  			return ret;
  5784  		}
  5785  	} );
  5786  } )();
  5787  
  5788  
  5789  function curCSS( elem, name, computed ) {
  5790  	var width, minWidth, maxWidth, ret,
  5791  		style = elem.style;
  5792  
  5793  	computed = computed || getStyles( elem );
  5794  
  5795  	// Support: IE9
  5796  	// getPropertyValue is only needed for .css('filter') (#12537)
  5797  	if ( computed ) {
  5798  		ret = computed.getPropertyValue( name ) || computed[ name ];
  5799  
  5800  		if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
  5801  			ret = jQuery.style( elem, name );
  5802  		}
  5803  
  5804  		// A tribute to the "awesome hack by Dean Edwards"
  5805  		// Android Browser returns percentage for some values,
  5806  		// but width seems to be reliably pixels.
  5807  		// This is against the CSSOM draft spec:
  5808  		// http://dev.w3.org/csswg/cssom/#resolved-values
  5809  		if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
  5810  
  5811  			// Remember the original values
  5812  			width = style.width;
  5813  			minWidth = style.minWidth;
  5814  			maxWidth = style.maxWidth;
  5815  
  5816  			// Put in the new values to get a computed value out
  5817  			style.minWidth = style.maxWidth = style.width = ret;
  5818  			ret = computed.width;
  5819  
  5820  			// Revert the changed values
  5821  			style.width = width;
  5822  			style.minWidth = minWidth;
  5823  			style.maxWidth = maxWidth;
  5824  		}
  5825  	}
  5826  
  5827  	return ret !== undefined ?
  5828  
  5829  		// Support: IE9-11+
  5830  		// IE returns zIndex value as an integer.
  5831  		ret + "" :
  5832  		ret;
  5833  }
  5834  
  5835  
  5836  function addGetHookIf( conditionFn, hookFn ) {
  5837  
  5838  	// Define the hook, we'll check on the first run if it's really needed.
  5839  	return {
  5840  		get: function() {
  5841  			if ( conditionFn() ) {
  5842  
  5843  				// Hook not needed (or it's not possible to use it due
  5844  				// to missing dependency), remove it.
  5845  				delete this.get;
  5846  				return;
  5847  			}
  5848  
  5849  			// Hook needed; redefine it so that the support test is not executed again.
  5850  			return ( this.get = hookFn ).apply( this, arguments );
  5851  		}
  5852  	};
  5853  }
  5854  
  5855  
  5856  var
  5857  
  5858  	// Swappable if display is none or starts with table
  5859  	// except "table", "table-cell", or "table-caption"
  5860  	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
  5861  	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
  5862  
  5863  	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
  5864  	cssNormalTransform = {
  5865  		letterSpacing: "0",
  5866  		fontWeight: "400"
  5867  	},
  5868  
  5869  	cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
  5870  	emptyStyle = document.createElement( "div" ).style;
  5871  
  5872  // Return a css property mapped to a potentially vendor prefixed property
  5873  function vendorPropName( name ) {
  5874  
  5875  	// Shortcut for names that are not vendor prefixed
  5876  	if ( name in emptyStyle ) {
  5877  		return name;
  5878  	}
  5879  
  5880  	// Check for vendor prefixed names
  5881  	var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
  5882  		i = cssPrefixes.length;
  5883  
  5884  	while ( i-- ) {
  5885  		name = cssPrefixes[ i ] + capName;
  5886  		if ( name in emptyStyle ) {
  5887  			return name;
  5888  		}
  5889  	}
  5890  }
  5891  
  5892  function setPositiveNumber( elem, value, subtract ) {
  5893  
  5894  	// Any relative (+/-) values have already been
  5895  	// normalized at this point
  5896  	var matches = rcssNum.exec( value );
  5897  	return matches ?
  5898  
  5899  		// Guard against undefined "subtract", e.g., when used as in cssHooks
  5900  		Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
  5901  		value;
  5902  }
  5903  
  5904  function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
  5905  	var i = extra === ( isBorderBox ? "border" : "content" ) ?
  5906  
  5907  		// If we already have the right measurement, avoid augmentation
  5908  		4 :
  5909  
  5910  		// Otherwise initialize for horizontal or vertical properties
  5911  		name === "width" ? 1 : 0,
  5912  
  5913  		val = 0;
  5914  
  5915  	for ( ; i < 4; i += 2 ) {
  5916  
  5917  		// Both box models exclude margin, so add it if we want it
  5918  		if ( extra === "margin" ) {
  5919  			val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
  5920  		}
  5921  
  5922  		if ( isBorderBox ) {
  5923  
  5924  			// border-box includes padding, so remove it if we want content
  5925  			if ( extra === "content" ) {
  5926  				val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
  5927  			}
  5928  
  5929  			// At this point, extra isn't border nor margin, so remove border
  5930  			if ( extra !== "margin" ) {
  5931  				val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
  5932  			}
  5933  		} else {
  5934  
  5935  			// At this point, extra isn't content, so add padding
  5936  			val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
  5937  
  5938  			// At this point, extra isn't content nor padding, so add border
  5939  			if ( extra !== "padding" ) {
  5940  				val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
  5941  			}
  5942  		}
  5943  	}
  5944  
  5945  	return val;
  5946  }
  5947  
  5948  function getWidthOrHeight( elem, name, extra ) {
  5949  
  5950  	// Start with offset property, which is equivalent to the border-box value
  5951  	var valueIsBorderBox = true,
  5952  		val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
  5953  		styles = getStyles( elem ),
  5954  		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
  5955  
  5956  	// Support: IE11 only
  5957  	// In IE 11 fullscreen elements inside of an iframe have
  5958  	// 100x too small dimensions (gh-1764).
  5959  	if ( document.msFullscreenElement && window.top !== window ) {
  5960  
  5961  		// Support: IE11 only
  5962  		// Running getBoundingClientRect on a disconnected node
  5963  		// in IE throws an error.
  5964  		if ( elem.getClientRects().length ) {
  5965  			val = Math.round( elem.getBoundingClientRect()[ name ] * 100 );
  5966  		}
  5967  	}
  5968  
  5969  	// Some non-html elements return undefined for offsetWidth, so check for null/undefined
  5970  	// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
  5971  	// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
  5972  	if ( val <= 0 || val == null ) {
  5973  
  5974  		// Fall back to computed then uncomputed css if necessary
  5975  		val = curCSS( elem, name, styles );
  5976  		if ( val < 0 || val == null ) {
  5977  			val = elem.style[ name ];
  5978  		}
  5979  
  5980  		// Computed unit is not pixels. Stop here and return.
  5981  		if ( rnumnonpx.test( val ) ) {
  5982  			return val;
  5983  		}
  5984  
  5985  		// Check for style in case a browser which returns unreliable values
  5986  		// for getComputedStyle silently falls back to the reliable elem.style
  5987  		valueIsBorderBox = isBorderBox &&
  5988  			( support.boxSizingReliable() || val === elem.style[ name ] );
  5989  
  5990  		// Normalize "", auto, and prepare for extra
  5991  		val = parseFloat( val ) || 0;
  5992  	}
  5993  
  5994  	// Use the active box-sizing model to add/subtract irrelevant styles
  5995  	return ( val +
  5996  		augmentWidthOrHeight(
  5997  			elem,
  5998  			name,
  5999  			extra || ( isBorderBox ? "border" : "content" ),
  6000  			valueIsBorderBox,
  6001  			styles
  6002  		)
  6003  	) + "px";
  6004  }
  6005  
  6006  function showHide( elements, show ) {
  6007  	var display, elem, hidden,
  6008  		values = [],
  6009  		index = 0,
  6010  		length = elements.length;
  6011  
  6012  	for ( ; index < length; index++ ) {
  6013  		elem = elements[ index ];
  6014  		if ( !elem.style ) {
  6015  			continue;
  6016  		}
  6017  
  6018  		values[ index ] = dataPriv.get( elem, "olddisplay" );
  6019  		display = elem.style.display;
  6020  		if ( show ) {
  6021  
  6022  			// Reset the inline display of this element to learn if it is
  6023  			// being hidden by cascaded rules or not
  6024  			if ( !values[ index ] && display === "none" ) {
  6025  				elem.style.display = "";
  6026  			}
  6027  
  6028  			// Set elements which have been overridden with display: none
  6029  			// in a stylesheet to whatever the default browser style is
  6030  			// for such an element
  6031  			if ( elem.style.display === "" && isHidden( elem ) ) {
  6032  				values[ index ] = dataPriv.access(
  6033  					elem,
  6034  					"olddisplay",
  6035  					defaultDisplay( elem.nodeName )
  6036  				);
  6037  			}
  6038  		} else {
  6039  			hidden = isHidden( elem );
  6040  
  6041  			if ( display !== "none" || !hidden ) {
  6042  				dataPriv.set(
  6043  					elem,
  6044  					"olddisplay",
  6045  					hidden ? display : jQuery.css( elem, "display" )
  6046  				);
  6047  			}
  6048  		}
  6049  	}
  6050  
  6051  	// Set the display of most of the elements in a second loop
  6052  	// to avoid the constant reflow
  6053  	for ( index = 0; index < length; index++ ) {
  6054  		elem = elements[ index ];
  6055  		if ( !elem.style ) {
  6056  			continue;
  6057  		}
  6058  		if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
  6059  			elem.style.display = show ? values[ index ] || "" : "none";
  6060  		}
  6061  	}
  6062  
  6063  	return elements;
  6064  }
  6065  
  6066  jQuery.extend( {
  6067  
  6068  	// Add in style property hooks for overriding the default
  6069  	// behavior of getting and setting a style property
  6070  	cssHooks: {
  6071  		opacity: {
  6072  			get: function( elem, computed ) {
  6073  				if ( computed ) {
  6074  
  6075  					// We should always get a number back from opacity
  6076  					var ret = curCSS( elem, "opacity" );
  6077  					return ret === "" ? "1" : ret;
  6078  				}
  6079  			}
  6080  		}
  6081  	},
  6082  
  6083  	// Don't automatically add "px" to these possibly-unitless properties
  6084  	cssNumber: {
  6085  		"animationIterationCount": true,
  6086  		"columnCount": true,
  6087  		"fillOpacity": true,
  6088  		"flexGrow": true,
  6089  		"flexShrink": true,
  6090  		"fontWeight": true,
  6091  		"lineHeight": true,
  6092  		"opacity": true,
  6093  		"order": true,
  6094  		"orphans": true,
  6095  		"widows": true,
  6096  		"zIndex": true,
  6097  		"zoom": true
  6098  	},
  6099  
  6100  	// Add in properties whose names you wish to fix before
  6101  	// setting or getting the value
  6102  	cssProps: {
  6103  		"float": "cssFloat"
  6104  	},
  6105  
  6106  	// Get and set the style property on a DOM Node
  6107  	style: function( elem, name, value, extra ) {
  6108  
  6109  		// Don't set styles on text and comment nodes
  6110  		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
  6111  			return;
  6112  		}
  6113  
  6114  		// Make sure that we're working with the right name
  6115  		var ret, type, hooks,
  6116  			origName = jQuery.camelCase( name ),
  6117  			style = elem.style;
  6118  
  6119  		name = jQuery.cssProps[ origName ] ||
  6120  			( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
  6121  
  6122  		// Gets hook for the prefixed version, then unprefixed version
  6123  		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
  6124  
  6125  		// Check if we're setting a value
  6126  		if ( value !== undefined ) {
  6127  			type = typeof value;
  6128  
  6129  			// Convert "+=" or "-=" to relative numbers (#7345)
  6130  			if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
  6131  				value = adjustCSS( elem, name, ret );
  6132  
  6133  				// Fixes bug #9237
  6134  				type = "number";
  6135  			}
  6136  
  6137  			// Make sure that null and NaN values aren't set (#7116)
  6138  			if ( value == null || value !== value ) {
  6139  				return;
  6140  			}
  6141  
  6142  			// If a number was passed in, add the unit (except for certain CSS properties)
  6143  			if ( type === "number" ) {
  6144  				value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
  6145  			}
  6146  
  6147  			// Support: IE9-11+
  6148  			// background-* props affect original clone's values
  6149  			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
  6150  				style[ name ] = "inherit";
  6151  			}
  6152  
  6153  			// If a hook was provided, use that value, otherwise just set the specified value
  6154  			if ( !hooks || !( "set" in hooks ) ||
  6155  				( value = hooks.set( elem, value, extra ) ) !== undefined ) {
  6156  
  6157  				style[ name ] = value;
  6158  			}
  6159  
  6160  		} else {
  6161  
  6162  			// If a hook was provided get the non-computed value from there
  6163  			if ( hooks && "get" in hooks &&
  6164  				( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
  6165  
  6166  				return ret;
  6167  			}
  6168  
  6169  			// Otherwise just get the value from the style object
  6170  			return style[ name ];
  6171  		}
  6172  	},
  6173  
  6174  	css: function( elem, name, extra, styles ) {
  6175  		var val, num, hooks,
  6176  			origName = jQuery.camelCase( name );
  6177  
  6178  		// Make sure that we're working with the right name
  6179  		name = jQuery.cssProps[ origName ] ||
  6180  			( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
  6181  
  6182  		// Try prefixed name followed by the unprefixed name
  6183  		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
  6184  
  6185  		// If a hook was provided get the computed value from there
  6186  		if ( hooks && "get" in hooks ) {
  6187  			val = hooks.get( elem, true, extra );
  6188  		}
  6189  
  6190  		// Otherwise, if a way to get the computed value exists, use that
  6191  		if ( val === undefined ) {
  6192  			val = curCSS( elem, name, styles );
  6193  		}
  6194  
  6195  		// Convert "normal" to computed value
  6196  		if ( val === "normal" && name in cssNormalTransform ) {
  6197  			val = cssNormalTransform[ name ];
  6198  		}
  6199  
  6200  		// Make numeric if forced or a qualifier was provided and val looks numeric
  6201  		if ( extra === "" || extra ) {
  6202  			num = parseFloat( val );
  6203  			return extra === true || isFinite( num ) ? num || 0 : val;
  6204  		}
  6205  		return val;
  6206  	}
  6207  } );
  6208  
  6209  jQuery.each( [ "height", "width" ], function( i, name ) {
  6210  	jQuery.cssHooks[ name ] = {
  6211  		get: function( elem, computed, extra ) {
  6212  			if ( computed ) {
  6213  
  6214  				// Certain elements can have dimension info if we invisibly show them
  6215  				// but it must have a current display style that would benefit
  6216  				return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
  6217  					elem.offsetWidth === 0 ?
  6218  						swap( elem, cssShow, function() {
  6219  							return getWidthOrHeight( elem, name, extra );
  6220  						} ) :
  6221  						getWidthOrHeight( elem, name, extra );
  6222  			}
  6223  		},
  6224  
  6225  		set: function( elem, value, extra ) {
  6226  			var matches,
  6227  				styles = extra && getStyles( elem ),
  6228  				subtract = extra && augmentWidthOrHeight(
  6229  					elem,
  6230  					name,
  6231  					extra,
  6232  					jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
  6233  					styles
  6234  				);
  6235  
  6236  			// Convert to pixels if value adjustment is needed
  6237  			if ( subtract && ( matches = rcssNum.exec( value ) ) &&
  6238  				( matches[ 3 ] || "px" ) !== "px" ) {
  6239  
  6240  				elem.style[ name ] = value;
  6241  				value = jQuery.css( elem, name );
  6242  			}
  6243  
  6244  			return setPositiveNumber( elem, value, subtract );
  6245  		}
  6246  	};
  6247  } );
  6248  
  6249  jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
  6250  	function( elem, computed ) {
  6251  		if ( computed ) {
  6252  			return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
  6253  				elem.getBoundingClientRect().left -
  6254  					swap( elem, { marginLeft: 0 }, function() {
  6255  						return elem.getBoundingClientRect().left;
  6256  					} )
  6257  				) + "px";
  6258  		}
  6259  	}
  6260  );
  6261  
  6262  // Support: Android 2.3
  6263  jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
  6264  	function( elem, computed ) {
  6265  		if ( computed ) {
  6266  			return swap( elem, { "display": "inline-block" },
  6267  				curCSS, [ elem, "marginRight" ] );
  6268  		}
  6269  	}
  6270  );
  6271  
  6272  // These hooks are used by animate to expand properties
  6273  jQuery.each( {
  6274  	margin: "",
  6275  	padding: "",
  6276  	border: "Width"
  6277  }, function( prefix, suffix ) {
  6278  	jQuery.cssHooks[ prefix + suffix ] = {
  6279  		expand: function( value ) {
  6280  			var i = 0,
  6281  				expanded = {},
  6282  
  6283  				// Assumes a single number if not a string
  6284  				parts = typeof value === "string" ? value.split( " " ) : [ value ];
  6285  
  6286  			for ( ; i < 4; i++ ) {
  6287  				expanded[ prefix + cssExpand[ i ] + suffix ] =
  6288  					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
  6289  			}
  6290  
  6291  			return expanded;
  6292  		}
  6293  	};
  6294  
  6295  	if ( !rmargin.test( prefix ) ) {
  6296  		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
  6297  	}
  6298  } );
  6299  
  6300  jQuery.fn.extend( {
  6301  	css: function( name, value ) {
  6302  		return access( this, function( elem, name, value ) {
  6303  			var styles, len,
  6304  				map = {},
  6305  				i = 0;
  6306  
  6307  			if ( jQuery.isArray( name ) ) {
  6308  				styles = getStyles( elem );
  6309  				len = name.length;
  6310  
  6311  				for ( ; i < len; i++ ) {
  6312  					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
  6313  				}
  6314  
  6315  				return map;
  6316  			}
  6317  
  6318  			return value !== undefined ?
  6319  				jQuery.style( elem, name, value ) :
  6320  				jQuery.css( elem, name );
  6321  		}, name, value, arguments.length > 1 );
  6322  	},
  6323  	show: function() {
  6324  		return showHide( this, true );
  6325  	},
  6326  	hide: function() {
  6327  		return showHide( this );
  6328  	},
  6329  	toggle: function( state ) {
  6330  		if ( typeof state === "boolean" ) {
  6331  			return state ? this.show() : this.hide();
  6332  		}
  6333  
  6334  		return this.each( function() {
  6335  			if ( isHidden( this ) ) {
  6336  				jQuery( this ).show();
  6337  			} else {
  6338  				jQuery( this ).hide();
  6339  			}
  6340  		} );
  6341  	}
  6342  } );
  6343  
  6344  
  6345  function Tween( elem, options, prop, end, easing ) {
  6346  	return new Tween.prototype.init( elem, options, prop, end, easing );
  6347  }
  6348  jQuery.Tween = Tween;
  6349  
  6350  Tween.prototype = {
  6351  	constructor: Tween,
  6352  	init: function( elem, options, prop, end, easing, unit ) {
  6353  		this.elem = elem;
  6354  		this.prop = prop;
  6355  		this.easing = easing || jQuery.easing._default;
  6356  		this.options = options;
  6357  		this.start = this.now = this.cur();
  6358  		this.end = end;
  6359  		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
  6360  	},
  6361  	cur: function() {
  6362  		var hooks = Tween.propHooks[ this.prop ];
  6363  
  6364  		return hooks && hooks.get ?
  6365  			hooks.get( this ) :
  6366  			Tween.propHooks._default.get( this );
  6367  	},
  6368  	run: function( percent ) {
  6369  		var eased,
  6370  			hooks = Tween.propHooks[ this.prop ];
  6371  
  6372  		if ( this.options.duration ) {
  6373  			this.pos = eased = jQuery.easing[ this.easing ](
  6374  				percent, this.options.duration * percent, 0, 1, this.options.duration
  6375  			);
  6376  		} else {
  6377  			this.pos = eased = percent;
  6378  		}
  6379  		this.now = ( this.end - this.start ) * eased + this.start;
  6380  
  6381  		if ( this.options.step ) {
  6382  			this.options.step.call( this.elem, this.now, this );
  6383  		}
  6384  
  6385  		if ( hooks && hooks.set ) {
  6386  			hooks.set( this );
  6387  		} else {
  6388  			Tween.propHooks._default.set( this );
  6389  		}
  6390  		return this;
  6391  	}
  6392  };
  6393  
  6394  Tween.prototype.init.prototype = Tween.prototype;
  6395  
  6396  Tween.propHooks = {
  6397  	_default: {
  6398  		get: function( tween ) {
  6399  			var result;
  6400  
  6401  			// Use a property on the element directly when it is not a DOM element,
  6402  			// or when there is no matching style property that exists.
  6403  			if ( tween.elem.nodeType !== 1 ||
  6404  				tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
  6405  				return tween.elem[ tween.prop ];
  6406  			}
  6407  
  6408  			// Passing an empty string as a 3rd parameter to .css will automatically
  6409  			// attempt a parseFloat and fallback to a string if the parse fails.
  6410  			// Simple values such as "10px" are parsed to Float;
  6411  			// complex values such as "rotate(1rad)" are returned as-is.
  6412  			result = jQuery.css( tween.elem, tween.prop, "" );
  6413  
  6414  			// Empty strings, null, undefined and "auto" are converted to 0.
  6415  			return !result || result === "auto" ? 0 : result;
  6416  		},
  6417  		set: function( tween ) {
  6418  
  6419  			// Use step hook for back compat.
  6420  			// Use cssHook if its there.
  6421  			// Use .style if available and use plain properties where available.
  6422  			if ( jQuery.fx.step[ tween.prop ] ) {
  6423  				jQuery.fx.step[ tween.prop ]( tween );
  6424  			} else if ( tween.elem.nodeType === 1 &&
  6425  				( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
  6426  					jQuery.cssHooks[ tween.prop ] ) ) {
  6427  				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
  6428  			} else {
  6429  				tween.elem[ tween.prop ] = tween.now;
  6430  			}
  6431  		}
  6432  	}
  6433  };
  6434  
  6435  // Support: IE9
  6436  // Panic based approach to setting things on disconnected nodes
  6437  Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
  6438  	set: function( tween ) {
  6439  		if ( tween.elem.nodeType && tween.elem.parentNode ) {
  6440  			tween.elem[ tween.prop ] = tween.now;
  6441  		}
  6442  	}
  6443  };
  6444  
  6445  jQuery.easing = {
  6446  	linear: function( p ) {
  6447  		return p;
  6448  	},
  6449  	swing: function( p ) {
  6450  		return 0.5 - Math.cos( p * Math.PI ) / 2;
  6451  	},
  6452  	_default: "swing"
  6453  };
  6454  
  6455  jQuery.fx = Tween.prototype.init;
  6456  
  6457  // Back Compat <1.8 extension point
  6458  jQuery.fx.step = {};
  6459  
  6460  
  6461  
  6462  
  6463  var
  6464  	fxNow, timerId,
  6465  	rfxtypes = /^(?:toggle|show|hide)$/,
  6466  	rrun = /queueHooks$/;
  6467  
  6468  // Animations created synchronously will run synchronously
  6469  function createFxNow() {
  6470  	window.setTimeout( function() {
  6471  		fxNow = undefined;
  6472  	} );
  6473  	return ( fxNow = jQuery.now() );
  6474  }
  6475  
  6476  // Generate parameters to create a standard animation
  6477  function genFx( type, includeWidth ) {
  6478  	var which,
  6479  		i = 0,
  6480  		attrs = { height: type };
  6481  
  6482  	// If we include width, step value is 1 to do all cssExpand values,
  6483  	// otherwise step value is 2 to skip over Left and Right
  6484  	includeWidth = includeWidth ? 1 : 0;
  6485  	for ( ; i < 4 ; i += 2 - includeWidth ) {
  6486  		which = cssExpand[ i ];
  6487  		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
  6488  	}
  6489  
  6490  	if ( includeWidth ) {
  6491  		attrs.opacity = attrs.width = type;
  6492  	}
  6493  
  6494  	return attrs;
  6495  }
  6496  
  6497  function createTween( value, prop, animation ) {
  6498  	var tween,
  6499  		collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
  6500  		index = 0,
  6501  		length = collection.length;
  6502  	for ( ; index < length; index++ ) {
  6503  		if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
  6504  
  6505  			// We're done with this property
  6506  			return tween;
  6507  		}
  6508  	}
  6509  }
  6510  
  6511  function defaultPrefilter( elem, props, opts ) {
  6512  	/* jshint validthis: true */
  6513  	var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
  6514  		anim = this,
  6515  		orig = {},
  6516  		style = elem.style,
  6517  		hidden = elem.nodeType && isHidden( elem ),
  6518  		dataShow = dataPriv.get( elem, "fxshow" );
  6519  
  6520  	// Handle queue: false promises
  6521  	if ( !opts.queue ) {
  6522  		hooks = jQuery._queueHooks( elem, "fx" );
  6523  		if ( hooks.unqueued == null ) {
  6524  			hooks.unqueued = 0;
  6525  			oldfire = hooks.empty.fire;
  6526  			hooks.empty.fire = function() {
  6527  				if ( !hooks.unqueued ) {
  6528  					oldfire();
  6529  				}
  6530  			};
  6531  		}
  6532  		hooks.unqueued++;
  6533  
  6534  		anim.always( function() {
  6535  
  6536  			// Ensure the complete handler is called before this completes
  6537  			anim.always( function() {
  6538  				hooks.unqueued--;
  6539  				if ( !jQuery.queue( elem, "fx" ).length ) {
  6540  					hooks.empty.fire();
  6541  				}
  6542  			} );
  6543  		} );
  6544  	}
  6545  
  6546  	// Height/width overflow pass
  6547  	if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
  6548  
  6549  		// Make sure that nothing sneaks out
  6550  		// Record all 3 overflow attributes because IE9-10 do not
  6551  		// change the overflow attribute when overflowX and
  6552  		// overflowY are set to the same value
  6553  		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
  6554  
  6555  		// Set display property to inline-block for height/width
  6556  		// animations on inline elements that are having width/height animated
  6557  		display = jQuery.css( elem, "display" );
  6558  
  6559  		// Test default display if display is currently "none"
  6560  		checkDisplay = display === "none" ?
  6561  			dataPriv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
  6562  
  6563  		if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
  6564  			style.display = "inline-block";
  6565  		}
  6566  	}
  6567  
  6568  	if ( opts.overflow ) {
  6569  		style.overflow = "hidden";
  6570  		anim.always( function() {
  6571  			style.overflow = opts.overflow[ 0 ];
  6572  			style.overflowX = opts.overflow[ 1 ];
  6573  			style.overflowY = opts.overflow[ 2 ];
  6574  		} );
  6575  	}
  6576  
  6577  	// show/hide pass
  6578  	for ( prop in props ) {
  6579  		value = props[ prop ];
  6580  		if ( rfxtypes.exec( value ) ) {
  6581  			delete props[ prop ];
  6582  			toggle = toggle || value === "toggle";
  6583  			if ( value === ( hidden ? "hide" : "show" ) ) {
  6584  
  6585  				// If there is dataShow left over from a stopped hide or show
  6586  				// and we are going to proceed with show, we should pretend to be hidden
  6587  				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
  6588  					hidden = true;
  6589  				} else {
  6590  					continue;
  6591  				}
  6592  			}
  6593  			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
  6594  
  6595  		// Any non-fx value stops us from restoring the original display value
  6596  		} else {
  6597  			display = undefined;
  6598  		}
  6599  	}
  6600  
  6601  	if ( !jQuery.isEmptyObject( orig ) ) {
  6602  		if ( dataShow ) {
  6603  			if ( "hidden" in dataShow ) {
  6604  				hidden = dataShow.hidden;
  6605  			}
  6606  		} else {
  6607  			dataShow = dataPriv.access( elem, "fxshow", {} );
  6608  		}
  6609  
  6610  		// Store state if its toggle - enables .stop().toggle() to "reverse"
  6611  		if ( toggle ) {
  6612  			dataShow.hidden = !hidden;
  6613  		}
  6614  		if ( hidden ) {
  6615  			jQuery( elem ).show();
  6616  		} else {
  6617  			anim.done( function() {
  6618  				jQuery( elem ).hide();
  6619  			} );
  6620  		}
  6621  		anim.done( function() {
  6622  			var prop;
  6623  
  6624  			dataPriv.remove( elem, "fxshow" );
  6625  			for ( prop in orig ) {
  6626  				jQuery.style( elem, prop, orig[ prop ] );
  6627  			}
  6628  		} );
  6629  		for ( prop in orig ) {
  6630  			tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
  6631  
  6632  			if ( !( prop in dataShow ) ) {
  6633  				dataShow[ prop ] = tween.start;
  6634  				if ( hidden ) {
  6635  					tween.end = tween.start;
  6636  					tween.start = prop === "width" || prop === "height" ? 1 : 0;
  6637  				}
  6638  			}
  6639  		}
  6640  
  6641  	// If this is a noop like .hide().hide(), restore an overwritten display value
  6642  	} else if ( ( display === "none" ? defaultDisplay( elem.nodeName ) : display ) === "inline" ) {
  6643  		style.display = display;
  6644  	}
  6645  }
  6646  
  6647  function propFilter( props, specialEasing ) {
  6648  	var index, name, easing, value, hooks;
  6649  
  6650  	// camelCase, specialEasing and expand cssHook pass
  6651  	for ( index in props ) {
  6652  		name = jQuery.camelCase( index );
  6653  		easing = specialEasing[ name ];
  6654  		value = props[ index ];
  6655  		if ( jQuery.isArray( value ) ) {
  6656  			easing = value[ 1 ];
  6657  			value = props[ index ] = value[ 0 ];
  6658  		}
  6659  
  6660  		if ( index !== name ) {
  6661  			props[ name ] = value;
  6662  			delete props[ index ];
  6663  		}
  6664  
  6665  		hooks = jQuery.cssHooks[ name ];
  6666  		if ( hooks && "expand" in hooks ) {
  6667  			value = hooks.expand( value );
  6668  			delete props[ name ];
  6669  
  6670  			// Not quite $.extend, this won't overwrite existing keys.
  6671  			// Reusing 'index' because we have the correct "name"
  6672  			for ( index in value ) {
  6673  				if ( !( index in props ) ) {
  6674  					props[ index ] = value[ index ];
  6675  					specialEasing[ index ] = easing;
  6676  				}
  6677  			}
  6678  		} else {
  6679  			specialEasing[ name ] = easing;
  6680  		}
  6681  	}
  6682  }
  6683  
  6684  function Animation( elem, properties, options ) {
  6685  	var result,
  6686  		stopped,
  6687  		index = 0,
  6688  		length = Animation.prefilters.length,
  6689  		deferred = jQuery.Deferred().always( function() {
  6690  
  6691  			// Don't match elem in the :animated selector
  6692  			delete tick.elem;
  6693  		} ),
  6694  		tick = function() {
  6695  			if ( stopped ) {
  6696  				return false;
  6697  			}
  6698  			var currentTime = fxNow || createFxNow(),
  6699  				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
  6700  
  6701  				// Support: Android 2.3
  6702  				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
  6703  				temp = remaining / animation.duration || 0,
  6704  				percent = 1 - temp,
  6705  				index = 0,
  6706  				length = animation.tweens.length;
  6707  
  6708  			for ( ; index < length ; index++ ) {
  6709  				animation.tweens[ index ].run( percent );
  6710  			}
  6711  
  6712  			deferred.notifyWith( elem, [ animation, percent, remaining ] );
  6713  
  6714  			if ( percent < 1 && length ) {
  6715  				return remaining;
  6716  			} else {
  6717  				deferred.resolveWith( elem, [ animation ] );
  6718  				return false;
  6719  			}
  6720  		},
  6721  		animation = deferred.promise( {
  6722  			elem: elem,
  6723  			props: jQuery.extend( {}, properties ),
  6724  			opts: jQuery.extend( true, {
  6725  				specialEasing: {},
  6726  				easing: jQuery.easing._default
  6727  			}, options ),
  6728  			originalProperties: properties,
  6729  			originalOptions: options,
  6730  			startTime: fxNow || createFxNow(),
  6731  			duration: options.duration,
  6732  			tweens: [],
  6733  			createTween: function( prop, end ) {
  6734  				var tween = jQuery.Tween( elem, animation.opts, prop, end,
  6735  						animation.opts.specialEasing[ prop ] || animation.opts.easing );
  6736  				animation.tweens.push( tween );
  6737  				return tween;
  6738  			},
  6739  			stop: function( gotoEnd ) {
  6740  				var index = 0,
  6741  
  6742  					// If we are going to the end, we want to run all the tweens
  6743  					// otherwise we skip this part
  6744  					length = gotoEnd ? animation.tweens.length : 0;
  6745  				if ( stopped ) {
  6746  					return this;
  6747  				}
  6748  				stopped = true;
  6749  				for ( ; index < length ; index++ ) {
  6750  					animation.tweens[ index ].run( 1 );
  6751  				}
  6752  
  6753  				// Resolve when we played the last frame; otherwise, reject
  6754  				if ( gotoEnd ) {
  6755  					deferred.notifyWith( elem, [ animation, 1, 0 ] );
  6756  					deferred.resolveWith( elem, [ animation, gotoEnd ] );
  6757  				} else {
  6758  					deferred.rejectWith( elem, [ animation, gotoEnd ] );
  6759  				}
  6760  				return this;
  6761  			}
  6762  		} ),
  6763  		props = animation.props;
  6764  
  6765  	propFilter( props, animation.opts.specialEasing );
  6766  
  6767  	for ( ; index < length ; index++ ) {
  6768  		result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
  6769  		if ( result ) {
  6770  			if ( jQuery.isFunction( result.stop ) ) {
  6771  				jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
  6772  					jQuery.proxy( result.stop, result );
  6773  			}
  6774  			return result;
  6775  		}
  6776  	}
  6777  
  6778  	jQuery.map( props, createTween, animation );
  6779  
  6780  	if ( jQuery.isFunction( animation.opts.start ) ) {
  6781  		animation.opts.start.call( elem, animation );
  6782  	}
  6783  
  6784  	jQuery.fx.timer(
  6785  		jQuery.extend( tick, {
  6786  			elem: elem,
  6787  			anim: animation,
  6788  			queue: animation.opts.queue
  6789  		} )
  6790  	);
  6791  
  6792  	// attach callbacks from options
  6793  	return animation.progress( animation.opts.progress )
  6794  		.done( animation.opts.done, animation.opts.complete )
  6795  		.fail( animation.opts.fail )
  6796  		.always( animation.opts.always );
  6797  }
  6798  
  6799  jQuery.Animation = jQuery.extend( Animation, {
  6800  	tweeners: {
  6801  		"*": [ function( prop, value ) {
  6802  			var tween = this.createTween( prop, value );
  6803  			adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
  6804  			return tween;
  6805  		} ]
  6806  	},
  6807  
  6808  	tweener: function( props, callback ) {
  6809  		if ( jQuery.isFunction( props ) ) {
  6810  			callback = props;
  6811  			props = [ "*" ];
  6812  		} else {
  6813  			props = props.match( rnotwhite );
  6814  		}
  6815  
  6816  		var prop,
  6817  			index = 0,
  6818  			length = props.length;
  6819  
  6820  		for ( ; index < length ; index++ ) {
  6821  			prop = props[ index ];
  6822  			Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
  6823  			Animation.tweeners[ prop ].unshift( callback );
  6824  		}
  6825  	},
  6826  
  6827  	prefilters: [ defaultPrefilter ],
  6828  
  6829  	prefilter: function( callback, prepend ) {
  6830  		if ( prepend ) {
  6831  			Animation.prefilters.unshift( callback );
  6832  		} else {
  6833  			Animation.prefilters.push( callback );
  6834  		}
  6835  	}
  6836  } );
  6837  
  6838  jQuery.speed = function( speed, easing, fn ) {
  6839  	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
  6840  		complete: fn || !fn && easing ||
  6841  			jQuery.isFunction( speed ) && speed,
  6842  		duration: speed,
  6843  		easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
  6844  	};
  6845  
  6846  	opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ?
  6847  		opt.duration : opt.duration in jQuery.fx.speeds ?
  6848  			jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
  6849  
  6850  	// Normalize opt.queue - true/undefined/null -> "fx"
  6851  	if ( opt.queue == null || opt.queue === true ) {
  6852  		opt.queue = "fx";
  6853  	}
  6854  
  6855  	// Queueing
  6856  	opt.old = opt.complete;
  6857  
  6858  	opt.complete = function() {
  6859  		if ( jQuery.isFunction( opt.old ) ) {
  6860  			opt.old.call( this );
  6861  		}
  6862  
  6863  		if ( opt.queue ) {
  6864  			jQuery.dequeue( this, opt.queue );
  6865  		}
  6866  	};
  6867  
  6868  	return opt;
  6869  };
  6870  
  6871  jQuery.fn.extend( {
  6872  	fadeTo: function( speed, to, easing, callback ) {
  6873  
  6874  		// Show any hidden elements after setting opacity to 0
  6875  		return this.filter( isHidden ).css( "opacity", 0 ).show()
  6876  
  6877  			// Animate to the value specified
  6878  			.end().animate( { opacity: to }, speed, easing, callback );
  6879  	},
  6880  	animate: function( prop, speed, easing, callback ) {
  6881  		var empty = jQuery.isEmptyObject( prop ),
  6882  			optall = jQuery.speed( speed, easing, callback ),
  6883  			doAnimation = function() {
  6884  
  6885  				// Operate on a copy of prop so per-property easing won't be lost
  6886  				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
  6887  
  6888  				// Empty animations, or finishing resolves immediately
  6889  				if ( empty || dataPriv.get( this, "finish" ) ) {
  6890  					anim.stop( true );
  6891  				}
  6892  			};
  6893  			doAnimation.finish = doAnimation;
  6894  
  6895  		return empty || optall.queue === false ?
  6896  			this.each( doAnimation ) :
  6897  			this.queue( optall.queue, doAnimation );
  6898  	},
  6899  	stop: function( type, clearQueue, gotoEnd ) {
  6900  		var stopQueue = function( hooks ) {
  6901  			var stop = hooks.stop;
  6902  			delete hooks.stop;
  6903  			stop( gotoEnd );
  6904  		};
  6905  
  6906  		if ( typeof type !== "string" ) {
  6907  			gotoEnd = clearQueue;
  6908  			clearQueue = type;
  6909  			type = undefined;
  6910  		}
  6911  		if ( clearQueue && type !== false ) {
  6912  			this.queue( type || "fx", [] );
  6913  		}
  6914  
  6915  		return this.each( function() {
  6916  			var dequeue = true,
  6917  				index = type != null && type + "queueHooks",
  6918  				timers = jQuery.timers,
  6919  				data = dataPriv.get( this );
  6920  
  6921  			if ( index ) {
  6922  				if ( data[ index ] && data[ index ].stop ) {
  6923  					stopQueue( data[ index ] );
  6924  				}
  6925  			} else {
  6926  				for ( index in data ) {
  6927  					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
  6928  						stopQueue( data[ index ] );
  6929  					}
  6930  				}
  6931  			}
  6932  
  6933  			for ( index = timers.length; index--; ) {
  6934  				if ( timers[ index ].elem === this &&
  6935  					( type == null || timers[ index ].queue === type ) ) {
  6936  
  6937  					timers[ index ].anim.stop( gotoEnd );
  6938  					dequeue = false;
  6939  					timers.splice( index, 1 );
  6940  				}
  6941  			}
  6942  
  6943  			// Start the next in the queue if the last step wasn't forced.
  6944  			// Timers currently will call their complete callbacks, which
  6945  			// will dequeue but only if they were gotoEnd.
  6946  			if ( dequeue || !gotoEnd ) {
  6947  				jQuery.dequeue( this, type );
  6948  			}
  6949  		} );
  6950  	},
  6951  	finish: function( type ) {
  6952  		if ( type !== false ) {
  6953  			type = type || "fx";
  6954  		}
  6955  		return this.each( function() {
  6956  			var index,
  6957  				data = dataPriv.get( this ),
  6958  				queue = data[ type + "queue" ],
  6959  				hooks = data[ type + "queueHooks" ],
  6960  				timers = jQuery.timers,
  6961  				length = queue ? queue.length : 0;
  6962  
  6963  			// Enable finishing flag on private data
  6964  			data.finish = true;
  6965  
  6966  			// Empty the queue first
  6967  			jQuery.queue( this, type, [] );
  6968  
  6969  			if ( hooks && hooks.stop ) {
  6970  				hooks.stop.call( this, true );
  6971  			}
  6972  
  6973  			// Look for any active animations, and finish them
  6974  			for ( index = timers.length; index--; ) {
  6975  				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
  6976  					timers[ index ].anim.stop( true );
  6977  					timers.splice( index, 1 );
  6978  				}
  6979  			}
  6980  
  6981  			// Look for any animations in the old queue and finish them
  6982  			for ( index = 0; index < length; index++ ) {
  6983  				if ( queue[ index ] && queue[ index ].finish ) {
  6984  					queue[ index ].finish.call( this );
  6985  				}
  6986  			}
  6987  
  6988  			// Turn off finishing flag
  6989  			delete data.finish;
  6990  		} );
  6991  	}
  6992  } );
  6993  
  6994  jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
  6995  	var cssFn = jQuery.fn[ name ];
  6996  	jQuery.fn[ name ] = function( speed, easing, callback ) {
  6997  		return speed == null || typeof speed === "boolean" ?
  6998  			cssFn.apply( this, arguments ) :
  6999  			this.animate( genFx( name, true ), speed, easing, callback );
  7000  	};
  7001  } );
  7002  
  7003  // Generate shortcuts for custom animations
  7004  jQuery.each( {
  7005  	slideDown: genFx( "show" ),
  7006  	slideUp: genFx( "hide" ),
  7007  	slideToggle: genFx( "toggle" ),
  7008  	fadeIn: { opacity: "show" },
  7009  	fadeOut: { opacity: "hide" },
  7010  	fadeToggle: { opacity: "toggle" }
  7011  }, function( name, props ) {
  7012  	jQuery.fn[ name ] = function( speed, easing, callback ) {
  7013  		return this.animate( props, speed, easing, callback );
  7014  	};
  7015  } );
  7016  
  7017  jQuery.timers = [];
  7018  jQuery.fx.tick = function() {
  7019  	var timer,
  7020  		i = 0,
  7021  		timers = jQuery.timers;
  7022  
  7023  	fxNow = jQuery.now();
  7024  
  7025  	for ( ; i < timers.length; i++ ) {
  7026  		timer = timers[ i ];
  7027  
  7028  		// Checks the timer has not already been removed
  7029  		if ( !timer() && timers[ i ] === timer ) {
  7030  			timers.splice( i--, 1 );
  7031  		}
  7032  	}
  7033  
  7034  	if ( !timers.length ) {
  7035  		jQuery.fx.stop();
  7036  	}
  7037  	fxNow = undefined;
  7038  };
  7039  
  7040  jQuery.fx.timer = function( timer ) {
  7041  	jQuery.timers.push( timer );
  7042  	if ( timer() ) {
  7043  		jQuery.fx.start();
  7044  	} else {
  7045  		jQuery.timers.pop();
  7046  	}
  7047  };
  7048  
  7049  jQuery.fx.interval = 13;
  7050  jQuery.fx.start = function() {
  7051  	if ( !timerId ) {
  7052  		timerId = window.setInterval( jQuery.fx.tick, jQuery.fx.interval );
  7053  	}
  7054  };
  7055  
  7056  jQuery.fx.stop = function() {
  7057  	window.clearInterval( timerId );
  7058  
  7059  	timerId = null;
  7060  };
  7061  
  7062  jQuery.fx.speeds = {
  7063  	slow: 600,
  7064  	fast: 200,
  7065  
  7066  	// Default speed
  7067  	_default: 400
  7068  };
  7069  
  7070  
  7071  // Based off of the plugin by Clint Helfers, with permission.
  7072  // http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
  7073  jQuery.fn.delay = function( time, type ) {
  7074  	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
  7075  	type = type || "fx";
  7076  
  7077  	return this.queue( type, function( next, hooks ) {
  7078  		var timeout = window.setTimeout( next, time );
  7079  		hooks.stop = function() {
  7080  			window.clearTimeout( timeout );
  7081  		};
  7082  	} );
  7083  };
  7084  
  7085  
  7086  ( function() {
  7087  	var input = document.createElement( "input" ),
  7088  		select = document.createElement( "select" ),
  7089  		opt = select.appendChild( document.createElement( "option" ) );
  7090  
  7091  	input.type = "checkbox";
  7092  
  7093  	// Support: iOS<=5.1, Android<=4.2+
  7094  	// Default value for a checkbox should be "on"
  7095  	support.checkOn = input.value !== "";
  7096  
  7097  	// Support: IE<=11+
  7098  	// Must access selectedIndex to make default options select
  7099  	support.optSelected = opt.selected;
  7100  
  7101  	// Support: Android<=2.3
  7102  	// Options inside disabled selects are incorrectly marked as disabled
  7103  	select.disabled = true;
  7104  	support.optDisabled = !opt.disabled;
  7105  
  7106  	// Support: IE<=11+
  7107  	// An input loses its value after becoming a radio
  7108  	input = document.createElement( "input" );
  7109  	input.value = "t";
  7110  	input.type = "radio";
  7111  	support.radioValue = input.value === "t";
  7112  } )();
  7113  
  7114  
  7115  var boolHook,
  7116  	attrHandle = jQuery.expr.attrHandle;
  7117  
  7118  jQuery.fn.extend( {
  7119  	attr: function( name, value ) {
  7120  		return access( this, jQuery.attr, name, value, arguments.length > 1 );
  7121  	},
  7122  
  7123  	removeAttr: function( name ) {
  7124  		return this.each( function() {
  7125  			jQuery.removeAttr( this, name );
  7126  		} );
  7127  	}
  7128  } );
  7129  
  7130  jQuery.extend( {
  7131  	attr: function( elem, name, value ) {
  7132  		var ret, hooks,
  7133  			nType = elem.nodeType;
  7134  
  7135  		// Don't get/set attributes on text, comment and attribute nodes
  7136  		if ( nType === 3 || nType === 8 || nType === 2 ) {
  7137  			return;
  7138  		}
  7139  
  7140  		// Fallback to prop when attributes are not supported
  7141  		if ( typeof elem.getAttribute === "undefined" ) {
  7142  			return jQuery.prop( elem, name, value );
  7143  		}
  7144  
  7145  		// All attributes are lowercase
  7146  		// Grab necessary hook if one is defined
  7147  		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
  7148  			name = name.toLowerCase();
  7149  			hooks = jQuery.attrHooks[ name ] ||
  7150  				( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
  7151  		}
  7152  
  7153  		if ( value !== undefined ) {
  7154  			if ( value === null ) {
  7155  				jQuery.removeAttr( elem, name );
  7156  				return;
  7157  			}
  7158  
  7159  			if ( hooks && "set" in hooks &&
  7160  				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
  7161  				return ret;
  7162  			}
  7163  
  7164  			elem.setAttribute( name, value + "" );
  7165  			return value;
  7166  		}
  7167  
  7168  		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
  7169  			return ret;
  7170  		}
  7171  
  7172  		ret = jQuery.find.attr( elem, name );
  7173  
  7174  		// Non-existent attributes return null, we normalize to undefined
  7175  		return ret == null ? undefined : ret;
  7176  	},
  7177  
  7178  	attrHooks: {
  7179  		type: {
  7180  			set: function( elem, value ) {
  7181  				if ( !support.radioValue && value === "radio" &&
  7182  					jQuery.nodeName( elem, "input" ) ) {
  7183  					var val = elem.value;
  7184  					elem.setAttribute( "type", value );
  7185  					if ( val ) {
  7186  						elem.value = val;
  7187  					}
  7188  					return value;
  7189  				}
  7190  			}
  7191  		}
  7192  	},
  7193  
  7194  	removeAttr: function( elem, value ) {
  7195  		var name, propName,
  7196  			i = 0,
  7197  			attrNames = value && value.match( rnotwhite );
  7198  
  7199  		if ( attrNames && elem.nodeType === 1 ) {
  7200  			while ( ( name = attrNames[ i++ ] ) ) {
  7201  				propName = jQuery.propFix[ name ] || name;
  7202  
  7203  				// Boolean attributes get special treatment (#10870)
  7204  				if ( jQuery.expr.match.bool.test( name ) ) {
  7205  
  7206  					// Set corresponding property to false
  7207  					elem[ propName ] = false;
  7208  				}
  7209  
  7210  				elem.removeAttribute( name );
  7211  			}
  7212  		}
  7213  	}
  7214  } );
  7215  
  7216  // Hooks for boolean attributes
  7217  boolHook = {
  7218  	set: function( elem, value, name ) {
  7219  		if ( value === false ) {
  7220  
  7221  			// Remove boolean attributes when set to false
  7222  			jQuery.removeAttr( elem, name );
  7223  		} else {
  7224  			elem.setAttribute( name, name );
  7225  		}
  7226  		return name;
  7227  	}
  7228  };
  7229  jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
  7230  	var getter = attrHandle[ name ] || jQuery.find.attr;
  7231  
  7232  	attrHandle[ name ] = function( elem, name, isXML ) {
  7233  		var ret, handle;
  7234  		if ( !isXML ) {
  7235  
  7236  			// Avoid an infinite loop by temporarily removing this function from the getter
  7237  			handle = attrHandle[ name ];
  7238  			attrHandle[ name ] = ret;
  7239  			ret = getter( elem, name, isXML ) != null ?
  7240  				name.toLowerCase() :
  7241  				null;
  7242  			attrHandle[ name ] = handle;
  7243  		}
  7244  		return ret;
  7245  	};
  7246  } );
  7247  
  7248  
  7249  
  7250  
  7251  var rfocusable = /^(?:input|select|textarea|button)$/i,
  7252  	rclickable = /^(?:a|area)$/i;
  7253  
  7254  jQuery.fn.extend( {
  7255  	prop: function( name, value ) {
  7256  		return access( this, jQuery.prop, name, value, arguments.length > 1 );
  7257  	},
  7258  
  7259  	removeProp: function( name ) {
  7260  		return this.each( function() {
  7261  			delete this[ jQuery.propFix[ name ] || name ];
  7262  		} );
  7263  	}
  7264  } );
  7265  
  7266  jQuery.extend( {
  7267  	prop: function( elem, name, value ) {
  7268  		var ret, hooks,
  7269  			nType = elem.nodeType;
  7270  
  7271  		// Don't get/set properties on text, comment and attribute nodes
  7272  		if ( nType === 3 || nType === 8 || nType === 2 ) {
  7273  			return;
  7274  		}
  7275  
  7276  		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
  7277  
  7278  			// Fix name and attach hooks
  7279  			name = jQuery.propFix[ name ] || name;
  7280  			hooks = jQuery.propHooks[ name ];
  7281  		}
  7282  
  7283  		if ( value !== undefined ) {
  7284  			if ( hooks && "set" in hooks &&
  7285  				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
  7286  				return ret;
  7287  			}
  7288  
  7289  			return ( elem[ name ] = value );
  7290  		}
  7291  
  7292  		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
  7293  			return ret;
  7294  		}
  7295  
  7296  		return elem[ name ];
  7297  	},
  7298  
  7299  	propHooks: {
  7300  		tabIndex: {
  7301  			get: function( elem ) {
  7302  
  7303  				// elem.tabIndex doesn't always return the
  7304  				// correct value when it hasn't been explicitly set
  7305  				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
  7306  				// Use proper attribute retrieval(#12072)
  7307  				var tabindex = jQuery.find.attr( elem, "tabindex" );
  7308  
  7309  				return tabindex ?
  7310  					parseInt( tabindex, 10 ) :
  7311  					rfocusable.test( elem.nodeName ) ||
  7312  						rclickable.test( elem.nodeName ) && elem.href ?
  7313  							0 :
  7314  							-1;
  7315  			}
  7316  		}
  7317  	},
  7318  
  7319  	propFix: {
  7320  		"for": "htmlFor",
  7321  		"class": "className"
  7322  	}
  7323  } );
  7324  
  7325  if ( !support.optSelected ) {
  7326  	jQuery.propHooks.selected = {
  7327  		get: function( elem ) {
  7328  			var parent = elem.parentNode;
  7329  			if ( parent && parent.parentNode ) {
  7330  				parent.parentNode.selectedIndex;
  7331  			}
  7332  			return null;
  7333  		}
  7334  	};
  7335  }
  7336  
  7337  jQuery.each( [
  7338  	"tabIndex",
  7339  	"readOnly",
  7340  	"maxLength",
  7341  	"cellSpacing",
  7342  	"cellPadding",
  7343  	"rowSpan",
  7344  	"colSpan",
  7345  	"useMap",
  7346  	"frameBorder",
  7347  	"contentEditable"
  7348  ], function() {
  7349  	jQuery.propFix[ this.toLowerCase() ] = this;
  7350  } );
  7351  
  7352  
  7353  
  7354  
  7355  var rclass = /[\t\r\n\f]/g;
  7356  
  7357  function getClass( elem ) {
  7358  	return elem.getAttribute && elem.getAttribute( "class" ) || "";
  7359  }
  7360  
  7361  jQuery.fn.extend( {
  7362  	addClass: function( value ) {
  7363  		var classes, elem, cur, curValue, clazz, j, finalValue,
  7364  			i = 0;
  7365  
  7366  		if ( jQuery.isFunction( value ) ) {
  7367  			return this.each( function( j ) {
  7368  				jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
  7369  			} );
  7370  		}
  7371  
  7372  		if ( typeof value === "string" && value ) {
  7373  			classes = value.match( rnotwhite ) || [];
  7374  
  7375  			while ( ( elem = this[ i++ ] ) ) {
  7376  				curValue = getClass( elem );
  7377  				cur = elem.nodeType === 1 &&
  7378  					( " " + curValue + " " ).replace( rclass, " " );
  7379  
  7380  				if ( cur ) {
  7381  					j = 0;
  7382  					while ( ( clazz = classes[ j++ ] ) ) {
  7383  						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
  7384  							cur += clazz + " ";
  7385  						}
  7386  					}
  7387  
  7388  					// Only assign if different to avoid unneeded rendering.
  7389  					finalValue = jQuery.trim( cur );
  7390  					if ( curValue !== finalValue ) {
  7391  						elem.setAttribute( "class", finalValue );
  7392  					}
  7393  				}
  7394  			}
  7395  		}
  7396  
  7397  		return this;
  7398  	},
  7399  
  7400  	removeClass: function( value ) {
  7401  		var classes, elem, cur, curValue, clazz, j, finalValue,
  7402  			i = 0;
  7403  
  7404  		if ( jQuery.isFunction( value ) ) {
  7405  			return this.each( function( j ) {
  7406  				jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
  7407  			} );
  7408  		}
  7409  
  7410  		if ( !arguments.length ) {
  7411  			return this.attr( "class", "" );
  7412  		}
  7413  
  7414  		if ( typeof value === "string" && value ) {
  7415  			classes = value.match( rnotwhite ) || [];
  7416  
  7417  			while ( ( elem = this[ i++ ] ) ) {
  7418  				curValue = getClass( elem );
  7419  
  7420  				// This expression is here for better compressibility (see addClass)
  7421  				cur = elem.nodeType === 1 &&
  7422  					( " " + curValue + " " ).replace( rclass, " " );
  7423  
  7424  				if ( cur ) {
  7425  					j = 0;
  7426  					while ( ( clazz = classes[ j++ ] ) ) {
  7427  
  7428  						// Remove *all* instances
  7429  						while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
  7430  							cur = cur.replace( " " + clazz + " ", " " );
  7431  						}
  7432  					}
  7433  
  7434  					// Only assign if different to avoid unneeded rendering.
  7435  					finalValue = jQuery.trim( cur );
  7436  					if ( curValue !== finalValue ) {
  7437  						elem.setAttribute( "class", finalValue );
  7438  					}
  7439  				}
  7440  			}
  7441  		}
  7442  
  7443  		return this;
  7444  	},
  7445  
  7446  	toggleClass: function( value, stateVal ) {
  7447  		var type = typeof value;
  7448  
  7449  		if ( typeof stateVal === "boolean" && type === "string" ) {
  7450  			return stateVal ? this.addClass( value ) : this.removeClass( value );
  7451  		}
  7452  
  7453  		if ( jQuery.isFunction( value ) ) {
  7454  			return this.each( function( i ) {
  7455  				jQuery( this ).toggleClass(
  7456  					value.call( this, i, getClass( this ), stateVal ),
  7457  					stateVal
  7458  				);
  7459  			} );
  7460  		}
  7461  
  7462  		return this.each( function() {
  7463  			var className, i, self, classNames;
  7464  
  7465  			if ( type === "string" ) {
  7466  
  7467  				// Toggle individual class names
  7468  				i = 0;
  7469  				self = jQuery( this );
  7470  				classNames = value.match( rnotwhite ) || [];
  7471  
  7472  				while ( ( className = classNames[ i++ ] ) ) {
  7473  
  7474  					// Check each className given, space separated list
  7475  					if ( self.hasClass( className ) ) {
  7476  						self.removeClass( className );
  7477  					} else {
  7478  						self.addClass( className );
  7479  					}
  7480  				}
  7481  
  7482  			// Toggle whole class name
  7483  			} else if ( value === undefined || type === "boolean" ) {
  7484  				className = getClass( this );
  7485  				if ( className ) {
  7486  
  7487  					// Store className if set
  7488  					dataPriv.set( this, "__className__", className );
  7489  				}
  7490  
  7491  				// If the element has a class name or if we're passed `false`,
  7492  				// then remove the whole classname (if there was one, the above saved it).
  7493  				// Otherwise bring back whatever was previously saved (if anything),
  7494  				// falling back to the empty string if nothing was stored.
  7495  				if ( this.setAttribute ) {
  7496  					this.setAttribute( "class",
  7497  						className || value === false ?
  7498  						"" :
  7499  						dataPriv.get( this, "__className__" ) || ""
  7500  					);
  7501  				}
  7502  			}
  7503  		} );
  7504  	},
  7505  
  7506  	hasClass: function( selector ) {
  7507  		var className, elem,
  7508  			i = 0;
  7509  
  7510  		className = " " + selector + " ";
  7511  		while ( ( elem = this[ i++ ] ) ) {
  7512  			if ( elem.nodeType === 1 &&
  7513  				( " " + getClass( elem ) + " " ).replace( rclass, " " )
  7514  					.indexOf( className ) > -1
  7515  			) {
  7516  				return true;
  7517  			}
  7518  		}
  7519  
  7520  		return false;
  7521  	}
  7522  } );
  7523  
  7524  
  7525  
  7526  
  7527  var rreturn = /\r/g;
  7528  
  7529  jQuery.fn.extend( {
  7530  	val: function( value ) {
  7531  		var hooks, ret, isFunction,
  7532  			elem = this[ 0 ];
  7533  
  7534  		if ( !arguments.length ) {
  7535  			if ( elem ) {
  7536  				hooks = jQuery.valHooks[ elem.type ] ||
  7537  					jQuery.valHooks[ elem.nodeName.toLowerCase() ];
  7538  
  7539  				if ( hooks &&
  7540  					"get" in hooks &&
  7541  					( ret = hooks.get( elem, "value" ) ) !== undefined
  7542  				) {
  7543  					return ret;
  7544  				}
  7545  
  7546  				ret = elem.value;
  7547  
  7548  				return typeof ret === "string" ?
  7549  
  7550  					// Handle most common string cases
  7551  					ret.replace( rreturn, "" ) :
  7552  
  7553  					// Handle cases where value is null/undef or number
  7554  					ret == null ? "" : ret;
  7555  			}
  7556  
  7557  			return;
  7558  		}
  7559  
  7560  		isFunction = jQuery.isFunction( value );
  7561  
  7562  		return this.each( function( i ) {
  7563  			var val;
  7564  
  7565  			if ( this.nodeType !== 1 ) {
  7566  				return;
  7567  			}
  7568  
  7569  			if ( isFunction ) {
  7570  				val = value.call( this, i, jQuery( this ).val() );
  7571  			} else {
  7572  				val = value;
  7573  			}
  7574  
  7575  			// Treat null/undefined as ""; convert numbers to string
  7576  			if ( val == null ) {
  7577  				val = "";
  7578  
  7579  			} else if ( typeof val === "number" ) {
  7580  				val += "";
  7581  
  7582  			} else if ( jQuery.isArray( val ) ) {
  7583  				val = jQuery.map( val, function( value ) {
  7584  					return value == null ? "" : value + "";
  7585  				} );
  7586  			}
  7587  
  7588  			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
  7589  
  7590  			// If set returns undefined, fall back to normal setting
  7591  			if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
  7592  				this.value = val;
  7593  			}
  7594  		} );
  7595  	}
  7596  } );
  7597  
  7598  jQuery.extend( {
  7599  	valHooks: {
  7600  		option: {
  7601  			get: function( elem ) {
  7602  
  7603  				// Support: IE<11
  7604  				// option.value not trimmed (#14858)
  7605  				return jQuery.trim( elem.value );
  7606  			}
  7607  		},
  7608  		select: {
  7609  			get: function( elem ) {
  7610  				var value, option,
  7611  					options = elem.options,
  7612  					index = elem.selectedIndex,
  7613  					one = elem.type === "select-one" || index < 0,
  7614  					values = one ? null : [],
  7615  					max = one ? index + 1 : options.length,
  7616  					i = index < 0 ?
  7617  						max :
  7618  						one ? index : 0;
  7619  
  7620  				// Loop through all the selected options
  7621  				for ( ; i < max; i++ ) {
  7622  					option = options[ i ];
  7623  
  7624  					// IE8-9 doesn't update selected after form reset (#2551)
  7625  					if ( ( option.selected || i === index ) &&
  7626  
  7627  							// Don't return options that are disabled or in a disabled optgroup
  7628  							( support.optDisabled ?
  7629  								!option.disabled : option.getAttribute( "disabled" ) === null ) &&
  7630  							( !option.parentNode.disabled ||
  7631  								!jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
  7632  
  7633  						// Get the specific value for the option
  7634  						value = jQuery( option ).val();
  7635  
  7636  						// We don't need an array for one selects
  7637  						if ( one ) {
  7638  							return value;
  7639  						}
  7640  
  7641  						// Multi-Selects return an array
  7642  						values.push( value );
  7643  					}
  7644  				}
  7645  
  7646  				return values;
  7647  			},
  7648  
  7649  			set: function( elem, value ) {
  7650  				var optionSet, option,
  7651  					options = elem.options,
  7652  					values = jQuery.makeArray( value ),
  7653  					i = options.length;
  7654  
  7655  				while ( i-- ) {
  7656  					option = options[ i ];
  7657  					if ( option.selected =
  7658  							jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
  7659  					) {
  7660  						optionSet = true;
  7661  					}
  7662  				}
  7663  
  7664  				// Force browsers to behave consistently when non-matching value is set
  7665  				if ( !optionSet ) {
  7666  					elem.selectedIndex = -1;
  7667  				}
  7668  				return values;
  7669  			}
  7670  		}
  7671  	}
  7672  } );
  7673  
  7674  // Radios and checkboxes getter/setter
  7675  jQuery.each( [ "radio", "checkbox" ], function() {
  7676  	jQuery.valHooks[ this ] = {
  7677  		set: function( elem, value ) {
  7678  			if ( jQuery.isArray( value ) ) {
  7679  				return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
  7680  			}
  7681  		}
  7682  	};
  7683  	if ( !support.checkOn ) {
  7684  		jQuery.valHooks[ this ].get = function( elem ) {
  7685  			return elem.getAttribute( "value" ) === null ? "on" : elem.value;
  7686  		};
  7687  	}
  7688  } );
  7689  
  7690  
  7691  
  7692  
  7693  // Return jQuery for attributes-only inclusion
  7694  
  7695  
  7696  var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;
  7697  
  7698  jQuery.extend( jQuery.event, {
  7699  
  7700  	trigger: function( event, data, elem, onlyHandlers ) {
  7701  
  7702  		var i, cur, tmp, bubbleType, ontype, handle, special,
  7703  			eventPath = [ elem || document ],
  7704  			type = hasOwn.call( event, "type" ) ? event.type : event,
  7705  			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
  7706  
  7707  		cur = tmp = elem = elem || document;
  7708  
  7709  		// Don't do events on text and comment nodes
  7710  		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
  7711  			return;
  7712  		}
  7713  
  7714  		// focus/blur morphs to focusin/out; ensure we're not firing them right now
  7715  		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
  7716  			return;
  7717  		}
  7718  
  7719  		if ( type.indexOf( "." ) > -1 ) {
  7720  
  7721  			// Namespaced trigger; create a regexp to match event type in handle()
  7722  			namespaces = type.split( "." );
  7723  			type = namespaces.shift();
  7724  			namespaces.sort();
  7725  		}
  7726  		ontype = type.indexOf( ":" ) < 0 && "on" + type;
  7727  
  7728  		// Caller can pass in a jQuery.Event object, Object, or just an event type string
  7729  		event = event[ jQuery.expando ] ?
  7730  			event :
  7731  			new jQuery.Event( type, typeof event === "object" && event );
  7732  
  7733  		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
  7734  		event.isTrigger = onlyHandlers ? 2 : 3;
  7735  		event.namespace = namespaces.join( "." );
  7736  		event.rnamespace = event.namespace ?
  7737  			new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
  7738  			null;
  7739  
  7740  		// Clean up the event in case it is being reused
  7741  		event.result = undefined;
  7742  		if ( !event.target ) {
  7743  			event.target = elem;
  7744  		}
  7745  
  7746  		// Clone any incoming data and prepend the event, creating the handler arg list
  7747  		data = data == null ?
  7748  			[ event ] :
  7749  			jQuery.makeArray( data, [ event ] );
  7750  
  7751  		// Allow special events to draw outside the lines
  7752  		special = jQuery.event.special[ type ] || {};
  7753  		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
  7754  			return;
  7755  		}
  7756  
  7757  		// Determine event propagation path in advance, per W3C events spec (#9951)
  7758  		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
  7759  		if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
  7760  
  7761  			bubbleType = special.delegateType || type;
  7762  			if ( !rfocusMorph.test( bubbleType + type ) ) {
  7763  				cur = cur.parentNode;
  7764  			}
  7765  			for ( ; cur; cur = cur.parentNode ) {
  7766  				eventPath.push( cur );
  7767  				tmp = cur;
  7768  			}
  7769  
  7770  			// Only add window if we got to document (e.g., not plain obj or detached DOM)
  7771  			if ( tmp === ( elem.ownerDocument || document ) ) {
  7772  				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
  7773  			}
  7774  		}
  7775  
  7776  		// Fire handlers on the event path
  7777  		i = 0;
  7778  		while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
  7779  
  7780  			event.type = i > 1 ?
  7781  				bubbleType :
  7782  				special.bindType || type;
  7783  
  7784  			// jQuery handler
  7785  			handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
  7786  				dataPriv.get( cur, "handle" );
  7787  			if ( handle ) {
  7788  				handle.apply( cur, data );
  7789  			}
  7790  
  7791  			// Native handler
  7792  			handle = ontype && cur[ ontype ];
  7793  			if ( handle && handle.apply && acceptData( cur ) ) {
  7794  				event.result = handle.apply( cur, data );
  7795  				if ( event.result === false ) {
  7796  					event.preventDefault();
  7797  				}
  7798  			}
  7799  		}
  7800  		event.type = type;
  7801  
  7802  		// If nobody prevented the default action, do it now
  7803  		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
  7804  
  7805  			if ( ( !special._default ||
  7806  				special._default.apply( eventPath.pop(), data ) === false ) &&
  7807  				acceptData( elem ) ) {
  7808  
  7809  				// Call a native DOM method on the target with the same name name as the event.
  7810  				// Don't do default actions on window, that's where global variables be (#6170)
  7811  				if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
  7812  
  7813  					// Don't re-trigger an onFOO event when we call its FOO() method
  7814  					tmp = elem[ ontype ];
  7815  
  7816  					if ( tmp ) {
  7817  						elem[ ontype ] = null;
  7818  					}
  7819  
  7820  					// Prevent re-triggering of the same event, since we already bubbled it above
  7821  					jQuery.event.triggered = type;
  7822  					elem[ type ]();
  7823  					jQuery.event.triggered = undefined;
  7824  
  7825  					if ( tmp ) {
  7826  						elem[ ontype ] = tmp;
  7827  					}
  7828  				}
  7829  			}
  7830  		}
  7831  
  7832  		return event.result;
  7833  	},
  7834  
  7835  	// Piggyback on a donor event to simulate a different one
  7836  	simulate: function( type, elem, event ) {
  7837  		var e = jQuery.extend(
  7838  			new jQuery.Event(),
  7839  			event,
  7840  			{
  7841  				type: type,
  7842  				isSimulated: true
  7843  
  7844  				// Previously, `originalEvent: {}` was set here, so stopPropagation call
  7845  				// would not be triggered on donor event, since in our own
  7846  				// jQuery.event.stopPropagation function we had a check for existence of
  7847  				// originalEvent.stopPropagation method, so, consequently it would be a noop.
  7848  				//
  7849  				// But now, this "simulate" function is used only for events
  7850  				// for which stopPropagation() is noop, so there is no need for that anymore.
  7851  				//
  7852  				// For the compat branch though, guard for "click" and "submit"
  7853  				// events is still used, but was moved to jQuery.event.stopPropagation function
  7854  				// because `originalEvent` should point to the original event for the constancy
  7855  				// with other events and for more focused logic
  7856  			}
  7857  		);
  7858  
  7859  		jQuery.event.trigger( e, null, elem );
  7860  
  7861  		if ( e.isDefaultPrevented() ) {
  7862  			event.preventDefault();
  7863  		}
  7864  	}
  7865  
  7866  } );
  7867  
  7868  jQuery.fn.extend( {
  7869  
  7870  	trigger: function( type, data ) {
  7871  		return this.each( function() {
  7872  			jQuery.event.trigger( type, data, this );
  7873  		} );
  7874  	},
  7875  	triggerHandler: function( type, data ) {
  7876  		var elem = this[ 0 ];
  7877  		if ( elem ) {
  7878  			return jQuery.event.trigger( type, data, elem, true );
  7879  		}
  7880  	}
  7881  } );
  7882  
  7883  
  7884  jQuery.each( ( "blur focus focusin focusout load resize scroll unload click dblclick " +
  7885  	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
  7886  	"change select submit keydown keypress keyup error contextmenu" ).split( " " ),
  7887  	function( i, name ) {
  7888  
  7889  	// Handle event binding
  7890  	jQuery.fn[ name ] = function( data, fn ) {
  7891  		return arguments.length > 0 ?
  7892  			this.on( name, null, data, fn ) :
  7893  			this.trigger( name );
  7894  	};
  7895  } );
  7896  
  7897  jQuery.fn.extend( {
  7898  	hover: function( fnOver, fnOut ) {
  7899  		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
  7900  	}
  7901  } );
  7902  
  7903  
  7904  
  7905  
  7906  support.focusin = "onfocusin" in window;
  7907  
  7908  
  7909  // Support: Firefox
  7910  // Firefox doesn't have focus(in | out) events
  7911  // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
  7912  //
  7913  // Support: Chrome, Safari
  7914  // focus(in | out) events fire after focus & blur events,
  7915  // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
  7916  // Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857
  7917  if ( !support.focusin ) {
  7918  	jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
  7919  
  7920  		// Attach a single capturing handler on the document while someone wants focusin/focusout
  7921  		var handler = function( event ) {
  7922  			jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
  7923  		};
  7924  
  7925  		jQuery.event.special[ fix ] = {
  7926  			setup: function() {
  7927  				var doc = this.ownerDocument || this,
  7928  					attaches = dataPriv.access( doc, fix );
  7929  
  7930  				if ( !attaches ) {
  7931  					doc.addEventListener( orig, handler, true );
  7932  				}
  7933  				dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
  7934  			},
  7935  			teardown: function() {
  7936  				var doc = this.ownerDocument || this,
  7937  					attaches = dataPriv.access( doc, fix ) - 1;
  7938  
  7939  				if ( !attaches ) {
  7940  					doc.removeEventListener( orig, handler, true );
  7941  					dataPriv.remove( doc, fix );
  7942  
  7943  				} else {
  7944  					dataPriv.access( doc, fix, attaches );
  7945  				}
  7946  			}
  7947  		};
  7948  	} );
  7949  }
  7950  var location = window.location;
  7951  
  7952  var nonce = jQuery.now();
  7953  
  7954  var rquery = ( /\?/ );
  7955  
  7956  
  7957  
  7958  // Support: Android 2.3
  7959  // Workaround failure to string-cast null input
  7960  jQuery.parseJSON = function( data ) {
  7961  	return JSON.parse( data + "" );
  7962  };
  7963  
  7964  
  7965  // Cross-browser xml parsing
  7966  jQuery.parseXML = function( data ) {
  7967  	var xml;
  7968  	if ( !data || typeof data !== "string" ) {
  7969  		return null;
  7970  	}
  7971  
  7972  	// Support: IE9
  7973  	try {
  7974  		xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
  7975  	} catch ( e ) {
  7976  		xml = undefined;
  7977  	}
  7978  
  7979  	if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
  7980  		jQuery.error( "Invalid XML: " + data );
  7981  	}
  7982  	return xml;
  7983  };
  7984  
  7985  
  7986  var
  7987  	rhash = /#.*$/,
  7988  	rts = /([?&])_=[^&]*/,
  7989  	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
  7990  
  7991  	// #7653, #8125, #8152: local protocol detection
  7992  	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
  7993  	rnoContent = /^(?:GET|HEAD)$/,
  7994  	rprotocol = /^\/\//,
  7995  
  7996  	/* Prefilters
  7997  	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
  7998  	 * 2) These are called:
  7999  	 *    - BEFORE asking for a transport
  8000  	 *    - AFTER param serialization (s.data is a string if s.processData is true)
  8001  	 * 3) key is the dataType
  8002  	 * 4) the catchall symbol "*" can be used
  8003  	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
  8004  	 */
  8005  	prefilters = {},
  8006  
  8007  	/* Transports bindings
  8008  	 * 1) key is the dataType
  8009  	 * 2) the catchall symbol "*" can be used
  8010  	 * 3) selection will start with transport dataType and THEN go to "*" if needed
  8011  	 */
  8012  	transports = {},
  8013  
  8014  	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
  8015  	allTypes = "*/".concat( "*" ),
  8016  
  8017  	// Anchor tag for parsing the document origin
  8018  	originAnchor = document.createElement( "a" );
  8019  	originAnchor.href = location.href;
  8020  
  8021  // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
  8022  function addToPrefiltersOrTransports( structure ) {
  8023  
  8024  	// dataTypeExpression is optional and defaults to "*"
  8025  	return function( dataTypeExpression, func ) {
  8026  
  8027  		if ( typeof dataTypeExpression !== "string" ) {
  8028  			func = dataTypeExpression;
  8029  			dataTypeExpression = "*";
  8030  		}
  8031  
  8032  		var dataType,
  8033  			i = 0,
  8034  			dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
  8035  
  8036  		if ( jQuery.isFunction( func ) ) {
  8037  
  8038  			// For each dataType in the dataTypeExpression
  8039  			while ( ( dataType = dataTypes[ i++ ] ) ) {
  8040  
  8041  				// Prepend if requested
  8042  				if ( dataType[ 0 ] === "+" ) {
  8043  					dataType = dataType.slice( 1 ) || "*";
  8044  					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
  8045  
  8046  				// Otherwise append
  8047  				} else {
  8048  					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
  8049  				}
  8050  			}
  8051  		}
  8052  	};
  8053  }
  8054  
  8055  // Base inspection function for prefilters and transports
  8056  function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
  8057  
  8058  	var inspected = {},
  8059  		seekingTransport = ( structure === transports );
  8060  
  8061  	function inspect( dataType ) {
  8062  		var selected;
  8063  		inspected[ dataType ] = true;
  8064  		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
  8065  			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
  8066  			if ( typeof dataTypeOrTransport === "string" &&
  8067  				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
  8068  
  8069  				options.dataTypes.unshift( dataTypeOrTransport );
  8070  				inspect( dataTypeOrTransport );
  8071  				return false;
  8072  			} else if ( seekingTransport ) {
  8073  				return !( selected = dataTypeOrTransport );
  8074  			}
  8075  		} );
  8076  		return selected;
  8077  	}
  8078  
  8079  	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
  8080  }
  8081  
  8082  // A special extend for ajax options
  8083  // that takes "flat" options (not to be deep extended)
  8084  // Fixes #9887
  8085  function ajaxExtend( target, src ) {
  8086  	var key, deep,
  8087  		flatOptions = jQuery.ajaxSettings.flatOptions || {};
  8088  
  8089  	for ( key in src ) {
  8090  		if ( src[ key ] !== undefined ) {
  8091  			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
  8092  		}
  8093  	}
  8094  	if ( deep ) {
  8095  		jQuery.extend( true, target, deep );
  8096  	}
  8097  
  8098  	return target;
  8099  }
  8100  
  8101  /* Handles responses to an ajax request:
  8102   * - finds the right dataType (mediates between content-type and expected dataType)
  8103   * - returns the corresponding response
  8104   */
  8105  function ajaxHandleResponses( s, jqXHR, responses ) {
  8106  
  8107  	var ct, type, finalDataType, firstDataType,
  8108  		contents = s.contents,
  8109  		dataTypes = s.dataTypes;
  8110  
  8111  	// Remove auto dataType and get content-type in the process
  8112  	while ( dataTypes[ 0 ] === "*" ) {
  8113  		dataTypes.shift();
  8114  		if ( ct === undefined ) {
  8115  			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
  8116  		}
  8117  	}
  8118  
  8119  	// Check if we're dealing with a known content-type
  8120  	if ( ct ) {
  8121  		for ( type in contents ) {
  8122  			if ( contents[ type ] && contents[ type ].test( ct ) ) {
  8123  				dataTypes.unshift( type );
  8124  				break;
  8125  			}
  8126  		}
  8127  	}
  8128  
  8129  	// Check to see if we have a response for the expected dataType
  8130  	if ( dataTypes[ 0 ] in responses ) {
  8131  		finalDataType = dataTypes[ 0 ];
  8132  	} else {
  8133  
  8134  		// Try convertible dataTypes
  8135  		for ( type in responses ) {
  8136  			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
  8137  				finalDataType = type;
  8138  				break;
  8139  			}
  8140  			if ( !firstDataType ) {
  8141  				firstDataType = type;
  8142  			}
  8143  		}
  8144  
  8145  		// Or just use first one
  8146  		finalDataType = finalDataType || firstDataType;
  8147  	}
  8148  
  8149  	// If we found a dataType
  8150  	// We add the dataType to the list if needed
  8151  	// and return the corresponding response
  8152  	if ( finalDataType ) {
  8153  		if ( finalDataType !== dataTypes[ 0 ] ) {
  8154  			dataTypes.unshift( finalDataType );
  8155  		}
  8156  		return responses[ finalDataType ];
  8157  	}
  8158  }
  8159  
  8160  /* Chain conversions given the request and the original response
  8161   * Also sets the responseXXX fields on the jqXHR instance
  8162   */
  8163  function ajaxConvert( s, response, jqXHR, isSuccess ) {
  8164  	var conv2, current, conv, tmp, prev,
  8165  		converters = {},
  8166  
  8167  		// Work with a copy of dataTypes in case we need to modify it for conversion
  8168  		dataTypes = s.dataTypes.slice();
  8169  
  8170  	// Create converters map with lowercased keys
  8171  	if ( dataTypes[ 1 ] ) {
  8172  		for ( conv in s.converters ) {
  8173  			converters[ conv.toLowerCase() ] = s.converters[ conv ];
  8174  		}
  8175  	}
  8176  
  8177  	current = dataTypes.shift();
  8178  
  8179  	// Convert to each sequential dataType
  8180  	while ( current ) {
  8181  
  8182  		if ( s.responseFields[ current ] ) {
  8183  			jqXHR[ s.responseFields[ current ] ] = response;
  8184  		}
  8185  
  8186  		// Apply the dataFilter if provided
  8187  		if ( !prev && isSuccess && s.dataFilter ) {
  8188  			response = s.dataFilter( response, s.dataType );
  8189  		}
  8190  
  8191  		prev = current;
  8192  		current = dataTypes.shift();
  8193  
  8194  		if ( current ) {
  8195  
  8196  		// There's only work to do if current dataType is non-auto
  8197  			if ( current === "*" ) {
  8198  
  8199  				current = prev;
  8200  
  8201  			// Convert response if prev dataType is non-auto and differs from current
  8202  			} else if ( prev !== "*" && prev !== current ) {
  8203  
  8204  				// Seek a direct converter
  8205  				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
  8206  
  8207  				// If none found, seek a pair
  8208  				if ( !conv ) {
  8209  					for ( conv2 in converters ) {
  8210  
  8211  						// If conv2 outputs current
  8212  						tmp = conv2.split( " " );
  8213  						if ( tmp[ 1 ] === current ) {
  8214  
  8215  							// If prev can be converted to accepted input
  8216  							conv = converters[ prev + " " + tmp[ 0 ] ] ||
  8217  								converters[ "* " + tmp[ 0 ] ];
  8218  							if ( conv ) {
  8219  
  8220  								// Condense equivalence converters
  8221  								if ( conv === true ) {
  8222  									conv = converters[ conv2 ];
  8223  
  8224  								// Otherwise, insert the intermediate dataType
  8225  								} else if ( converters[ conv2 ] !== true ) {
  8226  									current = tmp[ 0 ];
  8227  									dataTypes.unshift( tmp[ 1 ] );
  8228  								}
  8229  								break;
  8230  							}
  8231  						}
  8232  					}
  8233  				}
  8234  
  8235  				// Apply converter (if not an equivalence)
  8236  				if ( conv !== true ) {
  8237  
  8238  					// Unless errors are allowed to bubble, catch and return them
  8239  					if ( conv && s.throws ) {
  8240  						response = conv( response );
  8241  					} else {
  8242  						try {
  8243  							response = conv( response );
  8244  						} catch ( e ) {
  8245  							return {
  8246  								state: "parsererror",
  8247  								error: conv ? e : "No conversion from " + prev + " to " + current
  8248  							};
  8249  						}
  8250  					}
  8251  				}
  8252  			}
  8253  		}
  8254  	}
  8255  
  8256  	return { state: "success", data: response };
  8257  }
  8258  
  8259  jQuery.extend( {
  8260  
  8261  	// Counter for holding the number of active queries
  8262  	active: 0,
  8263  
  8264  	// Last-Modified header cache for next request
  8265  	lastModified: {},
  8266  	etag: {},
  8267  
  8268  	ajaxSettings: {
  8269  		url: location.href,
  8270  		type: "GET",
  8271  		isLocal: rlocalProtocol.test( location.protocol ),
  8272  		global: true,
  8273  		processData: true,
  8274  		async: true,
  8275  		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
  8276  		/*
  8277  		timeout: 0,
  8278  		data: null,
  8279  		dataType: null,
  8280  		username: null,
  8281  		password: null,
  8282  		cache: null,
  8283  		throws: false,
  8284  		traditional: false,
  8285  		headers: {},
  8286  		*/
  8287  
  8288  		accepts: {
  8289  			"*": allTypes,
  8290  			text: "text/plain",
  8291  			html: "text/html",
  8292  			xml: "application/xml, text/xml",
  8293  			json: "application/json, text/javascript"
  8294  		},
  8295  
  8296  		contents: {
  8297  			xml: /\bxml\b/,
  8298  			html: /\bhtml/,
  8299  			json: /\bjson\b/
  8300  		},
  8301  
  8302  		responseFields: {
  8303  			xml: "responseXML",
  8304  			text: "responseText",
  8305  			json: "responseJSON"
  8306  		},
  8307  
  8308  		// Data converters
  8309  		// Keys separate source (or catchall "*") and destination types with a single space
  8310  		converters: {
  8311  
  8312  			// Convert anything to text
  8313  			"* text": String,
  8314  
  8315  			// Text to html (true = no transformation)
  8316  			"text html": true,
  8317  
  8318  			// Evaluate text as a json expression
  8319  			"text json": jQuery.parseJSON,
  8320  
  8321  			// Parse text as xml
  8322  			"text xml": jQuery.parseXML
  8323  		},
  8324  
  8325  		// For options that shouldn't be deep extended:
  8326  		// you can add your own custom options here if
  8327  		// and when you create one that shouldn't be
  8328  		// deep extended (see ajaxExtend)
  8329  		flatOptions: {
  8330  			url: true,
  8331  			context: true
  8332  		}
  8333  	},
  8334  
  8335  	// Creates a full fledged settings object into target
  8336  	// with both ajaxSettings and settings fields.
  8337  	// If target is omitted, writes into ajaxSettings.
  8338  	ajaxSetup: function( target, settings ) {
  8339  		return settings ?
  8340  
  8341  			// Building a settings object
  8342  			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
  8343  
  8344  			// Extending ajaxSettings
  8345  			ajaxExtend( jQuery.ajaxSettings, target );
  8346  	},
  8347  
  8348  	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
  8349  	ajaxTransport: addToPrefiltersOrTransports( transports ),
  8350  
  8351  	// Main method
  8352  	ajax: function( url, options ) {
  8353  
  8354  		// If url is an object, simulate pre-1.5 signature
  8355  		if ( typeof url === "object" ) {
  8356  			options = url;
  8357  			url = undefined;
  8358  		}
  8359  
  8360  		// Force options to be an object
  8361  		options = options || {};
  8362  
  8363  		var transport,
  8364  
  8365  			// URL without anti-cache param
  8366  			cacheURL,
  8367  
  8368  			// Response headers
  8369  			responseHeadersString,
  8370  			responseHeaders,
  8371  
  8372  			// timeout handle
  8373  			timeoutTimer,
  8374  
  8375  			// Url cleanup var
  8376  			urlAnchor,
  8377  
  8378  			// To know if global events are to be dispatched
  8379  			fireGlobals,
  8380  
  8381  			// Loop variable
  8382  			i,
  8383  
  8384  			// Create the final options object
  8385  			s = jQuery.ajaxSetup( {}, options ),
  8386  
  8387  			// Callbacks context
  8388  			callbackContext = s.context || s,
  8389  
  8390  			// Context for global events is callbackContext if it is a DOM node or jQuery collection
  8391  			globalEventContext = s.context &&
  8392  				( callbackContext.nodeType || callbackContext.jquery ) ?
  8393  					jQuery( callbackContext ) :
  8394  					jQuery.event,
  8395  
  8396  			// Deferreds
  8397  			deferred = jQuery.Deferred(),
  8398  			completeDeferred = jQuery.Callbacks( "once memory" ),
  8399  
  8400  			// Status-dependent callbacks
  8401  			statusCode = s.statusCode || {},
  8402  
  8403  			// Headers (they are sent all at once)
  8404  			requestHeaders = {},
  8405  			requestHeadersNames = {},
  8406  
  8407  			// The jqXHR state
  8408  			state = 0,
  8409  
  8410  			// Default abort message
  8411  			strAbort = "canceled",
  8412  
  8413  			// Fake xhr
  8414  			jqXHR = {
  8415  				readyState: 0,
  8416  
  8417  				// Builds headers hashtable if needed
  8418  				getResponseHeader: function( key ) {
  8419  					var match;
  8420  					if ( state === 2 ) {
  8421  						if ( !responseHeaders ) {
  8422  							responseHeaders = {};
  8423  							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
  8424  								responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
  8425  							}
  8426  						}
  8427  						match = responseHeaders[ key.toLowerCase() ];
  8428  					}
  8429  					return match == null ? null : match;
  8430  				},
  8431  
  8432  				// Raw string
  8433  				getAllResponseHeaders: function() {
  8434  					return state === 2 ? responseHeadersString : null;
  8435  				},
  8436  
  8437  				// Caches the header
  8438  				setRequestHeader: function( name, value ) {
  8439  					var lname = name.toLowerCase();
  8440  					if ( !state ) {
  8441  						name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
  8442  						requestHeaders[ name ] = value;
  8443  					}
  8444  					return this;
  8445  				},
  8446  
  8447  				// Overrides response content-type header
  8448  				overrideMimeType: function( type ) {
  8449  					if ( !state ) {
  8450  						s.mimeType = type;
  8451  					}
  8452  					return this;
  8453  				},
  8454  
  8455  				// Status-dependent callbacks
  8456  				statusCode: function( map ) {
  8457  					var code;
  8458  					if ( map ) {
  8459  						if ( state < 2 ) {
  8460  							for ( code in map ) {
  8461  
  8462  								// Lazy-add the new callback in a way that preserves old ones
  8463  								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
  8464  							}
  8465  						} else {
  8466  
  8467  							// Execute the appropriate callbacks
  8468  							jqXHR.always( map[ jqXHR.status ] );
  8469  						}
  8470  					}
  8471  					return this;
  8472  				},
  8473  
  8474  				// Cancel the request
  8475  				abort: function( statusText ) {
  8476  					var finalText = statusText || strAbort;
  8477  					if ( transport ) {
  8478  						transport.abort( finalText );
  8479  					}
  8480  					done( 0, finalText );
  8481  					return this;
  8482  				}
  8483  			};
  8484  
  8485  		// Attach deferreds
  8486  		deferred.promise( jqXHR ).complete = completeDeferred.add;
  8487  		jqXHR.success = jqXHR.done;
  8488  		jqXHR.error = jqXHR.fail;
  8489  
  8490  		// Remove hash character (#7531: and string promotion)
  8491  		// Add protocol if not provided (prefilters might expect it)
  8492  		// Handle falsy url in the settings object (#10093: consistency with old signature)
  8493  		// We also use the url parameter if available
  8494  		s.url = ( ( url || s.url || location.href ) + "" ).replace( rhash, "" )
  8495  			.replace( rprotocol, location.protocol + "//" );
  8496  
  8497  		// Alias method option to type as per ticket #12004
  8498  		s.type = options.method || options.type || s.method || s.type;
  8499  
  8500  		// Extract dataTypes list
  8501  		s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
  8502  
  8503  		// A cross-domain request is in order when the origin doesn't match the current origin.
  8504  		if ( s.crossDomain == null ) {
  8505  			urlAnchor = document.createElement( "a" );
  8506  
  8507  			// Support: IE8-11+
  8508  			// IE throws exception if url is malformed, e.g. http://example.com:80x/
  8509  			try {
  8510  				urlAnchor.href = s.url;
  8511  
  8512  				// Support: IE8-11+
  8513  				// Anchor's host property isn't correctly set when s.url is relative
  8514  				urlAnchor.href = urlAnchor.href;
  8515  				s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
  8516  					urlAnchor.protocol + "//" + urlAnchor.host;
  8517  			} catch ( e ) {
  8518  
  8519  				// If there is an error parsing the URL, assume it is crossDomain,
  8520  				// it can be rejected by the transport if it is invalid
  8521  				s.crossDomain = true;
  8522  			}
  8523  		}
  8524  
  8525  		// Convert data if not already a string
  8526  		if ( s.data && s.processData && typeof s.data !== "string" ) {
  8527  			s.data = jQuery.param( s.data, s.traditional );
  8528  		}
  8529  
  8530  		// Apply prefilters
  8531  		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
  8532  
  8533  		// If request was aborted inside a prefilter, stop there
  8534  		if ( state === 2 ) {
  8535  			return jqXHR;
  8536  		}
  8537  
  8538  		// We can fire global events as of now if asked to
  8539  		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
  8540  		fireGlobals = jQuery.event && s.global;
  8541  
  8542  		// Watch for a new set of requests
  8543  		if ( fireGlobals && jQuery.active++ === 0 ) {
  8544  			jQuery.event.trigger( "ajaxStart" );
  8545  		}
  8546  
  8547  		// Uppercase the type
  8548  		s.type = s.type.toUpperCase();
  8549  
  8550  		// Determine if request has content
  8551  		s.hasContent = !rnoContent.test( s.type );
  8552  
  8553  		// Save the URL in case we're toying with the If-Modified-Since
  8554  		// and/or If-None-Match header later on
  8555  		cacheURL = s.url;
  8556  
  8557  		// More options handling for requests with no content
  8558  		if ( !s.hasContent ) {
  8559  
  8560  			// If data is available, append data to url
  8561  			if ( s.data ) {
  8562  				cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
  8563  
  8564  				// #9682: remove data so that it's not used in an eventual retry
  8565  				delete s.data;
  8566  			}
  8567  
  8568  			// Add anti-cache in url if needed
  8569  			if ( s.cache === false ) {
  8570  				s.url = rts.test( cacheURL ) ?
  8571  
  8572  					// If there is already a '_' parameter, set its value
  8573  					cacheURL.replace( rts, "$1_=" + nonce++ ) :
  8574  
  8575  					// Otherwise add one to the end
  8576  					cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
  8577  			}
  8578  		}
  8579  
  8580  		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
  8581  		if ( s.ifModified ) {
  8582  			if ( jQuery.lastModified[ cacheURL ] ) {
  8583  				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
  8584  			}
  8585  			if ( jQuery.etag[ cacheURL ] ) {
  8586  				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
  8587  			}
  8588  		}
  8589  
  8590  		// Set the correct header, if data is being sent
  8591  		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
  8592  			jqXHR.setRequestHeader( "Content-Type", s.contentType );
  8593  		}
  8594  
  8595  		// Set the Accepts header for the server, depending on the dataType
  8596  		jqXHR.setRequestHeader(
  8597  			"Accept",
  8598  			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
  8599  				s.accepts[ s.dataTypes[ 0 ] ] +
  8600  					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
  8601  				s.accepts[ "*" ]
  8602  		);
  8603  
  8604  		// Check for headers option
  8605  		for ( i in s.headers ) {
  8606  			jqXHR.setRequestHeader( i, s.headers[ i ] );
  8607  		}
  8608  
  8609  		// Allow custom headers/mimetypes and early abort
  8610  		if ( s.beforeSend &&
  8611  			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
  8612  
  8613  			// Abort if not done already and return
  8614  			return jqXHR.abort();
  8615  		}
  8616  
  8617  		// Aborting is no longer a cancellation
  8618  		strAbort = "abort";
  8619  
  8620  		// Install callbacks on deferreds
  8621  		for ( i in { success: 1, error: 1, complete: 1 } ) {
  8622  			jqXHR[ i ]( s[ i ] );
  8623  		}
  8624  
  8625  		// Get transport
  8626  		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
  8627  
  8628  		// If no transport, we auto-abort
  8629  		if ( !transport ) {
  8630  			done( -1, "No Transport" );
  8631  		} else {
  8632  			jqXHR.readyState = 1;
  8633  
  8634  			// Send global event
  8635  			if ( fireGlobals ) {
  8636  				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
  8637  			}
  8638  
  8639  			// If request was aborted inside ajaxSend, stop there
  8640  			if ( state === 2 ) {
  8641  				return jqXHR;
  8642  			}
  8643  
  8644  			// Timeout
  8645  			if ( s.async && s.timeout > 0 ) {
  8646  				timeoutTimer = window.setTimeout( function() {
  8647  					jqXHR.abort( "timeout" );
  8648  				}, s.timeout );
  8649  			}
  8650  
  8651  			try {
  8652  				state = 1;
  8653  				transport.send( requestHeaders, done );
  8654  			} catch ( e ) {
  8655  
  8656  				// Propagate exception as error if not done
  8657  				if ( state < 2 ) {
  8658  					done( -1, e );
  8659  
  8660  				// Simply rethrow otherwise
  8661  				} else {
  8662  					throw e;
  8663  				}
  8664  			}
  8665  		}
  8666  
  8667  		// Callback for when everything is done
  8668  		function done( status, nativeStatusText, responses, headers ) {
  8669  			var isSuccess, success, error, response, modified,
  8670  				statusText = nativeStatusText;
  8671  
  8672  			// Called once
  8673  			if ( state === 2 ) {
  8674  				return;
  8675  			}
  8676  
  8677  			// State is "done" now
  8678  			state = 2;
  8679  
  8680  			// Clear timeout if it exists
  8681  			if ( timeoutTimer ) {
  8682  				window.clearTimeout( timeoutTimer );
  8683  			}
  8684  
  8685  			// Dereference transport for early garbage collection
  8686  			// (no matter how long the jqXHR object will be used)
  8687  			transport = undefined;
  8688  
  8689  			// Cache response headers
  8690  			responseHeadersString = headers || "";
  8691  
  8692  			// Set readyState
  8693  			jqXHR.readyState = status > 0 ? 4 : 0;
  8694  
  8695  			// Determine if successful
  8696  			isSuccess = status >= 200 && status < 300 || status === 304;
  8697  
  8698  			// Get response data
  8699  			if ( responses ) {
  8700  				response = ajaxHandleResponses( s, jqXHR, responses );
  8701  			}
  8702  
  8703  			// Convert no matter what (that way responseXXX fields are always set)
  8704  			response = ajaxConvert( s, response, jqXHR, isSuccess );
  8705  
  8706  			// If successful, handle type chaining
  8707  			if ( isSuccess ) {
  8708  
  8709  				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
  8710  				if ( s.ifModified ) {
  8711  					modified = jqXHR.getResponseHeader( "Last-Modified" );
  8712  					if ( modified ) {
  8713  						jQuery.lastModified[ cacheURL ] = modified;
  8714  					}
  8715  					modified = jqXHR.getResponseHeader( "etag" );
  8716  					if ( modified ) {
  8717  						jQuery.etag[ cacheURL ] = modified;
  8718  					}
  8719  				}
  8720  
  8721  				// if no content
  8722  				if ( status === 204 || s.type === "HEAD" ) {
  8723  					statusText = "nocontent";
  8724  
  8725  				// if not modified
  8726  				} else if ( status === 304 ) {
  8727  					statusText = "notmodified";
  8728  
  8729  				// If we have data, let's convert it
  8730  				} else {
  8731  					statusText = response.state;
  8732  					success = response.data;
  8733  					error = response.error;
  8734  					isSuccess = !error;
  8735  				}
  8736  			} else {
  8737  
  8738  				// Extract error from statusText and normalize for non-aborts
  8739  				error = statusText;
  8740  				if ( status || !statusText ) {
  8741  					statusText = "error";
  8742  					if ( status < 0 ) {
  8743  						status = 0;
  8744  					}
  8745  				}
  8746  			}
  8747  
  8748  			// Set data for the fake xhr object
  8749  			jqXHR.status = status;
  8750  			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
  8751  
  8752  			// Success/Error
  8753  			if ( isSuccess ) {
  8754  				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
  8755  			} else {
  8756  				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
  8757  			}
  8758  
  8759  			// Status-dependent callbacks
  8760  			jqXHR.statusCode( statusCode );
  8761  			statusCode = undefined;
  8762  
  8763  			if ( fireGlobals ) {
  8764  				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
  8765  					[ jqXHR, s, isSuccess ? success : error ] );
  8766  			}
  8767  
  8768  			// Complete
  8769  			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
  8770  
  8771  			if ( fireGlobals ) {
  8772  				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
  8773  
  8774  				// Handle the global AJAX counter
  8775  				if ( !( --jQuery.active ) ) {
  8776  					jQuery.event.trigger( "ajaxStop" );
  8777  				}
  8778  			}
  8779  		}
  8780  
  8781  		return jqXHR;
  8782  	},
  8783  
  8784  	getJSON: function( url, data, callback ) {
  8785  		return jQuery.get( url, data, callback, "json" );
  8786  	},
  8787  
  8788  	getScript: function( url, callback ) {
  8789  		return jQuery.get( url, undefined, callback, "script" );
  8790  	}
  8791  } );
  8792  
  8793  jQuery.each( [ "get", "post" ], function( i, method ) {
  8794  	jQuery[ method ] = function( url, data, callback, type ) {
  8795  
  8796  		// Shift arguments if data argument was omitted
  8797  		if ( jQuery.isFunction( data ) ) {
  8798  			type = type || callback;
  8799  			callback = data;
  8800  			data = undefined;
  8801  		}
  8802  
  8803  		// The url can be an options object (which then must have .url)
  8804  		return jQuery.ajax( jQuery.extend( {
  8805  			url: url,
  8806  			type: method,
  8807  			dataType: type,
  8808  			data: data,
  8809  			success: callback
  8810  		}, jQuery.isPlainObject( url ) && url ) );
  8811  	};
  8812  } );
  8813  
  8814  
  8815  jQuery._evalUrl = function( url ) {
  8816  	return jQuery.ajax( {
  8817  		url: url,
  8818  
  8819  		// Make this explicit, since user can override this through ajaxSetup (#11264)
  8820  		type: "GET",
  8821  		dataType: "script",
  8822  		async: false,
  8823  		global: false,
  8824  		"throws": true
  8825  	} );
  8826  };
  8827  
  8828  
  8829  jQuery.fn.extend( {
  8830  	wrapAll: function( html ) {
  8831  		var wrap;
  8832  
  8833  		if ( jQuery.isFunction( html ) ) {
  8834  			return this.each( function( i ) {
  8835  				jQuery( this ).wrapAll( html.call( this, i ) );
  8836  			} );
  8837  		}
  8838  
  8839  		if ( this[ 0 ] ) {
  8840  
  8841  			// The elements to wrap the target around
  8842  			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
  8843  
  8844  			if ( this[ 0 ].parentNode ) {
  8845  				wrap.insertBefore( this[ 0 ] );
  8846  			}
  8847  
  8848  			wrap.map( function() {
  8849  				var elem = this;
  8850  
  8851  				while ( elem.firstElementChild ) {
  8852  					elem = elem.firstElementChild;
  8853  				}
  8854  
  8855  				return elem;
  8856  			} ).append( this );
  8857  		}
  8858  
  8859  		return this;
  8860  	},
  8861  
  8862  	wrapInner: function( html ) {
  8863  		if ( jQuery.isFunction( html ) ) {
  8864  			return this.each( function( i ) {
  8865  				jQuery( this ).wrapInner( html.call( this, i ) );
  8866  			} );
  8867  		}
  8868  
  8869  		return this.each( function() {
  8870  			var self = jQuery( this ),
  8871  				contents = self.contents();
  8872  
  8873  			if ( contents.length ) {
  8874  				contents.wrapAll( html );
  8875  
  8876  			} else {
  8877  				self.append( html );
  8878  			}
  8879  		} );
  8880  	},
  8881  
  8882  	wrap: function( html ) {
  8883  		var isFunction = jQuery.isFunction( html );
  8884  
  8885  		return this.each( function( i ) {
  8886  			jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
  8887  		} );
  8888  	},
  8889  
  8890  	unwrap: function() {
  8891  		return this.parent().each( function() {
  8892  			if ( !jQuery.nodeName( this, "body" ) ) {
  8893  				jQuery( this ).replaceWith( this.childNodes );
  8894  			}
  8895  		} ).end();
  8896  	}
  8897  } );
  8898  
  8899  
  8900  jQuery.expr.filters.hidden = function( elem ) {
  8901  	return !jQuery.expr.filters.visible( elem );
  8902  };
  8903  jQuery.expr.filters.visible = function( elem ) {
  8904  
  8905  	// Support: Opera <= 12.12
  8906  	// Opera reports offsetWidths and offsetHeights less than zero on some elements
  8907  	// Use OR instead of AND as the element is not visible if either is true
  8908  	// See tickets #10406 and #13132
  8909  	return elem.offsetWidth > 0 || elem.offsetHeight > 0 || elem.getClientRects().length > 0;
  8910  };
  8911  
  8912  
  8913  
  8914  
  8915  var r20 = /%20/g,
  8916  	rbracket = /\[\]$/,
  8917  	rCRLF = /\r?\n/g,
  8918  	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
  8919  	rsubmittable = /^(?:input|select|textarea|keygen)/i;
  8920  
  8921  function buildParams( prefix, obj, traditional, add ) {
  8922  	var name;
  8923  
  8924  	if ( jQuery.isArray( obj ) ) {
  8925  
  8926  		// Serialize array item.
  8927  		jQuery.each( obj, function( i, v ) {
  8928  			if ( traditional || rbracket.test( prefix ) ) {
  8929  
  8930  				// Treat each array item as a scalar.
  8931  				add( prefix, v );
  8932  
  8933  			} else {
  8934  
  8935  				// Item is non-scalar (array or object), encode its numeric index.
  8936  				buildParams(
  8937  					prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
  8938  					v,
  8939  					traditional,
  8940  					add
  8941  				);
  8942  			}
  8943  		} );
  8944  
  8945  	} else if ( !traditional && jQuery.type( obj ) === "object" ) {
  8946  
  8947  		// Serialize object item.
  8948  		for ( name in obj ) {
  8949  			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
  8950  		}
  8951  
  8952  	} else {
  8953  
  8954  		// Serialize scalar item.
  8955  		add( prefix, obj );
  8956  	}
  8957  }
  8958  
  8959  // Serialize an array of form elements or a set of
  8960  // key/values into a query string
  8961  jQuery.param = function( a, traditional ) {
  8962  	var prefix,
  8963  		s = [],
  8964  		add = function( key, value ) {
  8965  
  8966  			// If value is a function, invoke it and return its value
  8967  			value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
  8968  			s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
  8969  		};
  8970  
  8971  	// Set traditional to true for jQuery <= 1.3.2 behavior.
  8972  	if ( traditional === undefined ) {
  8973  		traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
  8974  	}
  8975  
  8976  	// If an array was passed in, assume that it is an array of form elements.
  8977  	if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
  8978  
  8979  		// Serialize the form elements
  8980  		jQuery.each( a, function() {
  8981  			add( this.name, this.value );
  8982  		} );
  8983  
  8984  	} else {
  8985  
  8986  		// If traditional, encode the "old" way (the way 1.3.2 or older
  8987  		// did it), otherwise encode params recursively.
  8988  		for ( prefix in a ) {
  8989  			buildParams( prefix, a[ prefix ], traditional, add );
  8990  		}
  8991  	}
  8992  
  8993  	// Return the resulting serialization
  8994  	return s.join( "&" ).replace( r20, "+" );
  8995  };
  8996  
  8997  jQuery.fn.extend( {
  8998  	serialize: function() {
  8999  		return jQuery.param( this.serializeArray() );
  9000  	},
  9001  	serializeArray: function() {
  9002  		return this.map( function() {
  9003  
  9004  			// Can add propHook for "elements" to filter or add form elements
  9005  			var elements = jQuery.prop( this, "elements" );
  9006  			return elements ? jQuery.makeArray( elements ) : this;
  9007  		} )
  9008  		.filter( function() {
  9009  			var type = this.type;
  9010  
  9011  			// Use .is( ":disabled" ) so that fieldset[disabled] works
  9012  			return this.name && !jQuery( this ).is( ":disabled" ) &&
  9013  				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
  9014  				( this.checked || !rcheckableType.test( type ) );
  9015  		} )
  9016  		.map( function( i, elem ) {
  9017  			var val = jQuery( this ).val();
  9018  
  9019  			return val == null ?
  9020  				null :
  9021  				jQuery.isArray( val ) ?
  9022  					jQuery.map( val, function( val ) {
  9023  						return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
  9024  					} ) :
  9025  					{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
  9026  		} ).get();
  9027  	}
  9028  } );
  9029  
  9030  
  9031  jQuery.ajaxSettings.xhr = function() {
  9032  	try {
  9033  		return new window.XMLHttpRequest();
  9034  	} catch ( e ) {}
  9035  };
  9036  
  9037  var xhrSuccessStatus = {
  9038  
  9039  		// File protocol always yields status code 0, assume 200
  9040  		0: 200,
  9041  
  9042  		// Support: IE9
  9043  		// #1450: sometimes IE returns 1223 when it should be 204
  9044  		1223: 204
  9045  	},
  9046  	xhrSupported = jQuery.ajaxSettings.xhr();
  9047  
  9048  support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
  9049  support.ajax = xhrSupported = !!xhrSupported;
  9050  
  9051  jQuery.ajaxTransport( function( options ) {
  9052  	var callback, errorCallback;
  9053  
  9054  	// Cross domain only allowed if supported through XMLHttpRequest
  9055  	if ( support.cors || xhrSupported && !options.crossDomain ) {
  9056  		return {
  9057  			send: function( headers, complete ) {
  9058  				var i,
  9059  					xhr = options.xhr();
  9060  
  9061  				xhr.open(
  9062  					options.type,
  9063  					options.url,
  9064  					options.async,
  9065  					options.username,
  9066  					options.password
  9067  				);
  9068  
  9069  				// Apply custom fields if provided
  9070  				if ( options.xhrFields ) {
  9071  					for ( i in options.xhrFields ) {
  9072  						xhr[ i ] = options.xhrFields[ i ];
  9073  					}
  9074  				}
  9075  
  9076  				// Override mime type if needed
  9077  				if ( options.mimeType && xhr.overrideMimeType ) {
  9078  					xhr.overrideMimeType( options.mimeType );
  9079  				}
  9080  
  9081  				// X-Requested-With header
  9082  				// For cross-domain requests, seeing as conditions for a preflight are
  9083  				// akin to a jigsaw puzzle, we simply never set it to be sure.
  9084  				// (it can always be set on a per-request basis or even using ajaxSetup)
  9085  				// For same-domain requests, won't change header if already provided.
  9086  				if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
  9087  					headers[ "X-Requested-With" ] = "XMLHttpRequest";
  9088  				}
  9089  
  9090  				// Set headers
  9091  				for ( i in headers ) {
  9092  					xhr.setRequestHeader( i, headers[ i ] );
  9093  				}
  9094  
  9095  				// Callback
  9096  				callback = function( type ) {
  9097  					return function() {
  9098  						if ( callback ) {
  9099  							callback = errorCallback = xhr.onload =
  9100  								xhr.onerror = xhr.onabort = xhr.onreadystatechange = null;
  9101  
  9102  							if ( type === "abort" ) {
  9103  								xhr.abort();
  9104  							} else if ( type === "error" ) {
  9105  
  9106  								// Support: IE9
  9107  								// On a manual native abort, IE9 throws
  9108  								// errors on any property access that is not readyState
  9109  								if ( typeof xhr.status !== "number" ) {
  9110  									complete( 0, "error" );
  9111  								} else {
  9112  									complete(
  9113  
  9114  										// File: protocol always yields status 0; see #8605, #14207
  9115  										xhr.status,
  9116  										xhr.statusText
  9117  									);
  9118  								}
  9119  							} else {
  9120  								complete(
  9121  									xhrSuccessStatus[ xhr.status ] || xhr.status,
  9122  									xhr.statusText,
  9123  
  9124  									// Support: IE9 only
  9125  									// IE9 has no XHR2 but throws on binary (trac-11426)
  9126  									// For XHR2 non-text, let the caller handle it (gh-2498)
  9127  									( xhr.responseType || "text" ) !== "text"  ||
  9128  									typeof xhr.responseText !== "string" ?
  9129  										{ binary: xhr.response } :
  9130  										{ text: xhr.responseText },
  9131  									xhr.getAllResponseHeaders()
  9132  								);
  9133  							}
  9134  						}
  9135  					};
  9136  				};
  9137  
  9138  				// Listen to events
  9139  				xhr.onload = callback();
  9140  				errorCallback = xhr.onerror = callback( "error" );
  9141  
  9142  				// Support: IE9
  9143  				// Use onreadystatechange to replace onabort
  9144  				// to handle uncaught aborts
  9145  				if ( xhr.onabort !== undefined ) {
  9146  					xhr.onabort = errorCallback;
  9147  				} else {
  9148  					xhr.onreadystatechange = function() {
  9149  
  9150  						// Check readyState before timeout as it changes
  9151  						if ( xhr.readyState === 4 ) {
  9152  
  9153  							// Allow onerror to be called first,
  9154  							// but that will not handle a native abort
  9155  							// Also, save errorCallback to a variable
  9156  							// as xhr.onerror cannot be accessed
  9157  							window.setTimeout( function() {
  9158  								if ( callback ) {
  9159  									errorCallback();
  9160  								}
  9161  							} );
  9162  						}
  9163  					};
  9164  				}
  9165  
  9166  				// Create the abort callback
  9167  				callback = callback( "abort" );
  9168  
  9169  				try {
  9170  
  9171  					// Do send the request (this may raise an exception)
  9172  					xhr.send( options.hasContent && options.data || null );
  9173  				} catch ( e ) {
  9174  
  9175  					// #14683: Only rethrow if this hasn't been notified as an error yet
  9176  					if ( callback ) {
  9177  						throw e;
  9178  					}
  9179  				}
  9180  			},
  9181  
  9182  			abort: function() {
  9183  				if ( callback ) {
  9184  					callback();
  9185  				}
  9186  			}
  9187  		};
  9188  	}
  9189  } );
  9190  
  9191  
  9192  
  9193  
  9194  // Install script dataType
  9195  jQuery.ajaxSetup( {
  9196  	accepts: {
  9197  		script: "text/javascript, application/javascript, " +
  9198  			"application/ecmascript, application/x-ecmascript"
  9199  	},
  9200  	contents: {
  9201  		script: /\b(?:java|ecma)script\b/
  9202  	},
  9203  	converters: {
  9204  		"text script": function( text ) {
  9205  			jQuery.globalEval( text );
  9206  			return text;
  9207  		}
  9208  	}
  9209  } );
  9210  
  9211  // Handle cache's special case and crossDomain
  9212  jQuery.ajaxPrefilter( "script", function( s ) {
  9213  	if ( s.cache === undefined ) {
  9214  		s.cache = false;
  9215  	}
  9216  	if ( s.crossDomain ) {
  9217  		s.type = "GET";
  9218  	}
  9219  } );
  9220  
  9221  // Bind script tag hack transport
  9222  jQuery.ajaxTransport( "script", function( s ) {
  9223  
  9224  	// This transport only deals with cross domain requests
  9225  	if ( s.crossDomain ) {
  9226  		var script, callback;
  9227  		return {
  9228  			send: function( _, complete ) {
  9229  				script = jQuery( "<script>" ).prop( {
  9230  					charset: s.scriptCharset,
  9231  					src: s.url
  9232  				} ).on(
  9233  					"load error",
  9234  					callback = function( evt ) {
  9235  						script.remove();
  9236  						callback = null;
  9237  						if ( evt ) {
  9238  							complete( evt.type === "error" ? 404 : 200, evt.type );
  9239  						}
  9240  					}
  9241  				);
  9242  
  9243  				// Use native DOM manipulation to avoid our domManip AJAX trickery
  9244  				document.head.appendChild( script[ 0 ] );
  9245  			},
  9246  			abort: function() {
  9247  				if ( callback ) {
  9248  					callback();
  9249  				}
  9250  			}
  9251  		};
  9252  	}
  9253  } );
  9254  
  9255  
  9256  
  9257  
  9258  var oldCallbacks = [],
  9259  	rjsonp = /(=)\?(?=&|$)|\?\?/;
  9260  
  9261  // Default jsonp settings
  9262  jQuery.ajaxSetup( {
  9263  	jsonp: "callback",
  9264  	jsonpCallback: function() {
  9265  		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
  9266  		this[ callback ] = true;
  9267  		return callback;
  9268  	}
  9269  } );
  9270  
  9271  // Detect, normalize options and install callbacks for jsonp requests
  9272  jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
  9273  
  9274  	var callbackName, overwritten, responseContainer,
  9275  		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
  9276  			"url" :
  9277  			typeof s.data === "string" &&
  9278  				( s.contentType || "" )
  9279  					.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
  9280  				rjsonp.test( s.data ) && "data"
  9281  		);
  9282  
  9283  	// Handle iff the expected data type is "jsonp" or we have a parameter to set
  9284  	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
  9285  
  9286  		// Get callback name, remembering preexisting value associated with it
  9287  		callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
  9288  			s.jsonpCallback() :
  9289  			s.jsonpCallback;
  9290  
  9291  		// Insert callback into url or form data
  9292  		if ( jsonProp ) {
  9293  			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
  9294  		} else if ( s.jsonp !== false ) {
  9295  			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
  9296  		}
  9297  
  9298  		// Use data converter to retrieve json after script execution
  9299  		s.converters[ "script json" ] = function() {
  9300  			if ( !responseContainer ) {
  9301  				jQuery.error( callbackName + " was not called" );
  9302  			}
  9303  			return responseContainer[ 0 ];
  9304  		};
  9305  
  9306  		// Force json dataType
  9307  		s.dataTypes[ 0 ] = "json";
  9308  
  9309  		// Install callback
  9310  		overwritten = window[ callbackName ];
  9311  		window[ callbackName ] = function() {
  9312  			responseContainer = arguments;
  9313  		};
  9314  
  9315  		// Clean-up function (fires after converters)
  9316  		jqXHR.always( function() {
  9317  
  9318  			// If previous value didn't exist - remove it
  9319  			if ( overwritten === undefined ) {
  9320  				jQuery( window ).removeProp( callbackName );
  9321  
  9322  			// Otherwise restore preexisting value
  9323  			} else {
  9324  				window[ callbackName ] = overwritten;
  9325  			}
  9326  
  9327  			// Save back as free
  9328  			if ( s[ callbackName ] ) {
  9329  
  9330  				// Make sure that re-using the options doesn't screw things around
  9331  				s.jsonpCallback = originalSettings.jsonpCallback;
  9332  
  9333  				// Save the callback name for future use
  9334  				oldCallbacks.push( callbackName );
  9335  			}
  9336  
  9337  			// Call if it was a function and we have a response
  9338  			if ( responseContainer && jQuery.isFunction( overwritten ) ) {
  9339  				overwritten( responseContainer[ 0 ] );
  9340  			}
  9341  
  9342  			responseContainer = overwritten = undefined;
  9343  		} );
  9344  
  9345  		// Delegate to script
  9346  		return "script";
  9347  	}
  9348  } );
  9349  
  9350  
  9351  
  9352  
  9353  // Support: Safari 8+
  9354  // In Safari 8 documents created via document.implementation.createHTMLDocument
  9355  // collapse sibling forms: the second one becomes a child of the first one.
  9356  // Because of that, this security measure has to be disabled in Safari 8.
  9357  // https://bugs.webkit.org/show_bug.cgi?id=137337
  9358  support.createHTMLDocument = ( function() {
  9359  	var body = document.implementation.createHTMLDocument( "" ).body;
  9360  	body.innerHTML = "<form></form><form></form>";
  9361  	return body.childNodes.length === 2;
  9362  } )();
  9363  
  9364  
  9365  // Argument "data" should be string of html
  9366  // context (optional): If specified, the fragment will be created in this context,
  9367  // defaults to document
  9368  // keepScripts (optional): If true, will include scripts passed in the html string
  9369  jQuery.parseHTML = function( data, context, keepScripts ) {
  9370  	if ( !data || typeof data !== "string" ) {
  9371  		return null;
  9372  	}
  9373  	if ( typeof context === "boolean" ) {
  9374  		keepScripts = context;
  9375  		context = false;
  9376  	}
  9377  
  9378  	// Stop scripts or inline event handlers from being executed immediately
  9379  	// by using document.implementation
  9380  	context = context || ( support.createHTMLDocument ?
  9381  		document.implementation.createHTMLDocument( "" ) :
  9382  		document );
  9383  
  9384  	var parsed = rsingleTag.exec( data ),
  9385  		scripts = !keepScripts && [];
  9386  
  9387  	// Single tag
  9388  	if ( parsed ) {
  9389  		return [ context.createElement( parsed[ 1 ] ) ];
  9390  	}
  9391  
  9392  	parsed = buildFragment( [ data ], context, scripts );
  9393  
  9394  	if ( scripts && scripts.length ) {
  9395  		jQuery( scripts ).remove();
  9396  	}
  9397  
  9398  	return jQuery.merge( [], parsed.childNodes );
  9399  };
  9400  
  9401  
  9402  // Keep a copy of the old load method
  9403  var _load = jQuery.fn.load;
  9404  
  9405  /**
  9406   * Load a url into a page
  9407   */
  9408  jQuery.fn.load = function( url, params, callback ) {
  9409  	if ( typeof url !== "string" && _load ) {
  9410  		return _load.apply( this, arguments );
  9411  	}
  9412  
  9413  	var selector, type, response,
  9414  		self = this,
  9415  		off = url.indexOf( " " );
  9416  
  9417  	if ( off > -1 ) {
  9418  		selector = jQuery.trim( url.slice( off ) );
  9419  		url = url.slice( 0, off );
  9420  	}
  9421  
  9422  	// If it's a function
  9423  	if ( jQuery.isFunction( params ) ) {
  9424  
  9425  		// We assume that it's the callback
  9426  		callback = params;
  9427  		params = undefined;
  9428  
  9429  	// Otherwise, build a param string
  9430  	} else if ( params && typeof params === "object" ) {
  9431  		type = "POST";
  9432  	}
  9433  
  9434  	// If we have elements to modify, make the request
  9435  	if ( self.length > 0 ) {
  9436  		jQuery.ajax( {
  9437  			url: url,
  9438  
  9439  			// If "type" variable is undefined, then "GET" method will be used.
  9440  			// Make value of this field explicit since
  9441  			// user can override it through ajaxSetup method
  9442  			type: type || "GET",
  9443  			dataType: "html",
  9444  			data: params
  9445  		} ).done( function( responseText ) {
  9446  
  9447  			// Save response for use in complete callback
  9448  			response = arguments;
  9449  
  9450  			self.html( selector ?
  9451  
  9452  				// If a selector was specified, locate the right elements in a dummy div
  9453  				// Exclude scripts to avoid IE 'Permission Denied' errors
  9454  				jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
  9455  
  9456  				// Otherwise use the full result
  9457  				responseText );
  9458  
  9459  		// If the request succeeds, this function gets "data", "status", "jqXHR"
  9460  		// but they are ignored because response was set above.
  9461  		// If it fails, this function gets "jqXHR", "status", "error"
  9462  		} ).always( callback && function( jqXHR, status ) {
  9463  			self.each( function() {
  9464  				callback.apply( self, response || [ jqXHR.responseText, status, jqXHR ] );
  9465  			} );
  9466  		} );
  9467  	}
  9468  
  9469  	return this;
  9470  };
  9471  
  9472  
  9473  
  9474  
  9475  // Attach a bunch of functions for handling common AJAX events
  9476  jQuery.each( [
  9477  	"ajaxStart",
  9478  	"ajaxStop",
  9479  	"ajaxComplete",
  9480  	"ajaxError",
  9481  	"ajaxSuccess",
  9482  	"ajaxSend"
  9483  ], function( i, type ) {
  9484  	jQuery.fn[ type ] = function( fn ) {
  9485  		return this.on( type, fn );
  9486  	};
  9487  } );
  9488  
  9489  
  9490  
  9491  
  9492  jQuery.expr.filters.animated = function( elem ) {
  9493  	return jQuery.grep( jQuery.timers, function( fn ) {
  9494  		return elem === fn.elem;
  9495  	} ).length;
  9496  };
  9497  
  9498  
  9499  
  9500  
  9501  /**
  9502   * Gets a window from an element
  9503   */
  9504  function getWindow( elem ) {
  9505  	return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
  9506  }
  9507  
  9508  jQuery.offset = {
  9509  	setOffset: function( elem, options, i ) {
  9510  		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
  9511  			position = jQuery.css( elem, "position" ),
  9512  			curElem = jQuery( elem ),
  9513  			props = {};
  9514  
  9515  		// Set position first, in-case top/left are set even on static elem
  9516  		if ( position === "static" ) {
  9517  			elem.style.position = "relative";
  9518  		}
  9519  
  9520  		curOffset = curElem.offset();
  9521  		curCSSTop = jQuery.css( elem, "top" );
  9522  		curCSSLeft = jQuery.css( elem, "left" );
  9523  		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
  9524  			( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
  9525  
  9526  		// Need to be able to calculate position if either
  9527  		// top or left is auto and position is either absolute or fixed
  9528  		if ( calculatePosition ) {
  9529  			curPosition = curElem.position();
  9530  			curTop = curPosition.top;
  9531  			curLeft = curPosition.left;
  9532  
  9533  		} else {
  9534  			curTop = parseFloat( curCSSTop ) || 0;
  9535  			curLeft = parseFloat( curCSSLeft ) || 0;
  9536  		}
  9537  
  9538  		if ( jQuery.isFunction( options ) ) {
  9539  
  9540  			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
  9541  			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
  9542  		}
  9543  
  9544  		if ( options.top != null ) {
  9545  			props.top = ( options.top - curOffset.top ) + curTop;
  9546  		}
  9547  		if ( options.left != null ) {
  9548  			props.left = ( options.left - curOffset.left ) + curLeft;
  9549  		}
  9550  
  9551  		if ( "using" in options ) {
  9552  			options.using.call( elem, props );
  9553  
  9554  		} else {
  9555  			curElem.css( props );
  9556  		}
  9557  	}
  9558  };
  9559  
  9560  jQuery.fn.extend( {
  9561  	offset: function( options ) {
  9562  		if ( arguments.length ) {
  9563  			return options === undefined ?
  9564  				this :
  9565  				this.each( function( i ) {
  9566  					jQuery.offset.setOffset( this, options, i );
  9567  				} );
  9568  		}
  9569  
  9570  		var docElem, win,
  9571  			elem = this[ 0 ],
  9572  			box = { top: 0, left: 0 },
  9573  			doc = elem && elem.ownerDocument;
  9574  
  9575  		if ( !doc ) {
  9576  			return;
  9577  		}
  9578  
  9579  		docElem = doc.documentElement;
  9580  
  9581  		// Make sure it's not a disconnected DOM node
  9582  		if ( !jQuery.contains( docElem, elem ) ) {
  9583  			return box;
  9584  		}
  9585  
  9586  		box = elem.getBoundingClientRect();
  9587  		win = getWindow( doc );
  9588  		return {
  9589  			top: box.top + win.pageYOffset - docElem.clientTop,
  9590  			left: box.left + win.pageXOffset - docElem.clientLeft
  9591  		};
  9592  	},
  9593  
  9594  	position: function() {
  9595  		if ( !this[ 0 ] ) {
  9596  			return;
  9597  		}
  9598  
  9599  		var offsetParent, offset,
  9600  			elem = this[ 0 ],
  9601  			parentOffset = { top: 0, left: 0 };
  9602  
  9603  		// Fixed elements are offset from window (parentOffset = {top:0, left: 0},
  9604  		// because it is its only offset parent
  9605  		if ( jQuery.css( elem, "position" ) === "fixed" ) {
  9606  
  9607  			// Assume getBoundingClientRect is there when computed position is fixed
  9608  			offset = elem.getBoundingClientRect();
  9609  
  9610  		} else {
  9611  
  9612  			// Get *real* offsetParent
  9613  			offsetParent = this.offsetParent();
  9614  
  9615  			// Get correct offsets
  9616  			offset = this.offset();
  9617  			if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
  9618  				parentOffset = offsetParent.offset();
  9619  			}
  9620  
  9621  			// Add offsetParent borders
  9622  			// Subtract offsetParent scroll positions
  9623  			parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ) -
  9624  				offsetParent.scrollTop();
  9625  			parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true ) -
  9626  				offsetParent.scrollLeft();
  9627  		}
  9628  
  9629  		// Subtract parent offsets and element margins
  9630  		return {
  9631  			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
  9632  			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
  9633  		};
  9634  	},
  9635  
  9636  	// This method will return documentElement in the following cases:
  9637  	// 1) For the element inside the iframe without offsetParent, this method will return
  9638  	//    documentElement of the parent window
  9639  	// 2) For the hidden or detached element
  9640  	// 3) For body or html element, i.e. in case of the html node - it will return itself
  9641  	//
  9642  	// but those exceptions were never presented as a real life use-cases
  9643  	// and might be considered as more preferable results.
  9644  	//
  9645  	// This logic, however, is not guaranteed and can change at any point in the future
  9646  	offsetParent: function() {
  9647  		return this.map( function() {
  9648  			var offsetParent = this.offsetParent;
  9649  
  9650  			while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
  9651  				offsetParent = offsetParent.offsetParent;
  9652  			}
  9653  
  9654  			return offsetParent || documentElement;
  9655  		} );
  9656  	}
  9657  } );
  9658  
  9659  // Create scrollLeft and scrollTop methods
  9660  jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
  9661  	var top = "pageYOffset" === prop;
  9662  
  9663  	jQuery.fn[ method ] = function( val ) {
  9664  		return access( this, function( elem, method, val ) {
  9665  			var win = getWindow( elem );
  9666  
  9667  			if ( val === undefined ) {
  9668  				return win ? win[ prop ] : elem[ method ];
  9669  			}
  9670  
  9671  			if ( win ) {
  9672  				win.scrollTo(
  9673  					!top ? val : win.pageXOffset,
  9674  					top ? val : win.pageYOffset
  9675  				);
  9676  
  9677  			} else {
  9678  				elem[ method ] = val;
  9679  			}
  9680  		}, method, val, arguments.length );
  9681  	};
  9682  } );
  9683  
  9684  // Support: Safari<7-8+, Chrome<37-44+
  9685  // Add the top/left cssHooks using jQuery.fn.position
  9686  // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
  9687  // Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280
  9688  // getComputedStyle returns percent when specified for top/left/bottom/right;
  9689  // rather than make the css module depend on the offset module, just check for it here
  9690  jQuery.each( [ "top", "left" ], function( i, prop ) {
  9691  	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
  9692  		function( elem, computed ) {
  9693  			if ( computed ) {
  9694  				computed = curCSS( elem, prop );
  9695  
  9696  				// If curCSS returns percentage, fallback to offset
  9697  				return rnumnonpx.test( computed ) ?
  9698  					jQuery( elem ).position()[ prop ] + "px" :
  9699  					computed;
  9700  			}
  9701  		}
  9702  	);
  9703  } );
  9704  
  9705  
  9706  // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
  9707  jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
  9708  	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
  9709  		function( defaultExtra, funcName ) {
  9710  
  9711  		// Margin is only for outerHeight, outerWidth
  9712  		jQuery.fn[ funcName ] = function( margin, value ) {
  9713  			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
  9714  				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
  9715  
  9716  			return access( this, function( elem, type, value ) {
  9717  				var doc;
  9718  
  9719  				if ( jQuery.isWindow( elem ) ) {
  9720  
  9721  					// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
  9722  					// isn't a whole lot we can do. See pull request at this URL for discussion:
  9723  					// https://github.com/jquery/jquery/pull/764
  9724  					return elem.document.documentElement[ "client" + name ];
  9725  				}
  9726  
  9727  				// Get document width or height
  9728  				if ( elem.nodeType === 9 ) {
  9729  					doc = elem.documentElement;
  9730  
  9731  					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
  9732  					// whichever is greatest
  9733  					return Math.max(
  9734  						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
  9735  						elem.body[ "offset" + name ], doc[ "offset" + name ],
  9736  						doc[ "client" + name ]
  9737  					);
  9738  				}
  9739  
  9740  				return value === undefined ?
  9741  
  9742  					// Get width or height on the element, requesting but not forcing parseFloat
  9743  					jQuery.css( elem, type, extra ) :
  9744  
  9745  					// Set width or height on the element
  9746  					jQuery.style( elem, type, value, extra );
  9747  			}, type, chainable ? margin : undefined, chainable, null );
  9748  		};
  9749  	} );
  9750  } );
  9751  
  9752  
  9753  jQuery.fn.extend( {
  9754  
  9755  	bind: function( types, data, fn ) {
  9756  		return this.on( types, null, data, fn );
  9757  	},
  9758  	unbind: function( types, fn ) {
  9759  		return this.off( types, null, fn );
  9760  	},
  9761  
  9762  	delegate: function( selector, types, data, fn ) {
  9763  		return this.on( types, selector, data, fn );
  9764  	},
  9765  	undelegate: function( selector, types, fn ) {
  9766  
  9767  		// ( namespace ) or ( selector, types [, fn] )
  9768  		return arguments.length === 1 ?
  9769  			this.off( selector, "**" ) :
  9770  			this.off( types, selector || "**", fn );
  9771  	},
  9772  	size: function() {
  9773  		return this.length;
  9774  	}
  9775  } );
  9776  
  9777  jQuery.fn.andSelf = jQuery.fn.addBack;
  9778  
  9779  
  9780  
  9781  
  9782  // Register as a named AMD module, since jQuery can be concatenated with other
  9783  // files that may use define, but not via a proper concatenation script that
  9784  // understands anonymous AMD modules. A named AMD is safest and most robust
  9785  // way to register. Lowercase jquery is used because AMD module names are
  9786  // derived from file names, and jQuery is normally delivered in a lowercase
  9787  // file name. Do this after creating the global so that if an AMD module wants
  9788  // to call noConflict to hide this version of jQuery, it will work.
  9789  
  9790  // Note that for maximum portability, libraries that are not jQuery should
  9791  // declare themselves as anonymous modules, and avoid setting a global if an
  9792  // AMD loader is present. jQuery is a special case. For more information, see
  9793  // https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
  9794  
  9795  if ( typeof define === "function" && define.amd ) {
  9796  	define( "jquery", [], function() {
  9797  		return jQuery;
  9798  	} );
  9799  }
  9800  
  9801  
  9802  
  9803  var
  9804  
  9805  	// Map over jQuery in case of overwrite
  9806  	_jQuery = window.jQuery,
  9807  
  9808  	// Map over the $ in case of overwrite
  9809  	_$ = window.$;
  9810  
  9811  jQuery.noConflict = function( deep ) {
  9812  	if ( window.$ === jQuery ) {
  9813  		window.$ = _$;
  9814  	}
  9815  
  9816  	if ( deep && window.jQuery === jQuery ) {
  9817  		window.jQuery = _jQuery;
  9818  	}
  9819  
  9820  	return jQuery;
  9821  };
  9822  
  9823  // Expose jQuery and $ identifiers, even in AMD
  9824  // (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
  9825  // and CommonJS for browser emulators (#13566)
  9826  if ( !noGlobal ) {
  9827  	window.jQuery = window.$ = jQuery;
  9828  }
  9829  
  9830  return jQuery;
  9831  }));