jquery-1.12.3

/*!
* jQuery JavaScript Library v1.12.3
* http://jquery.com/
*
* Includes Sizzle.js
* http://sizzlejs.com/
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license
* http://jquery.org/license
*
* Date: 2016-04-05T19:16Z
*/

(function( global, factory ) {

if ( typeof module === "object" && typeof module.exports === "object" ) {
    // For CommonJS and CommonJS-like environments where a proper `window`
    // is present, execute the factory and get jQuery.
    // For environments that do not have a `window` with a `document`
    // (such as Node.js), expose a factory as module.exports.
    // This accentuates the need for the creation of a real `window`.
    // e.g. var jQuery = require("jquery")(window);
    // See ticket #14549 for more info.
    module.exports = global.document ?
        factory( global, true ) :
        function( w ) {
            if ( !w.document ) {
                throw new Error( "jQuery requires a window with a document" );
            }
            return factory( w );
        };
} else {
    factory( global );
}

// Pass this if window is not defined yet
}(typeof window !== “undefined” ? window : this, function( window, noGlobal ) {

// Support: Firefox 18+
// Can’t be in strict mode, several libs including ASP.NET trace
// the stack via arguments.caller.callee and Firefox dies if
// you try to trace through “use strict” call chains. (#13335)
//”use strict”;
var deletedIds = [];

var document = window.document;

var slice = deletedIds.slice;

var concat = deletedIds.concat;

var push = deletedIds.push;

var indexOf = deletedIds.indexOf;

var class2type = {};

var toString = class2type.toString;

var hasOwn = class2type.hasOwnProperty;

var support = {};

var
version = “1.12.3”,

// Define a local copy of jQuery
jQuery = function( selector, context ) {

    // The jQuery object is actually just the init constructor 'enhanced'
    // Need init if jQuery is called (just allow error to be thrown if not included)
    return new jQuery.fn.init( selector, context );
},

// Support: Android<4.1, IE<9
// Make sure we trim BOM and NBSP
rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,

// Matches dashed string for camelizing
rmsPrefix = /^-ms-/,
rdashAlpha = /-([\da-z])/gi,

// Used by jQuery.camelCase as callback to replace()
fcamelCase = function( all, letter ) {
    return letter.toUpperCase();
};

jQuery.fn = jQuery.prototype = {

// The current version of jQuery being used
jquery: version,

constructor: jQuery,

// Start with an empty selector
selector: "",

// The default length of a jQuery object is 0
length: 0,

toArray: function() {
    return slice.call( this );
},

// Get the Nth element in the matched element set OR
// Get the whole matched element set as a clean array
get: function( num ) {
    return num != null ?

        // Return just the one element from the set
        ( num < 0 ? this[ num + this.length ] : this[ num ] ) :

        // Return all the elements in a clean array
        slice.call( this );
},

// Take an array of elements and push it onto the stack
// (returning the new matched element set)
pushStack: function( elems ) {

    // Build a new jQuery matched element set
    var ret = jQuery.merge( this.constructor(), elems );

    // Add the old object onto the stack (as a reference)
    ret.prevObject = this;
    ret.context = this.context;

    // Return the newly-formed element set
    return ret;
},

// Execute a callback for every element in the matched set.
each: function( callback ) {
    return jQuery.each( this, callback );
},

map: function( callback ) {
    return this.pushStack( jQuery.map( this, function( elem, i ) {
        return callback.call( elem, i, elem );
    } ) );
},

slice: function() {
    return this.pushStack( slice.apply( this, arguments ) );
},

first: function() {
    return this.eq( 0 );
},

last: function() {
    return this.eq( -1 );
},

eq: function( i ) {
    var len = this.length,
        j = +i + ( i < 0 ? len : 0 );
    return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
},

end: function() {
    return this.prevObject || this.constructor();
},

// For internal use only.
// Behaves like an Array's method, not like a jQuery method.
push: push,
sort: deletedIds.sort,
splice: deletedIds.splice

};

jQuery.extend = jQuery.fn.extend = function() {
var src, copyIsArray, copy, name, options, clone,
target = arguments[ 0 ] || {},
i = 1,
length = arguments.length,
deep = false;

// Handle a deep copy situation
if ( typeof target === "boolean" ) {
    deep = target;

    // skip the boolean and the target
    target = arguments[ i ] || {};
    i++;
}

// Handle case when target is a string or something (possible in deep copy)
if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
    target = {};
}

// extend jQuery itself if only one argument is passed
if ( i === length ) {
    target = this;
    i--;
}

for ( ; i < length; i++ ) {

    // Only deal with non-null/undefined values
    if ( ( options = arguments[ i ] ) != null ) {

        // Extend the base object
        for ( name in options ) {
            src = target[ name ];
            copy = options[ name ];

            // Prevent never-ending loop
            if ( target === copy ) {
                continue;
            }

            // Recurse if we're merging plain objects or arrays
            if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
                ( copyIsArray = jQuery.isArray( copy ) ) ) ) {

                if ( copyIsArray ) {
                    copyIsArray = false;
                    clone = src && jQuery.isArray( src ) ? src : [];

                } else {
                    clone = src && jQuery.isPlainObject( src ) ? src : {};
                }

                // Never move original objects, clone them
                target[ name ] = jQuery.extend( deep, clone, copy );

            // Don't bring in undefined values
            } else if ( copy !== undefined ) {
                target[ name ] = copy;
            }
        }
    }
}

// Return the modified object
return target;

};

jQuery.extend( {

// Unique for each copy of jQuery on the page
expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),

// Assume jQuery is ready without the ready module
isReady: true,

error: function( msg ) {
    throw new Error( msg );
},

noop: function() {},

// See test/unit/core.js for details concerning isFunction.
// Since version 1.3, DOM methods and functions like alert
// aren't supported. They return false on IE (#2968).
isFunction: function( obj ) {
    return jQuery.type( obj ) === "function";
},

isArray: Array.isArray || function( obj ) {
    return jQuery.type( obj ) === "array";
},

isWindow: function( obj ) {
    /* jshint eqeqeq: false */
    return obj != null && obj == obj.window;
},

isNumeric: function( obj ) {

    // parseFloat NaNs numeric-cast false positives (null|true|false|"")
    // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
    // subtraction forces infinities to NaN
    // adding 1 corrects loss of precision from parseFloat (#15100)
    var realStringObj = obj && obj.toString();
    return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;
},

isEmptyObject: function( obj ) {
    var name;
    for ( name in obj ) {
        return false;
    }
    return true;
},

isPlainObject: function( obj ) {
    var key;

    // Must be an Object.
    // Because of IE, we also have to check the presence of the constructor property.
    // Make sure that DOM nodes and window objects don't pass through, as well
    if ( !obj || jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
        return false;
    }

    try {

        // Not own constructor property must be Object
        if ( obj.constructor &&
            !hasOwn.call( obj, "constructor" ) &&
            !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
            return false;
        }
    } catch ( e ) {

        // IE8,9 Will throw exceptions on certain host objects #9897
        return false;
    }

    // Support: IE<9
    // Handle iteration over inherited properties before own properties.
    if ( !support.ownFirst ) {
        for ( key in obj ) {
            return hasOwn.call( obj, key );
        }
    }

    // Own properties are enumerated firstly, so to speed up,
    // if last one is own, then all properties are own.
    for ( key in obj ) {}

    return key === undefined || hasOwn.call( obj, key );
},

type: function( obj ) {
    if ( obj == null ) {
        return obj + "";
    }
    return typeof obj === "object" || typeof obj === "function" ?
        class2type[ toString.call( obj ) ] || "object" :
        typeof obj;
},

// Workarounds based on findings by Jim Driscoll
// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
globalEval: function( data ) {
    if ( data && jQuery.trim( data ) ) {

        // We use execScript on Internet Explorer
        // We use an anonymous function so that context is window
        // rather than jQuery in Firefox
        ( window.execScript || function( data ) {
            window[ "eval" ].call( window, data ); // jscs:ignore requireDotNotation
        } )( data );
    }
},

// Convert dashed to camelCase; used by the css and data modules
// Microsoft forgot to hump their vendor prefix (#9572)
camelCase: function( string ) {
    return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
},

nodeName: function( elem, name ) {
    return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
},

each: function( obj, callback ) {
    var length, i = 0;

    if ( isArrayLike( obj ) ) {
        length = obj.length;
        for ( ; i < length; i++ ) {
            if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
                break;
            }
        }
    } else {
        for ( i in obj ) {
            if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
                break;
            }
        }
    }

    return obj;
},

// Support: Android<4.1, IE<9
trim: function( text ) {
    return text == null ?
        "" :
        ( text + "" ).replace( rtrim, "" );
},

// results is for internal usage only
makeArray: function( arr, results ) {
    var ret = results || [];

    if ( arr != null ) {
        if ( isArrayLike( Object( arr ) ) ) {
            jQuery.merge( ret,
                typeof arr === "string" ?
                [ arr ] : arr
            );
        } else {
            push.call( ret, arr );
        }
    }

    return ret;
},

inArray: function( elem, arr, i ) {
    var len;

    if ( arr ) {
        if ( indexOf ) {
            return indexOf.call( arr, elem, i );
        }

        len = arr.length;
        i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;

        for ( ; i < len; i++ ) {

            // Skip accessing in sparse arrays
            if ( i in arr && arr[ i ] === elem ) {
                return i;
            }
        }
    }

    return -1;
},

merge: function( first, second ) {
    var len = +second.length,
        j = 0,
        i = first.length;

    while ( j < len ) {
        first[ i++ ] = second[ j++ ];
    }

    // Support: IE<9
    // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
    if ( len !== len ) {
        while ( second[ j ] !== undefined ) {
            first[ i++ ] = second[ j++ ];
        }
    }

    first.length = i;

    return first;
},

grep: function( elems, callback, invert ) {
    var callbackInverse,
        matches = [],
        i = 0,
        length = elems.length,
        callbackExpect = !invert;

    // Go through the array, only saving the items
    // that pass the validator function
    for ( ; i < length; i++ ) {
        callbackInverse = !callback( elems[ i ], i );
        if ( callbackInverse !== callbackExpect ) {
            matches.push( elems[ i ] );
        }
    }

    return matches;
},

// arg is for internal usage only
map: function( elems, callback, arg ) {
    var length, value,
        i = 0,
        ret = [];

    // Go through the array, translating each of the items to their new values
    if ( isArrayLike( elems ) ) {
        length = elems.length;
        for ( ; i < length; i++ ) {
            value = callback( elems[ i ], i, arg );

            if ( value != null ) {
                ret.push( value );
            }
        }

    // Go through every key on the object,
    } else {
        for ( i in elems ) {
            value = callback( elems[ i ], i, arg );

            if ( value != null ) {
                ret.push( value );
            }
        }
    }

    // Flatten any nested arrays
    return concat.apply( [], ret );
},

// A global GUID counter for objects
guid: 1,

// Bind a function to a context, optionally partially applying any
// arguments.
proxy: function( fn, context ) {
    var args, proxy, tmp;

    if ( typeof context === "string" ) {
        tmp = fn[ context ];
        context = fn;
        fn = tmp;
    }

    // Quick check to determine if target is callable, in the spec
    // this throws a TypeError, but we will just return undefined.
    if ( !jQuery.isFunction( fn ) ) {
        return undefined;
    }

    // Simulated bind
    args = slice.call( arguments, 2 );
    proxy = function() {
        return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
    };

    // Set the guid of unique handler to the same of original handler, so it can be removed
    proxy.guid = fn.guid = fn.guid || jQuery.guid++;

    return proxy;
},

now: function() {
    return +( new Date() );
},

// jQuery.support is not used in Core but other projects attach their
// properties to it so it needs to exist.
support: support

} );

// JSHint would error on this code due to the Symbol not being defined in ES5.
// Defining this global in .jshintrc would create a danger of using the global
// unguarded in another place, it seems safer to just disable JSHint for these
// three lines.
/* jshint ignore: start */
if ( typeof Symbol === “function” ) {
jQuery.fn[ Symbol.iterator ] = deletedIds[ Symbol.iterator ];
}
/* jshint ignore: end */

// Populate the class2type map
jQuery.each( “Boolean Number String Function Array Date RegExp Object Error Symbol”.split( ” ” ),
function( i, name ) {
class2type[ “[object ” + name + “]” ] = name.toLowerCase();
} );

function isArrayLike( obj ) {

// Support: iOS 8.2 (not reproducible in simulator)
// `in` check used to prevent JIT error (gh-2145)
// hasOwn isn't used here due to false negatives
// regarding Nodelist length in IE
var length = !!obj && "length" in obj && obj.length,
    type = jQuery.type( obj );

if ( type === "function" || jQuery.isWindow( obj ) ) {
    return false;
}

return type === "array" || length === 0 ||
    typeof length === "number" && length > 0 && ( length - 1 ) in obj;

}
var Sizzle =
/*!
* Sizzle CSS Selector Engine v2.2.1
* http://sizzlejs.com/
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license
* http://jquery.org/license
*
* Date: 2015-10-17
*/
(function( window ) {

var i,
support,
Expr,
getText,
isXML,
tokenize,
compile,
select,
outermostContext,
sortInput,
hasDuplicate,

// Local document vars
setDocument,
document,
docElem,
documentIsHTML,
rbuggyQSA,
rbuggyMatches,
matches,
contains,

// Instance-specific data
expando = "sizzle" + 1 * new Date(),
preferredDoc = window.document,
dirruns = 0,
done = 0,
classCache = createCache(),
tokenCache = createCache(),
compilerCache = createCache(),
sortOrder = function( a, b ) {
    if ( a === b ) {
        hasDuplicate = true;
    }
    return 0;
},

// General-purpose constants
MAX_NEGATIVE = 1 << 31,

// Instance methods
hasOwn = ({}).hasOwnProperty,
arr = [],
pop = arr.pop,
push_native = arr.push,
push = arr.push,
slice = arr.slice,
// Use a stripped-down indexOf as it's faster than native
// http://jsperf.com/thor-indexof-vs-for/5
indexOf = function( list, elem ) {
    var i = 0,
        len = list.length;
    for ( ; i < len; i++ ) {
        if ( list[i] === elem ) {
            return i;
        }
    }
    return -1;
},

booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",

// Regular expressions

// http://www.w3.org/TR/css3-selectors/#whitespace
whitespace = "[\\x20\\t\\r\\n\\f]",

// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",

// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
    // Operator (capture 2)
    "*([*^$|!~]?=)" + whitespace +
    // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
    "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
    "*\\]",

pseudos = ":(" + identifier + ")(?:\\((" +
    // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
    // 1. quoted (capture 3; capture 4 or capture 5)
    "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
    // 2. simple (capture 6)
    "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
    // 3. anything else (capture 2)
    ".*" +
    ")\\)|)",

// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
rwhitespace = new RegExp( whitespace + "+", "g" ),
rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),

rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),

rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),

rpseudo = new RegExp( pseudos ),
ridentifier = new RegExp( "^" + identifier + "$" ),

matchExpr = {
    "ID": new RegExp( "^#(" + identifier + ")" ),
    "CLASS": new RegExp( "^\\.(" + identifier + ")" ),
    "TAG": new RegExp( "^(" + identifier + "|[*])" ),
    "ATTR": new RegExp( "^" + attributes ),
    "PSEUDO": new RegExp( "^" + pseudos ),
    "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
        "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
        "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
    "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
    // For use in libraries implementing .is()
    // We use this for POS matching in `select`
    "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
        whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
},

rinputs = /^(?:input|select|textarea|button)$/i,
rheader = /^h\d$/i,

rnative = /^[^{]+\{\s*\[native \w/,

// Easily-parseable/retrievable ID or TAG or CLASS selectors
rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,

rsibling = /[+~]/,
rescape = /'|\\/g,

// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
funescape = function( _, escaped, escapedWhitespace ) {
    var high = "0x" + escaped - 0x10000;
    // NaN means non-codepoint
    // Support: Firefox<24
    // Workaround erroneous numeric interpretation of +"0x"
    return high !== high || escapedWhitespace ?
        escaped :
        high < 0 ?
            // BMP codepoint
            String.fromCharCode( high + 0x10000 ) :
            // Supplemental Plane codepoint (surrogate pair)
            String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
},

// Used for iframes
// See setDocument()
// Removing the function wrapper causes a "Permission Denied"
// error in IE
unloadHandler = function() {
    setDocument();
};

// Optimize for push.apply( _, NodeList )
try {
push.apply(
(arr = slice.call( preferredDoc.childNodes )),
preferredDoc.childNodes
);
// Support: Android<4.0
// Detect silently failing push.apply
arr[ preferredDoc.childNodes.length ].nodeType;
} catch ( e ) {
push = { apply: arr.length ?

    // Leverage slice if possible
    function( target, els ) {
        push_native.apply( target, slice.call(els) );
    } :

    // Support: IE<9
    // Otherwise append directly
    function( target, els ) {
        var j = target.length,
            i = 0;
        // Can't trust NodeList.length
        while ( (target[j++] = els[i++]) ) {}
        target.length = j - 1;
    }
};

}

function Sizzle( selector, context, results, seed ) {
var m, i, elem, nid, nidselect, match, groups, newSelector,
newContext = context && context.ownerDocument,

    // nodeType defaults to 9, since context defaults to document
    nodeType = context ? context.nodeType : 9;

results = results || [];

// Return early from calls with invalid selector or context
if ( typeof selector !== "string" || !selector ||
    nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {

    return results;
}

// Try to shortcut find operations (as opposed to filters) in HTML documents
if ( !seed ) {

    if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
        setDocument( context );
    }
    context = context || document;

    if ( documentIsHTML ) {

        // If the selector is sufficiently simple, try using a "get*By*" DOM method
        // (excepting DocumentFragment context, where the methods don't exist)
        if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {

            // ID selector
            if ( (m = match[1]) ) {

                // Document context
                if ( nodeType === 9 ) {
                    if ( (elem = context.getElementById( m )) ) {

                        // Support: IE, Opera, Webkit
                        // TODO: identify versions
                        // getElementById can match elements by name instead of ID
                        if ( elem.id === m ) {
                            results.push( elem );
                            return results;
                        }
                    } else {
                        return results;
                    }

                // Element context
                } else {

                    // Support: IE, Opera, Webkit
                    // TODO: identify versions
                    // getElementById can match elements by name instead of ID
                    if ( newContext && (elem = newContext.getElementById( m )) &&
                        contains( context, elem ) &&
                        elem.id === m ) {

                        results.push( elem );
                        return results;
                    }
                }

            // Type selector
            } else if ( match[2] ) {
                push.apply( results, context.getElementsByTagName( selector ) );
                return results;

            // Class selector
            } else if ( (m = match[3]) && support.getElementsByClassName &&
                context.getElementsByClassName ) {

                push.apply( results, context.getElementsByClassName( m ) );
                return results;
            }
        }

        // Take advantage of querySelectorAll
        if ( support.qsa &&
            !compilerCache[ selector + " " ] &&
            (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {

            if ( nodeType !== 1 ) {
                newContext = context;
                newSelector = selector;

            // qSA looks outside Element context, which is not what we want
            // Thanks to Andrew Dupont for this workaround technique
            // Support: IE <=8
            // Exclude object elements
            } else if ( context.nodeName.toLowerCase() !== "object" ) {

                // Capture the context ID, setting it first if necessary
                if ( (nid = context.getAttribute( "id" )) ) {
                    nid = nid.replace( rescape, "\\$&" );
                } else {
                    context.setAttribute( "id", (nid = expando) );
                }

                // Prefix every selector in the list
                groups = tokenize( selector );
                i = groups.length;
                nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']";
                while ( i-- ) {
                    groups[i] = nidselect + " " + toSelector( groups[i] );
                }
                newSelector = groups.join( "," );

                // Expand context for sibling selectors
                newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
                    context;
            }

            if ( newSelector ) {
                try {
                    push.apply( results,
                        newContext.querySelectorAll( newSelector )
                    );
                    return results;
                } catch ( qsaError ) {
                } finally {
                    if ( nid === expando ) {
                        context.removeAttribute( "id" );
                    }
                }
            }
        }
    }
}

// All others
return select( selector.replace( rtrim, "$1" ), context, results, seed );

}

/**
* Create key-value caches of limited size
* @returns {function(string, object)} Returns the Object data after storing it on itself with
* property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
* deleting the oldest entry
*/
function createCache() {
var keys = [];

function cache( key, value ) {
    // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
    if ( keys.push( key + " " ) > Expr.cacheLength ) {
        // Only keep the most recent entries
        delete cache[ keys.shift() ];
    }
    return (cache[ key + " " ] = value);
}
return cache;

}

/**
* Mark a function for special use by Sizzle
* @param {Function} fn The function to mark
*/
function markFunction( fn ) {
fn[ expando ] = true;
return fn;
}

/**
* Support testing using an element
* @param {Function} fn Passed the created div and expects a boolean result
*/
function assert( fn ) {
var div = document.createElement(“div”);

try {
    return !!fn( div );
} catch (e) {
    return false;
} finally {
    // Remove from its parent by default
    if ( div.parentNode ) {
        div.parentNode.removeChild( div );
    }
    // release memory in IE
    div = null;
}

}

/**
* Adds the same handler for all of the specified attrs
* @param {String} attrs Pipe-separated list of attributes
* @param {Function} handler The method that will be applied
*/
function addHandle( attrs, handler ) {
var arr = attrs.split(“|”),
i = arr.length;

while ( i-- ) {
    Expr.attrHandle[ arr[i] ] = handler;
}

}

/**
* Checks document order of two siblings
* @param {Element} a
* @param {Element} b
* @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
*/
function siblingCheck( a, b ) {
var cur = b && a,
diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
( ~b.sourceIndex || MAX_NEGATIVE ) -
( ~a.sourceIndex || MAX_NEGATIVE );

// Use IE sourceIndex if available on both nodes
if ( diff ) {
    return diff;
}

// Check if b follows a
if ( cur ) {
    while ( (cur = cur.nextSibling) ) {
        if ( cur === b ) {
            return -1;
        }
    }
}

return a ? 1 : -1;

}

/**
* Returns a function to use in pseudos for input types
* @param {String} type
*/
function createInputPseudo( type ) {
return function( elem ) {
var name = elem.nodeName.toLowerCase();
return name === “input” && elem.type === type;
};
}

/**
* Returns a function to use in pseudos for buttons
* @param {String} type
*/
function createButtonPseudo( type ) {
return function( elem ) {
var name = elem.nodeName.toLowerCase();
return (name === “input” || name === “button”) && elem.type === type;
};
}

/**
* Returns a function to use in pseudos for positionals
* @param {Function} fn
*/
function createPositionalPseudo( fn ) {
return markFunction(function( argument ) {
argument = +argument;
return markFunction(function( seed, matches ) {
var j,
matchIndexes = fn( [], seed.length, argument ),
i = matchIndexes.length;

        // Match elements found at the specified indexes
        while ( i-- ) {
            if ( seed[ (j = matchIndexes[i]) ] ) {
                seed[j] = !(matches[j] = seed[j]);
            }
        }
    });
});

}

/**
* Checks a node for validity as a Sizzle context
* @param {Element|Object=} context
* @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
*/
function testContext( context ) {
return context && typeof context.getElementsByTagName !== “undefined” && context;
}

// Expose support vars for convenience
support = Sizzle.support = {};

/**
* Detects XML nodes
* @param {Element|Object} elem An element or a document
* @returns {Boolean} True iff elem is a non-HTML XML node
*/
isXML = Sizzle.isXML = function( elem ) {
// documentElement is verified for cases where it doesn’t yet exist
// (such as loading iframes in IE - #4833)
var documentElement = elem && (elem.ownerDocument || elem).documentElement;
return documentElement ? documentElement.nodeName !== “HTML” : false;
};

/**
* Sets document-related variables once based on the current document
* @param {Element|Object} [doc] An element or document object to use to set the document
* @returns {Object} Returns the current document
*/
setDocument = Sizzle.setDocument = function( node ) {
var hasCompare, parent,
doc = node ? node.ownerDocument || node : preferredDoc;

// Return early if doc is invalid or already selected
if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
    return document;
}

// Update global variables
document = doc;
docElem = document.documentElement;
documentIsHTML = !isXML( document );

// Support: IE 9-11, Edge
// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
if ( (parent = document.defaultView) && parent.top !== parent ) {
    // Support: IE 11
    if ( parent.addEventListener ) {
        parent.addEventListener( "unload", unloadHandler, false );

    // Support: IE 9 - 10 only
    } else if ( parent.attachEvent ) {
        parent.attachEvent( "onunload", unloadHandler );
    }
}

/* Attributes
---------------------------------------------------------------------- */

// Support: IE<8
// Verify that getAttribute really returns attributes and not properties
// (excepting IE8 booleans)
support.attributes = assert(function( div ) {
    div.className = "i";
    return !div.getAttribute("className");
});

/* getElement(s)By*
---------------------------------------------------------------------- */

// Check if getElementsByTagName("*") returns only elements
support.getElementsByTagName = assert(function( div ) {
    div.appendChild( document.createComment("") );
    return !div.getElementsByTagName("*").length;
});

// Support: IE<9
support.getElementsByClassName = rnative.test( document.getElementsByClassName );

// Support: IE<10
// Check if getElementById returns elements by name
// The broken getElementById methods don't pick up programatically-set names,
// so use a roundabout getElementsByName test
support.getById = assert(function( div ) {
    docElem.appendChild( div ).id = expando;
    return !document.getElementsByName || !document.getElementsByName( expando ).length;
});

// ID find and filter
if ( support.getById ) {
    Expr.find["ID"] = function( id, context ) {
        if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
            var m = context.getElementById( id );
            return m ? [ m ] : [];
        }
    };
    Expr.filter["ID"] = function( id ) {
        var attrId = id.replace( runescape, funescape );
        return function( elem ) {
            return elem.getAttribute("id") === attrId;
        };
    };
} else {
    // Support: IE6/7
    // getElementById is not reliable as a find shortcut
    delete Expr.find["ID"];

    Expr.filter["ID"] =  function( id ) {
        var attrId = id.replace( runescape, funescape );
        return function( elem ) {
            var node = typeof elem.getAttributeNode !== "undefined" &&
                elem.getAttributeNode("id");
            return node && node.value === attrId;
        };
    };
}

// Tag
Expr.find["TAG"] = support.getElementsByTagName ?
    function( tag, context ) {
        if ( typeof context.getElementsByTagName !== "undefined" ) {
            return context.getElementsByTagName( tag );

        // DocumentFragment nodes don't have gEBTN
        } else if ( support.qsa ) {
            return context.querySelectorAll( tag );
        }
    } :

    function( tag, context ) {
        var elem,
            tmp = [],
            i = 0,
            // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
            results = context.getElementsByTagName( tag );

        // Filter out possible comments
        if ( tag === "*" ) {
            while ( (elem = results[i++]) ) {
                if ( elem.nodeType === 1 ) {
                    tmp.push( elem );
                }
            }

            return tmp;
        }
        return results;
    };

// Class
Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
    if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
        return context.getElementsByClassName( className );
    }
};

/* QSA/matchesSelector
---------------------------------------------------------------------- */

// QSA and matchesSelector support

// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
rbuggyMatches = [];

// qSa(:focus) reports false when true (Chrome 21)
// We allow this because of a bug in IE8/9 that throws an error
// whenever `document.activeElement` is accessed on an iframe
// So, we allow :focus to pass through QSA all the time to avoid the IE error
// See http://bugs.jquery.com/ticket/13378
rbuggyQSA = [];

if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
    // Build QSA regex
    // Regex strategy adopted from Diego Perini
    assert(function( div ) {
        // Select is set to empty string on purpose
        // This is to test IE's treatment of not explicitly
        // setting a boolean content attribute,
        // since its presence should be enough
        // http://bugs.jquery.com/ticket/12359
        docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
            "<select id='" + expando + "-\r\\' msallowcapture=''>" +
            "<option selected=''></option></select>";

        // Support: IE8, Opera 11-12.16
        // Nothing should be selected when empty strings follow ^= or $= or *=
        // The test attribute must be unknown in Opera but "safe" for WinRT
        // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
        if ( div.querySelectorAll("[msallowcapture^='']").length ) {
            rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
        }

        // Support: IE8
        // Boolean attributes and "value" are not treated correctly
        if ( !div.querySelectorAll("[selected]").length ) {
            rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
        }

        // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
        if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
            rbuggyQSA.push("~=");
        }

        // Webkit/Opera - :checked should return selected option elements
        // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
        // IE8 throws error here and will not see later tests
        if ( !div.querySelectorAll(":checked").length ) {
            rbuggyQSA.push(":checked");
        }

        // Support: Safari 8+, iOS 8+
        // https://bugs.webkit.org/show_bug.cgi?id=136851
        // In-page `selector#id sibing-combinator selector` fails
        if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
            rbuggyQSA.push(".#.+[+~]");
        }
    });

    assert(function( div ) {
        // Support: Windows 8 Native Apps
        // The type and name attributes are restricted during .innerHTML assignment
        var input = document.createElement("input");
        input.setAttribute( "type", "hidden" );
        div.appendChild( input ).setAttribute( "name", "D" );

        // Support: IE8
        // Enforce case-sensitivity of name attribute
        if ( div.querySelectorAll("[name=d]").length ) {
            rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
        }

        // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
        // IE8 throws error here and will not see later tests
        if ( !div.querySelectorAll(":enabled").length ) {
            rbuggyQSA.push( ":enabled", ":disabled" );
        }

        // Opera 10-11 does not throw on post-comma invalid pseudos
        div.querySelectorAll("*,:x");
        rbuggyQSA.push(",.*:");
    });
}

if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
    docElem.webkitMatchesSelector ||
    docElem.mozMatchesSelector ||
    docElem.oMatchesSelector ||
    docElem.msMatchesSelector) )) ) {

    assert(function( div ) {
        // Check to see if it's possible to do matchesSelector
        // on a disconnected node (IE 9)
        support.disconnectedMatch = matches.call( div, "div" );

        // This should fail with an exception
        // Gecko does not error, returns false instead
        matches.call( div, "[s!='']:x" );
        rbuggyMatches.push( "!=", pseudos );
    });
}

rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );

/* Contains
---------------------------------------------------------------------- */
hasCompare = rnative.test( docElem.compareDocumentPosition );

// Element contains another
// Purposefully self-exclusive
// As in, an element does not contain itself
contains = hasCompare || rnative.test( docElem.contains ) ?
    function( a, b ) {
        var adown = a.nodeType === 9 ? a.documentElement : a,
            bup = b && b.parentNode;
        return a === bup || !!( bup && bup.nodeType === 1 && (
            adown.contains ?
                adown.contains( bup ) :
                a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
        ));
    } :
    function( a, b ) {
        if ( b ) {
            while ( (b = b.parentNode) ) {
                if ( b === a ) {
                    return true;
                }
            }
        }
        return false;
    };

/* Sorting
---------------------------------------------------------------------- */

// Document order sorting
sortOrder = hasCompare ?
function( a, b ) {

    // Flag for duplicate removal
    if ( a === b ) {
        hasDuplicate = true;
        return 0;
    }

    // Sort on method existence if only one input has compareDocumentPosition
    var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
    if ( compare ) {
        return compare;
    }

    // Calculate position if both inputs belong to the same document
    compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
        a.compareDocumentPosition( b ) :

        // Otherwise we know they are disconnected
        1;

    // Disconnected nodes
    if ( compare & 1 ||
        (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {

        // Choose the first element that is related to our preferred document
        if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
            return -1;
        }
        if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
            return 1;
        }

        // Maintain original order
        return sortInput ?
            ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
            0;
    }

    return compare & 4 ? -1 : 1;
} :
function( a, b ) {
    // Exit early if the nodes are identical
    if ( a === b ) {
        hasDuplicate = true;
        return 0;
    }

    var cur,
        i = 0,
        aup = a.parentNode,
        bup = b.parentNode,
        ap = [ a ],
        bp = [ b ];

    // Parentless nodes are either documents or disconnected
    if ( !aup || !bup ) {
        return a === document ? -1 :
            b === document ? 1 :
            aup ? -1 :
            bup ? 1 :
            sortInput ?
            ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
            0;

    // If the nodes are siblings, we can do a quick check
    } else if ( aup === bup ) {
        return siblingCheck( a, b );
    }

    // Otherwise we need full lists of their ancestors for comparison
    cur = a;
    while ( (cur = cur.parentNode) ) {
        ap.unshift( cur );
    }
    cur = b;
    while ( (cur = cur.parentNode) ) {
        bp.unshift( cur );
    }

    // Walk down the tree looking for a discrepancy
    while ( ap[i] === bp[i] ) {
        i++;
    }

    return i ?
        // Do a sibling check if the nodes have a common ancestor
        siblingCheck( ap[i], bp[i] ) :

        // Otherwise nodes in our document sort first
        ap[i] === preferredDoc ? -1 :
        bp[i] === preferredDoc ? 1 :
        0;
};

return document;

};

Sizzle.matches = function( expr, elements ) {
return Sizzle( expr, null, null, elements );
};

Sizzle.matchesSelector = function( elem, expr ) {
// Set document vars if needed
if ( ( elem.ownerDocument || elem ) !== document ) {
setDocument( elem );
}

// Make sure that attribute selectors are quoted
expr = expr.replace( rattributeQuotes, "='$1']" );

if ( support.matchesSelector && documentIsHTML &&
    !compilerCache[ expr + " " ] &&
    ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
    ( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {

    try {
        var ret = matches.call( elem, expr );

        // IE 9's matchesSelector returns false on disconnected nodes
        if ( ret || support.disconnectedMatch ||
                // As well, disconnected nodes are said to be in a document
                // fragment in IE 9
                elem.document && elem.document.nodeType !== 11 ) {
            return ret;
        }
    } catch (e) {}
}

return Sizzle( expr, document, null, [ elem ] ).length > 0;

};

Sizzle.contains = function( context, elem ) {
// Set document vars if needed
if ( ( context.ownerDocument || context ) !== document ) {
setDocument( context );
}
return contains( context, elem );
};

Sizzle.attr = function( elem, name ) {
// Set document vars if needed
if ( ( elem.ownerDocument || elem ) !== document ) {
setDocument( elem );
}

var fn = Expr.attrHandle[ name.toLowerCase() ],
    // Don't get fooled by Object.prototype properties (jQuery #13807)
    val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
        fn( elem, name, !documentIsHTML ) :
        undefined;

return val !== undefined ?
    val :
    support.attributes || !documentIsHTML ?
        elem.getAttribute( name ) :
        (val = elem.getAttributeNode(name)) && val.specified ?
            val.value :
            null;

};

Sizzle.error = function( msg ) {
throw new Error( “Syntax error, unrecognized expression: ” + msg );
};

/**
* Document sorting and removing duplicates
* @param {ArrayLike} results
*/
Sizzle.uniqueSort = function( results ) {
var elem,
duplicates = [],
j = 0,
i = 0;

// Unless we *know* we can detect duplicates, assume their presence
hasDuplicate = !support.detectDuplicates;
sortInput = !support.sortStable && results.slice( 0 );
results.sort( sortOrder );

if ( hasDuplicate ) {
    while ( (elem = results[i++]) ) {
        if ( elem === results[ i ] ) {
            j = duplicates.push( i );
        }
    }
    while ( j-- ) {
        results.splice( duplicates[ j ], 1 );
    }
}

// Clear input after sorting to release objects
// See https://github.com/jquery/sizzle/pull/225
sortInput = null;

return results;

};

/**
* Utility function for retrieving the text value of an array of DOM nodes
* @param {Array|Element} elem
*/
getText = Sizzle.getText = function( elem ) {
var node,
ret = “”,
i = 0,
nodeType = elem.nodeType;

if ( !nodeType ) {
    // If no nodeType, this is expected to be an array
    while ( (node = elem[i++]) ) {
        // Do not traverse comment nodes
        ret += getText( node );
    }
} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
    // Use textContent for elements
    // innerText usage removed for consistency of new lines (jQuery #11153)
    if ( typeof elem.textContent === "string" ) {
        return elem.textContent;
    } else {
        // Traverse its children
        for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
            ret += getText( elem );
        }
    }
} else if ( nodeType === 3 || nodeType === 4 ) {
    return elem.nodeValue;
}
// Do not include comment or processing instruction nodes

return ret;

};

Expr = Sizzle.selectors = {

// Can be adjusted by the user
cacheLength: 50,

createPseudo: markFunction,

match: matchExpr,

attrHandle: {},

find: {},

relative: {
    ">": { dir: "parentNode", first: true },
    " ": { dir: "parentNode" },
    "+": { dir: "previousSibling", first: true },
    "~": { dir: "previousSibling" }
},

preFilter: {
    "ATTR": function( match ) {
        match[1] = match[1].replace( runescape, funescape );

        // Move the given value to match[3] whether quoted or unquoted
        match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );

        if ( match[2] === "~=" ) {
            match[3] = " " + match[3] + " ";
        }

        return match.slice( 0, 4 );
    },

    "CHILD": function( match ) {
        /* matches from matchExpr["CHILD"]
            1 type (only|nth|...)
            2 what (child|of-type)
            3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
            4 xn-component of xn+y argument ([+-]?\d*n|)
            5 sign of xn-component
            6 x of xn-component
            7 sign of y-component
            8 y of y-component
        */
        match[1] = match[1].toLowerCase();

        if ( match[1].slice( 0, 3 ) === "nth" ) {
            // nth-* requires argument
            if ( !match[3] ) {
                Sizzle.error( match[0] );
            }

            // numeric x and y parameters for Expr.filter.CHILD
            // remember that false/true cast respectively to 0/1
            match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
            match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );

        // other types prohibit arguments
        } else if ( match[3] ) {
            Sizzle.error( match[0] );
        }

        return match;
    },

    "PSEUDO": function( match ) {
        var excess,
            unquoted = !match[6] && match[2];

        if ( matchExpr["CHILD"].test( match[0] ) ) {
            return null;
        }

        // Accept quoted arguments as-is
        if ( match[3] ) {
            match[2] = match[4] || match[5] || "";

        // Strip excess characters from unquoted arguments
        } else if ( unquoted && rpseudo.test( unquoted ) &&
            // Get excess from tokenize (recursively)
            (excess = tokenize( unquoted, true )) &&
            // advance to the next closing parenthesis
            (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {

            // excess is a negative index
            match[0] = match[0].slice( 0, excess );
            match[2] = unquoted.slice( 0, excess );
        }

        // Return only captures needed by the pseudo filter method (type and argument)
        return match.slice( 0, 3 );
    }
},

filter: {

    "TAG": function( nodeNameSelector ) {
        var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
        return nodeNameSelector === "*" ?
            function() { return true; } :
            function( elem ) {
                return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
            };
    },

    "CLASS": function( className ) {
        var pattern = classCache[ className + " " ];

        return pattern ||
            (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
            classCache( className, function( elem ) {
                return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
            });
    },

    "ATTR": function( name, operator, check ) {
        return function( elem ) {
            var result = Sizzle.attr( elem, name );

            if ( result == null ) {
                return operator === "!=";
            }
            if ( !operator ) {
                return true;
            }

            result += "";

            return operator === "=" ? result === check :
                operator === "!=" ? result !== check :
                operator === "^=" ? check && result.indexOf( check ) === 0 :
                operator === "*=" ? check && result.indexOf( check ) > -1 :
                operator === "$=" ? check && result.slice( -check.length ) === check :
                operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
                operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
                false;
        };
    },

    "CHILD": function( type, what, argument, first, last ) {
        var simple = type.slice( 0, 3 ) !== "nth",
            forward = type.slice( -4 ) !== "last",
            ofType = what === "of-type";

        return first === 1 && last === 0 ?

            // Shortcut for :nth-*(n)
            function( elem ) {
                return !!elem.parentNode;
            } :

            function( elem, context, xml ) {
                var cache, uniqueCache, outerCache, node, nodeIndex, start,
                    dir = simple !== forward ? "nextSibling" : "previousSibling",
                    parent = elem.parentNode,
                    name = ofType && elem.nodeName.toLowerCase(),
                    useCache = !xml && !ofType,
                    diff = false;

                if ( parent ) {

                    // :(first|last|only)-(child|of-type)
                    if ( simple ) {
                        while ( dir ) {
                            node = elem;
                            while ( (node = node[ dir ]) ) {
                                if ( ofType ?
                                    node.nodeName.toLowerCase() === name :
                                    node.nodeType === 1 ) {

                                    return false;
                                }
                            }
                            // Reverse direction for :only-* (if we haven't yet done so)
                            start = dir = type === "only" && !start && "nextSibling";
                        }
                        return true;
                    }

                    start = [ forward ? parent.firstChild : parent.lastChild ];

                    // non-xml :nth-child(...) stores cache data on `parent`
                    if ( forward && useCache ) {

                        // Seek `elem` from a previously-cached index

                        // ...in a gzip-friendly way
                        node = parent;
                        outerCache = node[ expando ] || (node[ expando ] = {});

                        // Support: IE <9 only
                        // Defend against cloned attroperties (jQuery gh-1709)
                        uniqueCache = outerCache[ node.uniqueID ] ||
                            (outerCache[ node.uniqueID ] = {});

                        cache = uniqueCache[ type ] || [];
                        nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
                        diff = nodeIndex && cache[ 2 ];
                        node = nodeIndex && parent.childNodes[ nodeIndex ];

                        while ( (node = ++nodeIndex && node && node[ dir ] ||

                            // Fallback to seeking `elem` from the start
                            (diff = nodeIndex = 0) || start.pop()) ) {

                            // When found, cache indexes on `parent` and break
                            if ( node.nodeType === 1 && ++diff && node === elem ) {
                                uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
                                break;
                            }
                        }

                    } else {
                        // Use previously-cached element index if available
                        if ( useCache ) {
                            // ...in a gzip-friendly way
                            node = elem;
                            outerCache = node[ expando ] || (node[ expando ] = {});

                            // Support: IE <9 only
                            // Defend against cloned attroperties (jQuery gh-1709)
                            uniqueCache = outerCache[ node.uniqueID ] ||
                                (outerCache[ node.uniqueID ] = {});

                            cache = uniqueCache[ type ] || [];
                            nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
                            diff = nodeIndex;
                        }

                        // xml :nth-child(...)
                        // or :nth-last-child(...) or :nth(-last)?-of-type(...)
                        if ( diff === false ) {
                            // Use the same loop as above to seek `elem` from the start
                            while ( (node = ++nodeIndex && node && node[ dir ] ||
                                (diff = nodeIndex = 0) || start.pop()) ) {

                                if ( ( ofType ?
                                    node.nodeName.toLowerCase() === name :
                                    node.nodeType === 1 ) &&
                                    ++diff ) {

                                    // Cache the index of each encountered element
                                    if ( useCache ) {
                                        outerCache = node[ expando ] || (node[ expando ] = {});

                                        // Support: IE <9 only
                                        // Defend against cloned attroperties (jQuery gh-1709)
                                        uniqueCache = outerCache[ node.uniqueID ] ||
                                            (outerCache[ node.uniqueID ] = {});

                                        uniqueCache[ type ] = [ dirruns, diff ];
                                    }

                                    if ( node === elem ) {
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    // Incorporate the offset, then check against cycle size
                    diff -= last;
                    return diff === first || ( diff % first === 0 && diff / first >= 0 );
                }
            };
    },

    "PSEUDO": function( pseudo, argument ) {
        // pseudo-class names are case-insensitive
        // http://www.w3.org/TR/selectors/#pseudo-classes
        // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
        // Remember that setFilters inherits from pseudos
        var args,
            fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
                Sizzle.error( "unsupported pseudo: " + pseudo );

        // The user may use createPseudo to indicate that
        // arguments are needed to create the filter function
        // just as Sizzle does
        if ( fn[ expando ] ) {
            return fn( argument );
        }

        // But maintain support for old signatures
        if ( fn.length > 1 ) {
            args = [ pseudo, pseudo, "", argument ];
            return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
                markFunction(function( seed, matches ) {
                    var idx,
                        matched = fn( seed, argument ),
                        i = matched.length;
                    while ( i-- ) {
                        idx = indexOf( seed, matched[i] );
                        seed[ idx ] = !( matches[ idx ] = matched[i] );
                    }
                }) :
                function( elem ) {
                    return fn( elem, 0, args );
                };
        }

        return fn;
    }
},

pseudos: {
    // Potentially complex pseudos
    "not": markFunction(function( selector ) {
        // Trim the selector passed to compile
        // to avoid treating leading and trailing
        // spaces as combinators
        var input = [],
            results = [],
            matcher = compile( selector.replace( rtrim, "$1" ) );

        return matcher[ expando ] ?
            markFunction(function( seed, matches, context, xml ) {
                var elem,
                    unmatched = matcher( seed, null, xml, [] ),
                    i = seed.length;

                // Match elements unmatched by `matcher`
                while ( i-- ) {
                    if ( (elem = unmatched[i]) ) {
                        seed[i] = !(matches[i] = elem);
                    }
                }
            }) :
            function( elem, context, xml ) {
                input[0] = elem;
                matcher( input, null, xml, results );
                // Don't keep the element (issue #299)
                input[0] = null;
                return !results.pop();
            };
    }),

    "has": markFunction(function( selector ) {
        return function( elem ) {
            return Sizzle( selector, elem ).length > 0;
        };
    }),

    "contains": markFunction(function( text ) {
        text = text.replace( runescape, funescape );
        return function( elem ) {
            return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
        };
    }),

    // "Whether an element is represented by a :lang() selector
    // is based solely on the element's language value
    // being equal to the identifier C,
    // or beginning with the identifier C immediately followed by "-".
    // The matching of C against the element's language value is performed case-insensitively.
    // The identifier C does not have to be a valid language name."
    // http://www.w3.org/TR/selectors/#lang-pseudo
    "lang": markFunction( function( lang ) {
        // lang value must be a valid identifier
        if ( !ridentifier.test(lang || "") ) {
            Sizzle.error( "unsupported lang: " + lang );
        }
        lang = lang.replace( runescape, funescape ).toLowerCase();
        return function( elem ) {
            var elemLang;
            do {
                if ( (elemLang = documentIsHTML ?
                    elem.lang :
                    elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {

                    elemLang = elemLang.toLowerCase();
                    return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
                }
            } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
            return false;
        };
    }),

    // Miscellaneous
    "target": function( elem ) {
        var hash = window.location && window.location.hash;
        return hash && hash.slice( 1 ) === elem.id;
    },

    "root": function( elem ) {
        return elem === docElem;
    },

    "focus": function( elem ) {
        return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
    },

    // Boolean properties
    "enabled": function( elem ) {
        return elem.disabled === false;
    },

    "disabled": function( elem ) {
        return elem.disabled === true;
    },

    "checked": function( elem ) {
        // In CSS3, :checked should return both checked and selected elements
        // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
        var nodeName = elem.nodeName.toLowerCase();
        return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
    },

    "selected": function( elem ) {
        // Accessing this property makes selected-by-default
        // options in Safari work properly
        if ( elem.parentNode ) {
            elem.parentNode.selectedIndex;
        }

        return elem.selected === true;
    },

    // Contents
    "empty": function( elem ) {
        // http://www.w3.org/TR/selectors/#empty-pseudo
        // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
        //   but not by others (comment: 8; processing instruction: 7; etc.)
        // nodeType < 6 works because attributes (2) do not appear as children
        for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
            if ( elem.nodeType < 6 ) {
                return false;
            }
        }
        return true;
    },

    "parent": function( elem ) {
        return !Expr.pseudos["empty"]( elem );
    },

    // Element/input types
    "header": function( elem ) {
        return rheader.test( elem.nodeName );
    },

    "input": function( elem ) {
        return rinputs.test( elem.nodeName );
    },

    "button": function( elem ) {
        var name = elem.nodeName.toLowerCase();
        return name === "input" && elem.type === "button" || name === "button";
    },

    "text": function( elem ) {
        var attr;
        return elem.nodeName.toLowerCase() === "input" &&
            elem.type === "text" &&

            // Support: IE<8
            // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
            ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
    },

    // Position-in-collection
    "first": createPositionalPseudo(function() {
        return [ 0 ];
    }),

    "last": createPositionalPseudo(function( matchIndexes, length ) {
        return [ length - 1 ];
    }),

    "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
        return [ argument < 0 ? argument + length : argument ];
    }),

    "even": createPositionalPseudo(function( matchIndexes, length ) {
        var i = 0;
        for ( ; i < length; i += 2 ) {
            matchIndexes.push( i );
        }
        return matchIndexes;
    }),

    "odd": createPositionalPseudo(function( matchIndexes, length ) {
        var i = 1;
        for ( ; i < length; i += 2 ) {
            matchIndexes.push( i );
        }
        return matchIndexes;
    }),

    "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
        var i = argument < 0 ? argument + length : argument;
        for ( ; --i >= 0; ) {
            matchIndexes.push( i );
        }
        return matchIndexes;
    }),

    "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
        var i = argument < 0 ? argument + length : argument;
        for ( ; ++i < length; ) {
            matchIndexes.push( i );
        }
        return matchIndexes;
    })
}

};

Expr.pseudos[“nth”] = Expr.pseudos[“eq”];

// Add button/input type pseudos
for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
Expr.pseudos[ i ] = createInputPseudo( i );
}
for ( i in { submit: true, reset: true } ) {
Expr.pseudos[ i ] = createButtonPseudo( i );
}

// Easy API for creating new setFilters
function setFilters() {}
setFilters.prototype = Expr.filters = Expr.pseudos;
Expr.setFilters = new setFilters();

tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
var matched, match, tokens, type,
soFar, groups, preFilters,
cached = tokenCache[ selector + ” ” ];

if ( cached ) {
    return parseOnly ? 0 : cached.slice( 0 );
}

soFar = selector;
groups = [];
preFilters = Expr.preFilter;

while ( soFar ) {

    // Comma and first run
    if ( !matched || (match = rcomma.exec( soFar )) ) {
        if ( match ) {
            // Don't consume trailing commas as valid
            soFar = soFar.slice( match[0].length ) || soFar;
        }
        groups.push( (tokens = []) );
    }

    matched = false;

    // Combinators
    if ( (match = rcombinators.exec( soFar )) ) {
        matched = match.shift();
        tokens.push({
            value: matched,
            // Cast descendant combinators to space
            type: match[0].replace( rtrim, " " )
        });
        soFar = soFar.slice( matched.length );
    }

    // Filters
    for ( type in Expr.filter ) {
        if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
            (match = preFilters[ type ]( match ))) ) {
            matched = match.shift();
            tokens.push({
                value: matched,
                type: type,
                matches: match
            });
            soFar = soFar.slice( matched.length );
        }
    }

    if ( !matched ) {
        break;
    }
}

// Return the length of the invalid excess
// if we're just parsing
// Otherwise, throw an error or return tokens
return parseOnly ?
    soFar.length :
    soFar ?
        Sizzle.error( selector ) :
        // Cache the tokens
        tokenCache( selector, groups ).slice( 0 );

};

function toSelector( tokens ) {
var i = 0,
len = tokens.length,
selector = “”;
for ( ; i < len; i++ ) {
selector += tokens[i].value;
}
return selector;
}

function addCombinator( matcher, combinator, base ) {
var dir = combinator.dir,
checkNonElements = base && dir === “parentNode”,
doneName = done++;

return combinator.first ?
    // Check against closest ancestor/preceding element
    function( elem, context, xml ) {
        while ( (elem = elem[ dir ]) ) {
            if ( elem.nodeType === 1 || checkNonElements ) {
                return matcher( elem, context, xml );
            }
        }
    } :

    // Check against all ancestor/preceding elements
    function( elem, context, xml ) {
        var oldCache, uniqueCache, outerCache,
            newCache = [ dirruns, doneName ];

        // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
        if ( xml ) {
            while ( (elem = elem[ dir ]) ) {
                if ( elem.nodeType === 1 || checkNonElements ) {
                    if ( matcher( elem, context, xml ) ) {
                        return true;
                    }
                }
            }
        } else {
            while ( (elem = elem[ dir ]) ) {
                if ( elem.nodeType === 1 || checkNonElements ) {
                    outerCache = elem[ expando ] || (elem[ expando ] = {});

                    // Support: IE <9 only
                    // Defend against cloned attroperties (jQuery gh-1709)
                    uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});

                    if ( (oldCache = uniqueCache[ dir ]) &&
                        oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {

                        // Assign to newCache so results back-propagate to previous elements
                        return (newCache[ 2 ] = oldCache[ 2 ]);
                    } else {
                        // Reuse newcache so results back-propagate to previous elements
                        uniqueCache[ dir ] = newCache;

                        // A match means we're done; a fail means we have to keep checking
                        if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
                            return true;
                        }
                    }
                }
            }
        }
    };

}

function elementMatcher( matchers ) {
return matchers.length > 1 ?
function( elem, context, xml ) {
var i = matchers.length;
while ( i– ) {
if ( !matchers[i]( elem, context, xml ) ) {
return false;
}
}
return true;
} :
matchers[0];
}

function multipleContexts( selector, contexts, results ) {
var i = 0,
len = contexts.length;
for ( ; i < len; i++ ) {
Sizzle( selector, contexts[i], results );
}
return results;
}

function condense( unmatched, map, filter, context, xml ) {
var elem,
newUnmatched = [],
i = 0,
len = unmatched.length,
mapped = map != null;

for ( ; i < len; i++ ) {
    if ( (elem = unmatched[i]) ) {
        if ( !filter || filter( elem, context, xml ) ) {
            newUnmatched.push( elem );
            if ( mapped ) {
                map.push( i );
            }
        }
    }
}

return newUnmatched;

}

function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
if ( postFilter && !postFilter[ expando ] ) {
postFilter = setMatcher( postFilter );
}
if ( postFinder && !postFinder[ expando ] ) {
postFinder = setMatcher( postFinder, postSelector );
}
return markFunction(function( seed, results, context, xml ) {
var temp, i, elem,
preMap = [],
postMap = [],
preexisting = results.length,

        // Get initial elements from seed or context
        elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),

        // Prefilter to get matcher input, preserving a map for seed-results synchronization
        matcherIn = preFilter && ( seed || !selector ) ?
            condense( elems, preMap, preFilter, context, xml ) :
            elems,

        matcherOut = matcher ?
            // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
            postFinder || ( seed ? preFilter : preexisting || postFilter ) ?

                // ...intermediate processing is necessary
                [] :

                // ...otherwise use results directly
                results :
            matcherIn;

    // Find primary matches
    if ( matcher ) {
        matcher( matcherIn, matcherOut, context, xml );
    }

    // Apply postFilter
    if ( postFilter ) {
        temp = condense( matcherOut, postMap );
        postFilter( temp, [], context, xml );

        // Un-match failing elements by moving them back to matcherIn
        i = temp.length;
        while ( i-- ) {
            if ( (elem = temp[i]) ) {
                matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
            }
        }
    }

    if ( seed ) {
        if ( postFinder || preFilter ) {
            if ( postFinder ) {
                // Get the final matcherOut by condensing this intermediate into postFinder contexts
                temp = [];
                i = matcherOut.length;
                while ( i-- ) {
                    if ( (elem = matcherOut[i]) ) {
                        // Restore matcherIn since elem is not yet a final match
                        temp.push( (matcherIn[i] = elem) );
                    }
                }
                postFinder( null, (matcherOut = []), temp, xml );
            }

            // Move matched elements from seed to results to keep them synchronized
            i = matcherOut.length;
            while ( i-- ) {
                if ( (elem = matcherOut[i]) &&
                    (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {

                    seed[temp] = !(results[temp] = elem);
                }
            }
        }

    // Add elements to results, through postFinder if defined
    } else {
        matcherOut = condense(
            matcherOut === results ?
                matcherOut.splice( preexisting, matcherOut.length ) :
                matcherOut
        );
        if ( postFinder ) {
            postFinder( null, results, matcherOut, xml );
        } else {
            push.apply( results, matcherOut );
        }
    }
});

}

function matcherFromTokens( tokens ) {
var checkContext, matcher, j,
len = tokens.length,
leadingRelative = Expr.relative[ tokens[0].type ],
implicitRelative = leadingRelative || Expr.relative[” “],
i = leadingRelative ? 1 : 0,

    // The foundational matcher ensures that elements are reachable from top-level context(s)
    matchContext = addCombinator( function( elem ) {
        return elem === checkContext;
    }, implicitRelative, true ),
    matchAnyContext = addCombinator( function( elem ) {
        return indexOf( checkContext, elem ) > -1;
    }, implicitRelative, true ),
    matchers = [ function( elem, context, xml ) {
        var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
            (checkContext = context).nodeType ?
                matchContext( elem, context, xml ) :
                matchAnyContext( elem, context, xml ) );
        // Avoid hanging onto element (issue #299)
        checkContext = null;
        return ret;
    } ];

for ( ; i < len; i++ ) {
    if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
        matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
    } else {
        matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );

        // Return special upon seeing a positional matcher
        if ( matcher[ expando ] ) {
            // Find the next relative operator (if any) for proper handling
            j = ++i;
            for ( ; j < len; j++ ) {
                if ( Expr.relative[ tokens[j].type ] ) {
                    break;
                }
            }
            return setMatcher(
                i > 1 && elementMatcher( matchers ),
                i > 1 && toSelector(
                    // If the preceding token was a descendant combinator, insert an implicit any-element `*`
                    tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
                ).replace( rtrim, "$1" ),
                matcher,
                i < j && matcherFromTokens( tokens.slice( i, j ) ),
                j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
                j < len && toSelector( tokens )
            );
        }
        matchers.push( matcher );
    }
}

return elementMatcher( matchers );

}

function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
var bySet = setMatchers.length > 0,
byElement = elementMatchers.length > 0,
superMatcher = function( seed, context, xml, results, outermost ) {
var elem, j, matcher,
matchedCount = 0,
i = “0”,
unmatched = seed && [],
setMatched = [],
contextBackup = outermostContext,
// We must always have either seed elements or outermost context
elems = seed || byElement && Expr.find[“TAG”]( “*”, outermost ),
// Use integer dirruns iff this is the outermost matcher
dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
len = elems.length;

        if ( outermost ) {
            outermostContext = context === document || context || outermost;
        }

        // Add elements passing elementMatchers directly to results
        // Support: IE<9, Safari
        // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
        for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
            if ( byElement && elem ) {
                j = 0;
                if ( !context && elem.ownerDocument !== document ) {
                    setDocument( elem );
                    xml = !documentIsHTML;
                }
                while ( (matcher = elementMatchers[j++]) ) {
                    if ( matcher( elem, context || document, xml) ) {
                        results.push( elem );
                        break;
                    }
                }
                if ( outermost ) {
                    dirruns = dirrunsUnique;
                }
            }

            // Track unmatched elements for set filters
            if ( bySet ) {
                // They will have gone through all possible matchers
                if ( (elem = !matcher && elem) ) {
                    matchedCount--;
                }

                // Lengthen the array for every element, matched or not
                if ( seed ) {
                    unmatched.push( elem );
                }
            }
        }

        // `i` is now the count of elements visited above, and adding it to `matchedCount`
        // makes the latter nonnegative.
        matchedCount += i;

        // Apply set filters to unmatched elements
        // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
        // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
        // no element matchers and no seed.
        // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
        // case, which will result in a "00" `matchedCount` that differs from `i` but is also
        // numerically zero.
        if ( bySet && i !== matchedCount ) {
            j = 0;
            while ( (matcher = setMatchers[j++]) ) {
                matcher( unmatched, setMatched, context, xml );
            }

            if ( seed ) {
                // Reintegrate element matches to eliminate the need for sorting
                if ( matchedCount > 0 ) {
                    while ( i-- ) {
                        if ( !(unmatched[i] || setMatched[i]) ) {
                            setMatched[i] = pop.call( results );
                        }
                    }
                }

                // Discard index placeholder values to get only actual matches
                setMatched = condense( setMatched );
            }

            // Add matches to results
            push.apply( results, setMatched );

            // Seedless set matches succeeding multiple successful matchers stipulate sorting
            if ( outermost && !seed && setMatched.length > 0 &&
                ( matchedCount + setMatchers.length ) > 1 ) {

                Sizzle.uniqueSort( results );
            }
        }

        // Override manipulation of globals by nested matchers
        if ( outermost ) {
            dirruns = dirrunsUnique;
            outermostContext = contextBackup;
        }

        return unmatched;
    };

return bySet ?
    markFunction( superMatcher ) :
    superMatcher;

}

compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
var i,
setMatchers = [],
elementMatchers = [],
cached = compilerCache[ selector + ” ” ];

if ( !cached ) {
    // Generate a function of recursive functions that can be used to check each element
    if ( !match ) {
        match = tokenize( selector );
    }
    i = match.length;
    while ( i-- ) {
        cached = matcherFromTokens( match[i] );
        if ( cached[ expando ] ) {
            setMatchers.push( cached );
        } else {
            elementMatchers.push( cached );
        }
    }

    // Cache the compiled function
    cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );

    // Save selector and tokenization
    cached.selector = selector;
}
return cached;

};

/**
* A low-level selection function that works with Sizzle’s compiled
* selector functions
* @param {String|Function} selector A selector or a pre-compiled
* selector function built with Sizzle.compile
* @param {Element} context
* @param {Array} [results]
* @param {Array} [seed] A set of elements to match against
*/
select = Sizzle.select = function( selector, context, results, seed ) {
var i, tokens, token, type, find,
compiled = typeof selector === “function” && selector,
match = !seed && tokenize( (selector = compiled.selector || selector) );

results = results || [];

// Try to minimize operations if there is only one selector in the list and no seed
// (the latter of which guarantees us context)
if ( match.length === 1 ) {

    // Reduce context if the leading compound selector is an ID
    tokens = match[0] = match[0].slice( 0 );
    if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
            support.getById && context.nodeType === 9 && documentIsHTML &&
            Expr.relative[ tokens[1].type ] ) {

        context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
        if ( !context ) {
            return results;

        // Precompiled matchers will still verify ancestry, so step up a level
        } else if ( compiled ) {
            context = context.parentNode;
        }

        selector = selector.slice( tokens.shift().value.length );
    }

    // Fetch a seed set for right-to-left matching
    i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
    while ( i-- ) {
        token = tokens[i];

        // Abort if we hit a combinator
        if ( Expr.relative[ (type = token.type) ] ) {
            break;
        }
        if ( (find = Expr.find[ type ]) ) {
            // Search, expanding context for leading sibling combinators
            if ( (seed = find(
                token.matches[0].replace( runescape, funescape ),
                rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
            )) ) {

                // If seed is empty or no tokens remain, we can return early
                tokens.splice( i, 1 );
                selector = seed.length && toSelector( tokens );
                if ( !selector ) {
                    push.apply( results, seed );
                    return results;
                }

                break;
            }
        }
    }
}

// Compile and execute a filtering function if one is not provided
// Provide `match` to avoid retokenization if we modified the selector above
( compiled || compile( selector, match ) )(
    seed,
    context,
    !documentIsHTML,
    results,
    !context || rsibling.test( selector ) && testContext( context.parentNode ) || context
);
return results;

};

// One-time assignments

// Sort stability
support.sortStable = expando.split(“”).sort( sortOrder ).join(“”) === expando;

// Support: Chrome 14-35+
// Always assume duplicates if they aren’t passed to the comparison function
support.detectDuplicates = !!hasDuplicate;

// Initialize against the default document
setDocument();

// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
// Detached nodes confoundingly follow each other
support.sortDetached = assert(function( div1 ) {
// Should return 1, but returns 4 (following)
return div1.compareDocumentPosition( document.createElement(“div”) ) & 1;
});

// Support: IE<8
// Prevent attribute/property “interpolation”
// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
if ( !assert(function( div ) {
div.innerHTML = ““;
return div.firstChild.getAttribute(“href”) === “#” ;
}) ) {
addHandle( “type|href|height|width”, function( elem, name, isXML ) {
if ( !isXML ) {
return elem.getAttribute( name, name.toLowerCase() === “type” ? 1 : 2 );
}
});
}

// Support: IE<9
// Use defaultValue in place of getAttribute(“value”)
if ( !support.attributes || !assert(function( div ) {
div.innerHTML = “”;
div.firstChild.setAttribute( “value”, “” );
return div.firstChild.getAttribute( “value” ) === “”;
}) ) {
addHandle( “value”, function( elem, name, isXML ) {
if ( !isXML && elem.nodeName.toLowerCase() === “input” ) {
return elem.defaultValue;
}
});
}

// Support: IE<9
// Use getAttributeNode to fetch booleans when getAttribute lies
if ( !assert(function( div ) {
return div.getAttribute(“disabled”) == null;
}) ) {
addHandle( booleans, function( elem, name, isXML ) {
var val;
if ( !isXML ) {
return elem[ name ] === true ? name.toLowerCase() :
(val = elem.getAttributeNode( name )) && val.specified ?
val.value :
null;
}
});
}

return Sizzle;

})( window );

jQuery.find = Sizzle;
jQuery.expr = Sizzle.selectors;
jQuery.expr[ “:” ] = jQuery.expr.pseudos;
jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
jQuery.text = Sizzle.getText;
jQuery.isXMLDoc = Sizzle.isXML;
jQuery.contains = Sizzle.contains;

var dir = function( elem, dir, until ) {
var matched = [],
truncate = until !== undefined;

while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
    if ( elem.nodeType === 1 ) {
        if ( truncate && jQuery( elem ).is( until ) ) {
            break;
        }
        matched.push( elem );
    }
}
return matched;

};

var siblings = function( n, elem ) {
var matched = [];

for ( ; n; n = n.nextSibling ) {
    if ( n.nodeType === 1 && n !== elem ) {
        matched.push( n );
    }
}

return matched;

};

var rneedsContext = jQuery.expr.match.needsContext;

var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );

var risSimple = /^.[^:#[.,]*$/;

// Implement the identical functionality for filter and not
function winnow( elements, qualifier, not ) {
if ( jQuery.isFunction( qualifier ) ) {
return jQuery.grep( elements, function( elem, i ) {
/* jshint -W018 */
return !!qualifier.call( elem, i, elem ) !== not;
} );

}

if ( qualifier.nodeType ) {
    return jQuery.grep( elements, function( elem ) {
        return ( elem === qualifier ) !== not;
    } );

}

if ( typeof qualifier === "string" ) {
    if ( risSimple.test( qualifier ) ) {
        return jQuery.filter( qualifier, elements, not );
    }

    qualifier = jQuery.filter( qualifier, elements );
}

return jQuery.grep( elements, function( elem ) {
    return ( jQuery.inArray( elem, qualifier ) > -1 ) !== not;
} );

}

jQuery.filter = function( expr, elems, not ) {
var elem = elems[ 0 ];

if ( not ) {
    expr = ":not(" + expr + ")";
}

return elems.length === 1 && elem.nodeType === 1 ?
    jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
    jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
        return elem.nodeType === 1;
    } ) );

};

jQuery.fn.extend( {
find: function( selector ) {
var i,
ret = [],
self = this,
len = self.length;

    if ( typeof selector !== "string" ) {
        return this.pushStack( jQuery( selector ).filter( function() {
            for ( i = 0; i < len; i++ ) {
                if ( jQuery.contains( self[ i ], this ) ) {
                    return true;
                }
            }
        } ) );
    }

    for ( i = 0; i < len; i++ ) {
        jQuery.find( selector, self[ i ], ret );
    }

    // Needed because $( selector, context ) becomes $( context ).find( selector )
    ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
    ret.selector = this.selector ? this.selector + " " + selector : selector;
    return ret;
},
filter: function( selector ) {
    return this.pushStack( winnow( this, selector || [], false ) );
},
not: function( selector ) {
    return this.pushStack( winnow( this, selector || [], true ) );
},
is: function( selector ) {
    return !!winnow(
        this,

        // If this is a positional/relative selector, check membership in the returned set
        // so $("p:first").is("p:last") won't return true for a doc with two "p".
        typeof selector === "string" && rneedsContext.test( selector ) ?
            jQuery( selector ) :
            selector || [],
        false
    ).length;
}

} );

// Initialize a jQuery object

// A central reference to the root jQuery(document)
var rootjQuery,

// A simple way to check for HTML strings
// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
// Strict HTML recognition (#11290: must start with <)
rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,

init = jQuery.fn.init = function( selector, context, root ) {
    var match, elem;

    // HANDLE: $(""), $(null), $(undefined), $(false)
    if ( !selector ) {
        return this;
    }

    // init accepts an alternate rootjQuery
    // so migrate can support jQuery.sub (gh-2101)
    root = root || rootjQuery;

    // Handle HTML strings
    if ( typeof selector === "string" ) {
        if ( selector.charAt( 0 ) === "<" &&
            selector.charAt( selector.length - 1 ) === ">" &&
            selector.length >= 3 ) {

            // Assume that strings that start and end with <> are HTML and skip the regex check
            match = [ null, selector, null ];

        } else {
            match = rquickExpr.exec( selector );
        }

        // Match html or make sure no context is specified for #id
        if ( match && ( match[ 1 ] || !context ) ) {

            // HANDLE: $(html) -> $(array)
            if ( match[ 1 ] ) {
                context = context instanceof jQuery ? context[ 0 ] : context;

                // scripts is true for back-compat
                // Intentionally let the error be thrown if parseHTML is not present
                jQuery.merge( this, jQuery.parseHTML(
                    match[ 1 ],
                    context && context.nodeType ? context.ownerDocument || context : document,
                    true
                ) );

                // HANDLE: $(html, props)
                if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
                    for ( match in context ) {

                        // Properties of context are called as methods if possible
                        if ( jQuery.isFunction( this[ match ] ) ) {
                            this[ match ]( context[ match ] );

                        // ...and otherwise set as attributes
                        } else {
                            this.attr( match, context[ match ] );
                        }
                    }
                }

                return this;

            // HANDLE: $(#id)
            } else {
                elem = document.getElementById( match[ 2 ] );

                // Check parentNode to catch when Blackberry 4.6 returns
                // nodes that are no longer in the document #6963
                if ( elem && elem.parentNode ) {

                    // Handle the case where IE and Opera return items
                    // by name instead of ID
                    if ( elem.id !== match[ 2 ] ) {
                        return rootjQuery.find( selector );
                    }

                    // Otherwise, we inject the element directly into the jQuery object
                    this.length = 1;
                    this[ 0 ] = elem;
                }

                this.context = document;
                this.selector = selector;
                return this;
            }

        // HANDLE: $(expr, $(...))
        } else if ( !context || context.jquery ) {
            return ( context || root ).find( selector );

        // HANDLE: $(expr, context)
        // (which is just equivalent to: $(context).find(expr)
        } else {
            return this.constructor( context ).find( selector );
        }

    // HANDLE: $(DOMElement)
    } else if ( selector.nodeType ) {
        this.context = this[ 0 ] = selector;
        this.length = 1;
        return this;

    // HANDLE: $(function)
    // Shortcut for document ready
    } else if ( jQuery.isFunction( selector ) ) {
        return typeof root.ready !== "undefined" ?
            root.ready( selector ) :

            // Execute immediately if ready is not present
            selector( jQuery );
    }

    if ( selector.selector !== undefined ) {
        this.selector = selector.selector;
        this.context = selector.context;
    }

    return jQuery.makeArray( selector, this );
};

// Give the init function the jQuery prototype for later instantiation
init.prototype = jQuery.fn;

// Initialize central reference
rootjQuery = jQuery( document );

var rparentsprev = /^(?:parents|prev(?:Until|All))/,

// methods guaranteed to produce a unique set when starting from a unique set
guaranteedUnique = {
    children: true,
    contents: true,
    next: true,
    prev: true
};

jQuery.fn.extend( {
has: function( target ) {
var i,
targets = jQuery( target, this ),
len = targets.length;

    return this.filter( function() {
        for ( i = 0; i < len; i++ ) {
            if ( jQuery.contains( this, targets[ i ] ) ) {
                return true;
            }
        }
    } );
},

closest: function( selectors, context ) {
    var cur,
        i = 0,
        l = this.length,
        matched = [],
        pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
            jQuery( selectors, context || this.context ) :
            0;

    for ( ; i < l; i++ ) {
        for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {

            // Always skip document fragments
            if ( cur.nodeType < 11 && ( pos ?
                pos.index( cur ) > -1 :

                // Don't pass non-elements to Sizzle
                cur.nodeType === 1 &&
                    jQuery.find.matchesSelector( cur, selectors ) ) ) {

                matched.push( cur );
                break;
            }
        }
    }

    return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
},

// Determine the position of an element within
// the matched set of elements
index: function( elem ) {

    // No argument, return index in parent
    if ( !elem ) {
        return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
    }

    // index in selector
    if ( typeof elem === "string" ) {
        return jQuery.inArray( this[ 0 ], jQuery( elem ) );
    }

    // Locate the position of the desired element
    return jQuery.inArray(

        // If it receives a jQuery object, the first element is used
        elem.jquery ? elem[ 0 ] : elem, this );
},

add: function( selector, context ) {
    return this.pushStack(
        jQuery.uniqueSort(
            jQuery.merge( this.get(), jQuery( selector, context ) )
        )
    );
},

addBack: function( selector ) {
    return this.add( selector == null ?
        this.prevObject : this.prevObject.filter( selector )
    );
}

} );

function sibling( cur, dir ) {
do {
cur = cur[ dir ];
} while ( cur && cur.nodeType !== 1 );

return cur;

}

jQuery.each( {
parent: function( elem ) {
var parent = elem.parentNode;
return parent && parent.nodeType !== 11 ? parent : null;
},
parents: function( elem ) {
return dir( elem, “parentNode” );
},
parentsUntil: function( elem, i, until ) {
return dir( elem, “parentNode”, until );
},
next: function( elem ) {
return sibling( elem, “nextSibling” );
},
prev: function( elem ) {
return sibling( elem, “previousSibling” );
},
nextAll: function( elem ) {
return dir( elem, “nextSibling” );
},
prevAll: function( elem ) {
return dir( elem, “previousSibling” );
},
nextUntil: function( elem, i, until ) {
return dir( elem, “nextSibling”, until );
},
prevUntil: function( elem, i, until ) {
return dir( elem, “previousSibling”, until );
},
siblings: function( elem ) {
return siblings( ( elem.parentNode || {} ).firstChild, elem );
},
children: function( elem ) {
return siblings( elem.firstChild );
},
contents: function( elem ) {
return jQuery.nodeName( elem, “iframe” ) ?
elem.contentDocument || elem.contentWindow.document :
jQuery.merge( [], elem.childNodes );
}
}, function( name, fn ) {
jQuery.fn[ name ] = function( until, selector ) {
var ret = jQuery.map( this, fn, until );

    if ( name.slice( -5 ) !== "Until" ) {
        selector = until;
    }

    if ( selector && typeof selector === "string" ) {
        ret = jQuery.filter( selector, ret );
    }

    if ( this.length > 1 ) {

        // Remove duplicates
        if ( !guaranteedUnique[ name ] ) {
            ret = jQuery.uniqueSort( ret );
        }

        // Reverse order for parents* and prev-derivatives
        if ( rparentsprev.test( name ) ) {
            ret = ret.reverse();
        }
    }

    return this.pushStack( ret );
};

} );
var rnotwhite = ( /\S+/g );

// Convert String-formatted options into Object-formatted ones
function createOptions( options ) {
var object = {};
jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
object[ flag ] = true;
} );
return object;
}

/*
* Create a callback list using the following parameters:
*
* options: an optional list of space-separated options that will change how
* the callback list behaves or a more traditional option object
*
* By default a callback list will act like an event callback list and can be
* “fired” multiple times.
*
* Possible options:
*
* once: will ensure the callback list can only be fired once (like a Deferred)
*
* memory: will keep track of previous values and will call any callback added
* after the list has been fired right away with the latest “memorized”
* values (like a Deferred)
*
* unique: will ensure a callback can only be added once (no duplicate in the list)
*
* stopOnFalse: interrupt callings when a callback returns false
*
*/
jQuery.Callbacks = function( options ) {

// Convert options from String-formatted to Object-formatted if needed
// (we check in cache first)
options = typeof options === "string" ?
    createOptions( options ) :
    jQuery.extend( {}, options );

var // Flag to know if list is currently firing
    firing,

    // Last fire value for non-forgettable lists
    memory,

    // Flag to know if list was already fired
    fired,

    // Flag to prevent firing
    locked,

    // Actual callback list
    list = [],

    // Queue of execution data for repeatable lists
    queue = [],

    // Index of currently firing callback (modified by add/remove as needed)
    firingIndex = -1,

    // Fire callbacks
    fire = function() {

        // Enforce single-firing
        locked = options.once;

        // Execute callbacks for all pending executions,
        // respecting firingIndex overrides and runtime changes
        fired = firing = true;
        for ( ; queue.length; firingIndex = -1 ) {
            memory = queue.shift();
            while ( ++firingIndex < list.length ) {

                // Run callback and check for early termination
                if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
                    options.stopOnFalse ) {

                    // Jump to end and forget the data so .add doesn't re-fire
                    firingIndex = list.length;
                    memory = false;
                }
            }
        }

        // Forget the data if we're done with it
        if ( !options.memory ) {
            memory = false;
        }

        firing = false;

        // Clean up if we're done firing for good
        if ( locked ) {

            // Keep an empty list if we have data for future add calls
            if ( memory ) {
                list = [];

            // Otherwise, this object is spent
            } else {
                list = "";
            }
        }
    },

    // Actual Callbacks object
    self = {

        // Add a callback or a collection of callbacks to the list
        add: function() {
            if ( list ) {

                // If we have memory from a past run, we should fire after adding
                if ( memory && !firing ) {
                    firingIndex = list.length - 1;
                    queue.push( memory );
                }

                ( function add( args ) {
                    jQuery.each( args, function( _, arg ) {
                        if ( jQuery.isFunction( arg ) ) {
                            if ( !options.unique || !self.has( arg ) ) {
                                list.push( arg );
                            }
                        } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {

                            // Inspect recursively
                            add( arg );
                        }
                    } );
                } )( arguments );

                if ( memory && !firing ) {
                    fire();
                }
            }
            return this;
        },

        // Remove a callback from the list
        remove: function() {
            jQuery.each( arguments, function( _, arg ) {
                var index;
                while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
                    list.splice( index, 1 );

                    // Handle firing indexes
                    if ( index <= firingIndex ) {
                        firingIndex--;
                    }
                }
            } );
            return this;
        },

        // Check if a given callback is in the list.
        // If no argument is given, return whether or not list has callbacks attached.
        has: function( fn ) {
            return fn ?
                jQuery.inArray( fn, list ) > -1 :
                list.length > 0;
        },

        // Remove all callbacks from the list
        empty: function() {
            if ( list ) {
                list = [];
            }
            return this;
        },

        // Disable .fire and .add
        // Abort any current/pending executions
        // Clear all callbacks and values
        disable: function() {
            locked = queue = [];
            list = memory = "";
            return this;
        },
        disabled: function() {
            return !list;
        },

        // Disable .fire
        // Also disable .add unless we have memory (since it would have no effect)
        // Abort any pending executions
        lock: function() {
            locked = true;
            if ( !memory ) {
                self.disable();
            }
            return this;
        },
        locked: function() {
            return !!locked;
        },

        // Call all callbacks with the given context and arguments
        fireWith: function( context, args ) {
            if ( !locked ) {
                args = args || [];
                args = [ context, args.slice ? args.slice() : args ];
                queue.push( args );
                if ( !firing ) {
                    fire();
                }
            }
            return this;
        },

        // Call all the callbacks with the given arguments
        fire: function() {
            self.fireWith( this, arguments );
            return this;
        },

        // To know if the callbacks have already been called at least once
        fired: function() {
            return !!fired;
        }
    };

return self;

};

jQuery.extend( {

Deferred: function( func ) {
    var tuples = [

            // action, add listener, listener list, final state
            [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ],
            [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ],
            [ "notify", "progress", jQuery.Callbacks( "memory" ) ]
        ],
        state = "pending",
        promise = {
            state: function() {
                return state;
            },
            always: function() {
                deferred.done( arguments ).fail( arguments );
                return this;
            },
            then: function( /* fnDone, fnFail, fnProgress */ ) {
                var fns = arguments;
                return jQuery.Deferred( function( newDefer ) {
                    jQuery.each( tuples, function( i, tuple ) {
                        var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];

                        // deferred[ done | fail | progress ] for forwarding actions to newDefer
                        deferred[ tuple[ 1 ] ]( function() {
                            var returned = fn && fn.apply( this, arguments );
                            if ( returned && jQuery.isFunction( returned.promise ) ) {
                                returned.promise()
                                    .progress( newDefer.notify )
                                    .done( newDefer.resolve )
                                    .fail( newDefer.reject );
                            } else {
                                newDefer[ tuple[ 0 ] + "With" ](
                                    this === promise ? newDefer.promise() : this,
                                    fn ? [ returned ] : arguments
                                );
                            }
                        } );
                    } );
                    fns = null;
                } ).promise();
            },

            // Get a promise for this deferred
            // If obj is provided, the promise aspect is added to the object
            promise: function( obj ) {
                return obj != null ? jQuery.extend( obj, promise ) : promise;
            }
        },
        deferred = {};

    // Keep pipe for back-compat
    promise.pipe = promise.then;

    // Add list-specific methods
    jQuery.each( tuples, function( i, tuple ) {
        var list = tuple[ 2 ],
            stateString = tuple[ 3 ];

        // promise[ done | fail | progress ] = list.add
        promise[ tuple[ 1 ] ] = list.add;

        // Handle state
        if ( stateString ) {
            list.add( function() {

                // state = [ resolved | rejected ]
                state = stateString;

            // [ reject_list | resolve_list ].disable; progress_list.lock
            }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
        }

        // deferred[ resolve | reject | notify ]
        deferred[ tuple[ 0 ] ] = function() {
            deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
            return this;
        };
        deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
    } );

    // Make the deferred a promise
    promise.promise( deferred );

    // Call given func if any
    if ( func ) {
        func.call( deferred, deferred );
    }

    // All done!
    return deferred;
},

// Deferred helper
when: function( subordinate /* , ..., subordinateN */ ) {
    var i = 0,
        resolveValues = slice.call( arguments ),
        length = resolveValues.length,

        // the count of uncompleted subordinates
        remaining = length !== 1 ||
            ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,

        // the master Deferred.
        // If resolveValues consist of only a single Deferred, just use that.
        deferred = remaining === 1 ? subordinate : jQuery.Deferred(),

        // Update function for both resolve and progress values
        updateFunc = function( i, contexts, values ) {
            return function( value ) {
                contexts[ i ] = this;
                values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
                if ( values === progressValues ) {
                    deferred.notifyWith( contexts, values );

                } else if ( !( --remaining ) ) {
                    deferred.resolveWith( contexts, values );
                }
            };
        },

        progressValues, progressContexts, resolveContexts;

    // add listeners to Deferred subordinates; treat others as resolved
    if ( length > 1 ) {
        progressValues = new Array( length );
        progressContexts = new Array( length );
        resolveContexts = new Array( length );
        for ( ; i < length; i++ ) {
            if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
                resolveValues[ i ].promise()
                    .progress( updateFunc( i, progressContexts, progressValues ) )
                    .done( updateFunc( i, resolveContexts, resolveValues ) )
                    .fail( deferred.reject );
            } else {
                --remaining;
            }
        }
    }

    // if we're not waiting on anything, resolve the master
    if ( !remaining ) {
        deferred.resolveWith( resolveContexts, resolveValues );
    }

    return deferred.promise();
}

} );

// The deferred used on DOM ready
var readyList;

jQuery.fn.ready = function( fn ) {

// Add the callback
jQuery.ready.promise().done( fn );

return this;

};

jQuery.extend( {

// Is the DOM ready to be used? Set to true once it occurs.
isReady: false,

// A counter to track how many items to wait for before
// the ready event fires. See #6781
readyWait: 1,

// Hold (or release) the ready event
holdReady: function( hold ) {
    if ( hold ) {
        jQuery.readyWait++;
    } else {
        jQuery.ready( true );
    }
},

// Handle when the DOM is ready
ready: function( wait ) {

    // Abort if there are pending holds or we're already ready
    if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
        return;
    }

    // Remember that the DOM is ready
    jQuery.isReady = true;

    // If a normal DOM Ready event fired, decrement, and wait if need be
    if ( wait !== true && --jQuery.readyWait > 0 ) {
        return;
    }

    // If there are functions bound, to execute
    readyList.resolveWith( document, [ jQuery ] );

    // Trigger any bound ready events
    if ( jQuery.fn.triggerHandler ) {
        jQuery( document ).triggerHandler( "ready" );
        jQuery( document ).off( "ready" );
    }
}

} );

/**
* Clean-up method for dom ready events
*/
function detach() {
if ( document.addEventListener ) {
document.removeEventListener( “DOMContentLoaded”, completed );
window.removeEventListener( “load”, completed );

} else {
    document.detachEvent( "onreadystatechange", completed );
    window.detachEvent( "onload", completed );
}

}

/**
* The ready event handler and self cleanup method
*/
function completed() {

// readyState === "complete" is good enough for us to call the dom ready in oldIE
if ( document.addEventListener ||
    window.event.type === "load" ||
    document.readyState === "complete" ) {

    detach();
    jQuery.ready();
}

}

jQuery.ready.promise = function( obj ) {
if ( !readyList ) {

    readyList = jQuery.Deferred();

    // Catch cases where $(document).ready() is called
    // after the browser event has already occurred.
    // Support: IE6-10
    // Older IE sometimes signals "interactive" too soon
    if ( document.readyState === "complete" ||
        ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {

        // Handle it asynchronously to allow scripts the opportunity to delay ready
        window.setTimeout( jQuery.ready );

    // Standards-based browsers support DOMContentLoaded
    } else if ( document.addEventListener ) {

        // Use the handy event callback
        document.addEventListener( "DOMContentLoaded", completed );

        // A fallback to window.onload, that will always work
        window.addEventListener( "load", completed );

    // If IE event model is used
    } else {

        // Ensure firing before onload, maybe late but safe also for iframes
        document.attachEvent( "onreadystatechange", completed );

        // A fallback to window.onload, that will always work
        window.attachEvent( "onload", completed );

        // If IE and not a frame
        // continually check to see if the document is ready
        var top = false;

        try {
            top = window.frameElement == null && document.documentElement;
        } catch ( e ) {}

        if ( top && top.doScroll ) {
            ( function doScrollCheck() {
                if ( !jQuery.isReady ) {

                    try {

                        // Use the trick by Diego Perini
                        // http://javascript.nwbox.com/IEContentLoaded/
                        top.doScroll( "left" );
                    } catch ( e ) {
                        return window.setTimeout( doScrollCheck, 50 );
                    }

                    // detach all dom ready events
                    detach();

                    // and execute any waiting functions
                    jQuery.ready();
                }
            } )();
        }
    }
}
return readyList.promise( obj );

};

// Kick off the DOM ready check even if the user does not
jQuery.ready.promise();

// Support: IE<9
// Iteration over object’s inherited properties before its own
var i;
for ( i in jQuery( support ) ) {
break;
}
support.ownFirst = i === “0”;

// Note: most support tests are defined in their respective modules.
// false until the test is run
support.inlineBlockNeedsLayout = false;

// Execute ASAP in case we need to set body.style.zoom
jQuery( function() {

// Minified: var a,b,c,d
var val, div, body, container;

body = document.getElementsByTagName( "body" )[ 0 ];
if ( !body || !body.style ) {

    // Return for frameset docs that don't have a body
    return;
}

// Setup
div = document.createElement( "div" );
container = document.createElement( "div" );
container.style.cssText = "po

你可能感兴趣的:(jquery-1.12.3)