2 * Sizzle CSS Selector Engine - v1.0
3 * Copyright 2009, The Dojo Foundation
4 * Released under the MIT, BSD, and GPL Licenses.
5 * More information: http://sizzlejs.com/
9 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,
11 toString = Object.prototype.toString,
14 var Sizzle = function(selector, context, results, seed) {
15 results = results || [];
16 var origContext = context = context || document;
18 if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
22 if ( !selector || typeof selector !== "string" ) {
26 var parts = [], m, set, checkSet, check, mode, extra, prune = true, contextXML = isXML(context);
28 // Reset the position of the chunker regexp (start from head)
29 chunker.lastIndex = 0;
31 while ( (m = chunker.exec(selector)) !== null ) {
35 extra = RegExp.rightContext;
40 if ( parts.length > 1 && origPOS.exec( selector ) ) {
41 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
42 set = posProcess( parts[0] + parts[1], context );
44 set = Expr.relative[ parts[0] ] ?
46 Sizzle( parts.shift(), context );
48 while ( parts.length ) {
49 selector = parts.shift();
51 if ( Expr.relative[ selector ] )
52 selector += parts.shift();
54 set = posProcess( selector, set );
58 // Take a shortcut and set the context if the root selector is an ID
59 // (but not if it'll be faster if the inner selector is an ID)
60 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
61 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
62 var ret = Sizzle.find( parts.shift(), context, contextXML );
63 context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
68 { expr: parts.pop(), set: makeArray(seed) } :
69 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
70 set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
72 if ( parts.length > 0 ) {
73 checkSet = makeArray(set);
78 while ( parts.length ) {
79 var cur = parts.pop(), pop = cur;
81 if ( !Expr.relative[ cur ] ) {
91 Expr.relative[ cur ]( checkSet, pop, contextXML );
94 checkSet = parts = [];
103 throw "Syntax error, unrecognized expression: " + (cur || selector);
106 if ( toString.call(checkSet) === "[object Array]" ) {
108 results.push.apply( results, checkSet );
109 } else if ( context && context.nodeType === 1 ) {
110 for ( var i = 0; checkSet[i] != null; i++ ) {
111 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
112 results.push( set[i] );
116 for ( var i = 0; checkSet[i] != null; i++ ) {
117 if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
118 results.push( set[i] );
123 makeArray( checkSet, results );
127 Sizzle( extra, origContext, results, seed );
128 Sizzle.uniqueSort( results );
134 Sizzle.uniqueSort = function(results){
136 hasDuplicate = false;
137 results.sort(sortOrder);
139 if ( hasDuplicate ) {
140 for ( var i = 1; i < results.length; i++ ) {
141 if ( results[i] === results[i-1] ) {
142 results.splice(i--, 1);
151 Sizzle.matches = function(expr, set){
152 return Sizzle(expr, null, null, set);
155 Sizzle.find = function(expr, context, isXML){
162 for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
163 var type = Expr.order[i], match;
165 if ( (match = Expr.match[ type ].exec( expr )) ) {
166 var left = RegExp.leftContext;
168 if ( left.substr( left.length - 1 ) !== "\\" ) {
169 match[1] = (match[1] || "").replace(/\\/g, "");
170 set = Expr.find[ type ]( match, context, isXML );
172 expr = expr.replace( Expr.match[ type ], "" );
180 set = context.getElementsByTagName("*");
183 return {set: set, expr: expr};
186 Sizzle.filter = function(expr, set, inplace, not){
187 var old = expr, result = [], curLoop = set, match, anyFound,
188 isXMLFilter = set && set[0] && isXML(set[0]);
190 while ( expr && set.length ) {
191 for ( var type in Expr.filter ) {
192 if ( (match = Expr.match[ type ].exec( expr )) != null ) {
193 var filter = Expr.filter[ type ], found, item;
196 if ( curLoop == result ) {
200 if ( Expr.preFilter[ type ] ) {
201 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
204 anyFound = found = true;
205 } else if ( match === true ) {
211 for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
213 found = filter( item, match, i, curLoop );
214 var pass = not ^ !!found;
216 if ( inplace && found != null ) {
230 if ( found !== undefined ) {
235 expr = expr.replace( Expr.match[ type ], "" );
246 // Improper expression
248 if ( anyFound == null ) {
249 throw "Syntax error, unrecognized expression: " + expr;
261 var Expr = Sizzle.selectors = {
262 order: [ "ID", "NAME", "TAG" ],
264 ID: /#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
265 CLASS: /\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
266 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,
267 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
268 TAG: /^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,
269 CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
270 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
271 PSEUDO: /:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
274 "class": "className",
278 href: function(elem){
279 return elem.getAttribute("href");
283 "+": function(checkSet, part, isXML){
284 var isPartStr = typeof part === "string",
285 isTag = isPartStr && !/\W/.test(part),
286 isPartStrNotTag = isPartStr && !isTag;
288 if ( isTag && !isXML ) {
289 part = part.toUpperCase();
292 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
293 if ( (elem = checkSet[i]) ) {
294 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
296 checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
302 if ( isPartStrNotTag ) {
303 Sizzle.filter( part, checkSet, true );
306 ">": function(checkSet, part, isXML){
307 var isPartStr = typeof part === "string";
309 if ( isPartStr && !/\W/.test(part) ) {
310 part = isXML ? part : part.toUpperCase();
312 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
313 var elem = checkSet[i];
315 var parent = elem.parentNode;
316 checkSet[i] = parent.nodeName === part ? parent : false;
320 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
321 var elem = checkSet[i];
323 checkSet[i] = isPartStr ?
325 elem.parentNode === part;
330 Sizzle.filter( part, checkSet, true );
334 "": function(checkSet, part, isXML){
335 var doneName = done++, checkFn = dirCheck;
337 if ( !/\W/.test(part) ) {
338 var nodeCheck = part = isXML ? part : part.toUpperCase();
339 checkFn = dirNodeCheck;
342 checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
344 "~": function(checkSet, part, isXML){
345 var doneName = done++, checkFn = dirCheck;
347 if ( typeof part === "string" && !/\W/.test(part) ) {
348 var nodeCheck = part = isXML ? part : part.toUpperCase();
349 checkFn = dirNodeCheck;
352 checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
356 ID: function(match, context, isXML){
357 if ( typeof context.getElementById !== "undefined" && !isXML ) {
358 var m = context.getElementById(match[1]);
362 NAME: function(match, context, isXML){
363 if ( typeof context.getElementsByName !== "undefined" ) {
364 var ret = [], results = context.getElementsByName(match[1]);
366 for ( var i = 0, l = results.length; i < l; i++ ) {
367 if ( results[i].getAttribute("name") === match[1] ) {
368 ret.push( results[i] );
372 return ret.length === 0 ? null : ret;
375 TAG: function(match, context){
376 return context.getElementsByTagName(match[1]);
380 CLASS: function(match, curLoop, inplace, result, not, isXML){
381 match = " " + match[1].replace(/\\/g, "") + " ";
387 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
389 if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
392 } else if ( inplace ) {
401 return match[1].replace(/\\/g, "");
403 TAG: function(match, curLoop){
404 for ( var i = 0; curLoop[i] === false; i++ ){}
405 return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
407 CHILD: function(match){
408 if ( match[1] == "nth" ) {
409 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
410 var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
411 match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
412 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
414 // calculate the numbers (first)n+(last) including if they are negative
415 match[2] = (test[1] + (test[2] || 1)) - 0;
416 match[3] = test[3] - 0;
419 // TODO: Move to normal caching system
424 ATTR: function(match, curLoop, inplace, result, not, isXML){
425 var name = match[1].replace(/\\/g, "");
427 if ( !isXML && Expr.attrMap[name] ) {
428 match[1] = Expr.attrMap[name];
431 if ( match[2] === "~=" ) {
432 match[4] = " " + match[4] + " ";
437 PSEUDO: function(match, curLoop, inplace, result, not){
438 if ( match[1] === "not" ) {
439 // If we're dealing with a complex expression, or a simple one
440 if ( chunker.exec(match[3]).length > 1 || /^\w/.test(match[3]) ) {
441 match[3] = Sizzle(match[3], null, null, curLoop);
443 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
445 result.push.apply( result, ret );
449 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
455 POS: function(match){
456 match.unshift( true );
461 enabled: function(elem){
462 return elem.disabled === false && elem.type !== "hidden";
464 disabled: function(elem){
465 return elem.disabled === true;
467 checked: function(elem){
468 return elem.checked === true;
470 selected: function(elem){
471 // Accessing this property makes selected-by-default
472 // options in Safari work properly
473 elem.parentNode.selectedIndex;
474 return elem.selected === true;
476 parent: function(elem){
477 return !!elem.firstChild;
479 empty: function(elem){
480 return !elem.firstChild;
482 has: function(elem, i, match){
483 return !!Sizzle( match[3], elem ).length;
485 header: function(elem){
486 return /h\d/i.test( elem.nodeName );
488 text: function(elem){
489 return "text" === elem.type;
491 radio: function(elem){
492 return "radio" === elem.type;
494 checkbox: function(elem){
495 return "checkbox" === elem.type;
497 file: function(elem){
498 return "file" === elem.type;
500 password: function(elem){
501 return "password" === elem.type;
503 submit: function(elem){
504 return "submit" === elem.type;
506 image: function(elem){
507 return "image" === elem.type;
509 reset: function(elem){
510 return "reset" === elem.type;
512 button: function(elem){
513 return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
515 input: function(elem){
516 return /input|select|textarea|button/i.test(elem.nodeName);
520 first: function(elem, i){
523 last: function(elem, i, match, array){
524 return i === array.length - 1;
526 even: function(elem, i){
529 odd: function(elem, i){
532 lt: function(elem, i, match){
533 return i < match[3] - 0;
535 gt: function(elem, i, match){
536 return i > match[3] - 0;
538 nth: function(elem, i, match){
539 return match[3] - 0 == i;
541 eq: function(elem, i, match){
542 return match[3] - 0 == i;
546 PSEUDO: function(elem, match, i, array){
547 var name = match[1], filter = Expr.filters[ name ];
550 return filter( elem, i, match, array );
551 } else if ( name === "contains" ) {
552 return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
553 } else if ( name === "not" ) {
556 for ( var i = 0, l = not.length; i < l; i++ ) {
557 if ( not[i] === elem ) {
565 CHILD: function(elem, match){
566 var type = match[1], node = elem;
570 while ( (node = node.previousSibling) ) {
571 if ( node.nodeType === 1 ) return false;
573 if ( type == 'first') return true;
576 while ( (node = node.nextSibling) ) {
577 if ( node.nodeType === 1 ) return false;
581 var first = match[2], last = match[3];
583 if ( first == 1 && last == 0 ) {
587 var doneName = match[0],
588 parent = elem.parentNode;
590 if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
592 for ( node = parent.firstChild; node; node = node.nextSibling ) {
593 if ( node.nodeType === 1 ) {
594 node.nodeIndex = ++count;
597 parent.sizcache = doneName;
600 var diff = elem.nodeIndex - last;
604 return ( diff % first == 0 && diff / first >= 0 );
608 ID: function(elem, match){
609 return elem.nodeType === 1 && elem.getAttribute("id") === match;
611 TAG: function(elem, match){
612 return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
614 CLASS: function(elem, match){
615 return (" " + (elem.className || elem.getAttribute("class")) + " ")
616 .indexOf( match ) > -1;
618 ATTR: function(elem, match){
620 result = Expr.attrHandle[ name ] ?
621 Expr.attrHandle[ name ]( elem ) :
622 elem[ name ] != null ?
624 elem.getAttribute( name ),
629 return result == null ?
634 value.indexOf(check) >= 0 :
636 (" " + value + " ").indexOf(check) >= 0 :
638 value && result !== false :
642 value.indexOf(check) === 0 :
644 value.substr(value.length - check.length) === check :
646 value === check || value.substr(0, check.length + 1) === check + "-" :
649 POS: function(elem, match, i, array){
650 var name = match[2], filter = Expr.setFilters[ name ];
653 return filter( elem, i, match, array );
659 var origPOS = Expr.match.POS;
661 for ( var type in Expr.match ) {
662 Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
665 var makeArray = function(array, results) {
666 array = Array.prototype.slice.call( array, 0 );
669 results.push.apply( results, array );
676 // Perform a simple check to determine if the browser is capable of
677 // converting a NodeList to an array using builtin methods.
679 Array.prototype.slice.call( document.documentElement.childNodes, 0 );
681 // Provide a fallback method if it does not work
683 makeArray = function(array, results) {
684 var ret = results || [];
686 if ( toString.call(array) === "[object Array]" ) {
687 Array.prototype.push.apply( ret, array );
689 if ( typeof array.length === "number" ) {
690 for ( var i = 0, l = array.length; i < l; i++ ) {
691 ret.push( array[i] );
694 for ( var i = 0; array[i]; i++ ) {
695 ret.push( array[i] );
706 if ( document.documentElement.compareDocumentPosition ) {
707 sortOrder = function( a, b ) {
708 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
715 var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
721 } else if ( "sourceIndex" in document.documentElement ) {
722 sortOrder = function( a, b ) {
723 if ( !a.sourceIndex || !b.sourceIndex ) {
730 var ret = a.sourceIndex - b.sourceIndex;
736 } else if ( document.createRange ) {
737 sortOrder = function( a, b ) {
738 if ( !a.ownerDocument || !b.ownerDocument ) {
745 var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
746 aRange.selectNode(a);
747 aRange.collapse(true);
748 bRange.selectNode(b);
749 bRange.collapse(true);
750 var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
758 // Check to see if the browser returns elements by name when
759 // querying by getElementById (and provide a workaround)
761 // We're going to inject a fake input element with a specified name
762 var form = document.createElement("div"),
763 id = "script" + (new Date).getTime();
764 form.innerHTML = "<a name='" + id + "'/>";
766 // Inject it into the root element, check its status, and remove it quickly
767 var root = document.documentElement;
768 root.insertBefore( form, root.firstChild );
770 // The workaround has to do additional checks after a getElementById
771 // Which slows things down for other browsers (hence the branching)
772 if ( !!document.getElementById( id ) ) {
773 Expr.find.ID = function(match, context, isXML){
774 if ( typeof context.getElementById !== "undefined" && !isXML ) {
775 var m = context.getElementById(match[1]);
776 return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
780 Expr.filter.ID = function(elem, match){
781 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
782 return elem.nodeType === 1 && node && node.nodeValue === match;
786 root.removeChild( form );
787 root = form = null; // release memory in IE
791 // Check to see if the browser returns only elements
792 // when doing getElementsByTagName("*")
794 // Create a fake element
795 var div = document.createElement("div");
796 div.appendChild( document.createComment("") );
798 // Make sure no comments are found
799 if ( div.getElementsByTagName("*").length > 0 ) {
800 Expr.find.TAG = function(match, context){
801 var results = context.getElementsByTagName(match[1]);
803 // Filter out possible comments
804 if ( match[1] === "*" ) {
807 for ( var i = 0; results[i]; i++ ) {
808 if ( results[i].nodeType === 1 ) {
809 tmp.push( results[i] );
820 // Check to see if an attribute returns normalized href attributes
821 div.innerHTML = "<a href='#'></a>";
822 if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
823 div.firstChild.getAttribute("href") !== "#" ) {
824 Expr.attrHandle.href = function(elem){
825 return elem.getAttribute("href", 2);
829 div = null; // release memory in IE
832 if ( document.querySelectorAll ) (function(){
833 var oldSizzle = Sizzle, div = document.createElement("div");
834 div.innerHTML = "<p class='TEST'></p>";
836 // Safari can't handle uppercase or unicode characters when
838 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
842 Sizzle = function(query, context, extra, seed){
843 context = context || document;
845 // Only use querySelectorAll on non-XML documents
846 // (ID selectors don't work in non-HTML documents)
847 if ( !seed && context.nodeType === 9 && !isXML(context) ) {
849 return makeArray( context.querySelectorAll(query), extra );
853 return oldSizzle(query, context, extra, seed);
856 for ( var prop in oldSizzle ) {
857 Sizzle[ prop ] = oldSizzle[ prop ];
860 div = null; // release memory in IE
863 if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
864 var div = document.createElement("div");
865 div.innerHTML = "<div class='test e'></div><div class='test'></div>";
867 // Opera can't find a second classname (in 9.6)
868 if ( div.getElementsByClassName("e").length === 0 )
871 // Safari caches class attributes, doesn't catch changes (in 3.2)
872 div.lastChild.className = "e";
874 if ( div.getElementsByClassName("e").length === 1 )
877 Expr.order.splice(1, 0, "CLASS");
878 Expr.find.CLASS = function(match, context, isXML) {
879 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
880 return context.getElementsByClassName(match[1]);
884 div = null; // release memory in IE
887 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
888 var sibDir = dir == "previousSibling" && !isXML;
889 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
890 var elem = checkSet[i];
892 if ( sibDir && elem.nodeType === 1 ){
893 elem.sizcache = doneName;
900 if ( elem.sizcache === doneName ) {
901 match = checkSet[elem.sizset];
905 if ( elem.nodeType === 1 && !isXML ){
906 elem.sizcache = doneName;
910 if ( elem.nodeName === cur ) {
923 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
924 var sibDir = dir == "previousSibling" && !isXML;
925 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
926 var elem = checkSet[i];
928 if ( sibDir && elem.nodeType === 1 ) {
929 elem.sizcache = doneName;
936 if ( elem.sizcache === doneName ) {
937 match = checkSet[elem.sizset];
941 if ( elem.nodeType === 1 ) {
943 elem.sizcache = doneName;
946 if ( typeof cur !== "string" ) {
947 if ( elem === cur ) {
952 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
966 var contains = document.compareDocumentPosition ? function(a, b){
967 return a.compareDocumentPosition(b) & 16;
969 return a !== b && (a.contains ? a.contains(b) : true);
972 var isXML = function(elem){
973 return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
974 !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML";
977 var posProcess = function(selector, context){
978 var tmpSet = [], later = "", match,
979 root = context.nodeType ? [context] : context;
981 // Position selectors must be done after the filter
982 // And so must :not(positional) so we move all PSEUDOs to the end
983 while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
985 selector = selector.replace( Expr.match.PSEUDO, "" );
988 selector = Expr.relative[selector] ? selector + "*" : selector;
990 for ( var i = 0, l = root.length; i < l; i++ ) {
991 Sizzle( selector, root[i], tmpSet );
994 return Sizzle.filter( later, tmpSet );
998 jQuery.find = Sizzle;
999 jQuery.expr = Sizzle.selectors;
1000 jQuery.expr[":"] = jQuery.expr.filters;
1002 Sizzle.selectors.filters.hidden = function(elem){
1003 var width = elem.offsetWidth, height = elem.offsetHeight,
1004 force = /^tr$/i.test( elem.nodeName ); // ticket #4512
1005 return ( width === 0 && height === 0 && !force ) ?
1007 ( width !== 0 && height !== 0 && !force ) ?
1009 !!( jQuery.curCSS(elem, "display") === "none" );
1012 Sizzle.selectors.filters.visible = function(elem){
1013 return !Sizzle.selectors.filters.hidden(elem);
1016 Sizzle.selectors.filters.animated = function(elem){
1017 return jQuery.grep(jQuery.timers, function(fn){
1018 return elem === fn.elem;
1022 jQuery.filter = jQuery.multiFilter = function( expr, elems, not ) {
1024 expr = ":not(" + expr + ")";
1027 return Sizzle.matches(expr, elems);
1030 jQuery.dir = function( elem, dir ){
1031 var matched = [], cur = elem[dir];
1032 while ( cur && cur != document ) {
1033 if ( cur.nodeType == 1 )
1034 matched.push( cur );
1040 jQuery.nth = function(cur, result, dir, elem){
1041 result = result || 1;
1044 for ( ; cur; cur = cur[dir] )
1045 if ( cur.nodeType == 1 && ++num == result )
1051 jQuery.sibling = function(n, elem){
1054 for ( ; n; n = n.nextSibling ) {
1055 if ( n.nodeType == 1 && n != elem )
1062 jQuery.unique = Sizzle.uniqueSort;
1066 window.Sizzle = Sizzle;