tuiHoneyPot

front and back end of my TUI honeypot
Log | Files | Refs | README

selector.js (60394B)


      1 define( [
      2 	"./core",
      3 	"./core/nodeName",
      4 	"./var/arr",
      5 	"./var/document",
      6 	"./var/indexOf",
      7 	"./var/hasOwn",
      8 	"./var/pop",
      9 	"./var/push",
     10 	"./var/slice",
     11 	"./var/sort",
     12 	"./var/splice",
     13 	"./var/whitespace",
     14 	"./var/rtrimCSS",
     15 	"./var/support",
     16 
     17 	// The following utils are attached directly to the jQuery object.
     18 	"./selector/contains",
     19 	"./selector/escapeSelector"
     20 ], function( jQuery, nodeName, arr, document, indexOf, hasOwn, pop, push,
     21 	slice, sort, splice, whitespace, rtrimCSS, support ) {
     22 
     23 "use strict";
     24 
     25 var preferredDoc = document,
     26 	pushNative = push;
     27 
     28 ( function() {
     29 
     30 var i,
     31 	Expr,
     32 	outermostContext,
     33 	sortInput,
     34 	hasDuplicate,
     35 	push = pushNative,
     36 
     37 	// Local document vars
     38 	document,
     39 	documentElement,
     40 	documentIsHTML,
     41 	rbuggyQSA,
     42 	matches,
     43 
     44 	// Instance-specific data
     45 	expando = jQuery.expando,
     46 	dirruns = 0,
     47 	done = 0,
     48 	classCache = createCache(),
     49 	tokenCache = createCache(),
     50 	compilerCache = createCache(),
     51 	nonnativeSelectorCache = createCache(),
     52 	sortOrder = function( a, b ) {
     53 		if ( a === b ) {
     54 			hasDuplicate = true;
     55 		}
     56 		return 0;
     57 	},
     58 
     59 	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|" +
     60 		"loop|multiple|open|readonly|required|scoped",
     61 
     62 	// Regular expressions
     63 
     64 	// https://www.w3.org/TR/css-syntax-3/#ident-token-diagram
     65 	identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace +
     66 		"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",
     67 
     68 	// Attribute selectors: https://www.w3.org/TR/selectors/#attribute-selectors
     69 	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
     70 
     71 		// Operator (capture 2)
     72 		"*([*^$|!~]?=)" + whitespace +
     73 
     74 		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
     75 		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" +
     76 		whitespace + "*\\]",
     77 
     78 	pseudos = ":(" + identifier + ")(?:\\((" +
     79 
     80 		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
     81 		// 1. quoted (capture 3; capture 4 or capture 5)
     82 		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
     83 
     84 		// 2. simple (capture 6)
     85 		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
     86 
     87 		// 3. anything else (capture 2)
     88 		".*" +
     89 		")\\)|)",
     90 
     91 	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
     92 	rwhitespace = new RegExp( whitespace + "+", "g" ),
     93 
     94 	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
     95 	rleadingCombinator = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" +
     96 		whitespace + "*" ),
     97 	rdescend = new RegExp( whitespace + "|>" ),
     98 
     99 	rpseudo = new RegExp( pseudos ),
    100 	ridentifier = new RegExp( "^" + identifier + "$" ),
    101 
    102 	matchExpr = {
    103 		ID: new RegExp( "^#(" + identifier + ")" ),
    104 		CLASS: new RegExp( "^\\.(" + identifier + ")" ),
    105 		TAG: new RegExp( "^(" + identifier + "|[*])" ),
    106 		ATTR: new RegExp( "^" + attributes ),
    107 		PSEUDO: new RegExp( "^" + pseudos ),
    108 		CHILD: new RegExp(
    109 			"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" +
    110 				whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" +
    111 				whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
    112 		bool: new RegExp( "^(?:" + booleans + ")$", "i" ),
    113 
    114 		// For use in libraries implementing .is()
    115 		// We use this for POS matching in `select`
    116 		needsContext: new RegExp( "^" + whitespace +
    117 			"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
    118 			"*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
    119 	},
    120 
    121 	rinputs = /^(?:input|select|textarea|button)$/i,
    122 	rheader = /^h\d$/i,
    123 
    124 	// Easily-parseable/retrievable ID or TAG or CLASS selectors
    125 	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
    126 
    127 	rsibling = /[+~]/,
    128 
    129 	// CSS escapes
    130 	// https://www.w3.org/TR/CSS21/syndata.html#escaped-characters
    131 	runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace +
    132 		"?|\\\\([^\\r\\n\\f])", "g" ),
    133 	funescape = function( escape, nonHex ) {
    134 		var high = "0x" + escape.slice( 1 ) - 0x10000;
    135 
    136 		if ( nonHex ) {
    137 
    138 			// Strip the backslash prefix from a non-hex escape sequence
    139 			return nonHex;
    140 		}
    141 
    142 		// Replace a hexadecimal escape sequence with the encoded Unicode code point
    143 		// Support: IE <=11+
    144 		// For values outside the Basic Multilingual Plane (BMP), manually construct a
    145 		// surrogate pair
    146 		return high < 0 ?
    147 			String.fromCharCode( high + 0x10000 ) :
    148 			String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
    149 	},
    150 
    151 	// Used for iframes; see `setDocument`.
    152 	// Support: IE 9 - 11+, Edge 12 - 18+
    153 	// Removing the function wrapper causes a "Permission Denied"
    154 	// error in IE/Edge.
    155 	unloadHandler = function() {
    156 		setDocument();
    157 	},
    158 
    159 	inDisabledFieldset = addCombinator(
    160 		function( elem ) {
    161 			return elem.disabled === true && nodeName( elem, "fieldset" );
    162 		},
    163 		{ dir: "parentNode", next: "legend" }
    164 	);
    165 
    166 // Support: IE <=9 only
    167 // Accessing document.activeElement can throw unexpectedly
    168 // https://bugs.jquery.com/ticket/13393
    169 function safeActiveElement() {
    170 	try {
    171 		return document.activeElement;
    172 	} catch ( err ) { }
    173 }
    174 
    175 // Optimize for push.apply( _, NodeList )
    176 try {
    177 	push.apply(
    178 		( arr = slice.call( preferredDoc.childNodes ) ),
    179 		preferredDoc.childNodes
    180 	);
    181 
    182 	// Support: Android <=4.0
    183 	// Detect silently failing push.apply
    184 	// eslint-disable-next-line no-unused-expressions
    185 	arr[ preferredDoc.childNodes.length ].nodeType;
    186 } catch ( e ) {
    187 	push = {
    188 		apply: function( target, els ) {
    189 			pushNative.apply( target, slice.call( els ) );
    190 		},
    191 		call: function( target ) {
    192 			pushNative.apply( target, slice.call( arguments, 1 ) );
    193 		}
    194 	};
    195 }
    196 
    197 function find( selector, context, results, seed ) {
    198 	var m, i, elem, nid, match, groups, newSelector,
    199 		newContext = context && context.ownerDocument,
    200 
    201 		// nodeType defaults to 9, since context defaults to document
    202 		nodeType = context ? context.nodeType : 9;
    203 
    204 	results = results || [];
    205 
    206 	// Return early from calls with invalid selector or context
    207 	if ( typeof selector !== "string" || !selector ||
    208 		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
    209 
    210 		return results;
    211 	}
    212 
    213 	// Try to shortcut find operations (as opposed to filters) in HTML documents
    214 	if ( !seed ) {
    215 		setDocument( context );
    216 		context = context || document;
    217 
    218 		if ( documentIsHTML ) {
    219 
    220 			// If the selector is sufficiently simple, try using a "get*By*" DOM method
    221 			// (excepting DocumentFragment context, where the methods don't exist)
    222 			if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) {
    223 
    224 				// ID selector
    225 				if ( ( m = match[ 1 ] ) ) {
    226 
    227 					// Document context
    228 					if ( nodeType === 9 ) {
    229 						if ( ( elem = context.getElementById( m ) ) ) {
    230 
    231 							// Support: IE 9 only
    232 							// getElementById can match elements by name instead of ID
    233 							if ( elem.id === m ) {
    234 								push.call( results, elem );
    235 								return results;
    236 							}
    237 						} else {
    238 							return results;
    239 						}
    240 
    241 					// Element context
    242 					} else {
    243 
    244 						// Support: IE 9 only
    245 						// getElementById can match elements by name instead of ID
    246 						if ( newContext && ( elem = newContext.getElementById( m ) ) &&
    247 							find.contains( context, elem ) &&
    248 							elem.id === m ) {
    249 
    250 							push.call( results, elem );
    251 							return results;
    252 						}
    253 					}
    254 
    255 				// Type selector
    256 				} else if ( match[ 2 ] ) {
    257 					push.apply( results, context.getElementsByTagName( selector ) );
    258 					return results;
    259 
    260 				// Class selector
    261 				} else if ( ( m = match[ 3 ] ) && context.getElementsByClassName ) {
    262 					push.apply( results, context.getElementsByClassName( m ) );
    263 					return results;
    264 				}
    265 			}
    266 
    267 			// Take advantage of querySelectorAll
    268 			if ( !nonnativeSelectorCache[ selector + " " ] &&
    269 				( !rbuggyQSA || !rbuggyQSA.test( selector ) ) ) {
    270 
    271 				newSelector = selector;
    272 				newContext = context;
    273 
    274 				// qSA considers elements outside a scoping root when evaluating child or
    275 				// descendant combinators, which is not what we want.
    276 				// In such cases, we work around the behavior by prefixing every selector in the
    277 				// list with an ID selector referencing the scope context.
    278 				// The technique has to be used as well when a leading combinator is used
    279 				// as such selectors are not recognized by querySelectorAll.
    280 				// Thanks to Andrew Dupont for this technique.
    281 				if ( nodeType === 1 &&
    282 					( rdescend.test( selector ) || rleadingCombinator.test( selector ) ) ) {
    283 
    284 					// Expand context for sibling selectors
    285 					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
    286 						context;
    287 
    288 					// We can use :scope instead of the ID hack if the browser
    289 					// supports it & if we're not changing the context.
    290 					// Support: IE 11+, Edge 17 - 18+
    291 					// IE/Edge sometimes throw a "Permission denied" error when
    292 					// strict-comparing two documents; shallow comparisons work.
    293 					// eslint-disable-next-line eqeqeq
    294 					if ( newContext != context || !support.scope ) {
    295 
    296 						// Capture the context ID, setting it first if necessary
    297 						if ( ( nid = context.getAttribute( "id" ) ) ) {
    298 							nid = jQuery.escapeSelector( nid );
    299 						} else {
    300 							context.setAttribute( "id", ( nid = expando ) );
    301 						}
    302 					}
    303 
    304 					// Prefix every selector in the list
    305 					groups = tokenize( selector );
    306 					i = groups.length;
    307 					while ( i-- ) {
    308 						groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " +
    309 							toSelector( groups[ i ] );
    310 					}
    311 					newSelector = groups.join( "," );
    312 				}
    313 
    314 				try {
    315 					push.apply( results,
    316 						newContext.querySelectorAll( newSelector )
    317 					);
    318 					return results;
    319 				} catch ( qsaError ) {
    320 					nonnativeSelectorCache( selector, true );
    321 				} finally {
    322 					if ( nid === expando ) {
    323 						context.removeAttribute( "id" );
    324 					}
    325 				}
    326 			}
    327 		}
    328 	}
    329 
    330 	// All others
    331 	return select( selector.replace( rtrimCSS, "$1" ), context, results, seed );
    332 }
    333 
    334 /**
    335  * Create key-value caches of limited size
    336  * @returns {function(string, object)} Returns the Object data after storing it on itself with
    337  *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
    338  *	deleting the oldest entry
    339  */
    340 function createCache() {
    341 	var keys = [];
    342 
    343 	function cache( key, value ) {
    344 
    345 		// Use (key + " ") to avoid collision with native prototype properties
    346 		// (see https://github.com/jquery/sizzle/issues/157)
    347 		if ( keys.push( key + " " ) > Expr.cacheLength ) {
    348 
    349 			// Only keep the most recent entries
    350 			delete cache[ keys.shift() ];
    351 		}
    352 		return ( cache[ key + " " ] = value );
    353 	}
    354 	return cache;
    355 }
    356 
    357 /**
    358  * Mark a function for special use by jQuery selector module
    359  * @param {Function} fn The function to mark
    360  */
    361 function markFunction( fn ) {
    362 	fn[ expando ] = true;
    363 	return fn;
    364 }
    365 
    366 /**
    367  * Support testing using an element
    368  * @param {Function} fn Passed the created element and returns a boolean result
    369  */
    370 function assert( fn ) {
    371 	var el = document.createElement( "fieldset" );
    372 
    373 	try {
    374 		return !!fn( el );
    375 	} catch ( e ) {
    376 		return false;
    377 	} finally {
    378 
    379 		// Remove from its parent by default
    380 		if ( el.parentNode ) {
    381 			el.parentNode.removeChild( el );
    382 		}
    383 
    384 		// release memory in IE
    385 		el = null;
    386 	}
    387 }
    388 
    389 /**
    390  * Returns a function to use in pseudos for input types
    391  * @param {String} type
    392  */
    393 function createInputPseudo( type ) {
    394 	return function( elem ) {
    395 		return nodeName( elem, "input" ) && elem.type === type;
    396 	};
    397 }
    398 
    399 /**
    400  * Returns a function to use in pseudos for buttons
    401  * @param {String} type
    402  */
    403 function createButtonPseudo( type ) {
    404 	return function( elem ) {
    405 		return ( nodeName( elem, "input" ) || nodeName( elem, "button" ) ) &&
    406 			elem.type === type;
    407 	};
    408 }
    409 
    410 /**
    411  * Returns a function to use in pseudos for :enabled/:disabled
    412  * @param {Boolean} disabled true for :disabled; false for :enabled
    413  */
    414 function createDisabledPseudo( disabled ) {
    415 
    416 	// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
    417 	return function( elem ) {
    418 
    419 		// Only certain elements can match :enabled or :disabled
    420 		// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
    421 		// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
    422 		if ( "form" in elem ) {
    423 
    424 			// Check for inherited disabledness on relevant non-disabled elements:
    425 			// * listed form-associated elements in a disabled fieldset
    426 			//   https://html.spec.whatwg.org/multipage/forms.html#category-listed
    427 			//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
    428 			// * option elements in a disabled optgroup
    429 			//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
    430 			// All such elements have a "form" property.
    431 			if ( elem.parentNode && elem.disabled === false ) {
    432 
    433 				// Option elements defer to a parent optgroup if present
    434 				if ( "label" in elem ) {
    435 					if ( "label" in elem.parentNode ) {
    436 						return elem.parentNode.disabled === disabled;
    437 					} else {
    438 						return elem.disabled === disabled;
    439 					}
    440 				}
    441 
    442 				// Support: IE 6 - 11+
    443 				// Use the isDisabled shortcut property to check for disabled fieldset ancestors
    444 				return elem.isDisabled === disabled ||
    445 
    446 					// Where there is no isDisabled, check manually
    447 					elem.isDisabled !== !disabled &&
    448 						inDisabledFieldset( elem ) === disabled;
    449 			}
    450 
    451 			return elem.disabled === disabled;
    452 
    453 		// Try to winnow out elements that can't be disabled before trusting the disabled property.
    454 		// Some victims get caught in our net (label, legend, menu, track), but it shouldn't
    455 		// even exist on them, let alone have a boolean value.
    456 		} else if ( "label" in elem ) {
    457 			return elem.disabled === disabled;
    458 		}
    459 
    460 		// Remaining elements are neither :enabled nor :disabled
    461 		return false;
    462 	};
    463 }
    464 
    465 /**
    466  * Returns a function to use in pseudos for positionals
    467  * @param {Function} fn
    468  */
    469 function createPositionalPseudo( fn ) {
    470 	return markFunction( function( argument ) {
    471 		argument = +argument;
    472 		return markFunction( function( seed, matches ) {
    473 			var j,
    474 				matchIndexes = fn( [], seed.length, argument ),
    475 				i = matchIndexes.length;
    476 
    477 			// Match elements found at the specified indexes
    478 			while ( i-- ) {
    479 				if ( seed[ ( j = matchIndexes[ i ] ) ] ) {
    480 					seed[ j ] = !( matches[ j ] = seed[ j ] );
    481 				}
    482 			}
    483 		} );
    484 	} );
    485 }
    486 
    487 /**
    488  * Checks a node for validity as a jQuery selector context
    489  * @param {Element|Object=} context
    490  * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
    491  */
    492 function testContext( context ) {
    493 	return context && typeof context.getElementsByTagName !== "undefined" && context;
    494 }
    495 
    496 /**
    497  * Sets document-related variables once based on the current document
    498  * @param {Element|Object} [node] An element or document object to use to set the document
    499  * @returns {Object} Returns the current document
    500  */
    501 function setDocument( node ) {
    502 	var subWindow,
    503 		doc = node ? node.ownerDocument || node : preferredDoc;
    504 
    505 	// Return early if doc is invalid or already selected
    506 	// Support: IE 11+, Edge 17 - 18+
    507 	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
    508 	// two documents; shallow comparisons work.
    509 	// eslint-disable-next-line eqeqeq
    510 	if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) {
    511 		return document;
    512 	}
    513 
    514 	// Update global variables
    515 	document = doc;
    516 	documentElement = document.documentElement;
    517 	documentIsHTML = !jQuery.isXMLDoc( document );
    518 
    519 	// Support: iOS 7 only, IE 9 - 11+
    520 	// Older browsers didn't support unprefixed `matches`.
    521 	matches = documentElement.matches ||
    522 		documentElement.webkitMatchesSelector ||
    523 		documentElement.msMatchesSelector;
    524 
    525 	// Support: IE 9 - 11+, Edge 12 - 18+
    526 	// Accessing iframe documents after unload throws "permission denied" errors
    527 	// (see trac-13936).
    528 	// Limit the fix to IE & Edge Legacy; despite Edge 15+ implementing `matches`,
    529 	// all IE 9+ and Edge Legacy versions implement `msMatchesSelector` as well.
    530 	if ( documentElement.msMatchesSelector &&
    531 
    532 		// Support: IE 11+, Edge 17 - 18+
    533 		// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
    534 		// two documents; shallow comparisons work.
    535 		// eslint-disable-next-line eqeqeq
    536 		preferredDoc != document &&
    537 		( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {
    538 
    539 		// Support: IE 9 - 11+, Edge 12 - 18+
    540 		subWindow.addEventListener( "unload", unloadHandler );
    541 	}
    542 
    543 	// Support: IE <10
    544 	// Check if getElementById returns elements by name
    545 	// The broken getElementById methods don't pick up programmatically-set names,
    546 	// so use a roundabout getElementsByName test
    547 	support.getById = assert( function( el ) {
    548 		documentElement.appendChild( el ).id = jQuery.expando;
    549 		return !document.getElementsByName ||
    550 			!document.getElementsByName( jQuery.expando ).length;
    551 	} );
    552 
    553 	// Support: IE 9 only
    554 	// Check to see if it's possible to do matchesSelector
    555 	// on a disconnected node.
    556 	support.disconnectedMatch = assert( function( el ) {
    557 		return matches.call( el, "*" );
    558 	} );
    559 
    560 	// Support: IE 9 - 11+, Edge 12 - 18+
    561 	// IE/Edge don't support the :scope pseudo-class.
    562 	support.scope = assert( function() {
    563 		return document.querySelectorAll( ":scope" );
    564 	} );
    565 
    566 	// Support: Chrome 105 - 111 only, Safari 15.4 - 16.3 only
    567 	// Make sure the `:has()` argument is parsed unforgivingly.
    568 	// We include `*` in the test to detect buggy implementations that are
    569 	// _selectively_ forgiving (specifically when the list includes at least
    570 	// one valid selector).
    571 	// Note that we treat complete lack of support for `:has()` as if it were
    572 	// spec-compliant support, which is fine because use of `:has()` in such
    573 	// environments will fail in the qSA path and fall back to jQuery traversal
    574 	// anyway.
    575 	support.cssHas = assert( function() {
    576 		try {
    577 			document.querySelector( ":has(*,:jqfake)" );
    578 			return false;
    579 		} catch ( e ) {
    580 			return true;
    581 		}
    582 	} );
    583 
    584 	// ID filter and find
    585 	if ( support.getById ) {
    586 		Expr.filter.ID = function( id ) {
    587 			var attrId = id.replace( runescape, funescape );
    588 			return function( elem ) {
    589 				return elem.getAttribute( "id" ) === attrId;
    590 			};
    591 		};
    592 		Expr.find.ID = function( id, context ) {
    593 			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
    594 				var elem = context.getElementById( id );
    595 				return elem ? [ elem ] : [];
    596 			}
    597 		};
    598 	} else {
    599 		Expr.filter.ID =  function( id ) {
    600 			var attrId = id.replace( runescape, funescape );
    601 			return function( elem ) {
    602 				var node = typeof elem.getAttributeNode !== "undefined" &&
    603 					elem.getAttributeNode( "id" );
    604 				return node && node.value === attrId;
    605 			};
    606 		};
    607 
    608 		// Support: IE 6 - 7 only
    609 		// getElementById is not reliable as a find shortcut
    610 		Expr.find.ID = function( id, context ) {
    611 			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
    612 				var node, i, elems,
    613 					elem = context.getElementById( id );
    614 
    615 				if ( elem ) {
    616 
    617 					// Verify the id attribute
    618 					node = elem.getAttributeNode( "id" );
    619 					if ( node && node.value === id ) {
    620 						return [ elem ];
    621 					}
    622 
    623 					// Fall back on getElementsByName
    624 					elems = context.getElementsByName( id );
    625 					i = 0;
    626 					while ( ( elem = elems[ i++ ] ) ) {
    627 						node = elem.getAttributeNode( "id" );
    628 						if ( node && node.value === id ) {
    629 							return [ elem ];
    630 						}
    631 					}
    632 				}
    633 
    634 				return [];
    635 			}
    636 		};
    637 	}
    638 
    639 	// Tag
    640 	Expr.find.TAG = function( tag, context ) {
    641 		if ( typeof context.getElementsByTagName !== "undefined" ) {
    642 			return context.getElementsByTagName( tag );
    643 
    644 		// DocumentFragment nodes don't have gEBTN
    645 		} else {
    646 			return context.querySelectorAll( tag );
    647 		}
    648 	};
    649 
    650 	// Class
    651 	Expr.find.CLASS = function( className, context ) {
    652 		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
    653 			return context.getElementsByClassName( className );
    654 		}
    655 	};
    656 
    657 	/* QSA/matchesSelector
    658 	---------------------------------------------------------------------- */
    659 
    660 	// QSA and matchesSelector support
    661 
    662 	rbuggyQSA = [];
    663 
    664 	// Build QSA regex
    665 	// Regex strategy adopted from Diego Perini
    666 	assert( function( el ) {
    667 
    668 		var input;
    669 
    670 		documentElement.appendChild( el ).innerHTML =
    671 			"<a id='" + expando + "' href='' disabled='disabled'></a>" +
    672 			"<select id='" + expando + "-\r\\' disabled='disabled'>" +
    673 			"<option selected=''></option></select>";
    674 
    675 		// Support: iOS <=7 - 8 only
    676 		// Boolean attributes and "value" are not treated correctly in some XML documents
    677 		if ( !el.querySelectorAll( "[selected]" ).length ) {
    678 			rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
    679 		}
    680 
    681 		// Support: iOS <=7 - 8 only
    682 		if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
    683 			rbuggyQSA.push( "~=" );
    684 		}
    685 
    686 		// Support: iOS 8 only
    687 		// https://bugs.webkit.org/show_bug.cgi?id=136851
    688 		// In-page `selector#id sibling-combinator selector` fails
    689 		if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
    690 			rbuggyQSA.push( ".#.+[+~]" );
    691 		}
    692 
    693 		// Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+
    694 		// In some of the document kinds, these selectors wouldn't work natively.
    695 		// This is probably OK but for backwards compatibility we want to maintain
    696 		// handling them through jQuery traversal in jQuery 3.x.
    697 		if ( !el.querySelectorAll( ":checked" ).length ) {
    698 			rbuggyQSA.push( ":checked" );
    699 		}
    700 
    701 		// Support: Windows 8 Native Apps
    702 		// The type and name attributes are restricted during .innerHTML assignment
    703 		input = document.createElement( "input" );
    704 		input.setAttribute( "type", "hidden" );
    705 		el.appendChild( input ).setAttribute( "name", "D" );
    706 
    707 		// Support: IE 9 - 11+
    708 		// IE's :disabled selector does not pick up the children of disabled fieldsets
    709 		// Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+
    710 		// In some of the document kinds, these selectors wouldn't work natively.
    711 		// This is probably OK but for backwards compatibility we want to maintain
    712 		// handling them through jQuery traversal in jQuery 3.x.
    713 		documentElement.appendChild( el ).disabled = true;
    714 		if ( el.querySelectorAll( ":disabled" ).length !== 2 ) {
    715 			rbuggyQSA.push( ":enabled", ":disabled" );
    716 		}
    717 
    718 		// Support: IE 11+, Edge 15 - 18+
    719 		// IE 11/Edge don't find elements on a `[name='']` query in some cases.
    720 		// Adding a temporary attribute to the document before the selection works
    721 		// around the issue.
    722 		// Interestingly, IE 10 & older don't seem to have the issue.
    723 		input = document.createElement( "input" );
    724 		input.setAttribute( "name", "" );
    725 		el.appendChild( input );
    726 		if ( !el.querySelectorAll( "[name='']" ).length ) {
    727 			rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" +
    728 				whitespace + "*(?:''|\"\")" );
    729 		}
    730 	} );
    731 
    732 	if ( !support.cssHas ) {
    733 
    734 		// Support: Chrome 105 - 110+, Safari 15.4 - 16.3+
    735 		// Our regular `try-catch` mechanism fails to detect natively-unsupported
    736 		// pseudo-classes inside `:has()` (such as `:has(:contains("Foo"))`)
    737 		// in browsers that parse the `:has()` argument as a forgiving selector list.
    738 		// https://drafts.csswg.org/selectors/#relational now requires the argument
    739 		// to be parsed unforgivingly, but browsers have not yet fully adjusted.
    740 		rbuggyQSA.push( ":has" );
    741 	}
    742 
    743 	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) );
    744 
    745 	/* Sorting
    746 	---------------------------------------------------------------------- */
    747 
    748 	// Document order sorting
    749 	sortOrder = function( a, b ) {
    750 
    751 		// Flag for duplicate removal
    752 		if ( a === b ) {
    753 			hasDuplicate = true;
    754 			return 0;
    755 		}
    756 
    757 		// Sort on method existence if only one input has compareDocumentPosition
    758 		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
    759 		if ( compare ) {
    760 			return compare;
    761 		}
    762 
    763 		// Calculate position if both inputs belong to the same document
    764 		// Support: IE 11+, Edge 17 - 18+
    765 		// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
    766 		// two documents; shallow comparisons work.
    767 		// eslint-disable-next-line eqeqeq
    768 		compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?
    769 			a.compareDocumentPosition( b ) :
    770 
    771 			// Otherwise we know they are disconnected
    772 			1;
    773 
    774 		// Disconnected nodes
    775 		if ( compare & 1 ||
    776 			( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) {
    777 
    778 			// Choose the first element that is related to our preferred document
    779 			// Support: IE 11+, Edge 17 - 18+
    780 			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
    781 			// two documents; shallow comparisons work.
    782 			// eslint-disable-next-line eqeqeq
    783 			if ( a === document || a.ownerDocument == preferredDoc &&
    784 				find.contains( preferredDoc, a ) ) {
    785 				return -1;
    786 			}
    787 
    788 			// Support: IE 11+, Edge 17 - 18+
    789 			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
    790 			// two documents; shallow comparisons work.
    791 			// eslint-disable-next-line eqeqeq
    792 			if ( b === document || b.ownerDocument == preferredDoc &&
    793 				find.contains( preferredDoc, b ) ) {
    794 				return 1;
    795 			}
    796 
    797 			// Maintain original order
    798 			return sortInput ?
    799 				( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
    800 				0;
    801 		}
    802 
    803 		return compare & 4 ? -1 : 1;
    804 	};
    805 
    806 	return document;
    807 }
    808 
    809 find.matches = function( expr, elements ) {
    810 	return find( expr, null, null, elements );
    811 };
    812 
    813 find.matchesSelector = function( elem, expr ) {
    814 	setDocument( elem );
    815 
    816 	if ( documentIsHTML &&
    817 		!nonnativeSelectorCache[ expr + " " ] &&
    818 		( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
    819 
    820 		try {
    821 			var ret = matches.call( elem, expr );
    822 
    823 			// IE 9's matchesSelector returns false on disconnected nodes
    824 			if ( ret || support.disconnectedMatch ||
    825 
    826 					// As well, disconnected nodes are said to be in a document
    827 					// fragment in IE 9
    828 					elem.document && elem.document.nodeType !== 11 ) {
    829 				return ret;
    830 			}
    831 		} catch ( e ) {
    832 			nonnativeSelectorCache( expr, true );
    833 		}
    834 	}
    835 
    836 	return find( expr, document, null, [ elem ] ).length > 0;
    837 };
    838 
    839 find.contains = function( context, elem ) {
    840 
    841 	// Set document vars if needed
    842 	// Support: IE 11+, Edge 17 - 18+
    843 	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
    844 	// two documents; shallow comparisons work.
    845 	// eslint-disable-next-line eqeqeq
    846 	if ( ( context.ownerDocument || context ) != document ) {
    847 		setDocument( context );
    848 	}
    849 	return jQuery.contains( context, elem );
    850 };
    851 
    852 
    853 find.attr = function( elem, name ) {
    854 
    855 	// Set document vars if needed
    856 	// Support: IE 11+, Edge 17 - 18+
    857 	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
    858 	// two documents; shallow comparisons work.
    859 	// eslint-disable-next-line eqeqeq
    860 	if ( ( elem.ownerDocument || elem ) != document ) {
    861 		setDocument( elem );
    862 	}
    863 
    864 	var fn = Expr.attrHandle[ name.toLowerCase() ],
    865 
    866 		// Don't get fooled by Object.prototype properties (see trac-13807)
    867 		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
    868 			fn( elem, name, !documentIsHTML ) :
    869 			undefined;
    870 
    871 	if ( val !== undefined ) {
    872 		return val;
    873 	}
    874 
    875 	return elem.getAttribute( name );
    876 };
    877 
    878 find.error = function( msg ) {
    879 	throw new Error( "Syntax error, unrecognized expression: " + msg );
    880 };
    881 
    882 /**
    883  * Document sorting and removing duplicates
    884  * @param {ArrayLike} results
    885  */
    886 jQuery.uniqueSort = function( results ) {
    887 	var elem,
    888 		duplicates = [],
    889 		j = 0,
    890 		i = 0;
    891 
    892 	// Unless we *know* we can detect duplicates, assume their presence
    893 	//
    894 	// Support: Android <=4.0+
    895 	// Testing for detecting duplicates is unpredictable so instead assume we can't
    896 	// depend on duplicate detection in all browsers without a stable sort.
    897 	hasDuplicate = !support.sortStable;
    898 	sortInput = !support.sortStable && slice.call( results, 0 );
    899 	sort.call( results, sortOrder );
    900 
    901 	if ( hasDuplicate ) {
    902 		while ( ( elem = results[ i++ ] ) ) {
    903 			if ( elem === results[ i ] ) {
    904 				j = duplicates.push( i );
    905 			}
    906 		}
    907 		while ( j-- ) {
    908 			splice.call( results, duplicates[ j ], 1 );
    909 		}
    910 	}
    911 
    912 	// Clear input after sorting to release objects
    913 	// See https://github.com/jquery/sizzle/pull/225
    914 	sortInput = null;
    915 
    916 	return results;
    917 };
    918 
    919 jQuery.fn.uniqueSort = function() {
    920 	return this.pushStack( jQuery.uniqueSort( slice.apply( this ) ) );
    921 };
    922 
    923 Expr = jQuery.expr = {
    924 
    925 	// Can be adjusted by the user
    926 	cacheLength: 50,
    927 
    928 	createPseudo: markFunction,
    929 
    930 	match: matchExpr,
    931 
    932 	attrHandle: {},
    933 
    934 	find: {},
    935 
    936 	relative: {
    937 		">": { dir: "parentNode", first: true },
    938 		" ": { dir: "parentNode" },
    939 		"+": { dir: "previousSibling", first: true },
    940 		"~": { dir: "previousSibling" }
    941 	},
    942 
    943 	preFilter: {
    944 		ATTR: function( match ) {
    945 			match[ 1 ] = match[ 1 ].replace( runescape, funescape );
    946 
    947 			// Move the given value to match[3] whether quoted or unquoted
    948 			match[ 3 ] = ( match[ 3 ] || match[ 4 ] || match[ 5 ] || "" )
    949 				.replace( runescape, funescape );
    950 
    951 			if ( match[ 2 ] === "~=" ) {
    952 				match[ 3 ] = " " + match[ 3 ] + " ";
    953 			}
    954 
    955 			return match.slice( 0, 4 );
    956 		},
    957 
    958 		CHILD: function( match ) {
    959 
    960 			/* matches from matchExpr["CHILD"]
    961 				1 type (only|nth|...)
    962 				2 what (child|of-type)
    963 				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
    964 				4 xn-component of xn+y argument ([+-]?\d*n|)
    965 				5 sign of xn-component
    966 				6 x of xn-component
    967 				7 sign of y-component
    968 				8 y of y-component
    969 			*/
    970 			match[ 1 ] = match[ 1 ].toLowerCase();
    971 
    972 			if ( match[ 1 ].slice( 0, 3 ) === "nth" ) {
    973 
    974 				// nth-* requires argument
    975 				if ( !match[ 3 ] ) {
    976 					find.error( match[ 0 ] );
    977 				}
    978 
    979 				// numeric x and y parameters for Expr.filter.CHILD
    980 				// remember that false/true cast respectively to 0/1
    981 				match[ 4 ] = +( match[ 4 ] ?
    982 					match[ 5 ] + ( match[ 6 ] || 1 ) :
    983 					2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" )
    984 				);
    985 				match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" );
    986 
    987 			// other types prohibit arguments
    988 			} else if ( match[ 3 ] ) {
    989 				find.error( match[ 0 ] );
    990 			}
    991 
    992 			return match;
    993 		},
    994 
    995 		PSEUDO: function( match ) {
    996 			var excess,
    997 				unquoted = !match[ 6 ] && match[ 2 ];
    998 
    999 			if ( matchExpr.CHILD.test( match[ 0 ] ) ) {
   1000 				return null;
   1001 			}
   1002 
   1003 			// Accept quoted arguments as-is
   1004 			if ( match[ 3 ] ) {
   1005 				match[ 2 ] = match[ 4 ] || match[ 5 ] || "";
   1006 
   1007 			// Strip excess characters from unquoted arguments
   1008 			} else if ( unquoted && rpseudo.test( unquoted ) &&
   1009 
   1010 				// Get excess from tokenize (recursively)
   1011 				( excess = tokenize( unquoted, true ) ) &&
   1012 
   1013 				// advance to the next closing parenthesis
   1014 				( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) {
   1015 
   1016 				// excess is a negative index
   1017 				match[ 0 ] = match[ 0 ].slice( 0, excess );
   1018 				match[ 2 ] = unquoted.slice( 0, excess );
   1019 			}
   1020 
   1021 			// Return only captures needed by the pseudo filter method (type and argument)
   1022 			return match.slice( 0, 3 );
   1023 		}
   1024 	},
   1025 
   1026 	filter: {
   1027 
   1028 		TAG: function( nodeNameSelector ) {
   1029 			var expectedNodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
   1030 			return nodeNameSelector === "*" ?
   1031 				function() {
   1032 					return true;
   1033 				} :
   1034 				function( elem ) {
   1035 					return nodeName( elem, expectedNodeName );
   1036 				};
   1037 		},
   1038 
   1039 		CLASS: function( className ) {
   1040 			var pattern = classCache[ className + " " ];
   1041 
   1042 			return pattern ||
   1043 				( pattern = new RegExp( "(^|" + whitespace + ")" + className +
   1044 					"(" + whitespace + "|$)" ) ) &&
   1045 				classCache( className, function( elem ) {
   1046 					return pattern.test(
   1047 						typeof elem.className === "string" && elem.className ||
   1048 							typeof elem.getAttribute !== "undefined" &&
   1049 								elem.getAttribute( "class" ) ||
   1050 							""
   1051 					);
   1052 				} );
   1053 		},
   1054 
   1055 		ATTR: function( name, operator, check ) {
   1056 			return function( elem ) {
   1057 				var result = find.attr( elem, name );
   1058 
   1059 				if ( result == null ) {
   1060 					return operator === "!=";
   1061 				}
   1062 				if ( !operator ) {
   1063 					return true;
   1064 				}
   1065 
   1066 				result += "";
   1067 
   1068 				if ( operator === "=" ) {
   1069 					return result === check;
   1070 				}
   1071 				if ( operator === "!=" ) {
   1072 					return result !== check;
   1073 				}
   1074 				if ( operator === "^=" ) {
   1075 					return check && result.indexOf( check ) === 0;
   1076 				}
   1077 				if ( operator === "*=" ) {
   1078 					return check && result.indexOf( check ) > -1;
   1079 				}
   1080 				if ( operator === "$=" ) {
   1081 					return check && result.slice( -check.length ) === check;
   1082 				}
   1083 				if ( operator === "~=" ) {
   1084 					return ( " " + result.replace( rwhitespace, " " ) + " " )
   1085 						.indexOf( check ) > -1;
   1086 				}
   1087 				if ( operator === "|=" ) {
   1088 					return result === check || result.slice( 0, check.length + 1 ) === check + "-";
   1089 				}
   1090 
   1091 				return false;
   1092 			};
   1093 		},
   1094 
   1095 		CHILD: function( type, what, _argument, first, last ) {
   1096 			var simple = type.slice( 0, 3 ) !== "nth",
   1097 				forward = type.slice( -4 ) !== "last",
   1098 				ofType = what === "of-type";
   1099 
   1100 			return first === 1 && last === 0 ?
   1101 
   1102 				// Shortcut for :nth-*(n)
   1103 				function( elem ) {
   1104 					return !!elem.parentNode;
   1105 				} :
   1106 
   1107 				function( elem, _context, xml ) {
   1108 					var cache, outerCache, node, nodeIndex, start,
   1109 						dir = simple !== forward ? "nextSibling" : "previousSibling",
   1110 						parent = elem.parentNode,
   1111 						name = ofType && elem.nodeName.toLowerCase(),
   1112 						useCache = !xml && !ofType,
   1113 						diff = false;
   1114 
   1115 					if ( parent ) {
   1116 
   1117 						// :(first|last|only)-(child|of-type)
   1118 						if ( simple ) {
   1119 							while ( dir ) {
   1120 								node = elem;
   1121 								while ( ( node = node[ dir ] ) ) {
   1122 									if ( ofType ?
   1123 										nodeName( node, name ) :
   1124 										node.nodeType === 1 ) {
   1125 
   1126 										return false;
   1127 									}
   1128 								}
   1129 
   1130 								// Reverse direction for :only-* (if we haven't yet done so)
   1131 								start = dir = type === "only" && !start && "nextSibling";
   1132 							}
   1133 							return true;
   1134 						}
   1135 
   1136 						start = [ forward ? parent.firstChild : parent.lastChild ];
   1137 
   1138 						// non-xml :nth-child(...) stores cache data on `parent`
   1139 						if ( forward && useCache ) {
   1140 
   1141 							// Seek `elem` from a previously-cached index
   1142 							outerCache = parent[ expando ] || ( parent[ expando ] = {} );
   1143 							cache = outerCache[ type ] || [];
   1144 							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
   1145 							diff = nodeIndex && cache[ 2 ];
   1146 							node = nodeIndex && parent.childNodes[ nodeIndex ];
   1147 
   1148 							while ( ( node = ++nodeIndex && node && node[ dir ] ||
   1149 
   1150 								// Fallback to seeking `elem` from the start
   1151 								( diff = nodeIndex = 0 ) || start.pop() ) ) {
   1152 
   1153 								// When found, cache indexes on `parent` and break
   1154 								if ( node.nodeType === 1 && ++diff && node === elem ) {
   1155 									outerCache[ type ] = [ dirruns, nodeIndex, diff ];
   1156 									break;
   1157 								}
   1158 							}
   1159 
   1160 						} else {
   1161 
   1162 							// Use previously-cached element index if available
   1163 							if ( useCache ) {
   1164 								outerCache = elem[ expando ] || ( elem[ expando ] = {} );
   1165 								cache = outerCache[ type ] || [];
   1166 								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
   1167 								diff = nodeIndex;
   1168 							}
   1169 
   1170 							// xml :nth-child(...)
   1171 							// or :nth-last-child(...) or :nth(-last)?-of-type(...)
   1172 							if ( diff === false ) {
   1173 
   1174 								// Use the same loop as above to seek `elem` from the start
   1175 								while ( ( node = ++nodeIndex && node && node[ dir ] ||
   1176 									( diff = nodeIndex = 0 ) || start.pop() ) ) {
   1177 
   1178 									if ( ( ofType ?
   1179 										nodeName( node, name ) :
   1180 										node.nodeType === 1 ) &&
   1181 										++diff ) {
   1182 
   1183 										// Cache the index of each encountered element
   1184 										if ( useCache ) {
   1185 											outerCache = node[ expando ] ||
   1186 												( node[ expando ] = {} );
   1187 											outerCache[ type ] = [ dirruns, diff ];
   1188 										}
   1189 
   1190 										if ( node === elem ) {
   1191 											break;
   1192 										}
   1193 									}
   1194 								}
   1195 							}
   1196 						}
   1197 
   1198 						// Incorporate the offset, then check against cycle size
   1199 						diff -= last;
   1200 						return diff === first || ( diff % first === 0 && diff / first >= 0 );
   1201 					}
   1202 				};
   1203 		},
   1204 
   1205 		PSEUDO: function( pseudo, argument ) {
   1206 
   1207 			// pseudo-class names are case-insensitive
   1208 			// https://www.w3.org/TR/selectors/#pseudo-classes
   1209 			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
   1210 			// Remember that setFilters inherits from pseudos
   1211 			var args,
   1212 				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
   1213 					find.error( "unsupported pseudo: " + pseudo );
   1214 
   1215 			// The user may use createPseudo to indicate that
   1216 			// arguments are needed to create the filter function
   1217 			// just as jQuery does
   1218 			if ( fn[ expando ] ) {
   1219 				return fn( argument );
   1220 			}
   1221 
   1222 			// But maintain support for old signatures
   1223 			if ( fn.length > 1 ) {
   1224 				args = [ pseudo, pseudo, "", argument ];
   1225 				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
   1226 					markFunction( function( seed, matches ) {
   1227 						var idx,
   1228 							matched = fn( seed, argument ),
   1229 							i = matched.length;
   1230 						while ( i-- ) {
   1231 							idx = indexOf.call( seed, matched[ i ] );
   1232 							seed[ idx ] = !( matches[ idx ] = matched[ i ] );
   1233 						}
   1234 					} ) :
   1235 					function( elem ) {
   1236 						return fn( elem, 0, args );
   1237 					};
   1238 			}
   1239 
   1240 			return fn;
   1241 		}
   1242 	},
   1243 
   1244 	pseudos: {
   1245 
   1246 		// Potentially complex pseudos
   1247 		not: markFunction( function( selector ) {
   1248 
   1249 			// Trim the selector passed to compile
   1250 			// to avoid treating leading and trailing
   1251 			// spaces as combinators
   1252 			var input = [],
   1253 				results = [],
   1254 				matcher = compile( selector.replace( rtrimCSS, "$1" ) );
   1255 
   1256 			return matcher[ expando ] ?
   1257 				markFunction( function( seed, matches, _context, xml ) {
   1258 					var elem,
   1259 						unmatched = matcher( seed, null, xml, [] ),
   1260 						i = seed.length;
   1261 
   1262 					// Match elements unmatched by `matcher`
   1263 					while ( i-- ) {
   1264 						if ( ( elem = unmatched[ i ] ) ) {
   1265 							seed[ i ] = !( matches[ i ] = elem );
   1266 						}
   1267 					}
   1268 				} ) :
   1269 				function( elem, _context, xml ) {
   1270 					input[ 0 ] = elem;
   1271 					matcher( input, null, xml, results );
   1272 
   1273 					// Don't keep the element
   1274 					// (see https://github.com/jquery/sizzle/issues/299)
   1275 					input[ 0 ] = null;
   1276 					return !results.pop();
   1277 				};
   1278 		} ),
   1279 
   1280 		has: markFunction( function( selector ) {
   1281 			return function( elem ) {
   1282 				return find( selector, elem ).length > 0;
   1283 			};
   1284 		} ),
   1285 
   1286 		contains: markFunction( function( text ) {
   1287 			text = text.replace( runescape, funescape );
   1288 			return function( elem ) {
   1289 				return ( elem.textContent || jQuery.text( elem ) ).indexOf( text ) > -1;
   1290 			};
   1291 		} ),
   1292 
   1293 		// "Whether an element is represented by a :lang() selector
   1294 		// is based solely on the element's language value
   1295 		// being equal to the identifier C,
   1296 		// or beginning with the identifier C immediately followed by "-".
   1297 		// The matching of C against the element's language value is performed case-insensitively.
   1298 		// The identifier C does not have to be a valid language name."
   1299 		// https://www.w3.org/TR/selectors/#lang-pseudo
   1300 		lang: markFunction( function( lang ) {
   1301 
   1302 			// lang value must be a valid identifier
   1303 			if ( !ridentifier.test( lang || "" ) ) {
   1304 				find.error( "unsupported lang: " + lang );
   1305 			}
   1306 			lang = lang.replace( runescape, funescape ).toLowerCase();
   1307 			return function( elem ) {
   1308 				var elemLang;
   1309 				do {
   1310 					if ( ( elemLang = documentIsHTML ?
   1311 						elem.lang :
   1312 						elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) {
   1313 
   1314 						elemLang = elemLang.toLowerCase();
   1315 						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
   1316 					}
   1317 				} while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );
   1318 				return false;
   1319 			};
   1320 		} ),
   1321 
   1322 		// Miscellaneous
   1323 		target: function( elem ) {
   1324 			var hash = window.location && window.location.hash;
   1325 			return hash && hash.slice( 1 ) === elem.id;
   1326 		},
   1327 
   1328 		root: function( elem ) {
   1329 			return elem === documentElement;
   1330 		},
   1331 
   1332 		focus: function( elem ) {
   1333 			return elem === safeActiveElement() &&
   1334 				document.hasFocus() &&
   1335 				!!( elem.type || elem.href || ~elem.tabIndex );
   1336 		},
   1337 
   1338 		// Boolean properties
   1339 		enabled: createDisabledPseudo( false ),
   1340 		disabled: createDisabledPseudo( true ),
   1341 
   1342 		checked: function( elem ) {
   1343 
   1344 			// In CSS3, :checked should return both checked and selected elements
   1345 			// https://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
   1346 			return ( nodeName( elem, "input" ) && !!elem.checked ) ||
   1347 				( nodeName( elem, "option" ) && !!elem.selected );
   1348 		},
   1349 
   1350 		selected: function( elem ) {
   1351 
   1352 			// Support: IE <=11+
   1353 			// Accessing the selectedIndex property
   1354 			// forces the browser to treat the default option as
   1355 			// selected when in an optgroup.
   1356 			if ( elem.parentNode ) {
   1357 				// eslint-disable-next-line no-unused-expressions
   1358 				elem.parentNode.selectedIndex;
   1359 			}
   1360 
   1361 			return elem.selected === true;
   1362 		},
   1363 
   1364 		// Contents
   1365 		empty: function( elem ) {
   1366 
   1367 			// https://www.w3.org/TR/selectors/#empty-pseudo
   1368 			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
   1369 			//   but not by others (comment: 8; processing instruction: 7; etc.)
   1370 			// nodeType < 6 works because attributes (2) do not appear as children
   1371 			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
   1372 				if ( elem.nodeType < 6 ) {
   1373 					return false;
   1374 				}
   1375 			}
   1376 			return true;
   1377 		},
   1378 
   1379 		parent: function( elem ) {
   1380 			return !Expr.pseudos.empty( elem );
   1381 		},
   1382 
   1383 		// Element/input types
   1384 		header: function( elem ) {
   1385 			return rheader.test( elem.nodeName );
   1386 		},
   1387 
   1388 		input: function( elem ) {
   1389 			return rinputs.test( elem.nodeName );
   1390 		},
   1391 
   1392 		button: function( elem ) {
   1393 			return nodeName( elem, "input" ) && elem.type === "button" ||
   1394 				nodeName( elem, "button" );
   1395 		},
   1396 
   1397 		text: function( elem ) {
   1398 			var attr;
   1399 			return nodeName( elem, "input" ) && elem.type === "text" &&
   1400 
   1401 				// Support: IE <10 only
   1402 				// New HTML5 attribute values (e.g., "search") appear
   1403 				// with elem.type === "text"
   1404 				( ( attr = elem.getAttribute( "type" ) ) == null ||
   1405 					attr.toLowerCase() === "text" );
   1406 		},
   1407 
   1408 		// Position-in-collection
   1409 		first: createPositionalPseudo( function() {
   1410 			return [ 0 ];
   1411 		} ),
   1412 
   1413 		last: createPositionalPseudo( function( _matchIndexes, length ) {
   1414 			return [ length - 1 ];
   1415 		} ),
   1416 
   1417 		eq: createPositionalPseudo( function( _matchIndexes, length, argument ) {
   1418 			return [ argument < 0 ? argument + length : argument ];
   1419 		} ),
   1420 
   1421 		even: createPositionalPseudo( function( matchIndexes, length ) {
   1422 			var i = 0;
   1423 			for ( ; i < length; i += 2 ) {
   1424 				matchIndexes.push( i );
   1425 			}
   1426 			return matchIndexes;
   1427 		} ),
   1428 
   1429 		odd: createPositionalPseudo( function( matchIndexes, length ) {
   1430 			var i = 1;
   1431 			for ( ; i < length; i += 2 ) {
   1432 				matchIndexes.push( i );
   1433 			}
   1434 			return matchIndexes;
   1435 		} ),
   1436 
   1437 		lt: createPositionalPseudo( function( matchIndexes, length, argument ) {
   1438 			var i;
   1439 
   1440 			if ( argument < 0 ) {
   1441 				i = argument + length;
   1442 			} else if ( argument > length ) {
   1443 				i = length;
   1444 			} else {
   1445 				i = argument;
   1446 			}
   1447 
   1448 			for ( ; --i >= 0; ) {
   1449 				matchIndexes.push( i );
   1450 			}
   1451 			return matchIndexes;
   1452 		} ),
   1453 
   1454 		gt: createPositionalPseudo( function( matchIndexes, length, argument ) {
   1455 			var i = argument < 0 ? argument + length : argument;
   1456 			for ( ; ++i < length; ) {
   1457 				matchIndexes.push( i );
   1458 			}
   1459 			return matchIndexes;
   1460 		} )
   1461 	}
   1462 };
   1463 
   1464 Expr.pseudos.nth = Expr.pseudos.eq;
   1465 
   1466 // Add button/input type pseudos
   1467 for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
   1468 	Expr.pseudos[ i ] = createInputPseudo( i );
   1469 }
   1470 for ( i in { submit: true, reset: true } ) {
   1471 	Expr.pseudos[ i ] = createButtonPseudo( i );
   1472 }
   1473 
   1474 // Easy API for creating new setFilters
   1475 function setFilters() {}
   1476 setFilters.prototype = Expr.filters = Expr.pseudos;
   1477 Expr.setFilters = new setFilters();
   1478 
   1479 function tokenize( selector, parseOnly ) {
   1480 	var matched, match, tokens, type,
   1481 		soFar, groups, preFilters,
   1482 		cached = tokenCache[ selector + " " ];
   1483 
   1484 	if ( cached ) {
   1485 		return parseOnly ? 0 : cached.slice( 0 );
   1486 	}
   1487 
   1488 	soFar = selector;
   1489 	groups = [];
   1490 	preFilters = Expr.preFilter;
   1491 
   1492 	while ( soFar ) {
   1493 
   1494 		// Comma and first run
   1495 		if ( !matched || ( match = rcomma.exec( soFar ) ) ) {
   1496 			if ( match ) {
   1497 
   1498 				// Don't consume trailing commas as valid
   1499 				soFar = soFar.slice( match[ 0 ].length ) || soFar;
   1500 			}
   1501 			groups.push( ( tokens = [] ) );
   1502 		}
   1503 
   1504 		matched = false;
   1505 
   1506 		// Combinators
   1507 		if ( ( match = rleadingCombinator.exec( soFar ) ) ) {
   1508 			matched = match.shift();
   1509 			tokens.push( {
   1510 				value: matched,
   1511 
   1512 				// Cast descendant combinators to space
   1513 				type: match[ 0 ].replace( rtrimCSS, " " )
   1514 			} );
   1515 			soFar = soFar.slice( matched.length );
   1516 		}
   1517 
   1518 		// Filters
   1519 		for ( type in Expr.filter ) {
   1520 			if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||
   1521 				( match = preFilters[ type ]( match ) ) ) ) {
   1522 				matched = match.shift();
   1523 				tokens.push( {
   1524 					value: matched,
   1525 					type: type,
   1526 					matches: match
   1527 				} );
   1528 				soFar = soFar.slice( matched.length );
   1529 			}
   1530 		}
   1531 
   1532 		if ( !matched ) {
   1533 			break;
   1534 		}
   1535 	}
   1536 
   1537 	// Return the length of the invalid excess
   1538 	// if we're just parsing
   1539 	// Otherwise, throw an error or return tokens
   1540 	if ( parseOnly ) {
   1541 		return soFar.length;
   1542 	}
   1543 
   1544 	return soFar ?
   1545 		find.error( selector ) :
   1546 
   1547 		// Cache the tokens
   1548 		tokenCache( selector, groups ).slice( 0 );
   1549 }
   1550 
   1551 function toSelector( tokens ) {
   1552 	var i = 0,
   1553 		len = tokens.length,
   1554 		selector = "";
   1555 	for ( ; i < len; i++ ) {
   1556 		selector += tokens[ i ].value;
   1557 	}
   1558 	return selector;
   1559 }
   1560 
   1561 function addCombinator( matcher, combinator, base ) {
   1562 	var dir = combinator.dir,
   1563 		skip = combinator.next,
   1564 		key = skip || dir,
   1565 		checkNonElements = base && key === "parentNode",
   1566 		doneName = done++;
   1567 
   1568 	return combinator.first ?
   1569 
   1570 		// Check against closest ancestor/preceding element
   1571 		function( elem, context, xml ) {
   1572 			while ( ( elem = elem[ dir ] ) ) {
   1573 				if ( elem.nodeType === 1 || checkNonElements ) {
   1574 					return matcher( elem, context, xml );
   1575 				}
   1576 			}
   1577 			return false;
   1578 		} :
   1579 
   1580 		// Check against all ancestor/preceding elements
   1581 		function( elem, context, xml ) {
   1582 			var oldCache, outerCache,
   1583 				newCache = [ dirruns, doneName ];
   1584 
   1585 			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
   1586 			if ( xml ) {
   1587 				while ( ( elem = elem[ dir ] ) ) {
   1588 					if ( elem.nodeType === 1 || checkNonElements ) {
   1589 						if ( matcher( elem, context, xml ) ) {
   1590 							return true;
   1591 						}
   1592 					}
   1593 				}
   1594 			} else {
   1595 				while ( ( elem = elem[ dir ] ) ) {
   1596 					if ( elem.nodeType === 1 || checkNonElements ) {
   1597 						outerCache = elem[ expando ] || ( elem[ expando ] = {} );
   1598 
   1599 						if ( skip && nodeName( elem, skip ) ) {
   1600 							elem = elem[ dir ] || elem;
   1601 						} else if ( ( oldCache = outerCache[ key ] ) &&
   1602 							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
   1603 
   1604 							// Assign to newCache so results back-propagate to previous elements
   1605 							return ( newCache[ 2 ] = oldCache[ 2 ] );
   1606 						} else {
   1607 
   1608 							// Reuse newcache so results back-propagate to previous elements
   1609 							outerCache[ key ] = newCache;
   1610 
   1611 							// A match means we're done; a fail means we have to keep checking
   1612 							if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {
   1613 								return true;
   1614 							}
   1615 						}
   1616 					}
   1617 				}
   1618 			}
   1619 			return false;
   1620 		};
   1621 }
   1622 
   1623 function elementMatcher( matchers ) {
   1624 	return matchers.length > 1 ?
   1625 		function( elem, context, xml ) {
   1626 			var i = matchers.length;
   1627 			while ( i-- ) {
   1628 				if ( !matchers[ i ]( elem, context, xml ) ) {
   1629 					return false;
   1630 				}
   1631 			}
   1632 			return true;
   1633 		} :
   1634 		matchers[ 0 ];
   1635 }
   1636 
   1637 function multipleContexts( selector, contexts, results ) {
   1638 	var i = 0,
   1639 		len = contexts.length;
   1640 	for ( ; i < len; i++ ) {
   1641 		find( selector, contexts[ i ], results );
   1642 	}
   1643 	return results;
   1644 }
   1645 
   1646 function condense( unmatched, map, filter, context, xml ) {
   1647 	var elem,
   1648 		newUnmatched = [],
   1649 		i = 0,
   1650 		len = unmatched.length,
   1651 		mapped = map != null;
   1652 
   1653 	for ( ; i < len; i++ ) {
   1654 		if ( ( elem = unmatched[ i ] ) ) {
   1655 			if ( !filter || filter( elem, context, xml ) ) {
   1656 				newUnmatched.push( elem );
   1657 				if ( mapped ) {
   1658 					map.push( i );
   1659 				}
   1660 			}
   1661 		}
   1662 	}
   1663 
   1664 	return newUnmatched;
   1665 }
   1666 
   1667 function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
   1668 	if ( postFilter && !postFilter[ expando ] ) {
   1669 		postFilter = setMatcher( postFilter );
   1670 	}
   1671 	if ( postFinder && !postFinder[ expando ] ) {
   1672 		postFinder = setMatcher( postFinder, postSelector );
   1673 	}
   1674 	return markFunction( function( seed, results, context, xml ) {
   1675 		var temp, i, elem, matcherOut,
   1676 			preMap = [],
   1677 			postMap = [],
   1678 			preexisting = results.length,
   1679 
   1680 			// Get initial elements from seed or context
   1681 			elems = seed ||
   1682 				multipleContexts( selector || "*",
   1683 					context.nodeType ? [ context ] : context, [] ),
   1684 
   1685 			// Prefilter to get matcher input, preserving a map for seed-results synchronization
   1686 			matcherIn = preFilter && ( seed || !selector ) ?
   1687 				condense( elems, preMap, preFilter, context, xml ) :
   1688 				elems;
   1689 
   1690 		if ( matcher ) {
   1691 
   1692 			// If we have a postFinder, or filtered seed, or non-seed postFilter
   1693 			// or preexisting results,
   1694 			matcherOut = postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
   1695 
   1696 				// ...intermediate processing is necessary
   1697 				[] :
   1698 
   1699 				// ...otherwise use results directly
   1700 				results;
   1701 
   1702 			// Find primary matches
   1703 			matcher( matcherIn, matcherOut, context, xml );
   1704 		} else {
   1705 			matcherOut = matcherIn;
   1706 		}
   1707 
   1708 		// Apply postFilter
   1709 		if ( postFilter ) {
   1710 			temp = condense( matcherOut, postMap );
   1711 			postFilter( temp, [], context, xml );
   1712 
   1713 			// Un-match failing elements by moving them back to matcherIn
   1714 			i = temp.length;
   1715 			while ( i-- ) {
   1716 				if ( ( elem = temp[ i ] ) ) {
   1717 					matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem );
   1718 				}
   1719 			}
   1720 		}
   1721 
   1722 		if ( seed ) {
   1723 			if ( postFinder || preFilter ) {
   1724 				if ( postFinder ) {
   1725 
   1726 					// Get the final matcherOut by condensing this intermediate into postFinder contexts
   1727 					temp = [];
   1728 					i = matcherOut.length;
   1729 					while ( i-- ) {
   1730 						if ( ( elem = matcherOut[ i ] ) ) {
   1731 
   1732 							// Restore matcherIn since elem is not yet a final match
   1733 							temp.push( ( matcherIn[ i ] = elem ) );
   1734 						}
   1735 					}
   1736 					postFinder( null, ( matcherOut = [] ), temp, xml );
   1737 				}
   1738 
   1739 				// Move matched elements from seed to results to keep them synchronized
   1740 				i = matcherOut.length;
   1741 				while ( i-- ) {
   1742 					if ( ( elem = matcherOut[ i ] ) &&
   1743 						( temp = postFinder ? indexOf.call( seed, elem ) : preMap[ i ] ) > -1 ) {
   1744 
   1745 						seed[ temp ] = !( results[ temp ] = elem );
   1746 					}
   1747 				}
   1748 			}
   1749 
   1750 		// Add elements to results, through postFinder if defined
   1751 		} else {
   1752 			matcherOut = condense(
   1753 				matcherOut === results ?
   1754 					matcherOut.splice( preexisting, matcherOut.length ) :
   1755 					matcherOut
   1756 			);
   1757 			if ( postFinder ) {
   1758 				postFinder( null, results, matcherOut, xml );
   1759 			} else {
   1760 				push.apply( results, matcherOut );
   1761 			}
   1762 		}
   1763 	} );
   1764 }
   1765 
   1766 function matcherFromTokens( tokens ) {
   1767 	var checkContext, matcher, j,
   1768 		len = tokens.length,
   1769 		leadingRelative = Expr.relative[ tokens[ 0 ].type ],
   1770 		implicitRelative = leadingRelative || Expr.relative[ " " ],
   1771 		i = leadingRelative ? 1 : 0,
   1772 
   1773 		// The foundational matcher ensures that elements are reachable from top-level context(s)
   1774 		matchContext = addCombinator( function( elem ) {
   1775 			return elem === checkContext;
   1776 		}, implicitRelative, true ),
   1777 		matchAnyContext = addCombinator( function( elem ) {
   1778 			return indexOf.call( checkContext, elem ) > -1;
   1779 		}, implicitRelative, true ),
   1780 		matchers = [ function( elem, context, xml ) {
   1781 
   1782 			// Support: IE 11+, Edge 17 - 18+
   1783 			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
   1784 			// two documents; shallow comparisons work.
   1785 			// eslint-disable-next-line eqeqeq
   1786 			var ret = ( !leadingRelative && ( xml || context != outermostContext ) ) || (
   1787 				( checkContext = context ).nodeType ?
   1788 					matchContext( elem, context, xml ) :
   1789 					matchAnyContext( elem, context, xml ) );
   1790 
   1791 			// Avoid hanging onto element
   1792 			// (see https://github.com/jquery/sizzle/issues/299)
   1793 			checkContext = null;
   1794 			return ret;
   1795 		} ];
   1796 
   1797 	for ( ; i < len; i++ ) {
   1798 		if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) {
   1799 			matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
   1800 		} else {
   1801 			matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );
   1802 
   1803 			// Return special upon seeing a positional matcher
   1804 			if ( matcher[ expando ] ) {
   1805 
   1806 				// Find the next relative operator (if any) for proper handling
   1807 				j = ++i;
   1808 				for ( ; j < len; j++ ) {
   1809 					if ( Expr.relative[ tokens[ j ].type ] ) {
   1810 						break;
   1811 					}
   1812 				}
   1813 				return setMatcher(
   1814 					i > 1 && elementMatcher( matchers ),
   1815 					i > 1 && toSelector(
   1816 
   1817 						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
   1818 						tokens.slice( 0, i - 1 )
   1819 							.concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } )
   1820 					).replace( rtrimCSS, "$1" ),
   1821 					matcher,
   1822 					i < j && matcherFromTokens( tokens.slice( i, j ) ),
   1823 					j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),
   1824 					j < len && toSelector( tokens )
   1825 				);
   1826 			}
   1827 			matchers.push( matcher );
   1828 		}
   1829 	}
   1830 
   1831 	return elementMatcher( matchers );
   1832 }
   1833 
   1834 function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
   1835 	var bySet = setMatchers.length > 0,
   1836 		byElement = elementMatchers.length > 0,
   1837 		superMatcher = function( seed, context, xml, results, outermost ) {
   1838 			var elem, j, matcher,
   1839 				matchedCount = 0,
   1840 				i = "0",
   1841 				unmatched = seed && [],
   1842 				setMatched = [],
   1843 				contextBackup = outermostContext,
   1844 
   1845 				// We must always have either seed elements or outermost context
   1846 				elems = seed || byElement && Expr.find.TAG( "*", outermost ),
   1847 
   1848 				// Use integer dirruns iff this is the outermost matcher
   1849 				dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ),
   1850 				len = elems.length;
   1851 
   1852 			if ( outermost ) {
   1853 
   1854 				// Support: IE 11+, Edge 17 - 18+
   1855 				// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
   1856 				// two documents; shallow comparisons work.
   1857 				// eslint-disable-next-line eqeqeq
   1858 				outermostContext = context == document || context || outermost;
   1859 			}
   1860 
   1861 			// Add elements passing elementMatchers directly to results
   1862 			// Support: iOS <=7 - 9 only
   1863 			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching
   1864 			// elements by id. (see trac-14142)
   1865 			for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {
   1866 				if ( byElement && elem ) {
   1867 					j = 0;
   1868 
   1869 					// Support: IE 11+, Edge 17 - 18+
   1870 					// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
   1871 					// two documents; shallow comparisons work.
   1872 					// eslint-disable-next-line eqeqeq
   1873 					if ( !context && elem.ownerDocument != document ) {
   1874 						setDocument( elem );
   1875 						xml = !documentIsHTML;
   1876 					}
   1877 					while ( ( matcher = elementMatchers[ j++ ] ) ) {
   1878 						if ( matcher( elem, context || document, xml ) ) {
   1879 							push.call( results, elem );
   1880 							break;
   1881 						}
   1882 					}
   1883 					if ( outermost ) {
   1884 						dirruns = dirrunsUnique;
   1885 					}
   1886 				}
   1887 
   1888 				// Track unmatched elements for set filters
   1889 				if ( bySet ) {
   1890 
   1891 					// They will have gone through all possible matchers
   1892 					if ( ( elem = !matcher && elem ) ) {
   1893 						matchedCount--;
   1894 					}
   1895 
   1896 					// Lengthen the array for every element, matched or not
   1897 					if ( seed ) {
   1898 						unmatched.push( elem );
   1899 					}
   1900 				}
   1901 			}
   1902 
   1903 			// `i` is now the count of elements visited above, and adding it to `matchedCount`
   1904 			// makes the latter nonnegative.
   1905 			matchedCount += i;
   1906 
   1907 			// Apply set filters to unmatched elements
   1908 			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
   1909 			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
   1910 			// no element matchers and no seed.
   1911 			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
   1912 			// case, which will result in a "00" `matchedCount` that differs from `i` but is also
   1913 			// numerically zero.
   1914 			if ( bySet && i !== matchedCount ) {
   1915 				j = 0;
   1916 				while ( ( matcher = setMatchers[ j++ ] ) ) {
   1917 					matcher( unmatched, setMatched, context, xml );
   1918 				}
   1919 
   1920 				if ( seed ) {
   1921 
   1922 					// Reintegrate element matches to eliminate the need for sorting
   1923 					if ( matchedCount > 0 ) {
   1924 						while ( i-- ) {
   1925 							if ( !( unmatched[ i ] || setMatched[ i ] ) ) {
   1926 								setMatched[ i ] = pop.call( results );
   1927 							}
   1928 						}
   1929 					}
   1930 
   1931 					// Discard index placeholder values to get only actual matches
   1932 					setMatched = condense( setMatched );
   1933 				}
   1934 
   1935 				// Add matches to results
   1936 				push.apply( results, setMatched );
   1937 
   1938 				// Seedless set matches succeeding multiple successful matchers stipulate sorting
   1939 				if ( outermost && !seed && setMatched.length > 0 &&
   1940 					( matchedCount + setMatchers.length ) > 1 ) {
   1941 
   1942 					jQuery.uniqueSort( results );
   1943 				}
   1944 			}
   1945 
   1946 			// Override manipulation of globals by nested matchers
   1947 			if ( outermost ) {
   1948 				dirruns = dirrunsUnique;
   1949 				outermostContext = contextBackup;
   1950 			}
   1951 
   1952 			return unmatched;
   1953 		};
   1954 
   1955 	return bySet ?
   1956 		markFunction( superMatcher ) :
   1957 		superMatcher;
   1958 }
   1959 
   1960 function compile( selector, match /* Internal Use Only */ ) {
   1961 	var i,
   1962 		setMatchers = [],
   1963 		elementMatchers = [],
   1964 		cached = compilerCache[ selector + " " ];
   1965 
   1966 	if ( !cached ) {
   1967 
   1968 		// Generate a function of recursive functions that can be used to check each element
   1969 		if ( !match ) {
   1970 			match = tokenize( selector );
   1971 		}
   1972 		i = match.length;
   1973 		while ( i-- ) {
   1974 			cached = matcherFromTokens( match[ i ] );
   1975 			if ( cached[ expando ] ) {
   1976 				setMatchers.push( cached );
   1977 			} else {
   1978 				elementMatchers.push( cached );
   1979 			}
   1980 		}
   1981 
   1982 		// Cache the compiled function
   1983 		cached = compilerCache( selector,
   1984 			matcherFromGroupMatchers( elementMatchers, setMatchers ) );
   1985 
   1986 		// Save selector and tokenization
   1987 		cached.selector = selector;
   1988 	}
   1989 	return cached;
   1990 }
   1991 
   1992 /**
   1993  * A low-level selection function that works with jQuery's compiled
   1994  *  selector functions
   1995  * @param {String|Function} selector A selector or a pre-compiled
   1996  *  selector function built with jQuery selector compile
   1997  * @param {Element} context
   1998  * @param {Array} [results]
   1999  * @param {Array} [seed] A set of elements to match against
   2000  */
   2001 function select( selector, context, results, seed ) {
   2002 	var i, tokens, token, type, find,
   2003 		compiled = typeof selector === "function" && selector,
   2004 		match = !seed && tokenize( ( selector = compiled.selector || selector ) );
   2005 
   2006 	results = results || [];
   2007 
   2008 	// Try to minimize operations if there is only one selector in the list and no seed
   2009 	// (the latter of which guarantees us context)
   2010 	if ( match.length === 1 ) {
   2011 
   2012 		// Reduce context if the leading compound selector is an ID
   2013 		tokens = match[ 0 ] = match[ 0 ].slice( 0 );
   2014 		if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" &&
   2015 				context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) {
   2016 
   2017 			context = ( Expr.find.ID(
   2018 				token.matches[ 0 ].replace( runescape, funescape ),
   2019 				context
   2020 			) || [] )[ 0 ];
   2021 			if ( !context ) {
   2022 				return results;
   2023 
   2024 			// Precompiled matchers will still verify ancestry, so step up a level
   2025 			} else if ( compiled ) {
   2026 				context = context.parentNode;
   2027 			}
   2028 
   2029 			selector = selector.slice( tokens.shift().value.length );
   2030 		}
   2031 
   2032 		// Fetch a seed set for right-to-left matching
   2033 		i = matchExpr.needsContext.test( selector ) ? 0 : tokens.length;
   2034 		while ( i-- ) {
   2035 			token = tokens[ i ];
   2036 
   2037 			// Abort if we hit a combinator
   2038 			if ( Expr.relative[ ( type = token.type ) ] ) {
   2039 				break;
   2040 			}
   2041 			if ( ( find = Expr.find[ type ] ) ) {
   2042 
   2043 				// Search, expanding context for leading sibling combinators
   2044 				if ( ( seed = find(
   2045 					token.matches[ 0 ].replace( runescape, funescape ),
   2046 					rsibling.test( tokens[ 0 ].type ) &&
   2047 						testContext( context.parentNode ) || context
   2048 				) ) ) {
   2049 
   2050 					// If seed is empty or no tokens remain, we can return early
   2051 					tokens.splice( i, 1 );
   2052 					selector = seed.length && toSelector( tokens );
   2053 					if ( !selector ) {
   2054 						push.apply( results, seed );
   2055 						return results;
   2056 					}
   2057 
   2058 					break;
   2059 				}
   2060 			}
   2061 		}
   2062 	}
   2063 
   2064 	// Compile and execute a filtering function if one is not provided
   2065 	// Provide `match` to avoid retokenization if we modified the selector above
   2066 	( compiled || compile( selector, match ) )(
   2067 		seed,
   2068 		context,
   2069 		!documentIsHTML,
   2070 		results,
   2071 		!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
   2072 	);
   2073 	return results;
   2074 }
   2075 
   2076 // One-time assignments
   2077 
   2078 // Support: Android <=4.0 - 4.1+
   2079 // Sort stability
   2080 support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando;
   2081 
   2082 // Initialize against the default document
   2083 setDocument();
   2084 
   2085 // Support: Android <=4.0 - 4.1+
   2086 // Detached nodes confoundingly follow *each other*
   2087 support.sortDetached = assert( function( el ) {
   2088 
   2089 	// Should return 1, but returns 4 (following)
   2090 	return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1;
   2091 } );
   2092 
   2093 jQuery.find = find;
   2094 
   2095 // Deprecated
   2096 jQuery.expr[ ":" ] = jQuery.expr.pseudos;
   2097 jQuery.unique = jQuery.uniqueSort;
   2098 
   2099 // These have always been private, but they used to be documented as part of
   2100 // Sizzle so let's maintain them for now for backwards compatibility purposes.
   2101 find.compile = compile;
   2102 find.select = select;
   2103 find.setDocument = setDocument;
   2104 find.tokenize = tokenize;
   2105 
   2106 find.escape = jQuery.escapeSelector;
   2107 find.getText = jQuery.text;
   2108 find.isXML = jQuery.isXMLDoc;
   2109 find.selectors = jQuery.expr;
   2110 find.support = jQuery.support;
   2111 find.uniqueSort = jQuery.uniqueSort;
   2112 
   2113 	/* eslint-enable */
   2114 
   2115 } )();
   2116 
   2117 } );