Merge "ResourceLoader: Honor $wgAllow* settings in site/user modules"
[lhc/web/wiklou.git] / resources / jquery / jquery.js
index 0770682..a86bf79 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery JavaScript Library v1.8.0
+ * jQuery JavaScript Library v1.8.3
  * http://jquery.com/
  *
  * Includes Sizzle.js
@@ -9,7 +9,7 @@
  * Released under the MIT license
  * http://jquery.org/license
  *
- * Date: Thu Aug 09 2012 16:24:48 GMT-0400 (Eastern Daylight Time)
+ * Date: Tue Nov 13 2012 08:20:33 GMT-0500 (Eastern Standard Time)
  */
 (function( window, undefined ) {
 var
@@ -51,8 +51,8 @@ var
        core_rnotwhite = /\S/,
        core_rspace = /\s+/,
 
-       // IE doesn't match non-breaking spaces with \s
-       rtrim = core_rnotwhite.test("\xA0") ? (/^[\s\xA0]+|[\s\xA0]+$/g) : /^\s+|\s+$/g,
+       // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)
+       rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
 
        // A simple way to check for HTML strings
        // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
@@ -186,7 +186,7 @@ jQuery.fn = jQuery.prototype = {
        selector: "",
 
        // The current version of jQuery being used
-       jquery: "1.8.0",
+       jquery: "1.8.3",
 
        // The default length of a jQuery object is 0
        length: 0,
@@ -573,7 +573,7 @@ jQuery.extend({
        },
 
        nodeName: function( elem, name ) {
-               return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
+               return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
        },
 
        // args is for internal usage only
@@ -619,7 +619,7 @@ jQuery.extend({
        },
 
        // Use native String.trim function wherever possible
-       trim: core_trim ?
+       trim: core_trim && !core_trim.call("\uFEFF\xA0") ?
                function( text ) {
                        return text == null ?
                                "" :
@@ -630,7 +630,7 @@ jQuery.extend({
                function( text ) {
                        return text == null ?
                                "" :
-                               text.toString().replace( rtrim, "" );
+                               ( text + "" ).replace( rtrim, "" );
                },
 
        // results is for internal usage only
@@ -776,7 +776,7 @@ jQuery.extend({
                };
 
                // Set the guid of unique handler to the same of original handler, so it can be removed
-               proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
+               proxy.guid = fn.guid = fn.guid || jQuery.guid++;
 
                return proxy;
        },
@@ -844,9 +844,10 @@ jQuery.ready.promise = function( obj ) {
 
                readyList = jQuery.Deferred();
 
-               // Catch cases where $(document).ready() is called after the
-               // browser event has already occurred.
-               if ( document.readyState === "complete" || ( document.readyState !== "loading" && document.addEventListener ) ) {
+               // Catch cases where $(document).ready() is called after the browser event has already occurred.
+               // we once tried to use readyState "interactive" here, but it caused issues like the one
+               // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
+               if ( document.readyState === "complete" ) {
                        // Handle it asynchronously to allow scripts the opportunity to delay ready
                        setTimeout( jQuery.ready, 1 );
 
@@ -997,9 +998,12 @@ jQuery.Callbacks = function( options ) {
                                        var start = list.length;
                                        (function add( args ) {
                                                jQuery.each( args, function( _, arg ) {
-                                                       if ( jQuery.isFunction( arg ) && ( !options.unique || !self.has( arg ) ) ) {
-                                                               list.push( arg );
-                                                       } else if ( arg && arg.length ) {
+                                                       var type = jQuery.type( arg );
+                                                       if ( type === "function" ) {
+                                                               if ( !options.unique || !self.has( arg ) ) {
+                                                                       list.push( arg );
+                                                               }
+                                                       } else if ( arg && arg.length && type !== "string" ) {
                                                                // Inspect recursively
                                                                add( arg );
                                                        }
@@ -1141,7 +1145,7 @@ jQuery.extend({
                                // Get a promise for this deferred
                                // If obj is provided, the promise aspect is added to the object
                                promise: function( obj ) {
-                                       return typeof obj === "object" ? jQuery.extend( obj, promise ) : promise;
+                                       return obj != null ? jQuery.extend( obj, promise ) : promise;
                                }
                        },
                        deferred = {};
@@ -1251,24 +1255,23 @@ jQuery.support = (function() {
                clickFn,
                div = document.createElement("div");
 
-       // Preliminary tests
+       // Setup
        div.setAttribute( "className", "t" );
        div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
 
+       // Support tests won't run in some limited or non-browser environments
        all = div.getElementsByTagName("*");
        a = div.getElementsByTagName("a")[ 0 ];
-       a.style.cssText = "top:1px;float:left;opacity:.5";
-
-       // Can't get basic test support
-       if ( !all || !all.length || !a ) {
+       if ( !all || !a || !all.length ) {
                return {};
        }
 
-       // First batch of supports tests
+       // First batch of tests
        select = document.createElement("select");
        opt = select.appendChild( document.createElement("option") );
        input = div.getElementsByTagName("input")[ 0 ];
 
+       a.style.cssText = "top:1px;float:left;opacity:.5";
        support = {
                // IE strips leading whitespace when .innerHTML is used
                leadingWhitespace: ( div.firstChild.nodeType === 3 ),
@@ -1310,7 +1313,7 @@ jQuery.support = (function() {
                // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
                getSetAttribute: div.className !== "t",
 
-               // Tests for enctype support on a form(#6743)
+               // Tests for enctype support on a form (#6743)
                enctype: !!document.createElement("form").enctype,
 
                // Makes sure cloning an html5 element does not cause problems
@@ -1452,10 +1455,8 @@ jQuery.support = (function() {
                support.boxSizing = ( div.offsetWidth === 4 );
                support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 );
 
-               // NOTE: To any future maintainer, window.getComputedStyle was used here
-               // instead of getComputedStyle because it gave a better gzip size.
-               // The difference between window.getComputedStyle and getComputedStyle is
-               // 7 bytes
+               // NOTE: To any future maintainer, we've window.getComputedStyle
+               // because jsdom on node.js will break without it.
                if ( window.getComputedStyle ) {
                        support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
                        support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
@@ -1505,7 +1506,7 @@ jQuery.support = (function() {
 
        return support;
 })();
-var rbrace = /^(?:\{.*\}|\[.*\])$/,
+var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
        rmultiDash = /([A-Z])/g;
 
 jQuery.extend({
@@ -1513,7 +1514,7 @@ jQuery.extend({
 
        deletedIds: [],
 
-       // Please use with caution
+       // Remove at next major release (1.9/2.0)
        uuid: 0,
 
        // Unique for each copy of jQuery on the page
@@ -1565,7 +1566,7 @@ jQuery.extend({
                        // Only DOM nodes need a new unique ID for each element since their data
                        // ends up in the global cache
                        if ( isNode ) {
-                               elem[ internalKey ] = id = jQuery.deletedIds.pop() || ++jQuery.uuid;
+                               elem[ internalKey ] = id = jQuery.deletedIds.pop() || jQuery.guid++;
                        } else {
                                id = internalKey;
                        }
@@ -1739,7 +1740,7 @@ jQuery.fn.extend({
                                        for ( l = attr.length; i < l; i++ ) {
                                                name = attr[i].name;
 
-                                               if ( name.indexOf( "data-" ) === 0 ) {
+                                               if ( !name.indexOf( "data-" ) ) {
                                                        name = jQuery.camelCase( name.substring(5) );
 
                                                        dataAttr( elem, name, data[ name ] );
@@ -1868,6 +1869,7 @@ jQuery.extend({
                type = type || "fx";
 
                var queue = jQuery.queue( elem, type ),
+                       startLength = queue.length,
                        fn = queue.shift(),
                        hooks = jQuery._queueHooks( elem, type ),
                        next = function() {
@@ -1877,6 +1879,7 @@ jQuery.extend({
                // If the fx queue is dequeued, always remove the progress sentinel
                if ( fn === "inprogress" ) {
                        fn = queue.shift();
+                       startLength--;
                }
 
                if ( fn ) {
@@ -1891,7 +1894,8 @@ jQuery.extend({
                        delete hooks.stop;
                        fn.call( elem, next, hooks );
                }
-               if ( !queue.length && hooks ) {
+
+               if ( !startLength && hooks ) {
                        hooks.empty.fire();
                }
        },
@@ -1977,7 +1981,8 @@ jQuery.fn.extend({
                type = type || "fx";
 
                while( i-- ) {
-                       if ( (tmp = jQuery._data( elements[ i ], type + "queueHooks" )) && tmp.empty ) {
+                       tmp = jQuery._data( elements[ i ], type + "queueHooks" );
+                       if ( tmp && tmp.empty ) {
                                count++;
                                tmp.empty.add( resolve );
                        }
@@ -2045,7 +2050,7 @@ jQuery.fn.extend({
                                                setClass = " " + elem.className + " ";
 
                                                for ( c = 0, cl = classNames.length; c < cl; c++ ) {
-                                                       if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {
+                                                       if ( setClass.indexOf( " " + classNames[ c ] + " " ) < 0 ) {
                                                                setClass += classNames[ c ] + " ";
                                                        }
                                                }
@@ -2078,7 +2083,7 @@ jQuery.fn.extend({
                                        // loop over each item in the removal list
                                        for ( c = 0, cl = removes.length; c < cl; c++ ) {
                                                // Remove until there is nothing to remove,
-                                               while ( className.indexOf(" " + removes[ c ] + " ") > -1 ) {
+                                               while ( className.indexOf(" " + removes[ c ] + " ") >= 0 ) {
                                                        className = className.replace( " " + removes[ c ] + " " , " " );
                                                }
                                        }
@@ -2132,7 +2137,7 @@ jQuery.fn.extend({
                        i = 0,
                        l = this.length;
                for ( ; i < l; i++ ) {
-                       if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
+                       if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
                                return true;
                        }
                }
@@ -2213,26 +2218,25 @@ jQuery.extend({
                },
                select: {
                        get: function( elem ) {
-                               var value, i, max, option,
-                                       index = elem.selectedIndex,
-                                       values = [],
+                               var value, option,
                                        options = elem.options,
-                                       one = elem.type === "select-one";
-
-                               // Nothing was selected
-                               if ( index < 0 ) {
-                                       return null;
-                               }
+                                       index = elem.selectedIndex,
+                                       one = elem.type === "select-one" || index < 0,
+                                       values = one ? null : [],
+                                       max = one ? index + 1 : options.length,
+                                       i = index < 0 ?
+                                               max :
+                                               one ? index : 0;
 
                                // Loop through all the selected options
-                               i = one ? index : 0;
-                               max = one ? index + 1 : options.length;
                                for ( ; i < max; i++ ) {
                                        option = options[ i ];
 
-                                       // Don't return options that are disabled or in a disabled optgroup
-                                       if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
-                                                       (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
+                                       // oldIE doesn't update selected after form reset (#2551)
+                                       if ( ( option.selected || i === index ) &&
+                                                       // Don't return options that are disabled or in a disabled optgroup
+                                                       ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
+                                                       ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
 
                                                // Get the specific value for the option
                                                value = jQuery( option ).val();
@@ -2247,11 +2251,6 @@ jQuery.extend({
                                        }
                                }
 
-                               // Fixes Bug #2551 -- select.val() broken in IE after form.reset()
-                               if ( one && !values.length && options.length ) {
-                                       return jQuery( options[ index ] ).val();
-                               }
-
                                return values;
                        },
 
@@ -2310,7 +2309,7 @@ jQuery.extend({
                                return ret;
 
                        } else {
-                               elem.setAttribute( name, "" + value );
+                               elem.setAttribute( name, value + "" );
                                return value;
                        }
 
@@ -2574,7 +2573,7 @@ if ( !jQuery.support.style ) {
                        return elem.style.cssText.toLowerCase() || undefined;
                },
                set: function( elem, value ) {
-                       return ( elem.style.cssText = "" + value );
+                       return ( elem.style.cssText = value + "" );
                }
        };
 }
@@ -2707,6 +2706,7 @@ jQuery.event = {
                                handler: handler,
                                guid: handler.guid,
                                selector: selector,
+                               needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
                                namespace: namespaces.join(".")
                        }, handleObjIn );
 
@@ -2942,7 +2942,7 @@ jQuery.event = {
                        }
                        // Note that this is a bare JS function and not a jQuery handler
                        handle = ontype && cur[ ontype ];
-                       if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) {
+                       if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {
                                event.preventDefault();
                        }
                }
@@ -2987,10 +2987,10 @@ jQuery.event = {
                // Make a writable jQuery.Event from the native event object
                event = jQuery.event.fix( event || window.event );
 
-               var i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related,
+               var i, j, cur, ret, selMatch, matched, matches, handleObj, sel, related,
                        handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []),
                        delegateCount = handlers.delegateCount,
-                       args = [].slice.call( arguments ),
+                       args = core_slice.call( arguments ),
                        run_all = !event.exclusive && !event.namespace,
                        special = jQuery.event.special[ event.type ] || {},
                        handlerQueue = [];
@@ -3008,23 +3008,20 @@ jQuery.event = {
                // Avoid non-left-click bubbling in Firefox (#3861)
                if ( delegateCount && !(event.button && event.type === "click") ) {
 
-                       // Pregenerate a single jQuery object for reuse with .is()
-                       jqcur = jQuery(this);
-                       jqcur.context = this;
-
                        for ( cur = event.target; cur != this; cur = cur.parentNode || this ) {
 
-                               // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #xxxx)
+                               // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764)
                                if ( cur.disabled !== true || event.type !== "click" ) {
                                        selMatch = {};
                                        matches = [];
-                                       jqcur[0] = cur;
                                        for ( i = 0; i < delegateCount; i++ ) {
                                                handleObj = handlers[ i ];
                                                sel = handleObj.selector;
 
                                                if ( selMatch[ sel ] === undefined ) {
-                                                       selMatch[ sel ] = jqcur.is( sel );
+                                                       selMatch[ sel ] = handleObj.needsContext ?
+                                                               jQuery( sel, this ).index( cur ) >= 0 :
+                                                               jQuery.find( sel, this, null, [ cur ] ).length;
                                                }
                                                if ( selMatch[ sel ] ) {
                                                        matches.push( handleObj );
@@ -3165,11 +3162,6 @@ jQuery.event = {
        },
 
        special: {
-               ready: {
-                       // Make sure the ready event is setup
-                       setup: jQuery.bindReady
-               },
-
                load: {
                        // Prevent triggered image.load events from bubbling to window.load
                        noBubble: true
@@ -3236,7 +3228,7 @@ jQuery.removeEvent = document.removeEventListener ?
 
                if ( elem.detachEvent ) {
 
-                       // #8545, #7054, preventing memory leaks for custom events in IE6-8 â€“
+                       // #8545, #7054, preventing memory leaks for custom events in IE6-8
                        // detachEvent needed property on element, by name of that event, to properly expose it to GC
                        if ( typeof elem[ name ] === "undefined" ) {
                                elem[ name ] = null;
@@ -3458,7 +3450,7 @@ if ( !jQuery.support.changeBubbles ) {
                teardown: function() {
                        jQuery.event.remove( this, "._change" );
 
-                       return rformElems.test( this.nodeName );
+                       return !rformElems.test( this.nodeName );
                }
        };
 }
@@ -3599,7 +3591,7 @@ jQuery.fn.extend({
        },
        undelegate: function( selector, types, fn ) {
                // ( namespace ) or ( selector, types [, fn] )
-               return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
+               return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
        },
 
        trigger: function( type, data ) {
@@ -3670,29 +3662,72 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl
 });
 /*!\r
  * Sizzle CSS Selector Engine\r
- *  Copyright 2012 jQuery Foundation and other contributors\r
- *  Released under the MIT license\r
- *  http://sizzlejs.com/\r
+ * Copyright 2012 jQuery Foundation and other contributors\r
+ * Released under the MIT license\r
+ * http://sizzlejs.com/\r
  */\r
 (function( window, undefined ) {\r
 \r
 var cachedruns,\r
-       dirruns,\r
-       sortOrder,\r
-       siblingCheck,\r
        assertGetIdNotName,\r
+       Expr,\r
+       getText,\r
+       isXML,\r
+       contains,\r
+       compile,\r
+       sortOrder,\r
+       hasDuplicate,\r
+       outermostContext,\r
+\r
+       baseHasDuplicate = true,\r
+       strundefined = "undefined",\r
+\r
+       expando = ( "sizcache" + Math.random() ).replace( ".", "" ),\r
 \r
+       Token = String,\r
        document = window.document,\r
        docElem = document.documentElement,\r
-\r
-       strundefined = "undefined",\r
-       hasDuplicate = false,\r
-       baseHasDuplicate = true,\r
+       dirruns = 0,\r
        done = 0,\r
-       slice = [].slice,\r
+       pop = [].pop,\r
        push = [].push,\r
+       slice = [].slice,\r
+       // Use a stripped-down indexOf if a native one is unavailable\r
+       indexOf = [].indexOf || function( elem ) {\r
+               var i = 0,\r
+                       len = this.length;\r
+               for ( ; i < len; i++ ) {\r
+                       if ( this[i] === elem ) {\r
+                               return i;\r
+                       }\r
+               }\r
+               return -1;\r
+       },\r
 \r
-       expando = ( "sizcache" + Math.random() ).replace( ".", "" ),\r
+       // Augment a function for special use by Sizzle\r
+       markFunction = function( fn, value ) {\r
+               fn[ expando ] = value == null || value;\r
+               return fn;\r
+       },\r
+\r
+       createCache = function() {\r
+               var cache = {},\r
+                       keys = [];\r
+\r
+               return markFunction(function( key, value ) {\r
+                       // Only keep the most recent entries\r
+                       if ( keys.push( key ) > Expr.cacheLength ) {\r
+                               delete cache[ keys.shift() ];\r
+                       }\r
+\r
+                       // Retrieve with (key + " ") to avoid collision with native Object.prototype properties (see Issue #157)\r
+                       return (cache[ key + " " ] = value);\r
+               }, cache );\r
+       },\r
+\r
+       classCache = createCache(),\r
+       tokenCache = createCache(),\r
+       compilerCache = createCache(),\r
 \r
        // Regex\r
 \r
@@ -3710,29 +3745,29 @@ var cachedruns,
        operators = "([*^$|!~]?=)",\r
        attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +\r
                "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",\r
-       pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|((?:[^,]|\\\\,|(?:,(?=[^\\[]*\\]))|(?:,(?=[^\\(]*\\))))*))\\)|)",\r
-       pos = ":(nth|eq|gt|lt|first|last|even|odd)(?:\\((\\d*)\\)|)(?=[^-]|$)",\r
-       combinators = whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*",\r
-       groups = "(?=[^\\x20\\t\\r\\n\\f])(?:\\\\.|" + attributes + "|" + pseudos.replace( 2, 7 ) + "|[^\\\\(),])+",\r
-\r
-       // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\r
-       rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),\r
 \r
-       rcombinators = new RegExp( "^" + combinators ),\r
+       // Prefer arguments not in parens/brackets,\r
+       //   then attribute selectors and non-pseudos (denoted by :),\r
+       //   then anything else\r
+       // These preferences are here to reduce the number of selectors\r
+       //   needing tokenize in the PSEUDO preFilter\r
+       pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)",\r
 \r
-       // All simple (non-comma) selectors, excluding insignifant trailing whitespace\r
-       rgroups = new RegExp( groups + "?(?=" + whitespace + "*,|$)", "g" ),\r
+       // For matchExpr.POS and matchExpr.needsContext\r
+       pos = ":(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +\r
+               "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)",\r
 \r
-       // A selector, or everything after leading whitespace\r
-       // Optionally followed in either case by a ")" for terminating sub-selectors\r
-       rselector = new RegExp( "^(?:(?!,)(?:(?:^|,)" + whitespace + "*" + groups + ")*?|" + whitespace + "*(.*?))(\\)|$)" ),\r
+       // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\r
+       rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),\r
 \r
-       // All combinators and selector components (attribute test, tag, pseudo, etc.), the latter appearing together when consecutive\r
-       rtokens = new RegExp( groups.slice( 19, -6 ) + "\\x20\\t\\r\\n\\f>+~])+|" + combinators, "g" ),\r
+       rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),\r
+       rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ),\r
+       rpseudo = new RegExp( pseudos ),\r
 \r
        // Easily-parseable/retrievable ID or TAG or CLASS selectors\r
        rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,\r
 \r
+       rnot = /^:not/,\r
        rsibling = /[\x20\t\r\n\f]*[+~]/,\r
        rendsWithNot = /:not\($/,\r
 \r
@@ -3745,56 +3780,46 @@ var cachedruns,
                "ID": new RegExp( "^#(" + characterEncoding + ")" ),\r
                "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),\r
                "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ),\r
-               "TAG": new RegExp( "^(" + characterEncoding.replace( "[-", "[-\\*" ) + ")" ),\r
+               "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),\r
                "ATTR": new RegExp( "^" + attributes ),\r
                "PSEUDO": new RegExp( "^" + pseudos ),\r
-               "CHILD": new RegExp( "^:(only|nth|last|first)-child(?:\\(" + whitespace +\r
+               "POS": new RegExp( pos, "i" ),\r
+               "CHILD": new RegExp( "^:(only|nth|first|last)-child(?:\\(" + whitespace +\r
                        "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +\r
                        "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),\r
-               "POS": new RegExp( pos, "ig" ),\r
                // For use in libraries implementing .is()\r
                "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" )\r
        },\r
 \r
-       classCache = {},\r
-       cachedClasses = [],\r
-       compilerCache = {},\r
-       cachedSelectors = [],\r
-\r
-       // Mark a function for use in filtering\r
-       markFunction = function( fn ) {\r
-               fn.sizzleFilter = true;\r
-               return fn;\r
-       },\r
-\r
-       // Returns a function to use in pseudos for input types\r
-       createInputFunction = function( type ) {\r
-               return function( elem ) {\r
-                       // Check the input's nodeName and type\r
-                       return elem.nodeName.toLowerCase() === "input" && elem.type === type;\r
-               };\r
-       },\r
-\r
-       // Returns a function to use in pseudos for buttons\r
-       createButtonFunction = function( type ) {\r
-               return function( elem ) {\r
-                       var name = elem.nodeName.toLowerCase();\r
-                       return (name === "input" || name === "button") && elem.type === type;\r
-               };\r
-       },\r
+       // Support\r
 \r
        // Used for testing something on an element\r
        assert = function( fn ) {\r
-               var pass = false,\r
-                       div = document.createElement("div");\r
+               var div = document.createElement("div");\r
+\r
                try {\r
-                       pass = fn( div );\r
-               } catch (e) {}\r
-               // release memory in IE\r
-               div = null;\r
-               return pass;\r
+                       return fn( div );\r
+               } catch (e) {\r
+                       return false;\r
+               } finally {\r
+                       // release memory in IE\r
+                       div = null;\r
+               }\r
        },\r
 \r
+       // Check if getElementsByTagName("*") returns only elements\r
+       assertTagNameNoComments = assert(function( div ) {\r
+               div.appendChild( document.createComment("") );\r
+               return !div.getElementsByTagName("*").length;\r
+       }),\r
+\r
+       // Check if getAttribute returns normalized href attributes\r
+       assertHrefNotNormalized = assert(function( div ) {\r
+               div.innerHTML = "<a href='#'></a>";\r
+               return div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&\r
+                       div.firstChild.getAttribute("href") === "#";\r
+       }),\r
+\r
        // Check if attributes should be retrieved by attribute nodes\r
        assertAttributes = assert(function( div ) {\r
                div.innerHTML = "<select></select>";\r
@@ -3803,6 +3828,19 @@ var cachedruns,
                return type !== "boolean" && type !== "string";\r
        }),\r
 \r
+       // Check if getElementsByClassName can be trusted\r
+       assertUsableClassName = assert(function( div ) {\r
+               // Opera can't find a second classname (in 9.6)\r
+               div.innerHTML = "<div class='hidden e'></div><div class='hidden'></div>";\r
+               if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) {\r
+                       return false;\r
+               }\r
+\r
+               // Safari 3.2 caches class attributes and doesn't catch changes\r
+               div.lastChild.className = "e";\r
+               return div.getElementsByClassName("e").length === 2;\r
+       }),\r
+\r
        // Check if getElementById returns elements by name\r
        // Check if getElementsByName privileges form controls or returns elements by ID\r
        assertUsableName = assert(function( div ) {\r
@@ -3814,58 +3852,45 @@ var cachedruns,
                // Test\r
                var pass = document.getElementsByName &&\r
                        // buggy browsers will return fewer than the correct 2\r
-                       document.getElementsByName( expando ).length ===\r
+                       document.getElementsByName( expando ).length === 2 +\r
                        // buggy browsers will return more than the correct 0\r
-                       2 + document.getElementsByName( expando + 0 ).length;\r
+                       document.getElementsByName( expando + 0 ).length;\r
                assertGetIdNotName = !document.getElementById( expando );\r
 \r
                // Cleanup\r
                docElem.removeChild( div );\r
 \r
                return pass;\r
-       }),\r
-\r
-       // Check if the browser returns only elements\r
-       // when doing getElementsByTagName("*")\r
-       assertTagNameNoComments = assert(function( div ) {\r
-               div.appendChild( document.createComment("") );\r
-               return div.getElementsByTagName("*").length === 0;\r
-       }),\r
-\r
-       // Check if getAttribute returns normalized href attributes\r
-       assertHrefNotNormalized = assert(function( div ) {\r
-               div.innerHTML = "<a href='#'></a>";\r
-               return div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&\r
-                       div.firstChild.getAttribute("href") === "#";\r
-       }),\r
+       });\r
 \r
-       // Check if getElementsByClassName can be trusted\r
-       assertUsableClassName = assert(function( div ) {\r
-               // Opera can't find a second classname (in 9.6)\r
-               div.innerHTML = "<div class='hidden e'></div><div class='hidden'></div>";\r
-               if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {\r
-                       return false;\r
+// If slice is not available, provide a backup\r
+try {\r
+       slice.call( docElem.childNodes, 0 )[0].nodeType;\r
+} catch ( e ) {\r
+       slice = function( i ) {\r
+               var elem,\r
+                       results = [];\r
+               for ( ; (elem = this[i]); i++ ) {\r
+                       results.push( elem );\r
                }\r
+               return results;\r
+       };\r
+}\r
 \r
-               // Safari caches class attributes, doesn't catch changes (in 3.2)\r
-               div.lastChild.className = "e";\r
-               return div.getElementsByClassName("e").length !== 1;\r
-       });\r
-\r
-var Sizzle = function( selector, context, results, seed ) {\r
+function Sizzle( selector, context, results, seed ) {\r
        results = results || [];\r
        context = context || document;\r
        var match, elem, xml, m,\r
                nodeType = context.nodeType;\r
 \r
-       if ( nodeType !== 1 && nodeType !== 9 ) {\r
-               return [];\r
-       }\r
-\r
        if ( !selector || typeof selector !== "string" ) {\r
                return results;\r
        }\r
 \r
+       if ( nodeType !== 1 && nodeType !== 9 ) {\r
+               return [];\r
+       }\r
+\r
        xml = isXML( context );\r
 \r
        if ( !xml && !seed ) {\r
@@ -3909,22 +3934,158 @@ var Sizzle = function( selector, context, results, seed ) {
        }\r
 \r
        // All others\r
-       return select( selector, context, results, seed, xml );\r
+       return select( selector.replace( rtrim, "$1" ), context, results, seed, xml );\r
+}\r
+\r
+Sizzle.matches = function( expr, elements ) {\r
+       return Sizzle( expr, null, null, elements );\r
 };\r
 \r
-var Expr = Sizzle.selectors = {\r
+Sizzle.matchesSelector = function( elem, expr ) {\r
+       return Sizzle( expr, null, null, [ elem ] ).length > 0;\r
+};\r
 \r
-       // Can be adjusted by the user\r
-       cacheLength: 50,\r
+// Returns a function to use in pseudos for input types\r
+function createInputPseudo( type ) {\r
+       return function( elem ) {\r
+               var name = elem.nodeName.toLowerCase();\r
+               return name === "input" && elem.type === type;\r
+       };\r
+}\r
 \r
-       match: matchExpr,\r
+// Returns a function to use in pseudos for buttons\r
+function createButtonPseudo( type ) {\r
+       return function( elem ) {\r
+               var name = elem.nodeName.toLowerCase();\r
+               return (name === "input" || name === "button") && elem.type === type;\r
+       };\r
+}\r
+\r
+// Returns a function to use in pseudos for positionals\r
+function createPositionalPseudo( fn ) {\r
+       return markFunction(function( argument ) {\r
+               argument = +argument;\r
+               return markFunction(function( seed, matches ) {\r
+                       var j,\r
+                               matchIndexes = fn( [], seed.length, argument ),\r
+                               i = matchIndexes.length;\r
+\r
+                       // Match elements found at the specified indexes\r
+                       while ( i-- ) {\r
+                               if ( seed[ (j = matchIndexes[i]) ] ) {\r
+                                       seed[j] = !(matches[j] = seed[j]);\r
+                               }\r
+                       }\r
+               });\r
+       });\r
+}\r
+\r
+/**\r
+ * Utility function for retrieving the text value of an array of DOM nodes\r
+ * @param {Array|Element} elem\r
+ */\r
+getText = Sizzle.getText = function( elem ) {\r
+       var node,\r
+               ret = "",\r
+               i = 0,\r
+               nodeType = elem.nodeType;\r
+\r
+       if ( nodeType ) {\r
+               if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\r
+                       // Use textContent for elements\r
+                       // innerText usage removed for consistency of new lines (see #11153)\r
+                       if ( typeof elem.textContent === "string" ) {\r
+                               return elem.textContent;\r
+                       } else {\r
+                               // Traverse its children\r
+                               for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\r
+                                       ret += getText( elem );\r
+                               }\r
+                       }\r
+               } else if ( nodeType === 3 || nodeType === 4 ) {\r
+                       return elem.nodeValue;\r
+               }\r
+               // Do not include comment or processing instruction nodes\r
+       } else {\r
 \r
-       order: [ "ID", "TAG" ],\r
+               // If no nodeType, this is expected to be an array\r
+               for ( ; (node = elem[i]); i++ ) {\r
+                       // Do not traverse comment nodes\r
+                       ret += getText( node );\r
+               }\r
+       }\r
+       return ret;\r
+};\r
 \r
-       attrHandle: {},\r
+isXML = Sizzle.isXML = function( elem ) {\r
+       // documentElement is verified for cases where it doesn't yet exist\r
+       // (such as loading iframes in IE - #4833)\r
+       var documentElement = elem && (elem.ownerDocument || elem).documentElement;\r
+       return documentElement ? documentElement.nodeName !== "HTML" : false;\r
+};\r
+\r
+// Element contains another\r
+contains = Sizzle.contains = docElem.contains ?\r
+       function( a, b ) {\r
+               var adown = a.nodeType === 9 ? a.documentElement : a,\r
+                       bup = b && b.parentNode;\r
+               return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) );\r
+       } :\r
+       docElem.compareDocumentPosition ?\r
+       function( a, b ) {\r
+               return b && !!( a.compareDocumentPosition( b ) & 16 );\r
+       } :\r
+       function( a, b ) {\r
+               while ( (b = b.parentNode) ) {\r
+                       if ( b === a ) {\r
+                               return true;\r
+                       }\r
+               }\r
+               return false;\r
+       };\r
+\r
+Sizzle.attr = function( elem, name ) {\r
+       var val,\r
+               xml = isXML( elem );\r
+\r
+       if ( !xml ) {\r
+               name = name.toLowerCase();\r
+       }\r
+       if ( (val = Expr.attrHandle[ name ]) ) {\r
+               return val( elem );\r
+       }\r
+       if ( xml || assertAttributes ) {\r
+               return elem.getAttribute( name );\r
+       }\r
+       val = elem.getAttributeNode( name );\r
+       return val ?\r
+               typeof elem[ name ] === "boolean" ?\r
+                       elem[ name ] ? name : null :\r
+                       val.specified ? val.value : null :\r
+               null;\r
+};\r
+\r
+Expr = Sizzle.selectors = {\r
+\r
+       // Can be adjusted by the user\r
+       cacheLength: 50,\r
 \r
        createPseudo: markFunction,\r
 \r
+       match: matchExpr,\r
+\r
+       // IE6/7 return a modified href\r
+       attrHandle: assertHrefNotNormalized ?\r
+               {} :\r
+               {\r
+                       "href": function( elem ) {\r
+                               return elem.getAttribute( "href", 2 );\r
+                       },\r
+                       "type": function( elem ) {\r
+                               return elem.getAttribute("type");\r
+                       }\r
+               },\r
+\r
        find: {\r
                "ID": assertGetIdNotName ?\r
                        function( id, context, xml ) {\r
@@ -3971,7 +4132,19 @@ var Expr = Sizzle.selectors = {
                                        return tmp;\r
                                }\r
                                return results;\r
+                       },\r
+\r
+               "NAME": assertUsableName && function( tag, context ) {\r
+                       if ( typeof context.getElementsByName !== strundefined ) {\r
+                               return context.getElementsByName( name );\r
                        }\r
+               },\r
+\r
+               "CLASS": assertUsableClassName && function( className, context, xml ) {\r
+                       if ( typeof context.getElementsByClassName !== strundefined && !xml ) {\r
+                               return context.getElementsByClassName( className );\r
+                       }\r
+               }\r
        },\r
 \r
        relative: {\r
@@ -3996,7 +4169,7 @@ var Expr = Sizzle.selectors = {
                },\r
 \r
                "CHILD": function( match ) {\r
-                       /* matches from matchExpr.CHILD\r
+                       /* matches from matchExpr["CHILD"]\r
                                1 type (only|nth|...)\r
                                2 argument (even|odd|\d*|\d*n([+-]\d+)?|...)\r
                                3 xn-component of xn+y argument ([+-]?\d*n|)\r
@@ -4027,24 +4200,30 @@ var Expr = Sizzle.selectors = {
                },\r
 \r
                "PSEUDO": function( match ) {\r
-                       var argument,\r
-                               unquoted = match[4];\r
-\r
+                       var unquoted, excess;\r
                        if ( matchExpr["CHILD"].test( match[0] ) ) {\r
                                return null;\r
                        }\r
 \r
-                       // Relinquish our claim on characters in `unquoted` from a closing parenthesis on\r
-                       if ( unquoted && (argument = rselector.exec( unquoted )) && argument.pop() ) {\r
-\r
-                               match[0] = match[0].slice( 0, argument[0].length - unquoted.length - 1 );\r
-                               unquoted = argument[0].slice( 0, -1 );\r
+                       if ( match[3] ) {\r
+                               match[2] = match[3];\r
+                       } else if ( (unquoted = match[4]) ) {\r
+                               // Only check arguments that contain a pseudo\r
+                               if ( rpseudo.test(unquoted) &&\r
+                                       // Get excess from tokenize (recursively)\r
+                                       (excess = tokenize( unquoted, true )) &&\r
+                                       // advance to the next closing parenthesis\r
+                                       (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {\r
+\r
+                                       // excess is a negative index\r
+                                       unquoted = unquoted.slice( 0, excess );\r
+                                       match[0] = match[0].slice( 0, excess );\r
+                               }\r
+                               match[2] = unquoted;\r
                        }\r
 \r
-                       // Quoted or unquoted, we have the full argument\r
                        // Return only captures needed by the pseudo filter method (type and argument)\r
-                       match.splice( 2, 3, unquoted || match[3] );\r
-                       return match;\r
+                       return match.slice( 0, 3 );\r
                }\r
        },\r
 \r
@@ -4076,91 +4255,65 @@ var Expr = Sizzle.selectors = {
                },\r
 \r
                "CLASS": function( className ) {\r
-                       var pattern = classCache[ className ];\r
-                       if ( !pattern ) {\r
-                               pattern = classCache[ className ] = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" );\r
-                               cachedClasses.push( className );\r
-                               // Avoid too large of a cache\r
-                               if ( cachedClasses.length > Expr.cacheLength ) {\r
-                                       delete classCache[ cachedClasses.shift() ];\r
-                               }\r
-                       }\r
-                       return function( elem ) {\r
-                               return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" );\r
-                       };\r
+                       var pattern = classCache[ expando ][ className + " " ];\r
+\r
+                       return pattern ||\r
+                               (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&\r
+                               classCache( className, function( elem ) {\r
+                                       return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" );\r
+                               });\r
                },\r
 \r
                "ATTR": function( name, operator, check ) {\r
-                       if ( !operator ) {\r
-                               return function( elem ) {\r
-                                       return Sizzle.attr( elem, name ) != null;\r
-                               };\r
-                       }\r
-\r
-                       return function( elem ) {\r
-                               var result = Sizzle.attr( elem, name ),\r
-                                       value = result + "";\r
+                       return function( elem, context ) {\r
+                               var result = Sizzle.attr( elem, name );\r
 \r
                                if ( result == null ) {\r
                                        return operator === "!=";\r
                                }\r
-\r
-                               switch ( operator ) {\r
-                                       case "=":\r
-                                               return value === check;\r
-                                       case "!=":\r
-                                               return value !== check;\r
-                                       case "^=":\r
-                                               return check && value.indexOf( check ) === 0;\r
-                                       case "*=":\r
-                                               return check && value.indexOf( check ) > -1;\r
-                                       case "$=":\r
-                                               return check && value.substr( value.length - check.length ) === check;\r
-                                       case "~=":\r
-                                               return ( " " + value + " " ).indexOf( check ) > -1;\r
-                                       case "|=":\r
-                                               return value === check || value.substr( 0, check.length + 1 ) === check + "-";\r
+                               if ( !operator ) {\r
+                                       return true;\r
                                }\r
+\r
+                               result += "";\r
+\r
+                               return operator === "=" ? result === check :\r
+                                       operator === "!=" ? result !== check :\r
+                                       operator === "^=" ? check && result.indexOf( check ) === 0 :\r
+                                       operator === "*=" ? check && result.indexOf( check ) > -1 :\r
+                                       operator === "$=" ? check && result.substr( result.length - check.length ) === check :\r
+                                       operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :\r
+                                       operator === "|=" ? result === check || result.substr( 0, check.length + 1 ) === check + "-" :\r
+                                       false;\r
                        };\r
                },\r
 \r
                "CHILD": function( type, argument, first, last ) {\r
 \r
                        if ( type === "nth" ) {\r
-                               var doneName = done++;\r
-\r
                                return function( elem ) {\r
-                                       var parent, diff,\r
-                                               count = 0,\r
-                                               node = elem;\r
+                                       var node, diff,\r
+                                               parent = elem.parentNode;\r
 \r
                                        if ( first === 1 && last === 0 ) {\r
                                                return true;\r
                                        }\r
 \r
-                                       parent = elem.parentNode;\r
-\r
-                                       if ( parent && (parent[ expando ] !== doneName || !elem.sizset) ) {\r
+                                       if ( parent ) {\r
+                                               diff = 0;\r
                                                for ( node = parent.firstChild; node; node = node.nextSibling ) {\r
                                                        if ( node.nodeType === 1 ) {\r
-                                                               node.sizset = ++count;\r
-                                                               if ( node === elem ) {\r
+                                                               diff++;\r
+                                                               if ( elem === node ) {\r
                                                                        break;\r
                                                                }\r
                                                        }\r
                                                }\r
-\r
-                                               parent[ expando ] = doneName;\r
                                        }\r
 \r
-                                       diff = elem.sizset - last;\r
-\r
-                                       if ( first === 0 ) {\r
-                                               return diff === 0;\r
-\r
-                                       } else {\r
-                                               return ( diff % first === 0 && diff / first >= 0 );\r
-                                       }\r
+                                       // Incorporate the offset (or cast to NaN), then check against cycle size\r
+                                       diff -= last;\r
+                                       return diff === first || ( diff % first === 0 && diff / first >= 0 );\r
                                };\r
                        }\r
 \r
@@ -4195,35 +4348,82 @@ var Expr = Sizzle.selectors = {
                        };\r
                },\r
 \r
-               "PSEUDO": function( pseudo, argument, context, xml ) {\r
+               "PSEUDO": function( pseudo, argument ) {\r
                        // pseudo-class names are case-insensitive\r
                        // http://www.w3.org/TR/selectors/#pseudo-classes\r
                        // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\r
-                       var fn = Expr.pseudos[ pseudo ] || Expr.pseudos[ pseudo.toLowerCase() ];\r
+                       // Remember that setFilters inherits from pseudos\r
+                       var args,\r
+                               fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\r
+                                       Sizzle.error( "unsupported pseudo: " + pseudo );\r
 \r
-                       if ( !fn ) {\r
-                               Sizzle.error( "unsupported pseudo: " + pseudo );\r
+                       // The user may use createPseudo to indicate that\r
+                       // arguments are needed to create the filter function\r
+                       // just as Sizzle does\r
+                       if ( fn[ expando ] ) {\r
+                               return fn( argument );\r
                        }\r
 \r
-                       // The user may set fn.sizzleFilter to indicate\r
-                       // that arguments are needed to create the filter function\r
-                       // just as Sizzle does\r
-                       if ( !fn.sizzleFilter ) {\r
-                               return fn;\r
+                       // But maintain support for old signatures\r
+                       if ( fn.length > 1 ) {\r
+                               args = [ pseudo, pseudo, "", argument ];\r
+                               return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\r
+                                       markFunction(function( seed, matches ) {\r
+                                               var idx,\r
+                                                       matched = fn( seed, argument ),\r
+                                                       i = matched.length;\r
+                                               while ( i-- ) {\r
+                                                       idx = indexOf.call( seed, matched[i] );\r
+                                                       seed[ idx ] = !( matches[ idx ] = matched[i] );\r
+                                               }\r
+                                       }) :\r
+                                       function( elem ) {\r
+                                               return fn( elem, 0, args );\r
+                                       };\r
                        }\r
 \r
-                       return fn( argument, context, xml );\r
+                       return fn;\r
                }\r
        },\r
 \r
        pseudos: {\r
-               "not": markFunction(function( selector, context, xml ) {\r
+               "not": markFunction(function( selector ) {\r
                        // Trim the selector passed to compile\r
                        // to avoid treating leading and trailing\r
                        // spaces as combinators\r
-                       var matcher = compile( selector.replace( rtrim, "$1" ), context, xml );\r
+                       var input = [],\r
+                               results = [],\r
+                               matcher = compile( selector.replace( rtrim, "$1" ) );\r
+\r
+                       return matcher[ expando ] ?\r
+                               markFunction(function( seed, matches, context, xml ) {\r
+                                       var elem,\r
+                                               unmatched = matcher( seed, null, xml, [] ),\r
+                                               i = seed.length;\r
+\r
+                                       // Match elements unmatched by `matcher`\r
+                                       while ( i-- ) {\r
+                                               if ( (elem = unmatched[i]) ) {\r
+                                                       seed[i] = !(matches[i] = elem);\r
+                                               }\r
+                                       }\r
+                               }) :\r
+                               function( elem, context, xml ) {\r
+                                       input[0] = elem;\r
+                                       matcher( input, null, xml, results );\r
+                                       return !results.pop();\r
+                               };\r
+               }),\r
+\r
+               "has": markFunction(function( selector ) {\r
                        return function( elem ) {\r
-                               return !matcher( elem );\r
+                               return Sizzle( selector, elem ).length > 0;\r
+                       };\r
+               }),\r
+\r
+               "contains": markFunction(function( text ) {\r
+                       return function( elem ) {\r
+                               return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\r
                        };\r
                }),\r
 \r
@@ -4273,18 +4473,6 @@ var Expr = Sizzle.selectors = {
                        return true;\r
                },\r
 \r
-               "contains": markFunction(function( text ) {\r
-                       return function( elem ) {\r
-                               return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\r
-                       };\r
-               }),\r
-\r
-               "has": markFunction(function( selector ) {\r
-                       return function( elem ) {\r
-                               return Sizzle( selector, elem ).length > 0;\r
-                       };\r
-               }),\r
-\r
                "header": function( elem ) {\r
                        return rheader.test( elem.nodeName );\r
                },\r
@@ -4299,14 +4487,14 @@ var Expr = Sizzle.selectors = {
                },\r
 \r
                // Input types\r
-               "radio": createInputFunction("radio"),\r
-               "checkbox": createInputFunction("checkbox"),\r
-               "file": createInputFunction("file"),\r
-               "password": createInputFunction("password"),\r
-               "image": createInputFunction("image"),\r
+               "radio": createInputPseudo("radio"),\r
+               "checkbox": createInputPseudo("checkbox"),\r
+               "file": createInputPseudo("file"),\r
+               "password": createInputPseudo("password"),\r
+               "image": createInputPseudo("image"),\r
 \r
-               "submit": createButtonFunction("submit"),\r
-               "reset": createButtonFunction("reset"),\r
+               "submit": createButtonPseudo("submit"),\r
+               "reset": createButtonPseudo("reset"),\r
 \r
                "button": function( elem ) {\r
                        var name = elem.nodeName.toLowerCase();\r
@@ -4319,210 +4507,76 @@ var Expr = Sizzle.selectors = {
 \r
                "focus": function( elem ) {\r
                        var doc = elem.ownerDocument;\r
-                       return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href);\r
+                       return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\r
                },\r
 \r
                "active": function( elem ) {\r
                        return elem === elem.ownerDocument.activeElement;\r
-               }\r
-       },\r
-\r
-       setFilters: {\r
-               "first": function( elements, argument, not ) {\r
-                       return not ? elements.slice( 1 ) : [ elements[0] ];\r
-               },\r
-\r
-               "last": function( elements, argument, not ) {\r
-                       var elem = elements.pop();\r
-                       return not ? elements : [ elem ];\r
-               },\r
-\r
-               "even": function( elements, argument, not ) {\r
-                       var results = [],\r
-                               i = not ? 1 : 0,\r
-                               len = elements.length;\r
-                       for ( ; i < len; i = i + 2 ) {\r
-                               results.push( elements[i] );\r
-                       }\r
-                       return results;\r
-               },\r
-\r
-               "odd": function( elements, argument, not ) {\r
-                       var results = [],\r
-                               i = not ? 0 : 1,\r
-                               len = elements.length;\r
-                       for ( ; i < len; i = i + 2 ) {\r
-                               results.push( elements[i] );\r
-                       }\r
-                       return results;\r
-               },\r
-\r
-               "lt": function( elements, argument, not ) {\r
-                       return not ? elements.slice( +argument ) : elements.slice( 0, +argument );\r
-               },\r
-\r
-               "gt": function( elements, argument, not ) {\r
-                       return not ? elements.slice( 0, +argument + 1 ) : elements.slice( +argument + 1 );\r
-               },\r
-\r
-               "eq": function( elements, argument, not ) {\r
-                       var elem = elements.splice( +argument, 1 );\r
-                       return not ? elements : elem;\r
-               }\r
-       }\r
-};\r
-\r
-// Deprecated\r
-Expr.setFilters["nth"] = Expr.setFilters["eq"];\r
-\r
-// Back-compat\r
-Expr.filters = Expr.pseudos;\r
-\r
-// IE6/7 return a modified href\r
-if ( !assertHrefNotNormalized ) {\r
-       Expr.attrHandle = {\r
-               "href": function( elem ) {\r
-                       return elem.getAttribute( "href", 2 );\r
                },\r
-               "type": function( elem ) {\r
-                       return elem.getAttribute("type");\r
-               }\r
-       };\r
-}\r
-\r
-// Add getElementsByName if usable\r
-if ( assertUsableName ) {\r
-       Expr.order.push("NAME");\r
-       Expr.find["NAME"] = function( name, context ) {\r
-               if ( typeof context.getElementsByName !== strundefined ) {\r
-                       return context.getElementsByName( name );\r
-               }\r
-       };\r
-}\r
-\r
-// Add getElementsByClassName if usable\r
-if ( assertUsableClassName ) {\r
-       Expr.order.splice( 1, 0, "CLASS" );\r
-       Expr.find["CLASS"] = function( className, context, xml ) {\r
-               if ( typeof context.getElementsByClassName !== strundefined && !xml ) {\r
-                       return context.getElementsByClassName( className );\r
-               }\r
-       };\r
-}\r
-\r
-// If slice is not available, provide a backup\r
-try {\r
-       slice.call( docElem.childNodes, 0 )[0].nodeType;\r
-} catch ( e ) {\r
-       slice = function( i ) {\r
-               var elem, results = [];\r
-               for ( ; (elem = this[i]); i++ ) {\r
-                       results.push( elem );\r
-               }\r
-               return results;\r
-       };\r
-}\r
 \r
-var isXML = Sizzle.isXML = function( elem ) {\r
-       // documentElement is verified for cases where it doesn't yet exist\r
-       // (such as loading iframes in IE - #4833)\r
-       var documentElement = elem && (elem.ownerDocument || elem).documentElement;\r
-       return documentElement ? documentElement.nodeName !== "HTML" : false;\r
-};\r
+               // Positional types\r
+               "first": createPositionalPseudo(function() {\r
+                       return [ 0 ];\r
+               }),\r
 \r
-// Element contains another\r
-var contains = Sizzle.contains = docElem.compareDocumentPosition ?\r
-       function( a, b ) {\r
-               return !!( a.compareDocumentPosition( b ) & 16 );\r
-       } :\r
-       docElem.contains ?\r
-       function( a, b ) {\r
-               var adown = a.nodeType === 9 ? a.documentElement : a,\r
-                       bup = b.parentNode;\r
-               return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) );\r
-       } :\r
-       function( a, b ) {\r
-               while ( (b = b.parentNode) ) {\r
-                       if ( b === a ) {\r
-                               return true;\r
-                       }\r
-               }\r
-               return false;\r
-       };\r
+               "last": createPositionalPseudo(function( matchIndexes, length ) {\r
+                       return [ length - 1 ];\r
+               }),\r
 \r
-/**\r
- * Utility function for retrieving the text value of an array of DOM nodes\r
- * @param {Array|Element} elem\r
- */\r
-var getText = Sizzle.getText = function( elem ) {\r
-       var node,\r
-               ret = "",\r
-               i = 0,\r
-               nodeType = elem.nodeType;\r
+               "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {\r
+                       return [ argument < 0 ? argument + length : argument ];\r
+               }),\r
 \r
-       if ( nodeType ) {\r
-               if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\r
-                       // Use textContent for elements\r
-                       // innerText usage removed for consistency of new lines (see #11153)\r
-                       if ( typeof elem.textContent === "string" ) {\r
-                               return elem.textContent;\r
-                       } else {\r
-                               // Traverse its children\r
-                               for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\r
-                                       ret += getText( elem );\r
-                               }\r
+               "even": createPositionalPseudo(function( matchIndexes, length ) {\r
+                       for ( var i = 0; i < length; i += 2 ) {\r
+                               matchIndexes.push( i );\r
                        }\r
-               } else if ( nodeType === 3 || nodeType === 4 ) {\r
-                       return elem.nodeValue;\r
-               }\r
-               // Do not include comment or processing instruction nodes\r
-       } else {\r
+                       return matchIndexes;\r
+               }),\r
 \r
-               // If no nodeType, this is expected to be an array\r
-               for ( ; (node = elem[i]); i++ ) {\r
-                       // Do not traverse comment nodes\r
-                       ret += getText( node );\r
-               }\r
-       }\r
-       return ret;\r
-};\r
+               "odd": createPositionalPseudo(function( matchIndexes, length ) {\r
+                       for ( var i = 1; i < length; i += 2 ) {\r
+                               matchIndexes.push( i );\r
+                       }\r
+                       return matchIndexes;\r
+               }),\r
 \r
-Sizzle.attr = function( elem, name ) {\r
-       var attr,\r
-               xml = isXML( elem );\r
+               "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {\r
+                       for ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) {\r
+                               matchIndexes.push( i );\r
+                       }\r
+                       return matchIndexes;\r
+               }),\r
 \r
-       if ( !xml ) {\r
-               name = name.toLowerCase();\r
-       }\r
-       if ( Expr.attrHandle[ name ] ) {\r
-               return Expr.attrHandle[ name ]( elem );\r
-       }\r
-       if ( assertAttributes || xml ) {\r
-               return elem.getAttribute( name );\r
+               "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {\r
+                       for ( var i = argument < 0 ? argument + length : argument; ++i < length; ) {\r
+                               matchIndexes.push( i );\r
+                       }\r
+                       return matchIndexes;\r
+               })\r
        }\r
-       attr = elem.getAttributeNode( name );\r
-       return attr ?\r
-               typeof elem[ name ] === "boolean" ?\r
-                       elem[ name ] ? name : null :\r
-                       attr.specified ? attr.value : null :\r
-               null;\r
 };\r
 \r
-Sizzle.error = function( msg ) {\r
-       throw new Error( "Syntax error, unrecognized expression: " + msg );\r
-};\r
+function siblingCheck( a, b, ret ) {\r
+       if ( a === b ) {\r
+               return ret;\r
+       }\r
+\r
+       var cur = a.nextSibling;\r
+\r
+       while ( cur ) {\r
+               if ( cur === b ) {\r
+                       return -1;\r
+               }\r
 \r
-// Check if the JavaScript engine is using some sort of\r
-// optimization where it does not always call our comparision\r
-// function. If that is the case, discard the hasDuplicate value.\r
-//   Thus far that includes Google Chrome.\r
-[0, 0].sort(function() {\r
-       return (baseHasDuplicate = 0);\r
-});\r
+               cur = cur.nextSibling;\r
+       }\r
 \r
+       return 1;\r
+}\r
 \r
-if ( docElem.compareDocumentPosition ) {\r
-       sortOrder = function( a, b ) {\r
+sortOrder = docElem.compareDocumentPosition ?\r
+       function( a, b ) {\r
                if ( a === b ) {\r
                        hasDuplicate = true;\r
                        return 0;\r
@@ -4532,10 +4586,8 @@ if ( docElem.compareDocumentPosition ) {
                        a.compareDocumentPosition :\r
                        a.compareDocumentPosition(b) & 4\r
                ) ? -1 : 1;\r
-       };\r
-\r
-} else {\r
-       sortOrder = function( a, b ) {\r
+       } :\r
+       function( a, b ) {\r
                // The nodes are identical, we can exit early\r
                if ( a === b ) {\r
                        hasDuplicate = true;\r
@@ -4595,397 +4647,532 @@ if ( docElem.compareDocumentPosition ) {
                        siblingCheck( ap[i], b, 1 );\r
        };\r
 \r
-       siblingCheck = function( a, b, ret ) {\r
-               if ( a === b ) {\r
-                       return ret;\r
-               }\r
-\r
-               var cur = a.nextSibling;\r
-\r
-               while ( cur ) {\r
-                       if ( cur === b ) {\r
-                               return -1;\r
-                       }\r
-\r
-                       cur = cur.nextSibling;\r
-               }\r
-\r
-               return 1;\r
-       };\r
-}\r
+// Always assume the presence of duplicates if sort doesn't\r
+// pass them to our comparison function (as in Google Chrome).\r
+[0, 0].sort( sortOrder );\r
+baseHasDuplicate = !hasDuplicate;\r
 \r
 // Document sorting and removing duplicates\r
 Sizzle.uniqueSort = function( results ) {\r
        var elem,\r
-               i = 1;\r
+               duplicates = [],\r
+               i = 1,\r
+               j = 0;\r
 \r
-       if ( sortOrder ) {\r
-               hasDuplicate = baseHasDuplicate;\r
-               results.sort( sortOrder );\r
+       hasDuplicate = baseHasDuplicate;\r
+       results.sort( sortOrder );\r
 \r
-               if ( hasDuplicate ) {\r
-                       for ( ; (elem = results[i]); i++ ) {\r
-                               if ( elem === results[ i - 1 ] ) {\r
-                                       results.splice( i--, 1 );\r
-                               }\r
+       if ( hasDuplicate ) {\r
+               for ( ; (elem = results[i]); i++ ) {\r
+                       if ( elem === results[ i - 1 ] ) {\r
+                               j = duplicates.push( i );\r
                        }\r
                }\r
+               while ( j-- ) {\r
+                       results.splice( duplicates[ j ], 1 );\r
+               }\r
        }\r
 \r
        return results;\r
 };\r
 \r
-function multipleContexts( selector, contexts, results, seed ) {\r
-       var i = 0,\r
-               len = contexts.length;\r
-       for ( ; i < len; i++ ) {\r
-               Sizzle( selector, contexts[i], results, seed );\r
-       }\r
-}\r
-\r
-function handlePOSGroup( selector, posfilter, argument, contexts, seed, not ) {\r
-       var results,\r
-               fn = Expr.setFilters[ posfilter.toLowerCase() ];\r
+Sizzle.error = function( msg ) {\r
+       throw new Error( "Syntax error, unrecognized expression: " + msg );\r
+};\r
 \r
-       if ( !fn ) {\r
-               Sizzle.error( posfilter );\r
-       }\r
+function tokenize( selector, parseOnly ) {\r
+       var matched, match, tokens, type,\r
+               soFar, groups, preFilters,\r
+               cached = tokenCache[ expando ][ selector + " " ];\r
 \r
-       if ( selector || !(results = seed) ) {\r
-               multipleContexts( selector || "*", contexts, (results = []), seed );\r
+       if ( cached ) {\r
+               return parseOnly ? 0 : cached.slice( 0 );\r
        }\r
 \r
-       return results.length > 0 ? fn( results, argument, not ) : [];\r
-}\r
-\r
-function handlePOS( selector, context, results, seed, groups ) {\r
-       var match, not, anchor, ret, elements, currentContexts, part, lastIndex,\r
-               i = 0,\r
-               len = groups.length,\r
-               rpos = matchExpr["POS"],\r
-               // This is generated here in case matchExpr["POS"] is extended\r
-               rposgroups = new RegExp( "^" + rpos.source + "(?!" + whitespace + ")", "i" ),\r
-               // This is for making sure non-participating\r
-               // matching groups are represented cross-browser (IE6-8)\r
-               setUndefined = function() {\r
-                       var i = 1,\r
-                               len = arguments.length - 2;\r
-                       for ( ; i < len; i++ ) {\r
-                               if ( arguments[i] === undefined ) {\r
-                                       match[i] = undefined;\r
-                               }\r
-                       }\r
-               };\r
-\r
-       for ( ; i < len; i++ ) {\r
-               // Reset regex index to 0\r
-               rpos.exec("");\r
-               selector = groups[i];\r
-               ret = [];\r
-               anchor = 0;\r
-               elements = seed;\r
-               while ( (match = rpos.exec( selector )) ) {\r
-                       lastIndex = rpos.lastIndex = match.index + match[0].length;\r
-                       if ( lastIndex > anchor ) {\r
-                               part = selector.slice( anchor, match.index );\r
-                               anchor = lastIndex;\r
-                               currentContexts = [ context ];\r
-\r
-                               if ( rcombinators.test(part) ) {\r
-                                       if ( elements ) {\r
-                                               currentContexts = elements;\r
-                                       }\r
-                                       elements = seed;\r
-                               }\r
-\r
-                               if ( (not = rendsWithNot.test( part )) ) {\r
-                                       part = part.slice( 0, -5 ).replace( rcombinators, "$&*" );\r
-                               }\r
-\r
-                               if ( match.length > 1 ) {\r
-                                       match[0].replace( rposgroups, setUndefined );\r
-                               }\r
-                               elements = handlePOSGroup( part, match[1], match[2], currentContexts, elements, not );\r
-                       }\r
-               }\r
+       soFar = selector;\r
+       groups = [];\r
+       preFilters = Expr.preFilter;\r
 \r
-               if ( elements ) {\r
-                       ret = ret.concat( elements );\r
+       while ( soFar ) {\r
 \r
-                       if ( (part = selector.slice( anchor )) && part !== ")" ) {\r
-                               if ( rcombinators.test(part) ) {\r
-                                       multipleContexts( part, ret, results, seed );\r
-                               } else {\r
-                                       Sizzle( part, context, results, seed ? seed.concat(elements) : elements );\r
-                               }\r
-                       } else {\r
-                               push.apply( results, ret );\r
+               // Comma and first run\r
+               if ( !matched || (match = rcomma.exec( soFar )) ) {\r
+                       if ( match ) {\r
+                               // Don't consume trailing commas as valid\r
+                               soFar = soFar.slice( match[0].length ) || soFar;\r
                        }\r
-               } else {\r
-                       Sizzle( selector, context, results, seed );\r
+                       groups.push( tokens = [] );\r
                }\r
-       }\r
 \r
-       // Do not sort if this is a single filter\r
-       return len === 1 ? results : Sizzle.uniqueSort( results );\r
-}\r
-\r
-function tokenize( selector, context, xml ) {\r
-       var tokens, soFar, type,\r
-               groups = [],\r
-               i = 0,\r
-\r
-               // Catch obvious selector issues: terminal ")"; nonempty fallback match\r
-               // rselector never fails to match *something*\r
-               match = rselector.exec( selector ),\r
-               matched = !match.pop() && !match.pop(),\r
-               selectorGroups = matched && selector.match( rgroups ) || [""],\r
+               matched = false;\r
 \r
-               preFilters = Expr.preFilter,\r
-               filters = Expr.filter,\r
-               checkContext = !xml && context !== document;\r
+               // Combinators\r
+               if ( (match = rcombinators.exec( soFar )) ) {\r
+                       tokens.push( matched = new Token( match.shift() ) );\r
+                       soFar = soFar.slice( matched.length );\r
 \r
-       for ( ; (soFar = selectorGroups[i]) != null && matched; i++ ) {\r
-               groups.push( tokens = [] );\r
-\r
-               // Need to make sure we're within a narrower context if necessary\r
-               // Adding a descendant combinator will generate what is needed\r
-               if ( checkContext ) {\r
-                       soFar = " " + soFar;\r
+                       // Cast descendant combinators to space\r
+                       matched.type = match[0].replace( rtrim, " " );\r
                }\r
 \r
-               while ( soFar ) {\r
-                       matched = false;\r
-\r
-                       // Combinators\r
-                       if ( (match = rcombinators.exec( soFar )) ) {\r
-                               soFar = soFar.slice( match[0].length );\r
-\r
-                               // Cast descendant combinators to space\r
-                               matched = tokens.push({ part: match.pop().replace( rtrim, " " ), captures: match });\r
-                       }\r
-\r
-                       // Filters\r
-                       for ( type in filters ) {\r
-                               if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\r
-                                       (match = preFilters[ type ]( match, context, xml )) ) ) {\r
-\r
-                                       soFar = soFar.slice( match.shift().length );\r
-                                       matched = tokens.push({ part: type, captures: match });\r
-                               }\r
-                       }\r
+               // Filters\r
+               for ( type in Expr.filter ) {\r
+                       if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\r
+                               (match = preFilters[ type ]( match ))) ) {\r
 \r
-                       if ( !matched ) {\r
-                               break;\r
+                               tokens.push( matched = new Token( match.shift() ) );\r
+                               soFar = soFar.slice( matched.length );\r
+                               matched.type = type;\r
+                               matched.matches = match;\r
                        }\r
                }\r
-       }\r
 \r
-       if ( !matched ) {\r
-               Sizzle.error( selector );\r
+               if ( !matched ) {\r
+                       break;\r
+               }\r
        }\r
 \r
-       return groups;\r
+       // Return the length of the invalid excess\r
+       // if we're just parsing\r
+       // Otherwise, throw an error or return tokens\r
+       return parseOnly ?\r
+               soFar.length :\r
+               soFar ?\r
+                       Sizzle.error( selector ) :\r
+                       // Cache the tokens\r
+                       tokenCache( selector, groups ).slice( 0 );\r
 }\r
 \r
-function addCombinator( matcher, combinator, context ) {\r
+function addCombinator( matcher, combinator, base ) {\r
        var dir = combinator.dir,\r
+               checkNonElements = base && combinator.dir === "parentNode",\r
                doneName = done++;\r
 \r
-       if ( !matcher ) {\r
-               // If there is no matcher to check, check against the context\r
-               matcher = function( elem ) {\r
-                       return elem === context;\r
-               };\r
-       }\r
        return combinator.first ?\r
-               function( elem, context ) {\r
+               // Check against closest ancestor/preceding element\r
+               function( elem, context, xml ) {\r
                        while ( (elem = elem[ dir ]) ) {\r
-                               if ( elem.nodeType === 1 ) {\r
-                                       return matcher( elem, context ) && elem;\r
+                               if ( checkNonElements || elem.nodeType === 1  ) {\r
+                                       return matcher( elem, context, xml );\r
                                }\r
                        }\r
                } :\r
-               function( elem, context ) {\r
-                       var cache,\r
-                               dirkey = doneName + "." + dirruns,\r
-                               cachedkey = dirkey + "." + cachedruns;\r
-                       while ( (elem = elem[ dir ]) ) {\r
-                               if ( elem.nodeType === 1 ) {\r
-                                       if ( (cache = elem[ expando ]) === cachedkey ) {\r
-                                               return elem.sizset;\r
-                                       } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) {\r
-                                               if ( elem.sizset ) {\r
-                                                       return elem;\r
+\r
+               // Check against all ancestor/preceding elements\r
+               function( elem, context, xml ) {\r
+                       // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching\r
+                       if ( !xml ) {\r
+                               var cache,\r
+                                       dirkey = dirruns + " " + doneName + " ",\r
+                                       cachedkey = dirkey + cachedruns;\r
+                               while ( (elem = elem[ dir ]) ) {\r
+                                       if ( checkNonElements || elem.nodeType === 1 ) {\r
+                                               if ( (cache = elem[ expando ]) === cachedkey ) {\r
+                                                       return elem.sizset;\r
+                                               } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) {\r
+                                                       if ( elem.sizset ) {\r
+                                                               return elem;\r
+                                                       }\r
+                                               } else {\r
+                                                       elem[ expando ] = cachedkey;\r
+                                                       if ( matcher( elem, context, xml ) ) {\r
+                                                               elem.sizset = true;\r
+                                                               return elem;\r
+                                                       }\r
+                                                       elem.sizset = false;\r
                                                }\r
-                                       } else {\r
-                                               elem[ expando ] = cachedkey;\r
-                                               if ( matcher( elem, context ) ) {\r
-                                                       elem.sizset = true;\r
+                                       }\r
+                               }\r
+                       } else {\r
+                               while ( (elem = elem[ dir ]) ) {\r
+                                       if ( checkNonElements || elem.nodeType === 1 ) {\r
+                                               if ( matcher( elem, context, xml ) ) {\r
                                                        return elem;\r
                                                }\r
-                                               elem.sizset = false;\r
                                        }\r
                                }\r
                        }\r
                };\r
 }\r
 \r
-function addMatcher( higher, deeper ) {\r
-       return higher ?\r
-               function( elem, context ) {\r
-                       var result = deeper( elem, context );\r
-                       return result && higher( result === true ? elem : result, context );\r
+function elementMatcher( matchers ) {\r
+       return matchers.length > 1 ?\r
+               function( elem, context, xml ) {\r
+                       var i = matchers.length;\r
+                       while ( i-- ) {\r
+                               if ( !matchers[i]( elem, context, xml ) ) {\r
+                                       return false;\r
+                               }\r
+                       }\r
+                       return true;\r
                } :\r
-               deeper;\r
+               matchers[0];\r
 }\r
 \r
-// ["TAG", ">", "ID", " ", "CLASS"]\r
-function matcherFromTokens( tokens, context, xml ) {\r
-       var token, matcher,\r
-               i = 0;\r
+function condense( unmatched, map, filter, context, xml ) {\r
+       var elem,\r
+               newUnmatched = [],\r
+               i = 0,\r
+               len = unmatched.length,\r
+               mapped = map != null;\r
 \r
-       for ( ; (token = tokens[i]); i++ ) {\r
-               if ( Expr.relative[ token.part ] ) {\r
-                       matcher = addCombinator( matcher, Expr.relative[ token.part ], context );\r
-               } else {\r
-                       token.captures.push( context, xml );\r
-                       matcher = addMatcher( matcher, Expr.filter[ token.part ].apply( null, token.captures ) );\r
+       for ( ; i < len; i++ ) {\r
+               if ( (elem = unmatched[i]) ) {\r
+                       if ( !filter || filter( elem, context, xml ) ) {\r
+                               newUnmatched.push( elem );\r
+                               if ( mapped ) {\r
+                                       map.push( i );\r
+                               }\r
+                       }\r
                }\r
        }\r
 \r
-       return matcher;\r
+       return newUnmatched;\r
 }\r
 \r
-function matcherFromGroupMatchers( matchers ) {\r
-       return function( elem, context ) {\r
-               var matcher,\r
-                       j = 0;\r
-               for ( ; (matcher = matchers[j]); j++ ) {\r
-                       if ( matcher(elem, context) ) {\r
-                               return true;\r
-                       }\r
+function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\r
+       if ( postFilter && !postFilter[ expando ] ) {\r
+               postFilter = setMatcher( postFilter );\r
+       }\r
+       if ( postFinder && !postFinder[ expando ] ) {\r
+               postFinder = setMatcher( postFinder, postSelector );\r
+       }\r
+       return markFunction(function( seed, results, context, xml ) {\r
+               var temp, i, elem,\r
+                       preMap = [],\r
+                       postMap = [],\r
+                       preexisting = results.length,\r
+\r
+                       // Get initial elements from seed or context\r
+                       elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),\r
+\r
+                       // Prefilter to get matcher input, preserving a map for seed-results synchronization\r
+                       matcherIn = preFilter && ( seed || !selector ) ?\r
+                               condense( elems, preMap, preFilter, context, xml ) :\r
+                               elems,\r
+\r
+                       matcherOut = matcher ?\r
+                               // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\r
+                               postFinder || ( seed ? preFilter : preexisting || postFilter ) ?\r
+\r
+                                       // ...intermediate processing is necessary\r
+                                       [] :\r
+\r
+                                       // ...otherwise use results directly\r
+                                       results :\r
+                               matcherIn;\r
+\r
+               // Find primary matches\r
+               if ( matcher ) {\r
+                       matcher( matcherIn, matcherOut, context, xml );\r
                }\r
-               return false;\r
-       };\r
-}\r
 \r
-var compile = Sizzle.compile = function( selector, context, xml ) {\r
-       var tokens, group, i,\r
-               cached = compilerCache[ selector ];\r
+               // Apply postFilter\r
+               if ( postFilter ) {\r
+                       temp = condense( matcherOut, postMap );\r
+                       postFilter( temp, [], context, xml );\r
 \r
-       // Return a cached group function if already generated (context dependent)\r
-       if ( cached && cached.context === context ) {\r
-               return cached;\r
-       }\r
+                       // Un-match failing elements by moving them back to matcherIn\r
+                       i = temp.length;\r
+                       while ( i-- ) {\r
+                               if ( (elem = temp[i]) ) {\r
+                                       matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\r
+                               }\r
+                       }\r
+               }\r
 \r
-       // Generate a function of recursive functions that can be used to check each element\r
-       group = tokenize( selector, context, xml );\r
-       for ( i = 0; (tokens = group[i]); i++ ) {\r
-               group[i] = matcherFromTokens( tokens, context, xml );\r
-       }\r
+               if ( seed ) {\r
+                       if ( postFinder || preFilter ) {\r
+                               if ( postFinder ) {\r
+                                       // Get the final matcherOut by condensing this intermediate into postFinder contexts\r
+                                       temp = [];\r
+                                       i = matcherOut.length;\r
+                                       while ( i-- ) {\r
+                                               if ( (elem = matcherOut[i]) ) {\r
+                                                       // Restore matcherIn since elem is not yet a final match\r
+                                                       temp.push( (matcherIn[i] = elem) );\r
+                                               }\r
+                                       }\r
+                                       postFinder( null, (matcherOut = []), temp, xml );\r
+                               }\r
 \r
-       // Cache the compiled function\r
-       cached = compilerCache[ selector ] = matcherFromGroupMatchers( group );\r
-       cached.context = context;\r
-       cached.runs = cached.dirruns = 0;\r
-       cachedSelectors.push( selector );\r
-       // Ensure only the most recent are cached\r
-       if ( cachedSelectors.length > Expr.cacheLength ) {\r
-               delete compilerCache[ cachedSelectors.shift() ];\r
-       }\r
-       return cached;\r
-};\r
+                               // Move matched elements from seed to results to keep them synchronized\r
+                               i = matcherOut.length;\r
+                               while ( i-- ) {\r
+                                       if ( (elem = matcherOut[i]) &&\r
+                                               (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {\r
 \r
-Sizzle.matches = function( expr, elements ) {\r
-       return Sizzle( expr, null, null, elements );\r
-};\r
+                                               seed[temp] = !(results[temp] = elem);\r
+                                       }\r
+                               }\r
+                       }\r
 \r
-Sizzle.matchesSelector = function( elem, expr ) {\r
-       return Sizzle( expr, null, null, [ elem ] ).length > 0;\r
-};\r
+               // Add elements to results, through postFinder if defined\r
+               } else {\r
+                       matcherOut = condense(\r
+                               matcherOut === results ?\r
+                                       matcherOut.splice( preexisting, matcherOut.length ) :\r
+                                       matcherOut\r
+                       );\r
+                       if ( postFinder ) {\r
+                               postFinder( null, results, matcherOut, xml );\r
+                       } else {\r
+                               push.apply( results, matcherOut );\r
+                       }\r
+               }\r
+       });\r
+}\r
 \r
-var select = function( selector, context, results, seed, xml ) {\r
-       // Remove excessive whitespace\r
-       selector = selector.replace( rtrim, "$1" );\r
-       var elements, matcher, i, len, elem, token,\r
-               type, findContext, notTokens,\r
-               match = selector.match( rgroups ),\r
-               tokens = selector.match( rtokens ),\r
-               contextNodeType = context.nodeType;\r
-\r
-       // POS handling\r
-       if ( matchExpr["POS"].test(selector) ) {\r
-               return handlePOS( selector, context, results, seed, match );\r
+function matcherFromTokens( tokens ) {\r
+       var checkContext, matcher, j,\r
+               len = tokens.length,\r
+               leadingRelative = Expr.relative[ tokens[0].type ],\r
+               implicitRelative = leadingRelative || Expr.relative[" "],\r
+               i = leadingRelative ? 1 : 0,\r
+\r
+               // The foundational matcher ensures that elements are reachable from top-level context(s)\r
+               matchContext = addCombinator( function( elem ) {\r
+                       return elem === checkContext;\r
+               }, implicitRelative, true ),\r
+               matchAnyContext = addCombinator( function( elem ) {\r
+                       return indexOf.call( checkContext, elem ) > -1;\r
+               }, implicitRelative, true ),\r
+               matchers = [ function( elem, context, xml ) {\r
+                       return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\r
+                               (checkContext = context).nodeType ?\r
+                                       matchContext( elem, context, xml ) :\r
+                                       matchAnyContext( elem, context, xml ) );\r
+               } ];\r
+\r
+       for ( ; i < len; i++ ) {\r
+               if ( (matcher = Expr.relative[ tokens[i].type ]) ) {\r
+                       matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];\r
+               } else {\r
+                       matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\r
+\r
+                       // Return special upon seeing a positional matcher\r
+                       if ( matcher[ expando ] ) {\r
+                               // Find the next relative operator (if any) for proper handling\r
+                               j = ++i;\r
+                               for ( ; j < len; j++ ) {\r
+                                       if ( Expr.relative[ tokens[j].type ] ) {\r
+                                               break;\r
+                                       }\r
+                               }\r
+                               return setMatcher(\r
+                                       i > 1 && elementMatcher( matchers ),\r
+                                       i > 1 && tokens.slice( 0, i - 1 ).join("").replace( rtrim, "$1" ),\r
+                                       matcher,\r
+                                       i < j && matcherFromTokens( tokens.slice( i, j ) ),\r
+                                       j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\r
+                                       j < len && tokens.join("")\r
+                               );\r
+                       }\r
+                       matchers.push( matcher );\r
+               }\r
        }\r
 \r
-       if ( seed ) {\r
-               elements = slice.call( seed, 0 );\r
+       return elementMatcher( matchers );\r
+}\r
+\r
+function matcherFromGroupMatchers( elementMatchers, setMatchers ) {\r
+       var bySet = setMatchers.length > 0,\r
+               byElement = elementMatchers.length > 0,\r
+               superMatcher = function( seed, context, xml, results, expandContext ) {\r
+                       var elem, j, matcher,\r
+                               setMatched = [],\r
+                               matchedCount = 0,\r
+                               i = "0",\r
+                               unmatched = seed && [],\r
+                               outermost = expandContext != null,\r
+                               contextBackup = outermostContext,\r
+                               // We must always have either seed elements or context\r
+                               elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ),\r
+                               // Nested matchers should use non-integer dirruns\r
+                               dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E);\r
+\r
+                       if ( outermost ) {\r
+                               outermostContext = context !== document && context;\r
+                               cachedruns = superMatcher.el;\r
+                       }\r
 \r
-       // To maintain document order, only narrow the\r
-       // set if there is one group\r
-       } else if ( match && match.length === 1 ) {\r
+                       // Add elements passing elementMatchers directly to results\r
+                       for ( ; (elem = elems[i]) != null; i++ ) {\r
+                               if ( byElement && elem ) {\r
+                                       for ( j = 0; (matcher = elementMatchers[j]); j++ ) {\r
+                                               if ( matcher( elem, context, xml ) ) {\r
+                                                       results.push( elem );\r
+                                                       break;\r
+                                               }\r
+                                       }\r
+                                       if ( outermost ) {\r
+                                               dirruns = dirrunsUnique;\r
+                                               cachedruns = ++superMatcher.el;\r
+                                       }\r
+                               }\r
 \r
-               // Take a shortcut and set the context if the root selector is an ID\r
-               if ( tokens.length > 1 && contextNodeType === 9 && !xml &&\r
-                               (match = matchExpr["ID"].exec( tokens[0] )) ) {\r
+                               // Track unmatched elements for set filters\r
+                               if ( bySet ) {\r
+                                       // They will have gone through all possible matchers\r
+                                       if ( (elem = !matcher && elem) ) {\r
+                                               matchedCount--;\r
+                                       }\r
 \r
-                       context = Expr.find["ID"]( match[1], context, xml )[0];\r
-                       if ( !context ) {\r
-                               return results;\r
+                                       // Lengthen the array for every element, matched or not\r
+                                       if ( seed ) {\r
+                                               unmatched.push( elem );\r
+                                       }\r
+                               }\r
                        }\r
 \r
-                       selector = selector.slice( tokens.shift().length );\r
-               }\r
+                       // Apply set filters to unmatched elements\r
+                       matchedCount += i;\r
+                       if ( bySet && i !== matchedCount ) {\r
+                               for ( j = 0; (matcher = setMatchers[j]); j++ ) {\r
+                                       matcher( unmatched, setMatched, context, xml );\r
+                               }\r
 \r
-               findContext = ( (match = rsibling.exec( tokens[0] )) && !match.index && context.parentNode ) || context;\r
+                               if ( seed ) {\r
+                                       // Reintegrate element matches to eliminate the need for sorting\r
+                                       if ( matchedCount > 0 ) {\r
+                                               while ( i-- ) {\r
+                                                       if ( !(unmatched[i] || setMatched[i]) ) {\r
+                                                               setMatched[i] = pop.call( results );\r
+                                                       }\r
+                                               }\r
+                                       }\r
 \r
-               // Get the last token, excluding :not\r
-               notTokens = tokens.pop();\r
-               token = notTokens.split(":not")[0];\r
+                                       // Discard index placeholder values to get only actual matches\r
+                                       setMatched = condense( setMatched );\r
+                               }\r
 \r
-               for ( i = 0, len = Expr.order.length; i < len; i++ ) {\r
-                       type = Expr.order[i];\r
+                               // Add matches to results\r
+                               push.apply( results, setMatched );\r
 \r
-                       if ( (match = matchExpr[ type ].exec( token )) ) {\r
-                               elements = Expr.find[ type ]( (match[1] || "").replace( rbackslash, "" ), findContext, xml );\r
+                               // Seedless set matches succeeding multiple successful matchers stipulate sorting\r
+                               if ( outermost && !seed && setMatched.length > 0 &&\r
+                                       ( matchedCount + setMatchers.length ) > 1 ) {\r
 \r
-                               if ( elements == null ) {\r
-                                       continue;\r
+                                       Sizzle.uniqueSort( results );\r
                                }\r
+                       }\r
 \r
-                               if ( token === notTokens ) {\r
-                                       selector = selector.slice( 0, selector.length - notTokens.length ) +\r
-                                               token.replace( matchExpr[ type ], "" );\r
+                       // Override manipulation of globals by nested matchers\r
+                       if ( outermost ) {\r
+                               dirruns = dirrunsUnique;\r
+                               outermostContext = contextBackup;\r
+                       }\r
 \r
-                                       if ( !selector ) {\r
-                                               push.apply( results, slice.call(elements, 0) );\r
-                                       }\r
-                               }\r
-                               break;\r
+                       return unmatched;\r
+               };\r
+\r
+       superMatcher.el = 0;\r
+       return bySet ?\r
+               markFunction( superMatcher ) :\r
+               superMatcher;\r
+}\r
+\r
+compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {\r
+       var i,\r
+               setMatchers = [],\r
+               elementMatchers = [],\r
+               cached = compilerCache[ expando ][ selector + " " ];\r
+\r
+       if ( !cached ) {\r
+               // Generate a function of recursive functions that can be used to check each element\r
+               if ( !group ) {\r
+                       group = tokenize( selector );\r
+               }\r
+               i = group.length;\r
+               while ( i-- ) {\r
+                       cached = matcherFromTokens( group[i] );\r
+                       if ( cached[ expando ] ) {\r
+                               setMatchers.push( cached );\r
+                       } else {\r
+                               elementMatchers.push( cached );\r
                        }\r
                }\r
+\r
+               // Cache the compiled function\r
+               cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\r
+       }\r
+       return cached;\r
+};\r
+\r
+function multipleContexts( selector, contexts, results ) {\r
+       var i = 0,\r
+               len = contexts.length;\r
+       for ( ; i < len; i++ ) {\r
+               Sizzle( selector, contexts[i], results );\r
        }\r
+       return results;\r
+}\r
 \r
-       // Only loop over the given elements once\r
-       // If selector is empty, we're already done\r
-       if ( selector ) {\r
-               matcher = compile( selector, context, xml );\r
-               dirruns = matcher.dirruns++;\r
+function select( selector, context, results, seed, xml ) {\r
+       var i, tokens, token, type, find,\r
+               match = tokenize( selector ),\r
+               j = match.length;\r
 \r
-               if ( elements == null ) {\r
-                       elements = Expr.find["TAG"]( "*", (rsibling.test( selector ) && context.parentNode) || context );\r
-               }\r
-               for ( i = 0; (elem = elements[i]); i++ ) {\r
-                       cachedruns = matcher.runs++;\r
-                       if ( matcher(elem, context) ) {\r
-                               results.push( elem );\r
+       if ( !seed ) {\r
+               // Try to minimize operations if there is only one group\r
+               if ( match.length === 1 ) {\r
+\r
+                       // Take a shortcut and set the context if the root selector is an ID\r
+                       tokens = match[0] = match[0].slice( 0 );\r
+                       if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&\r
+                                       context.nodeType === 9 && !xml &&\r
+                                       Expr.relative[ tokens[1].type ] ) {\r
+\r
+                               context = Expr.find["ID"]( token.matches[0].replace( rbackslash, "" ), context, xml )[0];\r
+                               if ( !context ) {\r
+                                       return results;\r
+                               }\r
+\r
+                               selector = selector.slice( tokens.shift().length );\r
+                       }\r
+\r
+                       // Fetch a seed set for right-to-left matching\r
+                       for ( i = matchExpr["POS"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) {\r
+                               token = tokens[i];\r
+\r
+                               // Abort if we hit a combinator\r
+                               if ( Expr.relative[ (type = token.type) ] ) {\r
+                                       break;\r
+                               }\r
+                               if ( (find = Expr.find[ type ]) ) {\r
+                                       // Search, expanding context for leading sibling combinators\r
+                                       if ( (seed = find(\r
+                                               token.matches[0].replace( rbackslash, "" ),\r
+                                               rsibling.test( tokens[0].type ) && context.parentNode || context,\r
+                                               xml\r
+                                       )) ) {\r
+\r
+                                               // If seed is empty or no tokens remain, we can return early\r
+                                               tokens.splice( i, 1 );\r
+                                               selector = seed.length && tokens.join("");\r
+                                               if ( !selector ) {\r
+                                                       push.apply( results, slice.call( seed, 0 ) );\r
+                                                       return results;\r
+                                               }\r
+\r
+                                               break;\r
+                                       }\r
+                               }\r
                        }\r
                }\r
        }\r
 \r
+       // Compile and execute a filtering function\r
+       // Provide `match` to avoid retokenization if we modified the selector above\r
+       compile( selector, match )(\r
+               seed,\r
+               context,\r
+               xml,\r
+               results,\r
+               rsibling.test( selector )\r
+       );\r
        return results;\r
-};\r
+}\r
 \r
 if ( document.querySelectorAll ) {\r
        (function() {\r
@@ -4993,11 +5180,15 @@ if ( document.querySelectorAll ) {
                        oldSelect = select,\r
                        rescape = /'|\\/g,\r
                        rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,\r
-                       rbuggyQSA = [],\r
+\r
+                       // qSa(:focus) reports false when true (Chrome 21), no need to also add to buggyMatches since matches checks buggyQSA\r
+                       // A support test would require too much code (would include document ready)\r
+                       rbuggyQSA = [ ":focus" ],\r
+\r
                        // matchesSelector(:active) reports false when true (IE9/Opera 11.5)\r
                        // A support test would require too much code (would include document ready)\r
                        // just skip matchesSelector for :active\r
-                       rbuggyMatches = [":active"],\r
+                       rbuggyMatches = [ ":active" ],\r
                        matches = docElem.matchesSelector ||\r
                                docElem.mozMatchesSelector ||\r
                                docElem.webkitMatchesSelector ||\r
@@ -5007,7 +5198,12 @@ if ( document.querySelectorAll ) {
                // Build QSA regex\r
                // Regex strategy adopted from Diego Perini\r
                assert(function( div ) {\r
-                       div.innerHTML = "<select><option selected></option></select>";\r
+                       // Select is set to empty string on purpose\r
+                       // This is to test IE's treatment of not explictly\r
+                       // setting a boolean content attribute,\r
+                       // since its presence should be enough\r
+                       // http://bugs.jquery.com/ticket/12359\r
+                       div.innerHTML = "<select><option selected=''></option></select>";\r
 \r
                        // IE8 - Some boolean attributes are not treated correctly\r
                        if ( !div.querySelectorAll("[selected]").length ) {\r
@@ -5033,42 +5229,52 @@ if ( document.querySelectorAll ) {
 \r
                        // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\r
                        // IE8 throws error here (do not put tests after this one)\r
-                       div.innerHTML = "<input type='hidden'>";\r
+                       div.innerHTML = "<input type='hidden'/>";\r
                        if ( !div.querySelectorAll(":enabled").length ) {\r
                                rbuggyQSA.push(":enabled", ":disabled");\r
                        }\r
                });\r
 \r
-               rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );\r
+               // rbuggyQSA always contains :focus, so no need for a length check\r
+               rbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join("|") );\r
 \r
                select = function( selector, context, results, seed, xml ) {\r
                        // Only use querySelectorAll when not filtering,\r
                        // when this is not xml,\r
                        // and when no QSA bugs apply\r
-                       if ( !seed && !xml && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {\r
-                               if ( context.nodeType === 9 ) {\r
-                                       try {\r
-                                               push.apply( results, slice.call(context.querySelectorAll( selector ), 0) );\r
-                                               return results;\r
-                                       } catch(qsaError) {}\r
+                       if ( !seed && !xml && !rbuggyQSA.test( selector ) ) {\r
+                               var groups, i,\r
+                                       old = true,\r
+                                       nid = expando,\r
+                                       newContext = context,\r
+                                       newSelector = context.nodeType === 9 && selector;\r
+\r
                                // qSA works strangely on Element-rooted queries\r
                                // We can work around this by specifying an extra ID on the root\r
                                // and working up from there (Thanks to Andrew Dupont for the technique)\r
                                // IE 8 doesn't work on object elements\r
-                               } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {\r
-                                       var old = context.getAttribute("id"),\r
-                                               nid = old || expando,\r
-                                               newContext = rsibling.test( selector ) && context.parentNode || context;\r
+                               if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {\r
+                                       groups = tokenize( selector );\r
 \r
-                                       if ( old ) {\r
-                                               nid = nid.replace( rescape, "\\$&" );\r
+                                       if ( (old = context.getAttribute("id")) ) {\r
+                                               nid = old.replace( rescape, "\\$&" );\r
                                        } else {\r
                                                context.setAttribute( "id", nid );\r
                                        }\r
+                                       nid = "[id='" + nid + "'] ";\r
 \r
+                                       i = groups.length;\r
+                                       while ( i-- ) {\r
+                                               groups[i] = nid + groups[i].join("");\r
+                                       }\r
+                                       newContext = rsibling.test( selector ) && context.parentNode || context;\r
+                                       newSelector = groups.join(",");\r
+                               }\r
+\r
+                               if ( newSelector ) {\r
                                        try {\r
                                                push.apply( results, slice.call( newContext.querySelectorAll(\r
-                                                       selector.replace( rgroups, "[id='" + nid + "'] $&" )\r
+                                                       newSelector\r
                                                ), 0 ) );\r
                                                return results;\r
                                        } catch(qsaError) {\r
@@ -5093,11 +5299,11 @@ if ( document.querySelectorAll ) {
                                // Gecko does not error, returns false instead\r
                                try {\r
                                        matches.call( div, "[test!='']:sizzle" );\r
-                                       rbuggyMatches.push( Expr.match.PSEUDO );\r
+                                       rbuggyMatches.push( "!=", pseudos );\r
                                } catch ( e ) {}\r
                        });\r
 \r
-                       // rbuggyMatches always contains :active, so no need for a length check\r
+                       // rbuggyMatches always contains :active and :focus, so no need for a length check\r
                        rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") );\r
 \r
                        Sizzle.matchesSelector = function( elem, expr ) {\r
@@ -5105,7 +5311,7 @@ if ( document.querySelectorAll ) {
                                expr = expr.replace( rattributeQuotes, "='$1']" );\r
 \r
                                // rbuggyMatches always contains :active, so no need for an existence check\r
-                               if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && (!rbuggyQSA || !rbuggyQSA.test( expr )) ) {\r
+                               if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && !rbuggyQSA.test( expr ) ) {\r
                                        try {\r
                                                var ret = matches.call( elem, expr );\r
 \r
@@ -5125,6 +5331,14 @@ if ( document.querySelectorAll ) {
        })();\r
 }\r
 \r
+// Deprecated\r
+Expr.pseudos["nth"] = Expr.pseudos["eq"];\r
+\r
+// Back-compat\r
+function setFilters() {}\r
+Expr.filters = setFilters.prototype = Expr.pseudos;\r
+Expr.setFilters = new setFilters();\r
+\r
 // Override sizzle attribute retrieval
 Sizzle.attr = jQuery.attr;
 jQuery.find = Sizzle;
@@ -5923,15 +6137,11 @@ jQuery.buildFragment = function( args, context, scripts ) {
                first = args[ 0 ];
 
        // Set context from what may come in as undefined or a jQuery collection or a node
+       // Updated to fix #12266 where accessing context[0] could throw an exception in IE9/10 &
+       // also doubles as fix for #8950 where plain objects caused createDocumentFragment exception
        context = context || document;
-       context = (context[0] || context).ownerDocument || context[0] || context;
-
-       // Ensure that an attr object doesn't incorrectly stand in as a document object
-       // Chrome and Firefox seem to allow this to occur and will throw exception
-       // Fixes #8950
-       if ( typeof context.createDocumentFragment === "undefined" ) {
-               context = document;
-       }
+       context = !context.nodeType && context[0] || context;
+       context = context.ownerDocument || context;
 
        // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
        // Cloning options loses the selected state, so don't cache them
@@ -6076,8 +6286,8 @@ jQuery.extend({
        },
 
        clean: function( elems, context, fragment, scripts ) {
-               var j, safe, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags,
-                       i = 0,
+               var i, j, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags,
+                       safe = context === document && safeFragment,
                        ret = [];
 
                // Ensure that context is a document
@@ -6086,7 +6296,7 @@ jQuery.extend({
                }
 
                // Use the already-created safe fragment if context permits
-               for ( safe = context === document && safeFragment; (elem = elems[i]) != null; i++ ) {
+               for ( i = 0; (elem = elems[i]) != null; i++ ) {
                        if ( typeof elem === "number" ) {
                                elem += "";
                        }
@@ -6102,7 +6312,8 @@ jQuery.extend({
                                } else {
                                        // Ensure a safe container in which to render the html
                                        safe = safe || createSafeFragment( context );
-                                       div = div || safe.appendChild( context.createElement("div") );
+                                       div = context.createElement("div");
+                                       safe.appendChild( div );
 
                                        // Fix "XHTML"-style tags in all browsers
                                        elem = elem.replace(rxhtmlTag, "<$1></$2>");
@@ -6145,21 +6356,20 @@ jQuery.extend({
 
                                        elem = div.childNodes;
 
-                                       // Remember the top-level container for proper cleanup
-                                       div = safe.lastChild;
+                                       // Take out of fragment container (we need a fresh div each time)
+                                       div.parentNode.removeChild( div );
                                }
                        }
 
                        if ( elem.nodeType ) {
                                ret.push( elem );
                        } else {
-                               ret = jQuery.merge( ret, elem );
+                               jQuery.merge( ret, elem );
                        }
                }
 
                // Fix #11356: Clear elements from safeFragment
                if ( div ) {
-                       safe.removeChild( div );
                        elem = div = safe = null;
                }
 
@@ -6294,9 +6504,10 @@ if ( matched.browser ) {
        browser.version = matched.version;
 }
 
-// Deprecated, use jQuery.browser.webkit instead
-// Maintained for back-compat only
-if ( browser.webkit ) {
+// Chrome is Webkit, but Webkit is also Safari.
+if ( browser.chrome ) {
+       browser.webkit = true;
+} else if ( browser.webkit ) {
        browser.safari = true;
 }
 
@@ -6322,23 +6533,25 @@ jQuery.sub = function() {
        var rootjQuerySub = jQuerySub(document);
        return jQuerySub;
 };
-       
+
 })();
 var curCSS, iframe, iframeDoc,
        ralpha = /alpha\([^)]*\)/i,
        ropacity = /opacity=([^)]*)/,
        rposition = /^(top|right|bottom|left)$/,
+       // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
+       // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
+       rdisplayswap = /^(none|table(?!-c[ea]).+)/,
        rmargin = /^margin/,
        rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ),
        rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ),
        rrelNum = new RegExp( "^([-+])=(" + core_pnum + ")", "i" ),
-       elemdisplay = {},
+       elemdisplay = { BODY: "block" },
 
        cssShow = { position: "absolute", visibility: "hidden", display: "block" },
        cssNormalTransform = {
                letterSpacing: 0,
-               fontWeight: 400,
-               lineHeight: 1
+               fontWeight: 400
        },
 
        cssExpand = [ "Top", "Right", "Bottom", "Left" ],
@@ -6604,18 +6817,20 @@ jQuery.extend({
        }
 });
 
-// NOTE: To any future maintainer, we've used both window.getComputedStyle
-// and getComputedStyle here to produce a better gzip size
+// NOTE: To any future maintainer, we've window.getComputedStyle
+// because jsdom on node.js will break without it.
 if ( window.getComputedStyle ) {
        curCSS = function( elem, name ) {
                var ret, width, minWidth, maxWidth,
-                       computed = getComputedStyle( elem, null ),
+                       computed = window.getComputedStyle( elem, null ),
                        style = elem.style;
 
                if ( computed ) {
 
-                       ret = computed[ name ];
-                       if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
+                       // getPropertyValue is only needed for .css('filter') in IE9, see #12537
+                       ret = computed.getPropertyValue( name ) || computed[ name ];
+
+                       if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
                                ret = jQuery.style( elem, name );
                        }
 
@@ -6738,7 +6953,10 @@ function getWidthOrHeight( elem, name, extra ) {
                valueIsBorderBox = true,
                isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box";
 
-       if ( val <= 0 ) {
+       // some non-html elements return undefined for offsetWidth, so check for null/undefined
+       // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
+       // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
+       if ( val <= 0 || val == null ) {
                // Fall back to computed then uncomputed css if necessary
                val = curCSS( elem, name );
                if ( val < 0 || val == null ) {
@@ -6817,12 +7035,14 @@ jQuery.each([ "height", "width" ], function( i, name ) {
        jQuery.cssHooks[ name ] = {
                get: function( elem, computed, extra ) {
                        if ( computed ) {
-                               if ( elem.offsetWidth !== 0 || curCSS( elem, "display" ) !== "none" ) {
-                                       return getWidthOrHeight( elem, name, extra );
-                               } else {
+                               // certain elements can have dimension info if we invisibly show them
+                               // however, it must have a current display style that would benefit from this
+                               if ( elem.offsetWidth === 0 && rdisplayswap.test( curCSS( elem, "display" ) ) ) {
                                        return jQuery.swap( elem, cssShow, function() {
                                                return getWidthOrHeight( elem, name, extra );
                                        });
+                               } else {
+                                       return getWidthOrHeight( elem, name, extra );
                                }
                        }
                },
@@ -7056,10 +7276,10 @@ function buildParams( prefix, obj, traditional, add ) {
                add( prefix, obj );
        }
 }
-var // Document location
-       ajaxLocation,
-       // Document location segments
+var
+       // Document location
        ajaxLocParts,
+       ajaxLocation,
 
        rhash = /#.*$/,
        rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
@@ -7228,7 +7448,7 @@ jQuery.fn.load = function( url, params, callback ) {
                params = undefined;
 
        // Otherwise, build a param string
-       } else if ( typeof params === "object" ) {
+       } else if ( params && typeof params === "object" ) {
                type = "POST";
        }
 
@@ -7576,7 +7796,7 @@ jQuery.extend({
 
                        // Set data for the fake xhr object
                        jqXHR.status = status;
-                       jqXHR.statusText = "" + ( nativeStatusText || statusText );
+                       jqXHR.statusText = ( nativeStatusText || statusText ) + "";
 
                        // Success/Error
                        if ( isSuccess ) {
@@ -7636,11 +7856,11 @@ jQuery.extend({
                // Extract dataTypes list
                s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( core_rspace );
 
-               // Determine if a cross-domain request is in order
+               // A cross-domain request is in order when we have a protocol:host:port mismatch
                if ( s.crossDomain == null ) {
                        parts = rurl.exec( s.url.toLowerCase() );
                        s.crossDomain = !!( parts &&
-                               ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
+                               ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
                                        ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
                                                ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
                        );
@@ -8262,7 +8482,7 @@ if ( jQuery.support.ajax ) {
                                                                        // on any attempt to access responseText (#11426)
                                                                        try {
                                                                                responses.text = xhr.responseText;
-                                                                       } catch( _ ) {
+                                                                       } catch( e ) {
                                                                        }
 
                                                                        // Firefox throws an exception when accessing
@@ -8338,12 +8558,13 @@ var fxNow, timerId,
        animationPrefilters = [ defaultPrefilter ],
        tweeners = {
                "*": [function( prop, value ) {
-                       var end, unit, prevScale,
+                       var end, unit,
                                tween = this.createTween( prop, value ),
                                parts = rfxnum.exec( value ),
                                target = tween.cur(),
                                start = +target || 0,
-                               scale = 1;
+                               scale = 1,
+                               maxIterations = 20;
 
                        if ( parts ) {
                                end = +parts[2];
@@ -8359,17 +8580,15 @@ var fxNow, timerId,
                                        do {
                                                // If previous iteration zeroed out, double until we get *something*
                                                // Use a string for doubling factor so we don't accidentally see scale as unchanged below
-                                               prevScale = scale = scale || ".5";
+                                               scale = scale || ".5";
 
                                                // Adjust and apply
                                                start = start / scale;
                                                jQuery.style( tween.elem, prop, start + unit );
 
-                                               // Update scale, tolerating zeroes from tween.cur()
-                                               scale = tween.cur() / target;
-
-                                       // Stop looping if we've hit the mark or scale is unchanged
-                                       } while ( scale !== 1 && scale !== prevScale );
+                                       // Update scale, tolerating zero or NaN from tween.cur()
+                                       // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
+                                       } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
                                }
 
                                tween.unit = unit;
@@ -8416,7 +8635,9 @@ function Animation( elem, properties, options ) {
                tick = function() {
                        var currentTime = fxNow || createFxNow(),
                                remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
-                               percent = 1 - ( remaining / animation.duration || 0 ),
+                               // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
+                               temp = remaining / animation.duration || 0,
+                               percent = 1 - temp,
                                index = 0,
                                length = animation.tweens.length;
 
@@ -8568,7 +8789,7 @@ jQuery.Animation = jQuery.extend( Animation, {
 });
 
 function defaultPrefilter( elem, props, opts ) {
-       var index, prop, value, length, dataShow, tween, hooks, oldfire,
+       var index, prop, value, length, dataShow, toggle, tween, hooks, oldfire,
                anim = this,
                style = elem.style,
                orig = {},
@@ -8642,6 +8863,7 @@ function defaultPrefilter( elem, props, opts ) {
                value = props[ index ];
                if ( rfxtypes.exec( value ) ) {
                        delete props[ index ];
+                       toggle = toggle || value === "toggle";
                        if ( value === ( hidden ? "hide" : "show" ) ) {
                                continue;
                        }
@@ -8652,6 +8874,14 @@ function defaultPrefilter( elem, props, opts ) {
        length = handled.length;
        if ( length ) {
                dataShow = jQuery._data( elem, "fxshow" ) || jQuery._data( elem, "fxshow", {} );
+               if ( "hidden" in dataShow ) {
+                       hidden = dataShow.hidden;
+               }
+
+               // store state if its toggle - enables .stop().toggle() to "reverse"
+               if ( toggle ) {
+                       dataShow.hidden = !hidden;
+               }
                if ( hidden ) {
                        jQuery( elem ).show();
                } else {
@@ -8709,7 +8939,13 @@ Tween.prototype = {
                var eased,
                        hooks = Tween.propHooks[ this.prop ];
 
-               this.pos = eased = jQuery.easing[ this.easing ]( percent, this.options.duration * percent, 0, 1, this.options.duration );
+               if ( this.options.duration ) {
+                       this.pos = eased = jQuery.easing[ this.easing ](
+                               percent, this.options.duration * percent, 0, 1, this.options.duration
+                       );
+               } else {
+                       this.pos = eased = percent;
+               }
                this.now = ( this.end - this.start ) * eased + this.start;
 
                if ( this.options.step ) {
@@ -8867,6 +9103,7 @@ function genFx( type, includeWidth ) {
 
        // if we include width, step value is 1 to do all cssExpand values,
        // if we don't include width, step value is 2 to skip over Left and Right
+       includeWidth = includeWidth? 1 : 0;
        for( ; i < 4 ; i += 2 - includeWidth ) {
                which = cssExpand[ i ];
                attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
@@ -8941,6 +9178,8 @@ jQuery.fx.tick = function() {
                timers = jQuery.timers,
                i = 0;
 
+       fxNow = jQuery.now();
+
        for ( ; i < timers.length; i++ ) {
                timer = timers[ i ];
                // Checks the timer has not already been removed
@@ -8952,6 +9191,7 @@ jQuery.fx.tick = function() {
        if ( !timers.length ) {
                jQuery.fx.stop();
        }
+       fxNow = undefined;
 };
 
 jQuery.fx.timer = function( timer ) {
@@ -8995,7 +9235,8 @@ jQuery.fn.offset = function( options ) {
                        });
        }
 
-       var box, docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft, top, left,
+       var docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft,
+               box = { top: 0, left: 0 },
                elem = this[ 0 ],
                doc = elem && elem.ownerDocument;
 
@@ -9009,21 +9250,25 @@ jQuery.fn.offset = function( options ) {
 
        docElem = doc.documentElement;
 
-       // Make sure we're not dealing with a disconnected DOM node
+       // Make sure it's not a disconnected DOM node
        if ( !jQuery.contains( docElem, elem ) ) {
-               return { top: 0, left: 0 };
+               return box;
        }
 
-       box = elem.getBoundingClientRect();
+       // If we don't have gBCR, just use 0,0 rather than error
+       // BlackBerry 5, iOS 3 (original iPhone)
+       if ( typeof elem.getBoundingClientRect !== "undefined" ) {
+               box = elem.getBoundingClientRect();
+       }
        win = getWindow( doc );
        clientTop  = docElem.clientTop  || body.clientTop  || 0;
        clientLeft = docElem.clientLeft || body.clientLeft || 0;
        scrollTop  = win.pageYOffset || docElem.scrollTop;
        scrollLeft = win.pageXOffset || docElem.scrollLeft;
-       top  = box.top  + scrollTop  - clientTop;
-       left = box.left + scrollLeft - clientLeft;
-
-       return { top: top, left: left };
+       return {
+               top: box.top  + scrollTop  - clientTop,
+               left: box.left + scrollLeft - clientLeft
+       };
 };
 
 jQuery.offset = {
@@ -9201,7 +9446,7 @@ jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
 
                                        // Set width or height on the element
                                        jQuery.style( elem, type, value, extra );
-                       }, type, chainable ? margin : undefined, chainable );
+                       }, type, chainable ? margin : undefined, chainable, null );
                };
        });
 });