Selector: update Sizzle
[jquery.git] / src / sizzle / dist / sizzle.js
blobbebf6e68a63ef572977dc4449949704d65d2d098
1 /*!
2  * Sizzle CSS Selector Engine v1.10.18
3  * http://sizzlejs.com/
4  *
5  * Copyright 2013 jQuery Foundation, Inc. and other contributors
6  * Released under the MIT license
7  * http://jquery.org/license
8  *
9  * Date: 2014-02-05
10  */
11 (function( window ) {
13 var i,
14         support,
15         Expr,
16         getText,
17         isXML,
18         compile,
19         select,
20         outermostContext,
21         sortInput,
22         hasDuplicate,
24         // Local document vars
25         setDocument,
26         document,
27         docElem,
28         documentIsHTML,
29         rbuggyQSA,
30         rbuggyMatches,
31         matches,
32         contains,
34         // Instance-specific data
35         expando = "sizzle" + -(new Date()),
36         preferredDoc = window.document,
37         dirruns = 0,
38         done = 0,
39         classCache = createCache(),
40         tokenCache = createCache(),
41         compilerCache = createCache(),
42         sortOrder = function( a, b ) {
43                 if ( a === b ) {
44                         hasDuplicate = true;
45                 }
46                 return 0;
47         },
49         // General-purpose constants
50         strundefined = typeof undefined,
51         MAX_NEGATIVE = 1 << 31,
53         // Instance methods
54         hasOwn = ({}).hasOwnProperty,
55         arr = [],
56         pop = arr.pop,
57         push_native = arr.push,
58         push = arr.push,
59         slice = arr.slice,
60         // Use a stripped-down indexOf if we can't use a native one
61         indexOf = arr.indexOf || function( elem ) {
62                 var i = 0,
63                         len = this.length;
64                 for ( ; i < len; i++ ) {
65                         if ( this[i] === elem ) {
66                                 return i;
67                         }
68                 }
69                 return -1;
70         },
72         booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
74         // Regular expressions
76         // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
77         whitespace = "[\\x20\\t\\r\\n\\f]",
78         // http://www.w3.org/TR/css3-syntax/#characters
79         characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
81         // Loosely modeled on CSS identifier characters
82         // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
83         // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
84         identifier = characterEncoding.replace( "w", "w#" ),
86         // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
87         attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
88                 "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
90         // Prefer arguments quoted,
91         //   then not containing pseudos/brackets,
92         //   then attribute selectors/non-parenthetical expressions,
93         //   then anything else
94         // These preferences are here to reduce the number of selectors
95         //   needing tokenize in the PSEUDO preFilter
96         pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)",
98         // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
99         rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
101         rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
102         rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
104         rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
106         rpseudo = new RegExp( pseudos ),
107         ridentifier = new RegExp( "^" + identifier + "$" ),
109         matchExpr = {
110                 "ID": new RegExp( "^#(" + characterEncoding + ")" ),
111                 "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
112                 "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
113                 "ATTR": new RegExp( "^" + attributes ),
114                 "PSEUDO": new RegExp( "^" + pseudos ),
115                 "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
116                         "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
117                         "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
118                 "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
119                 // For use in libraries implementing .is()
120                 // We use this for POS matching in `select`
121                 "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
122                         whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
123         },
125         rinputs = /^(?:input|select|textarea|button)$/i,
126         rheader = /^h\d$/i,
128         rnative = /^[^{]+\{\s*\[native \w/,
130         // Easily-parseable/retrievable ID or TAG or CLASS selectors
131         rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
133         rsibling = /[+~]/,
134         rescape = /'|\\/g,
136         // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
137         runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
138         funescape = function( _, escaped, escapedWhitespace ) {
139                 var high = "0x" + escaped - 0x10000;
140                 // NaN means non-codepoint
141                 // Support: Firefox<24
142                 // Workaround erroneous numeric interpretation of +"0x"
143                 return high !== high || escapedWhitespace ?
144                         escaped :
145                         high < 0 ?
146                                 // BMP codepoint
147                                 String.fromCharCode( high + 0x10000 ) :
148                                 // Supplemental Plane codepoint (surrogate pair)
149                                 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
150         };
152 // Optimize for push.apply( _, NodeList )
153 try {
154         push.apply(
155                 (arr = slice.call( preferredDoc.childNodes )),
156                 preferredDoc.childNodes
157         );
158         // Support: Android<4.0
159         // Detect silently failing push.apply
160         arr[ preferredDoc.childNodes.length ].nodeType;
161 } catch ( e ) {
162         push = { apply: arr.length ?
164                 // Leverage slice if possible
165                 function( target, els ) {
166                         push_native.apply( target, slice.call(els) );
167                 } :
169                 // Support: IE<9
170                 // Otherwise append directly
171                 function( target, els ) {
172                         var j = target.length,
173                                 i = 0;
174                         // Can't trust NodeList.length
175                         while ( (target[j++] = els[i++]) ) {}
176                         target.length = j - 1;
177                 }
178         };
181 function Sizzle( selector, context, results, seed ) {
182         var match, elem, m, nodeType,
183                 // QSA vars
184                 i, groups, old, nid, newContext, newSelector;
186         if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
187                 setDocument( context );
188         }
190         context = context || document;
191         results = results || [];
193         if ( !selector || typeof selector !== "string" ) {
194                 return results;
195         }
197         if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
198                 return [];
199         }
201         if ( documentIsHTML && !seed ) {
203                 // Shortcuts
204                 if ( (match = rquickExpr.exec( selector )) ) {
205                         // Speed-up: Sizzle("#ID")
206                         if ( (m = match[1]) ) {
207                                 if ( nodeType === 9 ) {
208                                         elem = context.getElementById( m );
209                                         // Check parentNode to catch when Blackberry 4.6 returns
210                                         // nodes that are no longer in the document (jQuery #6963)
211                                         if ( elem && elem.parentNode ) {
212                                                 // Handle the case where IE, Opera, and Webkit return items
213                                                 // by name instead of ID
214                                                 if ( elem.id === m ) {
215                                                         results.push( elem );
216                                                         return results;
217                                                 }
218                                         } else {
219                                                 return results;
220                                         }
221                                 } else {
222                                         // Context is not a document
223                                         if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
224                                                 contains( context, elem ) && elem.id === m ) {
225                                                 results.push( elem );
226                                                 return results;
227                                         }
228                                 }
230                         // Speed-up: Sizzle("TAG")
231                         } else if ( match[2] ) {
232                                 push.apply( results, context.getElementsByTagName( selector ) );
233                                 return results;
235                         // Speed-up: Sizzle(".CLASS")
236                         } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
237                                 push.apply( results, context.getElementsByClassName( m ) );
238                                 return results;
239                         }
240                 }
242                 // QSA path
243                 if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
244                         nid = old = expando;
245                         newContext = context;
246                         newSelector = nodeType === 9 && selector;
248                         // qSA works strangely on Element-rooted queries
249                         // We can work around this by specifying an extra ID on the root
250                         // and working up from there (Thanks to Andrew Dupont for the technique)
251                         // IE 8 doesn't work on object elements
252                         if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
253                                 groups = tokenize( selector );
255                                 if ( (old = context.getAttribute("id")) ) {
256                                         nid = old.replace( rescape, "\\$&" );
257                                 } else {
258                                         context.setAttribute( "id", nid );
259                                 }
260                                 nid = "[id='" + nid + "'] ";
262                                 i = groups.length;
263                                 while ( i-- ) {
264                                         groups[i] = nid + toSelector( groups[i] );
265                                 }
266                                 newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
267                                 newSelector = groups.join(",");
268                         }
270                         if ( newSelector ) {
271                                 try {
272                                         push.apply( results,
273                                                 newContext.querySelectorAll( newSelector )
274                                         );
275                                         return results;
276                                 } catch(qsaError) {
277                                 } finally {
278                                         if ( !old ) {
279                                                 context.removeAttribute("id");
280                                         }
281                                 }
282                         }
283                 }
284         }
286         // All others
287         return select( selector.replace( rtrim, "$1" ), context, results, seed );
291  * Create key-value caches of limited size
292  * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
293  *      property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
294  *      deleting the oldest entry
295  */
296 function createCache() {
297         var keys = [];
299         function cache( key, value ) {
300                 // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
301                 if ( keys.push( key + " " ) > Expr.cacheLength ) {
302                         // Only keep the most recent entries
303                         delete cache[ keys.shift() ];
304                 }
305                 return (cache[ key + " " ] = value);
306         }
307         return cache;
311  * Mark a function for special use by Sizzle
312  * @param {Function} fn The function to mark
313  */
314 function markFunction( fn ) {
315         fn[ expando ] = true;
316         return fn;
320  * Support testing using an element
321  * @param {Function} fn Passed the created div and expects a boolean result
322  */
323 function assert( fn ) {
324         var div = document.createElement("div");
326         try {
327                 return !!fn( div );
328         } catch (e) {
329                 return false;
330         } finally {
331                 // Remove from its parent by default
332                 if ( div.parentNode ) {
333                         div.parentNode.removeChild( div );
334                 }
335                 // release memory in IE
336                 div = null;
337         }
341  * Adds the same handler for all of the specified attrs
342  * @param {String} attrs Pipe-separated list of attributes
343  * @param {Function} handler The method that will be applied
344  */
345 function addHandle( attrs, handler ) {
346         var arr = attrs.split("|"),
347                 i = attrs.length;
349         while ( i-- ) {
350                 Expr.attrHandle[ arr[i] ] = handler;
351         }
355  * Checks document order of two siblings
356  * @param {Element} a
357  * @param {Element} b
358  * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
359  */
360 function siblingCheck( a, b ) {
361         var cur = b && a,
362                 diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
363                         ( ~b.sourceIndex || MAX_NEGATIVE ) -
364                         ( ~a.sourceIndex || MAX_NEGATIVE );
366         // Use IE sourceIndex if available on both nodes
367         if ( diff ) {
368                 return diff;
369         }
371         // Check if b follows a
372         if ( cur ) {
373                 while ( (cur = cur.nextSibling) ) {
374                         if ( cur === b ) {
375                                 return -1;
376                         }
377                 }
378         }
380         return a ? 1 : -1;
384  * Returns a function to use in pseudos for input types
385  * @param {String} type
386  */
387 function createInputPseudo( type ) {
388         return function( elem ) {
389                 var name = elem.nodeName.toLowerCase();
390                 return name === "input" && elem.type === type;
391         };
395  * Returns a function to use in pseudos for buttons
396  * @param {String} type
397  */
398 function createButtonPseudo( type ) {
399         return function( elem ) {
400                 var name = elem.nodeName.toLowerCase();
401                 return (name === "input" || name === "button") && elem.type === type;
402         };
406  * Returns a function to use in pseudos for positionals
407  * @param {Function} fn
408  */
409 function createPositionalPseudo( fn ) {
410         return markFunction(function( argument ) {
411                 argument = +argument;
412                 return markFunction(function( seed, matches ) {
413                         var j,
414                                 matchIndexes = fn( [], seed.length, argument ),
415                                 i = matchIndexes.length;
417                         // Match elements found at the specified indexes
418                         while ( i-- ) {
419                                 if ( seed[ (j = matchIndexes[i]) ] ) {
420                                         seed[j] = !(matches[j] = seed[j]);
421                                 }
422                         }
423                 });
424         });
428  * Checks a node for validity as a Sizzle context
429  * @param {Element|Object=} context
430  * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
431  */
432 function testContext( context ) {
433         return context && typeof context.getElementsByTagName !== strundefined && context;
436 // Expose support vars for convenience
437 support = Sizzle.support = {};
440  * Detects XML nodes
441  * @param {Element|Object} elem An element or a document
442  * @returns {Boolean} True iff elem is a non-HTML XML node
443  */
444 isXML = Sizzle.isXML = function( elem ) {
445         // documentElement is verified for cases where it doesn't yet exist
446         // (such as loading iframes in IE - #4833)
447         var documentElement = elem && (elem.ownerDocument || elem).documentElement;
448         return documentElement ? documentElement.nodeName !== "HTML" : false;
452  * Sets document-related variables once based on the current document
453  * @param {Element|Object} [doc] An element or document object to use to set the document
454  * @returns {Object} Returns the current document
455  */
456 setDocument = Sizzle.setDocument = function( node ) {
457         var hasCompare,
458                 doc = node ? node.ownerDocument || node : preferredDoc,
459                 parent = doc.defaultView;
461         // If no document and documentElement is available, return
462         if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
463                 return document;
464         }
466         // Set our document
467         document = doc;
468         docElem = doc.documentElement;
470         // Support tests
471         documentIsHTML = !isXML( doc );
473         // Support: IE>8
474         // If iframe document is assigned to "document" variable and if iframe has been reloaded,
475         // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
476         // IE6-8 do not support the defaultView property so parent will be undefined
477         if ( parent && parent !== parent.top ) {
478                 // IE11 does not have attachEvent, so all must suffer
479                 if ( parent.addEventListener ) {
480                         parent.addEventListener( "unload", function() {
481                                 setDocument();
482                         }, false );
483                 } else if ( parent.attachEvent ) {
484                         parent.attachEvent( "onunload", function() {
485                                 setDocument();
486                         });
487                 }
488         }
490         /* Attributes
491         ---------------------------------------------------------------------- */
493         // Support: IE<8
494         // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
495         support.attributes = assert(function( div ) {
496                 div.className = "i";
497                 return !div.getAttribute("className");
498         });
500         /* getElement(s)By*
501         ---------------------------------------------------------------------- */
503         // Check if getElementsByTagName("*") returns only elements
504         support.getElementsByTagName = assert(function( div ) {
505                 div.appendChild( doc.createComment("") );
506                 return !div.getElementsByTagName("*").length;
507         });
509         // Check if getElementsByClassName can be trusted
510         support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) {
511                 div.innerHTML = "<div class='a'></div><div class='a i'></div>";
513                 // Support: Safari<4
514                 // Catch class over-caching
515                 div.firstChild.className = "i";
516                 // Support: Opera<10
517                 // Catch gEBCN failure to find non-leading classes
518                 return div.getElementsByClassName("i").length === 2;
519         });
521         // Support: IE<10
522         // Check if getElementById returns elements by name
523         // The broken getElementById methods don't pick up programatically-set names,
524         // so use a roundabout getElementsByName test
525         support.getById = assert(function( div ) {
526                 docElem.appendChild( div ).id = expando;
527                 return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
528         });
530         // ID find and filter
531         if ( support.getById ) {
532                 Expr.find["ID"] = function( id, context ) {
533                         if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
534                                 var m = context.getElementById( id );
535                                 // Check parentNode to catch when Blackberry 4.6 returns
536                                 // nodes that are no longer in the document #6963
537                                 return m && m.parentNode ? [m] : [];
538                         }
539                 };
540                 Expr.filter["ID"] = function( id ) {
541                         var attrId = id.replace( runescape, funescape );
542                         return function( elem ) {
543                                 return elem.getAttribute("id") === attrId;
544                         };
545                 };
546         } else {
547                 // Support: IE6/7
548                 // getElementById is not reliable as a find shortcut
549                 delete Expr.find["ID"];
551                 Expr.filter["ID"] =  function( id ) {
552                         var attrId = id.replace( runescape, funescape );
553                         return function( elem ) {
554                                 var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
555                                 return node && node.value === attrId;
556                         };
557                 };
558         }
560         // Tag
561         Expr.find["TAG"] = support.getElementsByTagName ?
562                 function( tag, context ) {
563                         if ( typeof context.getElementsByTagName !== strundefined ) {
564                                 return context.getElementsByTagName( tag );
565                         }
566                 } :
567                 function( tag, context ) {
568                         var elem,
569                                 tmp = [],
570                                 i = 0,
571                                 results = context.getElementsByTagName( tag );
573                         // Filter out possible comments
574                         if ( tag === "*" ) {
575                                 while ( (elem = results[i++]) ) {
576                                         if ( elem.nodeType === 1 ) {
577                                                 tmp.push( elem );
578                                         }
579                                 }
581                                 return tmp;
582                         }
583                         return results;
584                 };
586         // Class
587         Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
588                 if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
589                         return context.getElementsByClassName( className );
590                 }
591         };
593         /* QSA/matchesSelector
594         ---------------------------------------------------------------------- */
596         // QSA and matchesSelector support
598         // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
599         rbuggyMatches = [];
601         // qSa(:focus) reports false when true (Chrome 21)
602         // We allow this because of a bug in IE8/9 that throws an error
603         // whenever `document.activeElement` is accessed on an iframe
604         // So, we allow :focus to pass through QSA all the time to avoid the IE error
605         // See http://bugs.jquery.com/ticket/13378
606         rbuggyQSA = [];
608         if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
609                 // Build QSA regex
610                 // Regex strategy adopted from Diego Perini
611                 assert(function( div ) {
612                         // Select is set to empty string on purpose
613                         // This is to test IE's treatment of not explicitly
614                         // setting a boolean content attribute,
615                         // since its presence should be enough
616                         // http://bugs.jquery.com/ticket/12359
617                         div.innerHTML = "<select t=''><option selected=''></option></select>";
619                         // Support: IE8, Opera 10-12
620                         // Nothing should be selected when empty strings follow ^= or $= or *=
621                         if ( div.querySelectorAll("[t^='']").length ) {
622                                 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
623                         }
625                         // Support: IE8
626                         // Boolean attributes and "value" are not treated correctly
627                         if ( !div.querySelectorAll("[selected]").length ) {
628                                 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
629                         }
631                         // Webkit/Opera - :checked should return selected option elements
632                         // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
633                         // IE8 throws error here and will not see later tests
634                         if ( !div.querySelectorAll(":checked").length ) {
635                                 rbuggyQSA.push(":checked");
636                         }
637                 });
639                 assert(function( div ) {
640                         // Support: Windows 8 Native Apps
641                         // The type and name attributes are restricted during .innerHTML assignment
642                         var input = doc.createElement("input");
643                         input.setAttribute( "type", "hidden" );
644                         div.appendChild( input ).setAttribute( "name", "D" );
646                         // Support: IE8
647                         // Enforce case-sensitivity of name attribute
648                         if ( div.querySelectorAll("[name=d]").length ) {
649                                 rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
650                         }
652                         // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
653                         // IE8 throws error here and will not see later tests
654                         if ( !div.querySelectorAll(":enabled").length ) {
655                                 rbuggyQSA.push( ":enabled", ":disabled" );
656                         }
658                         // Opera 10-11 does not throw on post-comma invalid pseudos
659                         div.querySelectorAll("*,:x");
660                         rbuggyQSA.push(",.*:");
661                 });
662         }
664         if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector ||
665                 docElem.mozMatchesSelector ||
666                 docElem.oMatchesSelector ||
667                 docElem.msMatchesSelector) )) ) {
669                 assert(function( div ) {
670                         // Check to see if it's possible to do matchesSelector
671                         // on a disconnected node (IE 9)
672                         support.disconnectedMatch = matches.call( div, "div" );
674                         // This should fail with an exception
675                         // Gecko does not error, returns false instead
676                         matches.call( div, "[s!='']:x" );
677                         rbuggyMatches.push( "!=", pseudos );
678                 });
679         }
681         rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
682         rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
684         /* Contains
685         ---------------------------------------------------------------------- */
686         hasCompare = rnative.test( docElem.compareDocumentPosition );
688         // Element contains another
689         // Purposefully does not implement inclusive descendent
690         // As in, an element does not contain itself
691         contains = hasCompare || rnative.test( docElem.contains ) ?
692                 function( a, b ) {
693                         var adown = a.nodeType === 9 ? a.documentElement : a,
694                                 bup = b && b.parentNode;
695                         return a === bup || !!( bup && bup.nodeType === 1 && (
696                                 adown.contains ?
697                                         adown.contains( bup ) :
698                                         a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
699                         ));
700                 } :
701                 function( a, b ) {
702                         if ( b ) {
703                                 while ( (b = b.parentNode) ) {
704                                         if ( b === a ) {
705                                                 return true;
706                                         }
707                                 }
708                         }
709                         return false;
710                 };
712         /* Sorting
713         ---------------------------------------------------------------------- */
715         // Document order sorting
716         sortOrder = hasCompare ?
717         function( a, b ) {
719                 // Flag for duplicate removal
720                 if ( a === b ) {
721                         hasDuplicate = true;
722                         return 0;
723                 }
725                 // Sort on method existence if only one input has compareDocumentPosition
726                 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
727                 if ( compare ) {
728                         return compare;
729                 }
731                 // Calculate position if both inputs belong to the same document
732                 compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
733                         a.compareDocumentPosition( b ) :
735                         // Otherwise we know they are disconnected
736                         1;
738                 // Disconnected nodes
739                 if ( compare & 1 ||
740                         (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
742                         // Choose the first element that is related to our preferred document
743                         if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
744                                 return -1;
745                         }
746                         if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
747                                 return 1;
748                         }
750                         // Maintain original order
751                         return sortInput ?
752                                 ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
753                                 0;
754                 }
756                 return compare & 4 ? -1 : 1;
757         } :
758         function( a, b ) {
759                 // Exit early if the nodes are identical
760                 if ( a === b ) {
761                         hasDuplicate = true;
762                         return 0;
763                 }
765                 var cur,
766                         i = 0,
767                         aup = a.parentNode,
768                         bup = b.parentNode,
769                         ap = [ a ],
770                         bp = [ b ];
772                 // Parentless nodes are either documents or disconnected
773                 if ( !aup || !bup ) {
774                         return a === doc ? -1 :
775                                 b === doc ? 1 :
776                                 aup ? -1 :
777                                 bup ? 1 :
778                                 sortInput ?
779                                 ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
780                                 0;
782                 // If the nodes are siblings, we can do a quick check
783                 } else if ( aup === bup ) {
784                         return siblingCheck( a, b );
785                 }
787                 // Otherwise we need full lists of their ancestors for comparison
788                 cur = a;
789                 while ( (cur = cur.parentNode) ) {
790                         ap.unshift( cur );
791                 }
792                 cur = b;
793                 while ( (cur = cur.parentNode) ) {
794                         bp.unshift( cur );
795                 }
797                 // Walk down the tree looking for a discrepancy
798                 while ( ap[i] === bp[i] ) {
799                         i++;
800                 }
802                 return i ?
803                         // Do a sibling check if the nodes have a common ancestor
804                         siblingCheck( ap[i], bp[i] ) :
806                         // Otherwise nodes in our document sort first
807                         ap[i] === preferredDoc ? -1 :
808                         bp[i] === preferredDoc ? 1 :
809                         0;
810         };
812         return doc;
815 Sizzle.matches = function( expr, elements ) {
816         return Sizzle( expr, null, null, elements );
819 Sizzle.matchesSelector = function( elem, expr ) {
820         // Set document vars if needed
821         if ( ( elem.ownerDocument || elem ) !== document ) {
822                 setDocument( elem );
823         }
825         // Make sure that attribute selectors are quoted
826         expr = expr.replace( rattributeQuotes, "='$1']" );
828         if ( support.matchesSelector && documentIsHTML &&
829                 ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
830                 ( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
832                 try {
833                         var ret = matches.call( elem, expr );
835                         // IE 9's matchesSelector returns false on disconnected nodes
836                         if ( ret || support.disconnectedMatch ||
837                                         // As well, disconnected nodes are said to be in a document
838                                         // fragment in IE 9
839                                         elem.document && elem.document.nodeType !== 11 ) {
840                                 return ret;
841                         }
842                 } catch(e) {}
843         }
845         return Sizzle( expr, document, null, [elem] ).length > 0;
848 Sizzle.contains = function( context, elem ) {
849         // Set document vars if needed
850         if ( ( context.ownerDocument || context ) !== document ) {
851                 setDocument( context );
852         }
853         return contains( context, elem );
856 Sizzle.attr = function( elem, name ) {
857         // Set document vars if needed
858         if ( ( elem.ownerDocument || elem ) !== document ) {
859                 setDocument( elem );
860         }
862         var fn = Expr.attrHandle[ name.toLowerCase() ],
863                 // Don't get fooled by Object.prototype properties (jQuery #13807)
864                 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
865                         fn( elem, name, !documentIsHTML ) :
866                         undefined;
868         return val !== undefined ?
869                 val :
870                 support.attributes || !documentIsHTML ?
871                         elem.getAttribute( name ) :
872                         (val = elem.getAttributeNode(name)) && val.specified ?
873                                 val.value :
874                                 null;
877 Sizzle.error = function( msg ) {
878         throw new Error( "Syntax error, unrecognized expression: " + msg );
882  * Document sorting and removing duplicates
883  * @param {ArrayLike} results
884  */
885 Sizzle.uniqueSort = function( results ) {
886         var elem,
887                 duplicates = [],
888                 j = 0,
889                 i = 0;
891         // Unless we *know* we can detect duplicates, assume their presence
892         hasDuplicate = !support.detectDuplicates;
893         sortInput = !support.sortStable && results.slice( 0 );
894         results.sort( sortOrder );
896         if ( hasDuplicate ) {
897                 while ( (elem = results[i++]) ) {
898                         if ( elem === results[ i ] ) {
899                                 j = duplicates.push( i );
900                         }
901                 }
902                 while ( j-- ) {
903                         results.splice( duplicates[ j ], 1 );
904                 }
905         }
907         // Clear input after sorting to release objects
908         // See https://github.com/jquery/sizzle/pull/225
909         sortInput = null;
911         return results;
915  * Utility function for retrieving the text value of an array of DOM nodes
916  * @param {Array|Element} elem
917  */
918 getText = Sizzle.getText = function( elem ) {
919         var node,
920                 ret = "",
921                 i = 0,
922                 nodeType = elem.nodeType;
924         if ( !nodeType ) {
925                 // If no nodeType, this is expected to be an array
926                 while ( (node = elem[i++]) ) {
927                         // Do not traverse comment nodes
928                         ret += getText( node );
929                 }
930         } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
931                 // Use textContent for elements
932                 // innerText usage removed for consistency of new lines (jQuery #11153)
933                 if ( typeof elem.textContent === "string" ) {
934                         return elem.textContent;
935                 } else {
936                         // Traverse its children
937                         for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
938                                 ret += getText( elem );
939                         }
940                 }
941         } else if ( nodeType === 3 || nodeType === 4 ) {
942                 return elem.nodeValue;
943         }
944         // Do not include comment or processing instruction nodes
946         return ret;
949 Expr = Sizzle.selectors = {
951         // Can be adjusted by the user
952         cacheLength: 50,
954         createPseudo: markFunction,
956         match: matchExpr,
958         attrHandle: {},
960         find: {},
962         relative: {
963                 ">": { dir: "parentNode", first: true },
964                 " ": { dir: "parentNode" },
965                 "+": { dir: "previousSibling", first: true },
966                 "~": { dir: "previousSibling" }
967         },
969         preFilter: {
970                 "ATTR": function( match ) {
971                         match[1] = match[1].replace( runescape, funescape );
973                         // Move the given value to match[3] whether quoted or unquoted
974                         match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape );
976                         if ( match[2] === "~=" ) {
977                                 match[3] = " " + match[3] + " ";
978                         }
980                         return match.slice( 0, 4 );
981                 },
983                 "CHILD": function( match ) {
984                         /* matches from matchExpr["CHILD"]
985                                 1 type (only|nth|...)
986                                 2 what (child|of-type)
987                                 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
988                                 4 xn-component of xn+y argument ([+-]?\d*n|)
989                                 5 sign of xn-component
990                                 6 x of xn-component
991                                 7 sign of y-component
992                                 8 y of y-component
993                         */
994                         match[1] = match[1].toLowerCase();
996                         if ( match[1].slice( 0, 3 ) === "nth" ) {
997                                 // nth-* requires argument
998                                 if ( !match[3] ) {
999                                         Sizzle.error( match[0] );
1000                                 }
1002                                 // numeric x and y parameters for Expr.filter.CHILD
1003                                 // remember that false/true cast respectively to 0/1
1004                                 match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
1005                                 match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
1007                         // other types prohibit arguments
1008                         } else if ( match[3] ) {
1009                                 Sizzle.error( match[0] );
1010                         }
1012                         return match;
1013                 },
1015                 "PSEUDO": function( match ) {
1016                         var excess,
1017                                 unquoted = !match[5] && match[2];
1019                         if ( matchExpr["CHILD"].test( match[0] ) ) {
1020                                 return null;
1021                         }
1023                         // Accept quoted arguments as-is
1024                         if ( match[3] && match[4] !== undefined ) {
1025                                 match[2] = match[4];
1027                         // Strip excess characters from unquoted arguments
1028                         } else if ( unquoted && rpseudo.test( unquoted ) &&
1029                                 // Get excess from tokenize (recursively)
1030                                 (excess = tokenize( unquoted, true )) &&
1031                                 // advance to the next closing parenthesis
1032                                 (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
1034                                 // excess is a negative index
1035                                 match[0] = match[0].slice( 0, excess );
1036                                 match[2] = unquoted.slice( 0, excess );
1037                         }
1039                         // Return only captures needed by the pseudo filter method (type and argument)
1040                         return match.slice( 0, 3 );
1041                 }
1042         },
1044         filter: {
1046                 "TAG": function( nodeNameSelector ) {
1047                         var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1048                         return nodeNameSelector === "*" ?
1049                                 function() { return true; } :
1050                                 function( elem ) {
1051                                         return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1052                                 };
1053                 },
1055                 "CLASS": function( className ) {
1056                         var pattern = classCache[ className + " " ];
1058                         return pattern ||
1059                                 (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
1060                                 classCache( className, function( elem ) {
1061                                         return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
1062                                 });
1063                 },
1065                 "ATTR": function( name, operator, check ) {
1066                         return function( elem ) {
1067                                 var result = Sizzle.attr( elem, name );
1069                                 if ( result == null ) {
1070                                         return operator === "!=";
1071                                 }
1072                                 if ( !operator ) {
1073                                         return true;
1074                                 }
1076                                 result += "";
1078                                 return operator === "=" ? result === check :
1079                                         operator === "!=" ? result !== check :
1080                                         operator === "^=" ? check && result.indexOf( check ) === 0 :
1081                                         operator === "*=" ? check && result.indexOf( check ) > -1 :
1082                                         operator === "$=" ? check && result.slice( -check.length ) === check :
1083                                         operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
1084                                         operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1085                                         false;
1086                         };
1087                 },
1089                 "CHILD": function( type, what, argument, first, last ) {
1090                         var simple = type.slice( 0, 3 ) !== "nth",
1091                                 forward = type.slice( -4 ) !== "last",
1092                                 ofType = what === "of-type";
1094                         return first === 1 && last === 0 ?
1096                                 // Shortcut for :nth-*(n)
1097                                 function( elem ) {
1098                                         return !!elem.parentNode;
1099                                 } :
1101                                 function( elem, context, xml ) {
1102                                         var cache, outerCache, node, diff, nodeIndex, start,
1103                                                 dir = simple !== forward ? "nextSibling" : "previousSibling",
1104                                                 parent = elem.parentNode,
1105                                                 name = ofType && elem.nodeName.toLowerCase(),
1106                                                 useCache = !xml && !ofType;
1108                                         if ( parent ) {
1110                                                 // :(first|last|only)-(child|of-type)
1111                                                 if ( simple ) {
1112                                                         while ( dir ) {
1113                                                                 node = elem;
1114                                                                 while ( (node = node[ dir ]) ) {
1115                                                                         if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
1116                                                                                 return false;
1117                                                                         }
1118                                                                 }
1119                                                                 // Reverse direction for :only-* (if we haven't yet done so)
1120                                                                 start = dir = type === "only" && !start && "nextSibling";
1121                                                         }
1122                                                         return true;
1123                                                 }
1125                                                 start = [ forward ? parent.firstChild : parent.lastChild ];
1127                                                 // non-xml :nth-child(...) stores cache data on `parent`
1128                                                 if ( forward && useCache ) {
1129                                                         // Seek `elem` from a previously-cached index
1130                                                         outerCache = parent[ expando ] || (parent[ expando ] = {});
1131                                                         cache = outerCache[ type ] || [];
1132                                                         nodeIndex = cache[0] === dirruns && cache[1];
1133                                                         diff = cache[0] === dirruns && cache[2];
1134                                                         node = nodeIndex && parent.childNodes[ nodeIndex ];
1136                                                         while ( (node = ++nodeIndex && node && node[ dir ] ||
1138                                                                 // Fallback to seeking `elem` from the start
1139                                                                 (diff = nodeIndex = 0) || start.pop()) ) {
1141                                                                 // When found, cache indexes on `parent` and break
1142                                                                 if ( node.nodeType === 1 && ++diff && node === elem ) {
1143                                                                         outerCache[ type ] = [ dirruns, nodeIndex, diff ];
1144                                                                         break;
1145                                                                 }
1146                                                         }
1148                                                 // Use previously-cached element index if available
1149                                                 } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
1150                                                         diff = cache[1];
1152                                                 // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
1153                                                 } else {
1154                                                         // Use the same loop as above to seek `elem` from the start
1155                                                         while ( (node = ++nodeIndex && node && node[ dir ] ||
1156                                                                 (diff = nodeIndex = 0) || start.pop()) ) {
1158                                                                 if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
1159                                                                         // Cache the index of each encountered element
1160                                                                         if ( useCache ) {
1161                                                                                 (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
1162                                                                         }
1164                                                                         if ( node === elem ) {
1165                                                                                 break;
1166                                                                         }
1167                                                                 }
1168                                                         }
1169                                                 }
1171                                                 // Incorporate the offset, then check against cycle size
1172                                                 diff -= last;
1173                                                 return diff === first || ( diff % first === 0 && diff / first >= 0 );
1174                                         }
1175                                 };
1176                 },
1178                 "PSEUDO": function( pseudo, argument ) {
1179                         // pseudo-class names are case-insensitive
1180                         // http://www.w3.org/TR/selectors/#pseudo-classes
1181                         // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1182                         // Remember that setFilters inherits from pseudos
1183                         var args,
1184                                 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
1185                                         Sizzle.error( "unsupported pseudo: " + pseudo );
1187                         // The user may use createPseudo to indicate that
1188                         // arguments are needed to create the filter function
1189                         // just as Sizzle does
1190                         if ( fn[ expando ] ) {
1191                                 return fn( argument );
1192                         }
1194                         // But maintain support for old signatures
1195                         if ( fn.length > 1 ) {
1196                                 args = [ pseudo, pseudo, "", argument ];
1197                                 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
1198                                         markFunction(function( seed, matches ) {
1199                                                 var idx,
1200                                                         matched = fn( seed, argument ),
1201                                                         i = matched.length;
1202                                                 while ( i-- ) {
1203                                                         idx = indexOf.call( seed, matched[i] );
1204                                                         seed[ idx ] = !( matches[ idx ] = matched[i] );
1205                                                 }
1206                                         }) :
1207                                         function( elem ) {
1208                                                 return fn( elem, 0, args );
1209                                         };
1210                         }
1212                         return fn;
1213                 }
1214         },
1216         pseudos: {
1217                 // Potentially complex pseudos
1218                 "not": markFunction(function( selector ) {
1219                         // Trim the selector passed to compile
1220                         // to avoid treating leading and trailing
1221                         // spaces as combinators
1222                         var input = [],
1223                                 results = [],
1224                                 matcher = compile( selector.replace( rtrim, "$1" ) );
1226                         return matcher[ expando ] ?
1227                                 markFunction(function( seed, matches, context, xml ) {
1228                                         var elem,
1229                                                 unmatched = matcher( seed, null, xml, [] ),
1230                                                 i = seed.length;
1232                                         // Match elements unmatched by `matcher`
1233                                         while ( i-- ) {
1234                                                 if ( (elem = unmatched[i]) ) {
1235                                                         seed[i] = !(matches[i] = elem);
1236                                                 }
1237                                         }
1238                                 }) :
1239                                 function( elem, context, xml ) {
1240                                         input[0] = elem;
1241                                         matcher( input, null, xml, results );
1242                                         return !results.pop();
1243                                 };
1244                 }),
1246                 "has": markFunction(function( selector ) {
1247                         return function( elem ) {
1248                                 return Sizzle( selector, elem ).length > 0;
1249                         };
1250                 }),
1252                 "contains": markFunction(function( text ) {
1253                         return function( elem ) {
1254                                 return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
1255                         };
1256                 }),
1258                 // "Whether an element is represented by a :lang() selector
1259                 // is based solely on the element's language value
1260                 // being equal to the identifier C,
1261                 // or beginning with the identifier C immediately followed by "-".
1262                 // The matching of C against the element's language value is performed case-insensitively.
1263                 // The identifier C does not have to be a valid language name."
1264                 // http://www.w3.org/TR/selectors/#lang-pseudo
1265                 "lang": markFunction( function( lang ) {
1266                         // lang value must be a valid identifier
1267                         if ( !ridentifier.test(lang || "") ) {
1268                                 Sizzle.error( "unsupported lang: " + lang );
1269                         }
1270                         lang = lang.replace( runescape, funescape ).toLowerCase();
1271                         return function( elem ) {
1272                                 var elemLang;
1273                                 do {
1274                                         if ( (elemLang = documentIsHTML ?
1275                                                 elem.lang :
1276                                                 elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
1278                                                 elemLang = elemLang.toLowerCase();
1279                                                 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
1280                                         }
1281                                 } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
1282                                 return false;
1283                         };
1284                 }),
1286                 // Miscellaneous
1287                 "target": function( elem ) {
1288                         var hash = window.location && window.location.hash;
1289                         return hash && hash.slice( 1 ) === elem.id;
1290                 },
1292                 "root": function( elem ) {
1293                         return elem === docElem;
1294                 },
1296                 "focus": function( elem ) {
1297                         return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
1298                 },
1300                 // Boolean properties
1301                 "enabled": function( elem ) {
1302                         return elem.disabled === false;
1303                 },
1305                 "disabled": function( elem ) {
1306                         return elem.disabled === true;
1307                 },
1309                 "checked": function( elem ) {
1310                         // In CSS3, :checked should return both checked and selected elements
1311                         // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1312                         var nodeName = elem.nodeName.toLowerCase();
1313                         return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
1314                 },
1316                 "selected": function( elem ) {
1317                         // Accessing this property makes selected-by-default
1318                         // options in Safari work properly
1319                         if ( elem.parentNode ) {
1320                                 elem.parentNode.selectedIndex;
1321                         }
1323                         return elem.selected === true;
1324                 },
1326                 // Contents
1327                 "empty": function( elem ) {
1328                         // http://www.w3.org/TR/selectors/#empty-pseudo
1329                         // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
1330                         //   but not by others (comment: 8; processing instruction: 7; etc.)
1331                         // nodeType < 6 works because attributes (2) do not appear as children
1332                         for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1333                                 if ( elem.nodeType < 6 ) {
1334                                         return false;
1335                                 }
1336                         }
1337                         return true;
1338                 },
1340                 "parent": function( elem ) {
1341                         return !Expr.pseudos["empty"]( elem );
1342                 },
1344                 // Element/input types
1345                 "header": function( elem ) {
1346                         return rheader.test( elem.nodeName );
1347                 },
1349                 "input": function( elem ) {
1350                         return rinputs.test( elem.nodeName );
1351                 },
1353                 "button": function( elem ) {
1354                         var name = elem.nodeName.toLowerCase();
1355                         return name === "input" && elem.type === "button" || name === "button";
1356                 },
1358                 "text": function( elem ) {
1359                         var attr;
1360                         return elem.nodeName.toLowerCase() === "input" &&
1361                                 elem.type === "text" &&
1363                                 // Support: IE<8
1364                                 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
1365                                 ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
1366                 },
1368                 // Position-in-collection
1369                 "first": createPositionalPseudo(function() {
1370                         return [ 0 ];
1371                 }),
1373                 "last": createPositionalPseudo(function( matchIndexes, length ) {
1374                         return [ length - 1 ];
1375                 }),
1377                 "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
1378                         return [ argument < 0 ? argument + length : argument ];
1379                 }),
1381                 "even": createPositionalPseudo(function( matchIndexes, length ) {
1382                         var i = 0;
1383                         for ( ; i < length; i += 2 ) {
1384                                 matchIndexes.push( i );
1385                         }
1386                         return matchIndexes;
1387                 }),
1389                 "odd": createPositionalPseudo(function( matchIndexes, length ) {
1390                         var i = 1;
1391                         for ( ; i < length; i += 2 ) {
1392                                 matchIndexes.push( i );
1393                         }
1394                         return matchIndexes;
1395                 }),
1397                 "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
1398                         var i = argument < 0 ? argument + length : argument;
1399                         for ( ; --i >= 0; ) {
1400                                 matchIndexes.push( i );
1401                         }
1402                         return matchIndexes;
1403                 }),
1405                 "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
1406                         var i = argument < 0 ? argument + length : argument;
1407                         for ( ; ++i < length; ) {
1408                                 matchIndexes.push( i );
1409                         }
1410                         return matchIndexes;
1411                 })
1412         }
1415 Expr.pseudos["nth"] = Expr.pseudos["eq"];
1417 // Add button/input type pseudos
1418 for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
1419         Expr.pseudos[ i ] = createInputPseudo( i );
1421 for ( i in { submit: true, reset: true } ) {
1422         Expr.pseudos[ i ] = createButtonPseudo( i );
1425 // Easy API for creating new setFilters
1426 function setFilters() {}
1427 setFilters.prototype = Expr.filters = Expr.pseudos;
1428 Expr.setFilters = new setFilters();
1430 function tokenize( selector, parseOnly ) {
1431         var matched, match, tokens, type,
1432                 soFar, groups, preFilters,
1433                 cached = tokenCache[ selector + " " ];
1435         if ( cached ) {
1436                 return parseOnly ? 0 : cached.slice( 0 );
1437         }
1439         soFar = selector;
1440         groups = [];
1441         preFilters = Expr.preFilter;
1443         while ( soFar ) {
1445                 // Comma and first run
1446                 if ( !matched || (match = rcomma.exec( soFar )) ) {
1447                         if ( match ) {
1448                                 // Don't consume trailing commas as valid
1449                                 soFar = soFar.slice( match[0].length ) || soFar;
1450                         }
1451                         groups.push( (tokens = []) );
1452                 }
1454                 matched = false;
1456                 // Combinators
1457                 if ( (match = rcombinators.exec( soFar )) ) {
1458                         matched = match.shift();
1459                         tokens.push({
1460                                 value: matched,
1461                                 // Cast descendant combinators to space
1462                                 type: match[0].replace( rtrim, " " )
1463                         });
1464                         soFar = soFar.slice( matched.length );
1465                 }
1467                 // Filters
1468                 for ( type in Expr.filter ) {
1469                         if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
1470                                 (match = preFilters[ type ]( match ))) ) {
1471                                 matched = match.shift();
1472                                 tokens.push({
1473                                         value: matched,
1474                                         type: type,
1475                                         matches: match
1476                                 });
1477                                 soFar = soFar.slice( matched.length );
1478                         }
1479                 }
1481                 if ( !matched ) {
1482                         break;
1483                 }
1484         }
1486         // Return the length of the invalid excess
1487         // if we're just parsing
1488         // Otherwise, throw an error or return tokens
1489         return parseOnly ?
1490                 soFar.length :
1491                 soFar ?
1492                         Sizzle.error( selector ) :
1493                         // Cache the tokens
1494                         tokenCache( selector, groups ).slice( 0 );
1497 function toSelector( tokens ) {
1498         var i = 0,
1499                 len = tokens.length,
1500                 selector = "";
1501         for ( ; i < len; i++ ) {
1502                 selector += tokens[i].value;
1503         }
1504         return selector;
1507 function addCombinator( matcher, combinator, base ) {
1508         var dir = combinator.dir,
1509                 checkNonElements = base && dir === "parentNode",
1510                 doneName = done++;
1512         return combinator.first ?
1513                 // Check against closest ancestor/preceding element
1514                 function( elem, context, xml ) {
1515                         while ( (elem = elem[ dir ]) ) {
1516                                 if ( elem.nodeType === 1 || checkNonElements ) {
1517                                         return matcher( elem, context, xml );
1518                                 }
1519                         }
1520                 } :
1522                 // Check against all ancestor/preceding elements
1523                 function( elem, context, xml ) {
1524                         var oldCache, outerCache,
1525                                 newCache = [ dirruns, doneName ];
1527                         // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
1528                         if ( xml ) {
1529                                 while ( (elem = elem[ dir ]) ) {
1530                                         if ( elem.nodeType === 1 || checkNonElements ) {
1531                                                 if ( matcher( elem, context, xml ) ) {
1532                                                         return true;
1533                                                 }
1534                                         }
1535                                 }
1536                         } else {
1537                                 while ( (elem = elem[ dir ]) ) {
1538                                         if ( elem.nodeType === 1 || checkNonElements ) {
1539                                                 outerCache = elem[ expando ] || (elem[ expando ] = {});
1540                                                 if ( (oldCache = outerCache[ dir ]) &&
1541                                                         oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
1543                                                         // Assign to newCache so results back-propagate to previous elements
1544                                                         return (newCache[ 2 ] = oldCache[ 2 ]);
1545                                                 } else {
1546                                                         // Reuse newcache so results back-propagate to previous elements
1547                                                         outerCache[ dir ] = newCache;
1549                                                         // A match means we're done; a fail means we have to keep checking
1550                                                         if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
1551                                                                 return true;
1552                                                         }
1553                                                 }
1554                                         }
1555                                 }
1556                         }
1557                 };
1560 function elementMatcher( matchers ) {
1561         return matchers.length > 1 ?
1562                 function( elem, context, xml ) {
1563                         var i = matchers.length;
1564                         while ( i-- ) {
1565                                 if ( !matchers[i]( elem, context, xml ) ) {
1566                                         return false;
1567                                 }
1568                         }
1569                         return true;
1570                 } :
1571                 matchers[0];
1574 function multipleContexts( selector, contexts, results ) {
1575         var i = 0,
1576                 len = contexts.length;
1577         for ( ; i < len; i++ ) {
1578                 Sizzle( selector, contexts[i], results );
1579         }
1580         return results;
1583 function condense( unmatched, map, filter, context, xml ) {
1584         var elem,
1585                 newUnmatched = [],
1586                 i = 0,
1587                 len = unmatched.length,
1588                 mapped = map != null;
1590         for ( ; i < len; i++ ) {
1591                 if ( (elem = unmatched[i]) ) {
1592                         if ( !filter || filter( elem, context, xml ) ) {
1593                                 newUnmatched.push( elem );
1594                                 if ( mapped ) {
1595                                         map.push( i );
1596                                 }
1597                         }
1598                 }
1599         }
1601         return newUnmatched;
1604 function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
1605         if ( postFilter && !postFilter[ expando ] ) {
1606                 postFilter = setMatcher( postFilter );
1607         }
1608         if ( postFinder && !postFinder[ expando ] ) {
1609                 postFinder = setMatcher( postFinder, postSelector );
1610         }
1611         return markFunction(function( seed, results, context, xml ) {
1612                 var temp, i, elem,
1613                         preMap = [],
1614                         postMap = [],
1615                         preexisting = results.length,
1617                         // Get initial elements from seed or context
1618                         elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
1620                         // Prefilter to get matcher input, preserving a map for seed-results synchronization
1621                         matcherIn = preFilter && ( seed || !selector ) ?
1622                                 condense( elems, preMap, preFilter, context, xml ) :
1623                                 elems,
1625                         matcherOut = matcher ?
1626                                 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
1627                                 postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
1629                                         // ...intermediate processing is necessary
1630                                         [] :
1632                                         // ...otherwise use results directly
1633                                         results :
1634                                 matcherIn;
1636                 // Find primary matches
1637                 if ( matcher ) {
1638                         matcher( matcherIn, matcherOut, context, xml );
1639                 }
1641                 // Apply postFilter
1642                 if ( postFilter ) {
1643                         temp = condense( matcherOut, postMap );
1644                         postFilter( temp, [], context, xml );
1646                         // Un-match failing elements by moving them back to matcherIn
1647                         i = temp.length;
1648                         while ( i-- ) {
1649                                 if ( (elem = temp[i]) ) {
1650                                         matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
1651                                 }
1652                         }
1653                 }
1655                 if ( seed ) {
1656                         if ( postFinder || preFilter ) {
1657                                 if ( postFinder ) {
1658                                         // Get the final matcherOut by condensing this intermediate into postFinder contexts
1659                                         temp = [];
1660                                         i = matcherOut.length;
1661                                         while ( i-- ) {
1662                                                 if ( (elem = matcherOut[i]) ) {
1663                                                         // Restore matcherIn since elem is not yet a final match
1664                                                         temp.push( (matcherIn[i] = elem) );
1665                                                 }
1666                                         }
1667                                         postFinder( null, (matcherOut = []), temp, xml );
1668                                 }
1670                                 // Move matched elements from seed to results to keep them synchronized
1671                                 i = matcherOut.length;
1672                                 while ( i-- ) {
1673                                         if ( (elem = matcherOut[i]) &&
1674                                                 (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
1676                                                 seed[temp] = !(results[temp] = elem);
1677                                         }
1678                                 }
1679                         }
1681                 // Add elements to results, through postFinder if defined
1682                 } else {
1683                         matcherOut = condense(
1684                                 matcherOut === results ?
1685                                         matcherOut.splice( preexisting, matcherOut.length ) :
1686                                         matcherOut
1687                         );
1688                         if ( postFinder ) {
1689                                 postFinder( null, results, matcherOut, xml );
1690                         } else {
1691                                 push.apply( results, matcherOut );
1692                         }
1693                 }
1694         });
1697 function matcherFromTokens( tokens ) {
1698         var checkContext, matcher, j,
1699                 len = tokens.length,
1700                 leadingRelative = Expr.relative[ tokens[0].type ],
1701                 implicitRelative = leadingRelative || Expr.relative[" "],
1702                 i = leadingRelative ? 1 : 0,
1704                 // The foundational matcher ensures that elements are reachable from top-level context(s)
1705                 matchContext = addCombinator( function( elem ) {
1706                         return elem === checkContext;
1707                 }, implicitRelative, true ),
1708                 matchAnyContext = addCombinator( function( elem ) {
1709                         return indexOf.call( checkContext, elem ) > -1;
1710                 }, implicitRelative, true ),
1711                 matchers = [ function( elem, context, xml ) {
1712                         return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
1713                                 (checkContext = context).nodeType ?
1714                                         matchContext( elem, context, xml ) :
1715                                         matchAnyContext( elem, context, xml ) );
1716                 } ];
1718         for ( ; i < len; i++ ) {
1719                 if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
1720                         matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
1721                 } else {
1722                         matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
1724                         // Return special upon seeing a positional matcher
1725                         if ( matcher[ expando ] ) {
1726                                 // Find the next relative operator (if any) for proper handling
1727                                 j = ++i;
1728                                 for ( ; j < len; j++ ) {
1729                                         if ( Expr.relative[ tokens[j].type ] ) {
1730                                                 break;
1731                                         }
1732                                 }
1733                                 return setMatcher(
1734                                         i > 1 && elementMatcher( matchers ),
1735                                         i > 1 && toSelector(
1736                                                 // If the preceding token was a descendant combinator, insert an implicit any-element `*`
1737                                                 tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
1738                                         ).replace( rtrim, "$1" ),
1739                                         matcher,
1740                                         i < j && matcherFromTokens( tokens.slice( i, j ) ),
1741                                         j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
1742                                         j < len && toSelector( tokens )
1743                                 );
1744                         }
1745                         matchers.push( matcher );
1746                 }
1747         }
1749         return elementMatcher( matchers );
1752 function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
1753         var bySet = setMatchers.length > 0,
1754                 byElement = elementMatchers.length > 0,
1755                 superMatcher = function( seed, context, xml, results, outermost ) {
1756                         var elem, j, matcher,
1757                                 matchedCount = 0,
1758                                 i = "0",
1759                                 unmatched = seed && [],
1760                                 setMatched = [],
1761                                 contextBackup = outermostContext,
1762                                 // We must always have either seed elements or outermost context
1763                                 elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
1764                                 // Use integer dirruns iff this is the outermost matcher
1765                                 dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
1766                                 len = elems.length;
1768                         if ( outermost ) {
1769                                 outermostContext = context !== document && context;
1770                         }
1772                         // Add elements passing elementMatchers directly to results
1773                         // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
1774                         // Support: IE<9, Safari
1775                         // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
1776                         for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
1777                                 if ( byElement && elem ) {
1778                                         j = 0;
1779                                         while ( (matcher = elementMatchers[j++]) ) {
1780                                                 if ( matcher( elem, context, xml ) ) {
1781                                                         results.push( elem );
1782                                                         break;
1783                                                 }
1784                                         }
1785                                         if ( outermost ) {
1786                                                 dirruns = dirrunsUnique;
1787                                         }
1788                                 }
1790                                 // Track unmatched elements for set filters
1791                                 if ( bySet ) {
1792                                         // They will have gone through all possible matchers
1793                                         if ( (elem = !matcher && elem) ) {
1794                                                 matchedCount--;
1795                                         }
1797                                         // Lengthen the array for every element, matched or not
1798                                         if ( seed ) {
1799                                                 unmatched.push( elem );
1800                                         }
1801                                 }
1802                         }
1804                         // Apply set filters to unmatched elements
1805                         matchedCount += i;
1806                         if ( bySet && i !== matchedCount ) {
1807                                 j = 0;
1808                                 while ( (matcher = setMatchers[j++]) ) {
1809                                         matcher( unmatched, setMatched, context, xml );
1810                                 }
1812                                 if ( seed ) {
1813                                         // Reintegrate element matches to eliminate the need for sorting
1814                                         if ( matchedCount > 0 ) {
1815                                                 while ( i-- ) {
1816                                                         if ( !(unmatched[i] || setMatched[i]) ) {
1817                                                                 setMatched[i] = pop.call( results );
1818                                                         }
1819                                                 }
1820                                         }
1822                                         // Discard index placeholder values to get only actual matches
1823                                         setMatched = condense( setMatched );
1824                                 }
1826                                 // Add matches to results
1827                                 push.apply( results, setMatched );
1829                                 // Seedless set matches succeeding multiple successful matchers stipulate sorting
1830                                 if ( outermost && !seed && setMatched.length > 0 &&
1831                                         ( matchedCount + setMatchers.length ) > 1 ) {
1833                                         Sizzle.uniqueSort( results );
1834                                 }
1835                         }
1837                         // Override manipulation of globals by nested matchers
1838                         if ( outermost ) {
1839                                 dirruns = dirrunsUnique;
1840                                 outermostContext = contextBackup;
1841                         }
1843                         return unmatched;
1844                 };
1846         return bySet ?
1847                 markFunction( superMatcher ) :
1848                 superMatcher;
1851 compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
1852         var i,
1853                 setMatchers = [],
1854                 elementMatchers = [],
1855                 cached = compilerCache[ selector + " " ];
1857         if ( !cached ) {
1858                 // Generate a function of recursive functions that can be used to check each element
1859                 if ( !match ) {
1860                         match = tokenize( selector );
1861                 }
1862                 i = match.length;
1863                 while ( i-- ) {
1864                         cached = matcherFromTokens( match[i] );
1865                         if ( cached[ expando ] ) {
1866                                 setMatchers.push( cached );
1867                         } else {
1868                                 elementMatchers.push( cached );
1869                         }
1870                 }
1872                 // Cache the compiled function
1873                 cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
1875                 // Save selector and tokenization
1876                 cached.selector = selector;
1877         }
1878         return cached;
1882  * A low-level selection function that works with Sizzle's compiled
1883  *  selector functions
1884  * @param {String|Function} selector A selector or a pre-compiled
1885  *  selector function built with Sizzle.compile
1886  * @param {Element} context
1887  * @param {Array} [results]
1888  * @param {Array} [seed] A set of elements to match against
1889  */
1890 select = Sizzle.select = function( selector, context, results, seed ) {
1891         var i, tokens, token, type, find,
1892                 compiled = typeof selector === "function" && selector,
1893                 match = !seed && tokenize( (selector = compiled.selector || selector) );
1895         results = results || [];
1897         // Try to minimize operations if there is no seed and only one group
1898         if ( match.length === 1 ) {
1900                 // Take a shortcut and set the context if the root selector is an ID
1901                 tokens = match[0] = match[0].slice( 0 );
1902                 if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
1903                                 support.getById && context.nodeType === 9 && documentIsHTML &&
1904                                 Expr.relative[ tokens[1].type ] ) {
1906                         context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
1907                         if ( !context ) {
1908                                 return results;
1910                         // Precompiled matchers will still verify ancestry, so step up a level
1911                         } else if ( compiled ) {
1912                                 context = context.parentNode;
1913                         }
1915                         selector = selector.slice( tokens.shift().value.length );
1916                 }
1918                 // Fetch a seed set for right-to-left matching
1919                 i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
1920                 while ( i-- ) {
1921                         token = tokens[i];
1923                         // Abort if we hit a combinator
1924                         if ( Expr.relative[ (type = token.type) ] ) {
1925                                 break;
1926                         }
1927                         if ( (find = Expr.find[ type ]) ) {
1928                                 // Search, expanding context for leading sibling combinators
1929                                 if ( (seed = find(
1930                                         token.matches[0].replace( runescape, funescape ),
1931                                         rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
1932                                 )) ) {
1934                                         // If seed is empty or no tokens remain, we can return early
1935                                         tokens.splice( i, 1 );
1936                                         selector = seed.length && toSelector( tokens );
1937                                         if ( !selector ) {
1938                                                 push.apply( results, seed );
1939                                                 return results;
1940                                         }
1942                                         break;
1943                                 }
1944                         }
1945                 }
1946         }
1948         // Compile and execute a filtering function if one is not provided
1949         // Provide `match` to avoid retokenization if we modified the selector above
1950         ( compiled || compile( selector, match ) )(
1951                 seed,
1952                 context,
1953                 !documentIsHTML,
1954                 results,
1955                 rsibling.test( selector ) && testContext( context.parentNode ) || context
1956         );
1957         return results;
1960 // One-time assignments
1962 // Sort stability
1963 support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
1965 // Support: Chrome<14
1966 // Always assume duplicates if they aren't passed to the comparison function
1967 support.detectDuplicates = !!hasDuplicate;
1969 // Initialize against the default document
1970 setDocument();
1972 // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
1973 // Detached nodes confoundingly follow *each other*
1974 support.sortDetached = assert(function( div1 ) {
1975         // Should return 1, but returns 4 (following)
1976         return div1.compareDocumentPosition( document.createElement("div") ) & 1;
1979 // Support: IE<8
1980 // Prevent attribute/property "interpolation"
1981 // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
1982 if ( !assert(function( div ) {
1983         div.innerHTML = "<a href='#'></a>";
1984         return div.firstChild.getAttribute("href") === "#" ;
1985 }) ) {
1986         addHandle( "type|href|height|width", function( elem, name, isXML ) {
1987                 if ( !isXML ) {
1988                         return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
1989                 }
1990         });
1993 // Support: IE<9
1994 // Use defaultValue in place of getAttribute("value")
1995 if ( !support.attributes || !assert(function( div ) {
1996         div.innerHTML = "<input/>";
1997         div.firstChild.setAttribute( "value", "" );
1998         return div.firstChild.getAttribute( "value" ) === "";
1999 }) ) {
2000         addHandle( "value", function( elem, name, isXML ) {
2001                 if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
2002                         return elem.defaultValue;
2003                 }
2004         });
2007 // Support: IE<9
2008 // Use getAttributeNode to fetch booleans when getAttribute lies
2009 if ( !assert(function( div ) {
2010         return div.getAttribute("disabled") == null;
2011 }) ) {
2012         addHandle( booleans, function( elem, name, isXML ) {
2013                 var val;
2014                 if ( !isXML ) {
2015                         return elem[ name ] === true ? name.toLowerCase() :
2016                                         (val = elem.getAttributeNode( name )) && val.specified ?
2017                                         val.value :
2018                                 null;
2019                 }
2020         });
2023 // EXPOSE
2024 if ( typeof define === "function" && define.amd ) {
2025         define(function() { return Sizzle; });
2026 // Sizzle requires that there be a global window in Common-JS like environments
2027 } else if ( typeof module !== "undefined" && module.exports ) {
2028         module.exports = Sizzle;
2029 } else {
2030         window.Sizzle = Sizzle;
2032 // EXPOSE
2034 })( window );