How to use oldCallbacks.pop method in Cypress

Best JavaScript code snippet using cypress

jquery-1.10.2.js

Source:jquery-1.10.2.js Github

copy

Full Screen

1/*!2 * jquery javascript library v1.10.23 * http://jquery.com/4 *5 * includes sizzle.js6 * http://sizzlejs.com/7 *8 * copyright 2005, 2013 jquery foundation, inc. and other contributors9 * released under the mit license10 * http://jquery.org/license11 *12 * date: 2013-07-03t13:48z13 */14(function( window, undefined ) {15// can't do this because several apps including asp.net trace16// the stack via arguments.caller.callee and firefox dies if17// you try to trace through "use strict" call chains. (#13335)18// support: firefox 18+19//"use strict";20 var21 // the deferred used on dom ready22 readylist,23 // a central reference to the root jquery(document)24 rootjquery,25 // support: ie<1026 // for `typeof xmlnode.method` instead of `xmlnode.method !== undefined`27 core_strundefined = typeof undefined,28 // use the correct document accordingly with window argument (sandbox)29 location = window.location,30 document = window.document,31 docelem = document.documentelement,32 // map over jquery in case of overwrite33 _jquery = window.jquery,34 // map over the $ in case of overwrite35 _$ = window.$,36 // [[class]] -> type pairs37 class2type = {},38 // list of deleted data cache ids, so we can reuse them39 core_deletedids = [],40 core_version = "1.10.2",41 // save a reference to some core methods42 core_concat = core_deletedids.concat,43 core_push = core_deletedids.push,44 core_slice = core_deletedids.slice,45 core_indexof = core_deletedids.indexof,46 core_tostring = class2type.tostring,47 core_hasown = class2type.hasownproperty,48 core_trim = core_version.trim,49 // define a local copy of jquery50 jquery = function( selector, context ) {51 // the jquery object is actually just the init constructor 'enhanced'52 return new jquery.fn.init( selector, context, rootjquery );53 },54 // used for matching numbers55 core_pnum = /[+-]?(?:\d*\.|)\d+(?:[ee][+-]?\d+|)/.source,56 // used for splitting on whitespace57 core_rnotwhite = /\s+/g,58 // make sure we trim bom and nbsp (here's looking at you, safari 5.0 and ie)59 rtrim = /^[\s\ufeff\xa0]+|[\s\ufeff\xa0]+$/g,60 // a simple way to check for html strings61 // prioritize #id over <tag> to avoid xss via location.hash (#9521)62 // strict html recognition (#11290: must start with <)63 rquickexpr = /^(?:\s*(<[\w\w]+>)[^>]*|#([\w-]*))$/,64 // match a standalone tag65 rsingletag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,66 // json regexp67 rvalidchars = /^[\],:{}\s]*$/,68 rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,69 rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fa-f]{4})/g,70 rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[ee][+-]?\d+|)/g,71 // matches dashed string for camelizing72 rmsprefix = /^-ms-/,73 rdashalpha = /-([\da-z])/gi,74 // used by jquery.camelcase as callback to replace()75 fcamelcase = function( all, letter ) {76 return letter.touppercase();77 },78 // the ready event handler79 completed = function( event ) {80 // readystate === "complete" is good enough for us to call the dom ready in oldie81 if ( document.addeventlistener || event.type === "load" || document.readystate === "complete" ) {82 detach();83 jquery.ready();84 }85 },86 // clean-up method for dom ready events87 detach = function() {88 if ( document.addeventlistener ) {89 document.removeeventlistener( "domcontentloaded", completed, false );90 window.removeeventlistener( "load", completed, false );91 } else {92 document.detachevent( "onreadystatechange", completed );93 window.detachevent( "onload", completed );94 }95 };96 jquery.fn = jquery.prototype = {97 // the current version of jquery being used98 jquery: core_version,99 constructor: jquery,100 init: function( selector, context, rootjquery ) {101 var match, elem;102 // handle: $(""), $(null), $(undefined), $(false)103 if ( !selector ) {104 return this;105 }106 // handle html strings107 if ( typeof selector === "string" ) {108 if ( selector.charat(0) === "<" && selector.charat( selector.length - 1 ) === ">" && selector.length >= 3 ) {109 // assume that strings that start and end with <> are html and skip the regex check110 match = [ null, selector, null ];111 } else {112 match = rquickexpr.exec( selector );113 }114 // match html or make sure no context is specified for #id115 if ( match && (match[1] || !context) ) {116 // handle: $(html) -> $(array)117 if ( match[1] ) {118 context = context instanceof jquery ? context[0] : context;119 // scripts is true for back-compat120 jquery.merge( this, jquery.parsehtml(121 match[1],122 context && context.nodetype ? context.ownerdocument || context : document,123 true124 ) );125 // handle: $(html, props)126 if ( rsingletag.test( match[1] ) && jquery.isplainobject( context ) ) {127 for ( match in context ) {128 // properties of context are called as methods if possible129 if ( jquery.isfunction( this[ match ] ) ) {130 this[ match ]( context[ match ] );131 // ...and otherwise set as attributes132 } else {133 this.attr( match, context[ match ] );134 }135 }136 }137 return this;138 // handle: $(#id)139 } else {140 elem = document.getelementbyid( match[2] );141 // check parentnode to catch when blackberry 4.6 returns142 // nodes that are no longer in the document #6963143 if ( elem && elem.parentnode ) {144 // handle the case where ie and opera return items145 // by name instead of id146 if ( elem.id !== match[2] ) {147 return rootjquery.find( selector );148 }149 // otherwise, we inject the element directly into the jquery object150 this.length = 1;151 this[0] = elem;152 }153 this.context = document;154 this.selector = selector;155 return this;156 }157 // handle: $(expr, $(...))158 } else if ( !context || context.jquery ) {159 return ( context || rootjquery ).find( selector );160 // handle: $(expr, context)161 // (which is just equivalent to: $(context).find(expr)162 } else {163 return this.constructor( context ).find( selector );164 }165 // handle: $(domelement)166 } else if ( selector.nodetype ) {167 this.context = this[0] = selector;168 this.length = 1;169 return this;170 // handle: $(function)171 // shortcut for document ready172 } else if ( jquery.isfunction( selector ) ) {173 return rootjquery.ready( selector );174 }175 if ( selector.selector !== undefined ) {176 this.selector = selector.selector;177 this.context = selector.context;178 }179 return jquery.makearray( selector, this );180 },181 // start with an empty selector182 selector: "",183 // the default length of a jquery object is 0184 length: 0,185 toarray: function() {186 return core_slice.call( this );187 },188 // get the nth element in the matched element set or189 // get the whole matched element set as a clean array190 get: function( num ) {191 return num == null ?192 // return a 'clean' array193 this.toarray() :194 // return just the object195 ( num < 0 ? this[ this.length + num ] : this[ num ] );196 },197 // take an array of elements and push it onto the stack198 // (returning the new matched element set)199 pushstack: function( elems ) {200 // build a new jquery matched element set201 var ret = jquery.merge( this.constructor(), elems );202 // add the old object onto the stack (as a reference)203 ret.prevobject = this;204 ret.context = this.context;205 // return the newly-formed element set206 return ret;207 },208 // execute a callback for every element in the matched set.209 // (you can seed the arguments with an array of args, but this is210 // only used internally.)211 each: function( callback, args ) {212 return jquery.each( this, callback, args );213 },214 ready: function( fn ) {215 // add the callback216 jquery.ready.promise().done( fn );217 return this;218 },219 slice: function() {220 return this.pushstack( core_slice.apply( this, arguments ) );221 },222 first: function() {223 return this.eq( 0 );224 },225 last: function() {226 return this.eq( -1 );227 },228 eq: function( i ) {229 var len = this.length,230 j = +i + ( i < 0 ? len : 0 );231 return this.pushstack( j >= 0 && j < len ? [ this[j] ] : [] );232 },233 map: function( callback ) {234 return this.pushstack( jquery.map(this, function( elem, i ) {235 return callback.call( elem, i, elem );236 }));237 },238 end: function() {239 return this.prevobject || this.constructor(null);240 },241 // for internal use only.242 // behaves like an array's method, not like a jquery method.243 push: core_push,244 sort: [].sort,245 splice: [].splice246 };247// give the init function the jquery prototype for later instantiation248 jquery.fn.init.prototype = jquery.fn;249 jquery.extend = jquery.fn.extend = function() {250 var src, copyisarray, copy, name, options, clone,251 target = arguments[0] || {},252 i = 1,253 length = arguments.length,254 deep = false;255 // handle a deep copy situation256 if ( typeof target === "boolean" ) {257 deep = target;258 target = arguments[1] || {};259 // skip the boolean and the target260 i = 2;261 }262 // handle case when target is a string or something (possible in deep copy)263 if ( typeof target !== "object" && !jquery.isfunction(target) ) {264 target = {};265 }266 // extend jquery itself if only one argument is passed267 if ( length === i ) {268 target = this;269 --i;270 }271 for ( ; i < length; i++ ) {272 // only deal with non-null/undefined values273 if ( (options = arguments[ i ]) != null ) {274 // extend the base object275 for ( name in options ) {276 src = target[ name ];277 copy = options[ name ];278 // prevent never-ending loop279 if ( target === copy ) {280 continue;281 }282 // recurse if we're merging plain objects or arrays283 if ( deep && copy && ( jquery.isplainobject(copy) || (copyisarray = jquery.isarray(copy)) ) ) {284 if ( copyisarray ) {285 copyisarray = false;286 clone = src && jquery.isarray(src) ? src : [];287 } else {288 clone = src && jquery.isplainobject(src) ? src : {};289 }290 // never move original objects, clone them291 target[ name ] = jquery.extend( deep, clone, copy );292 // don't bring in undefined values293 } else if ( copy !== undefined ) {294 target[ name ] = copy;295 }296 }297 }298 }299 // return the modified object300 return target;301 };302 jquery.extend({303 // unique for each copy of jquery on the page304 // non-digits removed to match rinlinejquery305 expando: "jquery" + ( core_version + math.random() ).replace( /\d/g, "" ),306 noconflict: function( deep ) {307 if ( window.$ === jquery ) {308 window.$ = _$;309 }310 if ( deep && window.jquery === jquery ) {311 window.jquery = _jquery;312 }313 return jquery;314 },315 // is the dom ready to be used? set to true once it occurs.316 isready: false,317 // a counter to track how many items to wait for before318 // the ready event fires. see #6781319 readywait: 1,320 // hold (or release) the ready event321 holdready: function( hold ) {322 if ( hold ) {323 jquery.readywait++;324 } else {325 jquery.ready( true );326 }327 },328 // handle when the dom is ready329 ready: function( wait ) {330 // abort if there are pending holds or we're already ready331 if ( wait === true ? --jquery.readywait : jquery.isready ) {332 return;333 }334 // make sure body exists, at least, in case ie gets a little overzealous (ticket #5443).335 if ( !document.body ) {336 return settimeout( jquery.ready );337 }338 // remember that the dom is ready339 jquery.isready = true;340 // if a normal dom ready event fired, decrement, and wait if need be341 if ( wait !== true && --jquery.readywait > 0 ) {342 return;343 }344 // if there are functions bound, to execute345 readylist.resolvewith( document, [ jquery ] );346 // trigger any bound ready events347 if ( jquery.fn.trigger ) {348 jquery( document ).trigger("ready").off("ready");349 }350 },351 // see test/unit/core.js for details concerning isfunction.352 // since version 1.3, dom methods and functions like alert353 // aren't supported. they return false on ie (#2968).354 isfunction: function( obj ) {355 return jquery.type(obj) === "function";356 },357 isarray: array.isarray || function( obj ) {358 return jquery.type(obj) === "array";359 },360 iswindow: function( obj ) {361 /* jshint eqeqeq: false */362 return obj != null && obj == obj.window;363 },364 isnumeric: function( obj ) {365 return !isnan( parsefloat(obj) ) && isfinite( obj );366 },367 type: function( obj ) {368 if ( obj == null ) {369 return string( obj );370 }371 return typeof obj === "object" || typeof obj === "function" ?372 class2type[ core_tostring.call(obj) ] || "object" :373 typeof obj;374 },375 isplainobject: function( obj ) {376 var key;377 // must be an object.378 // because of ie, we also have to check the presence of the constructor property.379 // make sure that dom nodes and window objects don't pass through, as well380 if ( !obj || jquery.type(obj) !== "object" || obj.nodetype || jquery.iswindow( obj ) ) {381 return false;382 }383 try {384 // not own constructor property must be object385 if ( obj.constructor &&386 !core_hasown.call(obj, "constructor") &&387 !core_hasown.call(obj.constructor.prototype, "isprototypeof") ) {388 return false;389 }390 } catch ( e ) {391 // ie8,9 will throw exceptions on certain host objects #9897392 return false;393 }394 // support: ie<9395 // handle iteration over inherited properties before own properties.396 if ( jquery.support.ownlast ) {397 for ( key in obj ) {398 return core_hasown.call( obj, key );399 }400 }401 // own properties are enumerated firstly, so to speed up,402 // if last one is own, then all properties are own.403 for ( key in obj ) {}404 return key === undefined || core_hasown.call( obj, key );405 },406 isemptyobject: function( obj ) {407 var name;408 for ( name in obj ) {409 return false;410 }411 return true;412 },413 error: function( msg ) {414 throw new error( msg );415 },416 // data: string of html417 // context (optional): if specified, the fragment will be created in this context, defaults to document418 // keepscripts (optional): if true, will include scripts passed in the html string419 parsehtml: function( data, context, keepscripts ) {420 if ( !data || typeof data !== "string" ) {421 return null;422 }423 if ( typeof context === "boolean" ) {424 keepscripts = context;425 context = false;426 }427 context = context || document;428 var parsed = rsingletag.exec( data ),429 scripts = !keepscripts && [];430 // single tag431 if ( parsed ) {432 return [ context.createelement( parsed[1] ) ];433 }434 parsed = jquery.buildfragment( [ data ], context, scripts );435 if ( scripts ) {436 jquery( scripts ).remove();437 }438 return jquery.merge( [], parsed.childnodes );439 },440 parsejson: function( data ) {441 // attempt to parse using the native json parser first442 if ( window.json && window.json.parse ) {443 return window.json.parse( data );444 }445 if ( data === null ) {446 return data;447 }448 if ( typeof data === "string" ) {449 // make sure leading/trailing whitespace is removed (ie can't handle it)450 data = jquery.trim( data );451 if ( data ) {452 // make sure the incoming data is actual json453 // logic borrowed from http://json.org/json2.js454 if ( rvalidchars.test( data.replace( rvalidescape, "@" )455 .replace( rvalidtokens, "]" )456 .replace( rvalidbraces, "")) ) {457 return ( new function( "return " + data ) )();458 }459 }460 }461 jquery.error( "invalid json: " + data );462 },463 // cross-browser xml parsing464 parsexml: function( data ) {465 var xml, tmp;466 if ( !data || typeof data !== "string" ) {467 return null;468 }469 try {470 if ( window.domparser ) { // standard471 tmp = new domparser();472 xml = tmp.parsefromstring( data , "text/xml" );473 } else { // ie474 xml = new activexobject( "microsoft.xmldom" );475 xml.async = "false";476 xml.loadxml( data );477 }478 } catch( e ) {479 xml = undefined;480 }481 if ( !xml || !xml.documentelement || xml.getelementsbytagname( "parsererror" ).length ) {482 jquery.error( "invalid xml: " + data );483 }484 return xml;485 },486 noop: function() {},487 // evaluates a script in a global context488 // workarounds based on findings by jim driscoll489 // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context490 globaleval: function( data ) {491 if ( data && jquery.trim( data ) ) {492 // we use execscript on internet explorer493 // we use an anonymous function so that context is window494 // rather than jquery in firefox495 ( window.execscript || function( data ) {496 window[ "eval" ].call( window, data );497 } )( data );498 }499 },500 // convert dashed to camelcase; used by the css and data modules501 // microsoft forgot to hump their vendor prefix (#9572)502 camelcase: function( string ) {503 return string.replace( rmsprefix, "ms-" ).replace( rdashalpha, fcamelcase );504 },505 nodename: function( elem, name ) {506 return elem.nodename && elem.nodename.tolowercase() === name.tolowercase();507 },508 // args is for internal usage only509 each: function( obj, callback, args ) {510 var value,511 i = 0,512 length = obj.length,513 isarray = isarraylike( obj );514 if ( args ) {515 if ( isarray ) {516 for ( ; i < length; i++ ) {517 value = callback.apply( obj[ i ], args );518 if ( value === false ) {519 break;520 }521 }522 } else {523 for ( i in obj ) {524 value = callback.apply( obj[ i ], args );525 if ( value === false ) {526 break;527 }528 }529 }530 // a special, fast, case for the most common use of each531 } else {532 if ( isarray ) {533 for ( ; i < length; i++ ) {534 value = callback.call( obj[ i ], i, obj[ i ] );535 if ( value === false ) {536 break;537 }538 }539 } else {540 for ( i in obj ) {541 value = callback.call( obj[ i ], i, obj[ i ] );542 if ( value === false ) {543 break;544 }545 }546 }547 }548 return obj;549 },550 // use native string.trim function wherever possible551 trim: core_trim && !core_trim.call("\ufeff\xa0") ?552 function( text ) {553 return text == null ?554 "" :555 core_trim.call( text );556 } :557 // otherwise use our own trimming functionality558 function( text ) {559 return text == null ?560 "" :561 ( text + "" ).replace( rtrim, "" );562 },563 // results is for internal usage only564 makearray: function( arr, results ) {565 var ret = results || [];566 if ( arr != null ) {567 if ( isarraylike( object(arr) ) ) {568 jquery.merge( ret,569 typeof arr === "string" ?570 [ arr ] : arr571 );572 } else {573 core_push.call( ret, arr );574 }575 }576 return ret;577 },578 inarray: function( elem, arr, i ) {579 var len;580 if ( arr ) {581 if ( core_indexof ) {582 return core_indexof.call( arr, elem, i );583 }584 len = arr.length;585 i = i ? i < 0 ? math.max( 0, len + i ) : i : 0;586 for ( ; i < len; i++ ) {587 // skip accessing in sparse arrays588 if ( i in arr && arr[ i ] === elem ) {589 return i;590 }591 }592 }593 return -1;594 },595 merge: function( first, second ) {596 var l = second.length,597 i = first.length,598 j = 0;599 if ( typeof l === "number" ) {600 for ( ; j < l; j++ ) {601 first[ i++ ] = second[ j ];602 }603 } else {604 while ( second[j] !== undefined ) {605 first[ i++ ] = second[ j++ ];606 }607 }608 first.length = i;609 return first;610 },611 grep: function( elems, callback, inv ) {612 var retval,613 ret = [],614 i = 0,615 length = elems.length;616 inv = !!inv;617 // go through the array, only saving the items618 // that pass the validator function619 for ( ; i < length; i++ ) {620 retval = !!callback( elems[ i ], i );621 if ( inv !== retval ) {622 ret.push( elems[ i ] );623 }624 }625 return ret;626 },627 // arg is for internal usage only628 map: function( elems, callback, arg ) {629 var value,630 i = 0,631 length = elems.length,632 isarray = isarraylike( elems ),633 ret = [];634 // go through the array, translating each of the items to their635 if ( isarray ) {636 for ( ; i < length; i++ ) {637 value = callback( elems[ i ], i, arg );638 if ( value != null ) {639 ret[ ret.length ] = value;640 }641 }642 // go through every key on the object,643 } else {644 for ( i in elems ) {645 value = callback( elems[ i ], i, arg );646 if ( value != null ) {647 ret[ ret.length ] = value;648 }649 }650 }651 // flatten any nested arrays652 return core_concat.apply( [], ret );653 },654 // a global guid counter for objects655 guid: 1,656 // bind a function to a context, optionally partially applying any657 // arguments.658 proxy: function( fn, context ) {659 var args, proxy, tmp;660 if ( typeof context === "string" ) {661 tmp = fn[ context ];662 context = fn;663 fn = tmp;664 }665 // quick check to determine if target is callable, in the spec666 // this throws a typeerror, but we will just return undefined.667 if ( !jquery.isfunction( fn ) ) {668 return undefined;669 }670 // simulated bind671 args = core_slice.call( arguments, 2 );672 proxy = function() {673 return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) );674 };675 // set the guid of unique handler to the same of original handler, so it can be removed676 proxy.guid = fn.guid = fn.guid || jquery.guid++;677 return proxy;678 },679 // multifunctional method to get and set values of a collection680 // the value/s can optionally be executed if it's a function681 access: function( elems, fn, key, value, chainable, emptyget, raw ) {682 var i = 0,683 length = elems.length,684 bulk = key == null;685 // sets many values686 if ( jquery.type( key ) === "object" ) {687 chainable = true;688 for ( i in key ) {689 jquery.access( elems, fn, i, key[i], true, emptyget, raw );690 }691 // sets one value692 } else if ( value !== undefined ) {693 chainable = true;694 if ( !jquery.isfunction( value ) ) {695 raw = true;696 }697 if ( bulk ) {698 // bulk operations run against the entire set699 if ( raw ) {700 fn.call( elems, value );701 fn = null;702 // ...except when executing function values703 } else {704 bulk = fn;705 fn = function( elem, key, value ) {706 return bulk.call( jquery( elem ), value );707 };708 }709 }710 if ( fn ) {711 for ( ; i < length; i++ ) {712 fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );713 }714 }715 }716 return chainable ?717 elems :718 // gets719 bulk ?720 fn.call( elems ) :721 length ? fn( elems[0], key ) : emptyget;722 },723 now: function() {724 return ( new date() ).gettime();725 },726 // a method for quickly swapping in/out css properties to get correct calculations.727 // note: this method belongs to the css module but it's needed here for the support module.728 // if support gets modularized, this method should be moved back to the css module.729 swap: function( elem, options, callback, args ) {730 var ret, name,731 old = {};732 // remember the old values, and insert the new ones733 for ( name in options ) {734 old[ name ] = elem.style[ name ];735 elem.style[ name ] = options[ name ];736 }737 ret = callback.apply( elem, args || [] );738 // revert the old values739 for ( name in options ) {740 elem.style[ name ] = old[ name ];741 }742 return ret;743 }744 });745 jquery.ready.promise = function( obj ) {746 if ( !readylist ) {747 readylist = jquery.deferred();748 // catch cases where $(document).ready() is called after the browser event has already occurred.749 // we once tried to use readystate "interactive" here, but it caused issues like the one750 // discovered by chriss here: http://bugs.jquery.com/ticket/12282#comment:15751 if ( document.readystate === "complete" ) {752 // handle it asynchronously to allow scripts the opportunity to delay ready753 settimeout( jquery.ready );754 // standards-based browsers support domcontentloaded755 } else if ( document.addeventlistener ) {756 // use the handy event callback757 document.addeventlistener( "domcontentloaded", completed, false );758 // a fallback to window.onload, that will always work759 window.addeventlistener( "load", completed, false );760 // if ie event model is used761 } else {762 // ensure firing before onload, maybe late but safe also for iframes763 document.attachevent( "onreadystatechange", completed );764 // a fallback to window.onload, that will always work765 window.attachevent( "onload", completed );766 // if ie and not a frame767 // continually check to see if the document is ready768 var top = false;769 try {770 top = window.frameelement == null && document.documentelement;771 } catch(e) {}772 if ( top && top.doscroll ) {773 (function doscrollcheck() {774 if ( !jquery.isready ) {775 try {776 // use the trick by diego perini777 // http://javascript.nwbox.com/iecontentloaded/778 top.doscroll("left");779 } catch(e) {780 return settimeout( doscrollcheck, 50 );781 }782 // detach all dom ready events783 detach();784 // and execute any waiting functions785 jquery.ready();786 }787 })();788 }789 }790 }791 return readylist.promise( obj );792 };793// populate the class2type map794 jquery.each("boolean number string function array date regexp object error".split(" "), function(i, name) {795 class2type[ "[object " + name + "]" ] = name.tolowercase();796 });797 function isarraylike( obj ) {798 var length = obj.length,799 type = jquery.type( obj );800 if ( jquery.iswindow( obj ) ) {801 return false;802 }803 if ( obj.nodetype === 1 && length ) {804 return true;805 }806 return type === "array" || type !== "function" &&807 ( length === 0 ||808 typeof length === "number" && length > 0 && ( length - 1 ) in obj );809 }810// all jquery objects should point back to these811 rootjquery = jquery(document);812 /*!813 * sizzle css selector engine v1.10.2814 * http://sizzlejs.com/815 *816 * copyright 2013 jquery foundation, inc. and other contributors817 * released under the mit license818 * http://jquery.org/license819 *820 * date: 2013-07-03821 */822 (function( window, undefined ) {823 var i,824 support,825 cachedruns,826 expr,827 gettext,828 isxml,829 compile,830 outermostcontext,831 sortinput,832 // local document vars833 setdocument,834 document,835 docelem,836 documentishtml,837 rbuggyqsa,838 rbuggymatches,839 matches,840 contains,841 // instance-specific data842 expando = "sizzle" + -(new date()),843 preferreddoc = window.document,844 dirruns = 0,845 done = 0,846 classcache = createcache(),847 tokencache = createcache(),848 compilercache = createcache(),849 hasduplicate = false,850 sortorder = function( a, b ) {851 if ( a === b ) {852 hasduplicate = true;853 return 0;854 }855 return 0;856 },857 // general-purpose constants858 strundefined = typeof undefined,859 max_negative = 1 << 31,860 // instance methods861 hasown = ({}).hasownproperty,862 arr = [],863 pop = arr.pop,864 push_native = arr.push,865 push = arr.push,866 slice = arr.slice,867 // use a stripped-down indexof if we can't use a native one868 indexof = arr.indexof || function( elem ) {869 var i = 0,870 len = this.length;871 for ( ; i < len; i++ ) {872 if ( this[i] === elem ) {873 return i;874 }875 }876 return -1;877 },878 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",879 // regular expressions880 // whitespace characters http://www.w3.org/tr/css3-selectors/#whitespace881 whitespace = "[\\x20\\t\\r\\n\\f]",882 // http://www.w3.org/tr/css3-syntax/#characters883 characterencoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",884 // loosely modeled on css identifier characters885 // an unquoted value should be a css identifier http://www.w3.org/tr/css3-selectors/#attribute-selectors886 // proper syntax: http://www.w3.org/tr/css21/syndata.html#value-def-identifier887 identifier = characterencoding.replace( "w", "w#" ),888 // acceptable operators http://www.w3.org/tr/selectors/#attribute-selectors889 attributes = "\\[" + whitespace + "*(" + characterencoding + ")" + whitespace +890 "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",891 // prefer arguments quoted,892 // then not containing pseudos/brackets,893 // then attribute selectors/non-parenthetical expressions,894 // then anything else895 // these preferences are here to reduce the number of selectors896 // needing tokenize in the pseudo prefilter897 pseudos = ":(" + characterencoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)",898 // leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter899 rtrim = new regexp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),900 rcomma = new regexp( "^" + whitespace + "*," + whitespace + "*" ),901 rcombinators = new regexp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),902 rsibling = new regexp( whitespace + "*[+~]" ),903 rattributequotes = new regexp( "=" + whitespace + "*([^\\]'\"]*)" + whitespace + "*\\]", "g" ),904 rpseudo = new regexp( pseudos ),905 ridentifier = new regexp( "^" + identifier + "$" ),906 matchexpr = {907 "id": new regexp( "^#(" + characterencoding + ")" ),908 "class": new regexp( "^\\.(" + characterencoding + ")" ),909 "tag": new regexp( "^(" + characterencoding.replace( "w", "w*" ) + ")" ),910 "attr": new regexp( "^" + attributes ),911 "pseudo": new regexp( "^" + pseudos ),912 "child": new regexp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +913 "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +914 "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),915 "bool": new regexp( "^(?:" + booleans + ")$", "i" ),916 // for use in libraries implementing .is()917 // we use this for pos matching in `select`918 "needscontext": new regexp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +919 whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )920 },921 rnative = /^[^{]+\{\s*\[native \w/,922 // easily-parseable/retrievable id or tag or class selectors923 rquickexpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,924 rinputs = /^(?:input|select|textarea|button)$/i,925 rheader = /^h\d$/i,926 rescape = /'|\\/g,927 // css escapes http://www.w3.org/tr/css21/syndata.html#escaped-characters928 runescape = new regexp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),929 funescape = function( _, escaped, escapedwhitespace ) {930 var high = "0x" + escaped - 0x10000;931 // nan means non-codepoint932 // support: firefox933 // workaround erroneous numeric interpretation of +"0x"934 return high !== high || escapedwhitespace ?935 escaped :936 // bmp codepoint937 high < 0 ?938 string.fromcharcode( high + 0x10000 ) :939 // supplemental plane codepoint (surrogate pair)940 string.fromcharcode( high >> 10 | 0xd800, high & 0x3ff | 0xdc00 );941 };942// optimize for push.apply( _, nodelist )943 try {944 push.apply(945 (arr = slice.call( preferreddoc.childnodes )),946 preferreddoc.childnodes947 );948 // support: android<4.0949 // detect silently failing push.apply950 arr[ preferreddoc.childnodes.length ].nodetype;951 } catch ( e ) {952 push = { apply: arr.length ?953 // leverage slice if possible954 function( target, els ) {955 push_native.apply( target, slice.call(els) );956 } :957 // support: ie<9958 // otherwise append directly959 function( target, els ) {960 var j = target.length,961 i = 0;962 // can't trust nodelist.length963 while ( (target[j++] = els[i++]) ) {}964 target.length = j - 1;965 }966 };967 }968 function sizzle( selector, context, results, seed ) {969 var match, elem, m, nodetype,970 // qsa vars971 i, groups, old, nid, newcontext, newselector;972 if ( ( context ? context.ownerdocument || context : preferreddoc ) !== document ) {973 setdocument( context );974 }975 context = context || document;976 results = results || [];977 if ( !selector || typeof selector !== "string" ) {978 return results;979 }980 if ( (nodetype = context.nodetype) !== 1 && nodetype !== 9 ) {981 return [];982 }983 if ( documentishtml && !seed ) {984 // shortcuts985 if ( (match = rquickexpr.exec( selector )) ) {986 // speed-up: sizzle("#id")987 if ( (m = match[1]) ) {988 if ( nodetype === 9 ) {989 elem = context.getelementbyid( m );990 // check parentnode to catch when blackberry 4.6 returns991 // nodes that are no longer in the document #6963992 if ( elem && elem.parentnode ) {993 // handle the case where ie, opera, and webkit return items994 // by name instead of id995 if ( elem.id === m ) {996 results.push( elem );997 return results;998 }999 } else {1000 return results;1001 }1002 } else {1003 // context is not a document1004 if ( context.ownerdocument && (elem = context.ownerdocument.getelementbyid( m )) &&1005 contains( context, elem ) && elem.id === m ) {1006 results.push( elem );1007 return results;1008 }1009 }1010 // speed-up: sizzle("tag")1011 } else if ( match[2] ) {1012 push.apply( results, context.getelementsbytagname( selector ) );1013 return results;1014 // speed-up: sizzle(".class")1015 } else if ( (m = match[3]) && support.getelementsbyclassname && context.getelementsbyclassname ) {1016 push.apply( results, context.getelementsbyclassname( m ) );1017 return results;1018 }1019 }1020 // qsa path1021 if ( support.qsa && (!rbuggyqsa || !rbuggyqsa.test( selector )) ) {1022 nid = old = expando;1023 newcontext = context;1024 newselector = nodetype === 9 && selector;1025 // qsa works strangely on element-rooted queries1026 // we can work around this by specifying an extra id on the root1027 // and working up from there (thanks to andrew dupont for the technique)1028 // ie 8 doesn't work on object elements1029 if ( nodetype === 1 && context.nodename.tolowercase() !== "object" ) {1030 groups = tokenize( selector );1031 if ( (old = context.getattribute("id")) ) {1032 nid = old.replace( rescape, "\\$&" );1033 } else {1034 context.setattribute( "id", nid );1035 }1036 nid = "[id='" + nid + "'] ";1037 i = groups.length;1038 while ( i-- ) {1039 groups[i] = nid + toselector( groups[i] );1040 }1041 newcontext = rsibling.test( selector ) && context.parentnode || context;1042 newselector = groups.join(",");1043 }1044 if ( newselector ) {1045 try {1046 push.apply( results,1047 newcontext.queryselectorall( newselector )1048 );1049 return results;1050 } catch(qsaerror) {1051 } finally {1052 if ( !old ) {1053 context.removeattribute("id");1054 }1055 }1056 }1057 }1058 }1059 // all others1060 return select( selector.replace( rtrim, "$1" ), context, results, seed );1061 }1062 /**1063 * create key-value caches of limited size1064 * @returns {function(string, object)} returns the object data after storing it on itself with1065 * property name the (space-suffixed) string and (if the cache is larger than expr.cachelength)1066 * deleting the oldest entry1067 */1068 function createcache() {1069 var keys = [];1070 function cache( key, value ) {1071 // use (key + " ") to avoid collision with native prototype properties (see issue #157)1072 if ( keys.push( key += " " ) > expr.cachelength ) {1073 // only keep the most recent entries1074 delete cache[ keys.shift() ];1075 }1076 return (cache[ key ] = value);1077 }1078 return cache;1079 }1080 /**1081 * mark a function for special use by sizzle1082 * @param {function} fn the function to mark1083 */1084 function markfunction( fn ) {1085 fn[ expando ] = true;1086 return fn;1087 }1088 /**1089 * support testing using an element1090 * @param {function} fn passed the created div and expects a boolean result1091 */1092 function assert( fn ) {1093 var div = document.createelement("div");1094 try {1095 return !!fn( div );1096 } catch (e) {1097 return false;1098 } finally {1099 // remove from its parent by default1100 if ( div.parentnode ) {1101 div.parentnode.removechild( div );1102 }1103 // release memory in ie1104 div = null;1105 }1106 }1107 /**1108 * adds the same handler for all of the specified attrs1109 * @param {string} attrs pipe-separated list of attributes1110 * @param {function} handler the method that will be applied1111 */1112 function addhandle( attrs, handler ) {1113 var arr = attrs.split("|"),1114 i = attrs.length;1115 while ( i-- ) {1116 expr.attrhandle[ arr[i] ] = handler;1117 }1118 }1119 /**1120 * checks document order of two siblings1121 * @param {element} a1122 * @param {element} b1123 * @returns {number} returns less than 0 if a precedes b, greater than 0 if a follows b1124 */1125 function siblingcheck( a, b ) {1126 var cur = b && a,1127 diff = cur && a.nodetype === 1 && b.nodetype === 1 &&1128 ( ~b.sourceindex || max_negative ) -1129 ( ~a.sourceindex || max_negative );1130 // use ie sourceindex if available on both nodes1131 if ( diff ) {1132 return diff;1133 }1134 // check if b follows a1135 if ( cur ) {1136 while ( (cur = cur.nextsibling) ) {1137 if ( cur === b ) {1138 return -1;1139 }1140 }1141 }1142 return a ? 1 : -1;1143 }1144 /**1145 * returns a function to use in pseudos for input types1146 * @param {string} type1147 */1148 function createinputpseudo( type ) {1149 return function( elem ) {1150 var name = elem.nodename.tolowercase();1151 return name === "input" && elem.type === type;1152 };1153 }1154 /**1155 * returns a function to use in pseudos for buttons1156 * @param {string} type1157 */1158 function createbuttonpseudo( type ) {1159 return function( elem ) {1160 var name = elem.nodename.tolowercase();1161 return (name === "input" || name === "button") && elem.type === type;1162 };1163 }1164 /**1165 * returns a function to use in pseudos for positionals1166 * @param {function} fn1167 */1168 function createpositionalpseudo( fn ) {1169 return markfunction(function( argument ) {1170 argument = +argument;1171 return markfunction(function( seed, matches ) {1172 var j,1173 matchindexes = fn( [], seed.length, argument ),1174 i = matchindexes.length;1175 // match elements found at the specified indexes1176 while ( i-- ) {1177 if ( seed[ (j = matchindexes[i]) ] ) {1178 seed[j] = !(matches[j] = seed[j]);1179 }1180 }1181 });1182 });1183 }1184 /**1185 * detect xml1186 * @param {element|object} elem an element or a document1187 */1188 isxml = sizzle.isxml = function( elem ) {1189 // documentelement is verified for cases where it doesn't yet exist1190 // (such as loading iframes in ie - #4833)1191 var documentelement = elem && (elem.ownerdocument || elem).documentelement;1192 return documentelement ? documentelement.nodename !== "html" : false;1193 };1194// expose support vars for convenience1195 support = sizzle.support = {};1196 /**1197 * sets document-related variables once based on the current document1198 * @param {element|object} [doc] an element or document object to use to set the document1199 * @returns {object} returns the current document1200 */1201 setdocument = sizzle.setdocument = function( node ) {1202 var doc = node ? node.ownerdocument || node : preferreddoc,1203 parent = doc.defaultview;1204 // if no document and documentelement is available, return1205 if ( doc === document || doc.nodetype !== 9 || !doc.documentelement ) {1206 return document;1207 }1208 // set our document1209 document = doc;1210 docelem = doc.documentelement;1211 // support tests1212 documentishtml = !isxml( doc );1213 // support: ie>81214 // if iframe document is assigned to "document" variable and if iframe has been reloaded,1215 // ie will throw "permission denied" error when accessing "document" variable, see jquery #139361216 // ie6-8 do not support the defaultview property so parent will be undefined1217 if ( parent && parent.attachevent && parent !== parent.top ) {1218 parent.attachevent( "onbeforeunload", function() {1219 setdocument();1220 });1221 }1222 /* attributes1223 ---------------------------------------------------------------------- */1224 // support: ie<81225 // verify that getattribute really returns attributes and not properties (excepting ie8 booleans)1226 support.attributes = assert(function( div ) {1227 div.classname = "i";1228 return !div.getattribute("classname");1229 });1230 /* getelement(s)by*1231 ---------------------------------------------------------------------- */1232 // check if getelementsbytagname("*") returns only elements1233 support.getelementsbytagname = assert(function( div ) {1234 div.appendchild( doc.createcomment("") );1235 return !div.getelementsbytagname("*").length;1236 });1237 // check if getelementsbyclassname can be trusted1238 support.getelementsbyclassname = assert(function( div ) {1239 div.innerhtml = "<div class='a'></div><div class='a i'></div>";1240 // support: safari<41241 // catch class over-caching1242 div.firstchild.classname = "i";1243 // support: opera<101244 // catch gebcn failure to find non-leading classes1245 return div.getelementsbyclassname("i").length === 2;1246 });1247 // support: ie<101248 // check if getelementbyid returns elements by name1249 // the broken getelementbyid methods don't pick up programatically-set names,1250 // so use a roundabout getelementsbyname test1251 support.getbyid = assert(function( div ) {1252 docelem.appendchild( div ).id = expando;1253 return !doc.getelementsbyname || !doc.getelementsbyname( expando ).length;1254 });1255 // id find and filter1256 if ( support.getbyid ) {1257 expr.find["id"] = function( id, context ) {1258 if ( typeof context.getelementbyid !== strundefined && documentishtml ) {1259 var m = context.getelementbyid( id );1260 // check parentnode to catch when blackberry 4.6 returns1261 // nodes that are no longer in the document #69631262 return m && m.parentnode ? [m] : [];1263 }1264 };1265 expr.filter["id"] = function( id ) {1266 var attrid = id.replace( runescape, funescape );1267 return function( elem ) {1268 return elem.getattribute("id") === attrid;1269 };1270 };1271 } else {1272 // support: ie6/71273 // getelementbyid is not reliable as a find shortcut1274 delete expr.find["id"];1275 expr.filter["id"] = function( id ) {1276 var attrid = id.replace( runescape, funescape );1277 return function( elem ) {1278 var node = typeof elem.getattributenode !== strundefined && elem.getattributenode("id");1279 return node && node.value === attrid;1280 };1281 };1282 }1283 // tag1284 expr.find["tag"] = support.getelementsbytagname ?1285 function( tag, context ) {1286 if ( typeof context.getelementsbytagname !== strundefined ) {1287 return context.getelementsbytagname( tag );1288 }1289 } :1290 function( tag, context ) {1291 var elem,1292 tmp = [],1293 i = 0,1294 results = context.getelementsbytagname( tag );1295 // filter out possible comments1296 if ( tag === "*" ) {1297 while ( (elem = results[i++]) ) {1298 if ( elem.nodetype === 1 ) {1299 tmp.push( elem );1300 }1301 }1302 return tmp;1303 }1304 return results;1305 };1306 // class1307 expr.find["class"] = support.getelementsbyclassname && function( classname, context ) {1308 if ( typeof context.getelementsbyclassname !== strundefined && documentishtml ) {1309 return context.getelementsbyclassname( classname );1310 }1311 };1312 /* qsa/matchesselector1313 ---------------------------------------------------------------------- */1314 // qsa and matchesselector support1315 // matchesselector(:active) reports false when true (ie9/opera 11.5)1316 rbuggymatches = [];1317 // qsa(:focus) reports false when true (chrome 21)1318 // we allow this because of a bug in ie8/9 that throws an error1319 // whenever `document.activeelement` is accessed on an iframe1320 // so, we allow :focus to pass through qsa all the time to avoid the ie error1321 // see http://bugs.jquery.com/ticket/133781322 rbuggyqsa = [];1323 if ( (support.qsa = rnative.test( doc.queryselectorall )) ) {1324 // build qsa regex1325 // regex strategy adopted from diego perini1326 assert(function( div ) {1327 // select is set to empty string on purpose1328 // this is to test ie's treatment of not explicitly1329 // setting a boolean content attribute,1330 // since its presence should be enough1331 // http://bugs.jquery.com/ticket/123591332 div.innerhtml = "<select><option selected=''></option></select>";1333 // support: ie81334 // boolean attributes and "value" are not treated correctly1335 if ( !div.queryselectorall("[selected]").length ) {1336 rbuggyqsa.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );1337 }1338 // webkit/opera - :checked should return selected option elements1339 // http://www.w3.org/tr/2011/rec-css3-selectors-20110929/#checked1340 // ie8 throws error here and will not see later tests1341 if ( !div.queryselectorall(":checked").length ) {1342 rbuggyqsa.push(":checked");1343 }1344 });1345 assert(function( div ) {1346 // support: opera 10-12/ie81347 // ^= $= *= and empty values1348 // should not select anything1349 // support: windows 8 native apps1350 // the type attribute is restricted during .innerhtml assignment1351 var input = doc.createelement("input");1352 input.setattribute( "type", "hidden" );1353 div.appendchild( input ).setattribute( "t", "" );1354 if ( div.queryselectorall("[t^='']").length ) {1355 rbuggyqsa.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );1356 }1357 // ff 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)1358 // ie8 throws error here and will not see later tests1359 if ( !div.queryselectorall(":enabled").length ) {1360 rbuggyqsa.push( ":enabled", ":disabled" );1361 }1362 // opera 10-11 does not throw on post-comma invalid pseudos1363 div.queryselectorall("*,:x");1364 rbuggyqsa.push(",.*:");1365 });1366 }1367 if ( (support.matchesselector = rnative.test( (matches = docelem.webkitmatchesselector ||1368 docelem.mozmatchesselector ||1369 docelem.omatchesselector ||1370 docelem.msmatchesselector) )) ) {1371 assert(function( div ) {1372 // check to see if it's possible to do matchesselector1373 // on a disconnected node (ie 9)1374 support.disconnectedmatch = matches.call( div, "div" );1375 // this should fail with an exception1376 // gecko does not error, returns false instead1377 matches.call( div, "[s!='']:x" );1378 rbuggymatches.push( "!=", pseudos );1379 });1380 }1381 rbuggyqsa = rbuggyqsa.length && new regexp( rbuggyqsa.join("|") );1382 rbuggymatches = rbuggymatches.length && new regexp( rbuggymatches.join("|") );1383 /* contains1384 ---------------------------------------------------------------------- */1385 // element contains another1386 // purposefully does not implement inclusive descendent1387 // as in, an element does not contain itself1388 contains = rnative.test( docelem.contains ) || docelem.comparedocumentposition ?1389 function( a, b ) {1390 var adown = a.nodetype === 9 ? a.documentelement : a,1391 bup = b && b.parentnode;1392 return a === bup || !!( bup && bup.nodetype === 1 && (1393 adown.contains ?1394 adown.contains( bup ) :1395 a.comparedocumentposition && a.comparedocumentposition( bup ) & 161396 ));1397 } :1398 function( a, b ) {1399 if ( b ) {1400 while ( (b = b.parentnode) ) {1401 if ( b === a ) {1402 return true;1403 }1404 }1405 }1406 return false;1407 };1408 /* sorting1409 ---------------------------------------------------------------------- */1410 // document order sorting1411 sortorder = docelem.comparedocumentposition ?1412 function( a, b ) {1413 // flag for duplicate removal1414 if ( a === b ) {1415 hasduplicate = true;1416 return 0;1417 }1418 var compare = b.comparedocumentposition && a.comparedocumentposition && a.comparedocumentposition( b );1419 if ( compare ) {1420 // disconnected nodes1421 if ( compare & 1 ||1422 (!support.sortdetached && b.comparedocumentposition( a ) === compare) ) {1423 // choose the first element that is related to our preferred document1424 if ( a === doc || contains(preferreddoc, a) ) {1425 return -1;1426 }1427 if ( b === doc || contains(preferreddoc, b) ) {1428 return 1;1429 }1430 // maintain original order1431 return sortinput ?1432 ( indexof.call( sortinput, a ) - indexof.call( sortinput, b ) ) :1433 0;1434 }1435 return compare & 4 ? -1 : 1;1436 }1437 // not directly comparable, sort on existence of method1438 return a.comparedocumentposition ? -1 : 1;1439 } :1440 function( a, b ) {1441 var cur,1442 i = 0,1443 aup = a.parentnode,1444 bup = b.parentnode,1445 ap = [ a ],1446 bp = [ b ];1447 // exit early if the nodes are identical1448 if ( a === b ) {1449 hasduplicate = true;1450 return 0;1451 // parentless nodes are either documents or disconnected1452 } else if ( !aup || !bup ) {1453 return a === doc ? -1 :1454 b === doc ? 1 :1455 aup ? -1 :1456 bup ? 1 :1457 sortinput ?1458 ( indexof.call( sortinput, a ) - indexof.call( sortinput, b ) ) :1459 0;1460 // if the nodes are siblings, we can do a quick check1461 } else if ( aup === bup ) {1462 return siblingcheck( a, b );1463 }1464 // otherwise we need full lists of their ancestors for comparison1465 cur = a;1466 while ( (cur = cur.parentnode) ) {1467 ap.unshift( cur );1468 }1469 cur = b;1470 while ( (cur = cur.parentnode) ) {1471 bp.unshift( cur );1472 }1473 // walk down the tree looking for a discrepancy1474 while ( ap[i] === bp[i] ) {1475 i++;1476 }1477 return i ?1478 // do a sibling check if the nodes have a common ancestor1479 siblingcheck( ap[i], bp[i] ) :1480 // otherwise nodes in our document sort first1481 ap[i] === preferreddoc ? -1 :1482 bp[i] === preferreddoc ? 1 :1483 0;1484 };1485 return doc;1486 };1487 sizzle.matches = function( expr, elements ) {1488 return sizzle( expr, null, null, elements );1489 };1490 sizzle.matchesselector = function( elem, expr ) {1491 // set document vars if needed1492 if ( ( elem.ownerdocument || elem ) !== document ) {1493 setdocument( elem );1494 }1495 // make sure that attribute selectors are quoted1496 expr = expr.replace( rattributequotes, "='$1']" );1497 if ( support.matchesselector && documentishtml &&1498 ( !rbuggymatches || !rbuggymatches.test( expr ) ) &&1499 ( !rbuggyqsa || !rbuggyqsa.test( expr ) ) ) {1500 try {1501 var ret = matches.call( elem, expr );1502 // ie 9's matchesselector returns false on disconnected nodes1503 if ( ret || support.disconnectedmatch ||1504 // as well, disconnected nodes are said to be in a document1505 // fragment in ie 91506 elem.document && elem.document.nodetype !== 11 ) {1507 return ret;1508 }1509 } catch(e) {}1510 }1511 return sizzle( expr, document, null, [elem] ).length > 0;1512 };1513 sizzle.contains = function( context, elem ) {1514 // set document vars if needed1515 if ( ( context.ownerdocument || context ) !== document ) {1516 setdocument( context );1517 }1518 return contains( context, elem );1519 };1520 sizzle.attr = function( elem, name ) {1521 // set document vars if needed1522 if ( ( elem.ownerdocument || elem ) !== document ) {1523 setdocument( elem );1524 }1525 var fn = expr.attrhandle[ name.tolowercase() ],1526 // don't get fooled by object.prototype properties (jquery #13807)1527 val = fn && hasown.call( expr.attrhandle, name.tolowercase() ) ?1528 fn( elem, name, !documentishtml ) :1529 undefined;1530 return val === undefined ?1531 support.attributes || !documentishtml ?1532 elem.getattribute( name ) :1533 (val = elem.getattributenode(name)) && val.specified ?1534 val.value :1535 null :1536 val;1537 };1538 sizzle.error = function( msg ) {1539 throw new error( "syntax error, unrecognized expression: " + msg );1540 };1541 /**1542 * document sorting and removing duplicates1543 * @param {arraylike} results1544 */1545 sizzle.uniquesort = function( results ) {1546 var elem,1547 duplicates = [],1548 j = 0,1549 i = 0;1550 // unless we *know* we can detect duplicates, assume their presence1551 hasduplicate = !support.detectduplicates;1552 sortinput = !support.sortstable && results.slice( 0 );1553 results.sort( sortorder );1554 if ( hasduplicate ) {1555 while ( (elem = results[i++]) ) {1556 if ( elem === results[ i ] ) {1557 j = duplicates.push( i );1558 }1559 }1560 while ( j-- ) {1561 results.splice( duplicates[ j ], 1 );1562 }1563 }1564 return results;1565 };1566 /**1567 * utility function for retrieving the text value of an array of dom nodes1568 * @param {array|element} elem1569 */1570 gettext = sizzle.gettext = function( elem ) {1571 var node,1572 ret = "",1573 i = 0,1574 nodetype = elem.nodetype;1575 if ( !nodetype ) {1576 // if no nodetype, this is expected to be an array1577 for ( ; (node = elem[i]); i++ ) {1578 // do not traverse comment nodes1579 ret += gettext( node );1580 }1581 } else if ( nodetype === 1 || nodetype === 9 || nodetype === 11 ) {1582 // use textcontent for elements1583 // innertext usage removed for consistency of new lines (see #11153)1584 if ( typeof elem.textcontent === "string" ) {1585 return elem.textcontent;1586 } else {1587 // traverse its children1588 for ( elem = elem.firstchild; elem; elem = elem.nextsibling ) {1589 ret += gettext( elem );1590 }1591 }1592 } else if ( nodetype === 3 || nodetype === 4 ) {1593 return elem.nodevalue;1594 }1595 // do not include comment or processing instruction nodes1596 return ret;1597 };1598 expr = sizzle.selectors = {1599 // can be adjusted by the user1600 cachelength: 50,1601 createpseudo: markfunction,1602 match: matchexpr,1603 attrhandle: {},1604 find: {},1605 relative: {1606 ">": { dir: "parentnode", first: true },1607 " ": { dir: "parentnode" },1608 "+": { dir: "previoussibling", first: true },1609 "~": { dir: "previoussibling" }1610 },1611 prefilter: {1612 "attr": function( match ) {1613 match[1] = match[1].replace( runescape, funescape );1614 // move the given value to match[3] whether quoted or unquoted1615 match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape );1616 if ( match[2] === "~=" ) {1617 match[3] = " " + match[3] + " ";1618 }1619 return match.slice( 0, 4 );1620 },1621 "child": function( match ) {1622 /* matches from matchexpr["child"]1623 1 type (only|nth|...)1624 2 what (child|of-type)1625 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)1626 4 xn-component of xn+y argument ([+-]?\d*n|)1627 5 sign of xn-component1628 6 x of xn-component1629 7 sign of y-component1630 8 y of y-component1631 */1632 match[1] = match[1].tolowercase();1633 if ( match[1].slice( 0, 3 ) === "nth" ) {1634 // nth-* requires argument1635 if ( !match[3] ) {1636 sizzle.error( match[0] );1637 }1638 // numeric x and y parameters for expr.filter.child1639 // remember that false/true cast respectively to 0/11640 match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );1641 match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );1642 // other types prohibit arguments1643 } else if ( match[3] ) {1644 sizzle.error( match[0] );1645 }1646 return match;1647 },1648 "pseudo": function( match ) {1649 var excess,1650 unquoted = !match[5] && match[2];1651 if ( matchexpr["child"].test( match[0] ) ) {1652 return null;1653 }1654 // accept quoted arguments as-is1655 if ( match[3] && match[4] !== undefined ) {1656 match[2] = match[4];1657 // strip excess characters from unquoted arguments1658 } else if ( unquoted && rpseudo.test( unquoted ) &&1659 // get excess from tokenize (recursively)1660 (excess = tokenize( unquoted, true )) &&1661 // advance to the next closing parenthesis1662 (excess = unquoted.indexof( ")", unquoted.length - excess ) - unquoted.length) ) {1663 // excess is a negative index1664 match[0] = match[0].slice( 0, excess );1665 match[2] = unquoted.slice( 0, excess );1666 }1667 // return only captures needed by the pseudo filter method (type and argument)1668 return match.slice( 0, 3 );1669 }1670 },1671 filter: {1672 "tag": function( nodenameselector ) {1673 var nodename = nodenameselector.replace( runescape, funescape ).tolowercase();1674 return nodenameselector === "*" ?1675 function() { return true; } :1676 function( elem ) {1677 return elem.nodename && elem.nodename.tolowercase() === nodename;1678 };1679 },1680 "class": function( classname ) {1681 var pattern = classcache[ classname + " " ];1682 return pattern ||1683 (pattern = new regexp( "(^|" + whitespace + ")" + classname + "(" + whitespace + "|$)" )) &&1684 classcache( classname, function( elem ) {1685 return pattern.test( typeof elem.classname === "string" && elem.classname || typeof elem.getattribute !== strundefined && elem.getattribute("class") || "" );1686 });1687 },1688 "attr": function( name, operator, check ) {1689 return function( elem ) {1690 var result = sizzle.attr( elem, name );1691 if ( result == null ) {1692 return operator === "!=";1693 }1694 if ( !operator ) {1695 return true;1696 }1697 result += "";1698 return operator === "=" ? result === check :1699 operator === "!=" ? result !== check :1700 operator === "^=" ? check && result.indexof( check ) === 0 :1701 operator === "*=" ? check && result.indexof( check ) > -1 :1702 operator === "$=" ? check && result.slice( -check.length ) === check :1703 operator === "~=" ? ( " " + result + " " ).indexof( check ) > -1 :1704 operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :1705 false;1706 };1707 },1708 "child": function( type, what, argument, first, last ) {1709 var simple = type.slice( 0, 3 ) !== "nth",1710 forward = type.slice( -4 ) !== "last",1711 oftype = what === "of-type";1712 return first === 1 && last === 0 ?1713 // shortcut for :nth-*(n)1714 function( elem ) {1715 return !!elem.parentnode;1716 } :1717 function( elem, context, xml ) {1718 var cache, outercache, node, diff, nodeindex, start,1719 dir = simple !== forward ? "nextsibling" : "previoussibling",1720 parent = elem.parentnode,1721 name = oftype && elem.nodename.tolowercase(),1722 usecache = !xml && !oftype;1723 if ( parent ) {1724 // :(first|last|only)-(child|of-type)1725 if ( simple ) {1726 while ( dir ) {1727 node = elem;1728 while ( (node = node[ dir ]) ) {1729 if ( oftype ? node.nodename.tolowercase() === name : node.nodetype === 1 ) {1730 return false;1731 }1732 }1733 // reverse direction for :only-* (if we haven't yet done so)1734 start = dir = type === "only" && !start && "nextsibling";1735 }1736 return true;1737 }1738 start = [ forward ? parent.firstchild : parent.lastchild ];1739 // non-xml :nth-child(...) stores cache data on `parent`1740 if ( forward && usecache ) {1741 // seek `elem` from a previously-cached index1742 outercache = parent[ expando ] || (parent[ expando ] = {});1743 cache = outercache[ type ] || [];1744 nodeindex = cache[0] === dirruns && cache[1];1745 diff = cache[0] === dirruns && cache[2];1746 node = nodeindex && parent.childnodes[ nodeindex ];1747 while ( (node = ++nodeindex && node && node[ dir ] ||1748 // fallback to seeking `elem` from the start1749 (diff = nodeindex = 0) || start.pop()) ) {1750 // when found, cache indexes on `parent` and break1751 if ( node.nodetype === 1 && ++diff && node === elem ) {1752 outercache[ type ] = [ dirruns, nodeindex, diff ];1753 break;1754 }1755 }1756 // use previously-cached element index if available1757 } else if ( usecache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {1758 diff = cache[1];1759 // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)1760 } else {1761 // use the same loop as above to seek `elem` from the start1762 while ( (node = ++nodeindex && node && node[ dir ] ||1763 (diff = nodeindex = 0) || start.pop()) ) {1764 if ( ( oftype ? node.nodename.tolowercase() === name : node.nodetype === 1 ) && ++diff ) {1765 // cache the index of each encountered element1766 if ( usecache ) {1767 (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];1768 }1769 if ( node === elem ) {1770 break;1771 }1772 }1773 }1774 }1775 // incorporate the offset, then check against cycle size1776 diff -= last;1777 return diff === first || ( diff % first === 0 && diff / first >= 0 );1778 }1779 };1780 },1781 "pseudo": function( pseudo, argument ) {1782 // pseudo-class names are case-insensitive1783 // http://www.w3.org/tr/selectors/#pseudo-classes1784 // prioritize by case sensitivity in case custom pseudos are added with uppercase letters1785 // remember that setfilters inherits from pseudos1786 var args,1787 fn = expr.pseudos[ pseudo ] || expr.setfilters[ pseudo.tolowercase() ] ||1788 sizzle.error( "unsupported pseudo: " + pseudo );1789 // the user may use createpseudo to indicate that1790 // arguments are needed to create the filter function1791 // just as sizzle does1792 if ( fn[ expando ] ) {1793 return fn( argument );1794 }1795 // but maintain support for old signatures1796 if ( fn.length > 1 ) {1797 args = [ pseudo, pseudo, "", argument ];1798 return expr.setfilters.hasownproperty( pseudo.tolowercase() ) ?1799 markfunction(function( seed, matches ) {1800 var idx,1801 matched = fn( seed, argument ),1802 i = matched.length;1803 while ( i-- ) {1804 idx = indexof.call( seed, matched[i] );1805 seed[ idx ] = !( matches[ idx ] = matched[i] );1806 }1807 }) :1808 function( elem ) {1809 return fn( elem, 0, args );1810 };1811 }1812 return fn;1813 }1814 },1815 pseudos: {1816 // potentially complex pseudos1817 "not": markfunction(function( selector ) {1818 // trim the selector passed to compile1819 // to avoid treating leading and trailing1820 // spaces as combinators1821 var input = [],1822 results = [],1823 matcher = compile( selector.replace( rtrim, "$1" ) );1824 return matcher[ expando ] ?1825 markfunction(function( seed, matches, context, xml ) {1826 var elem,1827 unmatched = matcher( seed, null, xml, [] ),1828 i = seed.length;1829 // match elements unmatched by `matcher`1830 while ( i-- ) {1831 if ( (elem = unmatched[i]) ) {1832 seed[i] = !(matches[i] = elem);1833 }1834 }1835 }) :1836 function( elem, context, xml ) {1837 input[0] = elem;1838 matcher( input, null, xml, results );1839 return !results.pop();1840 };1841 }),1842 "has": markfunction(function( selector ) {1843 return function( elem ) {1844 return sizzle( selector, elem ).length > 0;1845 };1846 }),1847 "contains": markfunction(function( text ) {1848 return function( elem ) {1849 return ( elem.textcontent || elem.innertext || gettext( elem ) ).indexof( text ) > -1;1850 };1851 }),1852 // "whether an element is represented by a :lang() selector1853 // is based solely on the element's language value1854 // being equal to the identifier c,1855 // or beginning with the identifier c immediately followed by "-".1856 // the matching of c against the element's language value is performed case-insensitively.1857 // the identifier c does not have to be a valid language name."1858 // http://www.w3.org/tr/selectors/#lang-pseudo1859 "lang": markfunction( function( lang ) {1860 // lang value must be a valid identifier1861 if ( !ridentifier.test(lang || "") ) {1862 sizzle.error( "unsupported lang: " + lang );1863 }1864 lang = lang.replace( runescape, funescape ).tolowercase();1865 return function( elem ) {1866 var elemlang;1867 do {1868 if ( (elemlang = documentishtml ?1869 elem.lang :1870 elem.getattribute("xml:lang") || elem.getattribute("lang")) ) {1871 elemlang = elemlang.tolowercase();1872 return elemlang === lang || elemlang.indexof( lang + "-" ) === 0;1873 }1874 } while ( (elem = elem.parentnode) && elem.nodetype === 1 );1875 return false;1876 };1877 }),1878 // miscellaneous1879 "target": function( elem ) {1880 var hash = window.location && window.location.hash;1881 return hash && hash.slice( 1 ) === elem.id;1882 },1883 "root": function( elem ) {1884 return elem === docelem;1885 },1886 "focus": function( elem ) {1887 return elem === document.activeelement && (!document.hasfocus || document.hasfocus()) && !!(elem.type || elem.href || ~elem.tabindex);1888 },1889 // boolean properties1890 "enabled": function( elem ) {1891 return elem.disabled === false;1892 },1893 "disabled": function( elem ) {1894 return elem.disabled === true;1895 },1896 "checked": function( elem ) {1897 // in css3, :checked should return both checked and selected elements1898 // http://www.w3.org/tr/2011/rec-css3-selectors-20110929/#checked1899 var nodename = elem.nodename.tolowercase();1900 return (nodename === "input" && !!elem.checked) || (nodename === "option" && !!elem.selected);1901 },1902 "selected": function( elem ) {1903 // accessing this property makes selected-by-default1904 // options in safari work properly1905 if ( elem.parentnode ) {1906 elem.parentnode.selectedindex;1907 }1908 return elem.selected === true;1909 },1910 // contents1911 "empty": function( elem ) {1912 // http://www.w3.org/tr/selectors/#empty-pseudo1913 // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),1914 // not comment, processing instructions, or others1915 // thanks to diego perini for the nodename shortcut1916 // greater than "@" means alpha characters (specifically not starting with "#" or "?")1917 for ( elem = elem.firstchild; elem; elem = elem.nextsibling ) {1918 if ( elem.nodename > "@" || elem.nodetype === 3 || elem.nodetype === 4 ) {1919 return false;1920 }1921 }1922 return true;1923 },1924 "parent": function( elem ) {1925 return !expr.pseudos["empty"]( elem );1926 },1927 // element/input types1928 "header": function( elem ) {1929 return rheader.test( elem.nodename );1930 },1931 "input": function( elem ) {1932 return rinputs.test( elem.nodename );1933 },1934 "button": function( elem ) {1935 var name = elem.nodename.tolowercase();1936 return name === "input" && elem.type === "button" || name === "button";1937 },1938 "text": function( elem ) {1939 var attr;1940 // ie6 and 7 will map elem.type to 'text' for new html5 types (search, etc)1941 // use getattribute instead to test this case1942 return elem.nodename.tolowercase() === "input" &&1943 elem.type === "text" &&1944 ( (attr = elem.getattribute("type")) == null || attr.tolowercase() === elem.type );1945 },1946 // position-in-collection1947 "first": createpositionalpseudo(function() {1948 return [ 0 ];1949 }),1950 "last": createpositionalpseudo(function( matchindexes, length ) {1951 return [ length - 1 ];1952 }),1953 "eq": createpositionalpseudo(function( matchindexes, length, argument ) {1954 return [ argument < 0 ? argument + length : argument ];1955 }),1956 "even": createpositionalpseudo(function( matchindexes, length ) {1957 var i = 0;1958 for ( ; i < length; i += 2 ) {1959 matchindexes.push( i );1960 }1961 return matchindexes;1962 }),1963 "odd": createpositionalpseudo(function( matchindexes, length ) {1964 var i = 1;1965 for ( ; i < length; i += 2 ) {1966 matchindexes.push( i );1967 }1968 return matchindexes;1969 }),1970 "lt": createpositionalpseudo(function( matchindexes, length, argument ) {1971 var i = argument < 0 ? argument + length : argument;1972 for ( ; --i >= 0; ) {1973 matchindexes.push( i );1974 }1975 return matchindexes;1976 }),1977 "gt": createpositionalpseudo(function( matchindexes, length, argument ) {1978 var i = argument < 0 ? argument + length : argument;1979 for ( ; ++i < length; ) {1980 matchindexes.push( i );1981 }1982 return matchindexes;1983 })1984 }1985 };1986 expr.pseudos["nth"] = expr.pseudos["eq"];1987// add button/input type pseudos1988 for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {1989 expr.pseudos[ i ] = createinputpseudo( i );1990 }1991 for ( i in { submit: true, reset: true } ) {1992 expr.pseudos[ i ] = createbuttonpseudo( i );1993 }1994// easy api for creating new setfilters1995 function setfilters() {}1996 setfilters.prototype = expr.filters = expr.pseudos;1997 expr.setfilters = new setfilters();1998 function tokenize( selector, parseonly ) {1999 var matched, match, tokens, type,2000 sofar, groups, prefilters,2001 cached = tokencache[ selector + " " ];2002 if ( cached ) {2003 return parseonly ? 0 : cached.slice( 0 );2004 }2005 sofar = selector;2006 groups = [];2007 prefilters = expr.prefilter;2008 while ( sofar ) {2009 // comma and first run2010 if ( !matched || (match = rcomma.exec( sofar )) ) {2011 if ( match ) {2012 // don't consume trailing commas as valid2013 sofar = sofar.slice( match[0].length ) || sofar;2014 }2015 groups.push( tokens = [] );2016 }2017 matched = false;2018 // combinators2019 if ( (match = rcombinators.exec( sofar )) ) {2020 matched = match.shift();2021 tokens.push({2022 value: matched,2023 // cast descendant combinators to space2024 type: match[0].replace( rtrim, " " )2025 });2026 sofar = sofar.slice( matched.length );2027 }2028 // filters2029 for ( type in expr.filter ) {2030 if ( (match = matchexpr[ type ].exec( sofar )) && (!prefilters[ type ] ||2031 (match = prefilters[ type ]( match ))) ) {2032 matched = match.shift();2033 tokens.push({2034 value: matched,2035 type: type,2036 matches: match2037 });2038 sofar = sofar.slice( matched.length );2039 }2040 }2041 if ( !matched ) {2042 break;2043 }2044 }2045 // return the length of the invalid excess2046 // if we're just parsing2047 // otherwise, throw an error or return tokens2048 return parseonly ?2049 sofar.length :2050 sofar ?2051 sizzle.error( selector ) :2052 // cache the tokens2053 tokencache( selector, groups ).slice( 0 );2054 }2055 function toselector( tokens ) {2056 var i = 0,2057 len = tokens.length,2058 selector = "";2059 for ( ; i < len; i++ ) {2060 selector += tokens[i].value;2061 }2062 return selector;2063 }2064 function addcombinator( matcher, combinator, base ) {2065 var dir = combinator.dir,2066 checknonelements = base && dir === "parentnode",2067 donename = done++;2068 return combinator.first ?2069 // check against closest ancestor/preceding element2070 function( elem, context, xml ) {2071 while ( (elem = elem[ dir ]) ) {2072 if ( elem.nodetype === 1 || checknonelements ) {2073 return matcher( elem, context, xml );2074 }2075 }2076 } :2077 // check against all ancestor/preceding elements2078 function( elem, context, xml ) {2079 var data, cache, outercache,2080 dirkey = dirruns + " " + donename;2081 // we can't set arbitrary data on xml nodes, so they don't benefit from dir caching2082 if ( xml ) {2083 while ( (elem = elem[ dir ]) ) {2084 if ( elem.nodetype === 1 || checknonelements ) {2085 if ( matcher( elem, context, xml ) ) {2086 return true;2087 }2088 }2089 }2090 } else {2091 while ( (elem = elem[ dir ]) ) {2092 if ( elem.nodetype === 1 || checknonelements ) {2093 outercache = elem[ expando ] || (elem[ expando ] = {});2094 if ( (cache = outercache[ dir ]) && cache[0] === dirkey ) {2095 if ( (data = cache[1]) === true || data === cachedruns ) {2096 return data === true;2097 }2098 } else {2099 cache = outercache[ dir ] = [ dirkey ];2100 cache[1] = matcher( elem, context, xml ) || cachedruns;2101 if ( cache[1] === true ) {2102 return true;2103 }2104 }2105 }2106 }2107 }2108 };2109 }2110 function elementmatcher( matchers ) {2111 return matchers.length > 1 ?2112 function( elem, context, xml ) {2113 var i = matchers.length;2114 while ( i-- ) {2115 if ( !matchers[i]( elem, context, xml ) ) {2116 return false;2117 }2118 }2119 return true;2120 } :2121 matchers[0];2122 }2123 function condense( unmatched, map, filter, context, xml ) {2124 var elem,2125 newunmatched = [],2126 i = 0,2127 len = unmatched.length,2128 mapped = map != null;2129 for ( ; i < len; i++ ) {2130 if ( (elem = unmatched[i]) ) {2131 if ( !filter || filter( elem, context, xml ) ) {2132 newunmatched.push( elem );2133 if ( mapped ) {2134 map.push( i );2135 }2136 }2137 }2138 }2139 return newunmatched;2140 }2141 function setmatcher( prefilter, selector, matcher, postfilter, postfinder, postselector ) {2142 if ( postfilter && !postfilter[ expando ] ) {2143 postfilter = setmatcher( postfilter );2144 }2145 if ( postfinder && !postfinder[ expando ] ) {2146 postfinder = setmatcher( postfinder, postselector );2147 }2148 return markfunction(function( seed, results, context, xml ) {2149 var temp, i, elem,2150 premap = [],2151 postmap = [],2152 preexisting = results.length,2153 // get initial elements from seed or context2154 elems = seed || multiplecontexts( selector || "*", context.nodetype ? [ context ] : context, [] ),2155 // prefilter to get matcher input, preserving a map for seed-results synchronization2156 matcherin = prefilter && ( seed || !selector ) ?2157 condense( elems, premap, prefilter, context, xml ) :2158 elems,2159 matcherout = matcher ?2160 // if we have a postfinder, or filtered seed, or non-seed postfilter or preexisting results,2161 postfinder || ( seed ? prefilter : preexisting || postfilter ) ?2162 // ...intermediate processing is necessary2163 [] :2164 // ...otherwise use results directly2165 results :2166 matcherin;2167 // find primary matches2168 if ( matcher ) {2169 matcher( matcherin, matcherout, context, xml );2170 }2171 // apply postfilter2172 if ( postfilter ) {2173 temp = condense( matcherout, postmap );2174 postfilter( temp, [], context, xml );2175 // un-match failing elements by moving them back to matcherin2176 i = temp.length;2177 while ( i-- ) {2178 if ( (elem = temp[i]) ) {2179 matcherout[ postmap[i] ] = !(matcherin[ postmap[i] ] = elem);2180 }2181 }2182 }2183 if ( seed ) {2184 if ( postfinder || prefilter ) {2185 if ( postfinder ) {2186 // get the final matcherout by condensing this intermediate into postfinder contexts2187 temp = [];2188 i = matcherout.length;2189 while ( i-- ) {2190 if ( (elem = matcherout[i]) ) {2191 // restore matcherin since elem is not yet a final match2192 temp.push( (matcherin[i] = elem) );2193 }2194 }2195 postfinder( null, (matcherout = []), temp, xml );2196 }2197 // move matched elements from seed to results to keep them synchronized2198 i = matcherout.length;2199 while ( i-- ) {2200 if ( (elem = matcherout[i]) &&2201 (temp = postfinder ? indexof.call( seed, elem ) : premap[i]) > -1 ) {2202 seed[temp] = !(results[temp] = elem);2203 }2204 }2205 }2206 // add elements to results, through postfinder if defined2207 } else {2208 matcherout = condense(2209 matcherout === results ?2210 matcherout.splice( preexisting, matcherout.length ) :2211 matcherout2212 );2213 if ( postfinder ) {2214 postfinder( null, results, matcherout, xml );2215 } else {2216 push.apply( results, matcherout );2217 }2218 }2219 });2220 }2221 function matcherfromtokens( tokens ) {2222 var checkcontext, matcher, j,2223 len = tokens.length,2224 leadingrelative = expr.relative[ tokens[0].type ],2225 implicitrelative = leadingrelative || expr.relative[" "],2226 i = leadingrelative ? 1 : 0,2227 // the foundational matcher ensures that elements are reachable from top-level context(s)2228 matchcontext = addcombinator( function( elem ) {2229 return elem === checkcontext;2230 }, implicitrelative, true ),2231 matchanycontext = addcombinator( function( elem ) {2232 return indexof.call( checkcontext, elem ) > -1;2233 }, implicitrelative, true ),2234 matchers = [ function( elem, context, xml ) {2235 return ( !leadingrelative && ( xml || context !== outermostcontext ) ) || (2236 (checkcontext = context).nodetype ?2237 matchcontext( elem, context, xml ) :2238 matchanycontext( elem, context, xml ) );2239 } ];2240 for ( ; i < len; i++ ) {2241 if ( (matcher = expr.relative[ tokens[i].type ]) ) {2242 matchers = [ addcombinator(elementmatcher( matchers ), matcher) ];2243 } else {2244 matcher = expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );2245 // return special upon seeing a positional matcher2246 if ( matcher[ expando ] ) {2247 // find the next relative operator (if any) for proper handling2248 j = ++i;2249 for ( ; j < len; j++ ) {2250 if ( expr.relative[ tokens[j].type ] ) {2251 break;2252 }2253 }2254 return setmatcher(2255 i > 1 && elementmatcher( matchers ),2256 i > 1 && toselector(2257 // if the preceding token was a descendant combinator, insert an implicit any-element `*`2258 tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })2259 ).replace( rtrim, "$1" ),2260 matcher,2261 i < j && matcherfromtokens( tokens.slice( i, j ) ),2262 j < len && matcherfromtokens( (tokens = tokens.slice( j )) ),2263 j < len && toselector( tokens )2264 );2265 }2266 matchers.push( matcher );2267 }2268 }2269 return elementmatcher( matchers );2270 }2271 function matcherfromgroupmatchers( elementmatchers, setmatchers ) {2272 // a counter to specify which element is currently being matched2273 var matchercachedruns = 0,2274 byset = setmatchers.length > 0,2275 byelement = elementmatchers.length > 0,2276 supermatcher = function( seed, context, xml, results, expandcontext ) {2277 var elem, j, matcher,2278 setmatched = [],2279 matchedcount = 0,2280 i = "0",2281 unmatched = seed && [],2282 outermost = expandcontext != null,2283 contextbackup = outermostcontext,2284 // we must always have either seed elements or context2285 elems = seed || byelement && expr.find["tag"]( "*", expandcontext && context.parentnode || context ),2286 // use integer dirruns iff this is the outermost matcher2287 dirrunsunique = (dirruns += contextbackup == null ? 1 : math.random() || 0.1);2288 if ( outermost ) {2289 outermostcontext = context !== document && context;2290 cachedruns = matchercachedruns;2291 }2292 // add elements passing elementmatchers directly to results2293 // keep `i` a string if there are no elements so `matchedcount` will be "00" below2294 for ( ; (elem = elems[i]) != null; i++ ) {2295 if ( byelement && elem ) {2296 j = 0;2297 while ( (matcher = elementmatchers[j++]) ) {2298 if ( matcher( elem, context, xml ) ) {2299 results.push( elem );2300 break;2301 }2302 }2303 if ( outermost ) {2304 dirruns = dirrunsunique;2305 cachedruns = ++matchercachedruns;2306 }2307 }2308 // track unmatched elements for set filters2309 if ( byset ) {2310 // they will have gone through all possible matchers2311 if ( (elem = !matcher && elem) ) {2312 matchedcount--;2313 }2314 // lengthen the array for every element, matched or not2315 if ( seed ) {2316 unmatched.push( elem );2317 }2318 }2319 }2320 // apply set filters to unmatched elements2321 matchedcount += i;2322 if ( byset && i !== matchedcount ) {2323 j = 0;2324 while ( (matcher = setmatchers[j++]) ) {2325 matcher( unmatched, setmatched, context, xml );2326 }2327 if ( seed ) {2328 // reintegrate element matches to eliminate the need for sorting2329 if ( matchedcount > 0 ) {2330 while ( i-- ) {2331 if ( !(unmatched[i] || setmatched[i]) ) {2332 setmatched[i] = pop.call( results );2333 }2334 }2335 }2336 // discard index placeholder values to get only actual matches2337 setmatched = condense( setmatched );2338 }2339 // add matches to results2340 push.apply( results, setmatched );2341 // seedless set matches succeeding multiple successful matchers stipulate sorting2342 if ( outermost && !seed && setmatched.length > 0 &&2343 ( matchedcount + setmatchers.length ) > 1 ) {2344 sizzle.uniquesort( results );2345 }2346 }2347 // override manipulation of globals by nested matchers2348 if ( outermost ) {2349 dirruns = dirrunsunique;2350 outermostcontext = contextbackup;2351 }2352 return unmatched;2353 };2354 return byset ?2355 markfunction( supermatcher ) :2356 supermatcher;2357 }2358 compile = sizzle.compile = function( selector, group /* internal use only */ ) {2359 var i,2360 setmatchers = [],2361 elementmatchers = [],2362 cached = compilercache[ selector + " " ];2363 if ( !cached ) {2364 // generate a function of recursive functions that can be used to check each element2365 if ( !group ) {2366 group = tokenize( selector );2367 }2368 i = group.length;2369 while ( i-- ) {2370 cached = matcherfromtokens( group[i] );2371 if ( cached[ expando ] ) {2372 setmatchers.push( cached );2373 } else {2374 elementmatchers.push( cached );2375 }2376 }2377 // cache the compiled function2378 cached = compilercache( selector, matcherfromgroupmatchers( elementmatchers, setmatchers ) );2379 }2380 return cached;2381 };2382 function multiplecontexts( selector, contexts, results ) {2383 var i = 0,2384 len = contexts.length;2385 for ( ; i < len; i++ ) {2386 sizzle( selector, contexts[i], results );2387 }2388 return results;2389 }2390 function select( selector, context, results, seed ) {2391 var i, tokens, token, type, find,2392 match = tokenize( selector );2393 if ( !seed ) {2394 // try to minimize operations if there is only one group2395 if ( match.length === 1 ) {2396 // take a shortcut and set the context if the root selector is an id2397 tokens = match[0] = match[0].slice( 0 );2398 if ( tokens.length > 2 && (token = tokens[0]).type === "id" &&2399 support.getbyid && context.nodetype === 9 && documentishtml &&2400 expr.relative[ tokens[1].type ] ) {2401 context = ( expr.find["id"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];2402 if ( !context ) {2403 return results;2404 }2405 selector = selector.slice( tokens.shift().value.length );2406 }2407 // fetch a seed set for right-to-left matching2408 i = matchexpr["needscontext"].test( selector ) ? 0 : tokens.length;2409 while ( i-- ) {2410 token = tokens[i];2411 // abort if we hit a combinator2412 if ( expr.relative[ (type = token.type) ] ) {2413 break;2414 }2415 if ( (find = expr.find[ type ]) ) {2416 // search, expanding context for leading sibling combinators2417 if ( (seed = find(2418 token.matches[0].replace( runescape, funescape ),2419 rsibling.test( tokens[0].type ) && context.parentnode || context2420 )) ) {2421 // if seed is empty or no tokens remain, we can return early2422 tokens.splice( i, 1 );2423 selector = seed.length && toselector( tokens );2424 if ( !selector ) {2425 push.apply( results, seed );2426 return results;2427 }2428 break;2429 }2430 }2431 }2432 }2433 }2434 // compile and execute a filtering function2435 // provide `match` to avoid retokenization if we modified the selector above2436 compile( selector, match )(2437 seed,2438 context,2439 !documentishtml,2440 results,2441 rsibling.test( selector )2442 );2443 return results;2444 }2445// one-time assignments2446// sort stability2447 support.sortstable = expando.split("").sort( sortorder ).join("") === expando;2448// support: chrome<142449// always assume duplicates if they aren't passed to the comparison function2450 support.detectduplicates = hasduplicate;2451// initialize against the default document2452 setdocument();2453// support: webkit<537.32 - safari 6.0.3/chrome 25 (fixed in chrome 27)2454// detached nodes confoundingly follow *each other*2455 support.sortdetached = assert(function( div1 ) {2456 // should return 1, but returns 4 (following)2457 return div1.comparedocumentposition( document.createelement("div") ) & 1;2458 });2459// support: ie<82460// prevent attribute/property "interpolation"2461// http://msdn.microsoft.com/en-us/library/ms536429%28vs.85%29.aspx2462 if ( !assert(function( div ) {2463 div.innerhtml = "<a href='#'></a>";2464 return div.firstchild.getattribute("href") === "#" ;2465 }) ) {2466 addhandle( "type|href|height|width", function( elem, name, isxml ) {2467 if ( !isxml ) {2468 return elem.getattribute( name, name.tolowercase() === "type" ? 1 : 2 );2469 }2470 });2471 }2472// support: ie<92473// use defaultvalue in place of getattribute("value")2474 if ( !support.attributes || !assert(function( div ) {2475 div.innerhtml = "<input/>";2476 div.firstchild.setattribute( "value", "" );2477 return div.firstchild.getattribute( "value" ) === "";2478 }) ) {2479 addhandle( "value", function( elem, name, isxml ) {2480 if ( !isxml && elem.nodename.tolowercase() === "input" ) {2481 return elem.defaultvalue;2482 }2483 });2484 }2485// support: ie<92486// use getattributenode to fetch booleans when getattribute lies2487 if ( !assert(function( div ) {2488 return div.getattribute("disabled") == null;2489 }) ) {2490 addhandle( booleans, function( elem, name, isxml ) {2491 var val;2492 if ( !isxml ) {2493 return (val = elem.getattributenode( name )) && val.specified ?2494 val.value :2495 elem[ name ] === true ? name.tolowercase() : null;2496 }2497 });2498 }2499 jquery.find = sizzle;2500 jquery.expr = sizzle.selectors;2501 jquery.expr[":"] = jquery.expr.pseudos;2502 jquery.unique = sizzle.uniquesort;2503 jquery.text = sizzle.gettext;2504 jquery.isxmldoc = sizzle.isxml;2505 jquery.contains = sizzle.contains;2506 })( window );2507// string to object options format cache2508 var optionscache = {};2509// convert string-formatted options into object-formatted ones and store in cache2510 function createoptions( options ) {2511 var object = optionscache[ options ] = {};2512 jquery.each( options.match( core_rnotwhite ) || [], function( _, flag ) {2513 object[ flag ] = true;2514 });2515 return object;2516 }2517 /*2518 * create a callback list using the following parameters:2519 *2520 * options: an optional list of space-separated options that will change how2521 * the callback list behaves or a more traditional option object2522 *2523 * by default a callback list will act like an event callback list and can be2524 * "fired" multiple times.2525 *2526 * possible options:2527 *2528 * once: will ensure the callback list can only be fired once (like a deferred)2529 *2530 * memory: will keep track of previous values and will call any callback added2531 * after the list has been fired right away with the latest "memorized"2532 * values (like a deferred)2533 *2534 * unique: will ensure a callback can only be added once (no duplicate in the list)2535 *2536 * stoponfalse: interrupt callings when a callback returns false2537 *2538 */2539 jquery.callbacks = function( options ) {2540 // convert options from string-formatted to object-formatted if needed2541 // (we check in cache first)2542 options = typeof options === "string" ?2543 ( optionscache[ options ] || createoptions( options ) ) :2544 jquery.extend( {}, options );2545 var // flag to know if list is currently firing2546 firing,2547 // last fire value (for non-forgettable lists)2548 memory,2549 // flag to know if list was already fired2550 fired,2551 // end of the loop when firing2552 firinglength,2553 // index of currently firing callback (modified by remove if needed)2554 firingindex,2555 // first callback to fire (used internally by add and firewith)2556 firingstart,2557 // actual callback list2558 list = [],2559 // stack of fire calls for repeatable lists2560 stack = !options.once && [],2561 // fire callbacks2562 fire = function( data ) {2563 memory = options.memory && data;2564 fired = true;2565 firingindex = firingstart || 0;2566 firingstart = 0;2567 firinglength = list.length;2568 firing = true;2569 for ( ; list && firingindex < firinglength; firingindex++ ) {2570 if ( list[ firingindex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stoponfalse ) {2571 memory = false; // to prevent further calls using add2572 break;2573 }2574 }2575 firing = false;2576 if ( list ) {2577 if ( stack ) {2578 if ( stack.length ) {2579 fire( stack.shift() );2580 }2581 } else if ( memory ) {2582 list = [];2583 } else {2584 self.disable();2585 }2586 }2587 },2588 // actual callbacks object2589 self = {2590 // add a callback or a collection of callbacks to the list2591 add: function() {2592 if ( list ) {2593 // first, we save the current length2594 var start = list.length;2595 (function add( args ) {2596 jquery.each( args, function( _, arg ) {2597 var type = jquery.type( arg );2598 if ( type === "function" ) {2599 if ( !options.unique || !self.has( arg ) ) {2600 list.push( arg );2601 }2602 } else if ( arg && arg.length && type !== "string" ) {2603 // inspect recursively2604 add( arg );2605 }2606 });2607 })( arguments );2608 // do we need to add the callbacks to the2609 // current firing batch?2610 if ( firing ) {2611 firinglength = list.length;2612 // with memory, if we're not firing then2613 // we should call right away2614 } else if ( memory ) {2615 firingstart = start;2616 fire( memory );2617 }2618 }2619 return this;2620 },2621 // remove a callback from the list2622 remove: function() {2623 if ( list ) {2624 jquery.each( arguments, function( _, arg ) {2625 var index;2626 while( ( index = jquery.inarray( arg, list, index ) ) > -1 ) {2627 list.splice( index, 1 );2628 // handle firing indexes2629 if ( firing ) {2630 if ( index <= firinglength ) {2631 firinglength--;2632 }2633 if ( index <= firingindex ) {2634 firingindex--;2635 }2636 }2637 }2638 });2639 }2640 return this;2641 },2642 // check if a given callback is in the list.2643 // if no argument is given, return whether or not list has callbacks attached.2644 has: function( fn ) {2645 return fn ? jquery.inarray( fn, list ) > -1 : !!( list && list.length );2646 },2647 // remove all callbacks from the list2648 empty: function() {2649 list = [];2650 firinglength = 0;2651 return this;2652 },2653 // have the list do nothing anymore2654 disable: function() {2655 list = stack = memory = undefined;2656 return this;2657 },2658 // is it disabled?2659 disabled: function() {2660 return !list;2661 },2662 // lock the list in its current state2663 lock: function() {2664 stack = undefined;2665 if ( !memory ) {2666 self.disable();2667 }2668 return this;2669 },2670 // is it locked?2671 locked: function() {2672 return !stack;2673 },2674 // call all callbacks with the given context and arguments2675 firewith: function( context, args ) {2676 if ( list && ( !fired || stack ) ) {2677 args = args || [];2678 args = [ context, args.slice ? args.slice() : args ];2679 if ( firing ) {2680 stack.push( args );2681 } else {2682 fire( args );2683 }2684 }2685 return this;2686 },2687 // call all the callbacks with the given arguments2688 fire: function() {2689 self.firewith( this, arguments );2690 return this;2691 },2692 // to know if the callbacks have already been called at least once2693 fired: function() {2694 return !!fired;2695 }2696 };2697 return self;2698 };2699 jquery.extend({2700 deferred: function( func ) {2701 var tuples = [2702 // action, add listener, listener list, final state2703 [ "resolve", "done", jquery.callbacks("once memory"), "resolved" ],2704 [ "reject", "fail", jquery.callbacks("once memory"), "rejected" ],2705 [ "notify", "progress", jquery.callbacks("memory") ]2706 ],2707 state = "pending",2708 promise = {2709 state: function() {2710 return state;2711 },2712 always: function() {2713 deferred.done( arguments ).fail( arguments );2714 return this;2715 },2716 then: function( /* fndone, fnfail, fnprogress */ ) {2717 var fns = arguments;2718 return jquery.deferred(function( newdefer ) {2719 jquery.each( tuples, function( i, tuple ) {2720 var action = tuple[ 0 ],2721 fn = jquery.isfunction( fns[ i ] ) && fns[ i ];2722 // deferred[ done | fail | progress ] for forwarding actions to newdefer2723 deferred[ tuple[1] ](function() {2724 var returned = fn && fn.apply( this, arguments );2725 if ( returned && jquery.isfunction( returned.promise ) ) {2726 returned.promise()2727 .done( newdefer.resolve )2728 .fail( newdefer.reject )2729 .progress( newdefer.notify );2730 } else {2731 newdefer[ action + "with" ]( this === promise ? newdefer.promise() : this, fn ? [ returned ] : arguments );2732 }2733 });2734 });2735 fns = null;2736 }).promise();2737 },2738 // get a promise for this deferred2739 // if obj is provided, the promise aspect is added to the object2740 promise: function( obj ) {2741 return obj != null ? jquery.extend( obj, promise ) : promise;2742 }2743 },2744 deferred = {};2745 // keep pipe for back-compat2746 promise.pipe = promise.then;2747 // add list-specific methods2748 jquery.each( tuples, function( i, tuple ) {2749 var list = tuple[ 2 ],2750 statestring = tuple[ 3 ];2751 // promise[ done | fail | progress ] = list.add2752 promise[ tuple[1] ] = list.add;2753 // handle state2754 if ( statestring ) {2755 list.add(function() {2756 // state = [ resolved | rejected ]2757 state = statestring;2758 // [ reject_list | resolve_list ].disable; progress_list.lock2759 }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );2760 }2761 // deferred[ resolve | reject | notify ]2762 deferred[ tuple[0] ] = function() {2763 deferred[ tuple[0] + "with" ]( this === deferred ? promise : this, arguments );2764 return this;2765 };2766 deferred[ tuple[0] + "with" ] = list.firewith;2767 });2768 // make the deferred a promise2769 promise.promise( deferred );2770 // call given func if any2771 if ( func ) {2772 func.call( deferred, deferred );2773 }2774 // all done!2775 return deferred;2776 },2777 // deferred helper2778 when: function( subordinate /* , ..., subordinaten */ ) {2779 var i = 0,2780 resolvevalues = core_slice.call( arguments ),2781 length = resolvevalues.length,2782 // the count of uncompleted subordinates2783 remaining = length !== 1 || ( subordinate && jquery.isfunction( subordinate.promise ) ) ? length : 0,2784 // the master deferred. if resolvevalues consist of only a single deferred, just use that.2785 deferred = remaining === 1 ? subordinate : jquery.deferred(),2786 // update function for both resolve and progress values2787 updatefunc = function( i, contexts, values ) {2788 return function( value ) {2789 contexts[ i ] = this;2790 values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;2791 if( values === progressvalues ) {2792 deferred.notifywith( contexts, values );2793 } else if ( !( --remaining ) ) {2794 deferred.resolvewith( contexts, values );2795 }2796 };2797 },2798 progressvalues, progresscontexts, resolvecontexts;2799 // add listeners to deferred subordinates; treat others as resolved2800 if ( length > 1 ) {2801 progressvalues = new array( length );2802 progresscontexts = new array( length );2803 resolvecontexts = new array( length );2804 for ( ; i < length; i++ ) {2805 if ( resolvevalues[ i ] && jquery.isfunction( resolvevalues[ i ].promise ) ) {2806 resolvevalues[ i ].promise()2807 .done( updatefunc( i, resolvecontexts, resolvevalues ) )2808 .fail( deferred.reject )2809 .progress( updatefunc( i, progresscontexts, progressvalues ) );2810 } else {2811 --remaining;2812 }2813 }2814 }2815 // if we're not waiting on anything, resolve the master2816 if ( !remaining ) {2817 deferred.resolvewith( resolvecontexts, resolvevalues );2818 }2819 return deferred.promise();2820 }2821 });2822 jquery.support = (function( support ) {2823 var all, a, input, select, fragment, opt, eventname, issupported, i,2824 div = document.createelement("div");2825 // setup2826 div.setattribute( "classname", "t" );2827 div.innerhtml = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";2828 // finish early in limited (non-browser) environments2829 all = div.getelementsbytagname("*") || [];2830 a = div.getelementsbytagname("a")[ 0 ];2831 if ( !a || !a.style || !all.length ) {2832 return support;2833 }2834 // first batch of tests2835 select = document.createelement("select");2836 opt = select.appendchild( document.createelement("option") );2837 input = div.getelementsbytagname("input")[ 0 ];2838 a.style.csstext = "top:1px;float:left;opacity:.5";2839 // test setattribute on camelcase class. if it works, we need attrfixes when doing get/setattribute (ie6/7)2840 support.getsetattribute = div.classname !== "t";2841 // ie strips leading whitespace when .innerhtml is used2842 support.leadingwhitespace = div.firstchild.nodetype === 3;2843 // make sure that tbody elements aren't automatically inserted2844 // ie will insert them into empty tables2845 support.tbody = !div.getelementsbytagname("tbody").length;2846 // make sure that link elements get serialized correctly by innerhtml2847 // this requires a wrapper element in ie2848 support.htmlserialize = !!div.getelementsbytagname("link").length;2849 // get the style information from getattribute2850 // (ie uses .csstext instead)2851 support.style = /top/.test( a.getattribute("style") );2852 // make sure that urls aren't manipulated2853 // (ie normalizes it by default)2854 support.hrefnormalized = a.getattribute("href") === "/a";2855 // make sure that element opacity exists2856 // (ie uses filter instead)2857 // use a regex to work around a webkit issue. see #51452858 support.opacity = /^0.5/.test( a.style.opacity );2859 // verify style float existence2860 // (ie uses stylefloat instead of cssfloat)2861 support.cssfloat = !!a.style.cssfloat;2862 // check the default checkbox/radio value ("" on webkit; "on" elsewhere)2863 support.checkon = !!input.value;2864 // make sure that a selected-by-default option has a working selected property.2865 // (webkit defaults to false instead of true, ie too, if it's in an optgroup)2866 support.optselected = opt.selected;2867 // tests for enctype support on a form (#6743)2868 support.enctype = !!document.createelement("form").enctype;2869 // makes sure cloning an html5 element does not cause problems2870 // where outerhtml is undefined, this still works2871 support.html5clone = document.createelement("nav").clonenode( true ).outerhtml !== "<:nav></:nav>";2872 // will be defined later2873 support.inlineblockneedslayout = false;2874 support.shrinkwrapblocks = false;2875 support.pixelposition = false;2876 support.deleteexpando = true;2877 support.nocloneevent = true;2878 support.reliablemarginright = true;2879 support.boxsizingreliable = true;2880 // make sure checked status is properly cloned2881 input.checked = true;2882 support.noclonechecked = input.clonenode( true ).checked;2883 // make sure that the options inside disabled selects aren't marked as disabled2884 // (webkit marks them as disabled)2885 select.disabled = true;2886 support.optdisabled = !opt.disabled;2887 // support: ie<92888 try {2889 delete div.test;2890 } catch( e ) {2891 support.deleteexpando = false;2892 }2893 // check if we can trust getattribute("value")2894 input = document.createelement("input");2895 input.setattribute( "value", "" );2896 support.input = input.getattribute( "value" ) === "";2897 // check if an input maintains its value after becoming a radio2898 input.value = "t";2899 input.setattribute( "type", "radio" );2900 support.radiovalue = input.value === "t";2901 // #11217 - webkit loses check when the name is after the checked attribute2902 input.setattribute( "checked", "t" );2903 input.setattribute( "name", "t" );2904 fragment = document.createdocumentfragment();2905 fragment.appendchild( input );2906 // check if a disconnected checkbox will retain its checked2907 // value of true after appended to the dom (ie6/7)2908 support.appendchecked = input.checked;2909 // webkit doesn't clone checked state correctly in fragments2910 support.checkclone = fragment.clonenode( true ).clonenode( true ).lastchild.checked;2911 // support: ie<92912 // opera does not clone events (and typeof div.attachevent === undefined).2913 // ie9-10 clones events bound via attachevent, but they don't trigger with .click()2914 if ( div.attachevent ) {2915 div.attachevent( "onclick", function() {2916 support.nocloneevent = false;2917 });2918 div.clonenode( true ).click();2919 }2920 // support: ie<9 (lack submit/change bubble), firefox 17+ (lack focusin event)2921 // beware of csp restrictions (https://developer.mozilla.org/en/security/csp)2922 for ( i in { submit: true, change: true, focusin: true }) {2923 div.setattribute( eventname = "on" + i, "t" );2924 support[ i + "bubbles" ] = eventname in window || div.attributes[ eventname ].expando === false;2925 }2926 div.style.backgroundclip = "content-box";2927 div.clonenode( true ).style.backgroundclip = "";2928 support.clearclonestyle = div.style.backgroundclip === "content-box";2929 // support: ie<92930 // iteration over object's inherited properties before its own.2931 for ( i in jquery( support ) ) {2932 break;2933 }2934 support.ownlast = i !== "0";2935 // run tests that need a body at doc ready2936 jquery(function() {2937 var container, margindiv, tds,2938 divreset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",2939 body = document.getelementsbytagname("body")[0];2940 if ( !body ) {2941 // return for frameset docs that don't have a body2942 return;2943 }2944 container = document.createelement("div");2945 container.style.csstext = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px";2946 body.appendchild( container ).appendchild( div );2947 // support: ie82948 // check if table cells still have offsetwidth/height when they are set2949 // to display:none and there are still other visible table cells in a2950 // table row; if so, offsetwidth/height are not reliable for use when2951 // determining if an element has been hidden directly using2952 // display:none (it is still safe to use offsets if a parent element is2953 // hidden; don safety goggles and see bug #4512 for more information).2954 div.innerhtml = "<table><tr><td></td><td>t</td></tr></table>";2955 tds = div.getelementsbytagname("td");2956 tds[ 0 ].style.csstext = "padding:0;margin:0;border:0;display:none";2957 issupported = ( tds[ 0 ].offsetheight === 0 );2958 tds[ 0 ].style.display = "";2959 tds[ 1 ].style.display = "none";2960 // support: ie82961 // check if empty table cells still have offsetwidth/height2962 support.reliablehiddenoffsets = issupported && ( tds[ 0 ].offsetheight === 0 );2963 // check box-sizing and margin behavior.2964 div.innerhtml = "";2965 div.style.csstext = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;";2966 // workaround failing boxsizing test due to offsetwidth returning wrong value2967 // with some non-1 values of body zoom, ticket #135432968 jquery.swap( body, body.style.zoom != null ? { zoom: 1 } : {}, function() {2969 support.boxsizing = div.offsetwidth === 4;2970 });2971 // use window.getcomputedstyle because jsdom on node.js will break without it.2972 if ( window.getcomputedstyle ) {2973 support.pixelposition = ( window.getcomputedstyle( div, null ) || {} ).top !== "1%";2974 support.boxsizingreliable = ( window.getcomputedstyle( div, null ) || { width: "4px" } ).width === "4px";2975 // check if div with explicit width and no margin-right incorrectly2976 // gets computed margin-right based on width of container. (#3333)2977 // fails in webkit before feb 2011 nightlies2978 // webkit bug 13343 - getcomputedstyle returns wrong value for margin-right2979 margindiv = div.appendchild( document.createelement("div") );2980 margindiv.style.csstext = div.style.csstext = divreset;2981 margindiv.style.marginright = margindiv.style.width = "0";2982 div.style.width = "1px";2983 support.reliablemarginright =2984 !parsefloat( ( window.getcomputedstyle( margindiv, null ) || {} ).marginright );2985 }2986 if ( typeof div.style.zoom !== core_strundefined ) {2987 // support: ie<82988 // check if natively block-level elements act like inline-block2989 // elements when setting their display to 'inline' and giving2990 // them layout2991 div.innerhtml = "";2992 div.style.csstext = divreset + "width:1px;padding:1px;display:inline;zoom:1";2993 support.inlineblockneedslayout = ( div.offsetwidth === 3 );2994 // support: ie62995 // check if elements with layout shrink-wrap their children2996 div.style.display = "block";2997 div.innerhtml = "<div></div>";2998 div.firstchild.style.width = "5px";2999 support.shrinkwrapblocks = ( div.offsetwidth !== 3 );3000 if ( support.inlineblockneedslayout ) {3001 // prevent ie 6 from affecting layout for positioned elements #110483002 // prevent ie from shrinking the body in ie 7 mode #128693003 // support: ie<83004 body.style.zoom = 1;3005 }3006 }3007 body.removechild( container );3008 // null elements to avoid leaks in ie3009 container = div = tds = margindiv = null;3010 });3011 // null elements to avoid leaks in ie3012 all = select = fragment = opt = a = input = null;3013 return support;3014 })({});3015 var rbrace = /(?:\{[\s\s]*\}|\[[\s\s]*\])$/,3016 rmultidash = /([a-z])/g;3017 function internaldata( elem, name, data, pvt /* internal use only */ ){3018 if ( !jquery.acceptdata( elem ) ) {3019 return;3020 }3021 var ret, thiscache,3022 internalkey = jquery.expando,3023 // we have to handle dom nodes and js objects differently because ie6-73024 // can't gc object references properly across the dom-js boundary3025 isnode = elem.nodetype,3026 // only dom nodes need the global jquery cache; js object data is3027 // attached directly to the object so gc can occur automatically3028 cache = isnode ? jquery.cache : elem,3029 // only defining an id for js objects if its cache already exists allows3030 // the code to shortcut on the same path as a dom node with no cache3031 id = isnode ? elem[ internalkey ] : elem[ internalkey ] && internalkey;3032 // avoid doing any more work than we need to when trying to get data on an3033 // object that has no data at all3034 if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) {3035 return;3036 }3037 if ( !id ) {3038 // only dom nodes need a new unique id for each element since their data3039 // ends up in the global cache3040 if ( isnode ) {3041 id = elem[ internalkey ] = core_deletedids.pop() || jquery.guid++;3042 } else {3043 id = internalkey;3044 }3045 }3046 if ( !cache[ id ] ) {3047 // avoid exposing jquery metadata on plain js objects when the object3048 // is serialized using json.stringify3049 cache[ id ] = isnode ? {} : { tojson: jquery.noop };3050 }3051 // an object can be passed to jquery.data instead of a key/value pair; this gets3052 // shallow copied over onto the existing cache3053 if ( typeof name === "object" || typeof name === "function" ) {3054 if ( pvt ) {3055 cache[ id ] = jquery.extend( cache[ id ], name );3056 } else {3057 cache[ id ].data = jquery.extend( cache[ id ].data, name );3058 }3059 }3060 thiscache = cache[ id ];3061 // jquery data() is stored in a separate object inside the object's internal data3062 // cache in order to avoid key collisions between internal data and user-defined3063 // data.3064 if ( !pvt ) {3065 if ( !thiscache.data ) {3066 thiscache.data = {};3067 }3068 thiscache = thiscache.data;3069 }3070 if ( data !== undefined ) {3071 thiscache[ jquery.camelcase( name ) ] = data;3072 }3073 // check for both converted-to-camel and non-converted data property names3074 // if a data property was specified3075 if ( typeof name === "string" ) {3076 // first try to find as-is property data3077 ret = thiscache[ name ];3078 // test for null|undefined property data3079 if ( ret == null ) {3080 // try to find the camelcased property3081 ret = thiscache[ jquery.camelcase( name ) ];3082 }3083 } else {3084 ret = thiscache;3085 }3086 return ret;3087 }3088 function internalremovedata( elem, name, pvt ) {3089 if ( !jquery.acceptdata( elem ) ) {3090 return;3091 }3092 var thiscache, i,3093 isnode = elem.nodetype,3094 // see jquery.data for more information3095 cache = isnode ? jquery.cache : elem,3096 id = isnode ? elem[ jquery.expando ] : jquery.expando;3097 // if there is already no cache entry for this object, there is no3098 // purpose in continuing3099 if ( !cache[ id ] ) {3100 return;3101 }3102 if ( name ) {3103 thiscache = pvt ? cache[ id ] : cache[ id ].data;3104 if ( thiscache ) {3105 // support array or space separated string names for data keys3106 if ( !jquery.isarray( name ) ) {3107 // try the string as a key before any manipulation3108 if ( name in thiscache ) {3109 name = [ name ];3110 } else {3111 // split the camel cased version by spaces unless a key with the spaces exists3112 name = jquery.camelcase( name );3113 if ( name in thiscache ) {3114 name = [ name ];3115 } else {3116 name = name.split(" ");3117 }3118 }3119 } else {3120 // if "name" is an array of keys...3121 // when data is initially created, via ("key", "val") signature,3122 // keys will be converted to camelcase.3123 // since there is no way to tell _how_ a key was added, remove3124 // both plain key and camelcase key. #127863125 // this will only penalize the array argument path.3126 name = name.concat( jquery.map( name, jquery.camelcase ) );3127 }3128 i = name.length;3129 while ( i-- ) {3130 delete thiscache[ name[i] ];3131 }3132 // if there is no data left in the cache, we want to continue3133 // and let the cache object itself get destroyed3134 if ( pvt ? !isemptydataobject(thiscache) : !jquery.isemptyobject(thiscache) ) {3135 return;3136 }3137 }3138 }3139 // see jquery.data for more information3140 if ( !pvt ) {3141 delete cache[ id ].data;3142 // don't destroy the parent cache unless the internal data object3143 // had been the only thing left in it3144 if ( !isemptydataobject( cache[ id ] ) ) {3145 return;3146 }3147 }3148 // destroy the cache3149 if ( isnode ) {3150 jquery.cleandata( [ elem ], true );3151 // use delete when supported for expandos or `cache` is not a window per iswindow (#10080)3152 /* jshint eqeqeq: false */3153 } else if ( jquery.support.deleteexpando || cache != cache.window ) {3154 /* jshint eqeqeq: true */3155 delete cache[ id ];3156 // when all else fails, null3157 } else {3158 cache[ id ] = null;3159 }3160 }3161 jquery.extend({3162 cache: {},3163 // the following elements throw uncatchable exceptions if you3164 // attempt to add expando properties to them.3165 nodata: {3166 "applet": true,3167 "embed": true,3168 // ban all objects except for flash (which handle expandos)3169 "object": "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"3170 },3171 hasdata: function( elem ) {3172 elem = elem.nodetype ? jquery.cache[ elem[jquery.expando] ] : elem[ jquery.expando ];3173 return !!elem && !isemptydataobject( elem );3174 },3175 data: function( elem, name, data ) {3176 return internaldata( elem, name, data );3177 },3178 removedata: function( elem, name ) {3179 return internalremovedata( elem, name );3180 },3181 // for internal use only.3182 _data: function( elem, name, data ) {3183 return internaldata( elem, name, data, true );3184 },3185 _removedata: function( elem, name ) {3186 return internalremovedata( elem, name, true );3187 },3188 // a method for determining if a dom node can handle the data expando3189 acceptdata: function( elem ) {3190 // do not set data on non-element because it will not be cleared (#8335).3191 if ( elem.nodetype && elem.nodetype !== 1 && elem.nodetype !== 9 ) {3192 return false;3193 }3194 var nodata = elem.nodename && jquery.nodata[ elem.nodename.tolowercase() ];3195 // nodes accept data unless otherwise specified; rejection can be conditional3196 return !nodata || nodata !== true && elem.getattribute("classid") === nodata;3197 }3198 });3199 jquery.fn.extend({3200 data: function( key, value ) {3201 var attrs, name,3202 data = null,3203 i = 0,3204 elem = this[0];3205 // special expections of .data basically thwart jquery.access,3206 // so implement the relevant behavior ourselves3207 // gets all values3208 if ( key === undefined ) {3209 if ( this.length ) {3210 data = jquery.data( elem );3211 if ( elem.nodetype === 1 && !jquery._data( elem, "parsedattrs" ) ) {3212 attrs = elem.attributes;3213 for ( ; i < attrs.length; i++ ) {3214 name = attrs[i].name;3215 if ( name.indexof("data-") === 0 ) {3216 name = jquery.camelcase( name.slice(5) );3217 dataattr( elem, name, data[ name ] );3218 }3219 }3220 jquery._data( elem, "parsedattrs", true );3221 }3222 }3223 return data;3224 }3225 // sets multiple values3226 if ( typeof key === "object" ) {3227 return this.each(function() {3228 jquery.data( this, key );3229 });3230 }3231 return arguments.length > 1 ?3232 // sets one value3233 this.each(function() {3234 jquery.data( this, key, value );3235 }) :3236 // gets one value3237 // try to fetch any internally stored data first3238 elem ? dataattr( elem, key, jquery.data( elem, key ) ) : null;3239 },3240 removedata: function( key ) {3241 return this.each(function() {3242 jquery.removedata( this, key );3243 });3244 }3245 });3246 function dataattr( elem, key, data ) {3247 // if nothing was found internally, try to fetch any3248 // data from the html5 data-* attribute3249 if ( data === undefined && elem.nodetype === 1 ) {3250 var name = "data-" + key.replace( rmultidash, "-$1" ).tolowercase();3251 data = elem.getattribute( name );3252 if ( typeof data === "string" ) {3253 try {3254 data = data === "true" ? true :3255 data === "false" ? false :3256 data === "null" ? null :3257 // only convert to a number if it doesn't change the string3258 +data + "" === data ? +data :3259 rbrace.test( data ) ? jquery.parsejson( data ) :3260 data;3261 } catch( e ) {}3262 // make sure we set the data so it isn't changed later3263 jquery.data( elem, key, data );3264 } else {3265 data = undefined;3266 }3267 }3268 return data;3269 }3270// checks a cache object for emptiness3271 function isemptydataobject( obj ) {3272 var name;3273 for ( name in obj ) {3274 // if the public data object is empty, the private is still empty3275 if ( name === "data" && jquery.isemptyobject( obj[name] ) ) {3276 continue;3277 }3278 if ( name !== "tojson" ) {3279 return false;3280 }3281 }3282 return true;3283 }3284 jquery.extend({3285 queue: function( elem, type, data ) {3286 var queue;3287 if ( elem ) {3288 type = ( type || "fx" ) + "queue";3289 queue = jquery._data( elem, type );3290 // speed up dequeue by getting out quickly if this is just a lookup3291 if ( data ) {3292 if ( !queue || jquery.isarray(data) ) {3293 queue = jquery._data( elem, type, jquery.makearray(data) );3294 } else {3295 queue.push( data );3296 }3297 }3298 return queue || [];3299 }3300 },3301 dequeue: function( elem, type ) {3302 type = type || "fx";3303 var queue = jquery.queue( elem, type ),3304 startlength = queue.length,3305 fn = queue.shift(),3306 hooks = jquery._queuehooks( elem, type ),3307 next = function() {3308 jquery.dequeue( elem, type );3309 };3310 // if the fx queue is dequeued, always remove the progress sentinel3311 if ( fn === "inprogress" ) {3312 fn = queue.shift();3313 startlength--;3314 }3315 if ( fn ) {3316 // add a progress sentinel to prevent the fx queue from being3317 // automatically dequeued3318 if ( type === "fx" ) {3319 queue.unshift( "inprogress" );3320 }3321 // clear up the last queue stop function3322 delete hooks.stop;3323 fn.call( elem, next, hooks );3324 }3325 if ( !startlength && hooks ) {3326 hooks.empty.fire();3327 }3328 },3329 // not intended for public consumption - generates a queuehooks object, or returns the current one3330 _queuehooks: function( elem, type ) {3331 var key = type + "queuehooks";3332 return jquery._data( elem, key ) || jquery._data( elem, key, {3333 empty: jquery.callbacks("once memory").add(function() {3334 jquery._removedata( elem, type + "queue" );3335 jquery._removedata( elem, key );3336 })3337 });3338 }3339 });3340 jquery.fn.extend({3341 queue: function( type, data ) {3342 var setter = 2;3343 if ( typeof type !== "string" ) {3344 data = type;3345 type = "fx";3346 setter--;3347 }3348 if ( arguments.length < setter ) {3349 return jquery.queue( this[0], type );3350 }3351 return data === undefined ?3352 this :3353 this.each(function() {3354 var queue = jquery.queue( this, type, data );3355 // ensure a hooks for this queue3356 jquery._queuehooks( this, type );3357 if ( type === "fx" && queue[0] !== "inprogress" ) {3358 jquery.dequeue( this, type );3359 }3360 });3361 },3362 dequeue: function( type ) {3363 return this.each(function() {3364 jquery.dequeue( this, type );3365 });3366 },3367 // based off of the plugin by clint helfers, with permission.3368 // http://blindsignals.com/index.php/2009/07/jquery-delay/3369 delay: function( time, type ) {3370 time = jquery.fx ? jquery.fx.speeds[ time ] || time : time;3371 type = type || "fx";3372 return this.queue( type, function( next, hooks ) {3373 var timeout = settimeout( next, time );3374 hooks.stop = function() {3375 cleartimeout( timeout );3376 };3377 });3378 },3379 clearqueue: function( type ) {3380 return this.queue( type || "fx", [] );3381 },3382 // get a promise resolved when queues of a certain type3383 // are emptied (fx is the type by default)3384 promise: function( type, obj ) {3385 var tmp,3386 count = 1,3387 defer = jquery.deferred(),3388 elements = this,3389 i = this.length,3390 resolve = function() {3391 if ( !( --count ) ) {3392 defer.resolvewith( elements, [ elements ] );3393 }3394 };3395 if ( typeof type !== "string" ) {3396 obj = type;3397 type = undefined;3398 }3399 type = type || "fx";3400 while( i-- ) {3401 tmp = jquery._data( elements[ i ], type + "queuehooks" );3402 if ( tmp && tmp.empty ) {3403 count++;3404 tmp.empty.add( resolve );3405 }3406 }3407 resolve();3408 return defer.promise( obj );3409 }3410 });3411 var nodehook, boolhook,3412 rclass = /[\t\r\n\f]/g,3413 rreturn = /\r/g,3414 rfocusable = /^(?:input|select|textarea|button|object)$/i,3415 rclickable = /^(?:a|area)$/i,3416 rusedefault = /^(?:checked|selected)$/i,3417 getsetattribute = jquery.support.getsetattribute,3418 getsetinput = jquery.support.input;3419 jquery.fn.extend({3420 attr: function( name, value ) {3421 return jquery.access( this, jquery.attr, name, value, arguments.length > 1 );3422 },3423 removeattr: function( name ) {3424 return this.each(function() {3425 jquery.removeattr( this, name );3426 });3427 },3428 prop: function( name, value ) {3429 return jquery.access( this, jquery.prop, name, value, arguments.length > 1 );3430 },3431 removeprop: function( name ) {3432 name = jquery.propfix[ name ] || name;3433 return this.each(function() {3434 // try/catch handles cases where ie balks (such as removing a property on window)3435 try {3436 this[ name ] = undefined;3437 delete this[ name ];3438 } catch( e ) {}3439 });3440 },3441 addclass: function( value ) {3442 var classes, elem, cur, clazz, j,3443 i = 0,3444 len = this.length,3445 proceed = typeof value === "string" && value;3446 if ( jquery.isfunction( value ) ) {3447 return this.each(function( j ) {3448 jquery( this ).addclass( value.call( this, j, this.classname ) );3449 });3450 }3451 if ( proceed ) {3452 // the disjunction here is for better compressibility (see removeclass)3453 classes = ( value || "" ).match( core_rnotwhite ) || [];3454 for ( ; i < len; i++ ) {3455 elem = this[ i ];3456 cur = elem.nodetype === 1 && ( elem.classname ?3457 ( " " + elem.classname + " " ).replace( rclass, " " ) :3458 " "3459 );3460 if ( cur ) {3461 j = 0;3462 while ( (clazz = classes[j++]) ) {3463 if ( cur.indexof( " " + clazz + " " ) < 0 ) {3464 cur += clazz + " ";3465 }3466 }3467 elem.classname = jquery.trim( cur );3468 }3469 }3470 }3471 return this;3472 },3473 removeclass: function( value ) {3474 var classes, elem, cur, clazz, j,3475 i = 0,3476 len = this.length,3477 proceed = arguments.length === 0 || typeof value === "string" && value;3478 if ( jquery.isfunction( value ) ) {3479 return this.each(function( j ) {3480 jquery( this ).removeclass( value.call( this, j, this.classname ) );3481 });3482 }3483 if ( proceed ) {3484 classes = ( value || "" ).match( core_rnotwhite ) || [];3485 for ( ; i < len; i++ ) {3486 elem = this[ i ];3487 // this expression is here for better compressibility (see addclass)3488 cur = elem.nodetype === 1 && ( elem.classname ?3489 ( " " + elem.classname + " " ).replace( rclass, " " ) :3490 ""3491 );3492 if ( cur ) {3493 j = 0;3494 while ( (clazz = classes[j++]) ) {3495 // remove *all* instances3496 while ( cur.indexof( " " + clazz + " " ) >= 0 ) {3497 cur = cur.replace( " " + clazz + " ", " " );3498 }3499 }3500 elem.classname = value ? jquery.trim( cur ) : "";3501 }3502 }3503 }3504 return this;3505 },3506 toggleclass: function( value, stateval ) {3507 var type = typeof value;3508 if ( typeof stateval === "boolean" && type === "string" ) {3509 return stateval ? this.addclass( value ) : this.removeclass( value );3510 }3511 if ( jquery.isfunction( value ) ) {3512 return this.each(function( i ) {3513 jquery( this ).toggleclass( value.call(this, i, this.classname, stateval), stateval );3514 });3515 }3516 return this.each(function() {3517 if ( type === "string" ) {3518 // toggle individual class names3519 var classname,3520 i = 0,3521 self = jquery( this ),3522 classnames = value.match( core_rnotwhite ) || [];3523 while ( (classname = classnames[ i++ ]) ) {3524 // check each classname given, space separated list3525 if ( self.hasclass( classname ) ) {3526 self.removeclass( classname );3527 } else {3528 self.addclass( classname );3529 }3530 }3531 // toggle whole class name3532 } else if ( type === core_strundefined || type === "boolean" ) {3533 if ( this.classname ) {3534 // store classname if set3535 jquery._data( this, "__classname__", this.classname );3536 }3537 // if the element has a class name or if we're passed "false",3538 // then remove the whole classname (if there was one, the above saved it).3539 // otherwise bring back whatever was previously saved (if anything),3540 // falling back to the empty string if nothing was stored.3541 this.classname = this.classname || value === false ? "" : jquery._data( this, "__classname__" ) || "";3542 }3543 });3544 },3545 hasclass: function( selector ) {3546 var classname = " " + selector + " ",3547 i = 0,3548 l = this.length;3549 for ( ; i < l; i++ ) {3550 if ( this[i].nodetype === 1 && (" " + this[i].classname + " ").replace(rclass, " ").indexof( classname ) >= 0 ) {3551 return true;3552 }3553 }3554 return false;3555 },3556 val: function( value ) {3557 var ret, hooks, isfunction,3558 elem = this[0];3559 if ( !arguments.length ) {3560 if ( elem ) {3561 hooks = jquery.valhooks[ elem.type ] || jquery.valhooks[ elem.nodename.tolowercase() ];3562 if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {3563 return ret;3564 }3565 ret = elem.value;3566 return typeof ret === "string" ?3567 // handle most common string cases3568 ret.replace(rreturn, "") :3569 // handle cases where value is null/undef or number3570 ret == null ? "" : ret;3571 }3572 return;3573 }3574 isfunction = jquery.isfunction( value );3575 return this.each(function( i ) {3576 var val;3577 if ( this.nodetype !== 1 ) {3578 return;3579 }3580 if ( isfunction ) {3581 val = value.call( this, i, jquery( this ).val() );3582 } else {3583 val = value;3584 }3585 // treat null/undefined as ""; convert numbers to string3586 if ( val == null ) {3587 val = "";3588 } else if ( typeof val === "number" ) {3589 val += "";3590 } else if ( jquery.isarray( val ) ) {3591 val = jquery.map(val, function ( value ) {3592 return value == null ? "" : value + "";3593 });3594 }3595 hooks = jquery.valhooks[ this.type ] || jquery.valhooks[ this.nodename.tolowercase() ];3596 // if set returns undefined, fall back to normal setting3597 if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {3598 this.value = val;3599 }3600 });3601 }3602 });3603 jquery.extend({3604 valhooks: {3605 option: {3606 get: function( elem ) {3607 // use proper attribute retrieval(#6932, #12072)3608 var val = jquery.find.attr( elem, "value" );3609 return val != null ?3610 val :3611 elem.text;3612 }3613 },3614 select: {3615 get: function( elem ) {3616 var value, option,3617 options = elem.options,3618 index = elem.selectedindex,3619 one = elem.type === "select-one" || index < 0,3620 values = one ? null : [],3621 max = one ? index + 1 : options.length,3622 i = index < 0 ?3623 max :3624 one ? index : 0;3625 // loop through all the selected options3626 for ( ; i < max; i++ ) {3627 option = options[ i ];3628 // oldie doesn't update selected after form reset (#2551)3629 if ( ( option.selected || i === index ) &&3630 // don't return options that are disabled or in a disabled optgroup3631 ( jquery.support.optdisabled ? !option.disabled : option.getattribute("disabled") === null ) &&3632 ( !option.parentnode.disabled || !jquery.nodename( option.parentnode, "optgroup" ) ) ) {3633 // get the specific value for the option3634 value = jquery( option ).val();3635 // we don't need an array for one selects3636 if ( one ) {3637 return value;3638 }3639 // multi-selects return an array3640 values.push( value );3641 }3642 }3643 return values;3644 },3645 set: function( elem, value ) {3646 var optionset, option,3647 options = elem.options,3648 values = jquery.makearray( value ),3649 i = options.length;3650 while ( i-- ) {3651 option = options[ i ];3652 if ( (option.selected = jquery.inarray( jquery(option).val(), values ) >= 0) ) {3653 optionset = true;3654 }3655 }3656 // force browsers to behave consistently when non-matching value is set3657 if ( !optionset ) {3658 elem.selectedindex = -1;3659 }3660 return values;3661 }3662 }3663 },3664 attr: function( elem, name, value ) {3665 var hooks, ret,3666 ntype = elem.nodetype;3667 // don't get/set attributes on text, comment and attribute nodes3668 if ( !elem || ntype === 3 || ntype === 8 || ntype === 2 ) {3669 return;3670 }3671 // fallback to prop when attributes are not supported3672 if ( typeof elem.getattribute === core_strundefined ) {3673 return jquery.prop( elem, name, value );3674 }3675 // all attributes are lowercase3676 // grab necessary hook if one is defined3677 if ( ntype !== 1 || !jquery.isxmldoc( elem ) ) {3678 name = name.tolowercase();3679 hooks = jquery.attrhooks[ name ] ||3680 ( jquery.expr.match.bool.test( name ) ? boolhook : nodehook );3681 }3682 if ( value !== undefined ) {3683 if ( value === null ) {3684 jquery.removeattr( elem, name );3685 } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {3686 return ret;3687 } else {3688 elem.setattribute( name, value + "" );3689 return value;3690 }3691 } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {3692 return ret;3693 } else {3694 ret = jquery.find.attr( elem, name );3695 // non-existent attributes return null, we normalize to undefined3696 return ret == null ?3697 undefined :3698 ret;3699 }3700 },3701 removeattr: function( elem, value ) {3702 var name, propname,3703 i = 0,3704 attrnames = value && value.match( core_rnotwhite );3705 if ( attrnames && elem.nodetype === 1 ) {3706 while ( (name = attrnames[i++]) ) {3707 propname = jquery.propfix[ name ] || name;3708 // boolean attributes get special treatment (#10870)3709 if ( jquery.expr.match.bool.test( name ) ) {3710 // set corresponding property to false3711 if ( getsetinput && getsetattribute || !rusedefault.test( name ) ) {3712 elem[ propname ] = false;3713 // support: ie<93714 // also clear defaultchecked/defaultselected (if appropriate)3715 } else {3716 elem[ jquery.camelcase( "default-" + name ) ] =3717 elem[ propname ] = false;3718 }3719 // see #9699 for explanation of this approach (setting first, then removal)3720 } else {3721 jquery.attr( elem, name, "" );3722 }3723 elem.removeattribute( getsetattribute ? name : propname );3724 }3725 }3726 },3727 attrhooks: {3728 type: {3729 set: function( elem, value ) {3730 if ( !jquery.support.radiovalue && value === "radio" && jquery.nodename(elem, "input") ) {3731 // setting the type on a radio button after the value resets the value in ie6-93732 // reset value to default in case type is set after value during creation3733 var val = elem.value;3734 elem.setattribute( "type", value );3735 if ( val ) {3736 elem.value = val;3737 }3738 return value;3739 }3740 }3741 }3742 },3743 propfix: {3744 "for": "htmlfor",3745 "class": "classname"3746 },3747 prop: function( elem, name, value ) {3748 var ret, hooks, notxml,3749 ntype = elem.nodetype;3750 // don't get/set properties on text, comment and attribute nodes3751 if ( !elem || ntype === 3 || ntype === 8 || ntype === 2 ) {3752 return;3753 }3754 notxml = ntype !== 1 || !jquery.isxmldoc( elem );3755 if ( notxml ) {3756 // fix name and attach hooks3757 name = jquery.propfix[ name ] || name;3758 hooks = jquery.prophooks[ name ];3759 }3760 if ( value !== undefined ) {3761 return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?3762 ret :3763 ( elem[ name ] = value );3764 } else {3765 return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?3766 ret :3767 elem[ name ];3768 }3769 },3770 prophooks: {3771 tabindex: {3772 get: function( elem ) {3773 // elem.tabindex doesn't always return the correct value when it hasn't been explicitly set3774 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/3775 // use proper attribute retrieval(#12072)3776 var tabindex = jquery.find.attr( elem, "tabindex" );3777 return tabindex ?3778 parseint( tabindex, 10 ) :3779 rfocusable.test( elem.nodename ) || rclickable.test( elem.nodename ) && elem.href ?3780 0 :3781 -1;3782 }3783 }3784 }3785 });3786// hooks for boolean attributes3787 boolhook = {3788 set: function( elem, value, name ) {3789 if ( value === false ) {3790 // remove boolean attributes when set to false3791 jquery.removeattr( elem, name );3792 } else if ( getsetinput && getsetattribute || !rusedefault.test( name ) ) {3793 // ie<8 needs the *property* name3794 elem.setattribute( !getsetattribute && jquery.propfix[ name ] || name, name );3795 // use defaultchecked and defaultselected for oldie3796 } else {3797 elem[ jquery.camelcase( "default-" + name ) ] = elem[ name ] = true;3798 }3799 return name;3800 }3801 };3802 jquery.each( jquery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {3803 var getter = jquery.expr.attrhandle[ name ] || jquery.find.attr;3804 jquery.expr.attrhandle[ name ] = getsetinput && getsetattribute || !rusedefault.test( name ) ?3805 function( elem, name, isxml ) {3806 var fn = jquery.expr.attrhandle[ name ],3807 ret = isxml ?3808 undefined :3809 /* jshint eqeqeq: false */3810 (jquery.expr.attrhandle[ name ] = undefined) !=3811 getter( elem, name, isxml ) ?3812 name.tolowercase() :3813 null;3814 jquery.expr.attrhandle[ name ] = fn;3815 return ret;3816 } :3817 function( elem, name, isxml ) {3818 return isxml ?3819 undefined :3820 elem[ jquery.camelcase( "default-" + name ) ] ?3821 name.tolowercase() :3822 null;3823 };3824 });3825// fix oldie attroperties3826 if ( !getsetinput || !getsetattribute ) {3827 jquery.attrhooks.value = {3828 set: function( elem, value, name ) {3829 if ( jquery.nodename( elem, "input" ) ) {3830 // does not return so that setattribute is also used3831 elem.defaultvalue = value;3832 } else {3833 // use nodehook if defined (#1954); otherwise setattribute is fine3834 return nodehook && nodehook.set( elem, value, name );3835 }3836 }3837 };3838 }3839// ie6/7 do not support getting/setting some attributes with get/setattribute3840 if ( !getsetattribute ) {3841 // use this for any attribute in ie6/73842 // this fixes almost every ie6/7 issue3843 nodehook = {3844 set: function( elem, value, name ) {3845 // set the existing or create a new attribute node3846 var ret = elem.getattributenode( name );3847 if ( !ret ) {3848 elem.setattributenode(3849 (ret = elem.ownerdocument.createattribute( name ))3850 );3851 }3852 ret.value = value += "";3853 // break association with cloned elements by also using setattribute (#9646)3854 return name === "value" || value === elem.getattribute( name ) ?3855 value :3856 undefined;3857 }3858 };3859 jquery.expr.attrhandle.id = jquery.expr.attrhandle.name = jquery.expr.attrhandle.coords =3860 // some attributes are constructed with empty-string values when not defined3861 function( elem, name, isxml ) {3862 var ret;3863 return isxml ?3864 undefined :3865 (ret = elem.getattributenode( name )) && ret.value !== "" ?3866 ret.value :3867 null;3868 };3869 jquery.valhooks.button = {3870 get: function( elem, name ) {3871 var ret = elem.getattributenode( name );3872 return ret && ret.specified ?3873 ret.value :3874 undefined;3875 },3876 set: nodehook.set3877 };3878 // set contenteditable to false on removals(#10429)3879 // setting to empty string throws an error as an invalid value3880 jquery.attrhooks.contenteditable = {3881 set: function( elem, value, name ) {3882 nodehook.set( elem, value === "" ? false : value, name );3883 }3884 };3885 // set width and height to auto instead of 0 on empty string( bug #8150 )3886 // this is for removals3887 jquery.each([ "width", "height" ], function( i, name ) {3888 jquery.attrhooks[ name ] = {3889 set: function( elem, value ) {3890 if ( value === "" ) {3891 elem.setattribute( name, "auto" );3892 return value;3893 }3894 }3895 };3896 });3897 }3898// some attributes require a special call on ie3899// http://msdn.microsoft.com/en-us/library/ms536429%28vs.85%29.aspx3900 if ( !jquery.support.hrefnormalized ) {3901 // href/src property should get the full normalized url (#10299/#12915)3902 jquery.each([ "href", "src" ], function( i, name ) {3903 jquery.prophooks[ name ] = {3904 get: function( elem ) {3905 return elem.getattribute( name, 4 );3906 }3907 };3908 });3909 }3910 if ( !jquery.support.style ) {3911 jquery.attrhooks.style = {3912 get: function( elem ) {3913 // return undefined in the case of empty string3914 // note: ie uppercases css property names, but if we were to .tolowercase()3915 // .csstext, that would destroy case senstitivity in url's, like in "background"3916 return elem.style.csstext || undefined;3917 },3918 set: function( elem, value ) {3919 return ( elem.style.csstext = value + "" );3920 }3921 };3922 }3923// safari mis-reports the default selected property of an option3924// accessing the parent's selectedindex property fixes it3925 if ( !jquery.support.optselected ) {3926 jquery.prophooks.selected = {3927 get: function( elem ) {3928 var parent = elem.parentnode;3929 if ( parent ) {3930 parent.selectedindex;3931 // make sure that it also works with optgroups, see #57013932 if ( parent.parentnode ) {3933 parent.parentnode.selectedindex;3934 }3935 }3936 return null;3937 }3938 };3939 }3940 jquery.each([3941 "tabindex",3942 "readonly",3943 "maxlength",3944 "cellspacing",3945 "cellpadding",3946 "rowspan",3947 "colspan",3948 "usemap",3949 "frameborder",3950 "contenteditable"3951 ], function() {3952 jquery.propfix[ this.tolowercase() ] = this;3953 });3954// ie6/7 call enctype encoding3955 if ( !jquery.support.enctype ) {3956 jquery.propfix.enctype = "encoding";3957 }3958// radios and checkboxes getter/setter3959 jquery.each([ "radio", "checkbox" ], function() {3960 jquery.valhooks[ this ] = {3961 set: function( elem, value ) {3962 if ( jquery.isarray( value ) ) {3963 return ( elem.checked = jquery.inarray( jquery(elem).val(), value ) >= 0 );3964 }3965 }3966 };3967 if ( !jquery.support.checkon ) {3968 jquery.valhooks[ this ].get = function( elem ) {3969 // support: webkit3970 // "" is returned instead of "on" if a value isn't specified3971 return elem.getattribute("value") === null ? "on" : elem.value;3972 };3973 }3974 });3975 var rformelems = /^(?:input|select|textarea)$/i,3976 rkeyevent = /^key/,3977 rmouseevent = /^(?:mouse|contextmenu)|click/,3978 rfocusmorph = /^(?:focusinfocus|focusoutblur)$/,3979 rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;3980 function returntrue() {3981 return true;3982 }3983 function returnfalse() {3984 return false;3985 }3986 function safeactiveelement() {3987 try {3988 return document.activeelement;3989 } catch ( err ) { }3990 }3991 /*3992 * helper functions for managing events -- not part of the public interface.3993 * props to dean edwards' addevent library for many of the ideas.3994 */3995 jquery.event = {3996 global: {},3997 add: function( elem, types, handler, data, selector ) {3998 var tmp, events, t, handleobjin,3999 special, eventhandle, handleobj,4000 handlers, type, namespaces, origtype,4001 elemdata = jquery._data( elem );4002 // don't attach events to nodata or text/comment nodes (but allow plain objects)4003 if ( !elemdata ) {4004 return;4005 }4006 // caller can pass in an object of custom data in lieu of the handler4007 if ( handler.handler ) {4008 handleobjin = handler;4009 handler = handleobjin.handler;4010 selector = handleobjin.selector;4011 }4012 // make sure that the handler has a unique id, used to find/remove it later4013 if ( !handler.guid ) {4014 handler.guid = jquery.guid++;4015 }4016 // init the element's event structure and main handler, if this is the first4017 if ( !(events = elemdata.events) ) {4018 events = elemdata.events = {};4019 }4020 if ( !(eventhandle = elemdata.handle) ) {4021 eventhandle = elemdata.handle = function( e ) {4022 // discard the second event of a jquery.event.trigger() and4023 // when an event is called after a page has unloaded4024 return typeof jquery !== core_strundefined && (!e || jquery.event.triggered !== e.type) ?4025 jquery.event.dispatch.apply( eventhandle.elem, arguments ) :4026 undefined;4027 };4028 // add elem as a property of the handle fn to prevent a memory leak with ie non-native events4029 eventhandle.elem = elem;4030 }4031 // handle multiple events separated by a space4032 types = ( types || "" ).match( core_rnotwhite ) || [""];4033 t = types.length;4034 while ( t-- ) {4035 tmp = rtypenamespace.exec( types[t] ) || [];4036 type = origtype = tmp[1];4037 namespaces = ( tmp[2] || "" ).split( "." ).sort();4038 // there *must* be a type, no attaching namespace-only handlers4039 if ( !type ) {4040 continue;4041 }4042 // if event changes its type, use the special event handlers for the changed type4043 special = jquery.event.special[ type ] || {};4044 // if selector defined, determine special event api type, otherwise given type4045 type = ( selector ? special.delegatetype : special.bindtype ) || type;4046 // update special based on newly reset type4047 special = jquery.event.special[ type ] || {};4048 // handleobj is passed to all event handlers4049 handleobj = jquery.extend({4050 type: type,4051 origtype: origtype,4052 data: data,4053 handler: handler,4054 guid: handler.guid,4055 selector: selector,4056 needscontext: selector && jquery.expr.match.needscontext.test( selector ),4057 namespace: namespaces.join(".")4058 }, handleobjin );4059 // init the event handler queue if we're the first4060 if ( !(handlers = events[ type ]) ) {4061 handlers = events[ type ] = [];4062 handlers.delegatecount = 0;4063 // only use addeventlistener/attachevent if the special events handler returns false4064 if ( !special.setup || special.setup.call( elem, data, namespaces, eventhandle ) === false ) {4065 // bind the global event handler to the element4066 if ( elem.addeventlistener ) {4067 elem.addeventlistener( type, eventhandle, false );4068 } else if ( elem.attachevent ) {4069 elem.attachevent( "on" + type, eventhandle );4070 }4071 }4072 }4073 if ( special.add ) {4074 special.add.call( elem, handleobj );4075 if ( !handleobj.handler.guid ) {4076 handleobj.handler.guid = handler.guid;4077 }4078 }4079 // add to the element's handler list, delegates in front4080 if ( selector ) {4081 handlers.splice( handlers.delegatecount++, 0, handleobj );4082 } else {4083 handlers.push( handleobj );4084 }4085 // keep track of which events have ever been used, for event optimization4086 jquery.event.global[ type ] = true;4087 }4088 // nullify elem to prevent memory leaks in ie4089 elem = null;4090 },4091 // detach an event or set of events from an element4092 remove: function( elem, types, handler, selector, mappedtypes ) {4093 var j, handleobj, tmp,4094 origcount, t, events,4095 special, handlers, type,4096 namespaces, origtype,4097 elemdata = jquery.hasdata( elem ) && jquery._data( elem );4098 if ( !elemdata || !(events = elemdata.events) ) {4099 return;4100 }4101 // once for each type.namespace in types; type may be omitted4102 types = ( types || "" ).match( core_rnotwhite ) || [""];4103 t = types.length;4104 while ( t-- ) {4105 tmp = rtypenamespace.exec( types[t] ) || [];4106 type = origtype = tmp[1];4107 namespaces = ( tmp[2] || "" ).split( "." ).sort();4108 // unbind all events (on this namespace, if provided) for the element4109 if ( !type ) {4110 for ( type in events ) {4111 jquery.event.remove( elem, type + types[ t ], handler, selector, true );4112 }4113 continue;4114 }4115 special = jquery.event.special[ type ] || {};4116 type = ( selector ? special.delegatetype : special.bindtype ) || type;4117 handlers = events[ type ] || [];4118 tmp = tmp[2] && new regexp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );4119 // remove matching events4120 origcount = j = handlers.length;4121 while ( j-- ) {4122 handleobj = handlers[ j ];4123 if ( ( mappedtypes || origtype === handleobj.origtype ) &&4124 ( !handler || handler.guid === handleobj.guid ) &&4125 ( !tmp || tmp.test( handleobj.namespace ) ) &&4126 ( !selector || selector === handleobj.selector || selector === "**" && handleobj.selector ) ) {4127 handlers.splice( j, 1 );4128 if ( handleobj.selector ) {4129 handlers.delegatecount--;4130 }4131 if ( special.remove ) {4132 special.remove.call( elem, handleobj );4133 }4134 }4135 }4136 // remove generic event handler if we removed something and no more handlers exist4137 // (avoids potential for endless recursion during removal of special event handlers)4138 if ( origcount && !handlers.length ) {4139 if ( !special.teardown || special.teardown.call( elem, namespaces, elemdata.handle ) === false ) {4140 jquery.removeevent( elem, type, elemdata.handle );4141 }4142 delete events[ type ];4143 }4144 }4145 // remove the expando if it's no longer used4146 if ( jquery.isemptyobject( events ) ) {4147 delete elemdata.handle;4148 // removedata also checks for emptiness and clears the expando if empty4149 // so use it instead of delete4150 jquery._removedata( elem, "events" );4151 }4152 },4153 trigger: function( event, data, elem, onlyhandlers ) {4154 var handle, ontype, cur,4155 bubbletype, special, tmp, i,4156 eventpath = [ elem || document ],4157 type = core_hasown.call( event, "type" ) ? event.type : event,4158 namespaces = core_hasown.call( event, "namespace" ) ? event.namespace.split(".") : [];4159 cur = tmp = elem = elem || document;4160 // don't do events on text and comment nodes4161 if ( elem.nodetype === 3 || elem.nodetype === 8 ) {4162 return;4163 }4164 // focus/blur morphs to focusin/out; ensure we're not firing them right now4165 if ( rfocusmorph.test( type + jquery.event.triggered ) ) {4166 return;4167 }4168 if ( type.indexof(".") >= 0 ) {4169 // namespaced trigger; create a regexp to match event type in handle()4170 namespaces = type.split(".");4171 type = namespaces.shift();4172 namespaces.sort();4173 }4174 ontype = type.indexof(":") < 0 && "on" + type;4175 // caller can pass in a jquery.event object, object, or just an event type string4176 event = event[ jquery.expando ] ?4177 event :4178 new jquery.event( type, typeof event === "object" && event );4179 // trigger bitmask: & 1 for native handlers; & 2 for jquery (always true)4180 event.istrigger = onlyhandlers ? 2 : 3;4181 event.namespace = namespaces.join(".");4182 event.namespace_re = event.namespace ?4183 new regexp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :4184 null;4185 // clean up the event in case it is being reused4186 event.result = undefined;4187 if ( !event.target ) {4188 event.target = elem;4189 }4190 // clone any incoming data and prepend the event, creating the handler arg list4191 data = data == null ?4192 [ event ] :4193 jquery.makearray( data, [ event ] );4194 // allow special events to draw outside the lines4195 special = jquery.event.special[ type ] || {};4196 if ( !onlyhandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {4197 return;4198 }4199 // determine event propagation path in advance, per w3c events spec (#9951)4200 // bubble up to document, then to window; watch for a global ownerdocument var (#9724)4201 if ( !onlyhandlers && !special.nobubble && !jquery.iswindow( elem ) ) {4202 bubbletype = special.delegatetype || type;4203 if ( !rfocusmorph.test( bubbletype + type ) ) {4204 cur = cur.parentnode;4205 }4206 for ( ; cur; cur = cur.parentnode ) {4207 eventpath.push( cur );4208 tmp = cur;4209 }4210 // only add window if we got to document (e.g., not plain obj or detached dom)4211 if ( tmp === (elem.ownerdocument || document) ) {4212 eventpath.push( tmp.defaultview || tmp.parentwindow || window );4213 }4214 }4215 // fire handlers on the event path4216 i = 0;4217 while ( (cur = eventpath[i++]) && !event.ispropagationstopped() ) {4218 event.type = i > 1 ?4219 bubbletype :4220 special.bindtype || type;4221 // jquery handler4222 handle = ( jquery._data( cur, "events" ) || {} )[ event.type ] && jquery._data( cur, "handle" );4223 if ( handle ) {4224 handle.apply( cur, data );4225 }4226 // native handler4227 handle = ontype && cur[ ontype ];4228 if ( handle && jquery.acceptdata( cur ) && handle.apply && handle.apply( cur, data ) === false ) {4229 event.preventdefault();4230 }4231 }4232 event.type = type;4233 // if nobody prevented the default action, do it now4234 if ( !onlyhandlers && !event.isdefaultprevented() ) {4235 if ( (!special._default || special._default.apply( eventpath.pop(), data ) === false) &&4236 jquery.acceptdata( elem ) ) {4237 // call a native dom method on the target with the same name name as the event.4238 // can't use an .isfunction() check here because ie6/7 fails that test.4239 // don't do default actions on window, that's where global variables be (#6170)4240 if ( ontype && elem[ type ] && !jquery.iswindow( elem ) ) {4241 // don't re-trigger an onfoo event when we call its foo() method4242 tmp = elem[ ontype ];4243 if ( tmp ) {4244 elem[ ontype ] = null;4245 }4246 // prevent re-triggering of the same event, since we already bubbled it above4247 jquery.event.triggered = type;4248 try {4249 elem[ type ]();4250 } catch ( e ) {4251 // ie<9 dies on focus/blur to hidden element (#1486,#12518)4252 // only reproducible on winxp ie8 native, not ie9 in ie8 mode4253 }4254 jquery.event.triggered = undefined;4255 if ( tmp ) {4256 elem[ ontype ] = tmp;4257 }4258 }4259 }4260 }4261 return event.result;4262 },4263 dispatch: function( event ) {4264 // make a writable jquery.event from the native event object4265 event = jquery.event.fix( event );4266 var i, ret, handleobj, matched, j,4267 handlerqueue = [],4268 args = core_slice.call( arguments ),4269 handlers = ( jquery._data( this, "events" ) || {} )[ event.type ] || [],4270 special = jquery.event.special[ event.type ] || {};4271 // use the fix-ed jquery.event rather than the (read-only) native event4272 args[0] = event;4273 event.delegatetarget = this;4274 // call the predispatch hook for the mapped type, and let it bail if desired4275 if ( special.predispatch && special.predispatch.call( this, event ) === false ) {4276 return;4277 }4278 // determine handlers4279 handlerqueue = jquery.event.handlers.call( this, event, handlers );4280 // run delegates first; they may want to stop propagation beneath us4281 i = 0;4282 while ( (matched = handlerqueue[ i++ ]) && !event.ispropagationstopped() ) {4283 event.currenttarget = matched.elem;4284 j = 0;4285 while ( (handleobj = matched.handlers[ j++ ]) && !event.isimmediatepropagationstopped() ) {4286 // triggered event must either 1) have no namespace, or4287 // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).4288 if ( !event.namespace_re || event.namespace_re.test( handleobj.namespace ) ) {4289 event.handleobj = handleobj;4290 event.data = handleobj.data;4291 ret = ( (jquery.event.special[ handleobj.origtype ] || {}).handle || handleobj.handler )4292 .apply( matched.elem, args );4293 if ( ret !== undefined ) {4294 if ( (event.result = ret) === false ) {4295 event.preventdefault();4296 event.stoppropagation();4297 }4298 }4299 }4300 }4301 }4302 // call the postdispatch hook for the mapped type4303 if ( special.postdispatch ) {4304 special.postdispatch.call( this, event );4305 }4306 return event.result;4307 },4308 handlers: function( event, handlers ) {4309 var sel, handleobj, matches, i,4310 handlerqueue = [],4311 delegatecount = handlers.delegatecount,4312 cur = event.target;4313 // find delegate handlers4314 // black-hole svg <use> instance trees (#13180)4315 // avoid non-left-click bubbling in firefox (#3861)4316 if ( delegatecount && cur.nodetype && (!event.button || event.type !== "click") ) {4317 /* jshint eqeqeq: false */4318 for ( ; cur != this; cur = cur.parentnode || this ) {4319 /* jshint eqeqeq: true */4320 // don't check non-elements (#13208)4321 // don't process clicks on disabled elements (#6911, #8165, #11382, #11764)4322 if ( cur.nodetype === 1 && (cur.disabled !== true || event.type !== "click") ) {4323 matches = [];4324 for ( i = 0; i < delegatecount; i++ ) {4325 handleobj = handlers[ i ];4326 // don't conflict with object.prototype properties (#13203)4327 sel = handleobj.selector + " ";4328 if ( matches[ sel ] === undefined ) {4329 matches[ sel ] = handleobj.needscontext ?4330 jquery( sel, this ).index( cur ) >= 0 :4331 jquery.find( sel, this, null, [ cur ] ).length;4332 }4333 if ( matches[ sel ] ) {4334 matches.push( handleobj );4335 }4336 }4337 if ( matches.length ) {4338 handlerqueue.push({ elem: cur, handlers: matches });4339 }4340 }4341 }4342 }4343 // add the remaining (directly-bound) handlers4344 if ( delegatecount < handlers.length ) {4345 handlerqueue.push({ elem: this, handlers: handlers.slice( delegatecount ) });4346 }4347 return handlerqueue;4348 },4349 fix: function( event ) {4350 if ( event[ jquery.expando ] ) {4351 return event;4352 }4353 // create a writable copy of the event object and normalize some properties4354 var i, prop, copy,4355 type = event.type,4356 originalevent = event,4357 fixhook = this.fixhooks[ type ];4358 if ( !fixhook ) {4359 this.fixhooks[ type ] = fixhook =4360 rmouseevent.test( type ) ? this.mousehooks :4361 rkeyevent.test( type ) ? this.keyhooks :4362 {};4363 }4364 copy = fixhook.props ? this.props.concat( fixhook.props ) : this.props;4365 event = new jquery.event( originalevent );4366 i = copy.length;4367 while ( i-- ) {4368 prop = copy[ i ];4369 event[ prop ] = originalevent[ prop ];4370 }4371 // support: ie<94372 // fix target property (#1925)4373 if ( !event.target ) {4374 event.target = originalevent.srcelement || document;4375 }4376 // support: chrome 23+, safari?4377 // target should not be a text node (#504, #13143)4378 if ( event.target.nodetype === 3 ) {4379 event.target = event.target.parentnode;4380 }4381 // support: ie<94382 // for mouse/key events, metakey==false if it's undefined (#3368, #11328)4383 event.metakey = !!event.metakey;4384 return fixhook.filter ? fixhook.filter( event, originalevent ) : event;4385 },4386 // includes some event props shared by keyevent and mouseevent4387 props: "altkey bubbles cancelable ctrlkey currenttarget eventphase metakey relatedtarget shiftkey target timestamp view which".split(" "),4388 fixhooks: {},4389 keyhooks: {4390 props: "char charcode key keycode".split(" "),4391 filter: function( event, original ) {4392 // add which for key events4393 if ( event.which == null ) {4394 event.which = original.charcode != null ? original.charcode : original.keycode;4395 }4396 return event;4397 }4398 },4399 mousehooks: {4400 props: "button buttons clientx clienty fromelement offsetx offsety pagex pagey screenx screeny toelement".split(" "),4401 filter: function( event, original ) {4402 var body, eventdoc, doc,4403 button = original.button,4404 fromelement = original.fromelement;4405 // calculate pagex/y if missing and clientx/y available4406 if ( event.pagex == null && original.clientx != null ) {4407 eventdoc = event.target.ownerdocument || document;4408 doc = eventdoc.documentelement;4409 body = eventdoc.body;4410 event.pagex = original.clientx + ( doc && doc.scrollleft || body && body.scrollleft || 0 ) - ( doc && doc.clientleft || body && body.clientleft || 0 );4411 event.pagey = original.clienty + ( doc && doc.scrolltop || body && body.scrolltop || 0 ) - ( doc && doc.clienttop || body && body.clienttop || 0 );4412 }4413 // add relatedtarget, if necessary4414 if ( !event.relatedtarget && fromelement ) {4415 event.relatedtarget = fromelement === event.target ? original.toelement : fromelement;4416 }4417 // add which for click: 1 === left; 2 === middle; 3 === right4418 // note: button is not normalized, so don't use it4419 if ( !event.which && button !== undefined ) {4420 event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );4421 }4422 return event;4423 }4424 },4425 special: {4426 load: {4427 // prevent triggered image.load events from bubbling to window.load4428 nobubble: true4429 },4430 focus: {4431 // fire native event if possible so blur/focus sequence is correct4432 trigger: function() {4433 if ( this !== safeactiveelement() && this.focus ) {4434 try {4435 this.focus();4436 return false;4437 } catch ( e ) {4438 // support: ie<94439 // if we error on focus to hidden element (#1486, #12518),4440 // let .trigger() run the handlers4441 }4442 }4443 },4444 delegatetype: "focusin"4445 },4446 blur: {4447 trigger: function() {4448 if ( this === safeactiveelement() && this.blur ) {4449 this.blur();4450 return false;4451 }4452 },4453 delegatetype: "focusout"4454 },4455 click: {4456 // for checkbox, fire native event so checked state will be right4457 trigger: function() {4458 if ( jquery.nodename( this, "input" ) && this.type === "checkbox" && this.click ) {4459 this.click();4460 return false;4461 }4462 },4463 // for cross-browser consistency, don't fire native .click() on links4464 _default: function( event ) {4465 return jquery.nodename( event.target, "a" );4466 }4467 },4468 beforeunload: {4469 postdispatch: function( event ) {4470 // even when returnvalue equals to undefined firefox will still show alert4471 if ( event.result !== undefined ) {4472 event.originalevent.returnvalue = event.result;4473 }4474 }4475 }4476 },4477 simulate: function( type, elem, event, bubble ) {4478 // piggyback on a donor event to simulate a different one.4479 // fake originalevent to avoid donor's stoppropagation, but if the4480 // simulated event prevents default then we do the same on the donor.4481 var e = jquery.extend(4482 new jquery.event(),4483 event,4484 {4485 type: type,4486 issimulated: true,4487 originalevent: {}4488 }4489 );4490 if ( bubble ) {4491 jquery.event.trigger( e, null, elem );4492 } else {4493 jquery.event.dispatch.call( elem, e );4494 }4495 if ( e.isdefaultprevented() ) {4496 event.preventdefault();4497 }4498 }4499 };4500 jquery.removeevent = document.removeeventlistener ?4501 function( elem, type, handle ) {4502 if ( elem.removeeventlistener ) {4503 elem.removeeventlistener( type, handle, false );4504 }4505 } :4506 function( elem, type, handle ) {4507 var name = "on" + type;4508 if ( elem.detachevent ) {4509 // #8545, #7054, preventing memory leaks for custom events in ie6-84510 // detachevent needed property on element, by name of that event, to properly expose it to gc4511 if ( typeof elem[ name ] === core_strundefined ) {4512 elem[ name ] = null;4513 }4514 elem.detachevent( name, handle );4515 }4516 };4517 jquery.event = function( src, props ) {4518 // allow instantiation without the 'new' keyword4519 if ( !(this instanceof jquery.event) ) {4520 return new jquery.event( src, props );4521 }4522 // event object4523 if ( src && src.type ) {4524 this.originalevent = src;4525 this.type = src.type;4526 // events bubbling up the document may have been marked as prevented4527 // by a handler lower down the tree; reflect the correct value.4528 this.isdefaultprevented = ( src.defaultprevented || src.returnvalue === false ||4529 src.getpreventdefault && src.getpreventdefault() ) ? returntrue : returnfalse;4530 // event type4531 } else {4532 this.type = src;4533 }4534 // put explicitly provided properties onto the event object4535 if ( props ) {4536 jquery.extend( this, props );4537 }4538 // create a timestamp if incoming event doesn't have one4539 this.timestamp = src && src.timestamp || jquery.now();4540 // mark it as fixed4541 this[ jquery.expando ] = true;4542 };4543// jquery.event is based on dom3 events as specified by the ecmascript language binding4544// http://www.w3.org/tr/2003/wd-dom-level-3-events-20030331/ecma-script-binding.html4545 jquery.event.prototype = {4546 isdefaultprevented: returnfalse,4547 ispropagationstopped: returnfalse,4548 isimmediatepropagationstopped: returnfalse,4549 preventdefault: function() {4550 var e = this.originalevent;4551 this.isdefaultprevented = returntrue;4552 if ( !e ) {4553 return;4554 }4555 // if preventdefault exists, run it on the original event4556 if ( e.preventdefault ) {4557 e.preventdefault();4558 // support: ie4559 // otherwise set the returnvalue property of the original event to false4560 } else {4561 e.returnvalue = false;4562 }4563 },4564 stoppropagation: function() {4565 var e = this.originalevent;4566 this.ispropagationstopped = returntrue;4567 if ( !e ) {4568 return;4569 }4570 // if stoppropagation exists, run it on the original event4571 if ( e.stoppropagation ) {4572 e.stoppropagation();4573 }4574 // support: ie4575 // set the cancelbubble property of the original event to true4576 e.cancelbubble = true;4577 },4578 stopimmediatepropagation: function() {4579 this.isimmediatepropagationstopped = returntrue;4580 this.stoppropagation();4581 }4582 };4583// create mouseenter/leave events using mouseover/out and event-time checks4584 jquery.each({4585 mouseenter: "mouseover",4586 mouseleave: "mouseout"4587 }, function( orig, fix ) {4588 jquery.event.special[ orig ] = {4589 delegatetype: fix,4590 bindtype: fix,4591 handle: function( event ) {4592 var ret,4593 target = this,4594 related = event.relatedtarget,4595 handleobj = event.handleobj;4596 // for mousenter/leave call the handler if related is outside the target.4597 // nb: no relatedtarget if the mouse left/entered the browser window4598 if ( !related || (related !== target && !jquery.contains( target, related )) ) {4599 event.type = handleobj.origtype;4600 ret = handleobj.handler.apply( this, arguments );4601 event.type = fix;4602 }4603 return ret;4604 }4605 };4606 });4607// ie submit delegation4608 if ( !jquery.support.submitbubbles ) {4609 jquery.event.special.submit = {4610 setup: function() {4611 // only need this for delegated form submit events4612 if ( jquery.nodename( this, "form" ) ) {4613 return false;4614 }4615 // lazy-add a submit handler when a descendant form may potentially be submitted4616 jquery.event.add( this, "click._submit keypress._submit", function( e ) {4617 // node name check avoids a vml-related crash in ie (#9807)4618 var elem = e.target,4619 form = jquery.nodename( elem, "input" ) || jquery.nodename( elem, "button" ) ? elem.form : undefined;4620 if ( form && !jquery._data( form, "submitbubbles" ) ) {4621 jquery.event.add( form, "submit._submit", function( event ) {4622 event._submit_bubble = true;4623 });4624 jquery._data( form, "submitbubbles", true );4625 }4626 });4627 // return undefined since we don't need an event listener4628 },4629 postdispatch: function( event ) {4630 // if form was submitted by the user, bubble the event up the tree4631 if ( event._submit_bubble ) {4632 delete event._submit_bubble;4633 if ( this.parentnode && !event.istrigger ) {4634 jquery.event.simulate( "submit", this.parentnode, event, true );4635 }4636 }4637 },4638 teardown: function() {4639 // only need this for delegated form submit events4640 if ( jquery.nodename( this, "form" ) ) {4641 return false;4642 }4643 // remove delegated handlers; cleandata eventually reaps submit handlers attached above4644 jquery.event.remove( this, "._submit" );4645 }4646 };4647 }4648// ie change delegation and checkbox/radio fix4649 if ( !jquery.support.changebubbles ) {4650 jquery.event.special.change = {4651 setup: function() {4652 if ( rformelems.test( this.nodename ) ) {4653 // ie doesn't fire change on a check/radio until blur; trigger it on click4654 // after a propertychange. eat the blur-change in special.change.handle.4655 // this still fires onchange a second time for check/radio after blur.4656 if ( this.type === "checkbox" || this.type === "radio" ) {4657 jquery.event.add( this, "propertychange._change", function( event ) {4658 if ( event.originalevent.propertyname === "checked" ) {4659 this._just_changed = true;4660 }4661 });4662 jquery.event.add( this, "click._change", function( event ) {4663 if ( this._just_changed && !event.istrigger ) {4664 this._just_changed = false;4665 }4666 // allow triggered, simulated change events (#11500)4667 jquery.event.simulate( "change", this, event, true );4668 });4669 }4670 return false;4671 }4672 // delegated event; lazy-add a change handler on descendant inputs4673 jquery.event.add( this, "beforeactivate._change", function( e ) {4674 var elem = e.target;4675 if ( rformelems.test( elem.nodename ) && !jquery._data( elem, "changebubbles" ) ) {4676 jquery.event.add( elem, "change._change", function( event ) {4677 if ( this.parentnode && !event.issimulated && !event.istrigger ) {4678 jquery.event.simulate( "change", this.parentnode, event, true );4679 }4680 });4681 jquery._data( elem, "changebubbles", true );4682 }4683 });4684 },4685 handle: function( event ) {4686 var elem = event.target;4687 // swallow native change events from checkbox/radio, we already triggered them above4688 if ( this !== elem || event.issimulated || event.istrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {4689 return event.handleobj.handler.apply( this, arguments );4690 }4691 },4692 teardown: function() {4693 jquery.event.remove( this, "._change" );4694 return !rformelems.test( this.nodename );4695 }4696 };4697 }4698// create "bubbling" focus and blur events4699 if ( !jquery.support.focusinbubbles ) {4700 jquery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {4701 // attach a single capturing handler while someone wants focusin/focusout4702 var attaches = 0,4703 handler = function( event ) {4704 jquery.event.simulate( fix, event.target, jquery.event.fix( event ), true );4705 };4706 jquery.event.special[ fix ] = {4707 setup: function() {4708 if ( attaches++ === 0 ) {4709 document.addeventlistener( orig, handler, true );4710 }4711 },4712 teardown: function() {4713 if ( --attaches === 0 ) {4714 document.removeeventlistener( orig, handler, true );4715 }4716 }4717 };4718 });4719 }4720 jquery.fn.extend({4721 on: function( types, selector, data, fn, /*internal*/ one ) {4722 var type, origfn;4723 // types can be a map of types/handlers4724 if ( typeof types === "object" ) {4725 // ( types-object, selector, data )4726 if ( typeof selector !== "string" ) {4727 // ( types-object, data )4728 data = data || selector;4729 selector = undefined;4730 }4731 for ( type in types ) {4732 this.on( type, selector, data, types[ type ], one );4733 }4734 return this;4735 }4736 if ( data == null && fn == null ) {4737 // ( types, fn )4738 fn = selector;4739 data = selector = undefined;4740 } else if ( fn == null ) {4741 if ( typeof selector === "string" ) {4742 // ( types, selector, fn )4743 fn = data;4744 data = undefined;4745 } else {4746 // ( types, data, fn )4747 fn = data;4748 data = selector;4749 selector = undefined;4750 }4751 }4752 if ( fn === false ) {4753 fn = returnfalse;4754 } else if ( !fn ) {4755 return this;4756 }4757 if ( one === 1 ) {4758 origfn = fn;4759 fn = function( event ) {4760 // can use an empty set, since event contains the info4761 jquery().off( event );4762 return origfn.apply( this, arguments );4763 };4764 // use same guid so caller can remove using origfn4765 fn.guid = origfn.guid || ( origfn.guid = jquery.guid++ );4766 }4767 return this.each( function() {4768 jquery.event.add( this, types, fn, data, selector );4769 });4770 },4771 one: function( types, selector, data, fn ) {4772 return this.on( types, selector, data, fn, 1 );4773 },4774 off: function( types, selector, fn ) {4775 var handleobj, type;4776 if ( types && types.preventdefault && types.handleobj ) {4777 // ( event ) dispatched jquery.event4778 handleobj = types.handleobj;4779 jquery( types.delegatetarget ).off(4780 handleobj.namespace ? handleobj.origtype + "." + handleobj.namespace : handleobj.origtype,4781 handleobj.selector,4782 handleobj.handler4783 );4784 return this;4785 }4786 if ( typeof types === "object" ) {4787 // ( types-object [, selector] )4788 for ( type in types ) {4789 this.off( type, selector, types[ type ] );4790 }4791 return this;4792 }4793 if ( selector === false || typeof selector === "function" ) {4794 // ( types [, fn] )4795 fn = selector;4796 selector = undefined;4797 }4798 if ( fn === false ) {4799 fn = returnfalse;4800 }4801 return this.each(function() {4802 jquery.event.remove( this, types, fn, selector );4803 });4804 },4805 trigger: function( type, data ) {4806 return this.each(function() {4807 jquery.event.trigger( type, data, this );4808 });4809 },4810 triggerhandler: function( type, data ) {4811 var elem = this[0];4812 if ( elem ) {4813 return jquery.event.trigger( type, data, elem, true );4814 }4815 }4816 });4817 var issimple = /^.[^:#\[\.,]*$/,4818 rparentsprev = /^(?:parents|prev(?:until|all))/,4819 rneedscontext = jquery.expr.match.needscontext,4820 // methods guaranteed to produce a unique set when starting from a unique set4821 guaranteedunique = {4822 children: true,4823 contents: true,4824 next: true,4825 prev: true4826 };4827 jquery.fn.extend({4828 find: function( selector ) {4829 var i,4830 ret = [],4831 self = this,4832 len = self.length;4833 if ( typeof selector !== "string" ) {4834 return this.pushstack( jquery( selector ).filter(function() {4835 for ( i = 0; i < len; i++ ) {4836 if ( jquery.contains( self[ i ], this ) ) {4837 return true;4838 }4839 }4840 }) );4841 }4842 for ( i = 0; i < len; i++ ) {4843 jquery.find( selector, self[ i ], ret );4844 }4845 // needed because $( selector, context ) becomes $( context ).find( selector )4846 ret = this.pushstack( len > 1 ? jquery.unique( ret ) : ret );4847 ret.selector = this.selector ? this.selector + " " + selector : selector;4848 return ret;4849 },4850 has: function( target ) {4851 var i,4852 targets = jquery( target, this ),4853 len = targets.length;4854 return this.filter(function() {4855 for ( i = 0; i < len; i++ ) {4856 if ( jquery.contains( this, targets[i] ) ) {4857 return true;4858 }4859 }4860 });4861 },4862 not: function( selector ) {4863 return this.pushstack( winnow(this, selector || [], true) );4864 },4865 filter: function( selector ) {4866 return this.pushstack( winnow(this, selector || [], false) );4867 },4868 is: function( selector ) {4869 return !!winnow(4870 this,4871 // if this is a positional/relative selector, check membership in the returned set4872 // so $("p:first").is("p:last") won't return true for a doc with two "p".4873 typeof selector === "string" && rneedscontext.test( selector ) ?4874 jquery( selector ) :4875 selector || [],4876 false4877 ).length;4878 },4879 closest: function( selectors, context ) {4880 var cur,4881 i = 0,4882 l = this.length,4883 ret = [],4884 pos = rneedscontext.test( selectors ) || typeof selectors !== "string" ?4885 jquery( selectors, context || this.context ) :4886 0;4887 for ( ; i < l; i++ ) {4888 for ( cur = this[i]; cur && cur !== context; cur = cur.parentnode ) {4889 // always skip document fragments4890 if ( cur.nodetype < 11 && (pos ?4891 pos.index(cur) > -1 :4892 // don't pass non-elements to sizzle4893 cur.nodetype === 1 &&4894 jquery.find.matchesselector(cur, selectors)) ) {4895 cur = ret.push( cur );4896 break;4897 }4898 }4899 }4900 return this.pushstack( ret.length > 1 ? jquery.unique( ret ) : ret );4901 },4902 // determine the position of an element within4903 // the matched set of elements4904 index: function( elem ) {4905 // no argument, return index in parent4906 if ( !elem ) {4907 return ( this[0] && this[0].parentnode ) ? this.first().prevall().length : -1;4908 }4909 // index in selector4910 if ( typeof elem === "string" ) {4911 return jquery.inarray( this[0], jquery( elem ) );4912 }4913 // locate the position of the desired element4914 return jquery.inarray(4915 // if it receives a jquery object, the first element is used4916 elem.jquery ? elem[0] : elem, this );4917 },4918 add: function( selector, context ) {4919 var set = typeof selector === "string" ?4920 jquery( selector, context ) :4921 jquery.makearray( selector && selector.nodetype ? [ selector ] : selector ),4922 all = jquery.merge( this.get(), set );4923 return this.pushstack( jquery.unique(all) );4924 },4925 addback: function( selector ) {4926 return this.add( selector == null ?4927 this.prevobject : this.prevobject.filter(selector)4928 );4929 }4930 });4931 function sibling( cur, dir ) {4932 do {4933 cur = cur[ dir ];4934 } while ( cur && cur.nodetype !== 1 );4935 return cur;4936 }4937 jquery.each({4938 parent: function( elem ) {4939 var parent = elem.parentnode;4940 return parent && parent.nodetype !== 11 ? parent : null;4941 },4942 parents: function( elem ) {4943 return jquery.dir( elem, "parentnode" );4944 },4945 parentsuntil: function( elem, i, until ) {4946 return jquery.dir( elem, "parentnode", until );4947 },4948 next: function( elem ) {4949 return sibling( elem, "nextsibling" );4950 },4951 prev: function( elem ) {4952 return sibling( elem, "previoussibling" );4953 },4954 nextall: function( elem ) {4955 return jquery.dir( elem, "nextsibling" );4956 },4957 prevall: function( elem ) {4958 return jquery.dir( elem, "previoussibling" );4959 },4960 nextuntil: function( elem, i, until ) {4961 return jquery.dir( elem, "nextsibling", until );4962 },4963 prevuntil: function( elem, i, until ) {4964 return jquery.dir( elem, "previoussibling", until );4965 },4966 siblings: function( elem ) {4967 return jquery.sibling( ( elem.parentnode || {} ).firstchild, elem );4968 },4969 children: function( elem ) {4970 return jquery.sibling( elem.firstchild );4971 },4972 contents: function( elem ) {4973 return jquery.nodename( elem, "iframe" ) ?4974 elem.contentdocument || elem.contentwindow.document :4975 jquery.merge( [], elem.childnodes );4976 }4977 }, function( name, fn ) {4978 jquery.fn[ name ] = function( until, selector ) {4979 var ret = jquery.map( this, fn, until );4980 if ( name.slice( -5 ) !== "until" ) {4981 selector = until;4982 }4983 if ( selector && typeof selector === "string" ) {4984 ret = jquery.filter( selector, ret );4985 }4986 if ( this.length > 1 ) {4987 // remove duplicates4988 if ( !guaranteedunique[ name ] ) {4989 ret = jquery.unique( ret );4990 }4991 // reverse order for parents* and prev-derivatives4992 if ( rparentsprev.test( name ) ) {4993 ret = ret.reverse();4994 }4995 }4996 return this.pushstack( ret );4997 };4998 });4999 jquery.extend({5000 filter: function( expr, elems, not ) {5001 var elem = elems[ 0 ];5002 if ( not ) {5003 expr = ":not(" + expr + ")";5004 }5005 return elems.length === 1 && elem.nodetype === 1 ?5006 jquery.find.matchesselector( elem, expr ) ? [ elem ] : [] :5007 jquery.find.matches( expr, jquery.grep( elems, function( elem ) {5008 return elem.nodetype === 1;5009 }));5010 },5011 dir: function( elem, dir, until ) {5012 var matched = [],5013 cur = elem[ dir ];5014 while ( cur && cur.nodetype !== 9 && (until === undefined || cur.nodetype !== 1 || !jquery( cur ).is( until )) ) {5015 if ( cur.nodetype === 1 ) {5016 matched.push( cur );5017 }5018 cur = cur[dir];5019 }5020 return matched;5021 },5022 sibling: function( n, elem ) {5023 var r = [];5024 for ( ; n; n = n.nextsibling ) {5025 if ( n.nodetype === 1 && n !== elem ) {5026 r.push( n );5027 }5028 }5029 return r;5030 }5031 });5032// implement the identical functionality for filter and not5033 function winnow( elements, qualifier, not ) {5034 if ( jquery.isfunction( qualifier ) ) {5035 return jquery.grep( elements, function( elem, i ) {5036 /* jshint -w018 */5037 return !!qualifier.call( elem, i, elem ) !== not;5038 });5039 }5040 if ( qualifier.nodetype ) {5041 return jquery.grep( elements, function( elem ) {5042 return ( elem === qualifier ) !== not;5043 });5044 }5045 if ( typeof qualifier === "string" ) {5046 if ( issimple.test( qualifier ) ) {5047 return jquery.filter( qualifier, elements, not );5048 }5049 qualifier = jquery.filter( qualifier, elements );5050 }5051 return jquery.grep( elements, function( elem ) {5052 return ( jquery.inarray( elem, qualifier ) >= 0 ) !== not;5053 });5054 }5055 function createsafefragment( document ) {5056 var list = nodenames.split( "|" ),5057 safefrag = document.createdocumentfragment();5058 if ( safefrag.createelement ) {5059 while ( list.length ) {5060 safefrag.createelement(5061 list.pop()5062 );5063 }5064 }5065 return safefrag;5066 }5067 var nodenames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +5068 "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",5069 rinlinejquery = / jquery\d+="(?:null|\d+)"/g,5070 rnoshimcache = new regexp("<(?:" + nodenames + ")[\\s/>]", "i"),5071 rleadingwhitespace = /^\s+/,5072 rxhtmltag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,5073 rtagname = /<([\w:]+)/,5074 rtbody = /<tbody/i,5075 rhtml = /<|&#?\w+;/,5076 rnoinnerhtml = /<(?:script|style|link)/i,5077 manipulation_rcheckabletype = /^(?:checkbox|radio)$/i,5078 // checked="checked" or checked5079 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,5080 rscripttype = /^$|\/(?:java|ecma)script/i,5081 rscripttypemasked = /^true\/(.*)/,5082 rcleanscript = /^\s*<!(?:\[cdata\[|--)|(?:\]\]|--)>\s*$/g,5083 // we have to close these tags to support xhtml (#13200)5084 wrapmap = {5085 option: [ 1, "<select multiple='multiple'>", "</select>" ],5086 legend: [ 1, "<fieldset>", "</fieldset>" ],5087 area: [ 1, "<map>", "</map>" ],5088 param: [ 1, "<object>", "</object>" ],5089 thead: [ 1, "<table>", "</table>" ],5090 tr: [ 2, "<table><tbody>", "</tbody></table>" ],5091 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],5092 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],5093 // ie6-8 can't serialize link, script, style, or any html5 (noscope) tags,5094 // unless wrapped in a div with non-breaking characters in front of it.5095 _default: jquery.support.htmlserialize ? [ 0, "", "" ] : [ 1, "x<div>", "</div>" ]5096 },5097 safefragment = createsafefragment( document ),5098 fragmentdiv = safefragment.appendchild( document.createelement("div") );5099 wrapmap.optgroup = wrapmap.option;5100 wrapmap.tbody = wrapmap.tfoot = wrapmap.colgroup = wrapmap.caption = wrapmap.thead;5101 wrapmap.th = wrapmap.td;5102 jquery.fn.extend({5103 text: function( value ) {5104 return jquery.access( this, function( value ) {5105 return value === undefined ?5106 jquery.text( this ) :5107 this.empty().append( ( this[0] && this[0].ownerdocument || document ).createtextnode( value ) );5108 }, null, value, arguments.length );5109 },5110 append: function() {5111 return this.dommanip( arguments, function( elem ) {5112 if ( this.nodetype === 1 || this.nodetype === 11 || this.nodetype === 9 ) {5113 var target = manipulationtarget( this, elem );5114 target.appendchild( elem );5115 }5116 });5117 },5118 prepend: function() {5119 return this.dommanip( arguments, function( elem ) {5120 if ( this.nodetype === 1 || this.nodetype === 11 || this.nodetype === 9 ) {5121 var target = manipulationtarget( this, elem );5122 target.insertbefore( elem, target.firstchild );5123 }5124 });5125 },5126 before: function() {5127 return this.dommanip( arguments, function( elem ) {5128 if ( this.parentnode ) {5129 this.parentnode.insertbefore( elem, this );5130 }5131 });5132 },5133 after: function() {5134 return this.dommanip( arguments, function( elem ) {5135 if ( this.parentnode ) {5136 this.parentnode.insertbefore( elem, this.nextsibling );5137 }5138 });5139 },5140 // keepdata is for internal use only--do not document5141 remove: function( selector, keepdata ) {5142 var elem,5143 elems = selector ? jquery.filter( selector, this ) : this,5144 i = 0;5145 for ( ; (elem = elems[i]) != null; i++ ) {5146 if ( !keepdata && elem.nodetype === 1 ) {5147 jquery.cleandata( getall( elem ) );5148 }5149 if ( elem.parentnode ) {5150 if ( keepdata && jquery.contains( elem.ownerdocument, elem ) ) {5151 setglobaleval( getall( elem, "script" ) );5152 }5153 elem.parentnode.removechild( elem );5154 }5155 }5156 return this;5157 },5158 empty: function() {5159 var elem,5160 i = 0;5161 for ( ; (elem = this[i]) != null; i++ ) {5162 // remove element nodes and prevent memory leaks5163 if ( elem.nodetype === 1 ) {5164 jquery.cleandata( getall( elem, false ) );5165 }5166 // remove any remaining nodes5167 while ( elem.firstchild ) {5168 elem.removechild( elem.firstchild );5169 }5170 // if this is a select, ensure that it displays empty (#12336)5171 // support: ie<95172 if ( elem.options && jquery.nodename( elem, "select" ) ) {5173 elem.options.length = 0;5174 }5175 }5176 return this;5177 },5178 clone: function( dataandevents, deepdataandevents ) {5179 dataandevents = dataandevents == null ? false : dataandevents;5180 deepdataandevents = deepdataandevents == null ? dataandevents : deepdataandevents;5181 return this.map( function () {5182 return jquery.clone( this, dataandevents, deepdataandevents );5183 });5184 },5185 html: function( value ) {5186 return jquery.access( this, function( value ) {5187 var elem = this[0] || {},5188 i = 0,5189 l = this.length;5190 if ( value === undefined ) {5191 return elem.nodetype === 1 ?5192 elem.innerhtml.replace( rinlinejquery, "" ) :5193 undefined;5194 }5195 // see if we can take a shortcut and just use innerhtml5196 if ( typeof value === "string" && !rnoinnerhtml.test( value ) &&5197 ( jquery.support.htmlserialize || !rnoshimcache.test( value ) ) &&5198 ( jquery.support.leadingwhitespace || !rleadingwhitespace.test( value ) ) &&5199 !wrapmap[ ( rtagname.exec( value ) || ["", ""] )[1].tolowercase() ] ) {5200 value = value.replace( rxhtmltag, "<$1></$2>" );5201 try {5202 for (; i < l; i++ ) {5203 // remove element nodes and prevent memory leaks5204 elem = this[i] || {};5205 if ( elem.nodetype === 1 ) {5206 jquery.cleandata( getall( elem, false ) );5207 elem.innerhtml = value;5208 }5209 }5210 elem = 0;5211 // if using innerhtml throws an exception, use the fallback method5212 } catch(e) {}5213 }5214 if ( elem ) {5215 this.empty().append( value );5216 }5217 }, null, value, arguments.length );5218 },5219 replacewith: function() {5220 var5221 // snapshot the dom in case .dommanip sweeps something relevant into its fragment5222 args = jquery.map( this, function( elem ) {5223 return [ elem.nextsibling, elem.parentnode ];5224 }),5225 i = 0;5226 // make the changes, replacing each context element with the new content5227 this.dommanip( arguments, function( elem ) {5228 var next = args[ i++ ],5229 parent = args[ i++ ];5230 if ( parent ) {5231 // don't use the snapshot next if it has moved (#13810)5232 if ( next && next.parentnode !== parent ) {5233 next = this.nextsibling;5234 }5235 jquery( this ).remove();5236 parent.insertbefore( elem, next );5237 }5238 // allow new content to include elements from the context set5239 }, true );5240 // force removal if there was no new content (e.g., from empty arguments)5241 return i ? this : this.remove();5242 },5243 detach: function( selector ) {5244 return this.remove( selector, true );5245 },5246 dommanip: function( args, callback, allowintersection ) {5247 // flatten any nested arrays5248 args = core_concat.apply( [], args );5249 var first, node, hasscripts,5250 scripts, doc, fragment,5251 i = 0,5252 l = this.length,5253 set = this,5254 inoclone = l - 1,5255 value = args[0],5256 isfunction = jquery.isfunction( value );5257 // we can't clonenode fragments that contain checked, in webkit5258 if ( isfunction || !( l <= 1 || typeof value !== "string" || jquery.support.checkclone || !rchecked.test( value ) ) ) {5259 return this.each(function( index ) {5260 var self = set.eq( index );5261 if ( isfunction ) {5262 args[0] = value.call( this, index, self.html() );5263 }5264 self.dommanip( args, callback, allowintersection );5265 });5266 }5267 if ( l ) {5268 fragment = jquery.buildfragment( args, this[ 0 ].ownerdocument, false, !allowintersection && this );5269 first = fragment.firstchild;5270 if ( fragment.childnodes.length === 1 ) {5271 fragment = first;5272 }5273 if ( first ) {5274 scripts = jquery.map( getall( fragment, "script" ), disablescript );5275 hasscripts = scripts.length;5276 // use the original fragment for the last item instead of the first because it can end up5277 // being emptied incorrectly in certain situations (#8070).5278 for ( ; i < l; i++ ) {5279 node = fragment;5280 if ( i !== inoclone ) {5281 node = jquery.clone( node, true, true );5282 // keep references to cloned scripts for later restoration5283 if ( hasscripts ) {5284 jquery.merge( scripts, getall( node, "script" ) );5285 }5286 }5287 callback.call( this[i], node, i );5288 }5289 if ( hasscripts ) {5290 doc = scripts[ scripts.length - 1 ].ownerdocument;5291 // reenable scripts5292 jquery.map( scripts, restorescript );5293 // evaluate executable scripts on first document insertion5294 for ( i = 0; i < hasscripts; i++ ) {5295 node = scripts[ i ];5296 if ( rscripttype.test( node.type || "" ) &&5297 !jquery._data( node, "globaleval" ) && jquery.contains( doc, node ) ) {5298 if ( node.src ) {5299 // hope ajax is available...5300 jquery._evalurl( node.src );5301 } else {5302 jquery.globaleval( ( node.text || node.textcontent || node.innerhtml || "" ).replace( rcleanscript, "" ) );5303 }5304 }5305 }5306 }5307 // fix #11809: avoid leaking memory5308 fragment = first = null;5309 }5310 }5311 return this;5312 }5313 });5314// support: ie<85315// manipulating tables requires a tbody5316 function manipulationtarget( elem, content ) {5317 return jquery.nodename( elem, "table" ) &&5318 jquery.nodename( content.nodetype === 1 ? content : content.firstchild, "tr" ) ?5319 elem.getelementsbytagname("tbody")[0] ||5320 elem.appendchild( elem.ownerdocument.createelement("tbody") ) :5321 elem;5322 }5323// replace/restore the type attribute of script elements for safe dom manipulation5324 function disablescript( elem ) {5325 elem.type = (jquery.find.attr( elem, "type" ) !== null) + "/" + elem.type;5326 return elem;5327 }5328 function restorescript( elem ) {5329 var match = rscripttypemasked.exec( elem.type );5330 if ( match ) {5331 elem.type = match[1];5332 } else {5333 elem.removeattribute("type");5334 }5335 return elem;5336 }5337// mark scripts as having already been evaluated5338 function setglobaleval( elems, refelements ) {5339 var elem,5340 i = 0;5341 for ( ; (elem = elems[i]) != null; i++ ) {5342 jquery._data( elem, "globaleval", !refelements || jquery._data( refelements[i], "globaleval" ) );5343 }5344 }5345 function clonecopyevent( src, dest ) {5346 if ( dest.nodetype !== 1 || !jquery.hasdata( src ) ) {5347 return;5348 }5349 var type, i, l,5350 olddata = jquery._data( src ),5351 curdata = jquery._data( dest, olddata ),5352 events = olddata.events;5353 if ( events ) {5354 delete curdata.handle;5355 curdata.events = {};5356 for ( type in events ) {5357 for ( i = 0, l = events[ type ].length; i < l; i++ ) {5358 jquery.event.add( dest, type, events[ type ][ i ] );5359 }5360 }5361 }5362 // make the cloned public data object a copy from the original5363 if ( curdata.data ) {5364 curdata.data = jquery.extend( {}, curdata.data );5365 }5366 }5367 function fixclonenodeissues( src, dest ) {5368 var nodename, e, data;5369 // we do not need to do anything for non-elements5370 if ( dest.nodetype !== 1 ) {5371 return;5372 }5373 nodename = dest.nodename.tolowercase();5374 // ie6-8 copies events bound via attachevent when using clonenode.5375 if ( !jquery.support.nocloneevent && dest[ jquery.expando ] ) {5376 data = jquery._data( dest );5377 for ( e in data.events ) {5378 jquery.removeevent( dest, e, data.handle );5379 }5380 // event data gets referenced instead of copied if the expando gets copied too5381 dest.removeattribute( jquery.expando );5382 }5383 // ie blanks contents when cloning scripts, and tries to evaluate newly-set text5384 if ( nodename === "script" && dest.text !== src.text ) {5385 disablescript( dest ).text = src.text;5386 restorescript( dest );5387 // ie6-10 improperly clones children of object elements using classid.5388 // ie10 throws nomodificationallowederror if parent is null, #12132.5389 } else if ( nodename === "object" ) {5390 if ( dest.parentnode ) {5391 dest.outerhtml = src.outerhtml;5392 }5393 // this path appears unavoidable for ie9. when cloning an object5394 // element in ie9, the outerhtml strategy above is not sufficient.5395 // if the src has innerhtml and the destination does not,5396 // copy the src.innerhtml into the dest.innerhtml. #103245397 if ( jquery.support.html5clone && ( src.innerhtml && !jquery.trim(dest.innerhtml) ) ) {5398 dest.innerhtml = src.innerhtml;5399 }5400 } else if ( nodename === "input" && manipulation_rcheckabletype.test( src.type ) ) {5401 // ie6-8 fails to persist the checked state of a cloned checkbox5402 // or radio button. worse, ie6-7 fail to give the cloned element5403 // a checked appearance if the defaultchecked value isn't also set5404 dest.defaultchecked = dest.checked = src.checked;5405 // ie6-7 get confused and end up setting the value of a cloned5406 // checkbox/radio button to an empty string instead of "on"5407 if ( dest.value !== src.value ) {5408 dest.value = src.value;5409 }5410 // ie6-8 fails to return the selected option to the default selected5411 // state when cloning options5412 } else if ( nodename === "option" ) {5413 dest.defaultselected = dest.selected = src.defaultselected;5414 // ie6-8 fails to set the defaultvalue to the correct value when5415 // cloning other types of input fields5416 } else if ( nodename === "input" || nodename === "textarea" ) {5417 dest.defaultvalue = src.defaultvalue;5418 }5419 }5420 jquery.each({5421 appendto: "append",5422 prependto: "prepend",5423 insertbefore: "before",5424 insertafter: "after",5425 replaceall: "replacewith"5426 }, function( name, original ) {5427 jquery.fn[ name ] = function( selector ) {5428 var elems,5429 i = 0,5430 ret = [],5431 insert = jquery( selector ),5432 last = insert.length - 1;5433 for ( ; i <= last; i++ ) {5434 elems = i === last ? this : this.clone(true);5435 jquery( insert[i] )[ original ]( elems );5436 // modern browsers can apply jquery collections as arrays, but oldie needs a .get()5437 core_push.apply( ret, elems.get() );5438 }5439 return this.pushstack( ret );5440 };5441 });5442 function getall( context, tag ) {5443 var elems, elem,5444 i = 0,5445 found = typeof context.getelementsbytagname !== core_strundefined ? context.getelementsbytagname( tag || "*" ) :5446 typeof context.queryselectorall !== core_strundefined ? context.queryselectorall( tag || "*" ) :5447 undefined;5448 if ( !found ) {5449 for ( found = [], elems = context.childnodes || context; (elem = elems[i]) != null; i++ ) {5450 if ( !tag || jquery.nodename( elem, tag ) ) {5451 found.push( elem );5452 } else {5453 jquery.merge( found, getall( elem, tag ) );5454 }5455 }5456 }5457 return tag === undefined || tag && jquery.nodename( context, tag ) ?5458 jquery.merge( [ context ], found ) :5459 found;5460 }5461// used in buildfragment, fixes the defaultchecked property5462 function fixdefaultchecked( elem ) {5463 if ( manipulation_rcheckabletype.test( elem.type ) ) {5464 elem.defaultchecked = elem.checked;5465 }5466 }5467 jquery.extend({5468 clone: function( elem, dataandevents, deepdataandevents ) {5469 var destelements, node, clone, i, srcelements,5470 inpage = jquery.contains( elem.ownerdocument, elem );5471 if ( jquery.support.html5clone || jquery.isxmldoc(elem) || !rnoshimcache.test( "<" + elem.nodename + ">" ) ) {5472 clone = elem.clonenode( true );5473 // ie<=8 does not properly clone detached, unknown element nodes5474 } else {5475 fragmentdiv.innerhtml = elem.outerhtml;5476 fragmentdiv.removechild( clone = fragmentdiv.firstchild );5477 }5478 if ( (!jquery.support.nocloneevent || !jquery.support.noclonechecked) &&5479 (elem.nodetype === 1 || elem.nodetype === 11) && !jquery.isxmldoc(elem) ) {5480 // we eschew sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/25481 destelements = getall( clone );5482 srcelements = getall( elem );5483 // fix all ie cloning issues5484 for ( i = 0; (node = srcelements[i]) != null; ++i ) {5485 // ensure that the destination node is not null; fixes #95875486 if ( destelements[i] ) {5487 fixclonenodeissues( node, destelements[i] );5488 }5489 }5490 }5491 // copy the events from the original to the clone5492 if ( dataandevents ) {5493 if ( deepdataandevents ) {5494 srcelements = srcelements || getall( elem );5495 destelements = destelements || getall( clone );5496 for ( i = 0; (node = srcelements[i]) != null; i++ ) {5497 clonecopyevent( node, destelements[i] );5498 }5499 } else {5500 clonecopyevent( elem, clone );5501 }5502 }5503 // preserve script evaluation history5504 destelements = getall( clone, "script" );5505 if ( destelements.length > 0 ) {5506 setglobaleval( destelements, !inpage && getall( elem, "script" ) );5507 }5508 destelements = srcelements = node = null;5509 // return the cloned set5510 return clone;5511 },5512 buildfragment: function( elems, context, scripts, selection ) {5513 var j, elem, contains,5514 tmp, tag, tbody, wrap,5515 l = elems.length,5516 // ensure a safe fragment5517 safe = createsafefragment( context ),5518 nodes = [],5519 i = 0;5520 for ( ; i < l; i++ ) {5521 elem = elems[ i ];5522 if ( elem || elem === 0 ) {5523 // add nodes directly5524 if ( jquery.type( elem ) === "object" ) {5525 jquery.merge( nodes, elem.nodetype ? [ elem ] : elem );5526 // convert non-html into a text node5527 } else if ( !rhtml.test( elem ) ) {5528 nodes.push( context.createtextnode( elem ) );5529 // convert html into dom nodes5530 } else {5531 tmp = tmp || safe.appendchild( context.createelement("div") );5532 // deserialize a standard representation5533 tag = ( rtagname.exec( elem ) || ["", ""] )[1].tolowercase();5534 wrap = wrapmap[ tag ] || wrapmap._default;5535 tmp.innerhtml = wrap[1] + elem.replace( rxhtmltag, "<$1></$2>" ) + wrap[2];5536 // descend through wrappers to the right content5537 j = wrap[0];5538 while ( j-- ) {5539 tmp = tmp.lastchild;5540 }5541 // manually add leading whitespace removed by ie5542 if ( !jquery.support.leadingwhitespace && rleadingwhitespace.test( elem ) ) {5543 nodes.push( context.createtextnode( rleadingwhitespace.exec( elem )[0] ) );5544 }5545 // remove ie's autoinserted <tbody> from table fragments5546 if ( !jquery.support.tbody ) {5547 // string was a <table>, *may* have spurious <tbody>5548 elem = tag === "table" && !rtbody.test( elem ) ?5549 tmp.firstchild :5550 // string was a bare <thead> or <tfoot>5551 wrap[1] === "<table>" && !rtbody.test( elem ) ?5552 tmp :5553 0;5554 j = elem && elem.childnodes.length;5555 while ( j-- ) {5556 if ( jquery.nodename( (tbody = elem.childnodes[j]), "tbody" ) && !tbody.childnodes.length ) {5557 elem.removechild( tbody );5558 }5559 }5560 }5561 jquery.merge( nodes, tmp.childnodes );5562 // fix #12392 for webkit and ie > 95563 tmp.textcontent = "";5564 // fix #12392 for oldie5565 while ( tmp.firstchild ) {5566 tmp.removechild( tmp.firstchild );5567 }5568 // remember the top-level container for proper cleanup5569 tmp = safe.lastchild;5570 }5571 }5572 }5573 // fix #11356: clear elements from fragment5574 if ( tmp ) {5575 safe.removechild( tmp );5576 }5577 // reset defaultchecked for any radios and checkboxes5578 // about to be appended to the dom in ie 6/7 (#8060)5579 if ( !jquery.support.appendchecked ) {5580 jquery.grep( getall( nodes, "input" ), fixdefaultchecked );5581 }5582 i = 0;5583 while ( (elem = nodes[ i++ ]) ) {5584 // #4087 - if origin and destination elements are the same, and this is5585 // that element, do not do anything5586 if ( selection && jquery.inarray( elem, selection ) !== -1 ) {5587 continue;5588 }5589 contains = jquery.contains( elem.ownerdocument, elem );5590 // append to fragment5591 tmp = getall( safe.appendchild( elem ), "script" );5592 // preserve script evaluation history5593 if ( contains ) {5594 setglobaleval( tmp );5595 }5596 // capture executables5597 if ( scripts ) {5598 j = 0;5599 while ( (elem = tmp[ j++ ]) ) {5600 if ( rscripttype.test( elem.type || "" ) ) {5601 scripts.push( elem );5602 }5603 }5604 }5605 }5606 tmp = null;5607 return safe;5608 },5609 cleandata: function( elems, /* internal */ acceptdata ) {5610 var elem, type, id, data,5611 i = 0,5612 internalkey = jquery.expando,5613 cache = jquery.cache,5614 deleteexpando = jquery.support.deleteexpando,5615 special = jquery.event.special;5616 for ( ; (elem = elems[i]) != null; i++ ) {5617 if ( acceptdata || jquery.acceptdata( elem ) ) {5618 id = elem[ internalkey ];5619 data = id && cache[ id ];5620 if ( data ) {5621 if ( data.events ) {5622 for ( type in data.events ) {5623 if ( special[ type ] ) {5624 jquery.event.remove( elem, type );5625 // this is a shortcut to avoid jquery.event.remove's overhead5626 } else {5627 jquery.removeevent( elem, type, data.handle );5628 }5629 }5630 }5631 // remove cache only if it was not already removed by jquery.event.remove5632 if ( cache[ id ] ) {5633 delete cache[ id ];5634 // ie does not allow us to delete expando properties from nodes,5635 // nor does it have a removeattribute function on document nodes;5636 // we must handle all of these cases5637 if ( deleteexpando ) {5638 delete elem[ internalkey ];5639 } else if ( typeof elem.removeattribute !== core_strundefined ) {5640 elem.removeattribute( internalkey );5641 } else {5642 elem[ internalkey ] = null;5643 }5644 core_deletedids.push( id );5645 }5646 }5647 }5648 }5649 },5650 _evalurl: function( url ) {5651 return jquery.ajax({5652 url: url,5653 type: "get",5654 datatype: "script",5655 async: false,5656 global: false,5657 "throws": true5658 });5659 }5660 });5661 jquery.fn.extend({5662 wrapall: function( html ) {5663 if ( jquery.isfunction( html ) ) {5664 return this.each(function(i) {5665 jquery(this).wrapall( html.call(this, i) );5666 });5667 }5668 if ( this[0] ) {5669 // the elements to wrap the target around5670 var wrap = jquery( html, this[0].ownerdocument ).eq(0).clone(true);5671 if ( this[0].parentnode ) {5672 wrap.insertbefore( this[0] );5673 }5674 wrap.map(function() {5675 var elem = this;5676 while ( elem.firstchild && elem.firstchild.nodetype === 1 ) {5677 elem = elem.firstchild;5678 }5679 return elem;5680 }).append( this );5681 }5682 return this;5683 },5684 wrapinner: function( html ) {5685 if ( jquery.isfunction( html ) ) {5686 return this.each(function(i) {5687 jquery(this).wrapinner( html.call(this, i) );5688 });5689 }5690 return this.each(function() {5691 var self = jquery( this ),5692 contents = self.contents();5693 if ( contents.length ) {5694 contents.wrapall( html );5695 } else {5696 self.append( html );5697 }5698 });5699 },5700 wrap: function( html ) {5701 var isfunction = jquery.isfunction( html );5702 return this.each(function(i) {5703 jquery( this ).wrapall( isfunction ? html.call(this, i) : html );5704 });5705 },5706 unwrap: function() {5707 return this.parent().each(function() {5708 if ( !jquery.nodename( this, "body" ) ) {5709 jquery( this ).replacewith( this.childnodes );5710 }5711 }).end();5712 }5713 });5714 var iframe, getstyles, curcss,5715 ralpha = /alpha\([^)]*\)/i,5716 ropacity = /opacity\s*=\s*([^)]*)/,5717 rposition = /^(top|right|bottom|left)$/,5718 // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"5719 // see here for display values: https://developer.mozilla.org/en-us/docs/css/display5720 rdisplayswap = /^(none|table(?!-c[ea]).+)/,5721 rmargin = /^margin/,5722 rnumsplit = new regexp( "^(" + core_pnum + ")(.*)$", "i" ),5723 rnumnonpx = new regexp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ),5724 rrelnum = new regexp( "^([+-])=(" + core_pnum + ")", "i" ),5725 elemdisplay = { body: "block" },5726 cssshow = { position: "absolute", visibility: "hidden", display: "block" },5727 cssnormaltransform = {5728 letterspacing: 0,5729 fontweight: 4005730 },5731 cssexpand = [ "top", "right", "bottom", "left" ],5732 cssprefixes = [ "webkit", "o", "moz", "ms" ];5733// return a css property mapped to a potentially vendor prefixed property5734 function vendorpropname( style, name ) {5735 // shortcut for names that are not vendor prefixed5736 if ( name in style ) {5737 return name;5738 }5739 // check for vendor prefixed names5740 var capname = name.charat(0).touppercase() + name.slice(1),5741 origname = name,5742 i = cssprefixes.length;5743 while ( i-- ) {5744 name = cssprefixes[ i ] + capname;5745 if ( name in style ) {5746 return name;5747 }5748 }5749 return origname;5750 }5751 function ishidden( elem, el ) {5752 // ishidden might be called from jquery#filter function;5753 // in that case, element will be second argument5754 elem = el || elem;5755 return jquery.css( elem, "display" ) === "none" || !jquery.contains( elem.ownerdocument, elem );5756 }5757 function showhide( elements, show ) {5758 var display, elem, hidden,5759 values = [],5760 index = 0,5761 length = elements.length;5762 for ( ; index < length; index++ ) {5763 elem = elements[ index ];5764 if ( !elem.style ) {5765 continue;5766 }5767 values[ index ] = jquery._data( elem, "olddisplay" );5768 display = elem.style.display;5769 if ( show ) {5770 // reset the inline display of this element to learn if it is5771 // being hidden by cascaded rules or not5772 if ( !values[ index ] && display === "none" ) {5773 elem.style.display = "";5774 }5775 // set elements which have been overridden with display: none5776 // in a stylesheet to whatever the default browser style is5777 // for such an element5778 if ( elem.style.display === "" && ishidden( elem ) ) {5779 values[ index ] = jquery._data( elem, "olddisplay", css_defaultdisplay(elem.nodename) );5780 }5781 } else {5782 if ( !values[ index ] ) {5783 hidden = ishidden( elem );5784 if ( display && display !== "none" || !hidden ) {5785 jquery._data( elem, "olddisplay", hidden ? display : jquery.css( elem, "display" ) );5786 }5787 }5788 }5789 }5790 // set the display of most of the elements in a second loop5791 // to avoid the constant reflow5792 for ( index = 0; index < length; index++ ) {5793 elem = elements[ index ];5794 if ( !elem.style ) {5795 continue;5796 }5797 if ( !show || elem.style.display === "none" || elem.style.display === "" ) {5798 elem.style.display = show ? values[ index ] || "" : "none";5799 }5800 }5801 return elements;5802 }5803 jquery.fn.extend({5804 css: function( name, value ) {5805 return jquery.access( this, function( elem, name, value ) {5806 var len, styles,5807 map = {},5808 i = 0;5809 if ( jquery.isarray( name ) ) {5810 styles = getstyles( elem );5811 len = name.length;5812 for ( ; i < len; i++ ) {5813 map[ name[ i ] ] = jquery.css( elem, name[ i ], false, styles );5814 }5815 return map;5816 }5817 return value !== undefined ?5818 jquery.style( elem, name, value ) :5819 jquery.css( elem, name );5820 }, name, value, arguments.length > 1 );5821 },5822 show: function() {5823 return showhide( this, true );5824 },5825 hide: function() {5826 return showhide( this );5827 },5828 toggle: function( state ) {5829 if ( typeof state === "boolean" ) {5830 return state ? this.show() : this.hide();5831 }5832 return this.each(function() {5833 if ( ishidden( this ) ) {5834 jquery( this ).show();5835 } else {5836 jquery( this ).hide();5837 }5838 });5839 }5840 });5841 jquery.extend({5842 // add in style property hooks for overriding the default5843 // behavior of getting and setting a style property5844 csshooks: {5845 opacity: {5846 get: function( elem, computed ) {5847 if ( computed ) {5848 // we should always get a number back from opacity5849 var ret = curcss( elem, "opacity" );5850 return ret === "" ? "1" : ret;5851 }5852 }5853 }5854 },5855 // don't automatically add "px" to these possibly-unitless properties5856 cssnumber: {5857 "columncount": true,5858 "fillopacity": true,5859 "fontweight": true,5860 "lineheight": true,5861 "opacity": true,5862 "order": true,5863 "orphans": true,5864 "widows": true,5865 "zindex": true,5866 "zoom": true5867 },5868 // add in properties whose names you wish to fix before5869 // setting or getting the value5870 cssprops: {5871 // normalize float css property5872 "float": jquery.support.cssfloat ? "cssfloat" : "stylefloat"5873 },5874 // get and set the style property on a dom node5875 style: function( elem, name, value, extra ) {5876 // don't set styles on text and comment nodes5877 if ( !elem || elem.nodetype === 3 || elem.nodetype === 8 || !elem.style ) {5878 return;5879 }5880 // make sure that we're working with the right name5881 var ret, type, hooks,5882 origname = jquery.camelcase( name ),5883 style = elem.style;5884 name = jquery.cssprops[ origname ] || ( jquery.cssprops[ origname ] = vendorpropname( style, origname ) );5885 // gets hook for the prefixed version5886 // followed by the unprefixed version5887 hooks = jquery.csshooks[ name ] || jquery.csshooks[ origname ];5888 // check if we're setting a value5889 if ( value !== undefined ) {5890 type = typeof value;5891 // convert relative number strings (+= or -=) to relative numbers. #73455892 if ( type === "string" && (ret = rrelnum.exec( value )) ) {5893 value = ( ret[1] + 1 ) * ret[2] + parsefloat( jquery.css( elem, name ) );5894 // fixes bug #92375895 type = "number";5896 }5897 // make sure that nan and null values aren't set. see: #71165898 if ( value == null || type === "number" && isnan( value ) ) {5899 return;5900 }5901 // if a number was passed in, add 'px' to the (except for certain css properties)5902 if ( type === "number" && !jquery.cssnumber[ origname ] ) {5903 value += "px";5904 }5905 // fixes #8908, it can be done more correctly by specifing setters in csshooks,5906 // but it would mean to define eight (for every problematic property) identical functions5907 if ( !jquery.support.clearclonestyle && value === "" && name.indexof("background") === 0 ) {5908 style[ name ] = "inherit";5909 }5910 // if a hook was provided, use that value, otherwise just set the specified value5911 if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {5912 // wrapped to prevent ie from throwing errors when 'invalid' values are provided5913 // fixes bug #55095914 try {5915 style[ name ] = value;5916 } catch(e) {}5917 }5918 } else {5919 // if a hook was provided get the non-computed value from there5920 if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {5921 return ret;5922 }5923 // otherwise just get the value from the style object5924 return style[ name ];5925 }5926 },5927 css: function( elem, name, extra, styles ) {5928 var num, val, hooks,5929 origname = jquery.camelcase( name );5930 // make sure that we're working with the right name5931 name = jquery.cssprops[ origname ] || ( jquery.cssprops[ origname ] = vendorpropname( elem.style, origname ) );5932 // gets hook for the prefixed version5933 // followed by the unprefixed version5934 hooks = jquery.csshooks[ name ] || jquery.csshooks[ origname ];5935 // if a hook was provided get the computed value from there5936 if ( hooks && "get" in hooks ) {5937 val = hooks.get( elem, true, extra );5938 }5939 // otherwise, if a way to get the computed value exists, use that5940 if ( val === undefined ) {5941 val = curcss( elem, name, styles );5942 }5943 //convert "normal" to computed value5944 if ( val === "normal" && name in cssnormaltransform ) {5945 val = cssnormaltransform[ name ];5946 }5947 // return, converting to number if forced or a qualifier was provided and val looks numeric5948 if ( extra === "" || extra ) {5949 num = parsefloat( val );5950 return extra === true || jquery.isnumeric( num ) ? num || 0 : val;5951 }5952 return val;5953 }5954 });5955// note: we've included the "window" in window.getcomputedstyle5956// because jsdom on node.js will break without it.5957 if ( window.getcomputedstyle ) {5958 getstyles = function( elem ) {5959 return window.getcomputedstyle( elem, null );5960 };5961 curcss = function( elem, name, _computed ) {5962 var width, minwidth, maxwidth,5963 computed = _computed || getstyles( elem ),5964 // getpropertyvalue is only needed for .css('filter') in ie9, see #125375965 ret = computed ? computed.getpropertyvalue( name ) || computed[ name ] : undefined,5966 style = elem.style;5967 if ( computed ) {5968 if ( ret === "" && !jquery.contains( elem.ownerdocument, elem ) ) {5969 ret = jquery.style( elem, name );5970 }5971 // a tribute to the "awesome hack by dean edwards"5972 // chrome < 17 and safari 5.0 uses "computed value" instead of "used value" for margin-right5973 // safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels5974 // this is against the cssom draft spec: http://dev.w3.org/csswg/cssom/#resolved-values5975 if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {5976 // remember the original values5977 width = style.width;5978 minwidth = style.minwidth;5979 maxwidth = style.maxwidth;5980 // put in the new values to get a computed value out5981 style.minwidth = style.maxwidth = style.width = ret;5982 ret = computed.width;5983 // revert the changed values5984 style.width = width;5985 style.minwidth = minwidth;5986 style.maxwidth = maxwidth;5987 }5988 }5989 return ret;5990 };5991 } else if ( document.documentelement.currentstyle ) {5992 getstyles = function( elem ) {5993 return elem.currentstyle;5994 };5995 curcss = function( elem, name, _computed ) {5996 var left, rs, rsleft,5997 computed = _computed || getstyles( elem ),5998 ret = computed ? computed[ name ] : undefined,5999 style = elem.style;6000 // avoid setting ret to empty string here6001 // so we don't default to auto6002 if ( ret == null && style && style[ name ] ) {6003 ret = style[ name ];6004 }6005 // from the awesome hack by dean edwards6006 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-1022916007 // if we're not dealing with a regular pixel number6008 // but a number that has a weird ending, we need to convert it to pixels6009 // but not position css attributes, as those are proportional to the parent element instead6010 // and we can't measure the parent instead because it might trigger a "stacking dolls" problem6011 if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {6012 // remember the original values6013 left = style.left;6014 rs = elem.runtimestyle;6015 rsleft = rs && rs.left;6016 // put in the new values to get a computed value out6017 if ( rsleft ) {6018 rs.left = elem.currentstyle.left;6019 }6020 style.left = name === "fontsize" ? "1em" : ret;6021 ret = style.pixelleft + "px";6022 // revert the changed values6023 style.left = left;6024 if ( rsleft ) {6025 rs.left = rsleft;6026 }6027 }6028 return ret === "" ? "auto" : ret;6029 };6030 }6031 function setpositivenumber( elem, value, subtract ) {6032 var matches = rnumsplit.exec( value );6033 return matches ?6034 // guard against undefined "subtract", e.g., when used as in csshooks6035 math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :6036 value;6037 }6038 function augmentwidthorheight( elem, name, extra, isborderbox, styles ) {6039 var i = extra === ( isborderbox ? "border" : "content" ) ?6040 // if we already have the right measurement, avoid augmentation6041 4 :6042 // otherwise initialize for horizontal or vertical properties6043 name === "width" ? 1 : 0,6044 val = 0;6045 for ( ; i < 4; i += 2 ) {6046 // both box models exclude margin, so add it if we want it6047 if ( extra === "margin" ) {6048 val += jquery.css( elem, extra + cssexpand[ i ], true, styles );6049 }6050 if ( isborderbox ) {6051 // border-box includes padding, so remove it if we want content6052 if ( extra === "content" ) {6053 val -= jquery.css( elem, "padding" + cssexpand[ i ], true, styles );6054 }6055 // at this point, extra isn't border nor margin, so remove border6056 if ( extra !== "margin" ) {6057 val -= jquery.css( elem, "border" + cssexpand[ i ] + "width", true, styles );6058 }6059 } else {6060 // at this point, extra isn't content, so add padding6061 val += jquery.css( elem, "padding" + cssexpand[ i ], true, styles );6062 // at this point, extra isn't content nor padding, so add border6063 if ( extra !== "padding" ) {6064 val += jquery.css( elem, "border" + cssexpand[ i ] + "width", true, styles );6065 }6066 }6067 }6068 return val;6069 }6070 function getwidthorheight( elem, name, extra ) {6071 // start with offset property, which is equivalent to the border-box value6072 var valueisborderbox = true,6073 val = name === "width" ? elem.offsetwidth : elem.offsetheight,6074 styles = getstyles( elem ),6075 isborderbox = jquery.support.boxsizing && jquery.css( elem, "boxsizing", false, styles ) === "border-box";6076 // some non-html elements return undefined for offsetwidth, so check for null/undefined6077 // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=6492856078 // mathml - https://bugzilla.mozilla.org/show_bug.cgi?id=4916686079 if ( val <= 0 || val == null ) {6080 // fall back to computed then uncomputed css if necessary6081 val = curcss( elem, name, styles );6082 if ( val < 0 || val == null ) {6083 val = elem.style[ name ];6084 }6085 // computed unit is not pixels. stop here and return.6086 if ( rnumnonpx.test(val) ) {6087 return val;6088 }6089 // we need the check for style in case a browser which returns unreliable values6090 // for getcomputedstyle silently falls back to the reliable elem.style6091 valueisborderbox = isborderbox && ( jquery.support.boxsizingreliable || val === elem.style[ name ] );6092 // normalize "", auto, and prepare for extra6093 val = parsefloat( val ) || 0;6094 }6095 // use the active box-sizing model to add/subtract irrelevant styles6096 return ( val +6097 augmentwidthorheight(6098 elem,6099 name,6100 extra || ( isborderbox ? "border" : "content" ),6101 valueisborderbox,6102 styles6103 )6104 ) + "px";6105 }6106// try to determine the default display value of an element6107 function css_defaultdisplay( nodename ) {6108 var doc = document,6109 display = elemdisplay[ nodename ];6110 if ( !display ) {6111 display = actualdisplay( nodename, doc );6112 // if the simple way fails, read from inside an iframe6113 if ( display === "none" || !display ) {6114 // use the already-created iframe if possible6115 iframe = ( iframe ||6116 jquery("<iframe frameborder='0' width='0' height='0'/>")6117 .css( "csstext", "display:block !important" )6118 ).appendto( doc.documentelement );6119 // always write a new html skeleton so webkit and firefox don't choke on reuse6120 doc = ( iframe[0].contentwindow || iframe[0].contentdocument ).document;6121 doc.write("<!doctype html><html><body>");6122 doc.close();6123 display = actualdisplay( nodename, doc );6124 iframe.detach();6125 }6126 // store the correct default display6127 elemdisplay[ nodename ] = display;6128 }6129 return display;6130 }6131// called only from within css_defaultdisplay6132 function actualdisplay( name, doc ) {6133 var elem = jquery( doc.createelement( name ) ).appendto( doc.body ),6134 display = jquery.css( elem[0], "display" );6135 elem.remove();6136 return display;6137 }6138 jquery.each([ "height", "width" ], function( i, name ) {6139 jquery.csshooks[ name ] = {6140 get: function( elem, computed, extra ) {6141 if ( computed ) {6142 // certain elements can have dimension info if we invisibly show them6143 // however, it must have a current display style that would benefit from this6144 return elem.offsetwidth === 0 && rdisplayswap.test( jquery.css( elem, "display" ) ) ?6145 jquery.swap( elem, cssshow, function() {6146 return getwidthorheight( elem, name, extra );6147 }) :6148 getwidthorheight( elem, name, extra );6149 }6150 },6151 set: function( elem, value, extra ) {6152 var styles = extra && getstyles( elem );6153 return setpositivenumber( elem, value, extra ?6154 augmentwidthorheight(6155 elem,6156 name,6157 extra,6158 jquery.support.boxsizing && jquery.css( elem, "boxsizing", false, styles ) === "border-box",6159 styles6160 ) : 06161 );6162 }6163 };6164 });6165 if ( !jquery.support.opacity ) {6166 jquery.csshooks.opacity = {6167 get: function( elem, computed ) {6168 // ie uses filters for opacity6169 return ropacity.test( (computed && elem.currentstyle ? elem.currentstyle.filter : elem.style.filter) || "" ) ?6170 ( 0.01 * parsefloat( regexp.$1 ) ) + "" :6171 computed ? "1" : "";6172 },6173 set: function( elem, value ) {6174 var style = elem.style,6175 currentstyle = elem.currentstyle,6176 opacity = jquery.isnumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",6177 filter = currentstyle && currentstyle.filter || style.filter || "";6178 // ie has trouble with opacity if it does not have layout6179 // force it by setting the zoom level6180 style.zoom = 1;6181 // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #66526182 // if value === "", then remove inline opacity #126856183 if ( ( value >= 1 || value === "" ) &&6184 jquery.trim( filter.replace( ralpha, "" ) ) === "" &&6185 style.removeattribute ) {6186 // setting style.filter to null, "" & " " still leave "filter:" in the csstext6187 // if "filter:" is present at all, cleartype is disabled, we want to avoid this6188 // style.removeattribute is ie only, but so apparently is this code path...6189 style.removeattribute( "filter" );6190 // if there is no filter style applied in a css rule or unset inline opacity, we are done6191 if ( value === "" || currentstyle && !currentstyle.filter ) {6192 return;6193 }6194 }6195 // otherwise, set new filter values6196 style.filter = ralpha.test( filter ) ?6197 filter.replace( ralpha, opacity ) :6198 filter + " " + opacity;6199 }6200 };6201 }6202// these hooks cannot be added until dom ready because the support test6203// for it is not run until after dom ready6204 jquery(function() {6205 if ( !jquery.support.reliablemarginright ) {6206 jquery.csshooks.marginright = {6207 get: function( elem, computed ) {6208 if ( computed ) {6209 // webkit bug 13343 - getcomputedstyle returns wrong value for margin-right6210 // work around by temporarily setting element display to inline-block6211 return jquery.swap( elem, { "display": "inline-block" },6212 curcss, [ elem, "marginright" ] );6213 }6214 }6215 };6216 }6217 // webkit bug: https://bugs.webkit.org/show_bug.cgi?id=290846218 // getcomputedstyle returns percent when specified for top/left/bottom/right6219 // rather than make the css module depend on the offset module, we just check for it here6220 if ( !jquery.support.pixelposition && jquery.fn.position ) {6221 jquery.each( [ "top", "left" ], function( i, prop ) {6222 jquery.csshooks[ prop ] = {6223 get: function( elem, computed ) {6224 if ( computed ) {6225 computed = curcss( elem, prop );6226 // if curcss returns percentage, fallback to offset6227 return rnumnonpx.test( computed ) ?6228 jquery( elem ).position()[ prop ] + "px" :6229 computed;6230 }6231 }6232 };6233 });6234 }6235 });6236 if ( jquery.expr && jquery.expr.filters ) {6237 jquery.expr.filters.hidden = function( elem ) {6238 // support: opera <= 12.126239 // opera reports offsetwidths and offsetheights less than zero on some elements6240 return elem.offsetwidth <= 0 && elem.offsetheight <= 0 ||6241 (!jquery.support.reliablehiddenoffsets && ((elem.style && elem.style.display) || jquery.css( elem, "display" )) === "none");6242 };6243 jquery.expr.filters.visible = function( elem ) {6244 return !jquery.expr.filters.hidden( elem );6245 };6246 }6247// these hooks are used by animate to expand properties6248 jquery.each({6249 margin: "",6250 padding: "",6251 border: "width"6252 }, function( prefix, suffix ) {6253 jquery.csshooks[ prefix + suffix ] = {6254 expand: function( value ) {6255 var i = 0,6256 expanded = {},6257 // assumes a single number if not a string6258 parts = typeof value === "string" ? value.split(" ") : [ value ];6259 for ( ; i < 4; i++ ) {6260 expanded[ prefix + cssexpand[ i ] + suffix ] =6261 parts[ i ] || parts[ i - 2 ] || parts[ 0 ];6262 }6263 return expanded;6264 }6265 };6266 if ( !rmargin.test( prefix ) ) {6267 jquery.csshooks[ prefix + suffix ].set = setpositivenumber;6268 }6269 });6270 var r20 = /%20/g,6271 rbracket = /\[\]$/,6272 rcrlf = /\r?\n/g,6273 rsubmittertypes = /^(?:submit|button|image|reset|file)$/i,6274 rsubmittable = /^(?:input|select|textarea|keygen)/i;6275 jquery.fn.extend({6276 serialize: function() {6277 return jquery.param( this.serializearray() );6278 },6279 serializearray: function() {6280 return this.map(function(){6281 // can add prophook for "elements" to filter or add form elements6282 var elements = jquery.prop( this, "elements" );6283 return elements ? jquery.makearray( elements ) : this;6284 })6285 .filter(function(){6286 var type = this.type;6287 // use .is(":disabled") so that fieldset[disabled] works6288 return this.name && !jquery( this ).is( ":disabled" ) &&6289 rsubmittable.test( this.nodename ) && !rsubmittertypes.test( type ) &&6290 ( this.checked || !manipulation_rcheckabletype.test( type ) );6291 })6292 .map(function( i, elem ){6293 var val = jquery( this ).val();6294 return val == null ?6295 null :6296 jquery.isarray( val ) ?6297 jquery.map( val, function( val ){6298 return { name: elem.name, value: val.replace( rcrlf, "\r\n" ) };6299 }) :6300 { name: elem.name, value: val.replace( rcrlf, "\r\n" ) };6301 }).get();6302 }6303 });6304//serialize an array of form elements or a set of6305//key/values into a query string6306 jquery.param = function( a, traditional ) {6307 var prefix,6308 s = [],6309 add = function( key, value ) {6310 // if value is a function, invoke it and return its value6311 value = jquery.isfunction( value ) ? value() : ( value == null ? "" : value );6312 s[ s.length ] = encodeuricomponent( key ) + "=" + encodeuricomponent( value );6313 };6314 // set traditional to true for jquery <= 1.3.2 behavior.6315 if ( traditional === undefined ) {6316 traditional = jquery.ajaxsettings && jquery.ajaxsettings.traditional;6317 }6318 // if an array was passed in, assume that it is an array of form elements.6319 if ( jquery.isarray( a ) || ( a.jquery && !jquery.isplainobject( a ) ) ) {6320 // serialize the form elements6321 jquery.each( a, function() {6322 add( this.name, this.value );6323 });6324 } else {6325 // if traditional, encode the "old" way (the way 1.3.2 or older6326 // did it), otherwise encode params recursively.6327 for ( prefix in a ) {6328 buildparams( prefix, a[ prefix ], traditional, add );6329 }6330 }6331 // return the resulting serialization6332 return s.join( "&" ).replace( r20, "+" );6333 };6334 function buildparams( prefix, obj, traditional, add ) {6335 var name;6336 if ( jquery.isarray( obj ) ) {6337 // serialize array item.6338 jquery.each( obj, function( i, v ) {6339 if ( traditional || rbracket.test( prefix ) ) {6340 // treat each array item as a scalar.6341 add( prefix, v );6342 } else {6343 // item is non-scalar (array or object), encode its numeric index.6344 buildparams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );6345 }6346 });6347 } else if ( !traditional && jquery.type( obj ) === "object" ) {6348 // serialize object item.6349 for ( name in obj ) {6350 buildparams( prefix + "[" + name + "]", obj[ name ], traditional, add );6351 }6352 } else {6353 // serialize scalar item.6354 add( prefix, obj );6355 }6356 }6357 jquery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +6358 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +6359 "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {6360 // handle event binding6361 jquery.fn[ name ] = function( data, fn ) {6362 return arguments.length > 0 ?6363 this.on( name, null, data, fn ) :6364 this.trigger( name );6365 };6366 });6367 jquery.fn.extend({6368 hover: function( fnover, fnout ) {6369 return this.mouseenter( fnover ).mouseleave( fnout || fnover );6370 },6371 bind: function( types, data, fn ) {6372 return this.on( types, null, data, fn );6373 },6374 unbind: function( types, fn ) {6375 return this.off( types, null, fn );6376 },6377 delegate: function( selector, types, data, fn ) {6378 return this.on( types, selector, data, fn );6379 },6380 undelegate: function( selector, types, fn ) {6381 // ( namespace ) or ( selector, types [, fn] )6382 return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );6383 }6384 });6385 var6386 // document location6387 ajaxlocparts,6388 ajaxlocation,6389 ajax_nonce = jquery.now(),6390 ajax_rquery = /\?/,6391 rhash = /#.*$/,6392 rts = /([?&])_=[^&]*/,6393 rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // ie leaves an \r character at eol6394 // #7653, #8125, #8152: local protocol detection6395 rlocalprotocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,6396 rnocontent = /^(?:get|head)$/,6397 rprotocol = /^\/\//,6398 rurl = /^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,6399 // keep a copy of the old load method6400 _load = jquery.fn.load,6401 /* prefilters6402 * 1) they are useful to introduce custom datatypes (see ajax/jsonp.js for an example)6403 * 2) these are called:6404 * - before asking for a transport6405 * - after param serialization (s.data is a string if s.processdata is true)6406 * 3) key is the datatype6407 * 4) the catchall symbol "*" can be used6408 * 5) execution will start with transport datatype and then continue down to "*" if needed6409 */6410 prefilters = {},6411 /* transports bindings6412 * 1) key is the datatype6413 * 2) the catchall symbol "*" can be used6414 * 3) selection will start with transport datatype and then go to "*" if needed6415 */6416 transports = {},6417 // avoid comment-prolog char sequence (#10098); must appease lint and evade compression6418 alltypes = "*/".concat("*");6419// #8138, ie may throw an exception when accessing6420// a field from window.location if document.domain has been set6421 try {6422 ajaxlocation = location.href;6423 } catch( e ) {6424 // use the href attribute of an a element6425 // since ie will modify it given document.location6426 ajaxlocation = document.createelement( "a" );6427 ajaxlocation.href = "";6428 ajaxlocation = ajaxlocation.href;6429 }6430// segment location into parts6431 ajaxlocparts = rurl.exec( ajaxlocation.tolowercase() ) || [];6432// base "constructor" for jquery.ajaxprefilter and jquery.ajaxtransport6433 function addtoprefiltersortransports( structure ) {6434 // datatypeexpression is optional and defaults to "*"6435 return function( datatypeexpression, func ) {6436 if ( typeof datatypeexpression !== "string" ) {6437 func = datatypeexpression;6438 datatypeexpression = "*";6439 }6440 var datatype,6441 i = 0,6442 datatypes = datatypeexpression.tolowercase().match( core_rnotwhite ) || [];6443 if ( jquery.isfunction( func ) ) {6444 // for each datatype in the datatypeexpression6445 while ( (datatype = datatypes[i++]) ) {6446 // prepend if requested6447 if ( datatype[0] === "+" ) {6448 datatype = datatype.slice( 1 ) || "*";6449 (structure[ datatype ] = structure[ datatype ] || []).unshift( func );6450 // otherwise append6451 } else {6452 (structure[ datatype ] = structure[ datatype ] || []).push( func );6453 }6454 }6455 }6456 };6457 }6458// base inspection function for prefilters and transports6459 function inspectprefiltersortransports( structure, options, originaloptions, jqxhr ) {6460 var inspected = {},6461 seekingtransport = ( structure === transports );6462 function inspect( datatype ) {6463 var selected;6464 inspected[ datatype ] = true;6465 jquery.each( structure[ datatype ] || [], function( _, prefilterorfactory ) {6466 var datatypeortransport = prefilterorfactory( options, originaloptions, jqxhr );6467 if( typeof datatypeortransport === "string" && !seekingtransport && !inspected[ datatypeortransport ] ) {6468 options.datatypes.unshift( datatypeortransport );6469 inspect( datatypeortransport );6470 return false;6471 } else if ( seekingtransport ) {6472 return !( selected = datatypeortransport );6473 }6474 });6475 return selected;6476 }6477 return inspect( options.datatypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );6478 }6479// a special extend for ajax options6480// that takes "flat" options (not to be deep extended)6481// fixes #98876482 function ajaxextend( target, src ) {6483 var deep, key,6484 flatoptions = jquery.ajaxsettings.flatoptions || {};6485 for ( key in src ) {6486 if ( src[ key ] !== undefined ) {6487 ( flatoptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];6488 }6489 }6490 if ( deep ) {6491 jquery.extend( true, target, deep );6492 }6493 return target;6494 }6495 jquery.fn.load = function( url, params, callback ) {6496 if ( typeof url !== "string" && _load ) {6497 return _load.apply( this, arguments );6498 }6499 var selector, response, type,6500 self = this,6501 off = url.indexof(" ");6502 if ( off >= 0 ) {6503 selector = url.slice( off, url.length );6504 url = url.slice( 0, off );6505 }6506 // if it's a function6507 if ( jquery.isfunction( params ) ) {6508 // we assume that it's the callback6509 callback = params;6510 params = undefined;6511 // otherwise, build a param string6512 } else if ( params && typeof params === "object" ) {6513 type = "post";6514 }6515 // if we have elements to modify, make the request6516 if ( self.length > 0 ) {6517 jquery.ajax({6518 url: url,6519 // if "type" variable is undefined, then "get" method will be used6520 type: type,6521 datatype: "html",6522 data: params6523 }).done(function( responsetext ) {6524 // save response for use in complete callback6525 response = arguments;6526 self.html( selector ?6527 // if a selector was specified, locate the right elements in a dummy div6528 // exclude scripts to avoid ie 'permission denied' errors6529 jquery("<div>").append( jquery.parsehtml( responsetext ) ).find( selector ) :6530 // otherwise use the full result6531 responsetext );6532 }).complete( callback && function( jqxhr, status ) {6533 self.each( callback, response || [ jqxhr.responsetext, status, jqxhr ] );6534 });6535 }6536 return this;6537 };6538// attach a bunch of functions for handling common ajax events6539 jquery.each( [ "ajaxstart", "ajaxstop", "ajaxcomplete", "ajaxerror", "ajaxsuccess", "ajaxsend" ], function( i, type ){6540 jquery.fn[ type ] = function( fn ){6541 return this.on( type, fn );6542 };6543 });6544 jquery.extend({6545 // counter for holding the number of active queries6546 active: 0,6547 // last-modified header cache for next request6548 lastmodified: {},6549 etag: {},6550 ajaxsettings: {6551 url: ajaxlocation,6552 type: "get",6553 islocal: rlocalprotocol.test( ajaxlocparts[ 1 ] ),6554 global: true,6555 processdata: true,6556 async: true,6557 contenttype: "application/x-www-form-urlencoded; charset=utf-8",6558 /*6559 timeout: 0,6560 data: null,6561 datatype: null,6562 username: null,6563 password: null,6564 cache: null,6565 throws: false,6566 traditional: false,6567 headers: {},6568 */6569 accepts: {6570 "*": alltypes,6571 text: "text/plain",6572 html: "text/html",6573 xml: "application/xml, text/xml",6574 json: "application/json, text/javascript"6575 },6576 contents: {6577 xml: /xml/,6578 html: /html/,6579 json: /json/6580 },6581 responsefields: {6582 xml: "responsexml",6583 text: "responsetext",6584 json: "responsejson"6585 },6586 // data converters6587 // keys separate source (or catchall "*") and destination types with a single space6588 converters: {6589 // convert anything to text6590 "* text": string,6591 // text to html (true = no transformation)6592 "text html": true,6593 // evaluate text as a json expression6594 "text json": jquery.parsejson,6595 // parse text as xml6596 "text xml": jquery.parsexml6597 },6598 // for options that shouldn't be deep extended:6599 // you can add your own custom options here if6600 // and when you create one that shouldn't be6601 // deep extended (see ajaxextend)6602 flatoptions: {6603 url: true,6604 context: true6605 }6606 },6607 // creates a full fledged settings object into target6608 // with both ajaxsettings and settings fields.6609 // if target is omitted, writes into ajaxsettings.6610 ajaxsetup: function( target, settings ) {6611 return settings ?6612 // building a settings object6613 ajaxextend( ajaxextend( target, jquery.ajaxsettings ), settings ) :6614 // extending ajaxsettings6615 ajaxextend( jquery.ajaxsettings, target );6616 },6617 ajaxprefilter: addtoprefiltersortransports( prefilters ),6618 ajaxtransport: addtoprefiltersortransports( transports ),6619 // main method6620 ajax: function( url, options ) {6621 // if url is an object, simulate pre-1.5 signature6622 if ( typeof url === "object" ) {6623 options = url;6624 url = undefined;6625 }6626 // force options to be an object6627 options = options || {};6628 var // cross-domain detection vars6629 parts,6630 // loop variable6631 i,6632 // url without anti-cache param6633 cacheurl,6634 // response headers as string6635 responseheadersstring,6636 // timeout handle6637 timeouttimer,6638 // to know if global events are to be dispatched6639 fireglobals,6640 transport,6641 // response headers6642 responseheaders,6643 // create the final options object6644 s = jquery.ajaxsetup( {}, options ),6645 // callbacks context6646 callbackcontext = s.context || s,6647 // context for global events is callbackcontext if it is a dom node or jquery collection6648 globaleventcontext = s.context && ( callbackcontext.nodetype || callbackcontext.jquery ) ?6649 jquery( callbackcontext ) :6650 jquery.event,6651 // deferreds6652 deferred = jquery.deferred(),6653 completedeferred = jquery.callbacks("once memory"),6654 // status-dependent callbacks6655 statuscode = s.statuscode || {},6656 // headers (they are sent all at once)6657 requestheaders = {},6658 requestheadersnames = {},6659 // the jqxhr state6660 state = 0,6661 // default abort message6662 strabort = "canceled",6663 // fake xhr6664 jqxhr = {6665 readystate: 0,6666 // builds headers hashtable if needed6667 getresponseheader: function( key ) {6668 var match;6669 if ( state === 2 ) {6670 if ( !responseheaders ) {6671 responseheaders = {};6672 while ( (match = rheaders.exec( responseheadersstring )) ) {6673 responseheaders[ match[1].tolowercase() ] = match[ 2 ];6674 }6675 }6676 match = responseheaders[ key.tolowercase() ];6677 }6678 return match == null ? null : match;6679 },6680 // raw string6681 getallresponseheaders: function() {6682 return state === 2 ? responseheadersstring : null;6683 },6684 // caches the header6685 setrequestheader: function( name, value ) {6686 var lname = name.tolowercase();6687 if ( !state ) {6688 name = requestheadersnames[ lname ] = requestheadersnames[ lname ] || name;6689 requestheaders[ name ] = value;6690 }6691 return this;6692 },6693 // overrides response content-type header6694 overridemimetype: function( type ) {6695 if ( !state ) {6696 s.mimetype = type;6697 }6698 return this;6699 },6700 // status-dependent callbacks6701 statuscode: function( map ) {6702 var code;6703 if ( map ) {6704 if ( state < 2 ) {6705 for ( code in map ) {6706 // lazy-add the new callback in a way that preserves old ones6707 statuscode[ code ] = [ statuscode[ code ], map[ code ] ];6708 }6709 } else {6710 // execute the appropriate callbacks6711 jqxhr.always( map[ jqxhr.status ] );6712 }6713 }6714 return this;6715 },6716 // cancel the request6717 abort: function( statustext ) {6718 var finaltext = statustext || strabort;6719 if ( transport ) {6720 transport.abort( finaltext );6721 }6722 done( 0, finaltext );6723 return this;6724 }6725 };6726 // attach deferreds6727 deferred.promise( jqxhr ).complete = completedeferred.add;6728 jqxhr.success = jqxhr.done;6729 jqxhr.error = jqxhr.fail;6730 // remove hash character (#7531: and string promotion)6731 // add protocol if not provided (#5866: ie7 issue with protocol-less urls)6732 // handle falsy url in the settings object (#10093: consistency with old signature)6733 // we also use the url parameter if available6734 s.url = ( ( url || s.url || ajaxlocation ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxlocparts[ 1 ] + "//" );6735 // alias method option to type as per ticket #120046736 s.type = options.method || options.type || s.method || s.type;6737 // extract datatypes list6738 s.datatypes = jquery.trim( s.datatype || "*" ).tolowercase().match( core_rnotwhite ) || [""];6739 // a cross-domain request is in order when we have a protocol:host:port mismatch6740 if ( s.crossdomain == null ) {6741 parts = rurl.exec( s.url.tolowercase() );6742 s.crossdomain = !!( parts &&6743 ( parts[ 1 ] !== ajaxlocparts[ 1 ] || parts[ 2 ] !== ajaxlocparts[ 2 ] ||6744 ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==6745 ( ajaxlocparts[ 3 ] || ( ajaxlocparts[ 1 ] === "http:" ? "80" : "443" ) ) )6746 );6747 }6748 // convert data if not already a string6749 if ( s.data && s.processdata && typeof s.data !== "string" ) {6750 s.data = jquery.param( s.data, s.traditional );6751 }6752 // apply prefilters6753 inspectprefiltersortransports( prefilters, s, options, jqxhr );6754 // if request was aborted inside a prefilter, stop there6755 if ( state === 2 ) {6756 return jqxhr;6757 }6758 // we can fire global events as of now if asked to6759 fireglobals = s.global;6760 // watch for a new set of requests6761 if ( fireglobals && jquery.active++ === 0 ) {6762 jquery.event.trigger("ajaxstart");6763 }6764 // uppercase the type6765 s.type = s.type.touppercase();6766 // determine if request has content6767 s.hascontent = !rnocontent.test( s.type );6768 // save the url in case we're toying with the if-modified-since6769 // and/or if-none-match header later on6770 cacheurl = s.url;6771 // more options handling for requests with no content6772 if ( !s.hascontent ) {6773 // if data is available, append data to url6774 if ( s.data ) {6775 cacheurl = ( s.url += ( ajax_rquery.test( cacheurl ) ? "&" : "?" ) + s.data );6776 // #9682: remove data so that it's not used in an eventual retry6777 delete s.data;6778 }6779 // add anti-cache in url if needed6780 if ( s.cache === false ) {6781 s.url = rts.test( cacheurl ) ?6782 // if there is already a '_' parameter, set its value6783 cacheurl.replace( rts, "$1_=" + ajax_nonce++ ) :6784 // otherwise add one to the end6785 cacheurl + ( ajax_rquery.test( cacheurl ) ? "&" : "?" ) + "_=" + ajax_nonce++;6786 }6787 }6788 // set the if-modified-since and/or if-none-match header, if in ifmodified mode.6789 if ( s.ifmodified ) {6790 if ( jquery.lastmodified[ cacheurl ] ) {6791 jqxhr.setrequestheader( "if-modified-since", jquery.lastmodified[ cacheurl ] );6792 }6793 if ( jquery.etag[ cacheurl ] ) {6794 jqxhr.setrequestheader( "if-none-match", jquery.etag[ cacheurl ] );6795 }6796 }6797 // set the correct header, if data is being sent6798 if ( s.data && s.hascontent && s.contenttype !== false || options.contenttype ) {6799 jqxhr.setrequestheader( "content-type", s.contenttype );6800 }6801 // set the accepts header for the server, depending on the datatype6802 jqxhr.setrequestheader(6803 "accept",6804 s.datatypes[ 0 ] && s.accepts[ s.datatypes[0] ] ?6805 s.accepts[ s.datatypes[0] ] + ( s.datatypes[ 0 ] !== "*" ? ", " + alltypes + "; q=0.01" : "" ) :6806 s.accepts[ "*" ]6807 );6808 // check for headers option6809 for ( i in s.headers ) {6810 jqxhr.setrequestheader( i, s.headers[ i ] );6811 }6812 // allow custom headers/mimetypes and early abort6813 if ( s.beforesend && ( s.beforesend.call( callbackcontext, jqxhr, s ) === false || state === 2 ) ) {6814 // abort if not done already and return6815 return jqxhr.abort();6816 }6817 // aborting is no longer a cancellation6818 strabort = "abort";6819 // install callbacks on deferreds6820 for ( i in { success: 1, error: 1, complete: 1 } ) {6821 jqxhr[ i ]( s[ i ] );6822 }6823 // get transport6824 transport = inspectprefiltersortransports( transports, s, options, jqxhr );6825 // if no transport, we auto-abort6826 if ( !transport ) {6827 done( -1, "no transport" );6828 } else {6829 jqxhr.readystate = 1;6830 // send global event6831 if ( fireglobals ) {6832 globaleventcontext.trigger( "ajaxsend", [ jqxhr, s ] );6833 }6834 // timeout6835 if ( s.async && s.timeout > 0 ) {6836 timeouttimer = settimeout(function() {6837 jqxhr.abort("timeout");6838 }, s.timeout );6839 }6840 try {6841 state = 1;6842 transport.send( requestheaders, done );6843 } catch ( e ) {6844 // propagate exception as error if not done6845 if ( state < 2 ) {6846 done( -1, e );6847 // simply rethrow otherwise6848 } else {6849 throw e;6850 }6851 }6852 }6853 // callback for when everything is done6854 function done( status, nativestatustext, responses, headers ) {6855 var issuccess, success, error, response, modified,6856 statustext = nativestatustext;6857 // called once6858 if ( state === 2 ) {6859 return;6860 }6861 // state is "done" now6862 state = 2;6863 // clear timeout if it exists6864 if ( timeouttimer ) {6865 cleartimeout( timeouttimer );6866 }6867 // dereference transport for early garbage collection6868 // (no matter how long the jqxhr object will be used)6869 transport = undefined;6870 // cache response headers6871 responseheadersstring = headers || "";6872 // set readystate6873 jqxhr.readystate = status > 0 ? 4 : 0;6874 // determine if successful6875 issuccess = status >= 200 && status < 300 || status === 304;6876 // get response data6877 if ( responses ) {6878 response = ajaxhandleresponses( s, jqxhr, responses );6879 }6880 // convert no matter what (that way responsexxx fields are always set)6881 response = ajaxconvert( s, response, jqxhr, issuccess );6882 // if successful, handle type chaining6883 if ( issuccess ) {6884 // set the if-modified-since and/or if-none-match header, if in ifmodified mode.6885 if ( s.ifmodified ) {6886 modified = jqxhr.getresponseheader("last-modified");6887 if ( modified ) {6888 jquery.lastmodified[ cacheurl ] = modified;6889 }6890 modified = jqxhr.getresponseheader("etag");6891 if ( modified ) {6892 jquery.etag[ cacheurl ] = modified;6893 }6894 }6895 // if no content6896 if ( status === 204 || s.type === "head" ) {6897 statustext = "nocontent";6898 // if not modified6899 } else if ( status === 304 ) {6900 statustext = "notmodified";6901 // if we have data, let's convert it6902 } else {6903 statustext = response.state;6904 success = response.data;6905 error = response.error;6906 issuccess = !error;6907 }6908 } else {6909 // we extract error from statustext6910 // then normalize statustext and status for non-aborts6911 error = statustext;6912 if ( status || !statustext ) {6913 statustext = "error";6914 if ( status < 0 ) {6915 status = 0;6916 }6917 }6918 }6919 // set data for the fake xhr object6920 jqxhr.status = status;6921 jqxhr.statustext = ( nativestatustext || statustext ) + "";6922 // success/error6923 if ( issuccess ) {6924 deferred.resolvewith( callbackcontext, [ success, statustext, jqxhr ] );6925 } else {6926 deferred.rejectwith( callbackcontext, [ jqxhr, statustext, error ] );6927 }6928 // status-dependent callbacks6929 jqxhr.statuscode( statuscode );6930 statuscode = undefined;6931 if ( fireglobals ) {6932 globaleventcontext.trigger( issuccess ? "ajaxsuccess" : "ajaxerror",6933 [ jqxhr, s, issuccess ? success : error ] );6934 }6935 // complete6936 completedeferred.firewith( callbackcontext, [ jqxhr, statustext ] );6937 if ( fireglobals ) {6938 globaleventcontext.trigger( "ajaxcomplete", [ jqxhr, s ] );6939 // handle the global ajax counter6940 if ( !( --jquery.active ) ) {6941 jquery.event.trigger("ajaxstop");6942 }6943 }6944 }6945 return jqxhr;6946 },6947 getjson: function( url, data, callback ) {6948 return jquery.get( url, data, callback, "json" );6949 },6950 getscript: function( url, callback ) {6951 return jquery.get( url, undefined, callback, "script" );6952 }6953 });6954 jquery.each( [ "get", "post" ], function( i, method ) {6955 jquery[ method ] = function( url, data, callback, type ) {6956 // shift arguments if data argument was omitted6957 if ( jquery.isfunction( data ) ) {6958 type = type || callback;6959 callback = data;6960 data = undefined;6961 }6962 return jquery.ajax({6963 url: url,6964 type: method,6965 datatype: type,6966 data: data,6967 success: callback6968 });6969 };6970 });6971 /* handles responses to an ajax request:6972 * - finds the right datatype (mediates between content-type and expected datatype)6973 * - returns the corresponding response6974 */6975 function ajaxhandleresponses( s, jqxhr, responses ) {6976 var firstdatatype, ct, finaldatatype, type,6977 contents = s.contents,6978 datatypes = s.datatypes;6979 // remove auto datatype and get content-type in the process6980 while( datatypes[ 0 ] === "*" ) {6981 datatypes.shift();6982 if ( ct === undefined ) {6983 ct = s.mimetype || jqxhr.getresponseheader("content-type");6984 }6985 }6986 // check if we're dealing with a known content-type6987 if ( ct ) {6988 for ( type in contents ) {6989 if ( contents[ type ] && contents[ type ].test( ct ) ) {6990 datatypes.unshift( type );6991 break;6992 }6993 }6994 }6995 // check to see if we have a response for the expected datatype6996 if ( datatypes[ 0 ] in responses ) {6997 finaldatatype = datatypes[ 0 ];6998 } else {6999 // try convertible datatypes7000 for ( type in responses ) {7001 if ( !datatypes[ 0 ] || s.converters[ type + " " + datatypes[0] ] ) {7002 finaldatatype = type;7003 break;7004 }7005 if ( !firstdatatype ) {7006 firstdatatype = type;7007 }7008 }7009 // or just use first one7010 finaldatatype = finaldatatype || firstdatatype;7011 }7012 // if we found a datatype7013 // we add the datatype to the list if needed7014 // and return the corresponding response7015 if ( finaldatatype ) {7016 if ( finaldatatype !== datatypes[ 0 ] ) {7017 datatypes.unshift( finaldatatype );7018 }7019 return responses[ finaldatatype ];7020 }7021 }7022 /* chain conversions given the request and the original response7023 * also sets the responsexxx fields on the jqxhr instance7024 */7025 function ajaxconvert( s, response, jqxhr, issuccess ) {7026 var conv2, current, conv, tmp, prev,7027 converters = {},7028 // work with a copy of datatypes in case we need to modify it for conversion7029 datatypes = s.datatypes.slice();7030 // create converters map with lowercased keys7031 if ( datatypes[ 1 ] ) {7032 for ( conv in s.converters ) {7033 converters[ conv.tolowercase() ] = s.converters[ conv ];7034 }7035 }7036 current = datatypes.shift();7037 // convert to each sequential datatype7038 while ( current ) {7039 if ( s.responsefields[ current ] ) {7040 jqxhr[ s.responsefields[ current ] ] = response;7041 }7042 // apply the datafilter if provided7043 if ( !prev && issuccess && s.datafilter ) {7044 response = s.datafilter( response, s.datatype );7045 }7046 prev = current;7047 current = datatypes.shift();7048 if ( current ) {7049 // there's only work to do if current datatype is non-auto7050 if ( current === "*" ) {7051 current = prev;7052 // convert response if prev datatype is non-auto and differs from current7053 } else if ( prev !== "*" && prev !== current ) {7054 // seek a direct converter7055 conv = converters[ prev + " " + current ] || converters[ "* " + current ];7056 // if none found, seek a pair7057 if ( !conv ) {7058 for ( conv2 in converters ) {7059 // if conv2 outputs current7060 tmp = conv2.split( " " );7061 if ( tmp[ 1 ] === current ) {7062 // if prev can be converted to accepted input7063 conv = converters[ prev + " " + tmp[ 0 ] ] ||7064 converters[ "* " + tmp[ 0 ] ];7065 if ( conv ) {7066 // condense equivalence converters7067 if ( conv === true ) {7068 conv = converters[ conv2 ];7069 // otherwise, insert the intermediate datatype7070 } else if ( converters[ conv2 ] !== true ) {7071 current = tmp[ 0 ];7072 datatypes.unshift( tmp[ 1 ] );7073 }7074 break;7075 }7076 }7077 }7078 }7079 // apply converter (if not an equivalence)7080 if ( conv !== true ) {7081 // unless errors are allowed to bubble, catch and return them7082 if ( conv && s[ "throws" ] ) {7083 response = conv( response );7084 } else {7085 try {7086 response = conv( response );7087 } catch ( e ) {7088 return { state: "parsererror", error: conv ? e : "no conversion from " + prev + " to " + current };7089 }7090 }7091 }7092 }7093 }7094 }7095 return { state: "success", data: response };7096 }7097// install script datatype7098 jquery.ajaxsetup({7099 accepts: {7100 script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"7101 },7102 contents: {7103 script: /(?:java|ecma)script/7104 },7105 converters: {7106 "text script": function( text ) {7107 jquery.globaleval( text );7108 return text;7109 }7110 }7111 });7112// handle cache's special case and global7113 jquery.ajaxprefilter( "script", function( s ) {7114 if ( s.cache === undefined ) {7115 s.cache = false;7116 }7117 if ( s.crossdomain ) {7118 s.type = "get";7119 s.global = false;7120 }7121 });7122// bind script tag hack transport7123 jquery.ajaxtransport( "script", function(s) {7124 // this transport only deals with cross domain requests7125 if ( s.crossdomain ) {7126 var script,7127 head = document.head || jquery("head")[0] || document.documentelement;7128 return {7129 send: function( _, callback ) {7130 script = document.createelement("script");7131 script.async = true;7132 if ( s.scriptcharset ) {7133 script.charset = s.scriptcharset;7134 }7135 script.src = s.url;7136 // attach handlers for all browsers7137 script.onload = script.onreadystatechange = function( _, isabort ) {7138 if ( isabort || !script.readystate || /loaded|complete/.test( script.readystate ) ) {7139 // handle memory leak in ie7140 script.onload = script.onreadystatechange = null;7141 // remove the script7142 if ( script.parentnode ) {7143 script.parentnode.removechild( script );7144 }7145 // dereference the script7146 script = null;7147 // callback if not abort7148 if ( !isabort ) {7149 callback( 200, "success" );7150 }7151 }7152 };7153 // circumvent ie6 bugs with base elements (#2709 and #4378) by prepending7154 // use native dom manipulation to avoid our dommanip ajax trickery7155 head.insertbefore( script, head.firstchild );7156 },7157 abort: function() {7158 if ( script ) {7159 script.onload( undefined, true );7160 }7161 }7162 };7163 }7164 });7165 var oldcallbacks = [],7166 rjsonp = /(=)\?(?=&|$)|\?\?/;7167// default jsonp settings7168 jquery.ajaxsetup({7169 jsonp: "callback",7170 jsonpcallback: function() {7171 var callback = oldcallbacks.pop() || ( jquery.expando + "_" + ( ajax_nonce++ ) );7172 this[ callback ] = true;7173 return callback;7174 }7175 });7176// detect, normalize options and install callbacks for jsonp requests7177 jquery.ajaxprefilter( "json jsonp", function( s, originalsettings, jqxhr ) {7178 var callbackname, overwritten, responsecontainer,7179 jsonprop = s.jsonp !== false && ( rjsonp.test( s.url ) ?7180 "url" :7181 typeof s.data === "string" && !( s.contenttype || "" ).indexof("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"7182 );7183 // handle iff the expected data type is "jsonp" or we have a parameter to set7184 if ( jsonprop || s.datatypes[ 0 ] === "jsonp" ) {7185 // get callback name, remembering preexisting value associated with it7186 callbackname = s.jsonpcallback = jquery.isfunction( s.jsonpcallback ) ?7187 s.jsonpcallback() :7188 s.jsonpcallback;7189 // insert callback into url or form data7190 if ( jsonprop ) {7191 s[ jsonprop ] = s[ jsonprop ].replace( rjsonp, "$1" + callbackname );7192 } else if ( s.jsonp !== false ) {7193 s.url += ( ajax_rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackname;7194 }7195 // use data converter to retrieve json after script execution7196 s.converters["script json"] = function() {7197 if ( !responsecontainer ) {7198 jquery.error( callbackname + " was not called" );7199 }7200 return responsecontainer[ 0 ];7201 };7202 // force json datatype7203 s.datatypes[ 0 ] = "json";7204 // install callback7205 overwritten = window[ callbackname ];7206 window[ callbackname ] = function() {7207 responsecontainer = arguments;7208 };7209 // clean-up function (fires after converters)7210 jqxhr.always(function() {7211 // restore preexisting value7212 window[ callbackname ] = overwritten;7213 // save back as free7214 if ( s[ callbackname ] ) {7215 // make sure that re-using the options doesn't screw things around7216 s.jsonpcallback = originalsettings.jsonpcallback;7217 // save the callback name for future use7218 oldcallbacks.push( callbackname );7219 }7220 // call if it was a function and we have a response7221 if ( responsecontainer && jquery.isfunction( overwritten ) ) {7222 overwritten( responsecontainer[ 0 ] );7223 }7224 responsecontainer = overwritten = undefined;7225 });7226 // delegate to script7227 return "script";7228 }7229 });7230 var xhrcallbacks, xhrsupported,7231 xhrid = 0,7232 // #5280: internet explorer will keep connections alive if we don't abort on unload7233 xhronunloadabort = window.activexobject && function() {7234 // abort all pending requests7235 var key;7236 for ( key in xhrcallbacks ) {7237 xhrcallbacks[ key ]( undefined, true );7238 }7239 };7240// functions to create xhrs7241 function createstandardxhr() {7242 try {7243 return new window.xmlhttprequest();7244 } catch( e ) {}7245 }7246 function createactivexhr() {7247 try {7248 return new window.activexobject("microsoft.xmlhttp");7249 } catch( e ) {}7250 }7251// create the request object7252// (this is still attached to ajaxsettings for backward compatibility)7253 jquery.ajaxsettings.xhr = window.activexobject ?7254 /* microsoft failed to properly7255 * implement the xmlhttprequest in ie7 (can't request local files),7256 * so we use the activexobject when it is available7257 * additionally xmlhttprequest can be disabled in ie7/ie8 so7258 * we need a fallback.7259 */7260 function() {7261 return !this.islocal && createstandardxhr() || createactivexhr();7262 } :7263 // for all other browsers, use the standard xmlhttprequest object7264 createstandardxhr;7265// determine support properties7266 xhrsupported = jquery.ajaxsettings.xhr();7267 jquery.support.cors = !!xhrsupported && ( "withcredentials" in xhrsupported );7268 xhrsupported = jquery.support.ajax = !!xhrsupported;7269// create transport if the browser can provide an xhr7270 if ( xhrsupported ) {7271 jquery.ajaxtransport(function( s ) {7272 // cross domain only allowed if supported through xmlhttprequest7273 if ( !s.crossdomain || jquery.support.cors ) {7274 var callback;7275 return {7276 send: function( headers, complete ) {7277 // get a new xhr7278 var handle, i,7279 xhr = s.xhr();7280 // open the socket7281 // passing null username, generates a login popup on opera (#2865)7282 if ( s.username ) {7283 xhr.open( s.type, s.url, s.async, s.username, s.password );7284 } else {7285 xhr.open( s.type, s.url, s.async );7286 }7287 // apply custom fields if provided7288 if ( s.xhrfields ) {7289 for ( i in s.xhrfields ) {7290 xhr[ i ] = s.xhrfields[ i ];7291 }7292 }7293 // override mime type if needed7294 if ( s.mimetype && xhr.overridemimetype ) {7295 xhr.overridemimetype( s.mimetype );7296 }7297 // x-requested-with header7298 // for cross-domain requests, seeing as conditions for a preflight are7299 // akin to a jigsaw puzzle, we simply never set it to be sure.7300 // (it can always be set on a per-request basis or even using ajaxsetup)7301 // for same-domain requests, won't change header if already provided.7302 if ( !s.crossdomain && !headers["x-requested-with"] ) {7303 headers["x-requested-with"] = "xmlhttprequest";7304 }7305 // need an extra try/catch for cross domain requests in firefox 37306 try {7307 for ( i in headers ) {7308 xhr.setrequestheader( i, headers[ i ] );7309 }7310 } catch( err ) {}7311 // do send the request7312 // this may raise an exception which is actually7313 // handled in jquery.ajax (so no try/catch here)7314 xhr.send( ( s.hascontent && s.data ) || null );7315 // listener7316 callback = function( _, isabort ) {7317 var status, responseheaders, statustext, responses;7318 // firefox throws exceptions when accessing properties7319 // of an xhr when a network error occurred7320 // http://helpful.knobs-dials.com/index.php/component_returned_failure_code:_0x80040111_(ns_error_not_available)7321 try {7322 // was never called and is aborted or complete7323 if ( callback && ( isabort || xhr.readystate === 4 ) ) {7324 // only called once7325 callback = undefined;7326 // do not keep as active anymore7327 if ( handle ) {7328 xhr.onreadystatechange = jquery.noop;7329 if ( xhronunloadabort ) {7330 delete xhrcallbacks[ handle ];7331 }7332 }7333 // if it's an abort7334 if ( isabort ) {7335 // abort it manually if needed7336 if ( xhr.readystate !== 4 ) {7337 xhr.abort();7338 }7339 } else {7340 responses = {};7341 status = xhr.status;7342 responseheaders = xhr.getallresponseheaders();7343 // when requesting binary data, ie6-9 will throw an exception7344 // on any attempt to access responsetext (#11426)7345 if ( typeof xhr.responsetext === "string" ) {7346 responses.text = xhr.responsetext;7347 }7348 // firefox throws an exception when accessing7349 // statustext for faulty cross-domain requests7350 try {7351 statustext = xhr.statustext;7352 } catch( e ) {7353 // we normalize with webkit giving an empty statustext7354 statustext = "";7355 }7356 // filter status for non standard behaviors7357 // if the request is local and we have data: assume a success7358 // (success with no data won't get notified, that's the best we7359 // can do given current implementations)7360 if ( !status && s.islocal && !s.crossdomain ) {7361 status = responses.text ? 200 : 404;7362 // ie - #1450: sometimes returns 1223 when it should be 2047363 } else if ( status === 1223 ) {7364 status = 204;7365 }7366 }7367 }7368 } catch( firefoxaccessexception ) {7369 if ( !isabort ) {7370 complete( -1, firefoxaccessexception );7371 }7372 }7373 // call complete if needed7374 if ( responses ) {7375 complete( status, statustext, responses, responseheaders );7376 }7377 };7378 if ( !s.async ) {7379 // if we're in sync mode we fire the callback7380 callback();7381 } else if ( xhr.readystate === 4 ) {7382 // (ie6 & ie7) if it's in cache and has been7383 // retrieved directly we need to fire the callback7384 settimeout( callback );7385 } else {7386 handle = ++xhrid;7387 if ( xhronunloadabort ) {7388 // create the active xhrs callbacks list if needed7389 // and attach the unload handler7390 if ( !xhrcallbacks ) {7391 xhrcallbacks = {};7392 jquery( window ).unload( xhronunloadabort );7393 }7394 // add to list of active xhrs callbacks7395 xhrcallbacks[ handle ] = callback;7396 }7397 xhr.onreadystatechange = callback;7398 }7399 },7400 abort: function() {7401 if ( callback ) {7402 callback( undefined, true );7403 }7404 }7405 };7406 }7407 });7408 }7409 var fxnow, timerid,7410 rfxtypes = /^(?:toggle|show|hide)$/,7411 rfxnum = new regexp( "^(?:([+-])=|)(" + core_pnum + ")([a-z%]*)$", "i" ),7412 rrun = /queuehooks$/,7413 animationprefilters = [ defaultprefilter ],7414 tweeners = {7415 "*": [function( prop, value ) {7416 var tween = this.createtween( prop, value ),7417 target = tween.cur(),7418 parts = rfxnum.exec( value ),7419 unit = parts && parts[ 3 ] || ( jquery.cssnumber[ prop ] ? "" : "px" ),7420 // starting value computation is required for potential unit mismatches7421 start = ( jquery.cssnumber[ prop ] || unit !== "px" && +target ) &&7422 rfxnum.exec( jquery.css( tween.elem, prop ) ),7423 scale = 1,7424 maxiterations = 20;7425 if ( start && start[ 3 ] !== unit ) {7426 // trust units reported by jquery.css7427 unit = unit || start[ 3 ];7428 // make sure we update the tween properties later on7429 parts = parts || [];7430 // iteratively approximate from a nonzero starting point7431 start = +target || 1;7432 do {7433 // if previous iteration zeroed out, double until we get *something*7434 // use a string for doubling factor so we don't accidentally see scale as unchanged below7435 scale = scale || ".5";7436 // adjust and apply7437 start = start / scale;7438 jquery.style( tween.elem, prop, start + unit );7439 // update scale, tolerating zero or nan from tween.cur()7440 // and breaking the loop if scale is unchanged or perfect, or if we've just had enough7441 } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxiterations );7442 }7443 // update tween properties7444 if ( parts ) {7445 start = tween.start = +start || +target || 0;7446 tween.unit = unit;7447 // if a +=/-= token was provided, we're doing a relative animation7448 tween.end = parts[ 1 ] ?7449 start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :7450 +parts[ 2 ];7451 }7452 return tween;7453 }]7454 };7455// animations created synchronously will run synchronously7456 function createfxnow() {7457 settimeout(function() {7458 fxnow = undefined;7459 });7460 return ( fxnow = jquery.now() );7461 }7462 function createtween( value, prop, animation ) {7463 var tween,7464 collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),7465 index = 0,7466 length = collection.length;7467 for ( ; index < length; index++ ) {7468 if ( (tween = collection[ index ].call( animation, prop, value )) ) {7469 // we're done with this property7470 return tween;7471 }7472 }7473 }7474 function animation( elem, properties, options ) {7475 var result,7476 stopped,7477 index = 0,7478 length = animationprefilters.length,7479 deferred = jquery.deferred().always( function() {7480 // don't match elem in the :animated selector7481 delete tick.elem;7482 }),7483 tick = function() {7484 if ( stopped ) {7485 return false;7486 }7487 var currenttime = fxnow || createfxnow(),7488 remaining = math.max( 0, animation.starttime + animation.duration - currenttime ),7489 // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)7490 temp = remaining / animation.duration || 0,7491 percent = 1 - temp,7492 index = 0,7493 length = animation.tweens.length;7494 for ( ; index < length ; index++ ) {7495 animation.tweens[ index ].run( percent );7496 }7497 deferred.notifywith( elem, [ animation, percent, remaining ]);7498 if ( percent < 1 && length ) {7499 return remaining;7500 } else {7501 deferred.resolvewith( elem, [ animation ] );7502 return false;7503 }7504 },7505 animation = deferred.promise({7506 elem: elem,7507 props: jquery.extend( {}, properties ),7508 opts: jquery.extend( true, { specialeasing: {} }, options ),7509 originalproperties: properties,7510 originaloptions: options,7511 starttime: fxnow || createfxnow(),7512 duration: options.duration,7513 tweens: [],7514 createtween: function( prop, end ) {7515 var tween = jquery.tween( elem, animation.opts, prop, end,7516 animation.opts.specialeasing[ prop ] || animation.opts.easing );7517 animation.tweens.push( tween );7518 return tween;7519 },7520 stop: function( gotoend ) {7521 var index = 0,7522 // if we are going to the end, we want to run all the tweens7523 // otherwise we skip this part7524 length = gotoend ? animation.tweens.length : 0;7525 if ( stopped ) {7526 return this;7527 }7528 stopped = true;7529 for ( ; index < length ; index++ ) {7530 animation.tweens[ index ].run( 1 );7531 }7532 // resolve when we played the last frame7533 // otherwise, reject7534 if ( gotoend ) {7535 deferred.resolvewith( elem, [ animation, gotoend ] );7536 } else {7537 deferred.rejectwith( elem, [ animation, gotoend ] );7538 }7539 return this;7540 }7541 }),7542 props = animation.props;7543 propfilter( props, animation.opts.specialeasing );7544 for ( ; index < length ; index++ ) {7545 result = animationprefilters[ index ].call( animation, elem, props, animation.opts );7546 if ( result ) {7547 return result;7548 }7549 }7550 jquery.map( props, createtween, animation );7551 if ( jquery.isfunction( animation.opts.start ) ) {7552 animation.opts.start.call( elem, animation );7553 }7554 jquery.fx.timer(7555 jquery.extend( tick, {7556 elem: elem,7557 anim: animation,7558 queue: animation.opts.queue7559 })7560 );7561 // attach callbacks from options7562 return animation.progress( animation.opts.progress )7563 .done( animation.opts.done, animation.opts.complete )7564 .fail( animation.opts.fail )7565 .always( animation.opts.always );7566 }7567 function propfilter( props, specialeasing ) {7568 var index, name, easing, value, hooks;7569 // camelcase, specialeasing and expand csshook pass7570 for ( index in props ) {7571 name = jquery.camelcase( index );7572 easing = specialeasing[ name ];7573 value = props[ index ];7574 if ( jquery.isarray( value ) ) {7575 easing = value[ 1 ];7576 value = props[ index ] = value[ 0 ];7577 }7578 if ( index !== name ) {7579 props[ name ] = value;7580 delete props[ index ];7581 }7582 hooks = jquery.csshooks[ name ];7583 if ( hooks && "expand" in hooks ) {7584 value = hooks.expand( value );7585 delete props[ name ];7586 // not quite $.extend, this wont overwrite keys already present.7587 // also - reusing 'index' from above because we have the correct "name"7588 for ( index in value ) {7589 if ( !( index in props ) ) {7590 props[ index ] = value[ index ];7591 specialeasing[ index ] = easing;7592 }7593 }7594 } else {7595 specialeasing[ name ] = easing;7596 }7597 }7598 }7599 jquery.animation = jquery.extend( animation, {7600 tweener: function( props, callback ) {7601 if ( jquery.isfunction( props ) ) {7602 callback = props;7603 props = [ "*" ];7604 } else {7605 props = props.split(" ");7606 }7607 var prop,7608 index = 0,7609 length = props.length;7610 for ( ; index < length ; index++ ) {7611 prop = props[ index ];7612 tweeners[ prop ] = tweeners[ prop ] || [];7613 tweeners[ prop ].unshift( callback );7614 }7615 },7616 prefilter: function( callback, prepend ) {7617 if ( prepend ) {7618 animationprefilters.unshift( callback );7619 } else {7620 animationprefilters.push( callback );7621 }7622 }7623 });7624 function defaultprefilter( elem, props, opts ) {7625 /* jshint validthis: true */7626 var prop, value, toggle, tween, hooks, oldfire,7627 anim = this,7628 orig = {},7629 style = elem.style,7630 hidden = elem.nodetype && ishidden( elem ),7631 datashow = jquery._data( elem, "fxshow" );7632 // handle queue: false promises7633 if ( !opts.queue ) {7634 hooks = jquery._queuehooks( elem, "fx" );7635 if ( hooks.unqueued == null ) {7636 hooks.unqueued = 0;7637 oldfire = hooks.empty.fire;7638 hooks.empty.fire = function() {7639 if ( !hooks.unqueued ) {7640 oldfire();7641 }7642 };7643 }7644 hooks.unqueued++;7645 anim.always(function() {7646 // doing this makes sure that the complete handler will be called7647 // before this completes7648 anim.always(function() {7649 hooks.unqueued--;7650 if ( !jquery.queue( elem, "fx" ).length ) {7651 hooks.empty.fire();7652 }7653 });7654 });7655 }7656 // height/width overflow pass7657 if ( elem.nodetype === 1 && ( "height" in props || "width" in props ) ) {7658 // make sure that nothing sneaks out7659 // record all 3 overflow attributes because ie does not7660 // change the overflow attribute when overflowx and7661 // overflowy are set to the same value7662 opts.overflow = [ style.overflow, style.overflowx, style.overflowy ];7663 // set display property to inline-block for height/width7664 // animations on inline elements that are having width/height animated7665 if ( jquery.css( elem, "display" ) === "inline" &&7666 jquery.css( elem, "float" ) === "none" ) {7667 // inline-level elements accept inline-block;7668 // block-level elements need to be inline with layout7669 if ( !jquery.support.inlineblockneedslayout || css_defaultdisplay( elem.nodename ) === "inline" ) {7670 style.display = "inline-block";7671 } else {7672 style.zoom = 1;7673 }7674 }7675 }7676 if ( opts.overflow ) {7677 style.overflow = "hidden";7678 if ( !jquery.support.shrinkwrapblocks ) {7679 anim.always(function() {7680 style.overflow = opts.overflow[ 0 ];7681 style.overflowx = opts.overflow[ 1 ];7682 style.overflowy = opts.overflow[ 2 ];7683 });7684 }7685 }7686 // show/hide pass7687 for ( prop in props ) {7688 value = props[ prop ];7689 if ( rfxtypes.exec( value ) ) {7690 delete props[ prop ];7691 toggle = toggle || value === "toggle";7692 if ( value === ( hidden ? "hide" : "show" ) ) {7693 continue;7694 }7695 orig[ prop ] = datashow && datashow[ prop ] || jquery.style( elem, prop );7696 }7697 }7698 if ( !jquery.isemptyobject( orig ) ) {7699 if ( datashow ) {7700 if ( "hidden" in datashow ) {7701 hidden = datashow.hidden;7702 }7703 } else {7704 datashow = jquery._data( elem, "fxshow", {} );7705 }7706 // store state if its toggle - enables .stop().toggle() to "reverse"7707 if ( toggle ) {7708 datashow.hidden = !hidden;7709 }7710 if ( hidden ) {7711 jquery( elem ).show();7712 } else {7713 anim.done(function() {7714 jquery( elem ).hide();7715 });7716 }7717 anim.done(function() {7718 var prop;7719 jquery._removedata( elem, "fxshow" );7720 for ( prop in orig ) {7721 jquery.style( elem, prop, orig[ prop ] );7722 }7723 });7724 for ( prop in orig ) {7725 tween = createtween( hidden ? datashow[ prop ] : 0, prop, anim );7726 if ( !( prop in datashow ) ) {7727 datashow[ prop ] = tween.start;7728 if ( hidden ) {7729 tween.end = tween.start;7730 tween.start = prop === "width" || prop === "height" ? 1 : 0;7731 }7732 }7733 }7734 }7735 }7736 function tween( elem, options, prop, end, easing ) {7737 return new tween.prototype.init( elem, options, prop, end, easing );7738 }7739 jquery.tween = tween;7740 tween.prototype = {7741 constructor: tween,7742 init: function( elem, options, prop, end, easing, unit ) {7743 this.elem = elem;7744 this.prop = prop;7745 this.easing = easing || "swing";7746 this.options = options;7747 this.start = this.now = this.cur();7748 this.end = end;7749 this.unit = unit || ( jquery.cssnumber[ prop ] ? "" : "px" );7750 },7751 cur: function() {7752 var hooks = tween.prophooks[ this.prop ];7753 return hooks && hooks.get ?7754 hooks.get( this ) :7755 tween.prophooks._default.get( this );7756 },7757 run: function( percent ) {7758 var eased,7759 hooks = tween.prophooks[ this.prop ];7760 if ( this.options.duration ) {7761 this.pos = eased = jquery.easing[ this.easing ](7762 percent, this.options.duration * percent, 0, 1, this.options.duration7763 );7764 } else {7765 this.pos = eased = percent;7766 }7767 this.now = ( this.end - this.start ) * eased + this.start;7768 if ( this.options.step ) {7769 this.options.step.call( this.elem, this.now, this );7770 }7771 if ( hooks && hooks.set ) {7772 hooks.set( this );7773 } else {7774 tween.prophooks._default.set( this );7775 }7776 return this;7777 }7778 };7779 tween.prototype.init.prototype = tween.prototype;7780 tween.prophooks = {7781 _default: {7782 get: function( tween ) {7783 var result;7784 if ( tween.elem[ tween.prop ] != null &&7785 (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {7786 return tween.elem[ tween.prop ];7787 }7788 // passing an empty string as a 3rd parameter to .css will automatically7789 // attempt a parsefloat and fallback to a string if the parse fails7790 // so, simple values such as "10px" are parsed to float.7791 // complex values such as "rotate(1rad)" are returned as is.7792 result = jquery.css( tween.elem, tween.prop, "" );7793 // empty strings, null, undefined and "auto" are converted to 0.7794 return !result || result === "auto" ? 0 : result;7795 },7796 set: function( tween ) {7797 // use step hook for back compat - use csshook if its there - use .style if its7798 // available and use plain properties where available7799 if ( jquery.fx.step[ tween.prop ] ) {7800 jquery.fx.step[ tween.prop ]( tween );7801 } else if ( tween.elem.style && ( tween.elem.style[ jquery.cssprops[ tween.prop ] ] != null || jquery.csshooks[ tween.prop ] ) ) {7802 jquery.style( tween.elem, tween.prop, tween.now + tween.unit );7803 } else {7804 tween.elem[ tween.prop ] = tween.now;7805 }7806 }7807 }7808 };7809// support: ie <=97810// panic based approach to setting things on disconnected nodes7811 tween.prophooks.scrolltop = tween.prophooks.scrollleft = {7812 set: function( tween ) {7813 if ( tween.elem.nodetype && tween.elem.parentnode ) {7814 tween.elem[ tween.prop ] = tween.now;7815 }7816 }7817 };7818 jquery.each([ "toggle", "show", "hide" ], function( i, name ) {7819 var cssfn = jquery.fn[ name ];7820 jquery.fn[ name ] = function( speed, easing, callback ) {7821 return speed == null || typeof speed === "boolean" ?7822 cssfn.apply( this, arguments ) :7823 this.animate( genfx( name, true ), speed, easing, callback );7824 };7825 });7826 jquery.fn.extend({7827 fadeto: function( speed, to, easing, callback ) {7828 // show any hidden elements after setting opacity to 07829 return this.filter( ishidden ).css( "opacity", 0 ).show()7830 // animate to the value specified7831 .end().animate({ opacity: to }, speed, easing, callback );7832 },7833 animate: function( prop, speed, easing, callback ) {7834 var empty = jquery.isemptyobject( prop ),7835 optall = jquery.speed( speed, easing, callback ),7836 doanimation = function() {7837 // operate on a copy of prop so per-property easing won't be lost7838 var anim = animation( this, jquery.extend( {}, prop ), optall );7839 // empty animations, or finishing resolves immediately7840 if ( empty || jquery._data( this, "finish" ) ) {7841 anim.stop( true );7842 }7843 };7844 doanimation.finish = doanimation;7845 return empty || optall.queue === false ?7846 this.each( doanimation ) :7847 this.queue( optall.queue, doanimation );7848 },7849 stop: function( type, clearqueue, gotoend ) {7850 var stopqueue = function( hooks ) {7851 var stop = hooks.stop;7852 delete hooks.stop;7853 stop( gotoend );7854 };7855 if ( typeof type !== "string" ) {7856 gotoend = clearqueue;7857 clearqueue = type;7858 type = undefined;7859 }7860 if ( clearqueue && type !== false ) {7861 this.queue( type || "fx", [] );7862 }7863 return this.each(function() {7864 var dequeue = true,7865 index = type != null && type + "queuehooks",7866 timers = jquery.timers,7867 data = jquery._data( this );7868 if ( index ) {7869 if ( data[ index ] && data[ index ].stop ) {7870 stopqueue( data[ index ] );7871 }7872 } else {7873 for ( index in data ) {7874 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {7875 stopqueue( data[ index ] );7876 }7877 }7878 }7879 for ( index = timers.length; index--; ) {7880 if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {7881 timers[ index ].anim.stop( gotoend );7882 dequeue = false;7883 timers.splice( index, 1 );7884 }7885 }7886 // start the next in the queue if the last step wasn't forced7887 // timers currently will call their complete callbacks, which will dequeue7888 // but only if they were gotoend7889 if ( dequeue || !gotoend ) {7890 jquery.dequeue( this, type );7891 }7892 });7893 },7894 finish: function( type ) {7895 if ( type !== false ) {7896 type = type || "fx";7897 }7898 return this.each(function() {7899 var index,7900 data = jquery._data( this ),7901 queue = data[ type + "queue" ],7902 hooks = data[ type + "queuehooks" ],7903 timers = jquery.timers,7904 length = queue ? queue.length : 0;7905 // enable finishing flag on private data7906 data.finish = true;7907 // empty the queue first7908 jquery.queue( this, type, [] );7909 if ( hooks && hooks.stop ) {7910 hooks.stop.call( this, true );7911 }7912 // look for any active animations, and finish them7913 for ( index = timers.length; index--; ) {7914 if ( timers[ index ].elem === this && timers[ index ].queue === type ) {7915 timers[ index ].anim.stop( true );7916 timers.splice( index, 1 );7917 }7918 }7919 // look for any animations in the old queue and finish them7920 for ( index = 0; index < length; index++ ) {7921 if ( queue[ index ] && queue[ index ].finish ) {7922 queue[ index ].finish.call( this );7923 }7924 }7925 // turn off finishing flag7926 delete data.finish;7927 });7928 }7929 });7930// generate parameters to create a standard animation7931 function genfx( type, includewidth ) {7932 var which,7933 attrs = { height: type },7934 i = 0;7935 // if we include width, step value is 1 to do all cssexpand values,7936 // if we don't include width, step value is 2 to skip over left and right7937 includewidth = includewidth? 1 : 0;7938 for( ; i < 4 ; i += 2 - includewidth ) {7939 which = cssexpand[ i ];7940 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;7941 }7942 if ( includewidth ) {7943 attrs.opacity = attrs.width = type;7944 }7945 return attrs;7946 }7947// generate shortcuts for custom animations7948 jquery.each({7949 slidedown: genfx("show"),7950 slideup: genfx("hide"),7951 slidetoggle: genfx("toggle"),7952 fadein: { opacity: "show" },7953 fadeout: { opacity: "hide" },7954 fadetoggle: { opacity: "toggle" }7955 }, function( name, props ) {7956 jquery.fn[ name ] = function( speed, easing, callback ) {7957 return this.animate( props, speed, easing, callback );7958 };7959 });7960 jquery.speed = function( speed, easing, fn ) {7961 var opt = speed && typeof speed === "object" ? jquery.extend( {}, speed ) : {7962 complete: fn || !fn && easing ||7963 jquery.isfunction( speed ) && speed,7964 duration: speed,7965 easing: fn && easing || easing && !jquery.isfunction( easing ) && easing7966 };7967 opt.duration = jquery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :7968 opt.duration in jquery.fx.speeds ? jquery.fx.speeds[ opt.duration ] : jquery.fx.speeds._default;7969 // normalize opt.queue - true/undefined/null -> "fx"7970 if ( opt.queue == null || opt.queue === true ) {7971 opt.queue = "fx";7972 }7973 // queueing7974 opt.old = opt.complete;7975 opt.complete = function() {7976 if ( jquery.isfunction( opt.old ) ) {7977 opt.old.call( this );7978 }7979 if ( opt.queue ) {7980 jquery.dequeue( this, opt.queue );7981 }7982 };7983 return opt;7984 };7985 jquery.easing = {7986 linear: function( p ) {7987 return p;7988 },7989 swing: function( p ) {7990 return 0.5 - math.cos( p*math.pi ) / 2;7991 }7992 };7993 jquery.timers = [];7994 jquery.fx = tween.prototype.init;7995 jquery.fx.tick = function() {7996 var timer,7997 timers = jquery.timers,7998 i = 0;7999 fxnow = jquery.now();8000 for ( ; i < timers.length; i++ ) {8001 timer = timers[ i ];8002 // checks the timer has not already been removed8003 if ( !timer() && timers[ i ] === timer ) {8004 timers.splice( i--, 1 );8005 }8006 }8007 if ( !timers.length ) {8008 jquery.fx.stop();8009 }8010 fxnow = undefined;8011 };8012 jquery.fx.timer = function( timer ) {8013 if ( timer() && jquery.timers.push( timer ) ) {8014 jquery.fx.start();8015 }8016 };8017 jquery.fx.interval = 13;8018 jquery.fx.start = function() {8019 if ( !timerid ) {8020 timerid = setinterval( jquery.fx.tick, jquery.fx.interval );8021 }8022 };8023 jquery.fx.stop = function() {8024 clearinterval( timerid );8025 timerid = null;8026 };8027 jquery.fx.speeds = {8028 slow: 600,8029 fast: 200,8030 // default speed8031 _default: 4008032 };8033// back compat <1.8 extension point8034 jquery.fx.step = {};8035 if ( jquery.expr && jquery.expr.filters ) {8036 jquery.expr.filters.animated = function( elem ) {8037 return jquery.grep(jquery.timers, function( fn ) {8038 return elem === fn.elem;8039 }).length;8040 };8041 }8042 jquery.fn.offset = function( options ) {8043 if ( arguments.length ) {8044 return options === undefined ?8045 this :8046 this.each(function( i ) {8047 jquery.offset.setoffset( this, options, i );8048 });8049 }8050 var docelem, win,8051 box = { top: 0, left: 0 },8052 elem = this[ 0 ],8053 doc = elem && elem.ownerdocument;8054 if ( !doc ) {8055 return;8056 }8057 docelem = doc.documentelement;8058 // make sure it's not a disconnected dom node8059 if ( !jquery.contains( docelem, elem ) ) {8060 return box;8061 }8062 // if we don't have gbcr, just use 0,0 rather than error8063 // blackberry 5, ios 3 (original iphone)8064 if ( typeof elem.getboundingclientrect !== core_strundefined ) {8065 box = elem.getboundingclientrect();8066 }8067 win = getwindow( doc );8068 return {8069 top: box.top + ( win.pageyoffset || docelem.scrolltop ) - ( docelem.clienttop || 0 ),8070 left: box.left + ( win.pagexoffset || docelem.scrollleft ) - ( docelem.clientleft || 0 )8071 };8072 };8073 jquery.offset = {8074 setoffset: function( elem, options, i ) {8075 var position = jquery.css( elem, "position" );8076 // set position first, in-case top/left are set even on static elem8077 if ( position === "static" ) {8078 elem.style.position = "relative";8079 }8080 var curelem = jquery( elem ),8081 curoffset = curelem.offset(),8082 curcsstop = jquery.css( elem, "top" ),8083 curcssleft = jquery.css( elem, "left" ),8084 calculateposition = ( position === "absolute" || position === "fixed" ) && jquery.inarray("auto", [curcsstop, curcssleft]) > -1,8085 props = {}, curposition = {}, curtop, curleft;8086 // need to be able to calculate position if either top or left is auto and position is either absolute or fixed8087 if ( calculateposition ) {8088 curposition = curelem.position();8089 curtop = curposition.top;8090 curleft = curposition.left;8091 } else {8092 curtop = parsefloat( curcsstop ) || 0;8093 curleft = parsefloat( curcssleft ) || 0;8094 }8095 if ( jquery.isfunction( options ) ) {8096 options = options.call( elem, i, curoffset );8097 }8098 if ( options.top != null ) {8099 props.top = ( options.top - curoffset.top ) + curtop;8100 }8101 if ( options.left != null ) {8102 props.left = ( options.left - curoffset.left ) + curleft;8103 }8104 if ( "using" in options ) {8105 options.using.call( elem, props );8106 } else {8107 curelem.css( props );8108 }8109 }8110 };8111 jquery.fn.extend({8112 position: function() {8113 if ( !this[ 0 ] ) {8114 return;8115 }8116 var offsetparent, offset,8117 parentoffset = { top: 0, left: 0 },8118 elem = this[ 0 ];8119 // fixed elements are offset from window (parentoffset = {top:0, left: 0}, because it is it's only offset parent8120 if ( jquery.css( elem, "position" ) === "fixed" ) {8121 // we assume that getboundingclientrect is available when computed position is fixed8122 offset = elem.getboundingclientrect();8123 } else {8124 // get *real* offsetparent8125 offsetparent = this.offsetparent();8126 // get correct offsets8127 offset = this.offset();8128 if ( !jquery.nodename( offsetparent[ 0 ], "html" ) ) {8129 parentoffset = offsetparent.offset();8130 }8131 // add offsetparent borders8132 parentoffset.top += jquery.css( offsetparent[ 0 ], "bordertopwidth", true );8133 parentoffset.left += jquery.css( offsetparent[ 0 ], "borderleftwidth", true );8134 }8135 // subtract parent offsets and element margins8136 // note: when an element has margin: auto the offsetleft and marginleft8137 // are the same in safari causing offset.left to incorrectly be 08138 return {8139 top: offset.top - parentoffset.top - jquery.css( elem, "margintop", true ),8140 left: offset.left - parentoffset.left - jquery.css( elem, "marginleft", true)8141 };8142 },8143 offsetparent: function() {8144 return this.map(function() {8145 var offsetparent = this.offsetparent || docelem;8146 while ( offsetparent && ( !jquery.nodename( offsetparent, "html" ) && jquery.css( offsetparent, "position") === "static" ) ) {8147 offsetparent = offsetparent.offsetparent;8148 }8149 return offsetparent || docelem;8150 });8151 }8152 });8153// create scrollleft and scrolltop methods8154 jquery.each( {scrollleft: "pagexoffset", scrolltop: "pageyoffset"}, function( method, prop ) {8155 var top = /y/.test( prop );8156 jquery.fn[ method ] = function( val ) {8157 return jquery.access( this, function( elem, method, val ) {8158 var win = getwindow( elem );8159 if ( val === undefined ) {8160 return win ? (prop in win) ? win[ prop ] :8161 win.document.documentelement[ method ] :8162 elem[ method ];8163 }8164 if ( win ) {8165 win.scrollto(8166 !top ? val : jquery( win ).scrollleft(),8167 top ? val : jquery( win ).scrolltop()8168 );8169 } else {8170 elem[ method ] = val;8171 }8172 }, method, val, arguments.length, null );8173 };8174 });8175 function getwindow( elem ) {8176 return jquery.iswindow( elem ) ?8177 elem :8178 elem.nodetype === 9 ?8179 elem.defaultview || elem.parentwindow :8180 false;8181 }8182// create innerheight, innerwidth, height, width, outerheight and outerwidth methods8183 jquery.each( { height: "height", width: "width" }, function( name, type ) {8184 jquery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultextra, funcname ) {8185 // margin is only for outerheight, outerwidth8186 jquery.fn[ funcname ] = function( margin, value ) {8187 var chainable = arguments.length && ( defaultextra || typeof margin !== "boolean" ),8188 extra = defaultextra || ( margin === true || value === true ? "margin" : "border" );8189 return jquery.access( this, function( elem, type, value ) {8190 var doc;8191 if ( jquery.iswindow( elem ) ) {8192 // as of 5/8/2012 this will yield incorrect results for mobile safari, but there8193 // isn't a whole lot we can do. see pull request at this url for discussion:8194 // https://github.com/jquery/jquery/pull/7648195 return elem.document.documentelement[ "client" + name ];8196 }8197 // get document width or height8198 if ( elem.nodetype === 9 ) {8199 doc = elem.documentelement;8200 // either scroll[width/height] or offset[width/height] or client[width/height], whichever is greatest8201 // unfortunately, this causes bug #3838 in ie6/8 only, but there is currently no good, small way to fix it.8202 return math.max(8203 elem.body[ "scroll" + name ], doc[ "scroll" + name ],8204 elem.body[ "offset" + name ], doc[ "offset" + name ],8205 doc[ "client" + name ]8206 );8207 }8208 return value === undefined ?8209 // get width or height on the element, requesting but not forcing parsefloat8210 jquery.css( elem, type, extra ) :8211 // set width or height on the element8212 jquery.style( elem, type, value, extra );8213 }, type, chainable ? margin : undefined, chainable, null );8214 };8215 });8216 });8217// limit scope pollution from any deprecated api8218// (function() {8219// the number of elements contained in the matched element set8220 jquery.fn.size = function() {8221 return this.length;8222 };8223 jquery.fn.andself = jquery.fn.addback;8224// })();8225 if ( typeof module === "object" && module && typeof module.exports === "object" ) {8226 // expose jquery as module.exports in loaders that implement the node8227 // module pattern (including browserify). do not create the global, since8228 // the user will be storing it themselves locally, and globals are frowned8229 // upon in the node module world.8230 module.exports = jquery;8231 } else {8232 // otherwise expose jquery to the global object as usual8233 window.jquery = window.$ = jquery;8234 // register as a named amd module, since jquery can be concatenated with other8235 // files that may use define, but not via a proper concatenation script that8236 // understands anonymous amd modules. a named amd is safest and most robust8237 // way to register. lowercase jquery is used because amd module names are8238 // derived from file names, and jquery is normally delivered in a lowercase8239 // file name. do this after creating the global so that if an amd module wants8240 // to call noconflict to hide this version of jquery, it will work.8241 if ( typeof define === "function" && define.amd ) {8242 define( "jquery", [], function () { return jquery; } );8243 }8244 }...

Full Screen

Full Screen

jQuery中文版v1.9.1注释全翻译.js

Source:jQuery中文版v1.9.1注释全翻译.js Github

copy

Full Screen

1/*!2 * jquery javascript library v1.9.13 * http://jquery .com/4 *5 * includes sizzle.js6 * http://sizzlejs .com/7 *8 * copyright 2005, 2012 jquery foundation, inc. and other contributors9 * released under the mit license10 * http://jquery .org/license11 *12 * 日期: 2013年2月4日13 * 翻译:刘建(毕业院校:家里蹲大学低能班)14 * 联系邮箱:243376129@qq.com15 * 原文地址:http://www.makaidong.com/laonanren/archive/2013/02/14/2912145.html16 * 翻译上的不足之处,希望大家能告诉我,我会尽量修改,本人才疏学浅,文化程度不高,希望大家多多包涵,我会努力改正。17 */18(function( window, undefined ) {19//不要做这个因为各自的应用程序包括asp.net查找20// the stack via arguments.caller.callee and firefox dies if21//你尝试查找通过“精确使用”呼叫链接(#13335)22//支持:火狐浏览器 18+23//“精确使用”;24var25 //deferred对象被使用在dom(document object model翻译:文档对象模型)准备之时26 //deferred(延迟)对象:从jquery 1.5.0版本开始引入的一个新功能27 //在dom准备好时调用28 readylist,29 //一个中心引用对于jquery 根文档30 //对根jquery 对象的主要引用31 rootjquery ,32 //支持:ie9之前的版本33 // for `typeof node.method` instead of `node.method !== undefined`34 core_strundefined = typeof undefined,35 // use the correct document accordingly with window argument (sandbox)36 document = window.document,//window文档赋值给变量document37 location = window.location,38 // map over jquery in case of overwrite(不确定,待修正,希望高人帮忙翻译一下)39 //在jquery 上绘制写在上面的实例40 //防止被覆盖41 _jquery = window.jquery ,42 // map over the $ in case of overwrite43 _$ = window.$,44 //将window正则表达式符号$赋值给变量_$45 //[类]:成双类型46 class2type = {},47 //在贮存区被删除数据id的列表,我们能够再用他们48 core_deletedids = [],49 core_version = "1.9.1",50 //保存一个参考给一些核心的方法51 //为核心方法创建引用52 core_concat = core_deletedids.concat,53 core_push = core_deletedids.push,54 core_slice = core_deletedids.slice,55 core_indexof = core_deletedids.indexof,56 core_tostring = class2type.tostring,57 core_hasown = class2type.hasownproperty,58 core_trim = core_version.trim,59 //规定一个jquery 本地代码60 //构建jquery 对象61 jquery = function( selector, context ) {62 //jquery 对象是实际上初始化名为enhanced(提高的)构造器63 //jquery 对象实际上只是增强的初始化构造方法64 return new jquery .fn.init( selector, context, rootjquery );65 },66 /* 用来匹配数字的正则,匹配可选正负号、浮点型、整型、科学 计数法67 * 没有使用(?)来表示可选而是通过(|)来选择68 * (?:\d*\.|)匹配浮点数时,|前的\d*\.可以匹配整数部分和小数点,小数部分由后面的\d+匹配69 * 匹配整数时,|)可以保证匹配继续向下进行,整数由后面的\d+匹配,同样的\d+在匹配整型和浮点型时负责的匹配部分不同70 * [ee][\-+]?\d+|)处理科学 计数法的匹配,同样没有使用?表示可选71 */72 core_pnum = /[+-]?(?:\d*\.|)\d+(?:[ee][+-]?\d+|)/.source,73 //用于分开空格74 core_rnotwhite = /\s+/g,75 //查找非空白字符串76 // make sure we trim bom and nbsp (here's looking at you, safari 5.0 and ie)77 rtrim = /^[\s\ufeff\xa0]+|[\s\ufeff\xa0]+$/g,78 //\ufeff:字节顺序标志79 //一个简单途径用于检查html字符串80 // prioritize #id over <tag> to avoid xss via location.hash (#9521)81 // strict html recognition (#11290: must start with <)82 rquickexpr = /^(?:(<[\w\w]+>)[^>]*|#([\w-]*))$/,83 //匹配一个独立的标签84 rsingletag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,85 // js on regexp(javascript object notation:javascript对象标记法正则表达式)86 rvalidchars = /^[\],:{}\s]*$/,87 rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,88 rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fa-f]{4})/g,89 rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[ee][+-]?\d+|)/g,90 // matches dashed string for camelizing91 rmsprefix = /^-ms-/,92 rdashalpha = /-([\da-z])/gi,93 //以上为正则运算表达式各种形式94此文来自: 马开东博客 转载请注明出处 网址: http://www.makaidong.com95,不太容易理解,尽量掌握。96 //使用jquery .camecase(camel-case:骆驼事例标记法)作为replce()函数(替换函数)的回调函数97 fcamelcase = function( all, letter ) {98 return letter.touppercase();99 },100 //准备事件管理语句101 completed = function( event ) {102 // readystate === "complete" is good enough for us to call the dom ready in oldie103 if ( document.addeventlistener || event.type === "load" || document.readystate === "complete" ) {104 detach();105 jquery .ready();106 }107 },108 //为dom准备事件清理方法109 detach = function() {110 if ( document.addeventlistener ) {111 document.removeeventlistener( "domcontentloaded", completed, false );112 window.removeeventlistener( "load", completed, false );113 } else {114 document.detachevent( "onreadystatechange", completed );115 window.detachevent( "onload", completed );116 }117 };118jquery .fn = jquery .prototype = {119 // the current version of jquery being used120 jquery : core_version,121 constructor: jquery ,122 init: function( selector, context, rootjquery ) {123 var match, elem;124 //handle(句柄):$(""), $(null), $(undefined), $(false)125 if ( !selector ) {126 return this;127 }128 //html字符串句柄129 if ( typeof selector === "string" ) {//如果(选择器的类型等于字符串130 if ( selector.charat(0) === "<" && selector.charat( selector.length - 1 ) === ">" && selector.length >= 3 ) {131 // assume that strings that start and end with <> are html and skip the regex check132 match = [ null, selector, null ];133 } else {134 match = rquickexpr.exec( selector );135 }136 // match html or make sure no context is specified for #id137 //匹配html或者确认对于#id没有环境是规定的138 if ( match && (match[1] || !context) ) {139 // handle: $(html) -> $(array)140 if ( match[1] ) {141 context = context instanceof jquery ? context[0] : context;142 // 脚本向后兼容143 jquery .merge( this, jquery .parsehtml(144 match[1],145 context && context.nodetype ? context.ownerdocument || context : document,146 true147 ) );148 //处理: $(html, props)149 if ( rsingletag.test( match[1] ) && jquery .isplainobject( context ) ) {150 for ( match in context ) {151 // properties of context are called as methods if possible152 //如果可能上下文的性质被访问153 if ( jquery .isfunction( this[ match ] ) ) {154 this[ match ]( context[ match ] );155 // ...and otherwise set as attributes156 } else {157 this.attr( match, context[ match ] );158 }159 }160 }161 return this;162 // handle: $(#id)163 // 处理: $(#id)164 } else {165 elem = document.getelementbyid( match[2] );166 // check parentnode to catch when blackberry 4.6 returns167 //节点不再在文档中 #6963168 if ( elem && elem.parentnode ) {169 // handle the case where ie and opera return items170 // 处理事件无论ie和opera把项目返回到哪里171 // by name instead of id172 // 用名字替代id173 if ( elem.id !== match[2] ) {174 return rootjquery .find( selector );175 }176 // otherwise, we inject the element directly into the jquery object177 this.length = 1;178 this[0] = elem;179 }180 this.context = document;181 this.selector = selector;182 return this;183 }184 // handle: $(expr, $(...))185 } else if ( !context || context.jquery ) {186 return ( context || rootjquery ).find( selector );187 // handle: $(expr, context)188 // (which is just equivalent to: $(context).find(expr)189 } else {190 return this.constructor( context ).find( selector );191 }192 // handle: $(domelement)193 } else if ( selector.nodetype ) {194 this.context = this[0] = selector;195 this.length = 1;196 return this;197 // handle: $(function)198 // shortcut for document ready199 } else if ( jquery .isfunction( selector ) ) {200 return rootjquery .ready( selector );201 }202 if ( selector.selector !== undefined ) {203 this.selector = selector.selector;204 this.context = selector.context;205 }206 return jquery .makearray( selector, this );207 },208 // start with an empty selector209 // 用一个空选择器开始210 selector: "",211 // the default length of a jquery object is 0212 length: 0,213 // the number of elements contained in the matched element set214 // 匹配事件集包含事件的数量215 size: function() {216 return this.length;217 },218 toarray: function() {219 return core_slice.call( this );220 },221 // get the nth element in the matched element set or222 // get the whole matched element set as a clean array223 get: function( num ) {224 return num == null ?225 // return a 'clean' array226 this.toarray() :227 // return just the object228 ( num < 0 ? this[ this.length + num ] : this[ num ] );229 },230 // take an array of elements and push it onto the stack231 // (returning the new matched element set)232 pushstack: function( elems ) {233 // build a new jquery matched element set234 var ret = jquery .merge( this.constructor(), elems );235 // add the old object onto the stack (as a reference)236 ret.prevobject = this;237 ret.context = this.context;238 // return the newly-formed element set239 return ret;240 },241 // execute a callback for every element in the matched set.242 // (you can seed the arguments with an array of args, but this is243 // only used internally.)244 each: function( callback, args ) {245 return jquery .each( this, callback, args );246 },247 ready: function( fn ) {248 // add the callback249 // 增加回调函数250 jquery .ready.promise().done( fn );251 return this;252 },253 slice: function() {254 return this.pushstack( core_slice.apply( this, arguments ) );255 },256 first: function() {257 return this.eq( 0 );258 },259 last: function() {260 return this.eq( -1 );261 },262 eq: function( i ) {263 var len = this.length,264 j = +i + ( i < 0 ? len : 0 );265 return this.pushstack( j >= 0 && j < len ? [ this[j] ] : [] );266 },267 map: function( callback ) {268 return this.pushstack( jquery .map(this, function( elem, i ) {269 return callback.call( elem, i, elem );270 }));271 },272 end: function() {273 return this.prevobject || this.constructor(null);274 },275 // for internal use only.276 // 只是为了内部使用277 // behaves like an array's method, not like a jquery method.278 push: core_push,279 sort: [].sort,280 splice: [].splice281};282// give the init function the jquery prototype for later instantiation283jquery .fn.init.prototype = jquery .fn;284jquery .extend = jquery .fn.extend = function() {285 var src, copyisarray, copy, name, options, clone,286 target = arguments[0] || {},287 i = 1,288 length = arguments.length,289 deep = false;290 // handle a deep copy situation291 if ( typeof target === "boolean" ) {292 deep = target;293 target = arguments[1] || {};294 // skip the boolean and the target295 i = 2;296 }297 // handle case when target is a string or something (possible in deep copy)298 if ( typeof target !== "object" && !jquery .isfunction(target) ) {299 target = {};300 }301 // extend jquery itself if only one argument is passed302 if ( length === i ) {303 target = this;304 --i;305 }306 for ( ; i < length; i++ ) {307 // only deal with non-null/undefined values308 if ( (options = arguments[ i ]) != null ) {309 // extend the base object310 for ( name in options ) {311 src = target[ name ];312 copy = options[ name ];313 // prevent never-ending loop314 if ( target === copy ) {315 continue;316 }317 // recurse if we're merging plain objects or arrays318 if ( deep && copy && ( jquery .isplainobject(copy) || (copyisarray = jquery .isarray(copy)) ) ) {319 if ( copyisarray ) {320 copyisarray = false;321 clone = src && jquery .isarray(src) ? src : [];322 } else {323 clone = src && jquery .isplainobject(src) ? src : {};324 }325 // never move original objects, clone them326 target[ name ] = jquery .extend( deep, clone, copy );327 // don't bring in undefined values328 } else if ( copy !== undefined ) {329 target[ name ] = copy;330 }331 }332 }333 }334 // return the modified object335 // 返回被修改的对象336 return target;337};338jquery .extend({339 noconflict: function( deep ) {340 if ( window.$ === jquery ) {341 window.$ = _$;342 }343 if ( deep && window.jquery === jquery ) {344 window.jquery = _jquery ;345 }346 return jquery ;347 },348 // is the dom ready to be used? set to true once it occurs.349 // dom文档是否准备被使用?一旦发生就设置为真。350 isready: false,351 // a counter to track how many items to wait for before352 // 一个计数器跟踪多少项目等待353 // the ready event fires. see #6781354 // 准备好的事件。请看#6781355 readywait: 1,356 // hold (or release) the ready event357 // 控制(或者释放)准备的事件358 holdready: function( hold ) {359 if ( hold ) {360 jquery .readywait++;361 } else {362 jquery .ready( true );363 }364 },365 // handle when the dom is ready366 // 操纵dom文档何时被准备367 ready: function( wait ) {368 // abort if there are pending holds or we're already ready369 // 终止如果有待定的holds或者已经准备好了370 if ( wait === true ? --jquery .readywait : jquery .isready ) {371 return;372 }373 // make sure body exists, at least, in case ie gets a little overzealous (ticket #5443).374 //375 if ( !document.body ) {376 return settimeout( jquery .ready );377 }378 // remember that the dom is ready379 // 记住文件对象模型(dom)正在准备380 jquery .isready = true;381 // if a normal dom ready event fired, decrement, and wait if need be382 if ( wait !== true && --jquery .readywait > 0 ) {383 return;384 }385 // if there are functions bound, to execute386 readylist.resolvewith( document, [ jquery ] );387 // trigger any bound ready events388 if ( jquery .fn.trigger ) {389 jquery ( document ).trigger("ready").off("ready");390 }391 },392 // see test/unit/core.js for details concerning isfunction.393 // since version 1.3, dom methods and functions like alert394 // aren't supported. they return false on ie (#2968).395 isfunction: function( obj ) {396 return jquery .type(obj) === "function";397 },398 isarray: array.isarray || function( obj ) {399 return jquery .type(obj) === "array";400 },401 iswindow: function( obj ) {402 return obj != null && obj == obj.window;403 },404 isnumeric: function( obj ) {405 return !isnan( parsefloat(obj) ) && isfinite( obj );406 },407 type: function( obj ) {408 if ( obj == null ) {409 return string( obj );410 }411 return typeof obj === "object" || typeof obj === "function" ?412 class2type[ core_tostring.call(obj) ] || "object" :413 typeof obj;414 },415 isplainobject: function( obj ) {416 // must be an object.417 // 必须是对象418 // because of ie, we also have to check the presence of the constructor property.419 // 由于ie的原因,我们必须检查存在的构造器属性420 // make sure that dom nodes and window objects don't pass through, as well421 // 还有确保dom节点和window对象不被传进来422 if ( !obj || jquery .type(obj) !== "object" || obj.nodetype || jquery .iswindow( obj ) ) {423 return false;424 }425 try {426 // not own constructor property must be object427 // 拥有的构造器属性不一定是对象428 if ( obj.constructor &&429 !core_hasown.call(obj, "constructor") &&430 !core_hasown.call(obj.constructor.prototype, "isprototypeof") ) {431 return false;432 }433 } catch ( e ) {434 // ie8,9 will throw exceptions on certain host objects #9897435 // ie8,9将会扔出例外在某些主机对象#9897436 return false;437 }438 // own properties are enumerated firstly, so to speed up,439 // 首先列举拥有的属性,为了加速,只判断最后一个440 // if last one is own, then all properties are own.441 // 如果含有最后一个属性,那么含有所有的属性442 var key;443 for ( key in obj ) {}444 return key === undefined || core_hasown.call( obj, key );445 //遍历对象中的变量key返回key没有找到446 },447 isemptyobject: function( obj ) {448 var name;449 for ( name in obj ) {450 return false;451 }452 return true;453 },454 error: function( msg ) {455 throw new error( msg );456 },457 // data: string of html458 // 数据:html的字符串459 // context (optional): if specified, the fragment will be created in this context, defaults to document460 // 上下文内容(任意的):如果被指定,片段会被创建到该上下文上,默认是创建在文档上461 // keepscripts (optional): if true, will include scripts passed in the html string462 // 保留脚本(可选的):如果为真,包含的脚本在html字符串中会通过463 parsehtml: function( data, context, keepscripts ) {// 解析html字符串,生成相应的dom元素并返回464 if ( !data || typeof data !== "string" ) {465 return null;466 }467 if ( typeof context === "boolean" ) {// 如果context是布尔类型,则将context的值赋给keepscripts,并将context设置为假468 keepscripts = context;469 context = false;470 }471 context = context || document;472 var parsed = rsingletag.exec( data ),473 scripts = !keepscripts && [];474 // single tag475 // 单独的标签476 if ( parsed ) {477 return [ context.createelement( parsed[1] ) ];478 }479 parsed = jquery .buildfragment( [ data ], context, scripts );480 if ( scripts ) {481 jquery ( scripts ).remove();482 }483 return jquery .merge( [], parsed.childnodes );484 },485 parsejs on: function( data ) {486 // attempt to parse using the native js on parser first487 if ( window.js on && window.js on.parse ) {488 return window.js on.parse( data );489 }490 if ( data === null ) {491 return data;492 }493 if ( typeof data === "string" ) {494 // make sure leading/trailing whitespace is removed (ie can't handle it)495 // 确认开头、末尾空白符号已被移走(ie无法操作)496 data = jquery .trim( data );497 if ( data ) {498 // make sure the incoming data is actual js on499 // 确认输入的数据现在的js on数据500 // logic borrowed from http://js on.org/js on2.js501 // 从http://js on.org/js on2.js 中借用逻辑502 if ( rvalidchars.test( data.replace( rvalidescape, "@" )503 .replace( rvalidtokens, "]" )504 .replace( rvalidbraces, "")) ) {505 return ( new function( "return " + data ) )();506 }507 }508 }509 jquery .error( "invalid js on: " + data );510 },511 // cross-browser xml parsing512 // 跨浏览器开发 的xml解析513 parsexml: function( data ) {514 var xml, tmp;515 if ( !data || typeof data !== "string" ) {516 return null;//如果传入的数据类型不是字符517此文来自: 马开东博客 转载请注明出处 网址: http://www.makaidong.com518串,返回空值。519 }520 try {521 if ( window.domparser ) { // standard(标准)522 tmp = new domparser();523 xml = tmp.parsefromstring( data , "text/xml" );524 } else { // ie525 xml = new activexobject( "microsoft.xmldom" );526 xml.async = "false";527 xml.loadxml( data );528 }529 } catch( e ) {530 xml = undefined;531 }532 if ( !xml || !xml.documentelement || xml.getelementsbytagname( "parsererror" ).length ) {533 jquery .error( "invalid xml: " + data );534 }535 return xml;536 },537 noop: function() {},538 // evaluates a script in a global context539 // 在全局上下文中执行脚本540 // workarounds based on findings by jim driscoll541 // 工作环境基于jim driscoll的发现542 // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context543 // 上面提到那人的一篇文章544 globaleval: function( data ) {545 if ( data && jquery .trim( data ) ) {546 // we use execscript on internet explorer547 // we use an anonymous function so that context is window548 // rather than jquery in firefox549 ( window.execscript || function( data ) {550 window[ "eval" ].call( window, data );551 } )( data );552 }553 },554 // convert dashed to camelcase; used by the css and data modules555 // microsoft forgot to hump their vendor prefix (#9572)556 camelcase: function( string ) {557 return string.replace( rmsprefix, "ms-" ).replace( rdashalpha, fcamelcase );558 },559 nodename: function( elem, name ) {560 return elem.nodename && elem.nodename.tolowercase() === name.tolowercase();561 },562 // args is for internal usage only563 each: function( obj, callback, args ) {564 var value,565 i = 0,566 length = obj.length,567 isarray = isarraylike( obj );568 if ( args ) {569 if ( isarray ) {570 for ( ; i < length; i++ ) {571 value = callback.apply( obj[ i ], args );572 if ( value === false ) {573 break;574 }575 }576 } else {577 for ( i in obj ) {578 value = callback.apply( obj[ i ], args );579 if ( value === false ) {580 break;581 }582 }583 }584 //一个特殊的,快速的,实例用于每个大部分普通应用585 } else {586 if ( isarray ) {587 for ( ; i < length; i++ ) {588 value = callback.call( obj[ i ], i, obj[ i ] );589 if ( value === false ) {590 break;591 }592 }593 } else {594 for ( i in obj ) {595 value = callback.call( obj[ i ], i, obj[ i ] );596 if ( value === false ) {597 break;598 }599 }600 }601 }602 return obj;603 },604 // use native string.trim function wherever possible605 trim: core_trim && !core_trim.call("\ufeff\xa0") ?606 function( text ) {607 return text == null ?608 "" :609 core_trim.call( text );610 } :611 // otherwise use our own trimming functionality612 function( text ) {613 return text == null ?614 "" :615 ( text + "" ).replace( rtrim, "" );616 },617 // results is for internal usage only618 makearray: function( arr, results ) {619 var ret = results || [];620 if ( arr != null ) {621 if ( isarraylike( object(arr) ) ) {622 jquery .merge( ret,623 typeof arr === "string" ?624 [ arr ] : arr625 );626 } else {627 core_push.call( ret, arr );628 }629 }630 return ret;631 },632 inarray: function( elem, arr, i ) {633 var len;634 if ( arr ) {635 if ( core_indexof ) {636 return core_indexof.call( arr, elem, i );637 }638 len = arr.length;639 i = i ? i < 0 ? math.max( 0, len + i ) : i : 0;640 for ( ; i < len; i++ ) {641 // skip accessing in sparse arrays642 if ( i in arr && arr[ i ] === elem ) {643 return i;644 }645 }646 }647 return -1;648 },649 merge: function( first, second ) {650 var l = second.length,651 i = first.length,652 j = 0;653 if ( typeof l === "number" ) {654 for ( ; j < l; j++ ) {655 first[ i++ ] = second[ j ];656 }657 } else {658 while ( second[j] !== undefined ) {659 first[ i++ ] = second[ j++ ];660 }661 }662 first.length = i;663 return first;664 },665 grep: function( elems, callback, inv ) {666 var retval,667 ret = [],668 i = 0,669 length = elems.length;670 inv = !!inv;671 // go through the array, only saving the items672 // that pass the validator function673 for ( ; i < length; i++ ) {674 retval = !!callback( elems[ i ], i );675 if ( inv !== retval ) {676 ret.push( elems[ i ] );677 }678 }679 return ret;680 },681 // arg is for internal usage only682 map: function( elems, callback, arg ) {683 var value,684 i = 0,685 length = elems.length,686 isarray = isarraylike( elems ),687 ret = [];688 // go through the array, translating each of the items to their689 if ( isarray ) {690 for ( ; i < length; i++ ) {691 value = callback( elems[ i ], i, arg );692 if ( value != null ) {693 ret[ ret.length ] = value;694 }695 }696 // go through every key on the object,697 } else {698 for ( i in elems ) {699 value = callback( elems[ i ], i, arg );700 if ( value != null ) {701 ret[ ret.length ] = value;702 }703 }704 }705 // flatten any nested arrays706 return core_concat.apply( [], ret );707 },708 // a global guid counter for objects709 guid: 1,710 // bind a function to a context, optionally partially applying any711 // arguments.712 proxy: function( fn, context ) {713 var args, proxy, tmp;714 if ( typeof context === "string" ) {715 tmp = fn[ context ];716 context = fn;717 fn = tmp;718 }719 // quick check to determine if target is callable, in the spec720 // this throws a typeerror, but we will just return undefined.721 if ( !jquery .isfunction( fn ) ) {722 return undefined;723 }724 // simulated bind725 args = core_slice.call( arguments, 2 );726 proxy = function() {727 return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) );728 };729 // set the guid of unique handler to the same of original handler, so it can be removed730 proxy.guid = fn.guid = fn.guid || jquery .guid++;731 return proxy;732 },733 // multifunctional method to get and set values of a collection734 // the value/s can optionally be executed if it's a function735 access: function( elems, fn, key, value, chainable, emptyget, raw ) {736 var i = 0,737 length = elems.length,738 bulk = key == null;739 // sets many values740 if ( jquery .type( key ) === "object" ) {741 chainable = true;742 for ( i in key ) {743 jquery .access( elems, fn, i, key[i], true, emptyget, raw );744 }745 // sets one value746 } else if ( value !== undefined ) {747 chainable = true;748 if ( !jquery .isfunction( value ) ) {749 raw = true;750 }751 if ( bulk ) {752 // bulk operations run against the entire set753 if ( raw ) {754 fn.call( elems, value );755 fn = null;756 // ...except when executing function values757 } else {758 bulk = fn;759 fn = function( elem, key, value ) {760 return bulk.call( jquery ( elem ), value );761 };762 }763 }764 if ( fn ) {765 for ( ; i < length; i++ ) {766 fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );767 }768 }769 }770 return chainable ?771 elems :772 // gets773 bulk ?774 fn.call( elems ) :775 length ? fn( elems[0], key ) : emptyget;776 },777 now: function() {778 return ( new date() ).gettime();779 }780});781jquery .ready.promise = function( obj ) {782 if ( !readylist ) {783 readylist = jquery .deferred();784 // catch cases where $(document).ready() is called after the browser event has already occurred.785 // we once tried to use readystate "interactive" here, but it caused issues like the one786 // discovered by chriss here: http://bugs.jquery .com/ticket/12282#comment:15787 if ( document.readystate === "complete" ) {788 // handle it asynchronously to allow scripts the opportunity to delay ready789 settimeout( jquery .ready );790 // standards-based browsers support domcontentloaded791 } else if ( document.addeventlistener ) {792 // use the handy event callback793 document.addeventlistener( "domcontentloaded", completed, false );794 // a fallback to window.onload, that will always work795 window.addeventlistener( "load", completed, false );796 // if ie event model is used797 } else {798 // ensure firing before onload, maybe late but safe also for iframes799 document.attachevent( "onreadystatechange", completed );800 // a fallback to window.onload, that will always work801 window.attachevent( "onload", completed );802 // if ie and not a frame803 // continually check to see if the document is ready804 var top = false;805 try {806 top = window.frameelement == null && document.documentelement;807 } catch(e) {}808 if ( top && top.doscroll ) {809 (function doscrollcheck() {810 if ( !jquery .isready ) {811 try {812 // use the trick by diego perini813 // http://javascript.nwbox.com/iecontentloaded/814 top.doscroll("left");815 } catch(e) {816 return settimeout( doscrollcheck, 50 );817 }818 // detach all dom ready events819 detach();820 // and execute any waiting functions821 jquery .ready();822 }823 })();824 }825 }826 }827 return readylist.promise( obj );828};829// populate the class2type map830jquery .each("boolean number string function array date regexp object error".split(" "), function(i, name) {831 class2type[ "[object " + name + "]" ] = name.tolowercase();832});833function isarraylike( obj ) {834 var length = obj.length,835 type = jquery .type( obj );836 if ( jquery .iswindow( obj ) ) {837 return false;838 }839 if ( obj.nodetype === 1 && length ) {840 return true;841 }842 return type === "array" || type !== "function" &&843 ( length === 0 ||844 typeof length === "number" && length > 0 && ( length - 1 ) in obj );845}846// all jquery objects should point back to these847rootjquery = jquery (document);848// string to object options format cache849var optionscache = {};850// convert string-formatted options into object-formatted ones and store in cache851function createoptions( options ) {852 var object = optionscache[ options ] = {};853 jquery .each( options.match( core_rnotwhite ) || [], function( _, flag ) {854 object[ flag ] = true;855 });856 return object;857}858/*859 * create a callback list using the following parameters:860 *861 * options: an optional list of space-separated options that will change how862 * the callback list behaves or a more traditional option object863 *864 * by default a callback list will act like an event callback list and can be865 * "fired" multiple times.866 *867 * possible options:868 *869 * once: will ensure the callback list can only be fired once (like a deferred)870 *871 * memory: will keep track of previous values and will call any callback added872 * after the list has been fired right away with the latest "memorized"873 * values (like a deferred)874 *875 * unique: will ensure a callback can only be added once (no duplicate in the list)876 *877 * stoponfalse: interrupt callings when a callback returns false878 *879 */880jquery .callbacks = function( options ) {881 // convert options from string-formatted to object-formatted if needed882 // (we check in cache first)883 options = typeof options === "string" ?884 ( optionscache[ options ] || createoptions( options ) ) :885 jquery .extend( {}, options );886 var // flag to know if list is currently firing887 firing,888 // last fire value (for non-forgettable lists)889 memory,890 // flag to know if list was already fired891 fired,892 // end of the loop when firing893 firinglength,894 // index of currently firing callback (modified by remove if needed)895 firingindex,896 // first callback to fire (used internally by add and firewith)897 firingstart,898 // actual callback list899 list = [],900 // stack of fire calls for repeatable lists901 stack = !options.once && [],902 // fire callbacks903 fire = function( data ) {904 memory = options.memory && data;905 fired = true;906 firingindex = firingstart || 0;907 firingstart = 0;908 firinglength = list.length;909 firing = true;910 for ( ; list && firingindex < firinglength; firingindex++ ) {911 if ( list[ firingindex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stoponfalse ) {912 memory = false; // to prevent further calls using add913 break;914 }915 }916 firing = false;917 if ( list ) {918 if ( stack ) {919 if ( stack.length ) {920 fire( stack.shift() );921 }922 } else if ( memory ) {923 list = [];924 } else {925 self.disable();926 }927 }928 },929 // actual callbacks object930 self = {931 // add a callback or a collection of callbacks to the list932 add: function() {933 if ( list ) {934 // first, we save the current length935 var start = list.length;936 (function add( args ) {937 jquery .each( args, function( _, arg ) {938 var type = jquery .type( arg );939 if ( type === "function" ) {940 if ( !options.unique || !self.has( arg ) ) {941 list.push( arg );942 }943 } else if ( arg && arg.length && type !== "string" ) {944 // inspect recursively945 add( arg );946 }947 });948 })( arguments );949 // do we need to add the callbacks to the950 // current firing batch?951 if ( firing ) {952 firinglength = list.length;953 // with memory, if we're not firing then954 // we should call right away955 } else if ( memory ) {956 firingstart = start;957 fire( memory );958 }959 }960 return this;961 },962 // remove a callback from the list963 remove: function() {964 if ( list ) {965 jquery .each( arguments, function( _, arg ) {966 var index;967 while( ( index = jquery .inarray( arg, list, index ) ) > -1 ) {968 list.splice( index, 1 );969 // handle firing indexes970 if ( firing ) {971 if ( index <= firinglength ) {972 firinglength--;973 }974 if ( index <= firingindex ) {975 firingindex--;976 }977 }978 }979 });980 }981 return this;982 },983 // check if a given callback is in the list.984 // if no argument is given, return whether or not list has callbacks attached.985 has: function( fn ) {986 return fn ? jquery .inarray( fn, list ) > -1 : !!( list && list.length );987 },988 // remove all callbacks from the list989 empty: function() {990 list = [];991 return this;992 },993 // have the list do nothing anymore994 disable: function() {995 list = stack = memory = undefined;996 return this;997 },998 // is it disabled?999 disabled: function() {1000 return !list;1001 },1002 // lock the list in its current state1003 lock: function() {1004 stack = undefined;1005 if ( !memory ) {1006 self.disable();1007 }1008 return this;1009 },1010 // is it locked?1011 locked: function() {1012 return !stack;1013 },1014 // call all callbacks with the given context and arguments1015 firewith: function( context, args ) {1016 args = args || [];1017 args = [ context, args.slice ? args.slice() : args ];1018 if ( list && ( !fired || stack ) ) {1019 if ( firing ) {1020 stack.push( args );1021 } else {1022 fire( args );1023 }1024 }1025 return this;1026 },1027 // call all the callbacks with the given arguments1028 fire: function() {1029 self.firewith( this, arguments );1030 return this;1031 },1032 // to know if the callbacks have already been called at least once1033 fired: function() {1034 return !!fired;1035 }1036 };1037 return self;1038};1039jquery .extend({1040 deferred: function( func ) {1041 var tuples = [1042 // action, add listener, listener list, final state1043 [ "resolve", "done", jquery .callbacks("once memory"), "resolved" ],1044 [ "reject", "fail", jquery .callbacks("once memory"), "rejected" ],1045 [ "notify", "progress", jquery .callbacks("memory") ]1046 ],1047 state = "pending",1048 promise = {1049 state: function() {1050 return state;1051 },1052 always: function() {1053 deferred.done( arguments ).fail( arguments );1054 return this;1055 },1056 then: function( /* fndone, fnfail, fnprogress */ ) {1057 var fns = arguments;1058 return jquery .deferred(function( newdefer ) {1059 jquery .each( tuples, function( i, tuple ) {1060 var action = tuple[ 0 ],1061 fn = jquery .isfunction( fns[ i ] ) && fns[ i ];1062 // deferred[ done | fail | progress ] for forwarding actions to newdefer1063 deferred[ tuple[1] ](function() {1064 var returned = fn && fn.apply( this, arguments );1065 if ( returned && jquery .isfunction( returned.promise ) ) {1066 returned.promise()1067 .done( newdefer.resolve )1068 .fail( newdefer.reject )1069 .progress( newdefer.notify );1070 } else {1071 newdefer[ action + "with" ]( this === promise ? newdefer.promise() : this, fn ? [ returned ] : arguments );1072 }1073 });1074 });1075 fns = null;1076 }).promise();1077 },1078 // get a promise for this deferred1079 // if obj is provided, the promise aspect is added to the object1080 promise: function( obj ) {1081 return obj != null ? jquery .extend( obj, promise ) : promise;1082 }1083 },1084 deferred = {};1085 // keep pipe for back-compat1086 promise.pipe = promise.then;1087 // add list-specific methods1088 jquery .each( tuples, function( i, tuple ) {1089 var list = tuple[ 2 ],1090 statestring = tuple[ 3 ];1091 // promise[ done | fail | progress ] = list.add1092 promise[ tuple[1] ] = list.add;1093 // handle state1094 if ( statestring ) {1095 list.add(function() {1096 // state = [ resolved | rejected ]1097 state = statestring;1098 // [ reject_list | resolve_list ].disable; progress_list.lock1099 }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );1100 }1101 // deferred[ resolve | reject | notify ]1102 deferred[ tuple[0] ] = function() {1103 deferred[ tuple[0] + "with" ]( this === deferred ? promise : this, arguments );1104 return this;1105 };1106 deferred[ tuple[0] + "with" ] = list.firewith;1107 });1108 // make the deferred a promise1109 promise.promise( deferred );1110 // call given func if any1111 if ( func ) {1112 func.call( deferred, deferred );1113 }1114 // all done!1115 return deferred;1116 },1117 // deferred helper1118 when: function( subordinate /* , ..., subordinaten */ ) {1119 var i = 0,1120 resolvevalues = core_slice.call( arguments ),1121 length = resolvevalues.length,1122 // the count of uncompleted subordinates1123 remaining = length !== 1 || ( subordinate && jquery .isfunction( subordinate.promise ) ) ? length : 0,1124 // the master deferred. if resolvevalues consist of only a single deferred, just use that.1125 deferred = remaining === 1 ? subordinate : jquery .deferred(),1126 // update function for both resolve and progress values1127 updatefunc = function( i, contexts, values ) {1128 return function( value ) {1129 contexts[ i ] = this;1130 values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;1131 if( values === progressvalues ) {1132 deferred.notifywith( contexts, values );1133 } else if ( !( --remaining ) ) {1134 deferred.resolvewith( contexts, values );1135 }1136 };1137 },1138 progressvalues, progresscontexts, resolvecontexts;1139 // add listeners to deferred subordinates; treat others as resolved1140 if ( length > 1 ) {1141 progressvalues = new array( length );1142 progresscontexts = new array( length );1143 resolvecontexts = new array( length );1144 for ( ; i < length; i++ ) {1145 if ( resolvevalues[ i ] && jquery .isfunction( resolvevalues[ i ].promise ) ) {1146 resolvevalues[ i ].promise()1147 .done( updatefunc( i, resolvecontexts, resolvevalues ) )1148 .fail( deferred.reject )1149 .progress( updatefunc( i, progresscontexts, progressvalues ) );1150 } else {1151 --remaining;1152 }1153 }1154 }1155 // if we're not waiting on anything, resolve the master1156 if ( !remaining ) {1157 deferred.resolvewith( resolvecontexts, resolvevalues );1158 }1159 return deferred.promise();1160 }1161});1162jquery .support = (function() {1163 var support, all, a,1164 input, select, fragment,1165 opt, eventname, issupported, i,1166 div = document.createelement("div");1167 // setup1168 div.setattribute( "classname", "t" );1169 div.innerhtml = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";1170 // support tests won't run in some limited or non-browser environments1171 all = div.getelementsbytagname("*");1172 a = div.getelementsbytagname("a")[ 0 ];1173 if ( !all || !a || !all.length ) {1174 return {};1175 }1176 // first batch of tests1177 select = document.createelement("select");1178 opt = select.appendchild( document.createelement("option") );1179 input = div.getelementsbytagname("input")[ 0 ];1180 a.style.csstext = "top:1px;float:left;opacity:.5";1181 support = {1182 // test setattribute on camelcase class. if it works, we need attrfixes when doing get/setattribute (ie6/7)1183 getsetattribute: div.classname !== "t",1184 // ie strips leading whitespace when .innerhtml is used1185 leadingwhitespace: div.firstchild.nodetype === 3,1186 // make sure that tbody elements aren't automatically inserted1187 // ie will insert them into empty tables1188 tbody: !div.getelementsbytagname("tbody").length,1189 // make sure that link elements get serialized correctly by innerhtml1190 // this requires a wrapper element in ie1191 htmlserialize: !!div.getelementsbytagname("link").length,1192 // get the style information from getattribute1193 // (ie uses .csstext instead)1194 style: /top/.test( a.getattribute("style") ),1195 // make sure that urls aren't manipulated1196 // (ie normalizes it by default)1197 hrefnormalized: a.getattribute("href") === "/a",1198 // make sure that element opacity exists1199 // (ie uses filter instead)1200 // use a regex to work around a webkit issue. see #51451201 opacity: /^0.5/.test( a.style.opacity ),1202 // verify style float existence1203 // (ie uses stylefloat instead of cssfloat)1204 cssfloat: !!a.style.cssfloat,1205 // check the default checkbox/radio value ("" on webkit; "on" elsewhere)1206 checkon: !!input.value,1207 // make sure that a selected-by-default option has a working selected property.1208 // (webkit defaults to false instead of true, ie too, if it's in an optgroup)1209 optselected: opt.selected,1210 // tests for enctype support on a form (#6743)1211 enctype: !!document.createelement("form").enctype,1212 // makes sure cloning an html5 element does not cause problems1213 // where outerhtml is undefined, this still works1214 html5clone: document.createelement("nav").clonenode( true ).outerhtml !== "<:nav></:nav>",1215 // jquery .support.boxmodel deprecated in 1.8 since we don't support quirks mode1216 boxmodel: document.compatmode === "css1compat",1217 // will be defined later1218 deleteexpando: true,1219 nocloneevent: true,1220 inlineblockneedslayout: false,1221 shrinkwrapblocks: false,1222 reliablemarginright: true,1223 boxsizingreliable: true,1224 pixelposition: false1225 };1226 // make sure checked status is properly cloned1227 // 确认勾选的属性正确地被复制1228 input.checked = true;1229 support.noclonechecked = input.clonenode( true ).checked;1230 // make sure that the options inside disabled selects aren't marked as disabled1231 // 确认在无效选择中的选项没有被标记为无效1232 // (webkit marks them as disabled)1233 // webkit标记他们为无效1234 select.disabled = true;1235 support.optdisabled = !opt.disabled;1236 // support: ie<91237 // 支持:te<91238 try {1239 delete div.test;1240 } catch( e ) {1241 support.deleteexpando = false;1242 }1243 // check if we can trust getattribute("value")1244 // 检测我们是否能依赖getattribute得到的属性值1245 input = document.createelement("input");1246 input.setattribute( "value", "" );1247 support.input = input.getattribute( "value" ) === "";1248 // check if an input maintains its value after becoming a radio1249 // 在变成按钮后检测是否输入保持的值1250 input.value = "t";1251 input.setattribute( "type", "radio" );1252 support.radiovalue = input.value === "t";1253 // #11217 - webkit loses check when the name is after the checked attribute1254 input.setattribute( "checked", "t" );1255 input.setattribute( "name", "t" );1256 fragment = document.createdocumentfragment();1257 fragment.appendchild( input );1258 // check if a disconnected checkbox will retain its checked1259 // value of true after appended to the dom (ie6/7)1260 support.appendchecked = input.checked;1261 // webkit doesn't clone checked state correctly in fragments1262 support.checkclone = fragment.clonenode( true ).clonenode( true ).lastchild.checked;1263 // support: ie<91264 // opera does not clone events (and typeof div.attachevent === undefined).1265 // ie9-10 clones events bound via attachevent, but they don't trigger with .click()1266 if ( div.attachevent ) {1267 div.attachevent( "onclick", function() {1268 support.nocloneevent = false;1269 });1270 div.clonenode( true ).click();1271 }1272 // support: ie<9 (lack submit/change bubble), firefox 17+ (lack focusin event)1273 // beware of csp rest rictions (https://developer.mozilla.org/en/security/csp), test/csp.php1274 for ( i in { submit: true, change: true, focusin: true }) {1275 div.setattribute( eventname = "on" + i, "t" );1276 support[ i + "bubbles" ] = eventname in window || div.attributes[ eventname ].expando === false;1277 }1278 div.style.backgroundclip = "content-box";1279 div.clonenode( true ).style.backgroundclip = "";1280 support.clearclonestyle = div.style.backgroundclip === "content-box";1281 // run tests that need a body at doc ready1282 jquery (function() {1283 var container, margindiv, tds,1284 divreset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",1285 body = document.getelementsbytagname("body")[0];1286 if ( !body ) {1287 // return for frameset docs that don't have a body1288 // frameset文档中没有body节点就返回1289 return;1290 }1291 container = document.createelement("div");1292 container.style.csstext = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px";1293 body.appendchild( container ).appendchild( div );1294 // support: ie81295 // 支持:ie81296 // check if table cells still have offsetwidth/height when they are set1297 // 检查表单单元格是否还有返回元素的宽度/高度属性,当他们被设置时。1298 // to display:none and there are still other visible table cells in a1299 // 为了显示:没有,仍然有其他的可见单元格在一个表单行里1300 // table row; if so, offsetwidth/height are not reliable for use when1301 // 如此,返回元素的宽度/高度属性对于使用不是可靠的1302 // determining if an element has been hidden directly using1303 // 判断是否一个元素被直接隐藏使用1304 // display:none (it is still safe to use offsets if a parent element is1305 // 显示:没有(如果父元素是隐藏的,它仍居可以安全使用形成分支1306 // hidden; don safety goggles and see bug #4512 for more information).1307 // 看bug编号(#4512)查询更多信息1308 div.innerhtml = "<table><tr><td></td><td>t</td></tr></table>";1309 tds = div.getelementsbytagname("td");1310 tds[ 0 ].style.csstext = "padding:0;margin:0;border:0;display:none";1311 issupported = ( tds[ 0 ].offsetheight === 0 );1312 tds[ 0 ].style.display = "";1313 tds[ 1 ].style.display = "none";1314 // support: ie81315 // 支持:ie81316 // check if empty table cells still have offsetwidth/height1317 // 检查空的表单单元格是否仍旧有返回设置元素宽度、高度的属性1318 support.reliablehiddenoffsets = issupported && ( tds[ 0 ].offsetheight === 0 );1319 // check box-sizing and margin behavior1320 // 检测盒子大小和边界(详情参考css盒子模式)1321 div.innerhtml = "";1322 div.style.csstext = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;";1323 support.boxsizing = ( div.offsetwidth === 4 );1324 support.doesnotincludemargininbodyoffset = ( body.offsettop !== 1 );1325 // use window.getcomputedstyle because js dom on node.js will break without it.1326 // 使用window.getcomputedstyle方法,因为没有他在node.js 上的js dom将会损坏1327 if ( window.getcomputedstyle ) {1328 support.pixelposition = ( window.getcomputedstyle( div, null ) || {} ).top !== "1%";1329 support.boxsizingreliable = ( window.getcomputedstyle( div, null ) || { width: "4px" } ).width === "4px";1330 // check if div with explicit width and no margin-right incorrectly1331 // 检查div是否有明确的宽度和正确地右边缘1332 // gets computed margin-right based on width of container. (#3333)1333 // fails in webkit before feb 2011 nightlies1334 // webkit bug 13343 - getcomputedstyle returns wrong value for margin-right1335 // webkit bug 编号:13343——得到计算样式返回错误的值给右边缘1336 margindiv = div.appendchild( document.createelement("div") );1337 margindiv.style.csstext = div.style.csstext = divreset;1338 margindiv.style.marginright = margindiv.style.width = "0";1339 div.style.width = "1px";1340 support.reliablemarginright =1341 !parsefloat( ( window.getcomputedstyle( margindiv, null ) || {} ).marginright );1342 }1343 if ( typeof div.style.zoom !== core_strundefined ) {1344 // support: ie<81345 // check if natively block-level elements act like inline-block1346 // elements when setting their display to 'inline' and giving1347 // them layout1348 div.innerhtml = "";1349 div.style.csstext = divreset + "width:1px;padding:1px;display:inline;zoom:1";1350 support.inlineblockneedslayout = ( div.offsetwidth === 3 );1351 // support: ie61352 // check if elements with layout shrink-wrap their children1353 div.style.display = "block";1354 div.innerhtml = "<div></div>";1355 div.firstchild.style.width = "5px";1356 support.shrinkwrapblocks = ( div.offsetwidth !== 3 );1357 if ( support.inlineblockneedslayout ) {1358 // prevent ie 6 from affecting layout for positioned elements #110481359 // prevent ie from shrinking the body in ie 7 mode #128691360 // support: ie<81361 body.style.zoom = 1;1362 }1363 }1364 body.removechild( container );1365 // null elements to avoid leaks in ie1366 container = div = tds = margindiv = null;1367 });1368 // null elements to avoid leaks in ie1369 all = select = fragment = opt = a = input = null;1370 return support;1371})();1372var rbrace = /(?:\{[\s\s]*\}|\[[\s\s]*\])$/,1373 rmultidash = /([a-z])/g;1374function internaldata( elem, name, data, pvt /* internal use only */ ){1375 if ( !jquery .acceptdata( elem ) ) {1376 return;1377 }1378 var thiscache, ret,1379 internalkey = jquery .expando,1380 getbyname = typeof name === "string",1381 // we have to handle dom nodes and js objects differently because ie6-71382 // can't gc object references properly across the dom-js boundary1383 isnode = elem.nodetype,1384 // only dom nodes need the global jquery cache; js object data is1385 // attached directly to the object so gc can occur automatically1386 cache = isnode ? jquery .cache : elem,1387 // only defining an id for js objects if its cache already exists allows1388 // the code to shortcut on the same path as a dom node with no cache1389 id = isnode ? elem[ internalkey ] : elem[ internalkey ] && internalkey;1390 // avoid doing any more work than we need to when trying to get data on an1391 // object that has no data at all1392 if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getbyname && data === undefined ) {1393 return;1394 }1395 if ( !id ) {1396 // only dom nodes need a new unique id for each element since their data1397 // ends up in the global cache1398 if ( isnode ) {1399 elem[ internalkey ] = id = core_deletedids.pop() || jquery .guid++;1400 } else {1401 id = internalkey;1402 }1403 }1404 if ( !cache[ id ] ) {1405 cache[ id ] = {};1406 // avoids exposing jquery metadata on plain js objects when the object1407 // is serialized using js on.stringify1408 if ( !isnode ) {1409 cache[ id ].tojs on = jquery .noop;1410 }1411 }1412 // an object can be passed to jquery .data instead of a key/value pair; this gets1413 // shallow copied over onto the existing cache1414 if ( typeof name === "object" || typeof name === "function" ) {1415 if ( pvt ) {1416 cache[ id ] = jquery .extend( cache[ id ], name );1417 } else {1418 cache[ id ].data = jquery .extend( cache[ id ].data, name );1419 }1420 }1421 thiscache = cache[ id ];1422 // jquery data() is stored in a separate object inside the object's internal data1423 // cache in order to avoid key collisions between internal data and user-defined1424 // data.1425 if ( !pvt ) {1426 if ( !thiscache.data ) {1427 thiscache.data = {};1428 }1429 thiscache = thiscache.data;1430 }1431 if ( data !== undefined ) {1432 thiscache[ jquery .camelcase( name ) ] = data;1433 }1434 // check for both converted-to-camel and non-converted data property names1435 // if a data property was specified1436 if ( getbyname ) {1437 // first try to find as-is property data1438 ret = thiscache[ name ];1439 // test for null|undefined property data1440 if ( ret == null ) {1441 // try to find the camelcased property1442 ret = thiscache[ jquery .camelcase( name ) ];1443 }1444 } else {1445 ret = thiscache;1446 }1447 return ret;1448}1449function internalremovedata( elem, name, pvt ) {1450 if ( !jquery .acceptdata( elem ) ) {1451 return;1452 }1453 var i, l, thiscache,1454 isnode = elem.nodetype,1455 // see jquery .data for more information1456 cache = isnode ? jquery .cache : elem,1457 id = isnode ? elem[ jquery .expando ] : jquery .expando;1458 // if there is already no cache entry for this object, there is no1459 // purpose in continuing1460 if ( !cache[ id ] ) {1461 return;1462 }1463 if ( name ) {1464 thiscache = pvt ? cache[ id ] : cache[ id ].data;1465 if ( thiscache ) {1466 // support array or space separated string names for data keys1467 if ( !jquery .isarray( name ) ) {1468 // try the string as a key before any manipulation1469 if ( name in thiscache ) {1470 name = [ name ];1471 } else {1472 // split the camel cased version by spaces unless a key with the spaces exists1473 name = jquery .camelcase( name );1474 if ( name in thiscache ) {1475 name = [ name ];1476 } else {1477 name = name.split(" ");1478 }1479 }1480 } else {1481 // if "name" is an array of keys...1482 // when data is initially created, via ("key", "val") signature,1483 // keys will be converted to camelcase.1484 // since there is no way to tell _how_ a key was added, remove1485 // both plain key and camelcase key. #127861486 // this will only penalize the array argument path.1487 name = name.concat( jquery .map( name, jquery .camelcase ) );1488 }1489 for ( i = 0, l = name.length; i < l; i++ ) {1490 delete thiscache[ name[i] ];1491 }1492 // if there is no data left in the cache, we want to continue1493 // and let the cache object itself get destroyed1494 if ( !( pvt ? isemptydataobject : jquery .isemptyobject )( thiscache ) ) {1495 return;1496 }1497 }1498 }1499 // see jquery .data for more information1500 if ( !pvt ) {1501 delete cache[ id ].data;1502 // don't destroy the parent cache unless the internal data object1503 // had been the only thing left in it1504 if ( !isemptydataobject( cache[ id ] ) ) {1505 return;1506 }1507 }1508 // destroy the cache1509 if ( isnode ) {1510 jquery .cleandata( [ elem ], true );1511 // use delete when supported for expandos or `cache` is not a window per iswindow (#10080)1512 } else if ( jquery .support.deleteexpando || cache != cache.window ) {1513 delete cache[ id ];1514 // when all else fails, null1515 } else {1516 cache[ id ] = null;1517 }1518}1519jquery .extend({1520 cache: {},1521 // unique for each copy of jquery on the page1522 // non-digits removed to match rinlinejquery1523 expando: "jquery " + ( core_version + math.random() ).replace( /\d/g, "" ),1524 // the following elements throw uncatchable exceptions if you1525 // attempt to add expando properties to them.1526 nodata: {1527 "embed": true,1528 // ban all objects except for flash (which handle expandos)1529 "object": "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000",1530 "applet": true1531 },1532 hasdata: function( elem ) {1533 elem = elem.nodetype ? jquery .cache[ elem[jquery .expando] ] : elem[ jquery .expando ];1534 return !!elem && !isemptydataobject( elem );1535 },1536 data: function( elem, name, data ) {1537 return internaldata( elem, name, data );1538 },1539 removedata: function( elem, name ) {1540 return internalremovedata( elem, name );1541 },1542 // for internal use only.1543 _data: function( elem, name, data ) {1544 return internaldata( elem, name, data, true );1545 },1546 _removedata: function( elem, name ) {1547 return internalremovedata( elem, name, true );1548 },1549 // a method for determining if a dom node can handle the data expando1550 acceptdata: function( elem ) {1551 // do not set data on non-element because it will not be cleared (#8335).1552 if ( elem.nodetype && elem.nodetype !== 1 && elem.nodetype !== 9 ) {1553 return false;1554 }1555 var nodata = elem.nodename && jquery .nodata[ elem.nodename.tolowercase() ];1556 // nodes accept data unless otherwise specified; rejection can be conditional1557 return !nodata || nodata !== true && elem.getattribute("classid") === nodata;1558 }1559});1560jquery .fn.extend({1561 data: function( key, value ) {1562 var attrs, name,1563 elem = this[0],1564 i = 0,1565 data = null;1566 // gets all values1567 if ( key === undefined ) {1568 if ( this.length ) {1569 data = jquery .data( elem );1570 if ( elem.nodetype === 1 && !jquery ._data( elem, "parsedattrs" ) ) {1571 attrs = elem.attributes;1572 for ( ; i < attrs.length; i++ ) {1573 name = attrs[i].name;1574 if ( !name.indexof( "data-" ) ) {1575 name = jquery .camelcase( name.slice(5) );1576 dataattr( elem, name, data[ name ] );1577 }1578 }1579 jquery ._data( elem, "parsedattrs", true );1580 }1581 }1582 return data;1583 }1584 // sets multiple values1585 if ( typeof key === "object" ) {1586 return this.each(function() {1587 jquery .data( this, key );1588 });1589 }1590 return jquery .access( this, function( value ) {1591 if ( value === undefined ) {1592 // try to fetch any internally stored data first1593 return elem ? dataattr( elem, key, jquery .data( elem, key ) ) : null;1594 }1595 this.each(function() {1596 jquery .data( this, key, value );1597 });1598 }, null, value, arguments.length > 1, null, true );1599 },1600 removedata: function( key ) {1601 return this.each(function() {1602 jquery .removedata( this, key );1603 });1604 }1605});1606function dataattr( elem, key, data ) {1607 //如果在内心什么都没有找到,尝试接收任何数据1608 //数据从html5到任何类型1609 if ( data === undefined && elem.nodetype === 1 ) {1610 var name = "data-" + key.replace( rmultidash, "-$1" ).tolowercase();1611 data = elem.getattribute( name );1612 if ( typeof data === "string" ) {//如果数据类型为字符串1613 try {1614 data = data === "true" ? true ://如果数据等于【true】将true赋值给变量【data】否则执行下一步1615 data === "false" ? false :1616 data === "null" ? null :1617 // only convert to a number if it doesn't change the string1618 +data + "" === data ? +data :1619 rbrace.test( data ) ? jquery .parsejs on( data ) :1620 data;//这三元运算表达式真复杂!!!1621 //test函数:检索为字符串的数据是否匹配1622 //parsejs on函数:接收一个js on字符串,返回解析后的对象1623 } catch( e ) {}1624 // make sure we set the data so it isn't changed later1625 // 确认我们设定数据所以它在稍后不会被改变1626 jquery .data( elem, key, data );1627 } else {1628 data = undefined;1629 }1630 }1631 return data;1632}1633// checks a cache object for emptiness1634function isemptydataobject( obj ) {1635 var name;1636 for ( name in obj ) {1637 // if the public data object is empty, the private is still empty1638 if ( name === "data" && jquery .isemptyobject( obj[name] ) ) {1639 continue;1640 }1641 if ( name !== "tojs on" ) {1642 return false;1643 }1644 }1645 return true;1646}1647jquery .extend({1648 queue: function( elem, type, data ) {1649 var queue;1650 if ( elem ) {1651 type = ( type || "fx" ) + "queue";1652 queue = jquery ._data( elem, type );1653 // speed up dequeue by getting out quickly if this is just a lookup1654 if ( data ) {1655 if ( !queue || jquery .isarray(data) ) {1656 queue = jquery ._data( elem, type, jquery .makearray(data) );1657 } else {1658 queue.push( data );1659 }1660 }1661 return queue || [];1662 }1663 },1664 dequeue: function( elem, type ) {1665 type = type || "fx";1666 var queue = jquery .queue( elem, type ),1667 startlength = queue.length,1668 fn = queue.shift(),1669 hooks = jquery ._queuehooks( elem, type ),1670 next = function() {1671 jquery .dequeue( elem, type );1672 };1673 // if the fx queue is dequeued, always remove the progress sentinel1674 if ( fn === "inprogress" ) {1675 fn = queue.shift();1676 startlength--;1677 }1678 hooks.cur = fn;1679 if ( fn ) {1680 // add a progress sentinel to prevent the fx queue from being1681 // automatically dequeued1682 if ( type === "fx" ) {1683 queue.unshift( "inprogress" );1684 }1685 // clear up the last queue stop function1686 // 清理最后的队列停止功能1687 delete hooks.stop;1688 fn.call( elem, next, hooks );1689 }1690 if ( !startlength && hooks ) {1691 hooks.empty.fire();1692 }1693 },1694 // not intended for public consumption - generates a queuehooks object, or returns the current one1695 _queuehooks: function( elem, type ) {1696 var key = type + "queuehooks";1697 return jquery ._data( elem, key ) || jquery ._data( elem, key, {1698 empty: jquery .callbacks("once memory").add(function() {1699 jquery ._removedata( elem, type + "queue" );1700 jquery ._removedata( elem, key );1701 })1702 });1703 }1704});1705jquery .fn.extend({1706 queue: function( type, data ) {1707 var setter = 2;1708 if ( typeof type !== "string" ) {1709 data = type;1710 type = "fx";1711 setter--;1712 }1713 if ( arguments.length < setter ) {1714 return jquery .queue( this[0], type );1715 }1716 return data === undefined ?1717 this :1718 this.each(function() {1719 var queue = jquery .queue( this, type, data );1720 // ensure a hooks for this queue1721 jquery ._queuehooks( this, type );1722 if ( type === "fx" && queue[0] !== "inprogress" ) {1723 jquery .dequeue( this, type );1724 }1725 });1726 },1727 dequeue: function( type ) {1728 return this.each(function() {1729 jquery .dequeue( this, type );1730 });1731 },1732 // based off of the plugin by clint helfers, with permission.1733 // http://blindsignals.com/index.php/2009/07/jquery -delay/1734 delay: function( time, type ) {1735 time = jquery .fx ? jquery .fx.speeds[ time ] || time : time;1736 type = type || "fx";1737 return this.queue( type, function( next, hooks ) {1738 var timeout = settimeout( next, time );1739 hooks.stop = function() {1740 cleartimeout( timeout );1741 };1742 });1743 },1744 clearqueue: function( type ) {1745 return this.queue( type || "fx", [] );1746 },1747 // get a promise resolved when queues of a certain type1748 // are emptied (fx is the type by default)1749 promise: function( type, obj ) {1750 var tmp,1751 count = 1,1752 defer = jquery .deferred(),1753 elements = this,1754 i = this.length,1755 resolve = function() {1756 if ( !( --count ) ) {1757 defer.resolvewith( elements, [ elements ] );1758 }1759 };1760 if ( typeof type !== "string" ) {1761 obj = type;1762 type = undefined;1763 }1764 type = type || "fx";1765 while( i-- ) {1766 tmp = jquery ._data( elements[ i ], type + "queuehooks" );1767 if ( tmp && tmp.empty ) {1768 count++;1769 tmp.empty.add( resolve );1770 }1771 }1772 resolve();1773 return defer.promise( obj );1774 }1775});1776var nodehook, boolhook,1777 rclass = /[\t\r\n]/g,1778 rreturn = /\r/g,1779 rfocusable = /^(?:input|select|textarea|button|object)$/i,1780 rclickable = /^(?:a|area)$/i,1781 rboolean = /^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i,1782 rusedefault = /^(?:checked|selected)$/i,1783 getsetattribute = jquery .support.getsetattribute,1784 getsetinput = jquery .support.input;1785jquery .fn.extend({1786 attr: function( name, value ) {1787 return jquery .access( this, jquery .attr, name, value, arguments.length > 1 );1788 },1789 removeattr: function( name ) {1790 return this.each(function() {1791 jquery .removeattr( this, name );1792 });1793 },1794 prop: function( name, value ) {1795 return jquery .access( this, jquery .prop, name, value, arguments.length > 1 );1796 },1797 removeprop: function( name ) {1798 name = jquery .propfix[ name ] || name;1799 return this.each(function() {1800 // try/catch handles cases where ie balks (such as removing a property on window)1801 try {1802 this[ name ] = undefined;1803 delete this[ name ];1804 } catch( e ) {}1805 });1806 },1807 addclass: function( value ) {1808 var classes, elem, cur, clazz, j,1809 i = 0,1810 len = this.length,1811 proceed = typeof value === "string" && value;1812 if ( jquery .isfunction( value ) ) {1813 return this.each(function( j ) {1814 jquery ( this ).addclass( value.call( this, j, this.classname ) );1815 });1816 }1817 if ( proceed ) {1818 // the disjunction here is for better compressibility (see removeclass)1819 classes = ( value || "" ).match( core_rnotwhite ) || [];1820 for ( ; i < len; i++ ) {1821 elem = this[ i ];1822 cur = elem.nodetype === 1 && ( elem.classname ?1823 ( " " + elem.classname + " " ).replace( rclass, " " ) :1824 " "1825 );1826 if ( cur ) {1827 j = 0;1828 while ( (clazz = classes[j++]) ) {1829 if ( cur.indexof( " " + clazz + " " ) < 0 ) {1830 cur += clazz + " ";1831 }1832 }1833 elem.classname = jquery .trim( cur );1834 }1835 }1836 }1837 return this;1838 },1839 removeclass: function( value ) {1840 var classes, elem, cur, clazz, j,1841 i = 0,1842 len = this.length,1843 proceed = arguments.length === 0 || typeof value === "string" && value;1844 if ( jquery .isfunction( value ) ) {1845 return this.each(function( j ) {1846 jquery ( this ).removeclass( value.call( this, j, this.classname ) );1847 });1848 }1849 if ( proceed ) {1850 classes = ( value || "" ).match( core_rnotwhite ) || [];1851 for ( ; i < len; i++ ) {1852 elem = this[ i ];1853 // this expression is here for better compressibility (see addclass)1854 cur = elem.nodetype === 1 && ( elem.classname ?1855 ( " " + elem.classname + " " ).replace( rclass, " " ) :1856 ""1857 );1858 if ( cur ) {1859 j = 0;1860 while ( (clazz = classes[j++]) ) {1861 // remove *all* instances1862 while ( cur.indexof( " " + clazz + " " ) >= 0 ) {1863 cur = cur.replace( " " + clazz + " ", " " );1864 }1865 }1866 elem.classname = value ? jquery .trim( cur ) : "";1867 }1868 }1869 }1870 return this;1871 },1872 toggleclass: function( value, stateval ) {1873 var type = typeof value,1874 isbool = typeof stateval === "boolean";1875 if ( jquery .isfunction( value ) ) {1876 return this.each(function( i ) {1877 jquery ( this ).toggleclass( value.call(this, i, this.classname, stateval), stateval );1878 });1879 }1880 return this.each(function() {1881 if ( type === "string" ) {1882 // toggle individual class names1883 var classname,1884 i = 0,1885 self = jquery ( this ),1886 state = stateval,1887 classnames = value.match( core_rnotwhite ) || [];1888 while ( (classname = classnames[ i++ ]) ) {1889 // check each classname given, space separated list1890 state = isbool ? state : !self.hasclass( classname );1891 self[ state ? "addclass" : "removeclass" ]( classname );1892 }1893 // toggle whole class name1894 } else if ( type === core_strundefined || type === "boolean" ) {1895 if ( this.classname ) {1896 // store classname if set1897 jquery ._data( this, "__classname__", this.classname );1898 }1899 // if the element has a class name or if we're passed "false",1900 // then remove the whole classname (if there was one, the above saved it).1901 // otherwise bring back whatever was previously saved (if anything),1902 // falling back to the empty string if nothing was stored.1903 this.classname = this.classname || value === false ? "" : jquery ._data( this, "__classname__" ) || "";1904 }1905 });1906 },1907 hasclass: function( selector ) {1908 var classname = " " + selector + " ",1909 i = 0,1910 l = this.length;1911 for ( ; i < l; i++ ) {1912 if ( this[i].nodetype === 1 && (" " + this[i].classname + " ").replace(rclass, " ").indexof( classname ) >= 0 ) {1913 return true;1914 }1915 }1916 return false;1917 },1918 val: function( value ) {1919 var ret, hooks, isfunction,1920 elem = this[0];1921 if ( !arguments.length ) {1922 if ( elem ) {1923 hooks = jquery .valhooks[ elem.type ] || jquery .valhooks[ elem.nodename.tolowercase() ];1924 if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {1925 return ret;1926 }1927 ret = elem.value;1928 return typeof ret === "string" ?1929 // handle most common string cases1930 ret.replace(rreturn, "") :1931 // handle cases where value is null/undef or number1932 ret == null ? "" : ret;1933 }1934 return;1935 }1936 isfunction = jquery .isfunction( value );1937 return this.each(function( i ) {1938 var val,1939 self = jquery (this);1940 if ( this.nodetype !== 1 ) {1941 return;1942 }1943 if ( isfunction ) {1944 val = value.call( this, i, self.val() );1945 } else {1946 val = value;1947 }1948 // treat null/undefined as ""; convert numbers to string1949 if ( val == null ) {1950 val = "";1951 } else if ( typeof val === "number" ) {1952 val += "";1953 } else if ( jquery .isarray( val ) ) {1954 val = jquery .map(val, function ( value ) {1955 return value == null ? "" : value + "";1956 });1957 }1958 hooks = jquery .valhooks[ this.type ] || jquery .valhooks[ this.nodename.tolowercase() ];1959 // if set returns undefined, fall back to normal setting1960 if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {1961 this.value = val;1962 }1963 });1964 }1965});1966jquery .extend({1967 valhooks: {1968 option: {1969 get: function( elem ) {1970 // attributes.value is undefined in blackberry 4.7 but1971 // uses .value. see #69321972 var val = elem.attributes.value;1973 return !val || val.specified ? elem.value : elem.text;1974 }1975 },1976 select: {1977 get: function( elem ) {1978 var value, option,1979 options = elem.options,1980 index = elem.selectedindex,1981 one = elem.type === "select-one" || index < 0,1982 values = one ? null : [],1983 max = one ? index + 1 : options.length,1984 i = index < 0 ?1985 max :1986 one ? index : 0;1987 // loop through all the selected options1988 for ( ; i < max; i++ ) {1989 option = options[ i ];1990 // oldie doesn't update selected after form reset (#2551)1991 if ( ( option.selected || i === index ) &&1992 // don't return options that are disabled or in a disabled optgroup1993 ( jquery .support.optdisabled ? !option.disabled : option.getattribute("disabled") === null ) &&1994 ( !option.parentnode.disabled || !jquery .nodename( option.parentnode, "optgroup" ) ) ) {1995 // get the specific value for the option1996 value = jquery ( option ).val();1997 // we don't need an array for one selects1998 if ( one ) {1999 return value;2000 }2001 // multi-selects return an array2002 values.push( value );2003 }2004 }2005 return values;2006 },2007 set: function( elem, value ) {2008 var values = jquery .makearray( value );2009 jquery (elem).find("option").each(function() {2010 this.selected = jquery .inarray( jquery (this).val(), values ) >= 0;2011 });2012 if ( !values.length ) {2013 elem.selectedindex = -1;2014 }2015 return values;2016 }2017 }2018 },2019 attr: function( elem, name, value ) {2020 var hooks, notxml, ret,2021 ntype = elem.nodetype;2022 // don't get/set attributes on text, comment and attribute nodes2023 if ( !elem || ntype === 3 || ntype === 8 || ntype === 2 ) {2024 return;2025 }2026 // fallback to prop when attributes are not supported2027 if ( typeof elem.getattribute === core_strundefined ) {2028 return jquery .prop( elem, name, value );2029 }2030 notxml = ntype !== 1 || !jquery .isxmldoc( elem );2031 // all attributes are lowercase2032 // grab necessary hook if one is defined2033 if ( notxml ) {2034 name = name.tolowercase();2035 hooks = jquery .attrhooks[ name ] || ( rboolean.test( name ) ? boolhook : nodehook );2036 }2037 if ( value !== undefined ) {2038 if ( value === null ) {2039 jquery .removeattr( elem, name );2040 } else if ( hooks && notxml && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {2041 return ret;2042 } else {2043 elem.setattribute( name, value + "" );2044 return value;2045 }2046 } else if ( hooks && notxml && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {2047 return ret;2048 } else {2049 // in ie9+, flash objects don't have .getattribute (#12945)2050 // support: ie9+2051 if ( typeof elem.getattribute !== core_strundefined ) {2052 ret = elem.getattribute( name );2053 }2054 // non-existent attributes return null, we normalize to undefined2055 return ret == null ?2056 undefined :2057 ret;2058 }2059 },2060 removeattr: function( elem, value ) {2061 var name, propname,2062 i = 0,2063 attrnames = value && value.match( core_rnotwhite );2064 if ( attrnames && elem.nodetype === 1 ) {2065 while ( (name = attrnames[i++]) ) {2066 propname = jquery .propfix[ name ] || name;2067 // boolean attributes get special treatment (#10870)2068 if ( rboolean.test( name ) ) {2069 // set corresponding property to false for boolean attributes2070 // also clear defaultchecked/defaultselected (if appropriate) for ie<82071 if ( !getsetattribute && rusedefault.test( name ) ) {2072 elem[ jquery .camelcase( "default-" + name ) ] =2073 elem[ propname ] = false;2074 } else {2075 elem[ propname ] = false;2076 }2077 // see #9699 for explanation of this approach (setting first, then removal)2078 } else {2079 jquery .attr( elem, name, "" );2080 }2081 elem.removeattribute( getsetattribute ? name : propname );2082 }2083 }2084 },2085 attrhooks: {2086 type: {2087 set: function( elem, value ) {2088 if ( !jquery .support.radiovalue && value === "radio" && jquery .nodename(elem, "input") ) {2089 // setting the type on a radio button after the value resets the value in ie6-92090 // reset value to default in case type is set after value during creation2091 var val = elem.value;2092 elem.setattribute( "type", value );2093 if ( val ) {2094 elem.value = val;2095 }2096 return value;2097 }2098 }2099 }2100 },2101 propfix: {2102 tabindex: "tabindex",2103 readonly: "readonly",2104 "for": "htmlfor",2105 "class": "classname",2106 maxlength: "maxlength",2107 cellspacing: "cellspacing",2108 cellpadding: "cellpadding",2109 rowspan: "rowspan",2110 colspan: "colspan",2111 usemap: "usemap",2112 frameborder: "frameborder",2113 contenteditable: "contenteditable"2114 },2115 prop: function( elem, name, value ) {2116 var ret, hooks, notxml,2117 ntype = elem.nodetype;2118 // don't get/set properties on text, comment and attribute nodes2119 if ( !elem || ntype === 3 || ntype === 8 || ntype === 2 ) {2120 return;2121 }2122 notxml = ntype !== 1 || !jquery .isxmldoc( elem );2123 if ( notxml ) {2124 // fix name and attach hooks2125 name = jquery .propfix[ name ] || name;2126 hooks = jquery .prophooks[ name ];2127 }2128 if ( value !== undefined ) {2129 if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {2130 return ret;2131 } else {2132 return ( elem[ name ] = value );2133 }2134 } else {2135 if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {2136 return ret;2137 } else {2138 return elem[ name ];2139 }2140 }2141 },2142 prophooks: {2143 tabindex: {2144 get: function( elem ) {2145 // elem.tabindex doesn't always return the correct value when it hasn't been explicitly set2146 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/2147 var attributenode = elem.getattributenode("tabindex");2148 return attributenode && attributenode.specified ?2149 parseint( attributenode.value, 10 ) :2150 rfocusable.test( elem.nodename ) || rclickable.test( elem.nodename ) && elem.href ?2151 0 :2152 undefined;2153 }2154 }2155 }2156});2157// hook for boolean attributes2158boolhook = {2159 get: function( elem, name ) {2160 var2161 // use .prop to determine if this attribute is understood as boolean2162 prop = jquery .prop( elem, name ),2163 // fetch it accordingly2164 attr = typeof prop === "boolean" && elem.getattribute( name ),2165 detail = typeof prop === "boolean" ?2166 getsetinput && getsetattribute ?2167 attr != null :2168 // oldie fabricates an empty string for missing boolean attributes2169 // and conflates checked/selected into attroperties2170 rusedefault.test( name ) ?2171 elem[ jquery .camelcase( "default-" + name ) ] :2172 !!attr :2173 // fetch an attribute node for properties not recognized as boolean2174 elem.getattributenode( name );2175 return detail && detail.value !== false ?2176 name.tolowercase() :2177 undefined;2178 },2179 set: function( elem, value, name ) {2180 if ( value === false ) {2181 // remove boolean attributes when set to false2182 jquery .removeattr( elem, name );2183 } else if ( getsetinput && getsetattribute || !rusedefault.test( name ) ) {2184 // ie<8 needs the *property* name2185 elem.setattribute( !getsetattribute && jquery .propfix[ name ] || name, name );2186 // use defaultchecked and defaultselected for oldie2187 } else {2188 elem[ jquery .camelcase( "default-" + name ) ] = elem[ name ] = true;2189 }2190 return name;2191 }2192};2193// fix oldie value attroperty2194if ( !getsetinput || !getsetattribute ) {2195 jquery .attrhooks.value = {2196 get: function( elem, name ) {2197 var ret = elem.getattributenode( name );2198 return jquery .nodename( elem, "input" ) ?2199 // ignore the value *property* by using defaultvalue2200 elem.defaultvalue :2201 ret && ret.specified ? ret.value : undefined;2202 },2203 set: function( elem, value, name ) {2204 if ( jquery .nodename( elem, "input" ) ) {2205 // does not return so that setattribute is also used2206 elem.defaultvalue = value;2207 } else {2208 // use nodehook if defined (#1954); otherwise setattribute is fine2209 return nodehook && nodehook.set( elem, value, name );2210 }2211 }2212 };2213}2214// ie6/7 do not support getting/setting some attributes with get/setattribute2215if ( !getsetattribute ) {2216 // use this for any attribute in ie6/72217 // this fixes almost every ie6/7 issue2218 nodehook = jquery .valhooks.button = {2219 get: function( elem, name ) {2220 var ret = elem.getattributenode( name );2221 return ret && ( name === "id" || name === "name" || name === "coords" ? ret.value !== "" : ret.specified ) ?2222 ret.value :2223 undefined;2224 },2225 set: function( elem, value, name ) {2226 // set the existing or create a new attribute node2227 var ret = elem.getattributenode( name );2228 if ( !ret ) {2229 elem.setattributenode(2230 (ret = elem.ownerdocument.createattribute( name ))2231 );2232 }2233 ret.value = value += "";2234 // break association with cloned elements by also using setattribute (#9646)2235 return name === "value" || value === elem.getattribute( name ) ?2236 value :2237 undefined;2238 }2239 };2240 // set contenteditable to false on removals(#10429)2241 // setting to empty string throws an error as an invalid value2242 jquery .attrhooks.contenteditable = {2243 get: nodehook.get,2244 set: function( elem, value, name ) {2245 nodehook.set( elem, value === "" ? false : value, name );2246 }2247 };2248 // set width and height to auto instead of 0 on empty string( bug #8150 )2249 // this is for removals2250 jquery .each([ "width", "height" ], function( i, name ) {2251 jquery .attrhooks[ name ] = jquery .extend( jquery .attrhooks[ name ], {2252 set: function( elem, value ) {2253 if ( value === "" ) {2254 elem.setattribute( name, "auto" );2255 return value;2256 }2257 }2258 });2259 });2260}2261// some attributes require a special call on ie2262// http://msdn.microsoft.com/en-us/library/ms536429%28vs.85%29.aspx2263if ( !jquery .support.hrefnormalized ) {2264 jquery .each([ "href", "src", "width", "height" ], function( i, name ) {2265 jquery .attrhooks[ name ] = jquery .extend( jquery .attrhooks[ name ], {2266 get: function( elem ) {2267 var ret = elem.getattribute( name, 2 );2268 return ret == null ? undefined : ret;2269 }2270 });2271 });2272 // href/src property should get the full normalized url (#10299/#12915)2273 jquery .each([ "href", "src" ], function( i, name ) {2274 jquery .prophooks[ name ] = {2275 get: function( elem ) {2276 return elem.getattribute( name, 4 );2277 }2278 };2279 });2280}2281if ( !jquery .support.style ) {2282 jquery .attrhooks.style = {2283 get: function( elem ) {2284 // return undefined in the case of empty string2285 // note: ie uppercases css property names, but if we were to .tolowercase()2286 // .csstext, that would destroy case senstitivity in url's, like in "background"2287 return elem.style.csstext || undefined;2288 },2289 set: function( elem, value ) {2290 return ( elem.style.csstext = value + "" );2291 }2292 };2293}2294// safari mis-reports the default selected property of an option2295// accessing the parent's selectedindex property fixes it2296if ( !jquery .support.optselected ) {2297 jquery .prophooks.selected = jquery .extend( jquery .prophooks.selected, {2298 get: function( elem ) {2299 var parent = elem.parentnode;2300 if ( parent ) {2301 parent.selectedindex;2302 // make sure that it also works with optgroups, see #57012303 if ( parent.parentnode ) {2304 parent.parentnode.selectedindex;2305 }2306 }2307 return null;2308 }2309 });2310}2311// ie6/7 call enctype encoding2312if ( !jquery .support.enctype ) {2313 jquery .propfix.enctype = "encoding";2314}2315// radios and checkboxes getter/setter2316if ( !jquery .support.checkon ) {2317 jquery .each([ "radio", "checkbox" ], function() {2318 jquery .valhooks[ this ] = {2319 get: function( elem ) {2320 // handle the case where in webkit "" is returned instead of "on" if a value isn't specified2321 return elem.getattribute("value") === null ? "on" : elem.value;2322 }2323 };2324 });2325}2326jquery .each([ "radio", "checkbox" ], function() {2327 jquery .valhooks[ this ] = jquery .extend( jquery .valhooks[ this ], {2328 set: function( elem, value ) {2329 if ( jquery .isarray( value ) ) {2330 return ( elem.checked = jquery .inarray( jquery (elem).val(), value ) >= 0 );2331 }2332 }2333 });2334});2335var rformelems = /^(?:input|select|textarea)$/i,2336 rkeyevent = /^key/,2337 rmouseevent = /^(?:mouse|contextmenu)|click/,2338 rfocusmorph = /^(?:focusinfocus|focusoutblur)$/,2339 rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;2340function returntrue() {2341 return true;2342}2343function returnfalse() {2344 return false;2345}2346/*2347 * helper functions for managing events -- not part of the public interface.2348 * props to dean edwards' addevent library for many of the ideas.2349 */2350jquery .event = {2351 global: {},2352 add: function( elem, types, handler, data, selector ) {2353 var tmp, events, t, handleobjin,2354 special, eventhandle, handleobj,2355 handlers, type, namespaces, origtype,2356 elemdata = jquery ._data( elem );2357 // don't attach events to nodata or text/comment nodes (but allow plain objects)2358 if ( !elemdata ) {2359 return;2360 }2361 // caller can pass in an object of custom data in lieu of the handler2362 if ( handler.handler ) {2363 handleobjin = handler;2364 handler = handleobjin.handler;2365 selector = handleobjin.selector;2366 }2367 // make sure that the handler has a unique id, used to find/remove it later2368 if ( !handler.guid ) {2369 handler.guid = jquery .guid++;2370 }2371 // init the element's event structure and main handler, if this is the first2372 if ( !(events = elemdata.events) ) {2373 events = elemdata.events = {};2374 }2375 if ( !(eventhandle = elemdata.handle) ) {2376 eventhandle = elemdata.handle = function( e ) {2377 // discard the second event of a jquery .event.trigger() and2378 // when an event is called after a page has unloaded2379 return typeof jquery !== core_strundefined && (!e || jquery .event.triggered !== e.type) ?2380 jquery .event.dispatch.apply( eventhandle.elem, arguments ) :2381 undefined;2382 };2383 // add elem as a property of the handle fn to prevent a memory leak with ie non-native events2384 eventhandle.elem = elem;2385 }2386 // handle multiple events separated by a space2387 // jquery (...).bind("mouseover mouseout", fn);2388 types = ( types || "" ).match( core_rnotwhite ) || [""];2389 t = types.length;2390 while ( t-- ) {2391 tmp = rtypenamespace.exec( types[t] ) || [];2392 type = origtype = tmp[1];2393 namespaces = ( tmp[2] || "" ).split( "." ).sort();2394 // if event changes its type, use the special event handlers for the changed type2395 special = jquery .event.special[ type ] || {};2396 // if selector defined, determine special event api type, otherwise given type2397 type = ( selector ? special.delegatetype : special.bindtype ) || type;2398 // update special based on newly reset type2399 special = jquery .event.special[ type ] || {};2400 // handleobj is passed to all event handlers2401 handleobj = jquery .extend({2402 type: type,2403 origtype: origtype,2404 data: data,2405 handler: handler,2406 guid: handler.guid,2407 selector: selector,2408 needscontext: selector && jquery .expr.match.needscontext.test( selector ),2409 namespace: namespaces.join(".")2410 }, handleobjin );2411 // init the event handler queue if we're the first2412 if ( !(handlers = events[ type ]) ) {2413 handlers = events[ type ] = [];2414 handlers.delegatecount = 0;2415 // only use addeventlistener/attachevent if the special events handler returns false2416 if ( !special.setup || special.setup.call( elem, data, namespaces, eventhandle ) === false ) {2417 // bind the global event handler to the element2418 if ( elem.addeventlistener ) {2419 elem.addeventlistener( type, eventhandle, false );2420 } else if ( elem.attachevent ) {2421 elem.attachevent( "on" + type, eventhandle );2422 }2423 }2424 }2425 if ( special.add ) {2426 special.add.call( elem, handleobj );2427 if ( !handleobj.handler.guid ) {2428 handleobj.handler.guid = handler.guid;2429 }2430 }2431 // add to the element's handler list, delegates in front2432 if ( selector ) {2433 handlers.splice( handlers.delegatecount++, 0, handleobj );2434 } else {2435 handlers.push( handleobj );2436 }2437 // keep track of which events have ever been used, for event optimization2438 jquery .event.global[ type ] = true;2439 }2440 // nullify elem to prevent memory leaks in ie2441 elem = null;2442 },2443 // detach an event or set of events from an element2444 remove: function( elem, types, handler, selector, mappedtypes ) {2445 var j, handleobj, tmp,2446 origcount, t, events,2447 special, handlers, type,2448 namespaces, origtype,2449 elemdata = jquery .hasdata( elem ) && jquery ._data( elem );2450 if ( !elemdata || !(events = elemdata.events) ) {2451 return;2452 }2453 // once for each type.namespace in types; type may be omitted2454 types = ( types || "" ).match( core_rnotwhite ) || [""];2455 t = types.length;2456 while ( t-- ) {2457 tmp = rtypenamespace.exec( types[t] ) || [];2458 type = origtype = tmp[1];2459 namespaces = ( tmp[2] || "" ).split( "." ).sort();2460 // unbind all events (on this namespace, if provided) for the element2461 if ( !type ) {2462 for ( type in events ) {2463 jquery .event.remove( elem, type + types[ t ], handler, selector, true );2464 }2465 continue;2466 }2467 special = jquery .event.special[ type ] || {};2468 type = ( selector ? special.delegatetype : special.bindtype ) || type;2469 handlers = events[ type ] || [];2470 tmp = tmp[2] && new regexp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );2471 // remove matching events2472 origcount = j = handlers.length;2473 while ( j-- ) {2474 handleobj = handlers[ j ];2475 if ( ( mappedtypes || origtype === handleobj.origtype ) &&2476 ( !handler || handler.guid === handleobj.guid ) &&2477 ( !tmp || tmp.test( handleobj.namespace ) ) &&2478 ( !selector || selector === handleobj.selector || selector === "**" && handleobj.selector ) ) {2479 handlers.splice( j, 1 );2480 if ( handleobj.selector ) {2481 handlers.delegatecount--;2482 }2483 if ( special.remove ) {2484 special.remove.call( elem, handleobj );2485 }2486 }2487 }2488 // remove generic event handler if we removed something and no more handlers exist2489 // (avoids potential for endless recursion during removal of special event handlers)2490 if ( origcount && !handlers.length ) {2491 if ( !special.teardown || special.teardown.call( elem, namespaces, elemdata.handle ) === false ) {2492 jquery .removeevent( elem, type, elemdata.handle );2493 }2494 delete events[ type ];2495 }2496 }2497 // remove the expando if it's no longer used2498 if ( jquery .isemptyobject( events ) ) {2499 delete elemdata.handle;2500 // removedata also checks for emptiness and clears the expando if empty2501 // so use it instead of delete2502 jquery ._removedata( elem, "events" );2503 }2504 },2505 trigger: function( event, data, elem, onlyhandlers ) {2506 var handle, ontype, cur,2507 bubbletype, special, tmp, i,2508 eventpath = [ elem || document ],2509 type = core_hasown.call( event, "type" ) ? event.type : event,2510 namespaces = core_hasown.call( event, "namespace" ) ? event.namespace.split(".") : [];2511 cur = tmp = elem = elem || document;2512 // don't do events on text and comment nodes2513 // 不要在文本和内容节点上做事件2514 if ( elem.nodetype === 3 || elem.nodetype === 8 ) {2515 return;2516 }2517 // focus/blur morphs to focus in/out; ensure we're not firing them right now2518 // 聚焦/模糊 改变为了聚焦 内/外;确保我们现在没有解雇他们(这里fire中文怎么翻译暂时没想好,先翻译为解雇)2519 if ( rfocusmorph.test( type + jquery .event.triggered ) ) {2520 return;2521 }2522 if ( type.indexof(".") >= 0 ) {2523 // namespaced trigger; create a regexp to match event type in handle()2524 // 命名空间触发;用handle()函数创建一个正则表达式匹配的事件类型2525 namespaces = type.split(".");2526 type = namespaces.shift();2527 namespaces.sort();2528 }2529 ontype = type.indexof(":") < 0 && "on" + type;2530 // caller can pass in a jquery .event object, object, or just an event type string2531 // 访问者可以通过一个jquery 事件对象,对象,或者只是一个事件类型字符串2532 event = event[ jquery .expando ] ?2533 event :2534 new jquery .event( type, typeof event === "object" && event );2535 event.istrigger = true;2536 event.namespace = namespaces.join(".");2537 // 用符号(.)将命名空间连接起来2538 event.namespace_re = event.namespace ?2539 new regexp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :2540 null;2541 // clean up the event in case it is being reused2542 // 清理事件以免它被重用2543 event.result = undefined;2544 if ( !event.target ) {2545 event.target = elem;2546 }2547 // clone any incoming data and prepend the event, creating the handler arg list2548 // 克隆任何输入的数据并且前面加上事件,创建处理程序的参数列表2549 data = data == null ?2550 [ event ] :2551 jquery .makearray( data, [ event ] );2552 // allow special events to draw outside the lines2553 // 允许特殊事件为了利用外部的线(draw outside the lines暂时按字面翻译)2554 special = jquery .event.special[ type ] || {};2555 if ( !onlyhandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {2556 return;2557 }2558 // determine event propagation path in advance, per w3c events spec (#9951)2559 // 提前确定事件的传输路径,根据w3c事件标准(#9951)2560 // bubble up to document, then to window; watch for a global ownerdocument var (#9724)2561 // bubble up(冒泡)对文档,然后对window; 观察一个全局ownerdocument变量(#9724)2562 if ( !onlyhandlers && !special.nobubble && !jquery .iswindow( elem ) ) {2563 bubbletype = special.delegatetype || type;2564 if ( !rfocusmorph.test( bubbletype + type ) ) {2565 cur = cur.parentnode;2566 }2567 for ( ; cur; cur = cur.parentnode ) {2568 eventpath.push( cur );2569 tmp = cur;2570 }2571 // only add window if we got to document (e.g., not plain obj or detached dom)2572 if ( tmp === (elem.ownerdocument || document) ) {2573 eventpath.push( tmp.defaultview || tmp.parentwindow || window );2574 }2575 }2576 // fire handlers on the event path2577 // 在事件的处理途径上解雇处理者(fire handlers暂时译为:解雇处理者,没想到更好的翻译)2578 i = 0;2579 while ( (cur = eventpath[i++]) && !event.ispropagationstopped() ) {2580 event.type = i > 1 ?2581 bubbletype :2582 special.bindtype || type;2583 // jquery handler2584 // jquery 处理2585 handle = ( jquery ._data( cur, "events" ) || {} )[ event.type ] && jquery ._data( cur, "handle" );2586 if ( handle ) {2587 handle.apply( cur, data );2588 }2589 // native handler2590 // native处理2591 handle = ontype && cur[ ontype ];2592 if ( handle && jquery .acceptdata( cur ) && handle.apply && handle.apply( cur, data ) === false ) {2593 event.preventdefault();2594 }2595 }2596 event.type = type;2597 // if nobody prevented the default action, do it now2598 if ( !onlyhandlers && !event.isdefaultprevented() ) {2599 if ( (!special._default || special._default.apply( elem.ownerdocument, data ) === false) &&2600 !(type === "click" && jquery .nodename( elem, "a" )) && jquery .acceptdata( elem ) ) {2601 // call a native dom method on the target with the same name name as the event.2602 // can't use an .isfunction() check here because ie6/7 fails that test.2603 // don't do default actions on window, that's where global variables be (#6170)2604 if ( ontype && elem[ type ] && !jquery .iswindow( elem ) ) {2605 // don't re-trigger an onfoo event when we call its foo() method2606 tmp = elem[ ontype ];2607 if ( tmp ) {2608 elem[ ontype ] = null;2609 }2610 // prevent re-triggering of the same event, since we already bubbled it above2611 jquery .event.triggered = type;2612 try {2613 elem[ type ]();2614 } catch ( e ) {2615 // ie<9 dies on focus/blur to hidden element (#1486,#12518)2616 // only reproducible on winxp ie8 native, not ie9 in ie8 mode2617 }2618 jquery .event.triggered = undefined;2619 if ( tmp ) {2620 elem[ ontype ] = tmp;2621 }2622 }2623 }2624 }2625 return event.result;2626 },2627 dispatch: function( event ) {2628 // make a writable jquery .event from the native event object2629 event = jquery .event.fix( event );2630 var i, ret, handleobj, matched, j,2631 handlerqueue = [],2632 args = core_slice.call( arguments ),2633 handlers = ( jquery ._data( this, "events" ) || {} )[ event.type ] || [],2634 special = jquery .event.special[ event.type ] || {};2635 // use the fix-ed jquery .event rather than the (read-only) native event2636 args[0] = event;2637 event.delegatetarget = this;2638 // call the predispatch hook for the mapped type, and let it bail if desired2639 if ( special.predispatch && special.predispatch.call( this, event ) === false ) {2640 return;2641 }2642 // determine handlers2643 handlerqueue = jquery .event.handlers.call( this, event, handlers );2644 // run delegates first; they may want to stop propagation beneath us2645 i = 0;2646 while ( (matched = handlerqueue[ i++ ]) && !event.ispropagationstopped() ) {2647 event.currenttarget = matched.elem;2648 j = 0;2649 while ( (handleobj = matched.handlers[ j++ ]) && !event.isimmediatepropagationstopped() ) {2650 // triggered event must either 1) have no namespace, or2651 // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).2652 if ( !event.namespace_re || event.namespace_re.test( handleobj.namespace ) ) {2653 event.handleobj = handleobj;2654 event.data = handleobj.data;2655 ret = ( (jquery .event.special[ handleobj.origtype ] || {}).handle || handleobj.handler )2656 .apply( matched.elem, args );2657 if ( ret !== undefined ) {2658 if ( (event.result = ret) === false ) {2659 event.preventdefault();2660 event.stoppropagation();2661 }2662 }2663 }2664 }2665 }2666 // call the postdispatch hook for the mapped type2667 if ( special.postdispatch ) {2668 special.postdispatch.call( this, event );2669 }2670 return event.result;2671 },2672 handlers: function( event, handlers ) {2673 var sel, handleobj, matches, i,2674 handlerqueue = [],2675 delegatecount = handlers.delegatecount,2676 cur = event.target;2677 // find delegate handlers2678 // black-hole svg <use> instance trees (#13180)2679 // avoid non-left-click bubbling in firefox (#3861)2680 if ( delegatecount && cur.nodetype && (!event.button || event.type !== "click") ) {2681 for ( ; cur != this; cur = cur.parentnode || this ) {2682 // don't check non-elements (#13208)2683 // don't process clicks on disabled elements (#6911, #8165, #11382, #11764)2684 if ( cur.nodetype === 1 && (cur.disabled !== true || event.type !== "click") ) {2685 matches = [];2686 for ( i = 0; i < delegatecount; i++ ) {2687 handleobj = handlers[ i ];2688 // don't conflict with object.prototype properties (#13203)2689 sel = handleobj.selector + " ";2690 if ( matches[ sel ] === undefined ) {2691 matches[ sel ] = handleobj.needscontext ?2692 jquery ( sel, this ).index( cur ) >= 0 :2693 jquery .find( sel, this, null, [ cur ] ).length;2694 }2695 if ( matches[ sel ] ) {2696 matches.push( handleobj );2697 }2698 }2699 if ( matches.length ) {2700 handlerqueue.push({ elem: cur, handlers: matches });2701 }2702 }2703 }2704 }2705 // add the remaining (directly-bound) handlers2706 if ( delegatecount < handlers.length ) {2707 handlerqueue.push({ elem: this, handlers: handlers.slice( delegatecount ) });2708 }2709 return handlerqueue;2710 },2711 fix: function( event ) {2712 if ( event[ jquery .expando ] ) {2713 return event;2714 }2715 // create a writable copy of the event object and normalize some properties2716 var i, prop, copy,2717 type = event.type,2718 originalevent = event,2719 fixhook = this.fixhooks[ type ];2720 if ( !fixhook ) {2721 this.fixhooks[ type ] = fixhook =2722 rmouseevent.test( type ) ? this.mousehooks :2723 rkeyevent.test( type ) ? this.keyhooks :2724 {};2725 }2726 copy = fixhook.props ? this.props.concat( fixhook.props ) : this.props;2727 event = new jquery .event( originalevent );2728 i = copy.length;2729 while ( i-- ) {2730 prop = copy[ i ];2731 event[ prop ] = originalevent[ prop ];2732 }2733 // support: ie<92734 // fix target property (#1925)2735 if ( !event.target ) {2736 event.target = originalevent.srcelement || document;2737 }2738 // support: chrome 23+, safari?2739 // target should not be a text node (#504, #13143)2740 if ( event.target.nodetype === 3 ) {2741 event.target = event.target.parentnode;2742 }2743 // support: ie<92744 // for mouse/key events, metakey==false if it's undefined (#3368, #11328)2745 event.metakey = !!event.metakey;2746 return fixhook.filter ? fixhook.filter( event, originalevent ) : event;2747 },2748 // includes some event props shared by keyevent and mouseevent2749 props: "altkey bubbles cancelable ctrlkey currenttarget eventphase metakey relatedtarget shiftkey target timestamp view which".split(" "),2750 fixhooks: {},2751 keyhooks: {2752 props: "char charcode key keycode".split(" "),2753 filter: function( event, original ) {2754 // add which for key events2755 if ( event.which == null ) {2756 event.which = original.charcode != null ? original.charcode : original.keycode;2757 }2758 return event;2759 }2760 },2761 mousehooks: {2762 props: "button buttons clientx clienty fromelement offsetx offsety pagex pagey screenx screeny toelement".split(" "),2763 filter: function( event, original ) {2764 var body, eventdoc, doc,2765 button = original.button,2766 fromelement = original.fromelement;2767 // calculate pagex/y if missing and clientx/y available2768 if ( event.pagex == null && original.clientx != null ) {2769 eventdoc = event.target.ownerdocument || document;2770 doc = eventdoc.documentelement;2771 body = eventdoc.body;2772 event.pagex = original.clientx + ( doc && doc.scrollleft || body && body.scrollleft || 0 ) - ( doc && doc.clientleft || body && body.clientleft || 0 );2773 event.pagey = original.clienty + ( doc && doc.scrolltop || body && body.scrolltop || 0 ) - ( doc && doc.clienttop || body && body.clienttop || 0 );2774 }2775 // add relatedtarget, if necessary2776 if ( !event.relatedtarget && fromelement ) {2777 event.relatedtarget = fromelement === event.target ? original.toelement : fromelement;2778 }2779 // add which for click: 1 === left; 2 === middle; 3 === right2780 // note: button is not normalized, so don't use it2781 if ( !event.which && button !== undefined ) {2782 event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );2783 }2784 return event;2785 }2786 },2787 special: {2788 load: {2789 // prevent triggered image.load events from bubbling to window.load2790 nobubble: true2791 },2792 click: {2793 // for checkbox, fire native event so checked state will be right2794 trigger: function() {2795 if ( jquery .nodename( this, "input" ) && this.type === "checkbox" && this.click ) {2796 this.click();2797 return false;2798 }2799 }2800 },2801 focus: {2802 // fire native event if possible so blur/focus sequence is correct2803 trigger: function() {2804 if ( this !== document.activeelement && this.focus ) {2805 try {2806 this.focus();2807 return false;2808 } catch ( e ) {2809 // support: ie<92810 // if we error on focus to hidden element (#1486, #12518),2811 // let .trigger() run the handlers2812 }2813 }2814 },2815 delegatetype: "focusin"2816 },2817 blur: {2818 trigger: function() {2819 if ( this === document.activeelement && this.blur ) {2820 this.blur();2821 return false;2822 }2823 },2824 delegatetype: "focusout"2825 },2826 beforeunload: {2827 postdispatch: function( event ) {2828 // even when returnvalue equals to undefined firefox will still show alert2829 if ( event.result !== undefined ) {2830 event.originalevent.returnvalue = event.result;2831 }2832 }2833 }2834 },2835 simulate: function( type, elem, event, bubble ) {2836 // piggyback on a donor event to simulate a different one.2837 // fake originalevent to avoid donor's stoppropagation, but if the2838 // simulated event prevents default then we do the same on the donor.2839 var e = jquery .extend(2840 new jquery .event(),2841 event,2842 { type: type,2843 issimulated: true,2844 originalevent: {}2845 }2846 );2847 if ( bubble ) {2848 jquery .event.trigger( e, null, elem );2849 } else {2850 jquery .event.dispatch.call( elem, e );2851 }2852 if ( e.isdefaultprevented() ) {2853 event.preventdefault();2854 }2855 }2856};2857jquery .removeevent = document.removeeventlistener ?2858 function( elem, type, handle ) {2859 if ( elem.removeeventlistener ) {2860 elem.removeeventlistener( type, handle, false );2861 }2862 } :2863 function( elem, type, handle ) {2864 var name = "on" + type;2865 if ( elem.detachevent ) {2866 // #8545, #7054, preventing memory leaks for custom events in ie6-82867 // detachevent needed property on element, by name of that event, to properly expose it to gc2868 if ( typeof elem[ name ] === core_strundefined ) {2869 elem[ name ] = null;2870 }2871 elem.detachevent( name, handle );2872 }2873 };2874jquery .event = function( src, props ) {2875 // allow instantiation without the 'new' keyword2876 if ( !(this instanceof jquery .event) ) {2877 return new jquery .event( src, props );2878 }2879 // event object2880 if ( src && src.type ) {2881 this.originalevent = src;2882 this.type = src.type;2883 // events bubbling up the document may have been marked as prevented2884 // by a handler lower down the tree; reflect the correct value.2885 this.isdefaultprevented = ( src.defaultprevented || src.returnvalue === false ||2886 src.getpreventdefault && src.getpreventdefault() ) ? returntrue : returnfalse;2887 // event type2888 } else {2889 this.type = src;2890 }2891 // put explicitly provided properties onto the event object2892 if ( props ) {2893 jquery .extend( this, props );2894 }2895 // create a timestamp if incoming event doesn't have one2896 this.timestamp = src && src.timestamp || jquery .now();2897 // mark it as fixed2898 this[ jquery .expando ] = true;2899};2900// jquery .event is based on dom3 events as specified by the ecmascript language binding2901// http://www.w3.org/tr/2003/wd-dom-level-3-events-20030331/ecma-script-binding.html2902jquery .event.prototype = {2903 isdefaultprevented: returnfalse,2904 ispropagationstopped: returnfalse,2905 isimmediatepropagationstopped: returnfalse,2906 preventdefault: function() {2907 var e = this.originalevent;2908 this.isdefaultprevented = returntrue;2909 if ( !e ) {2910 return;2911 }2912 // if preventdefault exists, run it on the original event2913 if ( e.preventdefault ) {2914 e.preventdefault();2915 // support: ie2916 // otherwise set the returnvalue property of the original event to false2917 } else {2918 e.returnvalue = false;2919 }2920 },2921 stoppropagation: function() {2922 var e = this.originalevent;2923 this.ispropagationstopped = returntrue;2924 if ( !e ) {2925 return;2926 }2927 // if stoppropagation exists, run it on the original event2928 if ( e.stoppropagation ) {2929 e.stoppropagation();2930 }2931 // support: ie2932 // set the cancelbubble property of the original event to true2933 e.cancelbubble = true;2934 },2935 stopimmediatepropagation: function() {2936 this.isimmediatepropagationstopped = returntrue;2937 this.stoppropagation();2938 }2939};2940//创建鼠标进入/鼠标离开事件,使用鼠标在上面/鼠标离开和时间检查事件。2941jquery .each({2942 mouseenter: "mouseover",2943 mouseleave: "mouseout"2944}, function( orig, fix ) {2945 jquery .event.special[ orig ] = {2946 delegatetype: fix,2947 bindtype: fix,2948 handle: function( event ) {2949 var ret,2950 target = this,2951 related = event.relatedtarget,2952 handleobj = event.handleobj;2953 // for mousenter/leave call the handler if related is outside the target.2954 // nb: no relatedtarget if the mouse left/entered the browser window2955 if ( !related || (related !== target && !jquery .contains( target, related )) ) {2956 event.type = handleobj.origtype;2957 ret = handleobj.handler.apply( this, arguments );2958 event.type = fix;2959 }2960 return ret;2961 }2962 };2963});2964// ie submit delegation2965if ( !jquery .support.submitbubbles ) {2966 jquery .event.special.submit = {2967 setup: function() {2968 // only need this for delegated form submit events2969 if ( jquery .nodename( this, "form" ) ) {2970 return false;2971 }2972 // lazy-add a submit handler when a descendant form may potentially be submitted2973 jquery .event.add( this, "click._submit keypress._submit", function( e ) {2974 // node name check avoids a vml-related crash in ie (#9807)2975 var elem = e.target,2976 form = jquery .nodename( elem, "input" ) || jquery .nodename( elem, "button" ) ? elem.form : undefined;2977 if ( form && !jquery ._data( form, "submitbubbles" ) ) {2978 jquery .event.add( form, "submit._submit", function( event ) {2979 event._submit_bubble = true;2980 });2981 jquery ._data( form, "submitbubbles", true );2982 }2983 });2984 // return undefined since we don't need an event listener2985 },2986 postdispatch: function( event ) {2987 // if form was submitted by the user, bubble the event up the tree2988 if ( event._submit_bubble ) {2989 delete event._submit_bubble;2990 if ( this.parentnode && !event.istrigger ) {2991 jquery .event.simulate( "submit", this.parentnode, event, true );2992 }2993 }2994 },2995 teardown: function() {2996 // only need this for delegated form submit events2997 if ( jquery .nodename( this, "form" ) ) {2998 return false;2999 }3000 // remove delegated handlers; cleandata eventually reaps submit handlers attached above3001 jquery .event.remove( this, "._submit" );3002 }3003 };3004}3005// ie change delegation and checkbox/radio fix3006if ( !jquery .support.changebubbles ) {3007 jquery .event.special.change = {3008 setup: function() {3009 if ( rformelems.test( this.nodename ) ) {3010 // ie doesn't fire change on a check/radio until blur; trigger it on click3011 // after a propertychange. eat the blur-change in special.change.handle.3012 // this still fires onchange a second time for check/radio after blur.3013 if ( this.type === "checkbox" || this.type === "radio" ) {3014 jquery .event.add( this, "propertychange._change", function( event ) {3015 if ( event.originalevent.propertyname === "checked" ) {3016 this._just_changed = true;3017 }3018 });3019 jquery .event.add( this, "click._change", function( event ) {3020 if ( this._just_changed && !event.istrigger ) {3021 this._just_changed = false;3022 }3023 // allow triggered, simulated change events (#11500)3024 jquery .event.simulate( "change", this, event, true );3025 });3026 }3027 return false;3028 }3029 // delegated event; lazy-add a change handler on descendant inputs3030 jquery .event.add( this, "beforeactivate._change", function( e ) {3031 var elem = e.target;3032 if ( rformelems.test( elem.nodename ) && !jquery ._data( elem, "changebubbles" ) ) {3033 jquery .event.add( elem, "change._change", function( event ) {3034 if ( this.parentnode && !event.issimulated && !event.istrigger ) {3035 jquery .event.simulate( "change", this.parentnode, event, true );3036 }3037 });3038 jquery ._data( elem, "changebubbles", true );3039 }3040 });3041 },3042 handle: function( event ) {3043 var elem = event.target;3044 // swallow native change events from checkbox/radio, we already triggered them above3045 if ( this !== elem || event.issimulated || event.istrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {3046 return event.handleobj.handler.apply( this, arguments );3047 }3048 },3049 teardown: function() {3050 jquery .event.remove( this, "._change" );3051 return !rformelems.test( this.nodename );3052 }3053 };3054}3055// create "bubbling" focus and blur events3056if ( !jquery .support.focusinbubbles ) {3057 jquery .each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {3058 // attach a single capturing handler while someone wants focusin/focusout3059 var attaches = 0,3060 handler = function( event ) {3061 jquery .event.simulate( fix, event.target, jquery .event.fix( event ), true );3062 };3063 jquery .event.special[ fix ] = {3064 setup: function() {3065 if ( attaches++ === 0 ) {3066 document.addeventlistener( orig, handler, true );3067 }3068 },3069 teardown: function() {3070 if ( --attaches === 0 ) {3071 document.removeeventlistener( orig, handler, true );3072 }3073 }3074 };3075 });3076}3077jquery .fn.extend({3078 on: function( types, selector, data, fn, /*internal*/ one ) {3079 var type, origfn;3080 // types can be a map of types/handlers3081 if ( typeof types === "object" ) {3082 // ( types-object, selector, data )3083 if ( typeof selector !== "string" ) {3084 // ( types-object, data )3085 data = data || selector;3086 selector = undefined;3087 }3088 for ( type in types ) {3089 this.on( type, selector, data, types[ type ], one );3090 }3091 return this;3092 }3093 if ( data == null && fn == null ) {3094 // ( types, fn )3095 fn = selector;3096 data = selector = undefined;3097 } else if ( fn == null ) {3098 if ( typeof selector === "string" ) {3099 // ( types, selector, fn )3100 fn = data;3101 data = undefined;3102 } else {3103 // ( types, data, fn )3104 fn = data;3105 data = selector;3106 selector = undefined;3107 }3108 }3109 if ( fn === false ) {3110 fn = returnfalse;3111 } else if ( !fn ) {3112 return this;3113 }3114 if ( one === 1 ) {3115 origfn = fn;3116 fn = function( event ) {3117 // can use an empty set, since event contains the info3118 jquery ().off( event );3119 return origfn.apply( this, arguments );3120 };3121 // use same guid so caller can remove using origfn3122 fn.guid = origfn.guid || ( origfn.guid = jquery .guid++ );3123 }3124 return this.each( function() {3125 jquery .event.add( this, types, fn, data, selector );3126 });3127 },3128 one: function( types, selector, data, fn ) {3129 return this.on( types, selector, data, fn, 1 );3130 },3131 off: function( types, selector, fn ) {3132 var handleobj, type;3133 if ( types && types.preventdefault && types.handleobj ) {3134 // ( event ) dispatched jquery .event3135 handleobj = types.handleobj;3136 jquery ( types.delegatetarget ).off(3137 handleobj.namespace ? handleobj.origtype + "." + handleobj.namespace : handleobj.origtype,3138 handleobj.selector,3139 handleobj.handler3140 );3141 return this;3142 }3143 if ( typeof types === "object" ) {3144 // ( types-object [, selector] )3145 for ( type in types ) {3146 this.off( type, selector, types[ type ] );3147 }3148 return this;3149 }3150 if ( selector === false || typeof selector === "function" ) {3151 // ( types [, fn] )3152 fn = selector;3153 selector = undefined;3154 }3155 if ( fn === false ) {3156 fn = returnfalse;3157 }3158 return this.each(function() {3159 jquery .event.remove( this, types, fn, selector );3160 });3161 },3162 bind: function( types, data, fn ) {3163 return this.on( types, null, data, fn );3164 },3165 unbind: function( types, fn ) {3166 return this.off( types, null, fn );3167 },3168 delegate: function( selector, types, data, fn ) {3169 return this.on( types, selector, data, fn );3170 },3171 undelegate: function( selector, types, fn ) {3172 // ( namespace ) or ( selector, types [, fn] )3173 return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );3174 },3175 trigger: function( type, data ) {3176 return this.each(function() {3177 jquery .event.trigger( type, data, this );3178 });3179 },3180 triggerhandler: function( type, data ) {3181 var elem = this[0];3182 if ( elem ) {3183 return jquery .event.trigger( type, data, elem, true );3184 }3185 }3186});3187/*!3188 * sizzle css selector engine3189 * copyright 2012 jquery foundation and other contributors3190 * released under the mit license3191 * http://sizzlejs .com/3192 */3193(function( window, undefined ) {3194var i,3195 cachedruns,3196 expr,3197 gettext,3198 isxml,3199 compile,3200 hasduplicate,3201 outermostcontext,3202 // local document vars3203 setdocument,3204 document,3205 docelem,3206 documentisxml,3207 rbuggyqsa,3208 rbuggymatches,3209 matches,3210 contains,3211 sortorder,3212 // instance-specific data3213 expando = "sizzle" + -(new date()),3214 preferreddoc = window.document,3215 support = {},3216 dirruns = 0,3217 done = 0,3218 classcache = createcache(),3219 tokencache = createcache(),3220 compilercache = createcache(),3221 // general-purpose constants3222 strundefined = typeof undefined,3223 max_negative = 1 << 31,3224 // array methods3225 arr = [],3226 pop = arr.pop,3227 push = arr.push,3228 slice = arr.slice,3229 // use a stripped-down indexof if we can't use a native one3230 indexof = arr.indexof || function( elem ) {3231 var i = 0,3232 len = this.length;3233 for ( ; i < len; i++ ) {3234 if ( this[i] === elem ) {3235 return i;3236 }3237 }3238 return -1;3239 },3240 // regular expressions3241 // whitespace characters http://www.w3.org/tr/css3-selectors/#whitespace3242 whitespace = "[\\x20\\t\\r\\n\\f]",3243 // http://www.w3.org/tr/css3-syntax/#characters3244 characterencoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",3245 // loosely modeled on css identifier characters3246 // an unquoted value should be a css identifier http://www.w3.org/tr/css3-selectors/#attribute-selectors3247 // proper syntax: http://www.w3.org/tr/css21/syndata.html#value-def-identifier3248 identifier = characterencoding.replace( "w", "w#" ),3249 // acceptable operators http://www.w3.org/tr/selectors/#attribute-selectors3250 operators = "([*^$|!~]?=)",3251 attributes = "\\[" + whitespace + "*(" + characterencoding + ")" + whitespace +3252 "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",3253 // prefer arguments quoted,3254 // then not containing pseudos/brackets,3255 // then attribute selectors/non-parenthetical expressions,3256 // then anything else3257 // these preferences are here to reduce the number of selectors3258 // needing tokenize in the pseudo prefilter3259 pseudos = ":(" + characterencoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)",3260 // leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter3261 rtrim = new regexp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),3262 rcomma = new regexp( "^" + whitespace + "*," + whitespace + "*" ),3263 rcombinators = new regexp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ),3264 rpseudo = new regexp( pseudos ),3265 ridentifier = new regexp( "^" + identifier + "$" ),3266 matchexpr = {3267 "id": new regexp( "^#(" + characterencoding + ")" ),3268 "class": new regexp( "^\\.(" + characterencoding + ")" ),3269 "name": new regexp( "^\\[name=['\"]?(" + characterencoding + ")['\"]?\\]" ),3270 "tag": new regexp( "^(" + characterencoding.replace( "w", "w*" ) + ")" ),3271 "attr": new regexp( "^" + attributes ),3272 "pseudo": new regexp( "^" + pseudos ),3273 "child": new regexp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +3274 "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +3275 "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),3276 // for use in libraries implementing .is()3277 // we use this for pos matching in `select`3278 "needscontext": new regexp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +3279 whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )3280 },3281 rsibling = /[\x20\t\r\n\f]*[+~]/,3282 rnative = /^[^{]+\{\s*\[native code/,3283 // easily-parseable/retrievable id or tag or class selectors3284 rquickexpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,3285 rinputs = /^(?:input|select|textarea|button)$/i,3286 rheader = /^h\d$/i,3287 rescape = /'|\\/g,3288 rattributequotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,3289 // css escapes http://www.w3.org/tr/css21/syndata.html#escaped-characters3290 runescape = /\\([\da-fa-f]{1,6}[\x20\t\r\n\f]?|.)/g,3291 funescape = function( _, escaped ) {3292 var high = "0x" + escaped - 0x10000;3293 // nan means non-codepoint3294 return high !== high ?3295 escaped :3296 // bmp codepoint3297 high < 0 ?3298 string.fromcharcode( high + 0x10000 ) :3299 // supplemental plane codepoint (surrogate pair)3300 string.fromcharcode( high >> 10 | 0xd800, high & 0x3ff | 0xdc00 );3301 };3302// use a stripped-down slice if we can't use a native one3303try {3304 slice.call( preferreddoc.documentelement.childnodes, 0 )[0].nodetype;3305} catch ( e ) {3306 slice = function( i ) {3307 var elem,3308 results = [];3309 while ( (elem = this[i++]) ) {3310 results.push( elem );3311 }3312 return results;3313 };3314}3315/**3316 * for feature detection3317 * @param {function} fn the function to test for native support3318 */3319function isnative( fn ) {3320 return rnative.test( fn + "" );3321}3322/**3323 * create key-value caches of limited size3324 * @returns {function(string, object)} returns the object data after storing it on itself with3325 * property name the (space-suffixed) string and (if the cache is larger than expr.cachelength)3326 * deleting the oldest entry3327 */3328function createcache() {3329 var cache,3330 keys = [];3331 return (cache = function( key, value ) {3332 // use (key + " ") to avoid collision with native prototype properties (see issue #157)3333 if ( keys.push( key += " " ) > expr.cachelength ) {3334 // only keep the most recent entries3335 delete cache[ keys.shift() ];3336 }3337 return (cache[ key ] = value);3338 });3339}3340/**3341 * mark a function for special use by sizzle3342 * @param {function} fn the function to mark3343 */3344function markfunction( fn ) {3345 fn[ expando ] = true;3346 return fn;3347}3348/**3349 * support testing using an element3350 * @param {function} fn passed the created div and expects a boolean result3351 */3352function assert( fn ) {3353 var div = document.createelement("div");3354 try {3355 return fn( div );3356 } catch (e) {3357 return false;3358 } finally {3359 // release memory in ie3360 div = null;3361 }3362}3363function sizzle( selector, context, results, seed ) {3364 var match, elem, m, nodetype,3365 // qsa vars3366 i, groups, old, nid, newcontext, newselector;3367 if ( ( context ? context.ownerdocument || context : preferreddoc ) !== document ) {3368 setdocument( context );3369 }3370 context = context || document;3371 results = results || [];3372 if ( !selector || typeof selector !== "string" ) {3373 return results;3374 }3375 if ( (nodetype = context.nodetype) !== 1 && nodetype !== 9 ) {3376 return [];3377 }3378 if ( !documentisxml && !seed ) {3379 // shortcuts3380 if ( (match = rquickexpr.exec( selector )) ) {3381 // speed-up: sizzle("#id")3382 if ( (m = match[1]) ) {3383 if ( nodetype === 9 ) {3384 elem = context.getelementbyid( m );3385 // check parentnode to catch when blackberry 4.6 returns3386 // nodes that are no longer in the document #69633387 if ( elem && elem.parentnode ) {3388 // handle the case where ie, opera, and webkit return items3389 // by name instead of id3390 if ( elem.id === m ) {3391 results.push( elem );3392 return results;3393 }3394 } else {3395 return results;3396 }3397 } else {3398 // context is not a document3399 if ( context.ownerdocument && (elem = context.ownerdocument.getelementbyid( m )) &&3400 contains( context, elem ) && elem.id === m ) {3401 results.push( elem );3402 return results;3403 }3404 }3405 // speed-up: sizzle("tag")3406 } else if ( match[2] ) {3407 push.apply( results, slice.call(context.getelementsbytagname( selector ), 0) );3408 return results;3409 // speed-up: sizzle(".class")3410 } else if ( (m = match[3]) && support.getbyclassname && context.getelementsbyclassname ) {3411 push.apply( results, slice.call(context.getelementsbyclassname( m ), 0) );3412 return results;3413 }3414 }3415 // qsa path3416 if ( support.qsa && !rbuggyqsa.test(selector) ) {3417 old = true;3418 nid = expando;3419 newcontext = context;3420 newselector = nodetype === 9 && selector;3421 // qsa works strangely on element-rooted queries3422 // we can work around this by specifying an extra id on the root3423 // and working up from there (thanks to andrew dupont for the technique)3424 // ie 8 doesn't work on object elements3425 if ( nodetype === 1 && context.nodename.tolowercase() !== "object" ) {3426 groups = tokenize( selector );3427 if ( (old = context.getattribute("id")) ) {3428 nid = old.replace( rescape, "\\$&" );3429 } else {3430 context.setattribute( "id", nid );3431 }3432 nid = "[id='" + nid + "'] ";3433 i = groups.length;3434 while ( i-- ) {3435 groups[i] = nid + toselector( groups[i] );3436 }3437 newcontext = rsibling.test( selector ) && context.parentnode || context;3438 newselector = groups.join(",");3439 }3440 if ( newselector ) {3441 try {3442 push.apply( results, slice.call( newcontext.queryselectorall(3443 newselector3444 ), 0 ) );3445 return results;3446 } catch(qsaerror) {3447 } finally {3448 if ( !old ) {3449 context.removeattribute("id");3450 }3451 }3452 }3453 }3454 }3455 // all others3456 return select( selector.replace( rtrim, "$1" ), context, results, seed );3457}3458/**3459 * detect xml3460 * @param {element|object} elem an element or a document3461 */3462isxml = sizzle.isxml = function( elem ) {3463 // documentelement is verified for cases where it doesn't yet exist3464 // (such as loading iframes in ie - #4833)3465 var documentelement = elem && (elem.ownerdocument || elem).documentelement;3466 return documentelement ? documentelement.nodename !== "html" : false;3467};3468/**3469 * sets document-related variables once based on the current document3470 * @param {element|object} [doc] an element or document object to use to set the document3471 * @returns {object} returns the current document3472 */3473setdocument = sizzle.setdocument = function( node ) {3474 var doc = node ? node.ownerdocument || node : preferreddoc;3475 // if no document and documentelement is available, return3476 if ( doc === document || doc.nodetype !== 9 || !doc.documentelement ) {3477 return document;3478 }3479 // set our document3480 document = doc;3481 docelem = doc.documentelement;3482 // support tests3483 documentisxml = isxml( doc );3484 // check if getelementsbytagname("*") returns only elements3485 support.tagnamenocomments = assert(function( div ) {3486 div.appendchild( doc.createcomment("") );3487 return !div.getelementsbytagname("*").length;3488 });3489 // check if attributes should be retrieved by attribute nodes3490 support.attributes = assert(function( div ) {3491 div.innerhtml = "<select></select>";3492 var type = typeof div.lastchild.getattribute("multiple");3493 // ie8 returns a string for some attributes even when not present3494 return type !== "boolean" && type !== "string";3495 });3496 // check if getelementsbyclassname can be trusted3497 support.getbyclassname = assert(function( div ) {3498 // opera can't find a second classname (in 9.6)3499 div.innerhtml = "<div class='hidden e'></div><div class='hidden'></div>";3500 if ( !div.getelementsbyclassname || !div.getelementsbyclassname("e").length ) {3501 return false;3502 }3503 // safari 3.2 caches class attributes and doesn't catch changes3504 div.lastchild.classname = "e";3505 return div.getelementsbyclassname("e").length === 2;3506 });3507 // check if getelementbyid returns elements by name3508 // check if getelementsbyname privileges form controls or returns elements by id3509 support.getbyname = assert(function( div ) {3510 // inject content3511 div.id = expando + 0;3512 div.innerhtml = "<a name='" + expando + "'></a><div name='" + expando + "'></div>";3513 docelem.insertbefore( div, docelem.firstchild );3514 // test3515 var pass = doc.getelementsbyname &&3516 // buggy browsers will return fewer than the correct 23517 doc.getelementsbyname( expando ).length === 2 +3518 // buggy browsers will return more than the correct 03519 doc.getelementsbyname( expando + 0 ).length;3520 support.getidnotname = !doc.getelementbyid( expando );3521 // cleanup3522 docelem.removechild( div );3523 return pass;3524 });3525 // ie6/7 return modified attributes3526 expr.attrhandle = assert(function( div ) {3527 div.innerhtml = "<a href='#'></a>";3528 return div.firstchild && typeof div.firstchild.getattribute !== strundefined &&3529 div.firstchild.getattribute("href") === "#";3530 }) ?3531 {} :3532 {3533 "href": function( elem ) {3534 return elem.getattribute( "href", 2 );3535 },3536 "type": function( elem ) {3537 return elem.getattribute("type");3538 }3539 };3540 // id find and filter3541 if ( support.getidnotname ) {3542 expr.find["id"] = function( id, context ) {3543 if ( typeof context.getelementbyid !== strundefined && !documentisxml ) {3544 var m = context.getelementbyid( id );3545 // check parentnode to catch when blackberry 4.6 returns3546 // nodes that are no longer in the document #69633547 return m && m.parentnode ? [m] : [];3548 }3549 };3550 expr.filter["id"] = function( id ) {3551 var attrid = id.replace( runescape, funescape );3552 return function( elem ) {3553 return elem.getattribute("id") === attrid;3554 };3555 };3556 } else {3557 expr.find["id"] = function( id, context ) {3558 if ( typeof context.getelementbyid !== strundefined && !documentisxml ) {3559 var m = context.getelementbyid( id );3560 return m ?3561 m.id === id || typeof m.getattributenode !== strundefined && m.getattributenode("id").value === id ?3562 [m] :3563 undefined :3564 [];3565 }3566 };3567 expr.filter["id"] = function( id ) {3568 var attrid = id.replace( runescape, funescape );3569 return function( elem ) {3570 var node = typeof elem.getattributenode !== strundefined && elem.getattributenode("id");3571 return node && node.value === attrid;3572 };3573 };3574 }3575 // tag3576 expr.find["tag"] = support.tagnamenocomments ?3577 function( tag, context ) {3578 if ( typeof context.getelementsbytagname !== strundefined ) {3579 return context.getelementsbytagname( tag );3580 }3581 } :3582 function( tag, context ) {3583 var elem,3584 tmp = [],3585 i = 0,3586 results = context.getelementsbytagname( tag );3587 // filter out possible comments3588 if ( tag === "*" ) {3589 while ( (elem = results[i++]) ) {3590 if ( elem.nodetype === 1 ) {3591 tmp.push( elem );3592 }3593 }3594 return tmp;3595 }3596 return results;3597 };3598 // name3599 expr.find["name"] = support.getbyname && function( tag, context ) {3600 if ( typeof context.getelementsbyname !== strundefined ) {3601 return context.getelementsbyname( name );3602 }3603 };3604 // class3605 expr.find["class"] = support.getbyclassname && function( classname, context ) {3606 if ( typeof context.getelementsbyclassname !== strundefined && !documentisxml ) {3607 return context.getelementsbyclassname( classname );3608 }3609 };3610 // qsa and matchesselector support3611 // matchesselector(:active) reports false when true (ie9/opera 11.5)3612 rbuggymatches = [];3613 // qsa(:focus) reports false when true (chrome 21),3614 // no need to also add to buggymatches since matches checks buggyqsa3615 // a support test would require too much code (would include document ready)3616 rbuggyqsa = [ ":focus" ];3617 if ( (support.qsa = isnative(doc.queryselectorall)) ) {3618 // build qsa regex3619 // regex strategy adopted from diego perini3620 assert(function( div ) {3621 // select is set to empty string on purpose3622 // this is to test ie's treatment of not explictly3623 // setting a boolean content attribute,3624 // since its presence should be enough3625 // http://bugs.jquery .com/ticket/123593626 div.innerhtml = "<select><option selected=''></option></select>";3627 // ie8 - some boolean attributes are not treated correctly3628 if ( !div.queryselectorall("[selected]").length ) {3629 rbuggyqsa.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" );3630 }3631 // webkit/opera - :checked should return selected option elements3632 // http://www.w3.org/tr/2011/rec-css3-selectors-20110929/#checked3633 // ie8 throws error here and will not see later tests3634 if ( !div.queryselectorall(":checked").length ) {3635 rbuggyqsa.push(":checked");3636 }3637 });3638 assert(function( div ) {3639 // opera 10-12/ie8 - ^= $= *= and empty values3640 // should not select anything3641 div.innerhtml = "<input type='hidden' i=''/>";3642 if ( div.queryselectorall("[i^='']").length ) {3643 rbuggyqsa.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" );3644 }3645 // ff 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)3646 // ie8 throws error here and will not see later tests3647 if ( !div.queryselectorall(":enabled").length ) {3648 rbuggyqsa.push( ":enabled", ":disabled" );3649 }3650 // opera 10-11 does not throw on post-comma invalid pseudos3651 div.queryselectorall("*,:x");3652 rbuggyqsa.push(",.*:");3653 });3654 }3655 if ( (support.matchesselector = isnative( (matches = docelem.matchesselector ||3656 docelem.mozmatchesselector ||3657 docelem.webkitmatchesselector ||3658 docelem.omatchesselector ||3659 docelem.msmatchesselector) )) ) {3660 assert(function( div ) {3661 // check to see if it's possible to do matchesselector3662 // on a disconnected node (ie 9)3663 support.disconnectedmatch = matches.call( div, "div" );3664 // this should fail with an exception3665 // gecko does not error, returns false instead3666 matches.call( div, "[s!='']:x" );3667 rbuggymatches.push( "!=", pseudos );3668 });3669 }3670 rbuggyqsa = new regexp( rbuggyqsa.join("|") );3671 rbuggymatches = new regexp( rbuggymatches.join("|") );3672 // element contains another3673 // purposefully does not implement inclusive descendent3674 // as in, an element does not contain itself3675 contains = isnative(docelem.contains) || docelem.comparedocumentposition ?3676 function( a, b ) {3677 var adown = a.nodetype === 9 ? a.documentelement : a,3678 bup = b && b.parentnode;3679 return a === bup || !!( bup && bup.nodetype === 1 && (3680 adown.contains ?3681 adown.contains( bup ) :3682 a.comparedocumentposition && a.comparedocumentposition( bup ) & 163683 ));3684 } :3685 function( a, b ) {3686 if ( b ) {3687 while ( (b = b.parentnode) ) {3688 if ( b === a ) {3689 return true;3690 }3691 }3692 }3693 return false;3694 };3695 // document order sorting3696 sortorder = docelem.comparedocumentposition ?3697 function( a, b ) {3698 var compare;3699 if ( a === b ) {3700 hasduplicate = true;3701 return 0;3702 }3703 if ( (compare = b.comparedocumentposition && a.comparedocumentposition && a.comparedocumentposition( b )) ) {3704 if ( compare & 1 || a.parentnode && a.parentnode.nodetype === 11 ) {3705 if ( a === doc || contains( preferreddoc, a ) ) {3706 return -1;3707 }3708 if ( b === doc || contains( preferreddoc, b ) ) {3709 return 1;3710 }3711 return 0;3712 }3713 return compare & 4 ? -1 : 1;3714 }3715 return a.comparedocumentposition ? -1 : 1;3716 } :3717 function( a, b ) {3718 var cur,3719 i = 0,3720 aup = a.parentnode,3721 bup = b.parentnode,3722 ap = [ a ],3723 bp = [ b ];3724 // exit early if the nodes are identical3725 if ( a === b ) {3726 hasduplicate = true;3727 return 0;3728 // parentless nodes are either documents or disconnected3729 } else if ( !aup || !bup ) {3730 return a === doc ? -1 :3731 b === doc ? 1 :3732 aup ? -1 :3733 bup ? 1 :3734 0;3735 // if the nodes are siblings, we can do a quick check3736 } else if ( aup === bup ) {3737 return siblingcheck( a, b );3738 }3739 // otherwise we need full lists of their ancestors for comparIphone 苹果 ios n3740 cur = a;3741 while ( (cur = cur.parentnode) ) {3742 ap.unshift( cur );3743 }3744 cur = b;3745 while ( (cur = cur.parentnode) ) {3746 bp.unshift( cur );3747 }3748 // walk down the tree looking for a discrepancy3749 while ( ap[i] === bp[i] ) {3750 i++;3751 }3752 return i ?3753 // do a sibling check if the nodes have a common ancestor3754 siblingcheck( ap[i], bp[i] ) :3755 // otherwise nodes in our document sort first3756 ap[i] === preferreddoc ? -1 :3757 bp[i] === preferreddoc ? 1 :3758 0;3759 };3760 // always assume the presence of duplicates if sort doesn't3761 // pass them to our comparIphone 苹果 ios n function (as in google chrome).3762 hasduplicate = false;3763 [0, 0].sort( sortorder );3764 support.detectduplicates = hasduplicate;3765 return document;3766};3767sizzle.matches = function( expr, elements ) {3768 return sizzle( expr, null, null, elements );3769};3770sizzle.matchesselector = function( elem, expr ) {3771 // set document vars if needed3772 if ( ( elem.ownerdocument || elem ) !== document ) {3773 setdocument( elem );3774 }3775 // make sure that attribute selectors are quoted3776 expr = expr.replace( rattributequotes, "='$1']" );3777 // rbuggyqsa always contains :focus, so no need for an existence check3778 if ( support.matchesselector && !documentisxml && (!rbuggymatches || !rbuggymatches.test(expr)) && !rbuggyqsa.test(expr) ) {3779 try {3780 var ret = matches.call( elem, expr );3781 // ie 9's matchesselector returns false on disconnected nodes3782 if ( ret || support.disconnectedmatch ||3783 // as well, disconnected nodes are said to be in a document3784 // fragment in ie 93785 elem.document && elem.document.nodetype !== 11 ) {3786 return ret;3787 }3788 } catch(e) {}3789 }3790 return sizzle( expr, document, null, [elem] ).length > 0;3791};3792sizzle.contains = function( context, elem ) {3793 // set document vars if needed3794 if ( ( context.ownerdocument || context ) !== document ) {3795 setdocument( context );3796 }3797 return contains( context, elem );3798};3799sizzle.attr = function( elem, name ) {3800 var val;3801 // set document vars if needed3802 if ( ( elem.ownerdocument || elem ) !== document ) {3803 setdocument( elem );3804 }3805 if ( !documentisxml ) {3806 name = name.tolowercase();3807 }3808 if ( (val = expr.attrhandle[ name ]) ) {3809 return val( elem );3810 }3811 if ( documentisxml || support.attributes ) {3812 return elem.getattribute( name );3813 }3814 return ( (val = elem.getattributenode( name )) || elem.getattribute( name ) ) && elem[ name ] === true ?3815 name :3816 val && val.specified ? val.value : null;3817};3818sizzle.error = function( msg ) {3819 throw new error( "syntax error, unrecognized expression: " + msg );3820};3821// document sorting and removing duplicates3822sizzle.uniquesort = function( results ) {3823 var elem,3824 duplicates = [],3825 i = 1,3826 j = 0;3827 // unless we *know* we can detect duplicates, assume their presence3828 hasduplicate = !support.detectduplicates;3829 results.sort( sortorder );3830 if ( hasduplicate ) {3831 for ( ; (elem = results[i]); i++ ) {3832 if ( elem === results[ i - 1 ] ) {3833 j = duplicates.push( i );3834 }3835 }3836 while ( j-- ) {3837 results.splice( duplicates[ j ], 1 );3838 }3839 }3840 return results;3841};3842function siblingcheck( a, b ) {3843 var cur = b && a,3844 diff = cur && ( ~b.sourceindex || max_negative ) - ( ~a.sourceindex || max_negative );3845 // use ie sourceindex if available on both nodes3846 if ( diff ) {3847 return diff;3848 }3849 // check if b follows a3850 if ( cur ) {3851 while ( (cur = cur.nextsibling) ) {3852 if ( cur === b ) {3853 return -1;3854 }3855 }3856 }3857 return a ? 1 : -1;3858}3859// returns a function to use in pseudos for input types3860function createinputpseudo( type ) {3861 return function( elem ) {3862 var name = elem.nodename.tolowercase();3863 return name === "input" && elem.type === type;3864 };3865}3866// returns a function to use in pseudos for buttons3867function createbuttonpseudo( type ) {3868 return function( elem ) {3869 var name = elem.nodename.tolowercase();3870 return (name === "input" || name === "button") && elem.type === type;3871 };3872}3873// returns a function to use in pseudos for positionals3874function createpositionalpseudo( fn ) {3875 return markfunction(function( argument ) {3876 argument = +argument;3877 return markfunction(function( seed, matches ) {3878 var j,3879 matchindexes = fn( [], seed.length, argument ),3880 i = matchindexes.length;3881 // match elements found at the specified indexes3882 while ( i-- ) {3883 if ( seed[ (j = matchindexes[i]) ] ) {3884 seed[j] = !(matches[j] = seed[j]);3885 }3886 }3887 });3888 });3889}3890/**3891 * utility function for retrieving the text value of an array of dom nodes3892 * @param {array|element} elem3893 */3894gettext = sizzle.gettext = function( elem ) {3895 var node,3896 ret = "",3897 i = 0,3898 nodetype = elem.nodetype;3899 if ( !nodetype ) {3900 // if no nodetype, this is expected to be an array3901 for ( ; (node = elem[i]); i++ ) {3902 // do not traverse comment nodes3903 ret += gettext( node );3904 }3905 } else if ( nodetype === 1 || nodetype === 9 || nodetype === 11 ) {3906 // use textcontent for elements3907 // innertext usage removed for consistency of new lines (see #11153)3908 if ( typeof elem.textcontent === "string" ) {3909 return elem.textcontent;3910 } else {3911 // traverse its children3912 for ( elem = elem.firstchild; elem; elem = elem.nextsibling ) {3913 ret += gettext( elem );3914 }3915 }3916 } else if ( nodetype === 3 || nodetype === 4 ) {3917 return elem.nodevalue;3918 }3919 // do not include comment or processing instruction nodes3920 return ret;3921};3922expr = sizzle.selectors = {3923 // can be adjusted by the user3924 cachelength: 50,3925 createpseudo: markfunction,3926 match: matchexpr,3927 find: {},3928 relative: {3929 ">": { dir: "parentnode", first: true },3930 " ": { dir: "parentnode" },3931 "+": { dir: "previoussibling", first: true },3932 "~": { dir: "previoussibling" }3933 },3934 prefilter: {3935 "attr": function( match ) {3936 match[1] = match[1].replace( runescape, funescape );3937 // move the given value to match[3] whether quoted or unquoted3938 match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape );3939 if ( match[2] === "~=" ) {3940 match[3] = " " + match[3] + " ";3941 }3942 return match.slice( 0, 4 );3943 },3944 "child": function( match ) {3945 /* matches from matchexpr["child"]3946 1 type (only|nth|...)3947 2 what (child|of-type)3948 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)3949 4 xn-component of xn+y argument ([+-]?\d*n|)3950 5 sign of xn-component3951 6 x of xn-component3952 7 sign of y-component3953 8 y of y-component3954 */3955 match[1] = match[1].tolowercase();3956 if ( match[1].slice( 0, 3 ) === "nth" ) {3957 // nth-* requires argument3958 if ( !match[3] ) {3959 sizzle.error( match[0] );3960 }3961 // numeric x and y parameters for expr.filter.child3962 // remember that false/true cast respectively to 0/13963 match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );3964 match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );3965 // other types prohibit arguments3966 } else if ( match[3] ) {3967 sizzle.error( match[0] );3968 }3969 return match;3970 },3971 "pseudo": function( match ) {3972 var excess,3973 unquoted = !match[5] && match[2];3974 if ( matchexpr["child"].test( match[0] ) ) {3975 return null;3976 }3977 // accept quoted arguments as-is3978 if ( match[4] ) {3979 match[2] = match[4];3980 // strip excess characters from unquoted arguments3981 } else if ( unquoted && rpseudo.test( unquoted ) &&3982 // get excess from tokenize (recursively)3983 (excess = tokenize( unquoted, true )) &&3984 // advance to the next closing parenthesis3985 (excess = unquoted.indexof( ")", unquoted.length - excess ) - unquoted.length) ) {3986 // excess is a negative index3987 match[0] = match[0].slice( 0, excess );3988 match[2] = unquoted.slice( 0, excess );3989 }3990 // return only captures needed by the pseudo filter method (type and argument)3991 return match.slice( 0, 3 );3992 }3993 },3994 filter: {3995 "tag": function( nodename ) {3996 if ( nodename === "*" ) {3997 return function() { return true; };3998 }3999 nodename = nodename.replace( runescape, funescape ).tolowercase();4000 return function( elem ) {4001 return elem.nodename && elem.nodename.tolowercase() === nodename;4002 };4003 },4004 "class": function( classname ) {4005 var pattern = classcache[ classname + " " ];4006 return pattern ||4007 (pattern = new regexp( "(^|" + whitespace + ")" + classname + "(" + whitespace + "|$)" )) &&4008 classcache( classname, function( elem ) {4009 return pattern.test( elem.classname || (typeof elem.getattribute !== strundefined && elem.getattribute("class")) || "" );4010 });4011 },4012 "attr": function( name, operator, check ) {4013 return function( elem ) {4014 var result = sizzle.attr( elem, name );4015 if ( result == null ) {4016 return operator === "!=";4017 }4018 if ( !operator ) {4019 return true;4020 }4021 result += "";4022 return operator === "=" ? result === check :4023 operator === "!=" ? result !== check :4024 operator === "^=" ? check && result.indexof( check ) === 0 :4025 operator === "*=" ? check && result.indexof( check ) > -1 :4026 operator === "$=" ? check && result.slice( -check.length ) === check :4027 operator === "~=" ? ( " " + result + " " ).indexof( check ) > -1 :4028 operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :4029 false;4030 };4031 },4032 "child": function( type, what, argument, first, last ) {4033 var simple = type.slice( 0, 3 ) !== "nth",4034 forward = type.slice( -4 ) !== "last",4035 oftype = what === "of-type";4036 return first === 1 && last === 0 ?4037 // shortcut for :nth-*(n)4038 function( elem ) {4039 return !!elem.parentnode;4040 } :4041 function( elem, context, xml ) {4042 var cache, outercache, node, diff, nodeindex, start,4043 dir = simple !== forward ? "nextsibling" : "previoussibling",4044 parent = elem.parentnode,4045 name = oftype && elem.nodename.tolowercase(),4046 usecache = !xml && !oftype;4047 if ( parent ) {4048 // :(first|last|only)-(child|of-type)4049 if ( simple ) {4050 while ( dir ) {4051 node = elem;4052 while ( (node = node[ dir ]) ) {4053 if ( oftype ? node.nodename.tolowercase() === name : node.nodetype === 1 ) {4054 return false;4055 }4056 }4057 // reverse direction for :only-* (if we haven't yet done so)4058 start = dir = type === "only" && !start && "nextsibling";4059 }4060 return true;4061 }4062 start = [ forward ? parent.firstchild : parent.lastchild ];4063 // non-xml :nth-child(...) stores cache data on `parent`4064 if ( forward && usecache ) {4065 // seek `elem` from a previously-cached index4066 outercache = parent[ expando ] || (parent[ expando ] = {});4067 cache = outercache[ type ] || [];4068 nodeindex = cache[0] === dirruns && cache[1];4069 diff = cache[0] === dirruns && cache[2];4070 node = nodeindex && parent.childnodes[ nodeindex ];4071 while ( (node = ++nodeindex && node && node[ dir ] ||4072 // fallback to seeking `elem` from the start4073 (diff = nodeindex = 0) || start.pop()) ) {4074 // when found, cache indexes on `parent` and break4075 if ( node.nodetype === 1 && ++diff && node === elem ) {4076 outercache[ type ] = [ dirruns, nodeindex, diff ];4077 break;4078 }4079 }4080 // use previously-cached element index if available4081 } else if ( usecache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {4082 diff = cache[1];4083 // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)4084 } else {4085 // use the same loop as above to seek `elem` from the start4086 while ( (node = ++nodeindex && node && node[ dir ] ||4087 (diff = nodeindex = 0) || start.pop()) ) {4088 if ( ( oftype ? node.nodename.tolowercase() === name : node.nodetype === 1 ) && ++diff ) {4089 // cache the index of each encountered element4090 if ( usecache ) {4091 (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];4092 }4093 if ( node === elem ) {4094 break;4095 }4096 }4097 }4098 }4099 // incorporate the offset, then check against cycle size4100 diff -= last;4101 return diff === first || ( diff % first === 0 && diff / first >= 0 );4102 }4103 };4104 },4105 "pseudo": function( pseudo, argument ) {4106 // pseudo-class names are case-insensitive4107 // http://www.w3.org/tr/selectors/#pseudo-classes4108 // prioritize by case sensitivity in case custom pseudos are added with uppercase letters4109 // remember that setfilters inherits from pseudos4110 var args,4111 fn = expr.pseudos[ pseudo ] || expr.setfilters[ pseudo.tolowercase() ] ||4112 sizzle.error( "unsupported pseudo: " + pseudo );4113 // the user may use createpseudo to indicate that4114 // arguments are needed to create the filter function4115 // just as sizzle does4116 if ( fn[ expando ] ) {4117 return fn( argument );4118 }4119 // but maintain support for old signatures4120 if ( fn.length > 1 ) {4121 args = [ pseudo, pseudo, "", argument ];4122 return expr.setfilters.hasownproperty( pseudo.tolowercase() ) ?4123 markfunction(function( seed, matches ) {4124 var idx,4125 matched = fn( seed, argument ),4126 i = matched.length;4127 while ( i-- ) {4128 idx = indexof.call( seed, matched[i] );4129 seed[ idx ] = !( matches[ idx ] = matched[i] );4130 }4131 }) :4132 function( elem ) {4133 return fn( elem, 0, args );4134 };4135 }4136 return fn;4137 }4138 },4139 pseudos: {4140 // potentially complex pseudos4141 "not": markfunction(function( selector ) {4142 // trim the selector passed to compile4143 // to avoid treating leading and trailing4144 // spaces as combinators4145 var input = [],4146 results = [],4147 matcher = compile( selector.replace( rtrim, "$1" ) );4148 return matcher[ expando ] ?4149 markfunction(function( seed, matches, context, xml ) {4150 var elem,4151 unmatched = matcher( seed, null, xml, [] ),4152 i = seed.length;4153 // match elements unmatched by `matcher`4154 while ( i-- ) {4155 if ( (elem = unmatched[i]) ) {4156 seed[i] = !(matches[i] = elem);4157 }4158 }4159 }) :4160 function( elem, context, xml ) {4161 input[0] = elem;4162 matcher( input, null, xml, results );4163 return !results.pop();4164 };4165 }),4166 "has": markfunction(function( selector ) {4167 return function( elem ) {4168 return sizzle( selector, elem ).length > 0;4169 };4170 }),4171 "contains": markfunction(function( text ) {4172 return function( elem ) {4173 return ( elem.textcontent || elem.innertext || gettext( elem ) ).indexof( text ) > -1;4174 };4175 }),4176 // "whether an element is represented by a :lang() selector4177 // is based solely on the element's language value4178 // being equal to the identifier c,4179 // or beginning with the identifier c immediately followed by "-".4180 // the matching of c against the element's language value is performed case-insensitively.4181 // the identifier c does not have to be a valid language name."4182 // http://www.w3.org/tr/selectors/#lang-pseudo4183 "lang": markfunction( function( lang ) {4184 // lang value must be a valid identifider4185 if ( !ridentifier.test(lang || "") ) {4186 sizzle.error( "unsupported lang: " + lang );4187 }4188 lang = lang.replace( runescape, funescape ).tolowercase();4189 return function( elem ) {4190 var elemlang;4191 do {4192 if ( (elemlang = documentisxml ?4193 elem.getattribute("xml:lang") || elem.getattribute("lang") :4194 elem.lang) ) {4195 elemlang = elemlang.tolowercase();4196 return elemlang === lang || elemlang.indexof( lang + "-" ) === 0;4197 }4198 } while ( (elem = elem.parentnode) && elem.nodetype === 1 );4199 return false;4200 };4201 }),4202 // miscellaneous4203 "target": function( elem ) {4204 var hash = window.location && window.location.hash;4205 return hash && hash.slice( 1 ) === elem.id;4206 },4207 "root": function( elem ) {4208 return elem === docelem;4209 },4210 "focus": function( elem ) {4211 return elem === document.activeelement && (!document.hasfocus || document.hasfocus()) && !!(elem.type || elem.href || ~elem.tabindex);4212 },4213 // boolean properties4214 "enabled": function( elem ) {4215 return elem.disabled === false;4216 },4217 "disabled": function( elem ) {4218 return elem.disabled === true;4219 },4220 "checked": function( elem ) {4221 // in css3, :checked should return both checked and selected elements4222 // http://www.w3.org/tr/2011/rec-css3-selectors-20110929/#checked4223 var nodename = elem.nodename.tolowercase();4224 return (nodename === "input" && !!elem.checked) || (nodename === "option" && !!elem.selected);4225 },4226 "selected": function( elem ) {4227 // accessing this property makes selected-by-default4228 // options in safari work properly4229 if ( elem.parentnode ) {4230 elem.parentnode.selectedindex;4231 }4232 return elem.selected === true;4233 },4234 // contents4235 "empty": function( elem ) {4236 // http://www.w3.org/tr/selectors/#empty-pseudo4237 // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),4238 // not comment, processing instructions, or others4239 // thanks to diego perini for the nodename shortcut4240 // greater than "@" means alpha characters (specifically not starting with "#" or "?")4241 for ( elem = elem.firstchild; elem; elem = elem.nextsibling ) {4242 if ( elem.nodename > "@" || elem.nodetype === 3 || elem.nodetype === 4 ) {4243 return false;4244 }4245 }4246 return true;4247 },4248 "parent": function( elem ) {4249 return !expr.pseudos["empty"]( elem );4250 },4251 // element/input types4252 "header": function( elem ) {4253 return rheader.test( elem.nodename );4254 },4255 "input": function( elem ) {4256 return rinputs.test( elem.nodename );4257 },4258 "button": function( elem ) {4259 var name = elem.nodename.tolowercase();4260 return name === "input" && elem.type === "button" || name === "button";4261 },4262 "text": function( elem ) {4263 var attr;4264 // ie6 and 7 will map elem.type to 'text' for new html5 types (search, etc)4265 // use getattribute instead to test this case4266 return elem.nodename.tolowercase() === "input" &&4267 elem.type === "text" &&4268 ( (attr = elem.getattribute("type")) == null || attr.tolowercase() === elem.type );4269 },4270 // position-in-collection4271 "first": createpositionalpseudo(function() {4272 return [ 0 ];4273 }),4274 "last": createpositionalpseudo(function( matchindexes, length ) {4275 return [ length - 1 ];4276 }),4277 "eq": createpositionalpseudo(function( matchindexes, length, argument ) {4278 return [ argument < 0 ? argument + length : argument ];4279 }),4280 "even": createpositionalpseudo(function( matchindexes, length ) {4281 var i = 0;4282 for ( ; i < length; i += 2 ) {4283 matchindexes.push( i );4284 }4285 return matchindexes;4286 }),4287 "odd": createpositionalpseudo(function( matchindexes, length ) {4288 var i = 1;4289 for ( ; i < length; i += 2 ) {4290 matchindexes.push( i );4291 }4292 return matchindexes;4293 }),4294 "lt": createpositionalpseudo(function( matchindexes, length, argument ) {4295 var i = argument < 0 ? argument + length : argument;4296 for ( ; --i >= 0; ) {4297 matchindexes.push( i );4298 }4299 return matchindexes;4300 }),4301 "gt": createpositionalpseudo(function( matchindexes, length, argument ) {4302 var i = argument < 0 ? argument + length : argument;4303 for ( ; ++i < length; ) {4304 matchindexes.push( i );4305 }4306 return matchindexes;4307 })4308 }4309};4310// add button/input type pseudos4311for ( i in { radio: true, checkbox: true, file: true, password : true, image: true } ) {4312 expr.pseudos[ i ] = createinputpseudo( i );4313}4314for ( i in { submit: true, reset: true } ) {4315 expr.pseudos[ i ] = createbuttonpseudo( i );4316}4317function tokenize( selector, parseonly ) {4318 var matched, match, tokens, type,4319 sofar, groups, prefilters,4320 cached = tokencache[ selector + " " ];4321 if ( cached ) {4322 return parseonly ? 0 : cached.slice( 0 );4323 }4324 sofar = selector;4325 groups = [];4326 prefilters = expr.prefilter;4327 while ( sofar ) {4328 // comma and first run4329 if ( !matched || (match = rcomma.exec( sofar )) ) {4330 if ( match ) {4331 // don't consume trailing commas as valid4332 sofar = sofar.slice( match[0].length ) || sofar;4333 }4334 groups.push( tokens = [] );4335 }4336 matched = false;4337 // combinators4338 if ( (match = rcombinators.exec( sofar )) ) {4339 matched = match.shift();4340 tokens.push( {4341 value: matched,4342 // cast descendant combinators to space4343 type: match[0].replace( rtrim, " " )4344 } );4345 sofar = sofar.slice( matched.length );4346 }4347 // filters4348 for ( type in expr.filter ) {4349 if ( (match = matchexpr[ type ].exec( sofar )) && (!prefilters[ type ] ||4350 (match = prefilters[ type ]( match ))) ) {4351 matched = match.shift();4352 tokens.push( {4353 value: matched,4354 type: type,4355 matches: match4356 } );4357 sofar = sofar.slice( matched.length );4358 }4359 }4360 if ( !matched ) {4361 break;4362 }4363 }4364 // return the length of the invalid excess4365 // if we're just parsing4366 // otherwise, throw an error or return tokens4367 return parseonly ?4368 sofar.length :4369 sofar ?4370 sizzle.error( selector ) :4371 // cache the tokens4372 tokencache( selector, groups ).slice( 0 );4373}4374function toselector( tokens ) {4375 var i = 0,4376 len = tokens.length,4377 selector = "";4378 for ( ; i < len; i++ ) {4379 selector += tokens[i].value;4380 }4381 return selector;4382}4383function addcombinator( matcher, combinator, base ) {4384 var dir = combinator.dir,4385 checknonelements = base && dir === "parentnode",4386 donename = done++;4387 return combinator.first ?4388 // check against closest ancestor/preceding element4389 function( elem, context, xml ) {4390 while ( (elem = elem[ dir ]) ) {4391 if ( elem.nodetype === 1 || checknonelements ) {4392 return matcher( elem, context, xml );4393 }4394 }4395 } :4396 // check against all ancestor/preceding elements4397 function( elem, context, xml ) {4398 var data, cache, outercache,4399 dirkey = dirruns + " " + donename;4400 // we can't set arbitrary data on xml nodes, so they don't benefit from dir caching4401 if ( xml ) {4402 while ( (elem = elem[ dir ]) ) {4403 if ( elem.nodetype === 1 || checknonelements ) {4404 if ( matcher( elem, context, xml ) ) {4405 return true;4406 }4407 }4408 }4409 } else {4410 while ( (elem = elem[ dir ]) ) {4411 if ( elem.nodetype === 1 || checknonelements ) {4412 outercache = elem[ expando ] || (elem[ expando ] = {});4413 if ( (cache = outercache[ dir ]) && cache[0] === dirkey ) {4414 if ( (data = cache[1]) === true || data === cachedruns ) {4415 return data === true;4416 }4417 } else {4418 cache = outercache[ dir ] = [ dirkey ];4419 cache[1] = matcher( elem, context, xml ) || cachedruns;4420 if ( cache[1] === true ) {4421 return true;4422 }4423 }4424 }4425 }4426 }4427 };4428}4429function elementmatcher( matchers ) {4430 return matchers.length > 1 ?4431 function( elem, context, xml ) {4432 var i = matchers.length;4433 while ( i-- ) {4434 if ( !matchers[i]( elem, context, xml ) ) {4435 return false;4436 }4437 }4438 return true;4439 } :4440 matchers[0];4441}4442function condense( unmatched, map, filter, context, xml ) {4443 var elem,4444 newunmatched = [],4445 i = 0,4446 len = unmatched.length,4447 mapped = map != null;4448 for ( ; i < len; i++ ) {4449 if ( (elem = unmatched[i]) ) {4450 if ( !filter || filter( elem, context, xml ) ) {4451 newunmatched.push( elem );4452 if ( mapped ) {4453 map.push( i );4454 }4455 }4456 }4457 }4458 return newunmatched;4459}4460function setmatcher( prefilter, selector, matcher, postfilter, postfinder, postselector ) {4461 if ( postfilter && !postfilter[ expando ] ) {4462 postfilter = setmatcher( postfilter );4463 }4464 if ( postfinder && !postfinder[ expando ] ) {4465 postfinder = setmatcher( postfinder, postselector );4466 }4467 return markfunction(function( seed, results, context, xml ) {4468 var temp, i, elem,4469 premap = [],4470 postmap = [],4471 preexisting = results.length,4472 // get initial elements from seed or context4473 elems = seed || multiplecontexts( selector || "*", context.nodetype ? [ context ] : context, [] ),4474 // prefilter to get matcher input, preserving a map for seed-results synchronization4475 matcherin = prefilter && ( seed || !selector ) ?4476 condense( elems, premap, prefilter, context, xml ) :4477 elems,4478 matcherout = matcher ?4479 // if we have a postfinder, or filtered seed, or non-seed postfilter or preexisting results,4480 postfinder || ( seed ? prefilter : preexisting || postfilter ) ?4481 // ...intermediate processing is necessary4482 [] :4483 // ...otherwise use results directly4484 results :4485 matcherin;4486 // find primary matches4487 if ( matcher ) {4488 matcher( matcherin, matcherout, context, xml );4489 }4490 // apply postfilter4491 if ( postfilter ) {4492 temp = condense( matcherout, postmap );4493 postfilter( temp, [], context, xml );4494 // un-match failing elements by moving them back to matcherin4495 i = temp.length;4496 while ( i-- ) {4497 if ( (elem = temp[i]) ) {4498 matcherout[ postmap[i] ] = !(matcherin[ postmap[i] ] = elem);4499 }4500 }4501 }4502 if ( seed ) {4503 if ( postfinder || prefilter ) {4504 if ( postfinder ) {4505 // get the final matcherout by condensing this intermediate into postfinder contexts4506 temp = [];4507 i = matcherout.length;4508 while ( i-- ) {4509 if ( (elem = matcherout[i]) ) {4510 // rest ore matcherin since elem is not yet a final match4511 temp.push( (matcherin[i] = elem) );4512 }4513 }4514 postfinder( null, (matcherout = []), temp, xml );4515 }4516 // move matched elements from seed to results to keep them synchronized4517 i = matcherout.length;4518 while ( i-- ) {4519 if ( (elem = matcherout[i]) &&4520 (temp = postfinder ? indexof.call( seed, elem ) : premap[i]) > -1 ) {4521 seed[temp] = !(results[temp] = elem);4522 }4523 }4524 }4525 // add elements to results, through postfinder if defined4526 } else {4527 matcherout = condense(4528 matcherout === results ?4529 matcherout.splice( preexisting, matcherout.length ) :4530 matcherout4531 );4532 if ( postfinder ) {4533 postfinder( null, results, matcherout, xml );4534 } else {4535 push.apply( results, matcherout );4536 }4537 }4538 });4539}4540function matcherfromtokens( tokens ) {4541 var checkcontext, matcher, j,4542 len = tokens.length,4543 leadingrelative = expr.relative[ tokens[0].type ],4544 implicitrelative = leadingrelative || expr.relative[" "],4545 i = leadingrelative ? 1 : 0,4546 // the foundational matcher ensures that elements are reachable from top-level context(s)4547 matchcontext = addcombinator( function( elem ) {4548 return elem === checkcontext;4549 }, implicitrelative, true ),4550 matchanycontext = addcombinator( function( elem ) {4551 return indexof.call( checkcontext, elem ) > -1;4552 }, implicitrelative, true ),4553 matchers = [ function( elem, context, xml ) {4554 return ( !leadingrelative && ( xml || context !== outermostcontext ) ) || (4555 (checkcontext = context).nodetype ?4556 matchcontext( elem, context, xml ) :4557 matchanycontext( elem, context, xml ) );4558 } ];4559 for ( ; i < len; i++ ) {4560 if ( (matcher = expr.relative[ tokens[i].type ]) ) {4561 matchers = [ addcombinator(elementmatcher( matchers ), matcher) ];4562 } else {4563 matcher = expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );4564 // return special upon seeing a positional matcher4565 if ( matcher[ expando ] ) {4566 // find the next relative operator (if any) for proper handling4567 j = ++i;4568 for ( ; j < len; j++ ) {4569 if ( expr.relative[ tokens[j].type ] ) {4570 break;4571 }4572 }4573 return setmatcher(4574 i > 1 && elementmatcher( matchers ),4575 i > 1 && toselector( tokens.slice( 0, i - 1 ) ).replace( rtrim, "$1" ),4576 matcher,4577 i < j && matcherfromtokens( tokens.slice( i, j ) ),4578 j < len && matcherfromtokens( (tokens = tokens.slice( j )) ),4579 j < len && toselector( tokens )4580 );4581 }4582 matchers.push( matcher );4583 }4584 }4585 return elementmatcher( matchers );4586}4587function matcherfromgroupmatchers( elementmatchers, setmatchers ) {4588 // a counter to specify which element is currently being matched4589 var matchercachedruns = 0,4590 byset = setmatchers.length > 0,4591 byelement = elementmatchers.length > 0,4592 supermatcher = function( seed, context, xml, results, expandcontext ) {4593 var elem, j, matcher,4594 setmatched = [],4595 matchedcount = 0,4596 i = "0",4597 unmatched = seed && [],4598 outermost = expandcontext != null,4599 contextbackup = outermostcontext,4600 // we must always have either seed elements or context4601 elems = seed || byelement && expr.find["tag"]( "*", expandcontext && context.parentnode || context ),4602 // use integer dirruns iff this is the outermost matcher4603 dirrunsunique = (dirruns += contextbackup == null ? 1 : math.random() || 0.1);4604 if ( outermost ) {4605 outermostcontext = context !== document && context;4606 cachedruns = matchercachedruns;4607 }4608 // add elements passing elementmatchers directly to results4609 // keep `i` a string if there are no elements so `matchedcount` will be "00" below4610 for ( ; (elem = elems[i]) != null; i++ ) {4611 if ( byelement && elem ) {4612 j = 0;4613 while ( (matcher = elementmatchers[j++]) ) {4614 if ( matcher( elem, context, xml ) ) {4615 results.push( elem );4616 break;4617 }4618 }4619 if ( outermost ) {4620 dirruns = dirrunsunique;4621 cachedruns = ++matchercachedruns;4622 }4623 }4624 // track unmatched elements for set filters4625 if ( byset ) {4626 // they will have gone through all possible matchers4627 if ( (elem = !matcher && elem) ) {4628 matchedcount--;4629 }4630 // lengthen the array for every element, matched or not4631 if ( seed ) {4632 unmatched.push( elem );4633 }4634 }4635 }4636 // apply set filters to unmatched elements4637 matchedcount += i;4638 if ( byset && i !== matchedcount ) {4639 j = 0;4640 while ( (matcher = setmatchers[j++]) ) {4641 matcher( unmatched, setmatched, context, xml );4642 }4643 if ( seed ) {4644 // reintegrate element matches to eliminate the need for sorting4645 if ( matchedcount > 0 ) {4646 while ( i-- ) {4647 if ( !(unmatched[i] || setmatched[i]) ) {4648 setmatched[i] = pop.call( results );4649 }4650 }4651 }4652 // discard index placeholder values to get only actual matches4653 setmatched = condense( setmatched );4654 }4655 // add matches to results4656 push.apply( results, setmatched );4657 // seedless set matches succeeding multiple successful matchers stipulate sorting4658 if ( outermost && !seed && setmatched.length > 0 &&4659 ( matchedcount + setmatchers.length ) > 1 ) {4660 sizzle.uniquesort( results );4661 }4662 }4663 // override manipulation of globals by nested matchers4664 if ( outermost ) {4665 dirruns = dirrunsunique;4666 outermostcontext = contextbackup;4667 }4668 return unmatched;4669 };4670 return byset ?4671 markfunction( supermatcher ) :4672 supermatcher;4673}4674compile = sizzle.compile = function( selector, group /* internal use only */ ) {4675 var i,4676 setmatchers = [],4677 elementmatchers = [],4678 cached = compilercache[ selector + " " ];4679 if ( !cached ) {4680 // generate a function of recursive functions that can be used to check each element4681 if ( !group ) {4682 group = tokenize( selector );4683 }4684 i = group.length;4685 while ( i-- ) {4686 cached = matcherfromtokens( group[i] );4687 if ( cached[ expando ] ) {4688 setmatchers.push( cached );4689 } else {4690 elementmatchers.push( cached );4691 }4692 }4693 // cache the compiled function4694 cached = compilercache( selector, matcherfromgroupmatchers( elementmatchers, setmatchers ) );4695 }4696 return cached;4697};4698function multiplecontexts( selector, contexts, results ) {4699 var i = 0,4700 len = contexts.length;4701 for ( ; i < len; i++ ) {4702 sizzle( selector, contexts[i], results );4703 }4704 return results;4705}4706function select( selector, context, results, seed ) {4707 var i, tokens, token, type, find,4708 match = tokenize( selector );4709 if ( !seed ) {4710 // try to minimize operations if there is only one group4711 if ( match.length === 1 ) {4712 // take a shortcut and set the context if the root selector is an id4713 tokens = match[0] = match[0].slice( 0 );4714 if ( tokens.length > 2 && (token = tokens[0]).type === "id" &&4715 context.nodetype === 9 && !documentisxml &&4716 expr.relative[ tokens[1].type ] ) {4717 context = expr.find["id"]( token.matches[0].replace( runescape, funescape ), context )[0];4718 if ( !context ) {4719 return results;4720 }4721 selector = selector.slice( tokens.shift().value.length );4722 }4723 // fetch a seed set for right-to-left matching4724 i = matchexpr["needscontext"].test( selector ) ? 0 : tokens.length;4725 while ( i-- ) {4726 token = tokens[i];4727 // abort if we hit a combinator4728 if ( expr.relative[ (type = token.type) ] ) {4729 break;4730 }4731 if ( (find = expr.find[ type ]) ) {4732 // search, expanding context for leading sibling combinators4733 if ( (seed = find(4734 token.matches[0].replace( runescape, funescape ),4735 rsibling.test( tokens[0].type ) && context.parentnode || context4736 )) ) {4737 // if seed is empty or no tokens remain, we can return early4738 tokens.splice( i, 1 );4739 selector = seed.length && toselector( tokens );4740 if ( !selector ) {4741 push.apply( results, slice.call( seed, 0 ) );4742 return results;4743 }4744 break;4745 }4746 }4747 }4748 }4749 }4750 // compile and execute a filtering function4751 // provide `match` to avoid retokenization if we modified the selector above4752 compile( selector, match )(4753 seed,4754 context,4755 documentisxml,4756 results,4757 rsibling.test( selector )4758 );4759 return results;4760}4761// deprecated4762expr.pseudos["nth"] = expr.pseudos["eq"];4763// easy api for creating new setfilters4764function setfilters() {}4765expr.filters = setfilters.prototype = expr.pseudos;4766expr.setfilters = new setfilters();4767// initialize with the default document4768setdocument();4769// override sizzle attribute retrieval4770sizzle.attr = jquery .attr;4771jquery .find = sizzle;4772jquery .expr = sizzle.selectors;4773jquery .expr[":"] = jquery .expr.pseudos;4774jquery .unique = sizzle.uniquesort;4775jquery .text = sizzle.gettext;4776jquery .isxmldoc = sizzle.isxml;4777jquery .contains = sizzle.contains;4778})( window );4779var runtil = /until$/,4780 rparentsprev = /^(?:parents|prev(?:until|all))/,4781 issimple = /^.[^:#\[\.,]*$/,4782 rneedscontext = jquery .expr.match.needscontext,4783 // methods guaranteed to produce a unique set when starting from a unique set4784 guaranteedunique = {4785 children: true,4786 contents: true,4787 next: true,4788 prev: true4789 };4790jquery .fn.extend({4791 find: function( selector ) {4792 var i, ret, self,4793 len = this.length;4794 if ( typeof selector !== "string" ) {4795 self = this;4796 return this.pushstack( jquery ( selector ).filter(function() {4797 for ( i = 0; i < len; i++ ) {4798 if ( jquery .contains( self[ i ], this ) ) {4799 return true;4800 }4801 }4802 }) );4803 }4804 ret = [];4805 for ( i = 0; i < len; i++ ) {4806 jquery .find( selector, this[ i ], ret );4807 }4808 // needed because $( selector, context ) becomes $( context ).find( selector )4809 ret = this.pushstack( len > 1 ? jquery .unique( ret ) : ret );4810 ret.selector = ( this.selector ? this.selector + " " : "" ) + selector;4811 return ret;4812 },4813 has: function( target ) {4814 var i,4815 targets = jquery ( target, this ),4816 len = targets.length;4817 return this.filter(function() {4818 for ( i = 0; i < len; i++ ) {4819 if ( jquery .contains( this, targets[i] ) ) {4820 return true;4821 }4822 }4823 });4824 },4825 not: function( selector ) {4826 return this.pushstack( winnow(this, selector, false) );4827 },4828 filter: function( selector ) {4829 return this.pushstack( winnow(this, selector, true) );4830 },4831 is: function( selector ) {4832 return !!selector && (4833 typeof selector === "string" ?4834 // if this is a positional/relative selector, check membership in the returned set4835 // so $("p:first").is("p:last") won't return true for a doc with two "p".4836 rneedscontext.test( selector ) ?4837 jquery ( selector, this.context ).index( this[0] ) >= 0 :4838 jquery .filter( selector, this ).length > 0 :4839 this.filter( selector ).length > 0 );4840 },4841 closest: function( selectors, context ) {4842 var cur,4843 i = 0,4844 l = this.length,4845 ret = [],4846 pos = rneedscontext.test( selectors ) || typeof selectors !== "string" ?4847 jquery ( selectors, context || this.context ) :4848 0;4849 for ( ; i < l; i++ ) {4850 cur = this[i];4851 while ( cur && cur.ownerdocument && cur !== context && cur.nodetype !== 11 ) {4852 if ( pos ? pos.index(cur) > -1 : jquery .find.matchesselector(cur, selectors) ) {4853 ret.push( cur );4854 break;4855 }4856 cur = cur.parentnode;4857 }4858 }4859 return this.pushstack( ret.length > 1 ? jquery .unique( ret ) : ret );4860 },4861 // determine the position of an element within4862 // the matched set of elements4863 index: function( elem ) {4864 // no argument, return index in parent4865 if ( !elem ) {4866 return ( this[0] && this[0].parentnode ) ? this.first().prevall().length : -1;4867 }4868 // index in selector4869 if ( typeof elem === "string" ) {4870 return jquery .inarray( this[0], jquery ( elem ) );4871 }4872 // locate the position of the desired element4873 return jquery .inarray(4874 // if it receives a jquery object, the first element is used4875 elem.jquery ? elem[0] : elem, this );4876 },4877 add: function( selector, context ) {4878 var set = typeof selector === "string" ?4879 jquery ( selector, context ) :4880 jquery .makearray( selector && selector.nodetype ? [ selector ] : selector ),4881 all = jquery .merge( this.get(), set );4882 return this.pushstack( jquery .unique(all) );4883 },4884 addback: function( selector ) {4885 return this.add( selector == null ?4886 this.prevobject : this.prevobject.filter(selector)4887 );4888 }4889});4890jquery .fn.andself = jquery .fn.addback;4891function sibling( cur, dir ) {4892 do {4893 cur = cur[ dir ];4894 } while ( cur && cur.nodetype !== 1 );4895 return cur;4896}4897jquery .each({4898 parent: function( elem ) {4899 var parent = elem.parentnode;4900 return parent && parent.nodetype !== 11 ? parent : null;4901 },4902 parents: function( elem ) {4903 return jquery .dir( elem, "parentnode" );4904 },4905 parentsuntil: function( elem, i, until ) {4906 return jquery .dir( elem, "parentnode", until );4907 },4908 next: function( elem ) {4909 return sibling( elem, "nextsibling" );4910 },4911 prev: function( elem ) {4912 return sibling( elem, "previoussibling" );4913 },4914 nextall: function( elem ) {4915 return jquery .dir( elem, "nextsibling" );4916 },4917 prevall: function( elem ) {4918 return jquery .dir( elem, "previoussibling" );4919 },4920 nextuntil: function( elem, i, until ) {4921 return jquery .dir( elem, "nextsibling", until );4922 },4923 prevuntil: function( elem, i, until ) {4924 return jquery .dir( elem, "previoussibling", until );4925 },4926 siblings: function( elem ) {4927 return jquery .sibling( ( elem.parentnode || {} ).firstchild, elem );4928 },4929 children: function( elem ) {4930 return jquery .sibling( elem.firstchild );4931 },4932 contents: function( elem ) {4933 return jquery .nodename( elem, "iframe" ) ?4934 elem.contentdocument || elem.contentwindow.document :4935 jquery .merge( [], elem.childnodes );4936 }4937}, function( name, fn ) {4938 jquery .fn[ name ] = function( until, selector ) {4939 var ret = jquery .map( this, fn, until );4940 if ( !runtil.test( name ) ) {4941 selector = until;4942 }4943 if ( selector && typeof selector === "string" ) {4944 ret = jquery .filter( selector, ret );4945 }4946 ret = this.length > 1 && !guaranteedunique[ name ] ? jquery .unique( ret ) : ret;4947 if ( this.length > 1 && rparentsprev.test( name ) ) {4948 ret = ret.reverse();4949 }4950 return this.pushstack( ret );4951 };4952});4953jquery .extend({4954 filter: function( expr, elems, not ) {4955 if ( not ) {4956 expr = ":not(" + expr + ")";4957 }4958 return elems.length === 1 ?4959 jquery .find.matchesselector(elems[0], expr) ? [ elems[0] ] : [] :4960 jquery .find.matches(expr, elems);4961 },4962 dir: function( elem, dir, until ) {4963 var matched = [],4964 cur = elem[ dir ];4965 while ( cur && cur.nodetype !== 9 && (until === undefined || cur.nodetype !== 1 || !jquery ( cur ).is( until )) ) {4966 if ( cur.nodetype === 1 ) {4967 matched.push( cur );4968 }4969 cur = cur[dir];4970 }4971 return matched;4972 },4973 sibling: function( n, elem ) {4974 var r = [];4975 for ( ; n; n = n.nextsibling ) {4976 if ( n.nodetype === 1 && n !== elem ) {4977 r.push( n );4978 }4979 }4980 return r;4981 }4982});4983// implement the identical functionality for filter and not4984function winnow( elements, qualifier, keep ) {4985 // can't pass null or undefined to indexof in firefox 44986 // set to 0 to skip string check4987 qualifier = qualifier || 0;4988 if ( jquery .isfunction( qualifier ) ) {4989 return jquery .grep(elements, function( elem, i ) {4990 var retval = !!qualifier.call( elem, i, elem );4991 return retval === keep;4992 });4993 } else if ( qualifier.nodetype ) {4994 return jquery .grep(elements, function( elem ) {4995 return ( elem === qualifier ) === keep;4996 });4997 } else if ( typeof qualifier === "string" ) {4998 var filtered = jquery .grep(elements, function( elem ) {4999 return elem.nodetype === 1;5000 });5001 if ( issimple.test( qualifier ) ) {5002 return jquery .filter(qualifier, filtered, !keep);5003 } else {5004 qualifier = jquery .filter( qualifier, filtered );5005 }5006 }5007 return jquery .grep(elements, function( elem ) {5008 return ( jquery .inarray( elem, qualifier ) >= 0 ) === keep;5009 });5010}5011function createsafefragment( document ) {5012 var list = nodenames.split( "|" ),5013 safefrag = document.createdocumentfragment();5014 if ( safefrag.createelement ) {5015 while ( list.length ) {5016 safefrag.createelement(5017 list.pop()5018 );5019 }5020 }5021 return safefrag;5022}5023var nodenames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +5024 "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",5025 rinlinejquery = / jquery \d+="(?:null|\d+)"/g,5026 rnoshimcache = new regexp("<(?:" + nodenames + ")[\\s/>]", "i"),5027 rleadingwhitespace = /^\s+/,5028 rxhtmltag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,5029 rtagname = /<([\w:]+)/,5030 rtbody = /<tbody/i,5031 rhtml = /<|&#?\w+;/,5032 rnoinnerhtml = /<(?:script|style|link)/i,5033 manipulation_rcheckabletype = /^(?:checkbox|radio)$/i,5034 // checked="checked" or checked5035 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,5036 rscripttype = /^$|\/(?:java|ecma)script/i,5037 rscripttypemasked = /^true\/(.*)/,5038 rcleanscript = /^\s*<!(?:\[cdata\[|--)|(?:\]\]|--)>\s*$/g,5039 // we have to close these tags to support xhtml (#13200)5040 wrapmap = {5041 option: [ 1, "<select multiple='multiple'>", "</select>" ],5042 legend: [ 1, "<fieldset>", "</fieldset>" ],5043 area: [ 1, "<map>", "</map>" ],5044 param: [ 1, "<object>", "</object>" ],5045 thead: [ 1, "<table>", "</table>" ],5046 tr: [ 2, "<table><tbody>", "</tbody></table>" ],5047 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],5048 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],5049 // ie6-8 can't serialize link, script, style, or any html5 (noscope) tags,5050 // unless wrapped in a div with non-breaking characters in front of it.5051 _default: jquery .support.htmlserialize ? [ 0, "", "" ] : [ 1, "x<div>", "</div>" ]5052 },5053 safefragment = createsafefragment( document ),5054 fragmentdiv = safefragment.appendchild( document.createelement("div") );5055wrapmap.optgroup = wrapmap.option;5056wrapmap.tbody = wrapmap.tfoot = wrapmap.colgroup = wrapmap.caption = wrapmap.thead;5057wrapmap.th = wrapmap.td;5058jquery .fn.extend({5059 text: function( value ) {5060 return jquery .access( this, function( value ) {5061 return value === undefined ?5062 jquery .text( this ) :5063 this.empty().append( ( this[0] && this[0].ownerdocument || document ).createtextnode( value ) );5064 }, null, value, arguments.length );5065 },5066 wrapall: function( html ) {5067 if ( jquery .isfunction( html ) ) {5068 return this.each(function(i) {5069 jquery (this).wrapall( html.call(this, i) );5070 });5071 }5072 if ( this[0] ) {5073 // the elements to wrap the target around5074 var wrap = jquery ( html, this[0].ownerdocument ).eq(0).clone(true);5075 if ( this[0].parentnode ) {5076 wrap.insertbefore( this[0] );5077 }5078 wrap.map(function() {5079 var elem = this;5080 while ( elem.firstchild && elem.firstchild.nodetype === 1 ) {5081 elem = elem.firstchild;5082 }5083 return elem;5084 }).append( this );5085 }5086 return this;5087 },5088 wrapinner: function( html ) {5089 if ( jquery .isfunction( html ) ) {5090 return this.each(function(i) {5091 jquery (this).wrapinner( html.call(this, i) );5092 });5093 }5094 return this.each(function() {5095 var self = jquery ( this ),5096 contents = self.contents();5097 if ( contents.length ) {5098 contents.wrapall( html );5099 } else {5100 self.append( html );5101 }5102 });5103 },5104 wrap: function( html ) {5105 var isfunction = jquery .isfunction( html );5106 return this.each(function(i) {5107 jquery ( this ).wrapall( isfunction ? html.call(this, i) : html );5108 });5109 },5110 unwrap: function() {5111 return this.parent().each(function() {5112 if ( !jquery .nodename( this, "body" ) ) {5113 jquery ( this ).replacewith( this.childnodes );5114 }5115 }).end();5116 },5117 append: function() {5118 return this.dommanip(arguments, true, function( elem ) {5119 if ( this.nodetype === 1 || this.nodetype === 11 || this.nodetype === 9 ) {5120 this.appendchild( elem );5121 }5122 });5123 },5124 prepend: function() {5125 return this.dommanip(arguments, true, function( elem ) {5126 if ( this.nodetype === 1 || this.nodetype === 11 || this.nodetype === 9 ) {5127 this.insertbefore( elem, this.firstchild );5128 }5129 });5130 },5131 before: function() {5132 return this.dommanip( arguments, false, function( elem ) {5133 if ( this.parentnode ) {5134 this.parentnode.insertbefore( elem, this );5135 }5136 });5137 },5138 after: function() {5139 return this.dommanip( arguments, false, function( elem ) {5140 if ( this.parentnode ) {5141 this.parentnode.insertbefore( elem, this.nextsibling );5142 }5143 });5144 },5145 // keepdata is for internal use only--do not document5146 remove: function( selector, keepdata ) {5147 var elem,5148 i = 0;5149 for ( ; (elem = this[i]) != null; i++ ) {5150 if ( !selector || jquery .filter( selector, [ elem ] ).length > 0 ) {5151 if ( !keepdata && elem.nodetype === 1 ) {5152 jquery .cleandata( getall( elem ) );5153 }5154 if ( elem.parentnode ) {5155 if ( keepdata && jquery .contains( elem.ownerdocument, elem ) ) {5156 setglobaleval( getall( elem, "script" ) );5157 }5158 elem.parentnode.removechild( elem );5159 }5160 }5161 }5162 return this;5163 },5164 empty: function() {5165 var elem,5166 i = 0;5167 for ( ; (elem = this[i]) != null; i++ ) {5168 // remove element nodes and prevent memory leaks5169 if ( elem.nodetype === 1 ) {5170 jquery .cleandata( getall( elem, false ) );5171 }5172 // remove any remaining nodes5173 while ( elem.firstchild ) {5174 elem.removechild( elem.firstchild );5175 }5176 // if this is a select, ensure that it displays empty (#12336)5177 // support: ie<95178 if ( elem.options && jquery .nodename( elem, "select" ) ) {5179 elem.options.length = 0;5180 }5181 }5182 return this;5183 },5184 clone: function( dataandevents, deepdataandevents ) {5185 dataandevents = dataandevents == null ? false : dataandevents;5186 deepdataandevents = deepdataandevents == null ? dataandevents : deepdataandevents;5187 return this.map( function () {5188 return jquery .clone( this, dataandevents, deepdataandevents );5189 });5190 },5191 html: function( value ) {5192 return jquery .access( this, function( value ) {5193 var elem = this[0] || {},5194 i = 0,5195 l = this.length;5196 if ( value === undefined ) {5197 return elem.nodetype === 1 ?5198 elem.innerhtml.replace( rinlinejquery , "" ) :5199 undefined;5200 }5201 // see if we can take a shortcut and just use innerhtml5202 if ( typeof value === "string" && !rnoinnerhtml.test( value ) &&5203 ( jquery .support.htmlserialize || !rnoshimcache.test( value ) ) &&5204 ( jquery .support.leadingwhitespace || !rleadingwhitespace.test( value ) ) &&5205 !wrapmap[ ( rtagname.exec( value ) || ["", ""] )[1].tolowercase() ] ) {5206 value = value.replace( rxhtmltag, "<$1></$2>" );5207 try {5208 for (; i < l; i++ ) {5209 // remove element nodes and prevent memory leaks5210 elem = this[i] || {};5211 if ( elem.nodetype === 1 ) {5212 jquery .cleandata( getall( elem, false ) );5213 elem.innerhtml = value;5214 }5215 }5216 elem = 0;5217 // if using innerhtml throws an exception, use the fallback method5218 } catch(e) {}5219 }5220 if ( elem ) {5221 this.empty().append( value );5222 }5223 }, null, value, arguments.length );5224 },5225 replacewith: function( value ) {5226 var isfunc = jquery .isfunction( value );5227 // make sure that the elements are removed from the dom before they are inserted5228 // this can help fix replacing a parent with child elements5229 if ( !isfunc && typeof value !== "string" ) {5230 value = jquery ( value ).not( this ).detach();5231 }5232 return this.dommanip( [ value ], true, function( elem ) {5233 var next = this.nextsibling,5234 parent = this.parentnode;5235 if ( parent ) {5236 jquery ( this ).remove();5237 parent.insertbefore( elem, next );5238 }5239 });5240 },5241 detach: function( selector ) {5242 return this.remove( selector, true );5243 },5244 dommanip: function( args, table, callback ) {5245 // flatten any nested arrays5246 args = core_concat.apply( [], args );5247 var first, node, hasscripts,5248 scripts, doc, fragment,5249 i = 0,5250 l = this.length,5251 set = this,5252 inoclone = l - 1,5253 value = args[0],5254 isfunction = jquery .isfunction( value );5255 // we can't clonenode fragments that contain checked, in webkit5256 if ( isfunction || !( l <= 1 || typeof value !== "string" || jquery .support.checkclone || !rchecked.test( value ) ) ) {5257 return this.each(function( index ) {5258 var self = set.eq( index );5259 if ( isfunction ) {5260 args[0] = value.call( this, index, table ? self.html() : undefined );5261 }5262 self.dommanip( args, table, callback );5263 });5264 }5265 if ( l ) {5266 fragment = jquery .buildfragment( args, this[ 0 ].ownerdocument, false, this );5267 first = fragment.firstchild;5268 if ( fragment.childnodes.length === 1 ) {5269 fragment = first;5270 }5271 if ( first ) {5272 table = table && jquery .nodename( first, "tr" );5273 scripts = jquery .map( getall( fragment, "script" ), disablescript );5274 hasscripts = scripts.length;5275 // use the original fragment for the last item instead of the first because it can end up5276 // being emptied incorrectly in certain situations (#8070).5277 for ( ; i < l; i++ ) {5278 node = fragment;5279 if ( i !== inoclone ) {5280 node = jquery .clone( node, true, true );5281 // keep references to cloned scripts for later rest oration5282 if ( hasscripts ) {5283 jquery .merge( scripts, getall( node, "script" ) );5284 }5285 }5286 callback.call(5287 table && jquery .nodename( this[i], "table" ) ?5288 findorappend( this[i], "tbody" ) :5289 this[i],5290 node,5291 i5292 );5293 }5294 if ( hasscripts ) {5295 doc = scripts[ scripts.length - 1 ].ownerdocument;5296 // reenable scripts5297 // 重新启用脚本5298 jquery .map( scripts, rest orescript );5299 // evaluate executable scripts on first document insertion5300 for ( i = 0; i < hasscripts; i++ ) {5301 node = scripts[ i ];5302 if ( rscripttype.test( node.type || "" ) &&5303 !jquery ._data( node, "globaleval" ) && jquery .contains( doc, node ) ) {5304 if ( node.src ) {5305 // hope ajax is available...5306 jquery .ajax({5307 url: node.src,5308 type: "get",5309 datatype: "script",5310 async: false,5311 global: false,5312 "throws": true5313 });5314 } else {5315 jquery .globaleval( ( node.text || node.textcontent || node.innerhtml || "" ).replace( rcleanscript, "" ) );5316 }5317 }5318 }5319 }5320 // fix #11809: avoid leaking memory5321 fragment = first = null;5322 }5323 }5324 return this;5325 }5326});5327function findorappend( elem, tag ) {5328 return elem.getelementsbytagname( tag )[0] || elem.appendchild( elem.ownerdocument.createelement( tag ) );5329}5330// replace/rest ore the type attribute of script elements for safe dom manipulation5331function disablescript( elem ) {5332 var attr = elem.getattributenode("type");5333 elem.type = ( attr && attr.specified ) + "/" + elem.type;5334 return elem;5335}5336function rest orescript( elem ) {5337 var match = rscripttypemasked.exec( elem.type );5338 if ( match ) {5339 elem.type = match[1];5340 } else {5341 elem.removeattribute("type");5342 }5343 return elem;5344}5345// mark scripts as having already been evaluated5346function setglobaleval( elems, refelements ) {5347 var elem,5348 i = 0;5349 for ( ; (elem = elems[i]) != null; i++ ) {5350 jquery ._data( elem, "globaleval", !refelements || jquery ._data( refelements[i], "globaleval" ) );5351 }5352}5353function clonecopyevent( src, dest ) {5354 if ( dest.nodetype !== 1 || !jquery .hasdata( src ) ) {5355 return;5356 }5357 var type, i, l,5358 olddata = jquery ._data( src ),5359 curdata = jquery ._data( dest, olddata ),5360 events = olddata.events;5361 if ( events ) {5362 delete curdata.handle;5363 curdata.events = {};5364 for ( type in events ) {5365 for ( i = 0, l = events[ type ].length; i < l; i++ ) {5366 jquery .event.add( dest, type, events[ type ][ i ] );5367 }5368 }5369 }5370 // make the cloned public data object a copy from the original5371 if ( curdata.data ) {5372 curdata.data = jquery .extend( {}, curdata.data );5373 }5374}5375function fixclonenodeissues( src, dest ) {5376 var nodename, e, data;5377 // we do not need to do anything for non-elements5378 if ( dest.nodetype !== 1 ) {5379 return;5380 }5381 nodename = dest.nodename.tolowercase();5382 // ie6-8 copies events bound via attachevent when using clonenode.5383 if ( !jquery .support.nocloneevent && dest[ jquery .expando ] ) {5384 data = jquery ._data( dest );5385 for ( e in data.events ) {5386 jquery .removeevent( dest, e, data.handle );5387 }5388 // event data gets referenced instead of copied if the expando gets copied too5389 dest.removeattribute( jquery .expando );5390 }5391 // ie blanks contents when cloning scripts, and tries to evaluate newly-set text5392 if ( nodename === "script" && dest.text !== src.text ) {5393 disablescript( dest ).text = src.text;5394 rest orescript( dest );5395 // ie6-10 improperly clones children of object elements using classid.5396 // ie10 throws nomodificationallowederror if parent is null, #12132.5397 } else if ( nodename === "object" ) {5398 if ( dest.parentnode ) {5399 dest.outerhtml = src.outerhtml;5400 }5401 // this path appears unavoidable for ie9. when cloning an object5402 // element in ie9, the outerhtml strategy above is not sufficient.5403 // if the src has innerhtml and the destination does not,5404 // copy the src.innerhtml into the dest.innerhtml. #103245405 if ( jquery .support.html5clone && ( src.innerhtml && !jquery .trim(dest.innerhtml) ) ) {5406 dest.innerhtml = src.innerhtml;5407 }5408 } else if ( nodename === "input" && manipulation_rcheckabletype.test( src.type ) ) {5409 // ie6-8 fails to persist the checked state of a cloned checkbox5410 // or radio button. worse, ie6-7 fail to give the cloned element5411 // a checked appearance if the defaultchecked value isn't also set5412 dest.defaultchecked = dest.checked = src.checked;5413 // ie6-7 get confused and end up setting the value of a cloned5414 // checkbox/radio button to an empty string instead of "on"5415 if ( dest.value !== src.value ) {5416 dest.value = src.value;5417 }5418 // ie6-8 fails to return the selected option to the default selected5419 // state when cloning options5420 } else if ( nodename === "option" ) {5421 dest.defaultselected = dest.selected = src.defaultselected;5422 // ie6-8 fails to set the defaultvalue to the correct value when5423 // cloning other types of input fields5424 } else if ( nodename === "input" || nodename === "textarea" ) {5425 dest.defaultvalue = src.defaultvalue;5426 }5427}5428jquery .each({5429 appendto: "append",5430 prependto: "prepend",5431 insertbefore: "before",5432 insertafter: "after",5433 replaceall: "replacewith"5434}, function( name, original ) {5435 jquery .fn[ name ] = function( selector ) {5436 var elems,5437 i = 0,5438 ret = [],5439 insert = jquery ( selector ),5440 last = insert.length - 1;5441 for ( ; i <= last; i++ ) {5442 elems = i === last ? this : this.clone(true);5443 jquery ( insert[i] )[ original ]( elems );5444 // modern browsers can apply jquery collections as arrays, but oldie needs a .get()5445 core_push.apply( ret, elems.get() );5446 }5447 return this.pushstack( ret );5448 };5449});5450function getall( context, tag ) {5451 var elems, elem,5452 i = 0,5453 found = typeof context.getelementsbytagname !== core_strundefined ? context.getelementsbytagname( tag || "*" ) :5454 typeof context.queryselectorall !== core_strundefined ? context.queryselectorall( tag || "*" ) :5455 undefined;5456 if ( !found ) {5457 for ( found = [], elems = context.childnodes || context; (elem = elems[i]) != null; i++ ) {5458 if ( !tag || jquery .nodename( elem, tag ) ) {5459 found.push( elem );5460 } else {5461 jquery .merge( found, getall( elem, tag ) );5462 }5463 }5464 }5465 return tag === undefined || tag && jquery .nodename( context, tag ) ?5466 jquery .merge( [ context ], found ) :5467 found;5468}5469// used in buildfragment, fixes the defaultchecked property5470function fixdefaultchecked( elem ) {5471 if ( manipulation_rcheckabletype.test( elem.type ) ) {5472 elem.defaultchecked = elem.checked;5473 }5474}5475jquery .extend({5476 clone: function( elem, dataandevents, deepdataandevents ) {5477 var destelements, node, clone, i, srcelements,5478 inpage = jquery .contains( elem.ownerdocument, elem );5479 if ( jquery .support.html5clone || jquery .isxmldoc(elem) || !rnoshimcache.test( "<" + elem.nodename + ">" ) ) {5480 clone = elem.clonenode( true );5481 // ie<=8 does not properly clone detached, unknown element nodes5482 } else {5483 fragmentdiv.innerhtml = elem.outerhtml;5484 fragmentdiv.removechild( clone = fragmentdiv.firstchild );5485 }5486 if ( (!jquery .support.nocloneevent || !jquery .support.noclonechecked) &&5487 (elem.nodetype === 1 || elem.nodetype === 11) && !jquery .isxmldoc(elem) ) {5488 // we eschew sizzle here for performance reasons: http://js perf.com/getall-vs-sizzle/25489 destelements = getall( clone );5490 srcelements = getall( elem );5491 // fix all ie cloning issues5492 for ( i = 0; (node = srcelements[i]) != null; ++i ) {5493 // ensure that the destination node is not null; fixes #95875494 if ( destelements[i] ) {5495 fixclonenodeissues( node, destelements[i] );5496 }5497 }5498 }5499 // copy the events from the original to the clone5500 if ( dataandevents ) {5501 if ( deepdataandevents ) {5502 srcelements = srcelements || getall( elem );5503 destelements = destelements || getall( clone );5504 for ( i = 0; (node = srcelements[i]) != null; i++ ) {5505 clonecopyevent( node, destelements[i] );5506 }5507 } else {5508 clonecopyevent( elem, clone );5509 }5510 }5511 // preserve script evaluation history5512 destelements = getall( clone, "script" );5513 if ( destelements.length > 0 ) {5514 setglobaleval( destelements, !inpage && getall( elem, "script" ) );5515 }5516 destelements = srcelements = node = null;5517 // return the cloned set5518 return clone;5519 },5520 buildfragment: function( elems, context, scripts, selection ) {5521 var j, elem, contains,5522 tmp, tag, tbody, wrap,5523 l = elems.length,5524 // ensure a safe fragment5525 safe = createsafefragment( context ),5526 nodes = [],5527 i = 0;5528 for ( ; i < l; i++ ) {5529 elem = elems[ i ];5530 if ( elem || elem === 0 ) {5531 // add nodes directly5532 if ( jquery .type( elem ) === "object" ) {5533 jquery .merge( nodes, elem.nodetype ? [ elem ] : elem );5534 // convert non-html into a text node5535 } else if ( !rhtml.test( elem ) ) {5536 nodes.push( context.createtextnode( elem ) );5537 // convert html into dom nodes5538 } else {5539 tmp = tmp || safe.appendchild( context.createelement("div") );5540 // deserialize a standard representation5541 tag = ( rtagname.exec( elem ) || ["", ""] )[1].tolowercase();5542 wrap = wrapmap[ tag ] || wrapmap._default;5543 tmp.innerhtml = wrap[1] + elem.replace( rxhtmltag, "<$1></$2>" ) + wrap[2];5544 // descend through wrappers to the right content5545 j = wrap[0];5546 while ( j-- ) {5547 tmp = tmp.lastchild;5548 }5549 // manually add leading whitespace removed by ie5550 if ( !jquery .support.leadingwhitespace && rleadingwhitespace.test( elem ) ) {5551 nodes.push( context.createtextnode( rleadingwhitespace.exec( elem )[0] ) );5552 }5553 // remove ie's autoinserted <tbody> from table fragments5554 if ( !jquery .support.tbody ) {5555 // string was a <table>, *may* have spurious <tbody>5556 elem = tag === "table" && !rtbody.test( elem ) ?5557 tmp.firstchild :5558 // string was a bare <thead> or <tfoot>5559 wrap[1] === "<table>" && !rtbody.test( elem ) ?5560 tmp :5561 0;5562 j = elem && elem.childnodes.length;5563 while ( j-- ) {5564 if ( jquery .nodename( (tbody = elem.childnodes[j]), "tbody" ) && !tbody.childnodes.length ) {5565 elem.removechild( tbody );5566 }5567 }5568 }5569 jquery .merge( nodes, tmp.childnodes );5570 // fix #12392 for webkit and ie > 95571 tmp.textcontent = "";5572 // fix #12392 for oldie5573 while ( tmp.firstchild ) {5574 tmp.removechild( tmp.firstchild );5575 }5576 // remember the top-level container for proper cleanup5577 tmp = safe.lastchild;5578 }5579 }5580 }5581 // fix #11356: clear elements from fragment5582 if ( tmp ) {5583 safe.removechild( tmp );5584 }5585 // reset defaultchecked for any radios and checkboxes5586 // about to be appended to the dom in ie 6/7 (#8060)5587 if ( !jquery .support.appendchecked ) {5588 jquery .grep( getall( nodes, "input" ), fixdefaultchecked );5589 }5590 i = 0;5591 while ( (elem = nodes[ i++ ]) ) {5592 // #4087 - if origin and destination elements are the same, and this is5593 // that element, do not do anything5594 if ( selection && jquery .inarray( elem, selection ) !== -1 ) {5595 continue;5596 }5597 contains = jquery .contains( elem.ownerdocument, elem );5598 // append to fragment5599 tmp = getall( safe.appendchild( elem ), "script" );5600 // preserve script evaluation history5601 if ( contains ) {5602 setglobaleval( tmp );5603 }5604 // capture executables5605 if ( scripts ) {5606 j = 0;5607 while ( (elem = tmp[ j++ ]) ) {5608 if ( rscripttype.test( elem.type || "" ) ) {5609 scripts.push( elem );5610 }5611 }5612 }5613 }5614 tmp = null;5615 return safe;5616 },5617 cleandata: function( elems, /* internal */ acceptdata ) {5618 var elem, type, id, data,5619 i = 0,5620 internalkey = jquery .expando,5621 cache = jquery .cache,5622 deleteexpando = jquery .support.deleteexpando,5623 special = jquery .event.special;5624 for ( ; (elem = elems[i]) != null; i++ ) {5625 if ( acceptdata || jquery .acceptdata( elem ) ) {5626 id = elem[ internalkey ];5627 data = id && cache[ id ];5628 if ( data ) {5629 if ( data.events ) {5630 for ( type in data.events ) {5631 if ( special[ type ] ) {5632 jquery .event.remove( elem, type );5633 // this is a shortcut to avoid jquery .event.remove's overhead5634 } else {5635 jquery .removeevent( elem, type, data.handle );5636 }5637 }5638 }5639 // remove cache only if it was not already removed by jquery .event.remove5640 if ( cache[ id ] ) {5641 delete cache[ id ];5642 // ie does not allow us to delete expando properties from nodes,5643 // nor does it have a removeattribute function on document nodes;5644 // we must handle all of these cases5645 if ( deleteexpando ) {5646 delete elem[ internalkey ];5647 } else if ( typeof elem.removeattribute !== core_strundefined ) {5648 elem.removeattribute( internalkey );5649 } else {5650 elem[ internalkey ] = null;5651 }5652 core_deletedids.push( id );5653 }5654 }5655 }5656 }5657 }5658});5659var iframe, getstyles, curcss,5660 ralpha = /alpha\([^)]*\)/i,5661 ropacity = /opacity\s*=\s*([^)]*)/,5662 rposition = /^(top|right|bottom|left)$/,5663 // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"5664 // see here for display values: https://developer.mozilla.org/en-us/docs/css/display5665 rdisplayswap = /^(none|table(?!-c[ea]).+)/,5666 rmargin = /^margin/,5667 rnumsplit = new regexp( "^(" + core_pnum + ")(.*)$", "i" ),5668 rnumnonpx = new regexp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ),5669 rrelnum = new regexp( "^([+-])=(" + core_pnum + ")", "i" ),5670 elemdisplay = { body: "block" },5671 cssshow = { position: "absolute", visibility: "hidden", display: "block" },5672 cssnormaltransform = {5673 letterspacing: 0,5674 fontweight: 4005675 },5676 cssexpand = [ "top", "right", "bottom", "left" ],5677 cssprefixes = [ "webkit", "o", "moz", "ms" ];5678// return a css property mapped to a potentially vendor prefixed property5679function vendorpropname( style, name ) {5680 // shortcut for names that are not vendor prefixed5681 if ( name in style ) {5682 return name;5683 }5684 // check for vendor prefixed names5685 var capname = name.charat(0).touppercase() + name.slice(1),5686 origname = name,5687 i = cssprefixes.length;5688 while ( i-- ) {5689 name = cssprefixes[ i ] + capname;5690 if ( name in style ) {5691 return name;5692 }5693 }5694 return origname;5695}5696function ishidden( elem, el ) {5697 // ishidden might be called from jquery #filter function;5698 // in that case, element will be second argument5699 elem = el || elem;5700 return jquery .css( elem, "display" ) === "none" || !jquery .contains( elem.ownerdocument, elem );5701}5702function showhide( elements, show ) {5703 var display, elem, hidden,5704 values = [],5705 index = 0,5706 length = elements.length;5707 for ( ; index < length; index++ ) {5708 elem = elements[ index ];5709 //索引的事件赋值给变量elem5710 if ( !elem.style ) {5711 continue;5712 }5713 values[ index ] = jquery ._data( elem, "olddisplay" );5714 display = elem.style.display;5715 if ( show ) {5716 // reset the inline display of this element to learn if it is5717 // being hidden by cascaded rules or not5718 // 重置内联元素5719 if ( !values[ index ] && display === "none" ) {5720 elem.style.display = "";5721 }5722 // set elements which have been overridden with display: none5723 // in a stylesheet to whatever the default browser style is5724 // for such an element5725 if ( elem.style.display === "" && ishidden( elem ) ) {5726 values[ index ] = jquery ._data( elem, "olddisplay", css_defaultdisplay(elem.nodename) );5727 }5728 } else {5729 if ( !values[ index ] ) {5730 hidden = ishidden( elem );5731 if ( display && display !== "none" || !hidden ) {5732 jquery ._data( elem, "olddisplay", hidden ? display : jquery .css( elem, "display" ) );5733 }5734 }5735 }5736 }5737 // set the display of most of the elements in a second loop5738 // to avoid the constant reflow5739 for ( index = 0; index < length; index++ ) {5740 elem = elements[ index ];5741 if ( !elem.style ) {5742 continue;5743 }5744 if ( !show || elem.style.display === "none" || elem.style.display === "" ) {5745 elem.style.display = show ? values[ index ] || "" : "none";5746 }5747 }5748 return elements;5749}5750jquery .fn.extend({5751 css: function( name, value ) {5752 return jquery .access( this, function( elem, name, value ) {5753 var len, styles,5754 map = {},5755 i = 0;5756 if ( jquery .isarray( name ) ) {5757 styles = getstyles( elem );5758 len = name.length;5759 for ( ; i < len; i++ ) {5760 map[ name[ i ] ] = jquery .css( elem, name[ i ], false, styles );5761 }5762 return map;5763 }5764 return value !== undefined ?5765 jquery .style( elem, name, value ) :5766 jquery .css( elem, name );5767 }, name, value, arguments.length > 1 );5768 },5769 show: function() {5770 return showhide( this, true );5771 },5772 hide: function() {5773 return showhide( this );5774 },5775 toggle: function( state ) {5776 var bool = typeof state === "boolean";5777 return this.each(function() {5778 if ( bool ? state : ishidden( this ) ) {5779 jquery ( this ).show();5780 } else {5781 jquery ( this ).hide();5782 }5783 });5784 }5785});5786jquery .extend({5787 // add in style property hooks for overriding the default5788 // behavior of getting and setting a style property5789 csshooks: {5790 opacity: {5791 get: function( elem, computed ) {5792 if ( computed ) {5793 // we should always get a number back from opacity5794 var ret = curcss( elem, "opacity" );5795 return ret === "" ? "1" : ret;5796 }5797 }5798 }5799 },5800 // exclude the following css properties to add px5801 cssnumber: {5802 "columncount": true,5803 "fillopacity": true,5804 "fontweight": true,5805 "lineheight": true,5806 "opacity": true,5807 "orphans": true,5808 "widows": true,5809 "zindex": true,5810 "zoom": true5811 },5812 // add in properties whose names you wish to fix before5813 // setting or getting the value5814 cssprops: {5815 // normalize float css property5816 "float": jquery .support.cssfloat ? "cssfloat" : "stylefloat"5817 },5818 // get and set the style property on a dom node5819 style: function( elem, name, value, extra ) {5820 // don't set styles on text and comment nodes5821 if ( !elem || elem.nodetype === 3 || elem.nodetype === 8 || !elem.style ) {5822 return;5823 }5824 // make sure that we're working with the right name5825 var ret, type, hooks,5826 origname = jquery .camelcase( name ),5827 style = elem.style;5828 name = jquery .cssprops[ origname ] || ( jquery .cssprops[ origname ] = vendorpropname( style, origname ) );5829 // gets hook for the prefixed version5830 // followed by the unprefixed version5831 hooks = jquery .csshooks[ name ] || jquery .csshooks[ origname ];5832 // check if we're setting a value5833 if ( value !== undefined ) {5834 type = typeof value;5835 // convert relative number strings (+= or -=) to relative numbers. #73455836 if ( type === "string" && (ret = rrelnum.exec( value )) ) {5837 value = ( ret[1] + 1 ) * ret[2] + parsefloat( jquery .css( elem, name ) );5838 // fixes bug #92375839 type = "number";5840 }5841 // make sure that nan and null values aren't set. see: #71165842 if ( value == null || type === "number" && isnan( value ) ) {5843 return;5844 }5845 // if a number was passed in, add 'px' to the (except for certain css properties)5846 if ( type === "number" && !jquery .cssnumber[ origname ] ) {5847 value += "px";5848 }5849 // fixes #8908, it can be done more correctly by specifing setters in csshooks,5850 // but it would mean to define eight (for every problematic property) identical functions5851 if ( !jquery .support.clearclonestyle && value === "" && name.indexof("background") === 0 ) {5852 style[ name ] = "inherit";5853 }5854 // if a hook was provided, use that value, otherwise just set the specified value5855 if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {5856 // wrapped to prevent ie from throwing errors when 'invalid' values are provided5857 // fixes bug #55095858 try {5859 style[ name ] = value;5860 } catch(e) {}5861 }5862 } else {5863 // if a hook was provided get the non-computed value from there5864 if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {5865 return ret;5866 }5867 // otherwise just get the value from the style object5868 return style[ name ];5869 }5870 },5871 css: function( elem, name, extra, styles ) {5872 var num, val, hooks,5873 origname = jquery .camelcase( name );5874 // make sure that we're working with the right name5875 name = jquery .cssprops[ origname ] || ( jquery .cssprops[ origname ] = vendorpropname( elem.style, origname ) );5876 // gets hook for the prefixed version5877 // followed by the unprefixed version5878 hooks = jquery .csshooks[ name ] || jquery .csshooks[ origname ];5879 // if a hook was provided get the computed value from there5880 if ( hooks && "get" in hooks ) {5881 val = hooks.get( elem, true, extra );5882 }5883 // otherwise, if a way to get the computed value exists, use that5884 if ( val === undefined ) {5885 val = curcss( elem, name, styles );5886 }5887 //convert "normal" to computed value5888 if ( val === "normal" && name in cssnormaltransform ) {5889 val = cssnormaltransform[ name ];5890 }5891 // return, converting to number if forced or a qualifier was provided and val looks numeric5892 if ( extra === "" || extra ) {5893 num = parsefloat( val );5894 return extra === true || jquery .isnumeric( num ) ? num || 0 : val;5895 }5896 return val;5897 },5898 // a method for quickly swapping in/out css properties to get correct calculations5899 swap: function( elem, options, callback, args ) {5900 var ret, name,5901 old = {};5902 // remember the old values, and insert the new ones5903 for ( name in options ) {5904 old[ name ] = elem.style[ name ];5905 elem.style[ name ] = options[ name ];5906 }5907 ret = callback.apply( elem, args || [] );5908 // revert the old values5909 for ( name in options ) {5910 elem.style[ name ] = old[ name ];5911 }5912 return ret;5913 }5914});5915// note: we've included the "window" in window.getcomputedstyle5916// because js dom on node.js will break without it.5917if ( window.getcomputedstyle ) {5918 getstyles = function( elem ) {5919 return window.getcomputedstyle( elem, null );5920 };5921 curcss = function( elem, name, _computed ) {5922 var width, minwidth, maxwidth,5923 computed = _computed || getstyles( elem ),5924 // getpropertyvalue is only needed for .css('filter') in ie9, see #125375925 ret = computed ? computed.getpropertyvalue( name ) || computed[ name ] : undefined,5926 style = elem.style;5927 if ( computed ) {5928 if ( ret === "" && !jquery .contains( elem.ownerdocument, elem ) ) {5929 ret = jquery .style( elem, name );5930 }5931 // a tribute to the "awesome hack by dean edwards"5932 // chrome < 17 and safari 5.0 uses "computed value" instead of "used value" for margin-right5933 // safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels5934 // this is against the cssom draft spec: http://dev.w3.org/csswg/cssom/#resolved-values5935 if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {5936 // remember the original values5937 width = style.width;5938 minwidth = style.minwidth;5939 maxwidth = style.maxwidth;5940 // put in the new values to get a computed value out5941 style.minwidth = style.maxwidth = style.width = ret;5942 ret = computed.width;5943 // revert the changed values5944 style.width = width;5945 style.minwidth = minwidth;5946 style.maxwidth = maxwidth;5947 }5948 }5949 return ret;5950 };5951} else if ( document.documentelement.currentstyle ) {5952 getstyles = function( elem ) {5953 return elem.currentstyle;5954 };5955 curcss = function( elem, name, _computed ) {5956 var left, rs, rsleft,5957 computed = _computed || getstyles( elem ),5958 ret = computed ? computed[ name ] : undefined,5959 style = elem.style;5960 // avoid setting ret to empty string here5961 // so we don't default to auto5962 if ( ret == null && style && style[ name ] ) {5963 ret = style[ name ];5964 }5965 // from the awesome hack by dean edwards5966 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-1022915967 // if we're not dealing with a regular pixel number5968 // but a number that has a weird ending, we need to convert it to pixels5969 // but not position css attributes, as those are proportional to the parent element instead5970 // and we can't measure the parent instead because it might trigger a "stacking dolls" problem5971 if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {5972 // remember the original values5973 left = style.left;5974 rs = elem.runtimestyle;5975 rsleft = rs && rs.left;5976 // put in the new values to get a computed value out5977 if ( rsleft ) {5978 rs.left = elem.currentstyle.left;5979 }5980 style.left = name === "fontsize" ? "1em" : ret;5981 ret = style.pixelleft + "px";5982 // revert the changed values5983 style.left = left;5984 if ( rsleft ) {5985 rs.left = rsleft;5986 }5987 }5988 return ret === "" ? "auto" : ret;5989 };5990}5991function setpositivenumber( elem, value, subtract ) {5992 var matches = rnumsplit.exec( value );5993 return matches ?5994 // guard against undefined "subtract", e.g., when used as in csshooks5995 math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :5996 value;5997}5998function augmentwidthorheight( elem, name, extra, isborderbox, styles ) {5999 var i = extra === ( isborderbox ? "border" : "content" ) ?6000 // if we already have the right measurement, avoid augmentation6001 4 :6002 // otherwise initialize for horizontal or vertical properties6003 name === "width" ? 1 : 0,6004 val = 0;6005 for ( ; i < 4; i += 2 ) {6006 // both box models exclude margin, so add it if we want it6007 if ( extra === "margin" ) {6008 val += jquery .css( elem, extra + cssexpand[ i ], true, styles );6009 }6010 if ( isborderbox ) {6011 // border-box includes padding, so remove it if we want content6012 if ( extra === "content" ) {6013 val -= jquery .css( elem, "padding" + cssexpand[ i ], true, styles );6014 }6015 // at this point, extra isn't border nor margin, so remove border6016 if ( extra !== "margin" ) {6017 val -= jquery .css( elem, "border" + cssexpand[ i ] + "width", true, styles );6018 }6019 } else {6020 // at this point, extra isn't content, so add padding6021 val += jquery .css( elem, "padding" + cssexpand[ i ], true, styles );6022 // at this point, extra isn't content nor padding, so add border6023 if ( extra !== "padding" ) {6024 val += jquery .css( elem, "border" + cssexpand[ i ] + "width", true, styles );6025 }6026 }6027 }6028 return val;6029}6030function getwidthorheight( elem, name, extra ) {6031 // start with offset property, which is equivalent to the border-box value6032 var valueisborderbox = true,6033 val = name === "width" ? elem.offsetwidth : elem.offsetheight,6034 styles = getstyles( elem ),6035 isborderbox = jquery .support.boxsizing && jquery .css( elem, "boxsizing", false, styles ) === "border-box";6036 // some non-html elements return undefined for offsetwidth, so check for null/undefined6037 // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=6492856038 // mathml - https://bugzilla.mozilla.org/show_bug.cgi?id=4916686039 if ( val <= 0 || val == null ) {6040 // fall back to computed then uncomputed css if necessary6041 val = curcss( elem, name, styles );6042 if ( val < 0 || val == null ) {6043 val = elem.style[ name ];6044 }6045 // computed unit is not pixels. stop here and return.6046 if ( rnumnonpx.test(val) ) {6047 return val;6048 }6049 // we need the check for style in case a browser which returns unreliable values6050 // for getcomputedstyle silently falls back to the reliable elem.style6051 valueisborderbox = isborderbox && ( jquery .support.boxsizingreliable || val === elem.style[ name ] );6052 // normalize "", auto, and prepare for extra6053 val = parsefloat( val ) || 0;6054 }6055 // use the active box-sizing model to add/subtract irrelevant styles6056 return ( val +6057 augmentwidthorheight(6058 elem,6059 name,6060 extra || ( isborderbox ? "border" : "content" ),6061 valueisborderbox,6062 styles6063 )6064 ) + "px";6065}6066// try to determine the default display value of an element6067function css_defaultdisplay( nodename ) {6068 var doc = document,6069 display = elemdisplay[ nodename ];6070 if ( !display ) {6071 display = actualdisplay( nodename, doc );6072 // if the simple way fails, read from inside an iframe6073 if ( display === "none" || !display ) {6074 // use the already-created iframe if possible6075 iframe = ( iframe ||6076 jquery ("<iframe frameborder='0' width='0' height='0'/>")6077 .css( "csstext", "display:block !important" )6078 ).appendto( doc.documentelement );6079 // always write a new html skeleton so webkit and firefox don't choke on reuse6080 doc = ( iframe[0].contentwindow || iframe[0].contentdocument ).document;6081 doc.write("<!doctype html><html><body>");6082 doc.close();6083 display = actualdisplay( nodename, doc );6084 iframe.detach();6085 }6086 // store the correct default display6087 elemdisplay[ nodename ] = display;6088 }6089 return display;6090}6091// called only from within css_defaultdisplay6092function actualdisplay( name, doc ) {6093 var elem = jquery ( doc.createelement( name ) ).appendto( doc.body ),6094 display = jquery .css( elem[0], "display" );6095 elem.remove();6096 return display;6097}6098jquery .each([ "height", "width" ], function( i, name ) {6099 jquery .csshooks[ name ] = {6100 get: function( elem, computed, extra ) {6101 if ( computed ) {6102 // certain elements can have dimension info if we invisibly show them6103 // however, it must have a current display style that would benefit from this6104 return elem.offsetwidth === 0 && rdisplayswap.test( jquery .css( elem, "display" ) ) ?6105 jquery .swap( elem, cssshow, function() {6106 return getwidthorheight( elem, name, extra );6107 }) :6108 getwidthorheight( elem, name, extra );6109 }6110 },6111 set: function( elem, value, extra ) {6112 var styles = extra && getstyles( elem );6113 return setpositivenumber( elem, value, extra ?6114 augmentwidthorheight(6115 elem,6116 name,6117 extra,6118 jquery .support.boxsizing && jquery .css( elem, "boxsizing", false, styles ) === "border-box",6119 styles6120 ) : 06121 );6122 }6123 };6124});6125if ( !jquery .support.opacity ) {6126 jquery .csshooks.opacity = {6127 get: function( elem, computed ) {6128 // ie uses filters for opacity6129 return ropacity.test( (computed && elem.currentstyle ? elem.currentstyle.filter : elem.style.filter) || "" ) ?6130 ( 0.01 * parsefloat( regexp.$1 ) ) + "" :6131 computed ? "1" : "";6132 },6133 set: function( elem, value ) {6134 var style = elem.style,6135 currentstyle = elem.currentstyle,6136 opacity = jquery .isnumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",6137 filter = currentstyle && currentstyle.filter || style.filter || "";6138 // ie has trouble with opacity if it does not have layout6139 // force it by setting the zoom level6140 style.zoom = 1;6141 // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #66526142 // if value === "", then remove inline opacity #126856143 if ( ( value >= 1 || value === "" ) &&6144 jquery .trim( filter.replace( ralpha, "" ) ) === "" &&6145 style.removeattribute ) {6146 // setting style.filter to null, "" & " " still leave "filter:" in the csstext6147 // if "filter:" is present at all, cleartype is disabled, we want to avoid this6148 // style.removeattribute is ie only, but so apparently is this code path...6149 style.removeattribute( "filter" );6150 // if there is no filter style applied in a css rule or unset inline opacity, we are done6151 if ( value === "" || currentstyle && !currentstyle.filter ) {6152 return;6153 }6154 }6155 // otherwise, set new filter values6156 style.filter = ralpha.test( filter ) ?6157 filter.replace( ralpha, opacity ) :6158 filter + " " + opacity;6159 }6160 };6161}6162// these hooks cannot be added until dom ready because the support test6163// for it is not run until after dom ready6164jquery (function() {6165 if ( !jquery .support.reliablemarginright ) {6166 jquery .csshooks.marginright = {6167 get: function( elem, computed ) {6168 if ( computed ) {6169 // webkit bug 13343 - getcomputedstyle returns wrong value for margin-right6170 // work around by temporarily setting element display to inline-block6171 return jquery .swap( elem, { "display": "inline-block" },6172 curcss, [ elem, "marginright" ] );6173 }6174 }6175 };6176 }6177 // webkit bug: https://bugs.webkit.org/show_bug.cgi?id=290846178 // getcomputedstyle returns percent when specified for top/left/bottom/right6179 // rather than make the css module depend on the offset module, we just check for it here6180 if ( !jquery .support.pixelposition && jquery .fn.position ) {6181 jquery .each( [ "top", "left" ], function( i, prop ) {6182 jquery .csshooks[ prop ] = {6183 get: function( elem, computed ) {6184 if ( computed ) {6185 computed = curcss( elem, prop );6186 // if curcss returns percentage, fallback to offset6187 return rnumnonpx.test( computed ) ?6188 jquery ( elem ).position()[ prop ] + "px" :6189 computed;6190 }6191 }6192 };6193 });6194 }6195});6196if ( jquery .expr && jquery .expr.filters ) {6197 jquery .expr.filters.hidden = function( elem ) {6198 // support: opera <= 12.126199 // opera reports offsetwidths and offsetheights less than zero on some elements6200 return elem.offsetwidth <= 0 && elem.offsetheight <= 0 ||6201 (!jquery .support.reliablehiddenoffsets && ((elem.style && elem.style.display) || jquery .css( elem, "display" )) === "none");6202 };6203 jquery .expr.filters.visible = function( elem ) {6204 return !jquery .expr.filters.hidden( elem );6205 };6206}6207// these hooks are used by animate to expand properties6208jquery .each({6209 margin: "",6210 padding: "",6211 border: "width"6212}, function( prefix, suffix ) {6213 jquery .csshooks[ prefix + suffix ] = {6214 expand: function( value ) {6215 var i = 0,6216 expanded = {},6217 // assumes a single number if not a string6218 parts = typeof value === "string" ? value.split(" ") : [ value ];6219 for ( ; i < 4; i++ ) {6220 expanded[ prefix + cssexpand[ i ] + suffix ] =6221 parts[ i ] || parts[ i - 2 ] || parts[ 0 ];6222 }6223 return expanded;6224 }6225 };6226 if ( !rmargin.test( prefix ) ) {6227 jquery .csshooks[ prefix + suffix ].set = setpositivenumber;6228 }6229});6230var r20 = /%20/g,6231 rbracket = /\[\]$/,6232 rcrlf = /\r?\n/g,6233 rsubmittertypes = /^(?:submit|button|image|reset|file)$/i,6234 rsubmittable = /^(?:input|select|textarea|keygen)/i;6235jquery .fn.extend({6236 serialize: function() {6237 return jquery .param( this.serializearray() );6238 },6239 serializearray: function() {6240 return this.map(function(){6241 // can add prophook for "elements" to filter or add form elements6242 var elements = jquery .prop( this, "elements" );6243 return elements ? jquery .makearray( elements ) : this;6244 })6245 .filter(function(){6246 var type = this.type;6247 // use .is(":disabled") so that fieldset[disabled] works6248 return this.name && !jquery ( this ).is( ":disabled" ) &&6249 rsubmittable.test( this.nodename ) && !rsubmittertypes.test( type ) &&6250 ( this.checked || !manipulation_rcheckabletype.test( type ) );6251 })6252 .map(function( i, elem ){6253 var val = jquery ( this ).val();6254 return val == null ?6255 null :6256 jquery .isarray( val ) ?6257 jquery .map( val, function( val ){6258 return { name: elem.name, value: val.replace( rcrlf, "\r\n" ) };6259 }) :6260 { name: elem.name, value: val.replace( rcrlf, "\r\n" ) };6261 }).get();6262 }6263});6264//serialize an array of form elements or a set of6265//key/values into a query string6266jquery .param = function( a, traditional ) {6267 var prefix,6268 s = [],6269 add = function( key, value ) {6270 // if value is a function, invoke it and return its value6271 value = jquery .isfunction( value ) ? value() : ( value == null ? "" : value );6272 s[ s.length ] = encodeuricomponent( key ) + "=" + encodeuricomponent( value );6273 };6274 // set traditional to true for jquery <= 1.3.2 behavior.6275 if ( traditional === undefined ) {6276 traditional = jquery .ajaxsettings && jquery .ajaxsettings.traditional;6277 }6278 // if an array was passed in, assume that it is an array of form elements.6279 if ( jquery .isarray( a ) || ( a.jquery && !jquery .isplainobject( a ) ) ) {6280 // serialize the form elements6281 jquery .each( a, function() {6282 add( this.name, this.value );6283 });6284 } else {6285 // if traditional, encode the "old" way (the way 1.3.2 or older6286 // did it), otherwise encode params recursively.6287 for ( prefix in a ) {6288 buildparams( prefix, a[ prefix ], traditional, add );6289 }6290 }6291 // return the resulting serialization6292 return s.join( "&" ).replace( r20, "+" );6293};6294function buildparams( prefix, obj, traditional, add ) {6295 var name;6296 if ( jquery .isarray( obj ) ) {6297 // serialize array item.6298 jquery .each( obj, function( i, v ) {6299 if ( traditional || rbracket.test( prefix ) ) {6300 // treat each array item as a scalar.6301 add( prefix, v );6302 } else {6303 // item is non-scalar (array or object), encode its numeric index.6304 buildparams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );6305 }6306 });6307 } else if ( !traditional && jquery .type( obj ) === "object" ) {6308 // serialize object item.6309 for ( name in obj ) {6310 buildparams( prefix + "[" + name + "]", obj[ name ], traditional, add );6311 }6312 } else {6313 // serialize scalar item.6314 add( prefix, obj );6315 }6316}6317jquery .each( ("blur focus focusin focusout load resize scroll unload click dblclick " +6318 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +6319 "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {6320 // handle event binding6321 // 事件句柄封装6322 jquery .fn[ name ] = function( data, fn ) {6323 return arguments.length > 0 ?6324 this.on( name, null, data, fn ) :6325 this.trigger( name );6326 };6327});6328jquery .fn.hover = function( fnover, fnout ) {6329 return this.mouseenter( fnover ).mouseleave( fnout || fnover );6330};6331var6332 // document location6333 ajaxlocparts,6334 ajaxlocation,6335 ajax_nonce = jquery .now(),6336 ajax_rquery = /\?/,6337 rhash = /#.*$/,6338 rts = /([?&])_=[^&]*/,6339 rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // ie leaves an \r character at eol6340 // #7653, #8125, #8152: local protocol detection6341 rlocalprotocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,6342 rnocontent = /^(?:get|head)$/,6343 rprotocol = /^\/\//,6344 rurl = /^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,6345 // keep a copy of the old load method6346 _load = jquery .fn.load,6347 /* prefilters6348 * 1) they are useful to introduce custom datatypes (see ajax/js onp.js for an example)6349 * 2) these are called:6350 * - before asking for a transport6351 * - after param serialization (s.data is a string if s.processdata is true)6352 * 3) key is the datatype6353 * 4) the catchall symbol "*" can be used6354 * 5) execution will start with transport datatype and then continue down to "*" if needed6355 */6356 prefilters = {},6357 /* transports bindings6358 * 1) key is the datatype6359 * 2) the catchall symbol "*" can be used6360 * 3) selection will start with transport datatype and then go to "*" if needed6361 */6362 transports = {},6363 // avoid comment-prolog char sequence (#10098); must appease lint and evade compression6364 alltypes = "*/".concat("*");6365// #8138, ie may throw an exception when accessing6366// a field from window.location if document.domain has been set6367try {6368 ajaxlocation = location.href;6369} catch( e ) {6370 // use the href attribute of an a element6371 // since ie will modify it given document.location6372 ajaxlocation = document.createelement( "a" );6373 ajaxlocation.href = "";6374 ajaxlocation = ajaxlocation.href;6375}6376// segment location into parts6377ajaxlocparts = rurl.exec( ajaxlocation.tolowercase() ) || [];6378// base "constructor" for jquery .ajaxprefilter and jquery .ajaxtransport6379function addtoprefiltersortransports( structure ) {6380 // datatypeexpression is optional and defaults to "*"6381 return function( datatypeexpression, func ) {6382 if ( typeof datatypeexpression !== "string" ) {6383 func = datatypeexpression;6384 datatypeexpression = "*";6385 }6386 var datatype,6387 i = 0,6388 datatypes = datatypeexpression.tolowercase().match( core_rnotwhite ) || [];6389 if ( jquery .isfunction( func ) ) {6390 // for each datatype in the datatypeexpression6391 while ( (datatype = datatypes[i++]) ) {6392 // prepend if requested6393 if ( datatype[0] === "+" ) {6394 datatype = datatype.slice( 1 ) || "*";6395 (structure[ datatype ] = structure[ datatype ] || []).unshift( func );6396 // otherwise append6397 } else {6398 (structure[ datatype ] = structure[ datatype ] || []).push( func );6399 }6400 }6401 }6402 };6403}6404// base inspection function for prefilters and transports6405function inspectprefiltersortransports( structure, options, originaloptions, jqxhr ) {6406 var inspected = {},6407 seekingtransport = ( structure === transports );6408 function inspect( datatype ) {6409 var selected;6410 inspected[ datatype ] = true;6411 jquery .each( structure[ datatype ] || [], function( _, prefilterorfactory ) {6412 var datatypeortransport = prefilterorfactory( options, originaloptions, jqxhr );6413 if( typeof datatypeortransport === "string" && !seekingtransport && !inspected[ datatypeortransport ] ) {6414 options.datatypes.unshift( datatypeortransport );6415 inspect( datatypeortransport );6416 return false;6417 } else if ( seekingtransport ) {6418 return !( selected = datatypeortransport );6419 }6420 });6421 return selected;6422 }6423 return inspect( options.datatypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );6424}6425// a special extend for ajax options6426// that takes "flat" options (not to be deep extended)6427// fixes #98876428function ajaxextend( target, src ) {6429 var deep, key,6430 flatoptions = jquery .ajaxsettings.flatoptions || {};6431 for ( key in src ) {6432 if ( src[ key ] !== undefined ) {6433 ( flatoptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];6434 }6435 }6436 if ( deep ) {6437 jquery .extend( true, target, deep );6438 }6439 return target;6440}6441jquery .fn.load = function( url, params, callback ) {6442 if ( typeof url !== "string" && _load ) {6443 return _load.apply( this, arguments );6444 }6445 var selector, response, type,6446 self = this,6447 off = url.indexof(" ");6448 if ( off >= 0 ) {6449 selector = url.slice( off, url.length );6450 url = url.slice( 0, off );6451 }6452 // if it's a function6453 if ( jquery .isfunction( params ) ) {6454 // we assume that it's the callback6455 callback = params;6456 params = undefined;6457 // otherwise, build a param string6458 } else if ( params && typeof params === "object" ) {6459 type = "post";6460 }6461 // if we have elements to modify, make the request6462 if ( self.length > 0 ) {6463 jquery .ajax({6464 url: url,6465 // if "type" variable is undefined, then "get" method will be used6466 type: type,6467 datatype: "html",6468 data: params6469 }).done(function( responsetext ) {6470 // save response for use in complete callback6471 response = arguments;6472 self.html( selector ?6473 // if a selector was specified, locate the right elements in a dummy div6474 // exclude scripts to avoid ie 'permission denied' errors6475 jquery ("<div>").append( jquery .parsehtml( responsetext ) ).find( selector ) :6476 // otherwise use the full result6477 responsetext );6478 }).complete( callback && function( jqxhr, status ) {6479 self.each( callback, response || [ jqxhr.responsetext, status, jqxhr ] );6480 });6481 }6482 return this;6483};6484// attach a bunch of functions for handling common ajax events6485jquery .each( [ "ajaxstart", "ajaxstop", "ajaxcomplete", "ajaxerror", "ajaxsuccess", "ajaxsend" ], function( i, type ){6486 jquery .fn[ type ] = function( fn ){6487 return this.on( type, fn );6488 };6489});6490jquery .each( [ "get", "post" ], function( i, method ) {6491 jquery [ method ] = function( url, data, callback, type ) {6492 // shift arguments if data argument was omitted6493 if ( jquery .isfunction( data ) ) {6494 type = type || callback;6495 callback = data;6496 data = undefined;6497 }6498 return jquery .ajax({6499 url: url,6500 type: method,6501 datatype: type,6502 data: data,6503 success: callback6504 });6505 };6506});6507jquery .extend({6508 // counter for holding the number of active queries6509 active: 0,6510 // last-modified header cache for next request6511 lastmodified: {},6512 etag: {},6513 ajaxsettings: {6514 url: ajaxlocation,6515 type: "get",6516 islocal: rlocalprotocol.test( ajaxlocparts[ 1 ] ),6517 global: true,6518 processdata: true,6519 async: true,6520 contenttype: "application/x-www-form-urlencoded; charset=utf-8",6521 /*6522 timeout: 0,6523 data: null,6524 datatype: null,6525 username: null,6526 password : null,6527 cache: null,6528 throws: false,6529 traditional: false,6530 headers: {},6531 */6532 accepts: {6533 "*": alltypes,6534 text: "text/plain",6535 html: "text/html",6536 xml: "application/xml, text/xml",6537 js on: "application/js on, text/javascript"6538 },6539 contents: {6540 xml: /xml/,6541 html: /html/,6542 js on: /js on/6543 },6544 responsefields: {6545 xml: "responsexml",6546 text: "responsetext"6547 },6548 // data converters6549 // keys separate source (or catchall "*") and destination types with a single space6550 converters: {6551 // convert anything to text6552 "* text": window.string,6553 // text to html (true = no transformation)6554 "text html": true,6555 // evaluate text as a js on expression6556 "text js on": jquery .parsejs on,6557 // parse text as xml6558 "text xml": jquery .parsexml6559 },6560 // for options that shouldn't be deep extended:6561 // you can add your own custom options here if6562 // and when you create one that shouldn't be6563 // deep extended (see ajaxextend)6564 flatoptions: {6565 url: true,6566 context: true6567 }6568 },6569 // creates a full fledged settings object into target6570 // with both ajaxsettings and settings fields.6571 // if target is omitted, writes into ajaxsettings.6572 ajaxsetup: function( target, settings ) {6573 return settings ?6574 // building a settings object6575 ajaxextend( ajaxextend( target, jquery .ajaxsettings ), settings ) :6576 // extending ajaxsettings6577 ajaxextend( jquery .ajaxsettings, target );6578 },6579 ajaxprefilter: addtoprefiltersortransports( prefilters ),6580 ajaxtransport: addtoprefiltersortransports( transports ),6581 // main method6582 ajax: function( url, options ) {6583 // if url is an object, simulate pre-1.5 signature6584 if ( typeof url === "object" ) {6585 options = url;6586 url = undefined;6587 }6588 // force options to be an object6589 options = options || {};6590 var // cross-domain detection vars6591 parts,6592 // loop variable6593 i,6594 // url without anti-cache param6595 cacheurl,6596 // response headers as string6597 responseheadersstring,6598 // timeout handle6599 timeouttimer,6600 // to know if global events are to be dispatched6601 fireglobals,6602 transport,6603 // response headers6604 responseheaders,6605 // create the final options object6606 s = jquery .ajaxsetup( {}, options ),6607 // callbacks context6608 callbackcontext = s.context || s,6609 // context for global events is callbackcontext if it is a dom node or jquery collection6610 globaleventcontext = s.context && ( callbackcontext.nodetype || callbackcontext.jquery ) ?6611 jquery ( callbackcontext ) :6612 jquery .event,6613 // deferreds6614 deferred = jquery .deferred(),6615 completedeferred = jquery .callbacks("once memory"),6616 // status-dependent callbacks6617 statuscode = s.statuscode || {},6618 // headers (they are sent all at once)6619 requestheaders = {},6620 requestheadersnames = {},6621 // the jqxhr state6622 state = 0,6623 // default abort message6624 strabort = "canceled",6625 // fake xhr6626 jqxhr = {6627 readystate: 0,6628 // builds headers hashtable if needed6629 getresponseheader: function( key ) {6630 var match;6631 if ( state === 2 ) {6632 if ( !responseheaders ) {6633 responseheaders = {};6634 while ( (match = rheaders.exec( responseheadersstring )) ) {6635 responseheaders[ match[1].tolowercase() ] = match[ 2 ];6636 }6637 }6638 match = responseheaders[ key.tolowercase() ];6639 }6640 return match == null ? null : match;6641 },6642 // raw string6643 getallresponseheaders: function() {6644 return state === 2 ? responseheadersstring : null;6645 },6646 // caches the header6647 setrequestheader: function( name, value ) {6648 var lname = name.tolowercase();6649 if ( !state ) {6650 name = requestheadersnames[ lname ] = requestheadersnames[ lname ] || name;6651 requestheaders[ name ] = value;6652 }6653 return this;6654 },6655 // overrides response content-type header6656 overridemimetype: function( type ) {6657 if ( !state ) {6658 s.mimetype = type;6659 }6660 return this;6661 },6662 // status-dependent callbacks6663 statuscode: function( map ) {6664 var code;6665 if ( map ) {6666 if ( state < 2 ) {6667 for ( code in map ) {6668 // lazy-add the new callback in a way that preserves old ones6669 statuscode[ code ] = [ statuscode[ code ], map[ code ] ];6670 }6671 } else {6672 // execute the appropriate callbacks6673 jqxhr.always( map[ jqxhr.status ] );6674 }6675 }6676 return this;6677 },6678 // cancel the request6679 abort: function( statustext ) {6680 var finaltext = statustext || strabort;6681 if ( transport ) {6682 transport.abort( finaltext );6683 }6684 done( 0, finaltext );6685 return this;6686 }6687 };6688 // attach deferreds6689 deferred.promise( jqxhr ).complete = completedeferred.add;6690 jqxhr.success = jqxhr.done;6691 jqxhr.error = jqxhr.fail;6692 // remove hash character (#7531: and string promotion)6693 // add protocol if not provided (#5866: ie7 issue with protocol-less urls)6694 // handle falsy url in the settings object (#10093: consistency with old signature)6695 // we also use the url parameter if available6696 s.url = ( ( url || s.url || ajaxlocation ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxlocparts[ 1 ] + "//" );6697 // alias method option to type as per ticket #120046698 s.type = options.method || options.type || s.method || s.type;6699 // extract datatypes list6700 s.datatypes = jquery .trim( s.datatype || "*" ).tolowercase().match( core_rnotwhite ) || [""];6701 // a cross-domain request is in order when we have a protocol:host:port mismatch6702 if ( s.crossdomain == null ) {6703 parts = rurl.exec( s.url.tolowercase() );6704 s.crossdomain = !!( parts &&6705 ( parts[ 1 ] !== ajaxlocparts[ 1 ] || parts[ 2 ] !== ajaxlocparts[ 2 ] ||6706 ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=6707 ( ajaxlocparts[ 3 ] || ( ajaxlocparts[ 1 ] === "http:" ? 80 : 443 ) ) )6708 );6709 }6710 // convert data if not already a string6711 if ( s.data && s.processdata && typeof s.data !== "string" ) {6712 s.data = jquery .param( s.data, s.traditional );6713 }6714 // apply prefilters6715 inspectprefiltersortransports( prefilters, s, options, jqxhr );6716 // if request was aborted inside a prefilter, stop there6717 if ( state === 2 ) {6718 return jqxhr;6719 }6720 // we can fire global events as of now if asked to6721 fireglobals = s.global;6722 // watch for a new set of requests6723 if ( fireglobals && jquery .active++ === 0 ) {6724 jquery .event.trigger("ajaxstart");6725 }6726 // uppercase the type6727 s.type = s.type.touppercase();6728 // determine if request has content6729 s.hascontent = !rnocontent.test( s.type );6730 // save the url in case we're toying with the if-modified-since6731 // and/or if-none-match header later on6732 cacheurl = s.url;6733 // more options handling for requests with no content6734 if ( !s.hascontent ) {6735 // if data is available, append data to url6736 if ( s.data ) {6737 cacheurl = ( s.url += ( ajax_rquery.test( cacheurl ) ? "&" : "?" ) + s.data );6738 // #9682: remove data so that it's not used in an eventual retry6739 delete s.data;6740 }6741 // add anti-cache in url if needed6742 if ( s.cache === false ) {6743 s.url = rts.test( cacheurl ) ?6744 // if there is already a '_' parameter, set its value6745 cacheurl.replace( rts, "$1_=" + ajax_nonce++ ) :6746 // otherwise add one to the end6747 cacheurl + ( ajax_rquery.test( cacheurl ) ? "&" : "?" ) + "_=" + ajax_nonce++;6748 }6749 }6750 // set the if-modified-since and/or if-none-match header, if in ifmodified mode.6751 if ( s.ifmodified ) {6752 if ( jquery .lastmodified[ cacheurl ] ) {6753 jqxhr.setrequestheader( "if-modified-since", jquery .lastmodified[ cacheurl ] );6754 }6755 if ( jquery .etag[ cacheurl ] ) {6756 jqxhr.setrequestheader( "if-none-match", jquery .etag[ cacheurl ] );6757 }6758 }6759 // set the correct header, if data is being sent6760 if ( s.data && s.hascontent && s.contenttype !== false || options.contenttype ) {6761 jqxhr.setrequestheader( "content-type", s.contenttype );6762 }6763 // set the accepts header for the server, depending on the datatype6764 jqxhr.setrequestheader(6765 "accept",6766 s.datatypes[ 0 ] && s.accepts[ s.datatypes[0] ] ?6767 s.accepts[ s.datatypes[0] ] + ( s.datatypes[ 0 ] !== "*" ? ", " + alltypes + "; q=0.01" : "" ) :6768 s.accepts[ "*" ]6769 );6770 // check for headers option6771 for ( i in s.headers ) {6772 jqxhr.setrequestheader( i, s.headers[ i ] );6773 }6774 // allow custom headers/mimetypes and early abort6775 if ( s.beforesend && ( s.beforesend.call( callbackcontext, jqxhr, s ) === false || state === 2 ) ) {6776 // abort if not done already and return6777 return jqxhr.abort();6778 }6779 // aborting is no longer a cancellation6780 strabort = "abort";6781 // install callbacks on deferreds6782 for ( i in { success: 1, error: 1, complete: 1 } ) {6783 jqxhr[ i ]( s[ i ] );6784 }6785 // get transport6786 transport = inspectprefiltersortransports( transports, s, options, jqxhr );6787 // if no transport, we auto-abort6788 if ( !transport ) {6789 done( -1, "no transport" );6790 } else {6791 jqxhr.readystate = 1;6792 // send global event6793 if ( fireglobals ) {6794 globaleventcontext.trigger( "ajaxsend", [ jqxhr, s ] );6795 }6796 // timeout6797 if ( s.async && s.timeout > 0 ) {6798 timeouttimer = settimeout(function() {6799 jqxhr.abort("timeout");6800 }, s.timeout );6801 }6802 try {6803 state = 1;6804 transport.send( requestheaders, done );6805 } catch ( e ) {6806 // propagate exception as error if not done6807 if ( state < 2 ) {6808 done( -1, e );6809 // simply rethrow otherwise6810 } else {6811 throw e;6812 }6813 }6814 }6815 // callback for when everything is done6816 function done( status, nativestatustext, responses, headers ) {6817 var issuccess, success, error, response, modified,6818 statustext = nativestatustext;6819 // called once6820 if ( state === 2 ) {6821 return;6822 }6823 // state is "done" now6824 state = 2;6825 // clear timeout if it exists6826 if ( timeouttimer ) {6827 cleartimeout( timeouttimer );6828 }6829 // dereference transport for early garbage collection6830 // (no matter how long the jqxhr object will be used)6831 transport = undefined;6832 // cache response headers6833 responseheadersstring = headers || "";6834 // set readystate6835 jqxhr.readystate = status > 0 ? 4 : 0;6836 // get response data6837 if ( responses ) {6838 response = ajaxhandleresponses( s, jqxhr, responses );6839 }6840 // if successful, handle type chaining6841 if ( status >= 200 && status < 300 || status === 304 ) {6842 // set the if-modified-since and/or if-none-match header, if in ifmodified mode.6843 if ( s.ifmodified ) {6844 modified = jqxhr.getresponseheader("last-modified");6845 if ( modified ) {6846 jquery .lastmodified[ cacheurl ] = modified;6847 }6848 modified = jqxhr.getresponseheader("etag");6849 if ( modified ) {6850 jquery .etag[ cacheurl ] = modified;6851 }6852 }6853 // if no content6854 if ( status === 204 ) {6855 issuccess = true;6856 statustext = "nocontent";6857 // if not modified6858 } else if ( status === 304 ) {6859 issuccess = true;6860 statustext = "notmodified";6861 // if we have data, let's convert it6862 // 如果我们有数据,转换他6863 } else {6864 issuccess = ajaxconvert( s, response );6865 statustext = issuccess.state;6866 success = issuccess.data;6867 error = issuccess.error;6868 issuccess = !error;6869 }6870 } else {6871 // we extract error from statustext6872 // then normalize statustext and status for non-aborts6873 error = statustext;6874 if ( status || !statustext ) {6875 statustext = "error";6876 if ( status < 0 ) {6877 status = 0;6878 }6879 }6880 }6881 // set data for the fake xhr object6882 // 为伪造的xhr对象设置数据6883 jqxhr.status = status;6884 jqxhr.statustext = ( nativestatustext || statustext ) + "";6885 // success/error6886 if ( issuccess ) {6887 deferred.resolvewith( callbackcontext, [ success, statustext, jqxhr ] );6888 } else {6889 deferred.rejectwith( callbackcontext, [ jqxhr, statustext, error ] );6890 }6891 // status-dependent callbacks6892 jqxhr.statuscode( statuscode );6893 statuscode = undefined;6894 if ( fireglobals ) {6895 globaleventcontext.trigger( issuccess ? "ajaxsuccess" : "ajaxerror",6896 [ jqxhr, s, issuccess ? success : error ] );6897 }6898 // complete6899 // 完成6900 completedeferred.firewith( callbackcontext, [ jqxhr, statustext ] );6901 if ( fireglobals ) {6902 globaleventcontext.trigger( "ajaxcomplete", [ jqxhr, s ] );6903 // handle the global ajax counter6904 // 处理全局的ajax计数器6905 if ( !( --jquery .active ) ) {6906 jquery .event.trigger("ajaxstop");6907 }6908 }6909 }6910 return jqxhr;6911 },6912 getscript: function( url, callback ) {6913 return jquery .get( url, undefined, callback, "script" );6914 },6915 getjs on: function( url, data, callback ) {6916 return jquery .get( url, data, callback, "js on" );6917 }6918});6919/* handles responses to an ajax request:6920 * - sets all responsexxx fields accordingly6921 * - finds the right datatype (mediates between content-type and expected datatype)6922 * - returns the corresponding response6923 */6924function ajaxhandleresponses( s, jqxhr, responses ) {6925 var firstdatatype, ct, finaldatatype, type,6926 contents = s.contents,6927 datatypes = s.datatypes,6928 responsefields = s.responsefields;6929 // fill responsexxx fields6930 for ( type in responsefields ) {6931 if ( type in responses ) {6932 jqxhr[ responsefields[type] ] = responses[ type ];6933 }6934 }6935 // remove auto datatype and get content-type in the process6936 while( datatypes[ 0 ] === "*" ) {6937 datatypes.shift();6938 if ( ct === undefined ) {6939 ct = s.mimetype || jqxhr.getresponseheader("content-type");6940 }6941 }6942 // check if we're dealing with a known content-type6943 if ( ct ) {6944 for ( type in contents ) {6945 if ( contents[ type ] && contents[ type ].test( ct ) ) {6946 datatypes.unshift( type );6947 break;6948 }6949 }6950 }6951 // check to see if we have a response for the expected datatype6952 if ( datatypes[ 0 ] in responses ) {6953 finaldatatype = datatypes[ 0 ];6954 } else {6955 // try convertible datatypes6956 for ( type in responses ) {6957 if ( !datatypes[ 0 ] || s.converters[ type + " " + datatypes[0] ] ) {6958 finaldatatype = type;6959 break;6960 }6961 if ( !firstdatatype ) {6962 firstdatatype = type;6963 }6964 }6965 // or just use first one6966 finaldatatype = finaldatatype || firstdatatype;6967 }6968 // if we found a datatype6969 // we add the datatype to the list if needed6970 // and return the corresponding response6971 if ( finaldatatype ) {6972 if ( finaldatatype !== datatypes[ 0 ] ) {6973 datatypes.unshift( finaldatatype );6974 }6975 return responses[ finaldatatype ];6976 }6977}6978// chain conversions given the request and the original response6979function ajaxconvert( s, response ) {6980 var conv2, current, conv, tmp,6981 converters = {},6982 i = 0,6983 // work with a copy of datatypes in case we need to modify it for conversion6984 datatypes = s.datatypes.slice(),6985 prev = datatypes[ 0 ];6986 // apply the datafilter if provided6987 if ( s.datafilter ) {6988 response = s.datafilter( response, s.datatype );6989 }6990 // create converters map with lowercased keys6991 if ( datatypes[ 1 ] ) {6992 for ( conv in s.converters ) {6993 converters[ conv.tolowercase() ] = s.converters[ conv ];6994 }6995 }6996 // convert to each sequential datatype, tolerating list modification6997 for ( ; (current = datatypes[++i]); ) {6998 // there's only work to do if current datatype is non-auto6999 if ( current !== "*" ) {7000 // convert response if prev datatype is non-auto and differs from current7001 if ( prev !== "*" && prev !== current ) {7002 // seek a direct converter7003 conv = converters[ prev + " " + current ] || converters[ "* " + current ];7004 // if none found, seek a pair7005 if ( !conv ) {7006 for ( conv2 in converters ) {7007 // if conv2 outputs current7008 tmp = conv2.split(" ");7009 if ( tmp[ 1 ] === current ) {7010 // if prev can be converted to accepted input7011 conv = converters[ prev + " " + tmp[ 0 ] ] ||7012 converters[ "* " + tmp[ 0 ] ];7013 if ( conv ) {7014 // condense equivalence converters7015 if ( conv === true ) {7016 conv = converters[ conv2 ];7017 // otherwise, insert the intermediate datatype7018 } else if ( converters[ conv2 ] !== true ) {7019 current = tmp[ 0 ];7020 datatypes.splice( i--, 0, current );7021 }7022 break;7023 }7024 }7025 }7026 }7027 // apply converter (if not an equivalence)7028 if ( conv !== true ) {7029 // unless errors are allowed to bubble, catch and return them7030 if ( conv && s["throws"] ) {7031 response = conv( response );7032 } else {7033 try {7034 response = conv( response );7035 } catch ( e ) {7036 return { state: "parsererror", error: conv ? e : "no conversion from " + prev + " to " + current };7037 }7038 }7039 }7040 }7041 // update prev for next iteration7042 prev = current;7043 }7044 }7045 return { state: "success", data: response };7046}7047// install script datatype7048jquery .ajaxsetup({7049 accepts: {7050 script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"7051 },7052 contents: {7053 script: /(?:java|ecma)script/7054 },7055 converters: {7056 "text script": function( text ) {7057 jquery .globaleval( text );7058 return text;7059 }7060 }7061});7062// handle cache's special case and global7063jquery .ajaxprefilter( "script", function( s ) {7064 if ( s.cache === undefined ) {7065 s.cache = false;7066 }7067 if ( s.crossdomain ) {7068 s.type = "get";7069 s.global = false;7070 }7071});7072// bind script tag hack transport7073jquery .ajaxtransport( "script", function(s) {7074 // this transport only deals with cross domain requests7075 if ( s.crossdomain ) {7076 var script,7077 head = document.head || jquery ("head")[0] || document.documentelement;7078 return {7079 send: function( _, callback ) {7080 script = document.createelement("script");7081 script.async = true;7082 if ( s.scriptcharset ) {7083 script.charset = s.scriptcharset;7084 }7085 script.src = s.url;7086 // attach handlers for all browsers7087 script.onload = script.onreadystatechange = function( _, isabort ) {7088 if ( isabort || !script.readystate || /loaded|complete/.test( script.readystate ) ) {7089 // handle memory leak in ie7090 script.onload = script.onreadystatechange = null;7091 // remove the script7092 if ( script.parentnode ) {7093 script.parentnode.removechild( script );7094 }7095 // dereference the script7096 script = null;7097 // callback if not abort7098 if ( !isabort ) {7099 callback( 200, "success" );7100 }7101 }7102 };7103 // circumvent ie6 bugs with base elements (#2709 and #4378) by prepending7104 // use native dom manipulation to avoid our dommanip ajax trickery7105 head.insertbefore( script, head.firstchild );7106 },7107 abort: function() {7108 if ( script ) {7109 script.onload( undefined, true );7110 }7111 }7112 };7113 }7114});7115var oldcallbacks = [],7116 rjs onp = /(=)\?(?=&|$)|\?\?/;7117// default js onp settings7118jquery .ajaxsetup({7119 js onp: "callback",7120 js onpcallback: function() {7121 var callback = oldcallbacks.pop() || ( jquery .expando + "_" + ( ajax_nonce++ ) );7122 this[ callback ] = true;7123 return callback;7124 }7125});7126// detect, normalize options and install callbacks for js onp requests7127jquery .ajaxprefilter( "js on js onp", function( s, originalsettings, jqxhr ) {7128 var callbackname, overwritten, responsecontainer,7129 js onprop = s.js onp !== false && ( rjs onp.test( s.url ) ?7130 "url" :7131 typeof s.data === "string" && !( s.contenttype || "" ).indexof("application/x-www-form-urlencoded") && rjs onp.test( s.data ) && "data"7132 );7133 // handle iff the expected data type is "js onp" or we have a parameter to set7134 if ( js onprop || s.datatypes[ 0 ] === "js onp" ) {7135 // get callback name, remembering preexisting value associated with it7136 callbackname = s.js onpcallback = jquery .isfunction( s.js onpcallback ) ?7137 s.js onpcallback() :7138 s.js onpcallback;7139 // insert callback into url or form data7140 if ( js onprop ) {7141 s[ js onprop ] = s[ js onprop ].replace( rjs onp, "$1" + callbackname );7142 } else if ( s.js onp !== false ) {7143 s.url += ( ajax_rquery.test( s.url ) ? "&" : "?" ) + s.js onp + "=" + callbackname;7144 }7145 // use data converter to retrieve js on after script execution7146 s.converters["script js on"] = function() {7147 if ( !responsecontainer ) {7148 jquery .error( callbackname + " was not called" );7149 }7150 return responsecontainer[ 0 ];7151 };7152 // force js on datatype7153 s.datatypes[ 0 ] = "js on";7154 // install callback7155 overwritten = window[ callbackname ];7156 window[ callbackname ] = function() {7157 responsecontainer = arguments;7158 };7159 // clean-up function (fires after converters)7160 jqxhr.always(function() {7161 // rest ore preexisting value7162 window[ callbackname ] = overwritten;7163 // save back as free7164 if ( s[ callbackname ] ) {7165 // make sure that re-using the options doesn't screw things around7166 s.js onpcallback = originalsettings.js onpcallback;7167 // save the callback name for future use7168 oldcallbacks.push( callbackname );7169 }7170 // call if it was a function and we have a response7171 if ( responsecontainer && jquery .isfunction( overwritten ) ) {7172 overwritten( responsecontainer[ 0 ] );7173 }7174 responsecontainer = overwritten = undefined;7175 });7176 // delegate to script7177 return "script";7178 }7179});7180var xhrcallbacks, xhrsupported,7181 xhrid = 0,7182 // #5280: internet explorer will keep connections alive if we don't abort on unload7183 xhronunloadabort = window.activexobject && function() {7184 // abort all pending requests7185 var key;7186 for ( key in xhrcallbacks ) {7187 xhrcallbacks[ key ]( undefined, true );7188 }7189 };7190// functions to create xhrs7191function createstandardxhr() {7192 try {7193 return new window.xmlhttprequest();7194 } catch( e ) {}7195}7196function createactivexhr() {7197 try {7198 return new window.activexobject("microsoft.xmlhttp");7199 } catch( e ) {}7200}7201// create the request object7202// (this is still attached to ajaxsettings for backward compatibility)7203jquery .ajaxsettings.xhr = window.activexobject ?7204 /* microsoft failed to properly7205 * implement the xmlhttprequest in ie7 (can't request local files),7206 * so we use the activexobject when it is available7207 * additionally xmlhttprequest can be disabled in ie7/ie8 so7208 * we need a fallback.7209 */7210 function() {7211 return !this.islocal && createstandardxhr() || createactivexhr();7212 } :7213 // for all other browsers, use the standard xmlhttprequest object7214 createstandardxhr;7215// determine support properties7216xhrsupported = jquery .ajaxsettings.xhr();7217jquery .support.cors = !!xhrsupported && ( "withcredentials" in xhrsupported );7218xhrsupported = jquery .support.ajax = !!xhrsupported;7219// create transport if the browser can provide an xhr7220if ( xhrsupported ) {7221 jquery .ajaxtransport(function( s ) {7222 // cross domain only allowed if supported through xmlhttprequest7223 if ( !s.crossdomain || jquery .support.cors ) {7224 var callback;7225 return {7226 send: function( headers, complete ) {7227 // get a new xhr7228 var handle, i,7229 xhr = s.xhr();7230 // open the socket7231 // passing null username, generates a login popup on opera (#2865)7232 if ( s.username ) {7233 xhr.open( s.type, s.url, s.async, s.username, s.password );7234 } else {7235 xhr.open( s.type, s.url, s.async );7236 }7237 // apply custom fields if provided7238 if ( s.xhrfields ) {7239 for ( i in s.xhrfields ) {7240 xhr[ i ] = s.xhrfields[ i ];7241 }7242 }7243 // override mime type if needed7244 if ( s.mimetype && xhr.overridemimetype ) {7245 xhr.overridemimetype( s.mimetype );7246 }7247 // x-requested-with header7248 // for cross-domain requests, seeing as conditions for a preflight are7249 // akin to a jigsaw puzzle, we simply never set it to be sure.7250 // (it can always be set on a per-request basis or even using ajaxsetup)7251 // for same-domain requests, won't change header if already provided.7252 if ( !s.crossdomain && !headers["x-requested-with"] ) {7253 headers["x-requested-with"] = "xmlhttprequest";7254 }7255 // need an extra try/catch for cross domain requests in firefox 37256 try {7257 for ( i in headers ) {7258 xhr.setrequestheader( i, headers[ i ] );7259 }7260 } catch( err ) {}7261 // do send the request7262 // this may raise an exception which is actually7263 // handled in jquery .ajax (so no try/catch here)7264 xhr.send( ( s.hascontent && s.data ) || null );7265 // listener7266 callback = function( _, isabort ) {7267 var status, responseheaders, statustext, responses;7268 // firefox throws exceptions when accessing properties7269 // of an xhr when a network error occurred7270 // http://helpful.knobs-dials.com/index.php/component_returned_failure_code:_0x80040111_(ns_error_not_available)7271 try {7272 // was never called and is aborted or complete7273 if ( callback && ( isabort || xhr.readystate === 4 ) ) {7274 // only called once7275 callback = undefined;7276 // do not keep as active anymore7277 if ( handle ) {7278 xhr.onreadystatechange = jquery .noop;7279 if ( xhronunloadabort ) {7280 delete xhrcallbacks[ handle ];7281 }7282 }7283 // if it's an abort7284 if ( isabort ) {7285 // abort it manually if needed7286 if ( xhr.readystate !== 4 ) {7287 xhr.abort();7288 }7289 } else {7290 responses = {};7291 status = xhr.status;7292 responseheaders = xhr.getallresponseheaders();7293 // when requesting binary data, ie6-9 will throw an exception7294 // on any attempt to access responsetext (#11426)7295 if ( typeof xhr.responsetext === "string" ) {7296 responses.text = xhr.responsetext;7297 }7298 // firefox throws an exception when accessing7299 // statustext for faulty cross-domain requests7300 try {7301 statustext = xhr.statustext;7302 } catch( e ) {7303 // we normalize with webkit giving an empty statustext7304 statustext = "";7305 }7306 // filter status for non standard behaviors7307 // if the request is local and we have data: assume a success7308 // (success with no data won't get notified, that's the best we7309 // can do given current implementations)7310 if ( !status && s.islocal && !s.crossdomain ) {7311 status = responses.text ? 200 : 404;7312 // ie - #1450: sometimes returns 1223 when it should be 2047313 } else if ( status === 1223 ) {7314 status = 204;7315 }7316 }7317 }7318 } catch( firefoxaccessexception ) {7319 if ( !isabort ) {7320 complete( -1, firefoxaccessexception );7321 }7322 }7323 // call complete if needed7324 if ( responses ) {7325 complete( status, statustext, responses, responseheaders );7326 }7327 };7328 if ( !s.async ) {7329 // if we're in sync mode we fire the callback7330 callback();7331 } else if ( xhr.readystate === 4 ) {7332 // (ie6 & ie7) if it's in cache and has been7333 // retrieved directly we need to fire the callback7334 settimeout( callback );7335 } else {7336 handle = ++xhrid;7337 if ( xhronunloadabort ) {7338 // create the active xhrs callbacks list if needed7339 // and attach the unload handler7340 if ( !xhrcallbacks ) {7341 xhrcallbacks = {};7342 jquery ( window ).unload( xhronunloadabort );7343 }7344 // add to list of active xhrs callbacks7345 xhrcallbacks[ handle ] = callback;7346 }7347 xhr.onreadystatechange = callback;7348 }7349 },7350 abort: function() {7351 if ( callback ) {7352 callback( undefined, true );7353 }7354 }7355 };7356 }7357 });7358}7359var fxnow, timerid,7360 rfxtypes = /^(?:toggle|show|hide)$/,7361 rfxnum = new regexp( "^(?:([+-])=|)(" + core_pnum + ")([a-z%]*)$", "i" ),7362 rrun = /queuehooks$/,7363 animationprefilters = [ defaultprefilter ],7364 tweeners = {7365 "*": [function( prop, value ) {7366 var end, unit,7367 tween = this.createtween( prop, value ),7368 parts = rfxnum.exec( value ),7369 target = tween.cur(),7370 start = +target || 0,7371 scale = 1,7372 maxiterations = 20;7373 if ( parts ) {7374 end = +parts[2];7375 unit = parts[3] || ( jquery .cssnumber[ prop ] ? "" : "px" );7376 // we need to compute starting value7377 if ( unit !== "px" && start ) {7378 // iteratively approximate from a nonzero starting point7379 // prefer the current property, because this process will be trivial if it uses the same units7380 // fallback to end or a simple constant7381 start = jquery .css( tween.elem, prop, true ) || end || 1;7382 do {7383 // if previous iteration zeroed out, double until we get *something*7384 // use a string for doubling factor so we don't accidentally see scale as unchanged below7385 scale = scale || ".5";7386 // adjust and apply7387 start = start / scale;7388 jquery .style( tween.elem, prop, start + unit );7389 // update scale, tolerating zero or nan from tween.cur()7390 // and breaking the loop if scale is unchanged or perfect, or if we've just had enough7391 } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxiterations );7392 }7393 tween.unit = unit;7394 tween.start = start;7395 // if a +=/-= token was provided, we're doing a relative animation7396 tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end;7397 }7398 return tween;7399 }]7400 };7401// animations created synchronously will run synchronously7402function createfxnow() {7403 settimeout(function() {7404 fxnow = undefined;7405 });7406 return ( fxnow = jquery .now() );7407}7408function createtweens( animation, props ) {7409 jquery .each( props, function( prop, value ) {7410 var collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),//concat() 函数用于连接两个或者多个数组7411 index = 0,7412 length = collection.length;7413 for ( ; index < length; index++ ) {7414 if ( collection[ index ].call( animation, prop, value ) ) {7415 //我们做完了这个属性7416 return;7417 }7418 }7419 });7420}7421function animation( elem, properties, options ) {7422 var result,7423 stopped,7424 index = 0,7425 length = animationprefilters.length,7426 deferred = jquery .deferred().always( function() {7427 // don't match elem in the :animated selector7428 delete tick.elem;7429 }),7430 tick = function() {7431 if ( stopped ) {7432 return false;7433 }7434 var currenttime = fxnow || createfxnow(),7435 remaining = math.max( 0, animation.starttime + animation.duration - currenttime ),7436 // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)7437 temp = remaining / animation.duration || 0,7438 percent = 1 - temp,7439 index = 0,7440 length = animation.tweens.length;7441 for ( ; index < length ; index++ ) {7442 animation.tweens[ index ].run( percent );7443 }7444 deferred.notifywith( elem, [ animation, percent, remaining ]);7445 if ( percent < 1 && length ) {7446 return remaining;7447 } else {7448 deferred.resolvewith( elem, [ animation ] );7449 return false;7450 }7451 },7452 animation = deferred.promise({7453 elem: elem,7454 props: jquery .extend( {}, properties ),7455 opts: jquery .extend( true, { specialeasing: {} }, options ),7456 originalproperties: properties,7457 originaloptions: options,7458 starttime: fxnow || createfxnow(),7459 duration: options.duration,7460 tweens: [],7461 createtween: function( prop, end ) {7462 var tween = jquery .tween( elem, animation.opts, prop, end,7463 animation.opts.specialeasing[ prop ] || animation.opts.easing );7464 animation.tweens.push( tween );7465 return tween;7466 },7467 stop: function( gotoend ) {7468 var index = 0,7469 // if we are going to the end, we want to run all the tweens7470 // otherwise we skip this part7471 length = gotoend ? animation.tweens.length : 0;7472 if ( stopped ) {7473 return this;7474 }7475 stopped = true;7476 for ( ; index < length ; index++ ) {7477 animation.tweens[ index ].run( 1 );7478 }7479 // resolve when we played the last frame7480 // otherwise, reject7481 if ( gotoend ) {7482 deferred.resolvewith( elem, [ animation, gotoend ] );7483 } else {7484 deferred.rejectwith( elem, [ animation, gotoend ] );7485 }7486 return this;7487 }7488 }),7489 props = animation.props;7490 propfilter( props, animation.opts.specialeasing );7491 for ( ; index < length ; index++ ) {7492 result = animationprefilters[ index ].call( animation, elem, props, animation.opts );7493 if ( result ) {7494 return result;7495 }7496 }7497 createtweens( animation, props );7498 if ( jquery .isfunction( animation.opts.start ) ) {7499 animation.opts.start.call( elem, animation );7500 }7501 jquery .fx.timer(7502 jquery .extend( tick, {7503 elem: elem,7504 anim: animation,7505 queue: animation.opts.queue7506 })7507 );7508 // attach callbacks from options7509 return animation.progress( animation.opts.progress )7510 .done( animation.opts.done, animation.opts.complete )7511 .fail( animation.opts.fail )7512 .always( animation.opts.always );7513}7514function propfilter( props, specialeasing ) {7515 var value, name, index, easing, hooks;7516 // camelcase, specialeasing and expand csshook pass7517 for ( index in props ) {7518 name = jquery .camelcase( index );7519 easing = specialeasing[ name ];7520 value = props[ index ];7521 if ( jquery .isarray( value ) ) {7522 easing = value[ 1 ];7523 value = props[ index ] = value[ 0 ];7524 }7525 if ( index !== name ) {7526 props[ name ] = value;7527 delete props[ index ];7528 }7529 hooks = jquery .csshooks[ name ];7530 if ( hooks && "expand" in hooks ) {7531 value = hooks.expand( value );7532 delete props[ name ];7533 // not quite $.extend, this wont overwrite keys already present.7534 // also - reusing 'index' from above because we have the correct "name"7535 for ( index in value ) {7536 if ( !( index in props ) ) {7537 props[ index ] = value[ index ];7538 specialeasing[ index ] = easing;7539 }7540 }7541 } else {7542 specialeasing[ name ] = easing;7543 }7544 }7545}7546jquery .animation = jquery .extend( animation, {7547 tweener: function( props, callback ) {7548 if ( jquery .isfunction( props ) ) {7549 callback = props;7550 props = [ "*" ];7551 } else {7552 props = props.split(" ");7553 }7554 var prop,7555 index = 0,7556 length = props.length;7557 for ( ; index < length ; index++ ) {7558 prop = props[ index ];7559 tweeners[ prop ] = tweeners[ prop ] || [];7560 tweeners[ prop ].unshift( callback );7561 }7562 },7563 prefilter: function( callback, prepend ) {7564 if ( prepend ) {7565 animationprefilters.unshift( callback );7566 } else {7567 animationprefilters.push( callback );7568 }7569 }7570});7571function defaultprefilter( elem, props, opts ) {7572 /*js hint validthis:true */7573 var prop, index, length,7574 value, datashow, toggle,7575 tween, hooks, oldfire,7576 anim = this,7577 style = elem.style,7578 orig = {},7579 handled = [],7580 hidden = elem.nodetype && ishidden( elem );7581 // handle queue: false promises7582 if ( !opts.queue ) {7583 hooks = jquery ._queuehooks( elem, "fx" );7584 if ( hooks.unqueued == null ) {7585 hooks.unqueued = 0;7586 oldfire = hooks.empty.fire;7587 hooks.empty.fire = function() {7588 if ( !hooks.unqueued ) {7589 oldfire();7590 }7591 };7592 }7593 hooks.unqueued++;7594 anim.always(function() {7595 // doing this makes sure that the complete handler will be called7596 // before this completes7597 anim.always(function() {7598 hooks.unqueued--;7599 if ( !jquery .queue( elem, "fx" ).length ) {7600 hooks.empty.fire();7601 }7602 });7603 });7604 }7605 // height/width overflow pass7606 if ( elem.nodetype === 1 && ( "height" in props || "width" in props ) ) {7607 // make sure that nothing sneaks out7608 // record all 3 overflow attributes because ie does not7609 // change the overflow attribute when overflowx and7610 // overflowy are set to the same value7611 opts.overflow = [ style.overflow, style.overflowx, style.overflowy ];7612 // set display property to inline-block for height/width7613 // animations on inline elements that are having width/height animated7614 if ( jquery .css( elem, "display" ) === "inline" &&7615 jquery .css( elem, "float" ) === "none" ) {7616 // inline-level elements accept inline-block;7617 // block-level elements need to be inline with layout7618 if ( !jquery .support.inlineblockneedslayout || css_defaultdisplay( elem.nodename ) === "inline" ) {7619 style.display = "inline-block";7620 } else {7621 style.zoom = 1;7622 }7623 }7624 }7625 if ( opts.overflow ) {7626 style.overflow = "hidden";7627 if ( !jquery .support.shrinkwrapblocks ) {7628 anim.always(function() {7629 style.overflow = opts.overflow[ 0 ];7630 style.overflowx = opts.overflow[ 1 ];7631 style.overflowy = opts.overflow[ 2 ];7632 });7633 }7634 }7635 // show/hide pass7636 for ( index in props ) {7637 value = props[ index ];7638 if ( rfxtypes.exec( value ) ) {7639 delete props[ index ];7640 toggle = toggle || value === "toggle";7641 if ( value === ( hidden ? "hide" : "show" ) ) {7642 continue;7643 }7644 handled.push( index );7645 }7646 }7647 length = handled.length;7648 if ( length ) {7649 datashow = jquery ._data( elem, "fxshow" ) || jquery ._data( elem, "fxshow", {} );7650 if ( "hidden" in datashow ) {7651 hidden = datashow.hidden;7652 }7653 // store state if its toggle - enables .stop().toggle() to "reverse"7654 if ( toggle ) {7655 datashow.hidden = !hidden;7656 }7657 if ( hidden ) {7658 jquery ( elem ).show();7659 } else {7660 anim.done(function() {7661 jquery ( elem ).hide();7662 });7663 }7664 anim.done(function() {7665 var prop;7666 jquery ._removedata( elem, "fxshow" );7667 for ( prop in orig ) {7668 jquery .style( elem, prop, orig[ prop ] );7669 }7670 });7671 for ( index = 0 ; index < length ; index++ ) {7672 prop = handled[ index ];7673 tween = anim.createtween( prop, hidden ? datashow[ prop ] : 0 );7674 orig[ prop ] = datashow[ prop ] || jquery .style( elem, prop );7675 if ( !( prop in datashow ) ) {7676 datashow[ prop ] = tween.start;7677 if ( hidden ) {7678 tween.end = tween.start;7679 tween.start = prop === "width" || prop === "height" ? 1 : 0;7680 }7681 }7682 }7683 }7684}7685function tween( elem, options, prop, end, easing ) {7686 return new tween.prototype.init( elem, options, prop, end, easing );7687}7688jquery .tween = tween;7689tween.prototype = {7690 constructor: tween,7691 init: function( elem, options, prop, end, easing, unit ) {7692 this.elem = elem;7693 this.prop = prop;7694 this.easing = easing || "swing";7695 this.options = options;7696 this.start = this.now = this.cur();7697 this.end = end;7698 this.unit = unit || ( jquery .cssnumber[ prop ] ? "" : "px" );7699 },7700 cur: function() {7701 var hooks = tween.prophooks[ this.prop ];7702 return hooks && hooks.get ?7703 hooks.get( this ) :7704 tween.prophooks._default.get( this );7705 },7706 run: function( percent ) {7707 var eased,7708 hooks = tween.prophooks[ this.prop ];7709 if ( this.options.duration ) {7710 this.pos = eased = jquery .easing[ this.easing ](7711 percent, this.options.duration * percent, 0, 1, this.options.duration7712 );7713 } else {7714 this.pos = eased = percent;7715 }7716 this.now = ( this.end - this.start ) * eased + this.start;7717 if ( this.options.step ) {7718 this.options.step.call( this.elem, this.now, this );7719 }7720 if ( hooks && hooks.set ) {7721 hooks.set( this );7722 } else {7723 tween.prophooks._default.set( this );7724 }7725 return this;7726 }7727};7728tween.prototype.init.prototype = tween.prototype;7729tween.prophooks = {7730 _default: {7731 get: function( tween ) {7732 var result;7733 if ( tween.elem[ tween.prop ] != null &&7734 (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {7735 return tween.elem[ tween.prop ];7736 }7737 // passing an empty string as a 3rd parameter to .css will automatically7738 // attempt a parsefloat and fallback to a string if the parse fails7739 // so, simple values such as "10px" are parsed to float.7740 // complex values such as "rotate(1rad)" are returned as is.7741 result = jquery .css( tween.elem, tween.prop, "" );7742 // empty strings, null, undefined and "auto" are converted to 0.7743 return !result || result === "auto" ? 0 : result;7744 },7745 set: function( tween ) {7746 // use step hook for back compat - use csshook if its there - use .style if its7747 // available and use plain properties where available7748 if ( jquery .fx.step[ tween.prop ] ) {7749 jquery .fx.step[ tween.prop ]( tween );7750 } else if ( tween.elem.style && ( tween.elem.style[ jquery .cssprops[ tween.prop ] ] != null || jquery .csshooks[ tween.prop ] ) ) {7751 jquery .style( tween.elem, tween.prop, tween.now + tween.unit );7752 } else {7753 tween.elem[ tween.prop ] = tween.now;7754 }7755 }7756 }7757};7758// remove in 2.0 - this supports ie8's panic based approach7759// to setting things on disconnected nodes7760tween.prophooks.scrolltop = tween.prophooks.scrollleft = {7761 set: function( tween ) {7762 if ( tween.elem.nodetype && tween.elem.parentnode ) {7763 tween.elem[ tween.prop ] = tween.now;7764 }7765 }7766};7767jquery .each([ "toggle", "show", "hide" ], function( i, name ) {7768 var cssfn = jquery .fn[ name ];7769 jquery .fn[ name ] = function( speed, easing, callback ) {7770 return speed == null || typeof speed === "boolean" ?7771 cssfn.apply( this, arguments ) :7772 this.animate( genfx( name, true ), speed, easing, callback );7773 };7774});7775jquery .fn.extend({7776 fadeto: function( speed, to, easing, callback ) {7777 // show any hidden elements after setting opacity to 07778 return this.filter( ishidden ).css( "opacity", 0 ).show()7779 // animate to the value specified7780 .end().animate({ opacity: to }, speed, easing, callback );7781 },7782 animate: function( prop, speed, easing, callback ) {7783 var empty = jquery .isemptyobject( prop ),7784 optall = jquery .speed( speed, easing, callback ),7785 doanimation = function() {7786 // operate on a copy of prop so per-property easing won't be lost7787 var anim = animation( this, jquery .extend( {}, prop ), optall );7788 doanimation.finish = function() {7789 anim.stop( true );7790 };7791 // empty animations, or finishing resolves immediately7792 if ( empty || jquery ._data( this, "finish" ) ) {7793 anim.stop( true );7794 }7795 };7796 doanimation.finish = doanimation;7797 return empty || optall.queue === false ?7798 this.each( doanimation ) :7799 this.queue( optall.queue, doanimation );7800 },7801 stop: function( type, clearqueue, gotoend ) {7802 var stopqueue = function( hooks ) {7803 var stop = hooks.stop;7804 delete hooks.stop;7805 stop( gotoend );7806 };7807 if ( typeof type !== "string" ) {7808 gotoend = clearqueue;7809 clearqueue = type;7810 type = undefined;7811 }7812 if ( clearqueue && type !== false ) {7813 this.queue( type || "fx", [] );7814 }7815 return this.each(function() {7816 var dequeue = true,7817 index = type != null && type + "queuehooks",7818 timers = jquery .timers,7819 data = jquery ._data( this );7820 if ( index ) {7821 if ( data[ index ] && data[ index ].stop ) {7822 stopqueue( data[ index ] );7823 }7824 } else {7825 for ( index in data ) {7826 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {7827 stopqueue( data[ index ] );7828 }7829 }7830 }7831 for ( index = timers.length; index--; ) {7832 if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {7833 timers[ index ].anim.stop( gotoend );7834 dequeue = false;7835 timers.splice( index, 1 );7836 }7837 }7838 // start the next in the queue if the last step wasn't forced7839 // timers currently will call their complete callbacks, which will dequeue7840 // but only if they were gotoend7841 if ( dequeue || !gotoend ) {7842 jquery .dequeue( this, type );7843 }7844 });7845 },7846 finish: function( type ) {7847 if ( type !== false ) {7848 type = type || "fx";7849 }7850 return this.each(function() {7851 var index,7852 data = jquery ._data( this ),7853 queue = data[ type + "queue" ],7854 hooks = data[ type + "queuehooks" ],7855 timers = jquery .timers,7856 length = queue ? queue.length : 0;7857 // enable finishing flag on private data7858 data.finish = true;7859 // empty the queue first7860 jquery .queue( this, type, [] );7861 if ( hooks && hooks.cur && hooks.cur.finish ) {7862 hooks.cur.finish.call( this );7863 }7864 // look for any active animations, and finish them7865 for ( index = timers.length; index--; ) {7866 if ( timers[ index ].elem === this && timers[ index ].queue === type ) {7867 timers[ index ].anim.stop( true );7868 timers.splice( index, 1 );7869 }7870 }7871 // look for any animations in the old queue and finish them7872 for ( index = 0; index < length; index++ ) {7873 if ( queue[ index ] && queue[ index ].finish ) {7874 queue[ index ].finish.call( this );7875 }7876 }7877 // turn off finishing flag7878 delete data.finish;7879 });7880 }7881});7882// generate parameters to create a standard animation7883function genfx( type, includewidth ) {7884 var which,7885 attrs = { height: type },7886 i = 0;7887 // if we include width, step value is 1 to do all cssexpand values,7888 // if we don't include width, step value is 2 to skip over left and right7889 includewidth = includewidth? 1 : 0;7890 for( ; i < 4 ; i += 2 - includewidth ) {7891 which = cssexpand[ i ];7892 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;7893 }7894 if ( includewidth ) {7895 attrs.opacity = attrs.width = type;7896 }7897 return attrs;7898}7899// generate shortcuts for custom animations7900jquery .each({7901 slidedown: genfx("show"),7902 slideup: genfx("hide"),7903 slidetoggle: genfx("toggle"),7904 fadein: { opacity: "show" },7905 fadeout: { opacity: "hide" },7906 fadetoggle: { opacity: "toggle" }7907}, function( name, props ) {7908 jquery .fn[ name ] = function( speed, easing, callback ) {7909 return this.animate( props, speed, easing, callback );7910 };7911});7912jquery .speed = function( speed, easing, fn ) {7913 var opt = speed && typeof speed === "object" ? jquery .extend( {}, speed ) : {7914 complete: fn || !fn && easing ||7915 jquery .isfunction( speed ) && speed,7916 duration: speed,7917 easing: fn && easing || easing && !jquery .isfunction( easing ) && easing7918 };7919 opt.duration = jquery .fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :7920 opt.duration in jquery .fx.speeds ? jquery .fx.speeds[ opt.duration ] : jquery .fx.speeds._default;7921 // normalize opt.queue - true/undefined/null -> "fx"7922 if ( opt.queue == null || opt.queue === true ) {7923 opt.queue = "fx";7924 }7925 // queueing7926 opt.old = opt.complete;7927 opt.complete = function() {7928 if ( jquery .isfunction( opt.old ) ) {7929 opt.old.call( this );7930 }7931 if ( opt.queue ) {7932 jquery .dequeue( this, opt.queue );7933 }7934 };7935 return opt;7936};7937jquery .easing = {7938 linear: function( p ) {7939 return p;7940 },7941 swing: function( p ) {7942 return 0.5 - math.cos( p*math.pi ) / 2;7943 }7944};7945jquery .timers = [];7946jquery .fx = tween.prototype.init;7947jquery .fx.tick = function() {7948 var timer,7949 timers = jquery .timers,7950 i = 0;7951 fxnow = jquery .now();7952 for ( ; i < timers.length; i++ ) {7953 timer = timers[ i ];7954 // checks the timer has not already been removed7955 if ( !timer() && timers[ i ] === timer ) {7956 timers.splice( i--, 1 );7957 }7958 }7959 if ( !timers.length ) {7960 jquery .fx.stop();7961 }7962 fxnow = undefined;7963};7964jquery .fx.timer = function( timer ) {7965 if ( timer() && jquery .timers.push( timer ) ) {7966 jquery .fx.start();7967 }7968};7969jquery .fx.interval = 13;7970jquery .fx.start = function() {7971 if ( !timerid ) {7972 timerid = setinterval( jquery .fx.tick, jquery .fx.interval );7973 }7974};7975jquery .fx.stop = function() {7976 clearinterval( timerid );7977 timerid = null;7978};7979jquery .fx.speeds = {7980 slow: 600,7981 fast: 200,7982 // default speed7983 _default: 4007984};7985// back compat <1.8 extension point7986jquery .fx.step = {};7987if ( jquery .expr && jquery .expr.filters ) {7988 jquery .expr.filters.animated = function( elem ) {7989 return jquery .grep(jquery .timers, function( fn ) {7990 return elem === fn.elem;7991 }).length;7992 };7993}7994jquery .fn.offset = function( options ) {7995 if ( arguments.length ) {7996 return options === undefined ?7997 this :7998 this.each(function( i ) {7999 jquery .offset.setoffset( this, options, i );8000 });8001 }8002 var docelem, win,8003 box = { top: 0, left: 0 },8004 elem = this[ 0 ],8005 doc = elem && elem.ownerdocument;8006 if ( !doc ) {8007 return;8008 }8009 docelem = doc.documentelement;8010 // make sure it's not a disconnected dom node8011 if ( !jquery .contains( docelem, elem ) ) {8012 return box;8013 }8014 // if we don't have gbcr, just use 0,0 rather than error8015 // blackberry 5, ios 3 (original iphone)8016 if ( typeof elem.getboundingclientrect !== core_strundefined ) {8017 box = elem.getboundingclientrect();8018 }8019 win = getwindow( doc );8020 return {8021 top: box.top + ( win.pageyoffset || docelem.scrolltop ) - ( docelem.clienttop || 0 ),8022 left: box.left + ( win.pagexoffset || docelem.scrollleft ) - ( docelem.clientleft || 0 )8023 };8024};8025jquery .offset = {8026 setoffset: function( elem, options, i ) {8027 var position = jquery .css( elem, "position" );8028 // set position first, in-case top/left are set even on static elem8029 if ( position === "static" ) {8030 elem.style.position = "relative";8031 }8032 var curelem = jquery ( elem ),8033 curoffset = curelem.offset(),8034 curcsstop = jquery .css( elem, "top" ),8035 curcssleft = jquery .css( elem, "left" ),8036 calculateposition = ( position === "absolute" || position === "fixed" ) && jquery .inarray("auto", [curcsstop, curcssleft]) > -1,8037 props = {}, curposition = {}, curtop, curleft;8038 // need to be able to calculate position if either top or left is auto and position is either absolute or fixed8039 if ( calculateposition ) {8040 curposition = curelem.position();8041 curtop = curposition.top;8042 curleft = curposition.left;8043 } else {8044 curtop = parsefloat( curcsstop ) || 0;8045 curleft = parsefloat( curcssleft ) || 0;8046 }8047 if ( jquery .isfunction( options ) ) {8048 options = options.call( elem, i, curoffset );8049 }8050 if ( options.top != null ) {8051 props.top = ( options.top - curoffset.top ) + curtop;8052 }8053 if ( options.left != null ) {8054 props.left = ( options.left - curoffset.left ) + curleft;8055 }8056 if ( "using" in options ) {8057 options.using.call( elem, props );8058 } else {8059 curelem.css( props );8060 }8061 }8062};8063jquery .fn.extend({8064 position: function() {8065 if ( !this[ 0 ] ) {8066 return;8067 }8068 var offsetparent, offset,8069 parentoffset = { top: 0, left: 0 },8070 elem = this[ 0 ];8071 // fixed elements are offset from window (parentoffset = {top:0, left: 0}, because it is it's only offset parent8072 if ( jquery .css( elem, "position" ) === "fixed" ) {8073 // we assume that getboundingclientrect is available when computed position is fixed8074 offset = elem.getboundingclientrect();8075 } else {8076 // get *real* offsetparent8077 offsetparent = this.offsetparent();8078 // get correct offsets8079 offset = this.offset();8080 if ( !jquery .nodename( offsetparent[ 0 ], "html" ) ) {8081 parentoffset = offsetparent.offset();8082 }8083 // add offsetparent borders8084 parentoffset.top += jquery .css( offsetparent[ 0 ], "bordertopwidth", true );8085 parentoffset.left += jquery .css( offsetparent[ 0 ], "borderleftwidth", true );8086 }8087 // subtract parent offsets and element margins8088 // note: when an element has margin: auto the offsetleft and marginleft8089 // are the same in safari causing offset.left to incorrectly be 08090 return {8091 top: offset.top - parentoffset.top - jquery .css( elem, "margintop", true ),8092 left: offset.left - parentoffset.left - jquery .css( elem, "marginleft", true)8093 };8094 },8095 offsetparent: function() {8096 return this.map(function() {8097 var offsetparent = this.offsetparent || document.documentelement;8098 while ( offsetparent && ( !jquery .nodename( offsetparent, "html" ) && jquery .css( offsetparent, "position") === "static" ) ) {8099 offsetparent = offsetparent.offsetparent;8100 }8101 return offsetparent || document.documentelement;8102 });8103 }8104});8105// create scrollleft and scrolltop methods8106jquery .each( {scrollleft: "pagexoffset", scrolltop: "pageyoffset"}, function( method, prop ) {8107 var top = /y/.test( prop );8108 jquery .fn[ method ] = function( val ) {8109 return jquery .access( this, function( elem, method, val ) {8110 var win = getwindow( elem );8111 if ( val === undefined ) {8112 return win ? (prop in win) ? win[ prop ] :8113 win.document.documentelement[ method ] :8114 elem[ method ];8115 }8116 if ( win ) {8117 win.scrollto(8118 !top ? val : jquery ( win ).scrollleft(),8119 top ? val : jquery ( win ).scrolltop()8120 );8121 } else {8122 elem[ method ] = val;8123 }8124 }, method, val, arguments.length, null );8125 };8126});8127function getwindow( elem ) {8128 return jquery .iswindow( elem ) ?8129 elem :8130 elem.nodetype === 9 ?8131 elem.defaultview || elem.parentwindow :8132 false;8133}8134// create innerheight, innerwidth, height, width, outerheight and outerwidth methods8135jquery .each( { height: "height", width: "width" }, function( name, type ) {8136 jquery .each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultextra, funcname ) {8137 // margin is only for outerheight, outerwidth8138 jquery .fn[ funcname ] = function( margin, value ) {8139 var chainable = arguments.length && ( defaultextra || typeof margin !== "boolean" ),8140 extra = defaultextra || ( margin === true || value === true ? "margin" : "border" );8141 return jquery .access( this, function( elem, type, value ) {8142 var doc;8143 if ( jquery .iswindow( elem ) ) {8144 // as of 5/8/2012 this will yield incorrect results for mobile safari, but there8145 // isn't a whole lot we can do. see pull request at this url for discussion:8146 // https://github.com/jquery /jquery /pull/7648147 return elem.document.documentelement[ "client" + name ];8148 }8149 // get document width or height8150 if ( elem.nodetype === 9 ) {8151 doc = elem.documentelement;8152 // either scroll[width/height] or offset[width/height] or client[width/height], whichever is greatest8153 // unfortunately, this causes bug #3838 in ie6/8 only, but there is currently no good, small way to fix it.8154 return math.max(8155 elem.body[ "scroll" + name ], doc[ "scroll" + name ],8156 elem.body[ "offset" + name ], doc[ "offset" + name ],8157 doc[ "client" + name ]8158 );8159 }8160 return value === undefined ?8161 // get width or height on the element, requesting but not forcing parsefloat8162 jquery .css( elem, type, extra ) :8163 // set width or height on the element8164 jquery .style( elem, type, value, extra );8165 }, type, chainable ? margin : undefined, chainable, null );8166 };8167 });8168});8169// limit scope pollution from any deprecated api8170// (function() {8171// })();8172// expose jquery to the global object8173window.jquery = window.$ = jquery ;8174// expose jquery as an amd module, but only for amd loaders that8175// understand the issues with loading multiple versions of jquery8176// in a page that all might call define(). the loader will indicate8177// they have special allowances for multiple jquery versions by8178// specifying define.amd.jquery = true. regis地理信息系统 ter as a named module,8179// since jquery can be concatenated with other files that may use define,8180// but not use a proper concatenation script that understands anonymous8181// amd modules. a named amd is safest and most robust way to regis地理信息系统 ter.8182// lowercase jquery is used because amd module names are derived from8183// file names, and jquery is normally delivered in a lowercase file name.8184// do this after creating the global so that if an amd module wants to call8185// noconflict to hide this version of jquery , it will work.8186if ( typeof define === "function" && define.amd && define.amd.jquery ) {8187 define( "jquery ", [], function () { return jquery ; } );8188}8189})( window );8190/*8191 * 1.传入window8192 * 通过传入window变量,使得window由全局变量变为局部变量8193 * 当在jquery 代码块中访问window时,不需要将作用域链回退到顶层作用域,这样可以更快的访问window8194 * 更重要的是,将window作为参数传入,可以在压缩代码时进行优化8195 * (function(a,b){})(window);window 被优化为 a,压缩后文件更小8196 * 2.传入undefined8197 * 是为了在“自调用匿名函数”的作用域内...

Full Screen

Full Screen

jquery.js

Source:jquery.js Github

copy

Full Screen

1/*!2 * jQuery JavaScript Library v3.4.13 * https://jquery.com/4 *5 * Includes Sizzle.js6 * https://sizzlejs.com/7 *8 * Copyright JS Foundation and other contributors9 * Released under the MIT license10 * https://jquery.org/license11 *12 * Date: 2019-05-01T21:04Z13 */14( function( global, factory ) {15 "use strict";16 if ( typeof module === "object" && typeof module.exports === "object" ) {17 // For CommonJS and CommonJS-like environments where a proper `window`18 // is present, execute the factory and get jQuery.19 // For environments that do not have a `window` with a `document`20 // (such as Node.js), expose a factory as module.exports.21 // This accentuates the need for the creation of a real `window`.22 // e.g. var jQuery = require("jquery")(window);23 // See ticket #14549 for more info.24 module.exports = global.document ?25 factory( global, true ) :26 function( w ) {27 if ( !w.document ) {28 throw new Error( "jQuery requires a window with a document" );29 }30 return factory( w );31 };32 } else {33 factory( global );34 }35// Pass this if window is not defined yet36} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {37// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.138// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode39// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common40// enough that all such attempts are guarded in a try block.41"use strict";42var arr = [];43var document = window.document;44var getProto = Object.getPrototypeOf;45var slice = arr.slice;46var concat = arr.concat;47var push = arr.push;48var indexOf = arr.indexOf;49var class2type = {};50var toString = class2type.toString;51var hasOwn = class2type.hasOwnProperty;52var fnToString = hasOwn.toString;53var ObjectFunctionString = fnToString.call( Object );54var support = {};55var isFunction = function isFunction( obj ) {56 // Support: Chrome <=57, Firefox <=5257 // In some browsers, typeof returns "function" for HTML <object> elements58 // (i.e., `typeof document.createElement( "object" ) === "function"`).59 // We don't want to classify *any* DOM node as a function.60 return typeof obj === "function" && typeof obj.nodeType !== "number";61 };62var isWindow = function isWindow( obj ) {63 return obj != null && obj === obj.window;64 };65 var preservedScriptAttributes = {66 type: true,67 src: true,68 nonce: true,69 noModule: true70 };71 function DOMEval( code, node, doc ) {72 doc = doc || document;73 var i, val,74 script = doc.createElement( "script" );75 script.text = code;76 if ( node ) {77 for ( i in preservedScriptAttributes ) {78 // Support: Firefox 64+, Edge 18+79 // Some browsers don't support the "nonce" property on scripts.80 // On the other hand, just using `getAttribute` is not enough as81 // the `nonce` attribute is reset to an empty string whenever it82 // becomes browsing-context connected.83 // See https://github.com/whatwg/html/issues/236984 // See https://html.spec.whatwg.org/#nonce-attributes85 // The `node.getAttribute` check was added for the sake of86 // `jQuery.globalEval` so that it can fake a nonce-containing node87 // via an object.88 val = node[ i ] || node.getAttribute && node.getAttribute( i );89 if ( val ) {90 script.setAttribute( i, val );91 }92 }93 }94 doc.head.appendChild( script ).parentNode.removeChild( script );95 }96function toType( obj ) {97 if ( obj == null ) {98 return obj + "";99 }100 // Support: Android <=2.3 only (functionish RegExp)101 return typeof obj === "object" || typeof obj === "function" ?102 class2type[ toString.call( obj ) ] || "object" :103 typeof obj;104}105/* global Symbol */106// Defining this global in .eslintrc.json would create a danger of using the global107// unguarded in another place, it seems safer to define global only for this module108var109 version = "3.4.1",110 // Define a local copy of jQuery111 jQuery = function( selector, context ) {112 // The jQuery object is actually just the init constructor 'enhanced'113 // Need init if jQuery is called (just allow error to be thrown if not included)114 return new jQuery.fn.init( selector, context );115 },116 // Support: Android <=4.0 only117 // Make sure we trim BOM and NBSP118 rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;119jQuery.fn = jQuery.prototype = {120 // The current version of jQuery being used121 jquery: version,122 constructor: jQuery,123 // The default length of a jQuery object is 0124 length: 0,125 toArray: function() {126 return slice.call( this );127 },128 // Get the Nth element in the matched element set OR129 // Get the whole matched element set as a clean array130 get: function( num ) {131 // Return all the elements in a clean array132 if ( num == null ) {133 return slice.call( this );134 }135 // Return just the one element from the set136 return num < 0 ? this[ num + this.length ] : this[ num ];137 },138 // Take an array of elements and push it onto the stack139 // (returning the new matched element set)140 pushStack: function( elems ) {141 // Build a new jQuery matched element set142 var ret = jQuery.merge( this.constructor(), elems );143 // Add the old object onto the stack (as a reference)144 ret.prevObject = this;145 // Return the newly-formed element set146 return ret;147 },148 // Execute a callback for every element in the matched set.149 each: function( callback ) {150 return jQuery.each( this, callback );151 },152 map: function( callback ) {153 return this.pushStack( jQuery.map( this, function( elem, i ) {154 return callback.call( elem, i, elem );155 } ) );156 },157 slice: function() {158 return this.pushStack( slice.apply( this, arguments ) );159 },160 first: function() {161 return this.eq( 0 );162 },163 last: function() {164 return this.eq( -1 );165 },166 eq: function( i ) {167 var len = this.length,168 j = +i + ( i < 0 ? len : 0 );169 return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );170 },171 end: function() {172 return this.prevObject || this.constructor();173 },174 // For internal use only.175 // Behaves like an Array's method, not like a jQuery method.176 push: push,177 sort: arr.sort,178 splice: arr.splice179};180jQuery.extend = jQuery.fn.extend = function() {181 var options, name, src, copy, copyIsArray, clone,182 target = arguments[ 0 ] || {},183 i = 1,184 length = arguments.length,185 deep = false;186 // Handle a deep copy situation187 if ( typeof target === "boolean" ) {188 deep = target;189 // Skip the boolean and the target190 target = arguments[ i ] || {};191 i++;192 }193 // Handle case when target is a string or something (possible in deep copy)194 if ( typeof target !== "object" && !isFunction( target ) ) {195 target = {};196 }197 // Extend jQuery itself if only one argument is passed198 if ( i === length ) {199 target = this;200 i--;201 }202 for ( ; i < length; i++ ) {203 // Only deal with non-null/undefined values204 if ( ( options = arguments[ i ] ) != null ) {205 // Extend the base object206 for ( name in options ) {207 copy = options[ name ];208 // Prevent Object.prototype pollution209 // Prevent never-ending loop210 if ( name === "__proto__" || target === copy ) {211 continue;212 }213 // Recurse if we're merging plain objects or arrays214 if ( deep && copy && ( jQuery.isPlainObject( copy ) ||215 ( copyIsArray = Array.isArray( copy ) ) ) ) {216 src = target[ name ];217 // Ensure proper type for the source value218 if ( copyIsArray && !Array.isArray( src ) ) {219 clone = [];220 } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {221 clone = {};222 } else {223 clone = src;224 }225 copyIsArray = false;226 // Never move original objects, clone them227 target[ name ] = jQuery.extend( deep, clone, copy );228 // Don't bring in undefined values229 } else if ( copy !== undefined ) {230 target[ name ] = copy;231 }232 }233 }234 }235 // Return the modified object236 return target;237};238jQuery.extend( {239 // Unique for each copy of jQuery on the page240 expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),241 // Assume jQuery is ready without the ready module242 isReady: true,243 error: function( msg ) {244 throw new Error( msg );245 },246 noop: function() {},247 isPlainObject: function( obj ) {248 var proto, Ctor;249 // Detect obvious negatives250 // Use toString instead of jQuery.type to catch host objects251 if ( !obj || toString.call( obj ) !== "[object Object]" ) {252 return false;253 }254 proto = getProto( obj );255 // Objects with no prototype (e.g., `Object.create( null )`) are plain256 if ( !proto ) {257 return true;258 }259 // Objects with prototype are plain iff they were constructed by a global Object function260 Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;261 return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;262 },263 isEmptyObject: function( obj ) {264 var name;265 for ( name in obj ) {266 return false;267 }268 return true;269 },270 // Evaluates a script in a global context271 globalEval: function( code, options ) {272 DOMEval( code, { nonce: options && options.nonce } );273 },274 each: function( obj, callback ) {275 var length, i = 0;276 if ( isArrayLike( obj ) ) {277 length = obj.length;278 for ( ; i < length; i++ ) {279 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {280 break;281 }282 }283 } else {284 for ( i in obj ) {285 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {286 break;287 }288 }289 }290 return obj;291 },292 // Support: Android <=4.0 only293 trim: function( text ) {294 return text == null ?295 "" :296 ( text + "" ).replace( rtrim, "" );297 },298 // results is for internal usage only299 makeArray: function( arr, results ) {300 var ret = results || [];301 if ( arr != null ) {302 if ( isArrayLike( Object( arr ) ) ) {303 jQuery.merge( ret,304 typeof arr === "string" ?305 [ arr ] : arr306 );307 } else {308 push.call( ret, arr );309 }310 }311 return ret;312 },313 inArray: function( elem, arr, i ) {314 return arr == null ? -1 : indexOf.call( arr, elem, i );315 },316 // Support: Android <=4.0 only, PhantomJS 1 only317 // push.apply(_, arraylike) throws on ancient WebKit318 merge: function( first, second ) {319 var len = +second.length,320 j = 0,321 i = first.length;322 for ( ; j < len; j++ ) {323 first[ i++ ] = second[ j ];324 }325 first.length = i;326 return first;327 },328 grep: function( elems, callback, invert ) {329 var callbackInverse,330 matches = [],331 i = 0,332 length = elems.length,333 callbackExpect = !invert;334 // Go through the array, only saving the items335 // that pass the validator function336 for ( ; i < length; i++ ) {337 callbackInverse = !callback( elems[ i ], i );338 if ( callbackInverse !== callbackExpect ) {339 matches.push( elems[ i ] );340 }341 }342 return matches;343 },344 // arg is for internal usage only345 map: function( elems, callback, arg ) {346 var length, value,347 i = 0,348 ret = [];349 // Go through the array, translating each of the items to their new values350 if ( isArrayLike( elems ) ) {351 length = elems.length;352 for ( ; i < length; i++ ) {353 value = callback( elems[ i ], i, arg );354 if ( value != null ) {355 ret.push( value );356 }357 }358 // Go through every key on the object,359 } else {360 for ( i in elems ) {361 value = callback( elems[ i ], i, arg );362 if ( value != null ) {363 ret.push( value );364 }365 }366 }367 // Flatten any nested arrays368 return concat.apply( [], ret );369 },370 // A global GUID counter for objects371 guid: 1,372 // jQuery.support is not used in Core but other projects attach their373 // properties to it so it needs to exist.374 support: support375} );376if ( typeof Symbol === "function" ) {377 jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];378}379// Populate the class2type map380jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),381function( i, name ) {382 class2type[ "[object " + name + "]" ] = name.toLowerCase();383} );384function isArrayLike( obj ) {385 // Support: real iOS 8.2 only (not reproducible in simulator)386 // `in` check used to prevent JIT error (gh-2145)387 // hasOwn isn't used here due to false negatives388 // regarding Nodelist length in IE389 var length = !!obj && "length" in obj && obj.length,390 type = toType( obj );391 if ( isFunction( obj ) || isWindow( obj ) ) {392 return false;393 }394 return type === "array" || length === 0 ||395 typeof length === "number" && length > 0 && ( length - 1 ) in obj;396}397var Sizzle =398/*!399 * Sizzle CSS Selector Engine v2.3.4400 * https://sizzlejs.com/401 *402 * Copyright JS Foundation and other contributors403 * Released under the MIT license404 * https://js.foundation/405 *406 * Date: 2019-04-08407 */408(function( window ) {409var i,410 support,411 Expr,412 getText,413 isXML,414 tokenize,415 compile,416 select,417 outermostContext,418 sortInput,419 hasDuplicate,420 // Local document vars421 setDocument,422 document,423 docElem,424 documentIsHTML,425 rbuggyQSA,426 rbuggyMatches,427 matches,428 contains,429 // Instance-specific data430 expando = "sizzle" + 1 * new Date(),431 preferredDoc = window.document,432 dirruns = 0,433 done = 0,434 classCache = createCache(),435 tokenCache = createCache(),436 compilerCache = createCache(),437 nonnativeSelectorCache = createCache(),438 sortOrder = function( a, b ) {439 if ( a === b ) {440 hasDuplicate = true;441 }442 return 0;443 },444 // Instance methods445 hasOwn = ({}).hasOwnProperty,446 arr = [],447 pop = arr.pop,448 push_native = arr.push,449 push = arr.push,450 slice = arr.slice,451 // Use a stripped-down indexOf as it's faster than native452 // https://jsperf.com/thor-indexof-vs-for/5453 indexOf = function( list, elem ) {454 var i = 0,455 len = list.length;456 for ( ; i < len; i++ ) {457 if ( list[i] === elem ) {458 return i;459 }460 }461 return -1;462 },463 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",464 // Regular expressions465 // http://www.w3.org/TR/css3-selectors/#whitespace466 whitespace = "[\\x20\\t\\r\\n\\f]",467 // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier468 identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+",469 // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors470 attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +471 // Operator (capture 2)472 "*([*^$|!~]?=)" + whitespace +473 // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"474 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +475 "*\\]",476 pseudos = ":(" + identifier + ")(?:\\((" +477 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:478 // 1. quoted (capture 3; capture 4 or capture 5)479 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +480 // 2. simple (capture 6)481 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +482 // 3. anything else (capture 2)483 ".*" +484 ")\\)|)",485 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter486 rwhitespace = new RegExp( whitespace + "+", "g" ),487 rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),488 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),489 rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),490 rdescend = new RegExp( whitespace + "|>" ),491 rpseudo = new RegExp( pseudos ),492 ridentifier = new RegExp( "^" + identifier + "$" ),493 matchExpr = {494 "ID": new RegExp( "^#(" + identifier + ")" ),495 "CLASS": new RegExp( "^\\.(" + identifier + ")" ),496 "TAG": new RegExp( "^(" + identifier + "|[*])" ),497 "ATTR": new RegExp( "^" + attributes ),498 "PSEUDO": new RegExp( "^" + pseudos ),499 "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +500 "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +501 "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),502 "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),503 // For use in libraries implementing .is()504 // We use this for POS matching in `select`505 "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +506 whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )507 },508 rhtml = /HTML$/i,509 rinputs = /^(?:input|select|textarea|button)$/i,510 rheader = /^h\d$/i,511 rnative = /^[^{]+\{\s*\[native \w/,512 // Easily-parseable/retrievable ID or TAG or CLASS selectors513 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,514 rsibling = /[+~]/,515 // CSS escapes516 // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters517 runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),518 funescape = function( _, escaped, escapedWhitespace ) {519 var high = "0x" + escaped - 0x10000;520 // NaN means non-codepoint521 // Support: Firefox<24522 // Workaround erroneous numeric interpretation of +"0x"523 return high !== high || escapedWhitespace ?524 escaped :525 high < 0 ?526 // BMP codepoint527 String.fromCharCode( high + 0x10000 ) :528 // Supplemental Plane codepoint (surrogate pair)529 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );530 },531 // CSS string/identifier serialization532 // https://drafts.csswg.org/cssom/#common-serializing-idioms533 rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,534 fcssescape = function( ch, asCodePoint ) {535 if ( asCodePoint ) {536 // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER537 if ( ch === "\0" ) {538 return "\uFFFD";539 }540 // Control characters and (dependent upon position) numbers get escaped as code points541 return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";542 }543 // Other potentially-special ASCII characters get backslash-escaped544 return "\\" + ch;545 },546 // Used for iframes547 // See setDocument()548 // Removing the function wrapper causes a "Permission Denied"549 // error in IE550 unloadHandler = function() {551 setDocument();552 },553 inDisabledFieldset = addCombinator(554 function( elem ) {555 return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset";556 },557 { dir: "parentNode", next: "legend" }558 );559// Optimize for push.apply( _, NodeList )560try {561 push.apply(562 (arr = slice.call( preferredDoc.childNodes )),563 preferredDoc.childNodes564 );565 // Support: Android<4.0566 // Detect silently failing push.apply567 arr[ preferredDoc.childNodes.length ].nodeType;568} catch ( e ) {569 push = { apply: arr.length ?570 // Leverage slice if possible571 function( target, els ) {572 push_native.apply( target, slice.call(els) );573 } :574 // Support: IE<9575 // Otherwise append directly576 function( target, els ) {577 var j = target.length,578 i = 0;579 // Can't trust NodeList.length580 while ( (target[j++] = els[i++]) ) {}581 target.length = j - 1;582 }583 };584}585function Sizzle( selector, context, results, seed ) {586 var m, i, elem, nid, match, groups, newSelector,587 newContext = context && context.ownerDocument,588 // nodeType defaults to 9, since context defaults to document589 nodeType = context ? context.nodeType : 9;590 results = results || [];591 // Return early from calls with invalid selector or context592 if ( typeof selector !== "string" || !selector ||593 nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {594 return results;595 }596 // Try to shortcut find operations (as opposed to filters) in HTML documents597 if ( !seed ) {598 if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {599 setDocument( context );600 }601 context = context || document;602 if ( documentIsHTML ) {603 // If the selector is sufficiently simple, try using a "get*By*" DOM method604 // (excepting DocumentFragment context, where the methods don't exist)605 if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {606 // ID selector607 if ( (m = match[1]) ) {608 // Document context609 if ( nodeType === 9 ) {610 if ( (elem = context.getElementById( m )) ) {611 // Support: IE, Opera, Webkit612 // TODO: identify versions613 // getElementById can match elements by name instead of ID614 if ( elem.id === m ) {615 results.push( elem );616 return results;617 }618 } else {619 return results;620 }621 // Element context622 } else {623 // Support: IE, Opera, Webkit624 // TODO: identify versions625 // getElementById can match elements by name instead of ID626 if ( newContext && (elem = newContext.getElementById( m )) &&627 contains( context, elem ) &&628 elem.id === m ) {629 results.push( elem );630 return results;631 }632 }633 // Type selector634 } else if ( match[2] ) {635 push.apply( results, context.getElementsByTagName( selector ) );636 return results;637 // Class selector638 } else if ( (m = match[3]) && support.getElementsByClassName &&639 context.getElementsByClassName ) {640 push.apply( results, context.getElementsByClassName( m ) );641 return results;642 }643 }644 // Take advantage of querySelectorAll645 if ( support.qsa &&646 !nonnativeSelectorCache[ selector + " " ] &&647 (!rbuggyQSA || !rbuggyQSA.test( selector )) &&648 // Support: IE 8 only649 // Exclude object elements650 (nodeType !== 1 || context.nodeName.toLowerCase() !== "object") ) {651 newSelector = selector;652 newContext = context;653 // qSA considers elements outside a scoping root when evaluating child or654 // descendant combinators, which is not what we want.655 // In such cases, we work around the behavior by prefixing every selector in the656 // list with an ID selector referencing the scope context.657 // Thanks to Andrew Dupont for this technique.658 if ( nodeType === 1 && rdescend.test( selector ) ) {659 // Capture the context ID, setting it first if necessary660 if ( (nid = context.getAttribute( "id" )) ) {661 nid = nid.replace( rcssescape, fcssescape );662 } else {663 context.setAttribute( "id", (nid = expando) );664 }665 // Prefix every selector in the list666 groups = tokenize( selector );667 i = groups.length;668 while ( i-- ) {669 groups[i] = "#" + nid + " " + toSelector( groups[i] );670 }671 newSelector = groups.join( "," );672 // Expand context for sibling selectors673 newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||674 context;675 }676 try {677 push.apply( results,678 newContext.querySelectorAll( newSelector )679 );680 return results;681 } catch ( qsaError ) {682 nonnativeSelectorCache( selector, true );683 } finally {684 if ( nid === expando ) {685 context.removeAttribute( "id" );686 }687 }688 }689 }690 }691 // All others692 return select( selector.replace( rtrim, "$1" ), context, results, seed );693}694/**695 * Create key-value caches of limited size696 * @returns {function(string, object)} Returns the Object data after storing it on itself with697 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)698 * deleting the oldest entry699 */700function createCache() {701 var keys = [];702 function cache( key, value ) {703 // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)704 if ( keys.push( key + " " ) > Expr.cacheLength ) {705 // Only keep the most recent entries706 delete cache[ keys.shift() ];707 }708 return (cache[ key + " " ] = value);709 }710 return cache;711}712/**713 * Mark a function for special use by Sizzle714 * @param {Function} fn The function to mark715 */716function markFunction( fn ) {717 fn[ expando ] = true;718 return fn;719}720/**721 * Support testing using an element722 * @param {Function} fn Passed the created element and returns a boolean result723 */724function assert( fn ) {725 var el = document.createElement("fieldset");726 try {727 return !!fn( el );728 } catch (e) {729 return false;730 } finally {731 // Remove from its parent by default732 if ( el.parentNode ) {733 el.parentNode.removeChild( el );734 }735 // release memory in IE736 el = null;737 }738}739/**740 * Adds the same handler for all of the specified attrs741 * @param {String} attrs Pipe-separated list of attributes742 * @param {Function} handler The method that will be applied743 */744function addHandle( attrs, handler ) {745 var arr = attrs.split("|"),746 i = arr.length;747 while ( i-- ) {748 Expr.attrHandle[ arr[i] ] = handler;749 }750}751/**752 * Checks document order of two siblings753 * @param {Element} a754 * @param {Element} b755 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b756 */757function siblingCheck( a, b ) {758 var cur = b && a,759 diff = cur && a.nodeType === 1 && b.nodeType === 1 &&760 a.sourceIndex - b.sourceIndex;761 // Use IE sourceIndex if available on both nodes762 if ( diff ) {763 return diff;764 }765 // Check if b follows a766 if ( cur ) {767 while ( (cur = cur.nextSibling) ) {768 if ( cur === b ) {769 return -1;770 }771 }772 }773 return a ? 1 : -1;774}775/**776 * Returns a function to use in pseudos for input types777 * @param {String} type778 */779function createInputPseudo( type ) {780 return function( elem ) {781 var name = elem.nodeName.toLowerCase();782 return name === "input" && elem.type === type;783 };784}785/**786 * Returns a function to use in pseudos for buttons787 * @param {String} type788 */789function createButtonPseudo( type ) {790 return function( elem ) {791 var name = elem.nodeName.toLowerCase();792 return (name === "input" || name === "button") && elem.type === type;793 };794}795/**796 * Returns a function to use in pseudos for :enabled/:disabled797 * @param {Boolean} disabled true for :disabled; false for :enabled798 */799function createDisabledPseudo( disabled ) {800 // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable801 return function( elem ) {802 // Only certain elements can match :enabled or :disabled803 // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled804 // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled805 if ( "form" in elem ) {806 // Check for inherited disabledness on relevant non-disabled elements:807 // * listed form-associated elements in a disabled fieldset808 // https://html.spec.whatwg.org/multipage/forms.html#category-listed809 // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled810 // * option elements in a disabled optgroup811 // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled812 // All such elements have a "form" property.813 if ( elem.parentNode && elem.disabled === false ) {814 // Option elements defer to a parent optgroup if present815 if ( "label" in elem ) {816 if ( "label" in elem.parentNode ) {817 return elem.parentNode.disabled === disabled;818 } else {819 return elem.disabled === disabled;820 }821 }822 // Support: IE 6 - 11823 // Use the isDisabled shortcut property to check for disabled fieldset ancestors824 return elem.isDisabled === disabled ||825 // Where there is no isDisabled, check manually826 /* jshint -W018 */827 elem.isDisabled !== !disabled &&828 inDisabledFieldset( elem ) === disabled;829 }830 return elem.disabled === disabled;831 // Try to winnow out elements that can't be disabled before trusting the disabled property.832 // Some victims get caught in our net (label, legend, menu, track), but it shouldn't833 // even exist on them, let alone have a boolean value.834 } else if ( "label" in elem ) {835 return elem.disabled === disabled;836 }837 // Remaining elements are neither :enabled nor :disabled838 return false;839 };840}841/**842 * Returns a function to use in pseudos for positionals843 * @param {Function} fn844 */845function createPositionalPseudo( fn ) {846 return markFunction(function( argument ) {847 argument = +argument;848 return markFunction(function( seed, matches ) {849 var j,850 matchIndexes = fn( [], seed.length, argument ),851 i = matchIndexes.length;852 // Match elements found at the specified indexes853 while ( i-- ) {854 if ( seed[ (j = matchIndexes[i]) ] ) {855 seed[j] = !(matches[j] = seed[j]);856 }857 }858 });859 });860}861/**862 * Checks a node for validity as a Sizzle context863 * @param {Element|Object=} context864 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value865 */866function testContext( context ) {867 return context && typeof context.getElementsByTagName !== "undefined" && context;868}869// Expose support vars for convenience870support = Sizzle.support = {};871/**872 * Detects XML nodes873 * @param {Element|Object} elem An element or a document874 * @returns {Boolean} True iff elem is a non-HTML XML node875 */876isXML = Sizzle.isXML = function( elem ) {877 var namespace = elem.namespaceURI,878 docElem = (elem.ownerDocument || elem).documentElement;879 // Support: IE <=8880 // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes881 // https://bugs.jquery.com/ticket/4833882 return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" );883};884/**885 * Sets document-related variables once based on the current document886 * @param {Element|Object} [doc] An element or document object to use to set the document887 * @returns {Object} Returns the current document888 */889setDocument = Sizzle.setDocument = function( node ) {890 var hasCompare, subWindow,891 doc = node ? node.ownerDocument || node : preferredDoc;892 // Return early if doc is invalid or already selected893 if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {894 return document;895 }896 // Update global variables897 document = doc;898 docElem = document.documentElement;899 documentIsHTML = !isXML( document );900 // Support: IE 9-11, Edge901 // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)902 if ( preferredDoc !== document &&903 (subWindow = document.defaultView) && subWindow.top !== subWindow ) {904 // Support: IE 11, Edge905 if ( subWindow.addEventListener ) {906 subWindow.addEventListener( "unload", unloadHandler, false );907 // Support: IE 9 - 10 only908 } else if ( subWindow.attachEvent ) {909 subWindow.attachEvent( "onunload", unloadHandler );910 }911 }912 /* Attributes913 ---------------------------------------------------------------------- */914 // Support: IE<8915 // Verify that getAttribute really returns attributes and not properties916 // (excepting IE8 booleans)917 support.attributes = assert(function( el ) {918 el.className = "i";919 return !el.getAttribute("className");920 });921 /* getElement(s)By*922 ---------------------------------------------------------------------- */923 // Check if getElementsByTagName("*") returns only elements924 support.getElementsByTagName = assert(function( el ) {925 el.appendChild( document.createComment("") );926 return !el.getElementsByTagName("*").length;927 });928 // Support: IE<9929 support.getElementsByClassName = rnative.test( document.getElementsByClassName );930 // Support: IE<10931 // Check if getElementById returns elements by name932 // The broken getElementById methods don't pick up programmatically-set names,933 // so use a roundabout getElementsByName test934 support.getById = assert(function( el ) {935 docElem.appendChild( el ).id = expando;936 return !document.getElementsByName || !document.getElementsByName( expando ).length;937 });938 // ID filter and find939 if ( support.getById ) {940 Expr.filter["ID"] = function( id ) {941 var attrId = id.replace( runescape, funescape );942 return function( elem ) {943 return elem.getAttribute("id") === attrId;944 };945 };946 Expr.find["ID"] = function( id, context ) {947 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {948 var elem = context.getElementById( id );949 return elem ? [ elem ] : [];950 }951 };952 } else {953 Expr.filter["ID"] = function( id ) {954 var attrId = id.replace( runescape, funescape );955 return function( elem ) {956 var node = typeof elem.getAttributeNode !== "undefined" &&957 elem.getAttributeNode("id");958 return node && node.value === attrId;959 };960 };961 // Support: IE 6 - 7 only962 // getElementById is not reliable as a find shortcut963 Expr.find["ID"] = function( id, context ) {964 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {965 var node, i, elems,966 elem = context.getElementById( id );967 if ( elem ) {968 // Verify the id attribute969 node = elem.getAttributeNode("id");970 if ( node && node.value === id ) {971 return [ elem ];972 }973 // Fall back on getElementsByName974 elems = context.getElementsByName( id );975 i = 0;976 while ( (elem = elems[i++]) ) {977 node = elem.getAttributeNode("id");978 if ( node && node.value === id ) {979 return [ elem ];980 }981 }982 }983 return [];984 }985 };986 }987 // Tag988 Expr.find["TAG"] = support.getElementsByTagName ?989 function( tag, context ) {990 if ( typeof context.getElementsByTagName !== "undefined" ) {991 return context.getElementsByTagName( tag );992 // DocumentFragment nodes don't have gEBTN993 } else if ( support.qsa ) {994 return context.querySelectorAll( tag );995 }996 } :997 function( tag, context ) {998 var elem,999 tmp = [],1000 i = 0,1001 // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too1002 results = context.getElementsByTagName( tag );1003 // Filter out possible comments1004 if ( tag === "*" ) {1005 while ( (elem = results[i++]) ) {1006 if ( elem.nodeType === 1 ) {1007 tmp.push( elem );1008 }1009 }1010 return tmp;1011 }1012 return results;1013 };1014 // Class1015 Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {1016 if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {1017 return context.getElementsByClassName( className );1018 }1019 };1020 /* QSA/matchesSelector1021 ---------------------------------------------------------------------- */1022 // QSA and matchesSelector support1023 // matchesSelector(:active) reports false when true (IE9/Opera 11.5)1024 rbuggyMatches = [];1025 // qSa(:focus) reports false when true (Chrome 21)1026 // We allow this because of a bug in IE8/9 that throws an error1027 // whenever `document.activeElement` is accessed on an iframe1028 // So, we allow :focus to pass through QSA all the time to avoid the IE error1029 // See https://bugs.jquery.com/ticket/133781030 rbuggyQSA = [];1031 if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {1032 // Build QSA regex1033 // Regex strategy adopted from Diego Perini1034 assert(function( el ) {1035 // Select is set to empty string on purpose1036 // This is to test IE's treatment of not explicitly1037 // setting a boolean content attribute,1038 // since its presence should be enough1039 // https://bugs.jquery.com/ticket/123591040 docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +1041 "<select id='" + expando + "-\r\\' msallowcapture=''>" +1042 "<option selected=''></option></select>";1043 // Support: IE8, Opera 11-12.161044 // Nothing should be selected when empty strings follow ^= or $= or *=1045 // The test attribute must be unknown in Opera but "safe" for WinRT1046 // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section1047 if ( el.querySelectorAll("[msallowcapture^='']").length ) {1048 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );1049 }1050 // Support: IE81051 // Boolean attributes and "value" are not treated correctly1052 if ( !el.querySelectorAll("[selected]").length ) {1053 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );1054 }1055 // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+1056 if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {1057 rbuggyQSA.push("~=");1058 }1059 // Webkit/Opera - :checked should return selected option elements1060 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked1061 // IE8 throws error here and will not see later tests1062 if ( !el.querySelectorAll(":checked").length ) {1063 rbuggyQSA.push(":checked");1064 }1065 // Support: Safari 8+, iOS 8+1066 // https://bugs.webkit.org/show_bug.cgi?id=1368511067 // In-page `selector#id sibling-combinator selector` fails1068 if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {1069 rbuggyQSA.push(".#.+[+~]");1070 }1071 });1072 assert(function( el ) {1073 el.innerHTML = "<a href='' disabled='disabled'></a>" +1074 "<select disabled='disabled'><option/></select>";1075 // Support: Windows 8 Native Apps1076 // The type and name attributes are restricted during .innerHTML assignment1077 var input = document.createElement("input");1078 input.setAttribute( "type", "hidden" );1079 el.appendChild( input ).setAttribute( "name", "D" );1080 // Support: IE81081 // Enforce case-sensitivity of name attribute1082 if ( el.querySelectorAll("[name=d]").length ) {1083 rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );1084 }1085 // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)1086 // IE8 throws error here and will not see later tests1087 if ( el.querySelectorAll(":enabled").length !== 2 ) {1088 rbuggyQSA.push( ":enabled", ":disabled" );1089 }1090 // Support: IE9-11+1091 // IE's :disabled selector does not pick up the children of disabled fieldsets1092 docElem.appendChild( el ).disabled = true;1093 if ( el.querySelectorAll(":disabled").length !== 2 ) {1094 rbuggyQSA.push( ":enabled", ":disabled" );1095 }1096 // Opera 10-11 does not throw on post-comma invalid pseudos1097 el.querySelectorAll("*,:x");1098 rbuggyQSA.push(",.*:");1099 });1100 }1101 if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||1102 docElem.webkitMatchesSelector ||1103 docElem.mozMatchesSelector ||1104 docElem.oMatchesSelector ||1105 docElem.msMatchesSelector) )) ) {1106 assert(function( el ) {1107 // Check to see if it's possible to do matchesSelector1108 // on a disconnected node (IE 9)1109 support.disconnectedMatch = matches.call( el, "*" );1110 // This should fail with an exception1111 // Gecko does not error, returns false instead1112 matches.call( el, "[s!='']:x" );1113 rbuggyMatches.push( "!=", pseudos );1114 });1115 }1116 rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );1117 rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );1118 /* Contains1119 ---------------------------------------------------------------------- */1120 hasCompare = rnative.test( docElem.compareDocumentPosition );1121 // Element contains another1122 // Purposefully self-exclusive1123 // As in, an element does not contain itself1124 contains = hasCompare || rnative.test( docElem.contains ) ?1125 function( a, b ) {1126 var adown = a.nodeType === 9 ? a.documentElement : a,1127 bup = b && b.parentNode;1128 return a === bup || !!( bup && bup.nodeType === 1 && (1129 adown.contains ?1130 adown.contains( bup ) :1131 a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 161132 ));1133 } :1134 function( a, b ) {1135 if ( b ) {1136 while ( (b = b.parentNode) ) {1137 if ( b === a ) {1138 return true;1139 }1140 }1141 }1142 return false;1143 };1144 /* Sorting1145 ---------------------------------------------------------------------- */1146 // Document order sorting1147 sortOrder = hasCompare ?1148 function( a, b ) {1149 // Flag for duplicate removal1150 if ( a === b ) {1151 hasDuplicate = true;1152 return 0;1153 }1154 // Sort on method existence if only one input has compareDocumentPosition1155 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;1156 if ( compare ) {1157 return compare;1158 }1159 // Calculate position if both inputs belong to the same document1160 compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?1161 a.compareDocumentPosition( b ) :1162 // Otherwise we know they are disconnected1163 1;1164 // Disconnected nodes1165 if ( compare & 1 ||1166 (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {1167 // Choose the first element that is related to our preferred document1168 if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {1169 return -1;1170 }1171 if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {1172 return 1;1173 }1174 // Maintain original order1175 return sortInput ?1176 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :1177 0;1178 }1179 return compare & 4 ? -1 : 1;1180 } :1181 function( a, b ) {1182 // Exit early if the nodes are identical1183 if ( a === b ) {1184 hasDuplicate = true;1185 return 0;1186 }1187 var cur,1188 i = 0,1189 aup = a.parentNode,1190 bup = b.parentNode,1191 ap = [ a ],1192 bp = [ b ];1193 // Parentless nodes are either documents or disconnected1194 if ( !aup || !bup ) {1195 return a === document ? -1 :1196 b === document ? 1 :1197 aup ? -1 :1198 bup ? 1 :1199 sortInput ?1200 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :1201 0;1202 // If the nodes are siblings, we can do a quick check1203 } else if ( aup === bup ) {1204 return siblingCheck( a, b );1205 }1206 // Otherwise we need full lists of their ancestors for comparison1207 cur = a;1208 while ( (cur = cur.parentNode) ) {1209 ap.unshift( cur );1210 }1211 cur = b;1212 while ( (cur = cur.parentNode) ) {1213 bp.unshift( cur );1214 }1215 // Walk down the tree looking for a discrepancy1216 while ( ap[i] === bp[i] ) {1217 i++;1218 }1219 return i ?1220 // Do a sibling check if the nodes have a common ancestor1221 siblingCheck( ap[i], bp[i] ) :1222 // Otherwise nodes in our document sort first1223 ap[i] === preferredDoc ? -1 :1224 bp[i] === preferredDoc ? 1 :1225 0;1226 };1227 return document;1228};1229Sizzle.matches = function( expr, elements ) {1230 return Sizzle( expr, null, null, elements );1231};1232Sizzle.matchesSelector = function( elem, expr ) {1233 // Set document vars if needed1234 if ( ( elem.ownerDocument || elem ) !== document ) {1235 setDocument( elem );1236 }1237 if ( support.matchesSelector && documentIsHTML &&1238 !nonnativeSelectorCache[ expr + " " ] &&1239 ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&1240 ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {1241 try {1242 var ret = matches.call( elem, expr );1243 // IE 9's matchesSelector returns false on disconnected nodes1244 if ( ret || support.disconnectedMatch ||1245 // As well, disconnected nodes are said to be in a document1246 // fragment in IE 91247 elem.document && elem.document.nodeType !== 11 ) {1248 return ret;1249 }1250 } catch (e) {1251 nonnativeSelectorCache( expr, true );1252 }1253 }1254 return Sizzle( expr, document, null, [ elem ] ).length > 0;1255};1256Sizzle.contains = function( context, elem ) {1257 // Set document vars if needed1258 if ( ( context.ownerDocument || context ) !== document ) {1259 setDocument( context );1260 }1261 return contains( context, elem );1262};1263Sizzle.attr = function( elem, name ) {1264 // Set document vars if needed1265 if ( ( elem.ownerDocument || elem ) !== document ) {1266 setDocument( elem );1267 }1268 var fn = Expr.attrHandle[ name.toLowerCase() ],1269 // Don't get fooled by Object.prototype properties (jQuery #13807)1270 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?1271 fn( elem, name, !documentIsHTML ) :1272 undefined;1273 return val !== undefined ?1274 val :1275 support.attributes || !documentIsHTML ?1276 elem.getAttribute( name ) :1277 (val = elem.getAttributeNode(name)) && val.specified ?1278 val.value :1279 null;1280};1281Sizzle.escape = function( sel ) {1282 return (sel + "").replace( rcssescape, fcssescape );1283};1284Sizzle.error = function( msg ) {1285 throw new Error( "Syntax error, unrecognized expression: " + msg );1286};1287/**1288 * Document sorting and removing duplicates1289 * @param {ArrayLike} results1290 */1291Sizzle.uniqueSort = function( results ) {1292 var elem,1293 duplicates = [],1294 j = 0,1295 i = 0;1296 // Unless we *know* we can detect duplicates, assume their presence1297 hasDuplicate = !support.detectDuplicates;1298 sortInput = !support.sortStable && results.slice( 0 );1299 results.sort( sortOrder );1300 if ( hasDuplicate ) {1301 while ( (elem = results[i++]) ) {1302 if ( elem === results[ i ] ) {1303 j = duplicates.push( i );1304 }1305 }1306 while ( j-- ) {1307 results.splice( duplicates[ j ], 1 );1308 }1309 }1310 // Clear input after sorting to release objects1311 // See https://github.com/jquery/sizzle/pull/2251312 sortInput = null;1313 return results;1314};1315/**1316 * Utility function for retrieving the text value of an array of DOM nodes1317 * @param {Array|Element} elem1318 */1319getText = Sizzle.getText = function( elem ) {1320 var node,1321 ret = "",1322 i = 0,1323 nodeType = elem.nodeType;1324 if ( !nodeType ) {1325 // If no nodeType, this is expected to be an array1326 while ( (node = elem[i++]) ) {1327 // Do not traverse comment nodes1328 ret += getText( node );1329 }1330 } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {1331 // Use textContent for elements1332 // innerText usage removed for consistency of new lines (jQuery #11153)1333 if ( typeof elem.textContent === "string" ) {1334 return elem.textContent;1335 } else {1336 // Traverse its children1337 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {1338 ret += getText( elem );1339 }1340 }1341 } else if ( nodeType === 3 || nodeType === 4 ) {1342 return elem.nodeValue;1343 }1344 // Do not include comment or processing instruction nodes1345 return ret;1346};1347Expr = Sizzle.selectors = {1348 // Can be adjusted by the user1349 cacheLength: 50,1350 createPseudo: markFunction,1351 match: matchExpr,1352 attrHandle: {},1353 find: {},1354 relative: {1355 ">": { dir: "parentNode", first: true },1356 " ": { dir: "parentNode" },1357 "+": { dir: "previousSibling", first: true },1358 "~": { dir: "previousSibling" }1359 },1360 preFilter: {1361 "ATTR": function( match ) {1362 match[1] = match[1].replace( runescape, funescape );1363 // Move the given value to match[3] whether quoted or unquoted1364 match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );1365 if ( match[2] === "~=" ) {1366 match[3] = " " + match[3] + " ";1367 }1368 return match.slice( 0, 4 );1369 },1370 "CHILD": function( match ) {1371 /* matches from matchExpr["CHILD"]1372 1 type (only|nth|...)1373 2 what (child|of-type)1374 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)1375 4 xn-component of xn+y argument ([+-]?\d*n|)1376 5 sign of xn-component1377 6 x of xn-component1378 7 sign of y-component1379 8 y of y-component1380 */1381 match[1] = match[1].toLowerCase();1382 if ( match[1].slice( 0, 3 ) === "nth" ) {1383 // nth-* requires argument1384 if ( !match[3] ) {1385 Sizzle.error( match[0] );1386 }1387 // numeric x and y parameters for Expr.filter.CHILD1388 // remember that false/true cast respectively to 0/11389 match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );1390 match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );1391 // other types prohibit arguments1392 } else if ( match[3] ) {1393 Sizzle.error( match[0] );1394 }1395 return match;1396 },1397 "PSEUDO": function( match ) {1398 var excess,1399 unquoted = !match[6] && match[2];1400 if ( matchExpr["CHILD"].test( match[0] ) ) {1401 return null;1402 }1403 // Accept quoted arguments as-is1404 if ( match[3] ) {1405 match[2] = match[4] || match[5] || "";1406 // Strip excess characters from unquoted arguments1407 } else if ( unquoted && rpseudo.test( unquoted ) &&1408 // Get excess from tokenize (recursively)1409 (excess = tokenize( unquoted, true )) &&1410 // advance to the next closing parenthesis1411 (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {1412 // excess is a negative index1413 match[0] = match[0].slice( 0, excess );1414 match[2] = unquoted.slice( 0, excess );1415 }1416 // Return only captures needed by the pseudo filter method (type and argument)1417 return match.slice( 0, 3 );1418 }1419 },1420 filter: {1421 "TAG": function( nodeNameSelector ) {1422 var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();1423 return nodeNameSelector === "*" ?1424 function() { return true; } :1425 function( elem ) {1426 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;1427 };1428 },1429 "CLASS": function( className ) {1430 var pattern = classCache[ className + " " ];1431 return pattern ||1432 (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&1433 classCache( className, function( elem ) {1434 return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );1435 });1436 },1437 "ATTR": function( name, operator, check ) {1438 return function( elem ) {1439 var result = Sizzle.attr( elem, name );1440 if ( result == null ) {1441 return operator === "!=";1442 }1443 if ( !operator ) {1444 return true;1445 }1446 result += "";1447 return operator === "=" ? result === check :1448 operator === "!=" ? result !== check :1449 operator === "^=" ? check && result.indexOf( check ) === 0 :1450 operator === "*=" ? check && result.indexOf( check ) > -1 :1451 operator === "$=" ? check && result.slice( -check.length ) === check :1452 operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :1453 operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :1454 false;1455 };1456 },1457 "CHILD": function( type, what, argument, first, last ) {1458 var simple = type.slice( 0, 3 ) !== "nth",1459 forward = type.slice( -4 ) !== "last",1460 ofType = what === "of-type";1461 return first === 1 && last === 0 ?1462 // Shortcut for :nth-*(n)1463 function( elem ) {1464 return !!elem.parentNode;1465 } :1466 function( elem, context, xml ) {1467 var cache, uniqueCache, outerCache, node, nodeIndex, start,1468 dir = simple !== forward ? "nextSibling" : "previousSibling",1469 parent = elem.parentNode,1470 name = ofType && elem.nodeName.toLowerCase(),1471 useCache = !xml && !ofType,1472 diff = false;1473 if ( parent ) {1474 // :(first|last|only)-(child|of-type)1475 if ( simple ) {1476 while ( dir ) {1477 node = elem;1478 while ( (node = node[ dir ]) ) {1479 if ( ofType ?1480 node.nodeName.toLowerCase() === name :1481 node.nodeType === 1 ) {1482 return false;1483 }1484 }1485 // Reverse direction for :only-* (if we haven't yet done so)1486 start = dir = type === "only" && !start && "nextSibling";1487 }1488 return true;1489 }1490 start = [ forward ? parent.firstChild : parent.lastChild ];1491 // non-xml :nth-child(...) stores cache data on `parent`1492 if ( forward && useCache ) {1493 // Seek `elem` from a previously-cached index1494 // ...in a gzip-friendly way1495 node = parent;1496 outerCache = node[ expando ] || (node[ expando ] = {});1497 // Support: IE <9 only1498 // Defend against cloned attroperties (jQuery gh-1709)1499 uniqueCache = outerCache[ node.uniqueID ] ||1500 (outerCache[ node.uniqueID ] = {});1501 cache = uniqueCache[ type ] || [];1502 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];1503 diff = nodeIndex && cache[ 2 ];1504 node = nodeIndex && parent.childNodes[ nodeIndex ];1505 while ( (node = ++nodeIndex && node && node[ dir ] ||1506 // Fallback to seeking `elem` from the start1507 (diff = nodeIndex = 0) || start.pop()) ) {1508 // When found, cache indexes on `parent` and break1509 if ( node.nodeType === 1 && ++diff && node === elem ) {1510 uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];1511 break;1512 }1513 }1514 } else {1515 // Use previously-cached element index if available1516 if ( useCache ) {1517 // ...in a gzip-friendly way1518 node = elem;1519 outerCache = node[ expando ] || (node[ expando ] = {});1520 // Support: IE <9 only1521 // Defend against cloned attroperties (jQuery gh-1709)1522 uniqueCache = outerCache[ node.uniqueID ] ||1523 (outerCache[ node.uniqueID ] = {});1524 cache = uniqueCache[ type ] || [];1525 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];1526 diff = nodeIndex;1527 }1528 // xml :nth-child(...)1529 // or :nth-last-child(...) or :nth(-last)?-of-type(...)1530 if ( diff === false ) {1531 // Use the same loop as above to seek `elem` from the start1532 while ( (node = ++nodeIndex && node && node[ dir ] ||1533 (diff = nodeIndex = 0) || start.pop()) ) {1534 if ( ( ofType ?1535 node.nodeName.toLowerCase() === name :1536 node.nodeType === 1 ) &&1537 ++diff ) {1538 // Cache the index of each encountered element1539 if ( useCache ) {1540 outerCache = node[ expando ] || (node[ expando ] = {});1541 // Support: IE <9 only1542 // Defend against cloned attroperties (jQuery gh-1709)1543 uniqueCache = outerCache[ node.uniqueID ] ||1544 (outerCache[ node.uniqueID ] = {});1545 uniqueCache[ type ] = [ dirruns, diff ];1546 }1547 if ( node === elem ) {1548 break;1549 }1550 }1551 }1552 }1553 }1554 // Incorporate the offset, then check against cycle size1555 diff -= last;1556 return diff === first || ( diff % first === 0 && diff / first >= 0 );1557 }1558 };1559 },1560 "PSEUDO": function( pseudo, argument ) {1561 // pseudo-class names are case-insensitive1562 // http://www.w3.org/TR/selectors/#pseudo-classes1563 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters1564 // Remember that setFilters inherits from pseudos1565 var args,1566 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||1567 Sizzle.error( "unsupported pseudo: " + pseudo );1568 // The user may use createPseudo to indicate that1569 // arguments are needed to create the filter function1570 // just as Sizzle does1571 if ( fn[ expando ] ) {1572 return fn( argument );1573 }1574 // But maintain support for old signatures1575 if ( fn.length > 1 ) {1576 args = [ pseudo, pseudo, "", argument ];1577 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?1578 markFunction(function( seed, matches ) {1579 var idx,1580 matched = fn( seed, argument ),1581 i = matched.length;1582 while ( i-- ) {1583 idx = indexOf( seed, matched[i] );1584 seed[ idx ] = !( matches[ idx ] = matched[i] );1585 }1586 }) :1587 function( elem ) {1588 return fn( elem, 0, args );1589 };1590 }1591 return fn;1592 }1593 },1594 pseudos: {1595 // Potentially complex pseudos1596 "not": markFunction(function( selector ) {1597 // Trim the selector passed to compile1598 // to avoid treating leading and trailing1599 // spaces as combinators1600 var input = [],1601 results = [],1602 matcher = compile( selector.replace( rtrim, "$1" ) );1603 return matcher[ expando ] ?1604 markFunction(function( seed, matches, context, xml ) {1605 var elem,1606 unmatched = matcher( seed, null, xml, [] ),1607 i = seed.length;1608 // Match elements unmatched by `matcher`1609 while ( i-- ) {1610 if ( (elem = unmatched[i]) ) {1611 seed[i] = !(matches[i] = elem);1612 }1613 }1614 }) :1615 function( elem, context, xml ) {1616 input[0] = elem;1617 matcher( input, null, xml, results );1618 // Don't keep the element (issue #299)1619 input[0] = null;1620 return !results.pop();1621 };1622 }),1623 "has": markFunction(function( selector ) {1624 return function( elem ) {1625 return Sizzle( selector, elem ).length > 0;1626 };1627 }),1628 "contains": markFunction(function( text ) {1629 text = text.replace( runescape, funescape );1630 return function( elem ) {1631 return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1;1632 };1633 }),1634 // "Whether an element is represented by a :lang() selector1635 // is based solely on the element's language value1636 // being equal to the identifier C,1637 // or beginning with the identifier C immediately followed by "-".1638 // The matching of C against the element's language value is performed case-insensitively.1639 // The identifier C does not have to be a valid language name."1640 // http://www.w3.org/TR/selectors/#lang-pseudo1641 "lang": markFunction( function( lang ) {1642 // lang value must be a valid identifier1643 if ( !ridentifier.test(lang || "") ) {1644 Sizzle.error( "unsupported lang: " + lang );1645 }1646 lang = lang.replace( runescape, funescape ).toLowerCase();1647 return function( elem ) {1648 var elemLang;1649 do {1650 if ( (elemLang = documentIsHTML ?1651 elem.lang :1652 elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {1653 elemLang = elemLang.toLowerCase();1654 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;1655 }1656 } while ( (elem = elem.parentNode) && elem.nodeType === 1 );1657 return false;1658 };1659 }),1660 // Miscellaneous1661 "target": function( elem ) {1662 var hash = window.location && window.location.hash;1663 return hash && hash.slice( 1 ) === elem.id;1664 },1665 "root": function( elem ) {1666 return elem === docElem;1667 },1668 "focus": function( elem ) {1669 return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);1670 },1671 // Boolean properties1672 "enabled": createDisabledPseudo( false ),1673 "disabled": createDisabledPseudo( true ),1674 "checked": function( elem ) {1675 // In CSS3, :checked should return both checked and selected elements1676 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked1677 var nodeName = elem.nodeName.toLowerCase();1678 return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);1679 },1680 "selected": function( elem ) {1681 // Accessing this property makes selected-by-default1682 // options in Safari work properly1683 if ( elem.parentNode ) {1684 elem.parentNode.selectedIndex;1685 }1686 return elem.selected === true;1687 },1688 // Contents1689 "empty": function( elem ) {1690 // http://www.w3.org/TR/selectors/#empty-pseudo1691 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),1692 // but not by others (comment: 8; processing instruction: 7; etc.)1693 // nodeType < 6 works because attributes (2) do not appear as children1694 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {1695 if ( elem.nodeType < 6 ) {1696 return false;1697 }1698 }1699 return true;1700 },1701 "parent": function( elem ) {1702 return !Expr.pseudos["empty"]( elem );1703 },1704 // Element/input types1705 "header": function( elem ) {1706 return rheader.test( elem.nodeName );1707 },1708 "input": function( elem ) {1709 return rinputs.test( elem.nodeName );1710 },1711 "button": function( elem ) {1712 var name = elem.nodeName.toLowerCase();1713 return name === "input" && elem.type === "button" || name === "button";1714 },1715 "text": function( elem ) {1716 var attr;1717 return elem.nodeName.toLowerCase() === "input" &&1718 elem.type === "text" &&1719 // Support: IE<81720 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"1721 ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );1722 },1723 // Position-in-collection1724 "first": createPositionalPseudo(function() {1725 return [ 0 ];1726 }),1727 "last": createPositionalPseudo(function( matchIndexes, length ) {1728 return [ length - 1 ];1729 }),1730 "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {1731 return [ argument < 0 ? argument + length : argument ];1732 }),1733 "even": createPositionalPseudo(function( matchIndexes, length ) {1734 var i = 0;1735 for ( ; i < length; i += 2 ) {1736 matchIndexes.push( i );1737 }1738 return matchIndexes;1739 }),1740 "odd": createPositionalPseudo(function( matchIndexes, length ) {1741 var i = 1;1742 for ( ; i < length; i += 2 ) {1743 matchIndexes.push( i );1744 }1745 return matchIndexes;1746 }),1747 "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {1748 var i = argument < 0 ?1749 argument + length :1750 argument > length ?1751 length :1752 argument;1753 for ( ; --i >= 0; ) {1754 matchIndexes.push( i );1755 }1756 return matchIndexes;1757 }),1758 "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {1759 var i = argument < 0 ? argument + length : argument;1760 for ( ; ++i < length; ) {1761 matchIndexes.push( i );1762 }1763 return matchIndexes;1764 })1765 }1766};1767Expr.pseudos["nth"] = Expr.pseudos["eq"];1768// Add button/input type pseudos1769for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {1770 Expr.pseudos[ i ] = createInputPseudo( i );1771}1772for ( i in { submit: true, reset: true } ) {1773 Expr.pseudos[ i ] = createButtonPseudo( i );1774}1775// Easy API for creating new setFilters1776function setFilters() {}1777setFilters.prototype = Expr.filters = Expr.pseudos;1778Expr.setFilters = new setFilters();1779tokenize = Sizzle.tokenize = function( selector, parseOnly ) {1780 var matched, match, tokens, type,1781 soFar, groups, preFilters,1782 cached = tokenCache[ selector + " " ];1783 if ( cached ) {1784 return parseOnly ? 0 : cached.slice( 0 );1785 }1786 soFar = selector;1787 groups = [];1788 preFilters = Expr.preFilter;1789 while ( soFar ) {1790 // Comma and first run1791 if ( !matched || (match = rcomma.exec( soFar )) ) {1792 if ( match ) {1793 // Don't consume trailing commas as valid1794 soFar = soFar.slice( match[0].length ) || soFar;1795 }1796 groups.push( (tokens = []) );1797 }1798 matched = false;1799 // Combinators1800 if ( (match = rcombinators.exec( soFar )) ) {1801 matched = match.shift();1802 tokens.push({1803 value: matched,1804 // Cast descendant combinators to space1805 type: match[0].replace( rtrim, " " )1806 });1807 soFar = soFar.slice( matched.length );1808 }1809 // Filters1810 for ( type in Expr.filter ) {1811 if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||1812 (match = preFilters[ type ]( match ))) ) {1813 matched = match.shift();1814 tokens.push({1815 value: matched,1816 type: type,1817 matches: match1818 });1819 soFar = soFar.slice( matched.length );1820 }1821 }1822 if ( !matched ) {1823 break;1824 }1825 }1826 // Return the length of the invalid excess1827 // if we're just parsing1828 // Otherwise, throw an error or return tokens1829 return parseOnly ?1830 soFar.length :1831 soFar ?1832 Sizzle.error( selector ) :1833 // Cache the tokens1834 tokenCache( selector, groups ).slice( 0 );1835};1836function toSelector( tokens ) {1837 var i = 0,1838 len = tokens.length,1839 selector = "";1840 for ( ; i < len; i++ ) {1841 selector += tokens[i].value;1842 }1843 return selector;1844}1845function addCombinator( matcher, combinator, base ) {1846 var dir = combinator.dir,1847 skip = combinator.next,1848 key = skip || dir,1849 checkNonElements = base && key === "parentNode",1850 doneName = done++;1851 return combinator.first ?1852 // Check against closest ancestor/preceding element1853 function( elem, context, xml ) {1854 while ( (elem = elem[ dir ]) ) {1855 if ( elem.nodeType === 1 || checkNonElements ) {1856 return matcher( elem, context, xml );1857 }1858 }1859 return false;1860 } :1861 // Check against all ancestor/preceding elements1862 function( elem, context, xml ) {1863 var oldCache, uniqueCache, outerCache,1864 newCache = [ dirruns, doneName ];1865 // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching1866 if ( xml ) {1867 while ( (elem = elem[ dir ]) ) {1868 if ( elem.nodeType === 1 || checkNonElements ) {1869 if ( matcher( elem, context, xml ) ) {1870 return true;1871 }1872 }1873 }1874 } else {1875 while ( (elem = elem[ dir ]) ) {1876 if ( elem.nodeType === 1 || checkNonElements ) {1877 outerCache = elem[ expando ] || (elem[ expando ] = {});1878 // Support: IE <9 only1879 // Defend against cloned attroperties (jQuery gh-1709)1880 uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});1881 if ( skip && skip === elem.nodeName.toLowerCase() ) {1882 elem = elem[ dir ] || elem;1883 } else if ( (oldCache = uniqueCache[ key ]) &&1884 oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {1885 // Assign to newCache so results back-propagate to previous elements1886 return (newCache[ 2 ] = oldCache[ 2 ]);1887 } else {1888 // Reuse newcache so results back-propagate to previous elements1889 uniqueCache[ key ] = newCache;1890 // A match means we're done; a fail means we have to keep checking1891 if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {1892 return true;1893 }1894 }1895 }1896 }1897 }1898 return false;1899 };1900}1901function elementMatcher( matchers ) {1902 return matchers.length > 1 ?1903 function( elem, context, xml ) {1904 var i = matchers.length;1905 while ( i-- ) {1906 if ( !matchers[i]( elem, context, xml ) ) {1907 return false;1908 }1909 }1910 return true;1911 } :1912 matchers[0];1913}1914function multipleContexts( selector, contexts, results ) {1915 var i = 0,1916 len = contexts.length;1917 for ( ; i < len; i++ ) {1918 Sizzle( selector, contexts[i], results );1919 }1920 return results;1921}1922function condense( unmatched, map, filter, context, xml ) {1923 var elem,1924 newUnmatched = [],1925 i = 0,1926 len = unmatched.length,1927 mapped = map != null;1928 for ( ; i < len; i++ ) {1929 if ( (elem = unmatched[i]) ) {1930 if ( !filter || filter( elem, context, xml ) ) {1931 newUnmatched.push( elem );1932 if ( mapped ) {1933 map.push( i );1934 }1935 }1936 }1937 }1938 return newUnmatched;1939}1940function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {1941 if ( postFilter && !postFilter[ expando ] ) {1942 postFilter = setMatcher( postFilter );1943 }1944 if ( postFinder && !postFinder[ expando ] ) {1945 postFinder = setMatcher( postFinder, postSelector );1946 }1947 return markFunction(function( seed, results, context, xml ) {1948 var temp, i, elem,1949 preMap = [],1950 postMap = [],1951 preexisting = results.length,1952 // Get initial elements from seed or context1953 elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),1954 // Prefilter to get matcher input, preserving a map for seed-results synchronization1955 matcherIn = preFilter && ( seed || !selector ) ?1956 condense( elems, preMap, preFilter, context, xml ) :1957 elems,1958 matcherOut = matcher ?1959 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,1960 postFinder || ( seed ? preFilter : preexisting || postFilter ) ?1961 // ...intermediate processing is necessary1962 [] :1963 // ...otherwise use results directly1964 results :1965 matcherIn;1966 // Find primary matches1967 if ( matcher ) {1968 matcher( matcherIn, matcherOut, context, xml );1969 }1970 // Apply postFilter1971 if ( postFilter ) {1972 temp = condense( matcherOut, postMap );1973 postFilter( temp, [], context, xml );1974 // Un-match failing elements by moving them back to matcherIn1975 i = temp.length;1976 while ( i-- ) {1977 if ( (elem = temp[i]) ) {1978 matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);1979 }1980 }1981 }1982 if ( seed ) {1983 if ( postFinder || preFilter ) {1984 if ( postFinder ) {1985 // Get the final matcherOut by condensing this intermediate into postFinder contexts1986 temp = [];1987 i = matcherOut.length;1988 while ( i-- ) {1989 if ( (elem = matcherOut[i]) ) {1990 // Restore matcherIn since elem is not yet a final match1991 temp.push( (matcherIn[i] = elem) );1992 }1993 }1994 postFinder( null, (matcherOut = []), temp, xml );1995 }1996 // Move matched elements from seed to results to keep them synchronized1997 i = matcherOut.length;1998 while ( i-- ) {1999 if ( (elem = matcherOut[i]) &&2000 (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {2001 seed[temp] = !(results[temp] = elem);2002 }2003 }2004 }2005 // Add elements to results, through postFinder if defined2006 } else {2007 matcherOut = condense(2008 matcherOut === results ?2009 matcherOut.splice( preexisting, matcherOut.length ) :2010 matcherOut2011 );2012 if ( postFinder ) {2013 postFinder( null, results, matcherOut, xml );2014 } else {2015 push.apply( results, matcherOut );2016 }2017 }2018 });2019}2020function matcherFromTokens( tokens ) {2021 var checkContext, matcher, j,2022 len = tokens.length,2023 leadingRelative = Expr.relative[ tokens[0].type ],2024 implicitRelative = leadingRelative || Expr.relative[" "],2025 i = leadingRelative ? 1 : 0,2026 // The foundational matcher ensures that elements are reachable from top-level context(s)2027 matchContext = addCombinator( function( elem ) {2028 return elem === checkContext;2029 }, implicitRelative, true ),2030 matchAnyContext = addCombinator( function( elem ) {2031 return indexOf( checkContext, elem ) > -1;2032 }, implicitRelative, true ),2033 matchers = [ function( elem, context, xml ) {2034 var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (2035 (checkContext = context).nodeType ?2036 matchContext( elem, context, xml ) :2037 matchAnyContext( elem, context, xml ) );2038 // Avoid hanging onto element (issue #299)2039 checkContext = null;2040 return ret;2041 } ];2042 for ( ; i < len; i++ ) {2043 if ( (matcher = Expr.relative[ tokens[i].type ]) ) {2044 matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];2045 } else {2046 matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );2047 // Return special upon seeing a positional matcher2048 if ( matcher[ expando ] ) {2049 // Find the next relative operator (if any) for proper handling2050 j = ++i;2051 for ( ; j < len; j++ ) {2052 if ( Expr.relative[ tokens[j].type ] ) {2053 break;2054 }2055 }2056 return setMatcher(2057 i > 1 && elementMatcher( matchers ),2058 i > 1 && toSelector(2059 // If the preceding token was a descendant combinator, insert an implicit any-element `*`2060 tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })2061 ).replace( rtrim, "$1" ),2062 matcher,2063 i < j && matcherFromTokens( tokens.slice( i, j ) ),2064 j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),2065 j < len && toSelector( tokens )2066 );2067 }2068 matchers.push( matcher );2069 }2070 }2071 return elementMatcher( matchers );2072}2073function matcherFromGroupMatchers( elementMatchers, setMatchers ) {2074 var bySet = setMatchers.length > 0,2075 byElement = elementMatchers.length > 0,2076 superMatcher = function( seed, context, xml, results, outermost ) {2077 var elem, j, matcher,2078 matchedCount = 0,2079 i = "0",2080 unmatched = seed && [],2081 setMatched = [],2082 contextBackup = outermostContext,2083 // We must always have either seed elements or outermost context2084 elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),2085 // Use integer dirruns iff this is the outermost matcher2086 dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),2087 len = elems.length;2088 if ( outermost ) {2089 outermostContext = context === document || context || outermost;2090 }2091 // Add elements passing elementMatchers directly to results2092 // Support: IE<9, Safari2093 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id2094 for ( ; i !== len && (elem = elems[i]) != null; i++ ) {2095 if ( byElement && elem ) {2096 j = 0;2097 if ( !context && elem.ownerDocument !== document ) {2098 setDocument( elem );2099 xml = !documentIsHTML;2100 }2101 while ( (matcher = elementMatchers[j++]) ) {2102 if ( matcher( elem, context || document, xml) ) {2103 results.push( elem );2104 break;2105 }2106 }2107 if ( outermost ) {2108 dirruns = dirrunsUnique;2109 }2110 }2111 // Track unmatched elements for set filters2112 if ( bySet ) {2113 // They will have gone through all possible matchers2114 if ( (elem = !matcher && elem) ) {2115 matchedCount--;2116 }2117 // Lengthen the array for every element, matched or not2118 if ( seed ) {2119 unmatched.push( elem );2120 }2121 }2122 }2123 // `i` is now the count of elements visited above, and adding it to `matchedCount`2124 // makes the latter nonnegative.2125 matchedCount += i;2126 // Apply set filters to unmatched elements2127 // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`2128 // equals `i`), unless we didn't visit _any_ elements in the above loop because we have2129 // no element matchers and no seed.2130 // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that2131 // case, which will result in a "00" `matchedCount` that differs from `i` but is also2132 // numerically zero.2133 if ( bySet && i !== matchedCount ) {2134 j = 0;2135 while ( (matcher = setMatchers[j++]) ) {2136 matcher( unmatched, setMatched, context, xml );2137 }2138 if ( seed ) {2139 // Reintegrate element matches to eliminate the need for sorting2140 if ( matchedCount > 0 ) {2141 while ( i-- ) {2142 if ( !(unmatched[i] || setMatched[i]) ) {2143 setMatched[i] = pop.call( results );2144 }2145 }2146 }2147 // Discard index placeholder values to get only actual matches2148 setMatched = condense( setMatched );2149 }2150 // Add matches to results2151 push.apply( results, setMatched );2152 // Seedless set matches succeeding multiple successful matchers stipulate sorting2153 if ( outermost && !seed && setMatched.length > 0 &&2154 ( matchedCount + setMatchers.length ) > 1 ) {2155 Sizzle.uniqueSort( results );2156 }2157 }2158 // Override manipulation of globals by nested matchers2159 if ( outermost ) {2160 dirruns = dirrunsUnique;2161 outermostContext = contextBackup;2162 }2163 return unmatched;2164 };2165 return bySet ?2166 markFunction( superMatcher ) :2167 superMatcher;2168}2169compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {2170 var i,2171 setMatchers = [],2172 elementMatchers = [],2173 cached = compilerCache[ selector + " " ];2174 if ( !cached ) {2175 // Generate a function of recursive functions that can be used to check each element2176 if ( !match ) {2177 match = tokenize( selector );2178 }2179 i = match.length;2180 while ( i-- ) {2181 cached = matcherFromTokens( match[i] );2182 if ( cached[ expando ] ) {2183 setMatchers.push( cached );2184 } else {2185 elementMatchers.push( cached );2186 }2187 }2188 // Cache the compiled function2189 cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );2190 // Save selector and tokenization2191 cached.selector = selector;2192 }2193 return cached;2194};2195/**2196 * A low-level selection function that works with Sizzle's compiled2197 * selector functions2198 * @param {String|Function} selector A selector or a pre-compiled2199 * selector function built with Sizzle.compile2200 * @param {Element} context2201 * @param {Array} [results]2202 * @param {Array} [seed] A set of elements to match against2203 */2204select = Sizzle.select = function( selector, context, results, seed ) {2205 var i, tokens, token, type, find,2206 compiled = typeof selector === "function" && selector,2207 match = !seed && tokenize( (selector = compiled.selector || selector) );2208 results = results || [];2209 // Try to minimize operations if there is only one selector in the list and no seed2210 // (the latter of which guarantees us context)2211 if ( match.length === 1 ) {2212 // Reduce context if the leading compound selector is an ID2213 tokens = match[0] = match[0].slice( 0 );2214 if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&2215 context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {2216 context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];2217 if ( !context ) {2218 return results;2219 // Precompiled matchers will still verify ancestry, so step up a level2220 } else if ( compiled ) {2221 context = context.parentNode;2222 }2223 selector = selector.slice( tokens.shift().value.length );2224 }2225 // Fetch a seed set for right-to-left matching2226 i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;2227 while ( i-- ) {2228 token = tokens[i];2229 // Abort if we hit a combinator2230 if ( Expr.relative[ (type = token.type) ] ) {2231 break;2232 }2233 if ( (find = Expr.find[ type ]) ) {2234 // Search, expanding context for leading sibling combinators2235 if ( (seed = find(2236 token.matches[0].replace( runescape, funescape ),2237 rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context2238 )) ) {2239 // If seed is empty or no tokens remain, we can return early2240 tokens.splice( i, 1 );2241 selector = seed.length && toSelector( tokens );2242 if ( !selector ) {2243 push.apply( results, seed );2244 return results;2245 }2246 break;2247 }2248 }2249 }2250 }2251 // Compile and execute a filtering function if one is not provided2252 // Provide `match` to avoid retokenization if we modified the selector above2253 ( compiled || compile( selector, match ) )(2254 seed,2255 context,2256 !documentIsHTML,2257 results,2258 !context || rsibling.test( selector ) && testContext( context.parentNode ) || context2259 );2260 return results;2261};2262// One-time assignments2263// Sort stability2264support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;2265// Support: Chrome 14-35+2266// Always assume duplicates if they aren't passed to the comparison function2267support.detectDuplicates = !!hasDuplicate;2268// Initialize against the default document2269setDocument();2270// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)2271// Detached nodes confoundingly follow *each other*2272support.sortDetached = assert(function( el ) {2273 // Should return 1, but returns 4 (following)2274 return el.compareDocumentPosition( document.createElement("fieldset") ) & 1;2275});2276// Support: IE<82277// Prevent attribute/property "interpolation"2278// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx2279if ( !assert(function( el ) {2280 el.innerHTML = "<a href='#'></a>";2281 return el.firstChild.getAttribute("href") === "#" ;2282}) ) {2283 addHandle( "type|href|height|width", function( elem, name, isXML ) {2284 if ( !isXML ) {2285 return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );2286 }2287 });2288}2289// Support: IE<92290// Use defaultValue in place of getAttribute("value")2291if ( !support.attributes || !assert(function( el ) {2292 el.innerHTML = "<input/>";2293 el.firstChild.setAttribute( "value", "" );2294 return el.firstChild.getAttribute( "value" ) === "";2295}) ) {2296 addHandle( "value", function( elem, name, isXML ) {2297 if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {2298 return elem.defaultValue;2299 }2300 });2301}2302// Support: IE<92303// Use getAttributeNode to fetch booleans when getAttribute lies2304if ( !assert(function( el ) {2305 return el.getAttribute("disabled") == null;2306}) ) {2307 addHandle( booleans, function( elem, name, isXML ) {2308 var val;2309 if ( !isXML ) {2310 return elem[ name ] === true ? name.toLowerCase() :2311 (val = elem.getAttributeNode( name )) && val.specified ?2312 val.value :2313 null;2314 }2315 });2316}2317return Sizzle;2318})( window );2319jQuery.find = Sizzle;2320jQuery.expr = Sizzle.selectors;2321// Deprecated2322jQuery.expr[ ":" ] = jQuery.expr.pseudos;2323jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;2324jQuery.text = Sizzle.getText;2325jQuery.isXMLDoc = Sizzle.isXML;2326jQuery.contains = Sizzle.contains;2327jQuery.escapeSelector = Sizzle.escape;2328var dir = function( elem, dir, until ) {2329 var matched = [],2330 truncate = until !== undefined;2331 while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {2332 if ( elem.nodeType === 1 ) {2333 if ( truncate && jQuery( elem ).is( until ) ) {2334 break;2335 }2336 matched.push( elem );2337 }2338 }2339 return matched;2340};2341var siblings = function( n, elem ) {2342 var matched = [];2343 for ( ; n; n = n.nextSibling ) {2344 if ( n.nodeType === 1 && n !== elem ) {2345 matched.push( n );2346 }2347 }2348 return matched;2349};2350var rneedsContext = jQuery.expr.match.needsContext;2351function nodeName( elem, name ) {2352 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();2353};2354var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );2355// Implement the identical functionality for filter and not2356function winnow( elements, qualifier, not ) {2357 if ( isFunction( qualifier ) ) {2358 return jQuery.grep( elements, function( elem, i ) {2359 return !!qualifier.call( elem, i, elem ) !== not;2360 } );2361 }2362 // Single element2363 if ( qualifier.nodeType ) {2364 return jQuery.grep( elements, function( elem ) {2365 return ( elem === qualifier ) !== not;2366 } );2367 }2368 // Arraylike of elements (jQuery, arguments, Array)2369 if ( typeof qualifier !== "string" ) {2370 return jQuery.grep( elements, function( elem ) {2371 return ( indexOf.call( qualifier, elem ) > -1 ) !== not;2372 } );2373 }2374 // Filtered directly for both simple and complex selectors2375 return jQuery.filter( qualifier, elements, not );2376}2377jQuery.filter = function( expr, elems, not ) {2378 var elem = elems[ 0 ];2379 if ( not ) {2380 expr = ":not(" + expr + ")";2381 }2382 if ( elems.length === 1 && elem.nodeType === 1 ) {2383 return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];2384 }2385 return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {2386 return elem.nodeType === 1;2387 } ) );2388};2389jQuery.fn.extend( {2390 find: function( selector ) {2391 var i, ret,2392 len = this.length,2393 self = this;2394 if ( typeof selector !== "string" ) {2395 return this.pushStack( jQuery( selector ).filter( function() {2396 for ( i = 0; i < len; i++ ) {2397 if ( jQuery.contains( self[ i ], this ) ) {2398 return true;2399 }2400 }2401 } ) );2402 }2403 ret = this.pushStack( [] );2404 for ( i = 0; i < len; i++ ) {2405 jQuery.find( selector, self[ i ], ret );2406 }2407 return len > 1 ? jQuery.uniqueSort( ret ) : ret;2408 },2409 filter: function( selector ) {2410 return this.pushStack( winnow( this, selector || [], false ) );2411 },2412 not: function( selector ) {2413 return this.pushStack( winnow( this, selector || [], true ) );2414 },2415 is: function( selector ) {2416 return !!winnow(2417 this,2418 // If this is a positional/relative selector, check membership in the returned set2419 // so $("p:first").is("p:last") won't return true for a doc with two "p".2420 typeof selector === "string" && rneedsContext.test( selector ) ?2421 jQuery( selector ) :2422 selector || [],2423 false2424 ).length;2425 }2426} );2427// Initialize a jQuery object2428// A central reference to the root jQuery(document)2429var rootjQuery,2430 // A simple way to check for HTML strings2431 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)2432 // Strict HTML recognition (#11290: must start with <)2433 // Shortcut simple #id case for speed2434 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,2435 init = jQuery.fn.init = function( selector, context, root ) {2436 var match, elem;2437 // HANDLE: $(""), $(null), $(undefined), $(false)2438 if ( !selector ) {2439 return this;2440 }2441 // Method init() accepts an alternate rootjQuery2442 // so migrate can support jQuery.sub (gh-2101)2443 root = root || rootjQuery;2444 // Handle HTML strings2445 if ( typeof selector === "string" ) {2446 if ( selector[ 0 ] === "<" &&2447 selector[ selector.length - 1 ] === ">" &&2448 selector.length >= 3 ) {2449 // Assume that strings that start and end with <> are HTML and skip the regex check2450 match = [ null, selector, null ];2451 } else {2452 match = rquickExpr.exec( selector );2453 }2454 // Match html or make sure no context is specified for #id2455 if ( match && ( match[ 1 ] || !context ) ) {2456 // HANDLE: $(html) -> $(array)2457 if ( match[ 1 ] ) {2458 context = context instanceof jQuery ? context[ 0 ] : context;2459 // Option to run scripts is true for back-compat2460 // Intentionally let the error be thrown if parseHTML is not present2461 jQuery.merge( this, jQuery.parseHTML(2462 match[ 1 ],2463 context && context.nodeType ? context.ownerDocument || context : document,2464 true2465 ) );2466 // HANDLE: $(html, props)2467 if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {2468 for ( match in context ) {2469 // Properties of context are called as methods if possible2470 if ( isFunction( this[ match ] ) ) {2471 this[ match ]( context[ match ] );2472 // ...and otherwise set as attributes2473 } else {2474 this.attr( match, context[ match ] );2475 }2476 }2477 }2478 return this;2479 // HANDLE: $(#id)2480 } else {2481 elem = document.getElementById( match[ 2 ] );2482 if ( elem ) {2483 // Inject the element directly into the jQuery object2484 this[ 0 ] = elem;2485 this.length = 1;2486 }2487 return this;2488 }2489 // HANDLE: $(expr, $(...))2490 } else if ( !context || context.jquery ) {2491 return ( context || root ).find( selector );2492 // HANDLE: $(expr, context)2493 // (which is just equivalent to: $(context).find(expr)2494 } else {2495 return this.constructor( context ).find( selector );2496 }2497 // HANDLE: $(DOMElement)2498 } else if ( selector.nodeType ) {2499 this[ 0 ] = selector;2500 this.length = 1;2501 return this;2502 // HANDLE: $(function)2503 // Shortcut for document ready2504 } else if ( isFunction( selector ) ) {2505 return root.ready !== undefined ?2506 root.ready( selector ) :2507 // Execute immediately if ready is not present2508 selector( jQuery );2509 }2510 return jQuery.makeArray( selector, this );2511 };2512// Give the init function the jQuery prototype for later instantiation2513init.prototype = jQuery.fn;2514// Initialize central reference2515rootjQuery = jQuery( document );2516var rparentsprev = /^(?:parents|prev(?:Until|All))/,2517 // Methods guaranteed to produce a unique set when starting from a unique set2518 guaranteedUnique = {2519 children: true,2520 contents: true,2521 next: true,2522 prev: true2523 };2524jQuery.fn.extend( {2525 has: function( target ) {2526 var targets = jQuery( target, this ),2527 l = targets.length;2528 return this.filter( function() {2529 var i = 0;2530 for ( ; i < l; i++ ) {2531 if ( jQuery.contains( this, targets[ i ] ) ) {2532 return true;2533 }2534 }2535 } );2536 },2537 closest: function( selectors, context ) {2538 var cur,2539 i = 0,2540 l = this.length,2541 matched = [],2542 targets = typeof selectors !== "string" && jQuery( selectors );2543 // Positional selectors never match, since there's no _selection_ context2544 if ( !rneedsContext.test( selectors ) ) {2545 for ( ; i < l; i++ ) {2546 for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {2547 // Always skip document fragments2548 if ( cur.nodeType < 11 && ( targets ?2549 targets.index( cur ) > -1 :2550 // Don't pass non-elements to Sizzle2551 cur.nodeType === 1 &&2552 jQuery.find.matchesSelector( cur, selectors ) ) ) {2553 matched.push( cur );2554 break;2555 }2556 }2557 }2558 }2559 return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );2560 },2561 // Determine the position of an element within the set2562 index: function( elem ) {2563 // No argument, return index in parent2564 if ( !elem ) {2565 return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;2566 }2567 // Index in selector2568 if ( typeof elem === "string" ) {2569 return indexOf.call( jQuery( elem ), this[ 0 ] );2570 }2571 // Locate the position of the desired element2572 return indexOf.call( this,2573 // If it receives a jQuery object, the first element is used2574 elem.jquery ? elem[ 0 ] : elem2575 );2576 },2577 add: function( selector, context ) {2578 return this.pushStack(2579 jQuery.uniqueSort(2580 jQuery.merge( this.get(), jQuery( selector, context ) )2581 )2582 );2583 },2584 addBack: function( selector ) {2585 return this.add( selector == null ?2586 this.prevObject : this.prevObject.filter( selector )2587 );2588 }2589} );2590function sibling( cur, dir ) {2591 while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}2592 return cur;2593}2594jQuery.each( {2595 parent: function( elem ) {2596 var parent = elem.parentNode;2597 return parent && parent.nodeType !== 11 ? parent : null;2598 },2599 parents: function( elem ) {2600 return dir( elem, "parentNode" );2601 },2602 parentsUntil: function( elem, i, until ) {2603 return dir( elem, "parentNode", until );2604 },2605 next: function( elem ) {2606 return sibling( elem, "nextSibling" );2607 },2608 prev: function( elem ) {2609 return sibling( elem, "previousSibling" );2610 },2611 nextAll: function( elem ) {2612 return dir( elem, "nextSibling" );2613 },2614 prevAll: function( elem ) {2615 return dir( elem, "previousSibling" );2616 },2617 nextUntil: function( elem, i, until ) {2618 return dir( elem, "nextSibling", until );2619 },2620 prevUntil: function( elem, i, until ) {2621 return dir( elem, "previousSibling", until );2622 },2623 siblings: function( elem ) {2624 return siblings( ( elem.parentNode || {} ).firstChild, elem );2625 },2626 children: function( elem ) {2627 return siblings( elem.firstChild );2628 },2629 contents: function( elem ) {2630 if ( typeof elem.contentDocument !== "undefined" ) {2631 return elem.contentDocument;2632 }2633 // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only2634 // Treat the template element as a regular one in browsers that2635 // don't support it.2636 if ( nodeName( elem, "template" ) ) {2637 elem = elem.content || elem;2638 }2639 return jQuery.merge( [], elem.childNodes );2640 }2641}, function( name, fn ) {2642 jQuery.fn[ name ] = function( until, selector ) {2643 var matched = jQuery.map( this, fn, until );2644 if ( name.slice( -5 ) !== "Until" ) {2645 selector = until;2646 }2647 if ( selector && typeof selector === "string" ) {2648 matched = jQuery.filter( selector, matched );2649 }2650 if ( this.length > 1 ) {2651 // Remove duplicates2652 if ( !guaranteedUnique[ name ] ) {2653 jQuery.uniqueSort( matched );2654 }2655 // Reverse order for parents* and prev-derivatives2656 if ( rparentsprev.test( name ) ) {2657 matched.reverse();2658 }2659 }2660 return this.pushStack( matched );2661 };2662} );2663var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );2664// Convert String-formatted options into Object-formatted ones2665function createOptions( options ) {2666 var object = {};2667 jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {2668 object[ flag ] = true;2669 } );2670 return object;2671}2672/*2673 * Create a callback list using the following parameters:2674 *2675 * options: an optional list of space-separated options that will change how2676 * the callback list behaves or a more traditional option object2677 *2678 * By default a callback list will act like an event callback list and can be2679 * "fired" multiple times.2680 *2681 * Possible options:2682 *2683 * once: will ensure the callback list can only be fired once (like a Deferred)2684 *2685 * memory: will keep track of previous values and will call any callback added2686 * after the list has been fired right away with the latest "memorized"2687 * values (like a Deferred)2688 *2689 * unique: will ensure a callback can only be added once (no duplicate in the list)2690 *2691 * stopOnFalse: interrupt callings when a callback returns false2692 *2693 */2694jQuery.callbacks = function( options ) {2695 // Convert options from String-formatted to Object-formatted if needed2696 // (we check in cache first)2697 options = typeof options === "string" ?2698 createOptions( options ) :2699 jQuery.extend( {}, options );2700 var // Flag to know if list is currently firing2701 firing,2702 // Last fire value for non-forgettable lists2703 memory,2704 // Flag to know if list was already fired2705 fired,2706 // Flag to prevent firing2707 locked,2708 // Actual callback list2709 list = [],2710 // Queue of execution data for repeatable lists2711 queue = [],2712 // Index of currently firing callback (modified by add/remove as needed)2713 firingIndex = -1,2714 // Fire callbacks2715 fire = function() {2716 // Enforce single-firing2717 locked = locked || options.once;2718 // Execute callbacks for all pending executions,2719 // respecting firingIndex overrides and runtime changes2720 fired = firing = true;2721 for ( ; queue.length; firingIndex = -1 ) {2722 memory = queue.shift();2723 while ( ++firingIndex < list.length ) {2724 // Run callback and check for early termination2725 if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&2726 options.stopOnFalse ) {2727 // Jump to end and forget the data so .add doesn't re-fire2728 firingIndex = list.length;2729 memory = false;2730 }2731 }2732 }2733 // Forget the data if we're done with it2734 if ( !options.memory ) {2735 memory = false;2736 }2737 firing = false;2738 // Clean up if we're done firing for good2739 if ( locked ) {2740 // Keep an empty list if we have data for future add calls2741 if ( memory ) {2742 list = [];2743 // Otherwise, this object is spent2744 } else {2745 list = "";2746 }2747 }2748 },2749 // Actual callbacks object2750 self = {2751 // Add a callback or a collection of callbacks to the list2752 add: function() {2753 if ( list ) {2754 // If we have memory from a past run, we should fire after adding2755 if ( memory && !firing ) {2756 firingIndex = list.length - 1;2757 queue.push( memory );2758 }2759 ( function add( args ) {2760 jQuery.each( args, function( _, arg ) {2761 if ( isFunction( arg ) ) {2762 if ( !options.unique || !self.has( arg ) ) {2763 list.push( arg );2764 }2765 } else if ( arg && arg.length && toType( arg ) !== "string" ) {2766 // Inspect recursively2767 add( arg );2768 }2769 } );2770 } )( arguments );2771 if ( memory && !firing ) {2772 fire();2773 }2774 }2775 return this;2776 },2777 // Remove a callback from the list2778 remove: function() {2779 jQuery.each( arguments, function( _, arg ) {2780 var index;2781 while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {2782 list.splice( index, 1 );2783 // Handle firing indexes2784 if ( index <= firingIndex ) {2785 firingIndex--;2786 }2787 }2788 } );2789 return this;2790 },2791 // Check if a given callback is in the list.2792 // If no argument is given, return whether or not list has callbacks attached.2793 has: function( fn ) {2794 return fn ?2795 jQuery.inArray( fn, list ) > -1 :2796 list.length > 0;2797 },2798 // Remove all callbacks from the list2799 empty: function() {2800 if ( list ) {2801 list = [];2802 }2803 return this;2804 },2805 // Disable .fire and .add2806 // Abort any current/pending executions2807 // Clear all callbacks and values2808 disable: function() {2809 locked = queue = [];2810 list = memory = "";2811 return this;2812 },2813 disabled: function() {2814 return !list;2815 },2816 // Disable .fire2817 // Also disable .add unless we have memory (since it would have no effect)2818 // Abort any pending executions2819 lock: function() {2820 locked = queue = [];2821 if ( !memory && !firing ) {2822 list = memory = "";2823 }2824 return this;2825 },2826 locked: function() {2827 return !!locked;2828 },2829 // Call all callbacks with the given context and arguments2830 fireWith: function( context, args ) {2831 if ( !locked ) {2832 args = args || [];2833 args = [ context, args.slice ? args.slice() : args ];2834 queue.push( args );2835 if ( !firing ) {2836 fire();2837 }2838 }2839 return this;2840 },2841 // Call all the callbacks with the given arguments2842 fire: function() {2843 self.fireWith( this, arguments );2844 return this;2845 },2846 // To know if the callbacks have already been called at least once2847 fired: function() {2848 return !!fired;2849 }2850 };2851 return self;2852};2853function Identity( v ) {2854 return v;2855}2856function Thrower( ex ) {2857 throw ex;2858}2859function adoptValue( value, resolve, reject, noValue ) {2860 var method;2861 try {2862 // Check for promise aspect first to privilege synchronous behavior2863 if ( value && isFunction( ( method = value.promise ) ) ) {2864 method.call( value ).done( resolve ).fail( reject );2865 // Other thenables2866 } else if ( value && isFunction( ( method = value.then ) ) ) {2867 method.call( value, resolve, reject );2868 // Other non-thenables2869 } else {2870 // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:2871 // * false: [ value ].slice( 0 ) => resolve( value )2872 // * true: [ value ].slice( 1 ) => resolve()2873 resolve.apply( undefined, [ value ].slice( noValue ) );2874 }2875 // For Promises/A+, convert exceptions into rejections2876 // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in2877 // Deferred#then to conditionally suppress rejection.2878 } catch ( value ) {2879 // Support: Android 4.0 only2880 // Strict mode functions invoked without .call/.apply get global-object context2881 reject.apply( undefined, [ value ] );2882 }2883}2884jQuery.extend( {2885 Deferred: function( func ) {2886 var tuples = [2887 // action, add listener, callbacks,2888 // ... .then handlers, argument index, [final state]2889 [ "notify", "progress", jQuery.callbacks( "memory" ),2890 jQuery.callbacks( "memory" ), 2 ],2891 [ "resolve", "done", jQuery.callbacks( "once memory" ),2892 jQuery.callbacks( "once memory" ), 0, "resolved" ],2893 [ "reject", "fail", jQuery.callbacks( "once memory" ),2894 jQuery.callbacks( "once memory" ), 1, "rejected" ]2895 ],2896 state = "pending",2897 promise = {2898 state: function() {2899 return state;2900 },2901 always: function() {2902 deferred.done( arguments ).fail( arguments );2903 return this;2904 },2905 "catch": function( fn ) {2906 return promise.then( null, fn );2907 },2908 // Keep pipe for back-compat2909 pipe: function( /* fnDone, fnFail, fnProgress */ ) {2910 var fns = arguments;2911 return jQuery.Deferred( function( newDefer ) {2912 jQuery.each( tuples, function( i, tuple ) {2913 // Map tuples (progress, done, fail) to arguments (done, fail, progress)2914 var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];2915 // deferred.progress(function() { bind to newDefer or newDefer.notify })2916 // deferred.done(function() { bind to newDefer or newDefer.resolve })2917 // deferred.fail(function() { bind to newDefer or newDefer.reject })2918 deferred[ tuple[ 1 ] ]( function() {2919 var returned = fn && fn.apply( this, arguments );2920 if ( returned && isFunction( returned.promise ) ) {2921 returned.promise()2922 .progress( newDefer.notify )2923 .done( newDefer.resolve )2924 .fail( newDefer.reject );2925 } else {2926 newDefer[ tuple[ 0 ] + "With" ](2927 this,2928 fn ? [ returned ] : arguments2929 );2930 }2931 } );2932 } );2933 fns = null;2934 } ).promise();2935 },2936 then: function( onFulfilled, onRejected, onProgress ) {2937 var maxDepth = 0;2938 function resolve( depth, deferred, handler, special ) {2939 return function() {2940 var that = this,2941 args = arguments,2942 mightThrow = function() {2943 var returned, then;2944 // Support: Promises/A+ section 2.3.3.3.32945 // https://promisesaplus.com/#point-592946 // Ignore double-resolution attempts2947 if ( depth < maxDepth ) {2948 return;2949 }2950 returned = handler.apply( that, args );2951 // Support: Promises/A+ section 2.3.12952 // https://promisesaplus.com/#point-482953 if ( returned === deferred.promise() ) {2954 throw new TypeError( "Thenable self-resolution" );2955 }2956 // Support: Promises/A+ sections 2.3.3.1, 3.52957 // https://promisesaplus.com/#point-542958 // https://promisesaplus.com/#point-752959 // Retrieve `then` only once2960 then = returned &&2961 // Support: Promises/A+ section 2.3.42962 // https://promisesaplus.com/#point-642963 // Only check objects and functions for thenability2964 ( typeof returned === "object" ||2965 typeof returned === "function" ) &&2966 returned.then;2967 // Handle a returned thenable2968 if ( isFunction( then ) ) {2969 // Special processors (notify) just wait for resolution2970 if ( special ) {2971 then.call(2972 returned,2973 resolve( maxDepth, deferred, Identity, special ),2974 resolve( maxDepth, deferred, Thrower, special )2975 );2976 // Normal processors (resolve) also hook into progress2977 } else {2978 // ...and disregard older resolution values2979 maxDepth++;2980 then.call(2981 returned,2982 resolve( maxDepth, deferred, Identity, special ),2983 resolve( maxDepth, deferred, Thrower, special ),2984 resolve( maxDepth, deferred, Identity,2985 deferred.notifyWith )2986 );2987 }2988 // Handle all other returned values2989 } else {2990 // Only substitute handlers pass on context2991 // and multiple values (non-spec behavior)2992 if ( handler !== Identity ) {2993 that = undefined;2994 args = [ returned ];2995 }2996 // Process the value(s)2997 // Default process is resolve2998 ( special || deferred.resolveWith )( that, args );2999 }3000 },3001 // Only normal processors (resolve) catch and reject exceptions3002 process = special ?3003 mightThrow :3004 function() {3005 try {3006 mightThrow();3007 } catch ( e ) {3008 if ( jQuery.Deferred.exceptionHook ) {3009 jQuery.Deferred.exceptionHook( e,3010 process.stackTrace );3011 }3012 // Support: Promises/A+ section 2.3.3.3.4.13013 // https://promisesaplus.com/#point-613014 // Ignore post-resolution exceptions3015 if ( depth + 1 >= maxDepth ) {3016 // Only substitute handlers pass on context3017 // and multiple values (non-spec behavior)3018 if ( handler !== Thrower ) {3019 that = undefined;3020 args = [ e ];3021 }3022 deferred.rejectWith( that, args );3023 }3024 }3025 };3026 // Support: Promises/A+ section 2.3.3.3.13027 // https://promisesaplus.com/#point-573028 // Re-resolve promises immediately to dodge false rejection from3029 // subsequent errors3030 if ( depth ) {3031 process();3032 } else {3033 // Call an optional hook to record the stack, in case of exception3034 // since it's otherwise lost when execution goes async3035 if ( jQuery.Deferred.getStackHook ) {3036 process.stackTrace = jQuery.Deferred.getStackHook();3037 }3038 window.setTimeout( process );3039 }3040 };3041 }3042 return jQuery.Deferred( function( newDefer ) {3043 // progress_handlers.add( ... )3044 tuples[ 0 ][ 3 ].add(3045 resolve(3046 0,3047 newDefer,3048 isFunction( onProgress ) ?3049 onProgress :3050 Identity,3051 newDefer.notifyWith3052 )3053 );3054 // fulfilled_handlers.add( ... )3055 tuples[ 1 ][ 3 ].add(3056 resolve(3057 0,3058 newDefer,3059 isFunction( onFulfilled ) ?3060 onFulfilled :3061 Identity3062 )3063 );3064 // rejected_handlers.add( ... )3065 tuples[ 2 ][ 3 ].add(3066 resolve(3067 0,3068 newDefer,3069 isFunction( onRejected ) ?3070 onRejected :3071 Thrower3072 )3073 );3074 } ).promise();3075 },3076 // Get a promise for this deferred3077 // If obj is provided, the promise aspect is added to the object3078 promise: function( obj ) {3079 return obj != null ? jQuery.extend( obj, promise ) : promise;3080 }3081 },3082 deferred = {};3083 // Add list-specific methods3084 jQuery.each( tuples, function( i, tuple ) {3085 var list = tuple[ 2 ],3086 stateString = tuple[ 5 ];3087 // promise.progress = list.add3088 // promise.done = list.add3089 // promise.fail = list.add3090 promise[ tuple[ 1 ] ] = list.add;3091 // Handle state3092 if ( stateString ) {3093 list.add(3094 function() {3095 // state = "resolved" (i.e., fulfilled)3096 // state = "rejected"3097 state = stateString;3098 },3099 // rejected_callbacks.disable3100 // fulfilled_callbacks.disable3101 tuples[ 3 - i ][ 2 ].disable,3102 // rejected_handlers.disable3103 // fulfilled_handlers.disable3104 tuples[ 3 - i ][ 3 ].disable,3105 // progress_callbacks.lock3106 tuples[ 0 ][ 2 ].lock,3107 // progress_handlers.lock3108 tuples[ 0 ][ 3 ].lock3109 );3110 }3111 // progress_handlers.fire3112 // fulfilled_handlers.fire3113 // rejected_handlers.fire3114 list.add( tuple[ 3 ].fire );3115 // deferred.notify = function() { deferred.notifyWith(...) }3116 // deferred.resolve = function() { deferred.resolveWith(...) }3117 // deferred.reject = function() { deferred.rejectWith(...) }3118 deferred[ tuple[ 0 ] ] = function() {3119 deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );3120 return this;3121 };3122 // deferred.notifyWith = list.fireWith3123 // deferred.resolveWith = list.fireWith3124 // deferred.rejectWith = list.fireWith3125 deferred[ tuple[ 0 ] + "With" ] = list.fireWith;3126 } );3127 // Make the deferred a promise3128 promise.promise( deferred );3129 // Call given func if any3130 if ( func ) {3131 func.call( deferred, deferred );3132 }3133 // All done!3134 return deferred;3135 },3136 // Deferred helper3137 when: function( singleValue ) {3138 var3139 // count of uncompleted subordinates3140 remaining = arguments.length,3141 // count of unprocessed arguments3142 i = remaining,3143 // subordinate fulfillment data3144 resolveContexts = Array( i ),3145 resolveValues = slice.call( arguments ),3146 // the master Deferred3147 master = jQuery.Deferred(),3148 // subordinate callback factory3149 updateFunc = function( i ) {3150 return function( value ) {3151 resolveContexts[ i ] = this;3152 resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;3153 if ( !( --remaining ) ) {3154 master.resolveWith( resolveContexts, resolveValues );3155 }3156 };3157 };3158 // Single- and empty arguments are adopted like Promise.resolve3159 if ( remaining <= 1 ) {3160 adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,3161 !remaining );3162 // Use .then() to unwrap secondary thenables (cf. gh-3000)3163 if ( master.state() === "pending" ||3164 isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {3165 return master.then();3166 }3167 }3168 // Multiple arguments are aggregated like Promise.all array elements3169 while ( i-- ) {3170 adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );3171 }3172 return master.promise();3173 }3174} );3175// These usually indicate a programmer mistake during development,3176// warn about them ASAP rather than swallowing them by default.3177var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;3178jQuery.Deferred.exceptionHook = function( error, stack ) {3179 // Support: IE 8 - 9 only3180 // Console exists when dev tools are open, which can happen at any time3181 if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {3182 window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );3183 }3184};3185jQuery.readyException = function( error ) {3186 window.setTimeout( function() {3187 throw error;3188 } );3189};3190// The deferred used on DOM ready3191var readyList = jQuery.Deferred();3192jQuery.fn.ready = function( fn ) {3193 readyList3194 .then( fn )3195 // Wrap jQuery.readyException in a function so that the lookup3196 // happens at the time of error handling instead of callback3197 // registration.3198 .catch( function( error ) {3199 jQuery.readyException( error );3200 } );3201 return this;3202};3203jQuery.extend( {3204 // Is the DOM ready to be used? Set to true once it occurs.3205 isReady: false,3206 // A counter to track how many items to wait for before3207 // the ready event fires. See #67813208 readyWait: 1,3209 // Handle when the DOM is ready3210 ready: function( wait ) {3211 // Abort if there are pending holds or we're already ready3212 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {3213 return;3214 }3215 // Remember that the DOM is ready3216 jQuery.isReady = true;3217 // If a normal DOM Ready event fired, decrement, and wait if need be3218 if ( wait !== true && --jQuery.readyWait > 0 ) {3219 return;3220 }3221 // If there are functions bound, to execute3222 readyList.resolveWith( document, [ jQuery ] );3223 }3224} );3225jQuery.ready.then = readyList.then;3226// The ready event handler and self cleanup method3227function completed() {3228 document.removeEventListener( "DOMContentLoaded", completed );3229 window.removeEventListener( "load", completed );3230 jQuery.ready();3231}3232// Catch cases where $(document).ready() is called3233// after the browser event has already occurred.3234// Support: IE <=9 - 10 only3235// Older IE sometimes signals "interactive" too soon3236if ( document.readyState === "complete" ||3237 ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {3238 // Handle it asynchronously to allow scripts the opportunity to delay ready3239 window.setTimeout( jQuery.ready );3240} else {3241 // Use the handy event callback3242 document.addEventListener( "DOMContentLoaded", completed );3243 // A fallback to window.onload, that will always work3244 window.addEventListener( "load", completed );3245}3246// Multifunctional method to get and set values of a collection3247// The value/s can optionally be executed if it's a function3248var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {3249 var i = 0,3250 len = elems.length,3251 bulk = key == null;3252 // Sets many values3253 if ( toType( key ) === "object" ) {3254 chainable = true;3255 for ( i in key ) {3256 access( elems, fn, i, key[ i ], true, emptyGet, raw );3257 }3258 // Sets one value3259 } else if ( value !== undefined ) {3260 chainable = true;3261 if ( !isFunction( value ) ) {3262 raw = true;3263 }3264 if ( bulk ) {3265 // Bulk operations run against the entire set3266 if ( raw ) {3267 fn.call( elems, value );3268 fn = null;3269 // ...except when executing function values3270 } else {3271 bulk = fn;3272 fn = function( elem, key, value ) {3273 return bulk.call( jQuery( elem ), value );3274 };3275 }3276 }3277 if ( fn ) {3278 for ( ; i < len; i++ ) {3279 fn(3280 elems[ i ], key, raw ?3281 value :3282 value.call( elems[ i ], i, fn( elems[ i ], key ) )3283 );3284 }3285 }3286 }3287 if ( chainable ) {3288 return elems;3289 }3290 // Gets3291 if ( bulk ) {3292 return fn.call( elems );3293 }3294 return len ? fn( elems[ 0 ], key ) : emptyGet;3295};3296// Matches dashed string for camelizing3297var rmsPrefix = /^-ms-/,3298 rdashAlpha = /-([a-z])/g;3299// Used by camelCase as callback to replace()3300function fcamelCase( all, letter ) {3301 return letter.toUpperCase();3302}3303// Convert dashed to camelCase; used by the css and data modules3304// Support: IE <=9 - 11, Edge 12 - 153305// Microsoft forgot to hump their vendor prefix (#9572)3306function camelCase( string ) {3307 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );3308}3309var acceptData = function( owner ) {3310 // Accepts only:3311 // - Node3312 // - Node.ELEMENT_NODE3313 // - Node.DOCUMENT_NODE3314 // - Object3315 // - Any3316 return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );3317};3318function Data() {3319 this.expando = jQuery.expando + Data.uid++;3320}3321Data.uid = 1;3322Data.prototype = {3323 cache: function( owner ) {3324 // Check if the owner object already has a cache3325 var value = owner[ this.expando ];3326 // If not, create one3327 if ( !value ) {3328 value = {};3329 // We can accept data for non-element nodes in modern browsers,3330 // but we should not, see #8335.3331 // Always return an empty object.3332 if ( acceptData( owner ) ) {3333 // If it is a node unlikely to be stringify-ed or looped over3334 // use plain assignment3335 if ( owner.nodeType ) {3336 owner[ this.expando ] = value;3337 // Otherwise secure it in a non-enumerable property3338 // configurable must be true to allow the property to be3339 // deleted when data is removed3340 } else {3341 Object.defineProperty( owner, this.expando, {3342 value: value,3343 configurable: true3344 } );3345 }3346 }3347 }3348 return value;3349 },3350 set: function( owner, data, value ) {3351 var prop,3352 cache = this.cache( owner );3353 // Handle: [ owner, key, value ] args3354 // Always use camelCase key (gh-2257)3355 if ( typeof data === "string" ) {3356 cache[ camelCase( data ) ] = value;3357 // Handle: [ owner, { properties } ] args3358 } else {3359 // Copy the properties one-by-one to the cache object3360 for ( prop in data ) {3361 cache[ camelCase( prop ) ] = data[ prop ];3362 }3363 }3364 return cache;3365 },3366 get: function( owner, key ) {3367 return key === undefined ?3368 this.cache( owner ) :3369 // Always use camelCase key (gh-2257)3370 owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];3371 },3372 access: function( owner, key, value ) {3373 // In cases where either:3374 //3375 // 1. No key was specified3376 // 2. A string key was specified, but no value provided3377 //3378 // Take the "read" path and allow the get method to determine3379 // which value to return, respectively either:3380 //3381 // 1. The entire cache object3382 // 2. The data stored at the key3383 //3384 if ( key === undefined ||3385 ( ( key && typeof key === "string" ) && value === undefined ) ) {3386 return this.get( owner, key );3387 }3388 // When the key is not a string, or both a key and value3389 // are specified, set or extend (existing objects) with either:3390 //3391 // 1. An object of properties3392 // 2. A key and value3393 //3394 this.set( owner, key, value );3395 // Since the "set" path can have two possible entry points3396 // return the expected data based on which path was taken[*]3397 return value !== undefined ? value : key;3398 },3399 remove: function( owner, key ) {3400 var i,3401 cache = owner[ this.expando ];3402 if ( cache === undefined ) {3403 return;3404 }3405 if ( key !== undefined ) {3406 // Support array or space separated string of keys3407 if ( Array.isArray( key ) ) {3408 // If key is an array of keys...3409 // We always set camelCase keys, so remove that.3410 key = key.map( camelCase );3411 } else {3412 key = camelCase( key );3413 // If a key with the spaces exists, use it.3414 // Otherwise, create an array by matching non-whitespace3415 key = key in cache ?3416 [ key ] :3417 ( key.match( rnothtmlwhite ) || [] );3418 }3419 i = key.length;3420 while ( i-- ) {3421 delete cache[ key[ i ] ];3422 }3423 }3424 // Remove the expando if there's no more data3425 if ( key === undefined || jQuery.isEmptyObject( cache ) ) {3426 // Support: Chrome <=35 - 453427 // Webkit & Blink performance suffers when deleting properties3428 // from DOM nodes, so set to undefined instead3429 // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)3430 if ( owner.nodeType ) {3431 owner[ this.expando ] = undefined;3432 } else {3433 delete owner[ this.expando ];3434 }3435 }3436 },3437 hasData: function( owner ) {3438 var cache = owner[ this.expando ];3439 return cache !== undefined && !jQuery.isEmptyObject( cache );3440 }3441};3442var dataPriv = new Data();3443var dataUser = new Data();3444// Implementation Summary3445//3446// 1. Enforce API surface and semantic compatibility with 1.9.x branch3447// 2. Improve the module's maintainability by reducing the storage3448// paths to a single mechanism.3449// 3. Use the same single mechanism to support "private" and "user" data.3450// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)3451// 5. Avoid exposing implementation details on user objects (eg. expando properties)3452// 6. Provide a clear path for implementation upgrade to WeakMap in 20143453var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,3454 rmultiDash = /[A-Z]/g;3455function getData( data ) {3456 if ( data === "true" ) {3457 return true;3458 }3459 if ( data === "false" ) {3460 return false;3461 }3462 if ( data === "null" ) {3463 return null;3464 }3465 // Only convert to a number if it doesn't change the string3466 if ( data === +data + "" ) {3467 return +data;3468 }3469 if ( rbrace.test( data ) ) {3470 return JSON.parse( data );3471 }3472 return data;3473}3474function dataAttr( elem, key, data ) {3475 var name;3476 // If nothing was found internally, try to fetch any3477 // data from the HTML5 data-* attribute3478 if ( data === undefined && elem.nodeType === 1 ) {3479 name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();3480 data = elem.getAttribute( name );3481 if ( typeof data === "string" ) {3482 try {3483 data = getData( data );3484 } catch ( e ) {}3485 // Make sure we set the data so it isn't changed later3486 dataUser.set( elem, key, data );3487 } else {3488 data = undefined;3489 }3490 }3491 return data;3492}3493jQuery.extend( {3494 hasData: function( elem ) {3495 return dataUser.hasData( elem ) || dataPriv.hasData( elem );3496 },3497 data: function( elem, name, data ) {3498 return dataUser.access( elem, name, data );3499 },3500 removeData: function( elem, name ) {3501 dataUser.remove( elem, name );3502 },3503 // TODO: Now that all calls to _data and _removeData have been replaced3504 // with direct calls to dataPriv methods, these can be deprecated.3505 _data: function( elem, name, data ) {3506 return dataPriv.access( elem, name, data );3507 },3508 _removeData: function( elem, name ) {3509 dataPriv.remove( elem, name );3510 }3511} );3512jQuery.fn.extend( {3513 data: function( key, value ) {3514 var i, name, data,3515 elem = this[ 0 ],3516 attrs = elem && elem.attributes;3517 // Gets all values3518 if ( key === undefined ) {3519 if ( this.length ) {3520 data = dataUser.get( elem );3521 if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {3522 i = attrs.length;3523 while ( i-- ) {3524 // Support: IE 11 only3525 // The attrs elements can be null (#14894)3526 if ( attrs[ i ] ) {3527 name = attrs[ i ].name;3528 if ( name.indexOf( "data-" ) === 0 ) {3529 name = camelCase( name.slice( 5 ) );3530 dataAttr( elem, name, data[ name ] );3531 }3532 }3533 }3534 dataPriv.set( elem, "hasDataAttrs", true );3535 }3536 }3537 return data;3538 }3539 // Sets multiple values3540 if ( typeof key === "object" ) {3541 return this.each( function() {3542 dataUser.set( this, key );3543 } );3544 }3545 return access( this, function( value ) {3546 var data;3547 // The calling jQuery object (element matches) is not empty3548 // (and therefore has an element appears at this[ 0 ]) and the3549 // `value` parameter was not undefined. An empty jQuery object3550 // will result in `undefined` for elem = this[ 0 ] which will3551 // throw an exception if an attempt to read a data cache is made.3552 if ( elem && value === undefined ) {3553 // Attempt to get data from the cache3554 // The key will always be camelCased in Data3555 data = dataUser.get( elem, key );3556 if ( data !== undefined ) {3557 return data;3558 }3559 // Attempt to "discover" the data in3560 // HTML5 custom data-* attrs3561 data = dataAttr( elem, key );3562 if ( data !== undefined ) {3563 return data;3564 }3565 // We tried really hard, but the data doesn't exist.3566 return;3567 }3568 // Set the data...3569 this.each( function() {3570 // We always store the camelCased key3571 dataUser.set( this, key, value );3572 } );3573 }, null, value, arguments.length > 1, null, true );3574 },3575 removeData: function( key ) {3576 return this.each( function() {3577 dataUser.remove( this, key );3578 } );3579 }3580} );3581jQuery.extend( {3582 queue: function( elem, type, data ) {3583 var queue;3584 if ( elem ) {3585 type = ( type || "fx" ) + "queue";3586 queue = dataPriv.get( elem, type );3587 // Speed up dequeue by getting out quickly if this is just a lookup3588 if ( data ) {3589 if ( !queue || Array.isArray( data ) ) {3590 queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );3591 } else {3592 queue.push( data );3593 }3594 }3595 return queue || [];3596 }3597 },3598 dequeue: function( elem, type ) {3599 type = type || "fx";3600 var queue = jQuery.queue( elem, type ),3601 startLength = queue.length,3602 fn = queue.shift(),3603 hooks = jQuery._queueHooks( elem, type ),3604 next = function() {3605 jQuery.dequeue( elem, type );3606 };3607 // If the fx queue is dequeued, always remove the progress sentinel3608 if ( fn === "inprogress" ) {3609 fn = queue.shift();3610 startLength--;3611 }3612 if ( fn ) {3613 // Add a progress sentinel to prevent the fx queue from being3614 // automatically dequeued3615 if ( type === "fx" ) {3616 queue.unshift( "inprogress" );3617 }3618 // Clear up the last queue stop function3619 delete hooks.stop;3620 fn.call( elem, next, hooks );3621 }3622 if ( !startLength && hooks ) {3623 hooks.empty.fire();3624 }3625 },3626 // Not public - generate a queueHooks object, or return the current one3627 _queueHooks: function( elem, type ) {3628 var key = type + "queueHooks";3629 return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {3630 empty: jQuery.callbacks( "once memory" ).add( function() {3631 dataPriv.remove( elem, [ type + "queue", key ] );3632 } )3633 } );3634 }3635} );3636jQuery.fn.extend( {3637 queue: function( type, data ) {3638 var setter = 2;3639 if ( typeof type !== "string" ) {3640 data = type;3641 type = "fx";3642 setter--;3643 }3644 if ( arguments.length < setter ) {3645 return jQuery.queue( this[ 0 ], type );3646 }3647 return data === undefined ?3648 this :3649 this.each( function() {3650 var queue = jQuery.queue( this, type, data );3651 // Ensure a hooks for this queue3652 jQuery._queueHooks( this, type );3653 if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {3654 jQuery.dequeue( this, type );3655 }3656 } );3657 },3658 dequeue: function( type ) {3659 return this.each( function() {3660 jQuery.dequeue( this, type );3661 } );3662 },3663 clearQueue: function( type ) {3664 return this.queue( type || "fx", [] );3665 },3666 // Get a promise resolved when queues of a certain type3667 // are emptied (fx is the type by default)3668 promise: function( type, obj ) {3669 var tmp,3670 count = 1,3671 defer = jQuery.Deferred(),3672 elements = this,3673 i = this.length,3674 resolve = function() {3675 if ( !( --count ) ) {3676 defer.resolveWith( elements, [ elements ] );3677 }3678 };3679 if ( typeof type !== "string" ) {3680 obj = type;3681 type = undefined;3682 }3683 type = type || "fx";3684 while ( i-- ) {3685 tmp = dataPriv.get( elements[ i ], type + "queueHooks" );3686 if ( tmp && tmp.empty ) {3687 count++;3688 tmp.empty.add( resolve );3689 }3690 }3691 resolve();3692 return defer.promise( obj );3693 }3694} );3695var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;3696var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );3697var cssExpand = [ "Top", "Right", "Bottom", "Left" ];3698var documentElement = document.documentElement;3699 var isAttached = function( elem ) {3700 return jQuery.contains( elem.ownerDocument, elem );3701 },3702 composed = { composed: true };3703 // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only3704 // Check attachment across shadow DOM boundaries when possible (gh-3504)3705 // Support: iOS 10.0-10.2 only3706 // Early iOS 10 versions support `attachShadow` but not `getRootNode`,3707 // leading to errors. We need to check for `getRootNode`.3708 if ( documentElement.getRootNode ) {3709 isAttached = function( elem ) {3710 return jQuery.contains( elem.ownerDocument, elem ) ||3711 elem.getRootNode( composed ) === elem.ownerDocument;3712 };3713 }3714var isHiddenWithinTree = function( elem, el ) {3715 // isHiddenWithinTree might be called from jQuery#filter function;3716 // in that case, element will be second argument3717 elem = el || elem;3718 // Inline style trumps all3719 return elem.style.display === "none" ||3720 elem.style.display === "" &&3721 // Otherwise, check computed style3722 // Support: Firefox <=43 - 453723 // Disconnected elements can have computed display: none, so first confirm that elem is3724 // in the document.3725 isAttached( elem ) &&3726 jQuery.css( elem, "display" ) === "none";3727 };3728var swap = function( elem, options, callback, args ) {3729 var ret, name,3730 old = {};3731 // Remember the old values, and insert the new ones3732 for ( name in options ) {3733 old[ name ] = elem.style[ name ];3734 elem.style[ name ] = options[ name ];3735 }3736 ret = callback.apply( elem, args || [] );3737 // Revert the old values3738 for ( name in options ) {3739 elem.style[ name ] = old[ name ];3740 }3741 return ret;3742};3743function adjustCSS( elem, prop, valueParts, tween ) {3744 var adjusted, scale,3745 maxIterations = 20,3746 currentValue = tween ?3747 function() {3748 return tween.cur();3749 } :3750 function() {3751 return jQuery.css( elem, prop, "" );3752 },3753 initial = currentValue(),3754 unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),3755 // Starting value computation is required for potential unit mismatches3756 initialInUnit = elem.nodeType &&3757 ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&3758 rcssNum.exec( jQuery.css( elem, prop ) );3759 if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {3760 // Support: Firefox <=543761 // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)3762 initial = initial / 2;3763 // Trust units reported by jQuery.css3764 unit = unit || initialInUnit[ 3 ];3765 // Iteratively approximate from a nonzero starting point3766 initialInUnit = +initial || 1;3767 while ( maxIterations-- ) {3768 // Evaluate and update our best guess (doubling guesses that zero out).3769 // Finish if the scale equals or crosses 1 (making the old*new product non-positive).3770 jQuery.style( elem, prop, initialInUnit + unit );3771 if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {3772 maxIterations = 0;3773 }3774 initialInUnit = initialInUnit / scale;3775 }3776 initialInUnit = initialInUnit * 2;3777 jQuery.style( elem, prop, initialInUnit + unit );3778 // Make sure we update the tween properties later on3779 valueParts = valueParts || [];3780 }3781 if ( valueParts ) {3782 initialInUnit = +initialInUnit || +initial || 0;3783 // Apply relative offset (+=/-=) if specified3784 adjusted = valueParts[ 1 ] ?3785 initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :3786 +valueParts[ 2 ];3787 if ( tween ) {3788 tween.unit = unit;3789 tween.start = initialInUnit;3790 tween.end = adjusted;3791 }3792 }3793 return adjusted;3794}3795var defaultDisplayMap = {};3796function getDefaultDisplay( elem ) {3797 var temp,3798 doc = elem.ownerDocument,3799 nodeName = elem.nodeName,3800 display = defaultDisplayMap[ nodeName ];3801 if ( display ) {3802 return display;3803 }3804 temp = doc.body.appendChild( doc.createElement( nodeName ) );3805 display = jQuery.css( temp, "display" );3806 temp.parentNode.removeChild( temp );3807 if ( display === "none" ) {3808 display = "block";3809 }3810 defaultDisplayMap[ nodeName ] = display;3811 return display;3812}3813function showHide( elements, show ) {3814 var display, elem,3815 values = [],3816 index = 0,3817 length = elements.length;3818 // Determine new display value for elements that need to change3819 for ( ; index < length; index++ ) {3820 elem = elements[ index ];3821 if ( !elem.style ) {3822 continue;3823 }3824 display = elem.style.display;3825 if ( show ) {3826 // Since we force visibility upon cascade-hidden elements, an immediate (and slow)3827 // check is required in this first loop unless we have a nonempty display value (either3828 // inline or about-to-be-restored)3829 if ( display === "none" ) {3830 values[ index ] = dataPriv.get( elem, "display" ) || null;3831 if ( !values[ index ] ) {3832 elem.style.display = "";3833 }3834 }3835 if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {3836 values[ index ] = getDefaultDisplay( elem );3837 }3838 } else {3839 if ( display !== "none" ) {3840 values[ index ] = "none";3841 // Remember what we're overwriting3842 dataPriv.set( elem, "display", display );3843 }3844 }3845 }3846 // Set the display of the elements in a second loop to avoid constant reflow3847 for ( index = 0; index < length; index++ ) {3848 if ( values[ index ] != null ) {3849 elements[ index ].style.display = values[ index ];3850 }3851 }3852 return elements;3853}3854jQuery.fn.extend( {3855 show: function() {3856 return showHide( this, true );3857 },3858 hide: function() {3859 return showHide( this );3860 },3861 toggle: function( state ) {3862 if ( typeof state === "boolean" ) {3863 return state ? this.show() : this.hide();3864 }3865 return this.each( function() {3866 if ( isHiddenWithinTree( this ) ) {3867 jQuery( this ).show();3868 } else {3869 jQuery( this ).hide();3870 }3871 } );3872 }3873} );3874var rcheckableType = ( /^(?:checkbox|radio)$/i );3875var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i );3876var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i );3877// We have to close these tags to support XHTML (#13200)3878var wrapMap = {3879 // Support: IE <=9 only3880 option: [ 1, "<select multiple='multiple'>", "</select>" ],3881 // XHTML parsers do not magically insert elements in the3882 // same way that tag soup parsers do. So we cannot shorten3883 // this by omitting <tbody> or other required elements.3884 thead: [ 1, "<table>", "</table>" ],3885 col: [ 2, "<table><colgroup>", "</colgroup></table>" ],3886 tr: [ 2, "<table><tbody>", "</tbody></table>" ],3887 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],3888 _default: [ 0, "", "" ]3889};3890// Support: IE <=9 only3891wrapMap.optgroup = wrapMap.option;3892wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;3893wrapMap.th = wrapMap.td;3894function getAll( context, tag ) {3895 // Support: IE <=9 - 11 only3896 // Use typeof to avoid zero-argument method invocation on host objects (#15151)3897 var ret;3898 if ( typeof context.getElementsByTagName !== "undefined" ) {3899 ret = context.getElementsByTagName( tag || "*" );3900 } else if ( typeof context.querySelectorAll !== "undefined" ) {3901 ret = context.querySelectorAll( tag || "*" );3902 } else {3903 ret = [];3904 }3905 if ( tag === undefined || tag && nodeName( context, tag ) ) {3906 return jQuery.merge( [ context ], ret );3907 }3908 return ret;3909}3910// Mark scripts as having already been evaluated3911function setGlobalEval( elems, refElements ) {3912 var i = 0,3913 l = elems.length;3914 for ( ; i < l; i++ ) {3915 dataPriv.set(3916 elems[ i ],3917 "globalEval",3918 !refElements || dataPriv.get( refElements[ i ], "globalEval" )3919 );3920 }3921}3922var rhtml = /<|&#?\w+;/;3923function buildFragment( elems, context, scripts, selection, ignored ) {3924 var elem, tmp, tag, wrap, attached, j,3925 fragment = context.createDocumentFragment(),3926 nodes = [],3927 i = 0,3928 l = elems.length;3929 for ( ; i < l; i++ ) {3930 elem = elems[ i ];3931 if ( elem || elem === 0 ) {3932 // Add nodes directly3933 if ( toType( elem ) === "object" ) {3934 // Support: Android <=4.0 only, PhantomJS 1 only3935 // push.apply(_, arraylike) throws on ancient WebKit3936 jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );3937 // Convert non-html into a text node3938 } else if ( !rhtml.test( elem ) ) {3939 nodes.push( context.createTextNode( elem ) );3940 // Convert html into DOM nodes3941 } else {3942 tmp = tmp || fragment.appendChild( context.createElement( "div" ) );3943 // Deserialize a standard representation3944 tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();3945 wrap = wrapMap[ tag ] || wrapMap._default;3946 tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];3947 // Descend through wrappers to the right content3948 j = wrap[ 0 ];3949 while ( j-- ) {3950 tmp = tmp.lastChild;3951 }3952 // Support: Android <=4.0 only, PhantomJS 1 only3953 // push.apply(_, arraylike) throws on ancient WebKit3954 jQuery.merge( nodes, tmp.childNodes );3955 // Remember the top-level container3956 tmp = fragment.firstChild;3957 // Ensure the created nodes are orphaned (#12392)3958 tmp.textContent = "";3959 }3960 }3961 }3962 // Remove wrapper from fragment3963 fragment.textContent = "";3964 i = 0;3965 while ( ( elem = nodes[ i++ ] ) ) {3966 // Skip elements already in the context collection (trac-4087)3967 if ( selection && jQuery.inArray( elem, selection ) > -1 ) {3968 if ( ignored ) {3969 ignored.push( elem );3970 }3971 continue;3972 }3973 attached = isAttached( elem );3974 // Append to fragment3975 tmp = getAll( fragment.appendChild( elem ), "script" );3976 // Preserve script evaluation history3977 if ( attached ) {3978 setGlobalEval( tmp );3979 }3980 // Capture executables3981 if ( scripts ) {3982 j = 0;3983 while ( ( elem = tmp[ j++ ] ) ) {3984 if ( rscriptType.test( elem.type || "" ) ) {3985 scripts.push( elem );3986 }3987 }3988 }3989 }3990 return fragment;3991}3992( function() {3993 var fragment = document.createDocumentFragment(),3994 div = fragment.appendChild( document.createElement( "div" ) ),3995 input = document.createElement( "input" );3996 // Support: Android 4.0 - 4.3 only3997 // Check state lost if the name is set (#11217)3998 // Support: Windows Web Apps (WWA)3999 // `name` and `type` must use .setAttribute for WWA (#14901)4000 input.setAttribute( "type", "radio" );4001 input.setAttribute( "checked", "checked" );4002 input.setAttribute( "name", "t" );4003 div.appendChild( input );4004 // Support: Android <=4.1 only4005 // Older WebKit doesn't clone checked state correctly in fragments4006 support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;4007 // Support: IE <=11 only4008 // Make sure textarea (and checkbox) defaultValue is properly cloned4009 div.innerHTML = "<textarea>x</textarea>";4010 support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;4011} )();4012var4013 rkeyEvent = /^key/,4014 rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,4015 rtypenamespace = /^([^.]*)(?:\.(.+)|)/;4016function returnTrue() {4017 return true;4018}4019function returnFalse() {4020 return false;4021}4022// Support: IE <=9 - 11+4023// focus() and blur() are asynchronous, except when they are no-op.4024// So expect focus to be synchronous when the element is already active,4025// and blur to be synchronous when the element is not already active.4026// (focus and blur are always synchronous in other supported browsers,4027// this just defines when we can count on it).4028function expectSync( elem, type ) {4029 return ( elem === safeActiveElement() ) === ( type === "focus" );4030}4031// Support: IE <=9 only4032// Accessing document.activeElement can throw unexpectedly4033// https://bugs.jquery.com/ticket/133934034function safeActiveElement() {4035 try {4036 return document.activeElement;4037 } catch ( err ) { }4038}4039function on( elem, types, selector, data, fn, one ) {4040 var origFn, type;4041 // Types can be a map of types/handlers4042 if ( typeof types === "object" ) {4043 // ( types-Object, selector, data )4044 if ( typeof selector !== "string" ) {4045 // ( types-Object, data )4046 data = data || selector;4047 selector = undefined;4048 }4049 for ( type in types ) {4050 on( elem, type, selector, data, types[ type ], one );4051 }4052 return elem;4053 }4054 if ( data == null && fn == null ) {4055 // ( types, fn )4056 fn = selector;4057 data = selector = undefined;4058 } else if ( fn == null ) {4059 if ( typeof selector === "string" ) {4060 // ( types, selector, fn )4061 fn = data;4062 data = undefined;4063 } else {4064 // ( types, data, fn )4065 fn = data;4066 data = selector;4067 selector = undefined;4068 }4069 }4070 if ( fn === false ) {4071 fn = returnFalse;4072 } else if ( !fn ) {4073 return elem;4074 }4075 if ( one === 1 ) {4076 origFn = fn;4077 fn = function( event ) {4078 // Can use an empty set, since event contains the info4079 jQuery().off( event );4080 return origFn.apply( this, arguments );4081 };4082 // Use same guid so caller can remove using origFn4083 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );4084 }4085 return elem.each( function() {4086 jQuery.event.add( this, types, fn, data, selector );4087 } );4088}4089/*4090 * Helper functions for managing events -- not part of the public interface.4091 * Props to Dean Edwards' addEvent library for many of the ideas.4092 */4093jQuery.event = {4094 global: {},4095 add: function( elem, types, handler, data, selector ) {4096 var handleObjIn, eventHandle, tmp,4097 events, t, handleObj,4098 special, handlers, type, namespaces, origType,4099 elemData = dataPriv.get( elem );4100 // Don't attach events to noData or text/comment nodes (but allow plain objects)4101 if ( !elemData ) {4102 return;4103 }4104 // Caller can pass in an object of custom data in lieu of the handler4105 if ( handler.handler ) {4106 handleObjIn = handler;4107 handler = handleObjIn.handler;4108 selector = handleObjIn.selector;4109 }4110 // Ensure that invalid selectors throw exceptions at attach time4111 // Evaluate against documentElement in case elem is a non-element node (e.g., document)4112 if ( selector ) {4113 jQuery.find.matchesSelector( documentElement, selector );4114 }4115 // Make sure that the handler has a unique ID, used to find/remove it later4116 if ( !handler.guid ) {4117 handler.guid = jQuery.guid++;4118 }4119 // Init the element's event structure and main handler, if this is the first4120 if ( !( events = elemData.events ) ) {4121 events = elemData.events = {};4122 }4123 if ( !( eventHandle = elemData.handle ) ) {4124 eventHandle = elemData.handle = function( e ) {4125 // Discard the second event of a jQuery.event.trigger() and4126 // when an event is called after a page has unloaded4127 return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?4128 jQuery.event.dispatch.apply( elem, arguments ) : undefined;4129 };4130 }4131 // Handle multiple events separated by a space4132 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];4133 t = types.length;4134 while ( t-- ) {4135 tmp = rtypenamespace.exec( types[ t ] ) || [];4136 type = origType = tmp[ 1 ];4137 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();4138 // There *must* be a type, no attaching namespace-only handlers4139 if ( !type ) {4140 continue;4141 }4142 // If event changes its type, use the special event handlers for the changed type4143 special = jQuery.event.special[ type ] || {};4144 // If selector defined, determine special event api type, otherwise given type4145 type = ( selector ? special.delegateType : special.bindType ) || type;4146 // Update special based on newly reset type4147 special = jQuery.event.special[ type ] || {};4148 // handleObj is passed to all event handlers4149 handleObj = jQuery.extend( {4150 type: type,4151 origType: origType,4152 data: data,4153 handler: handler,4154 guid: handler.guid,4155 selector: selector,4156 needsContext: selector && jQuery.expr.match.needsContext.test( selector ),4157 namespace: namespaces.join( "." )4158 }, handleObjIn );4159 // Init the event handler queue if we're the first4160 if ( !( handlers = events[ type ] ) ) {4161 handlers = events[ type ] = [];4162 handlers.delegateCount = 0;4163 // Only use addEventListener if the special events handler returns false4164 if ( !special.setup ||4165 special.setup.call( elem, data, namespaces, eventHandle ) === false ) {4166 if ( elem.addEventListener ) {4167 elem.addEventListener( type, eventHandle );4168 }4169 }4170 }4171 if ( special.add ) {4172 special.add.call( elem, handleObj );4173 if ( !handleObj.handler.guid ) {4174 handleObj.handler.guid = handler.guid;4175 }4176 }4177 // Add to the element's handler list, delegates in front4178 if ( selector ) {4179 handlers.splice( handlers.delegateCount++, 0, handleObj );4180 } else {4181 handlers.push( handleObj );4182 }4183 // Keep track of which events have ever been used, for event optimization4184 jQuery.event.global[ type ] = true;4185 }4186 },4187 // Detach an event or set of events from an element4188 remove: function( elem, types, handler, selector, mappedTypes ) {4189 var j, origCount, tmp,4190 events, t, handleObj,4191 special, handlers, type, namespaces, origType,4192 elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );4193 if ( !elemData || !( events = elemData.events ) ) {4194 return;4195 }4196 // Once for each type.namespace in types; type may be omitted4197 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];4198 t = types.length;4199 while ( t-- ) {4200 tmp = rtypenamespace.exec( types[ t ] ) || [];4201 type = origType = tmp[ 1 ];4202 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();4203 // Unbind all events (on this namespace, if provided) for the element4204 if ( !type ) {4205 for ( type in events ) {4206 jQuery.event.remove( elem, type + types[ t ], handler, selector, true );4207 }4208 continue;4209 }4210 special = jQuery.event.special[ type ] || {};4211 type = ( selector ? special.delegateType : special.bindType ) || type;4212 handlers = events[ type ] || [];4213 tmp = tmp[ 2 ] &&4214 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );4215 // Remove matching events4216 origCount = j = handlers.length;4217 while ( j-- ) {4218 handleObj = handlers[ j ];4219 if ( ( mappedTypes || origType === handleObj.origType ) &&4220 ( !handler || handler.guid === handleObj.guid ) &&4221 ( !tmp || tmp.test( handleObj.namespace ) ) &&4222 ( !selector || selector === handleObj.selector ||4223 selector === "**" && handleObj.selector ) ) {4224 handlers.splice( j, 1 );4225 if ( handleObj.selector ) {4226 handlers.delegateCount--;4227 }4228 if ( special.remove ) {4229 special.remove.call( elem, handleObj );4230 }4231 }4232 }4233 // Remove generic event handler if we removed something and no more handlers exist4234 // (avoids potential for endless recursion during removal of special event handlers)4235 if ( origCount && !handlers.length ) {4236 if ( !special.teardown ||4237 special.teardown.call( elem, namespaces, elemData.handle ) === false ) {4238 jQuery.removeEvent( elem, type, elemData.handle );4239 }4240 delete events[ type ];4241 }4242 }4243 // Remove data and the expando if it's no longer used4244 if ( jQuery.isEmptyObject( events ) ) {4245 dataPriv.remove( elem, "handle events" );4246 }4247 },4248 dispatch: function( nativeEvent ) {4249 // Make a writable jQuery.Event from the native event object4250 var event = jQuery.event.fix( nativeEvent );4251 var i, j, ret, matched, handleObj, handlerQueue,4252 args = new Array( arguments.length ),4253 handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],4254 special = jQuery.event.special[ event.type ] || {};4255 // Use the fix-ed jQuery.Event rather than the (read-only) native event4256 args[ 0 ] = event;4257 for ( i = 1; i < arguments.length; i++ ) {4258 args[ i ] = arguments[ i ];4259 }4260 event.delegateTarget = this;4261 // Call the preDispatch hook for the mapped type, and let it bail if desired4262 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {4263 return;4264 }4265 // Determine handlers4266 handlerQueue = jQuery.event.handlers.call( this, event, handlers );4267 // Run delegates first; they may want to stop propagation beneath us4268 i = 0;4269 while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {4270 event.currentTarget = matched.elem;4271 j = 0;4272 while ( ( handleObj = matched.handlers[ j++ ] ) &&4273 !event.isImmediatePropagationStopped() ) {4274 // If the event is namespaced, then each handler is only invoked if it is4275 // specially universal or its namespaces are a superset of the event's.4276 if ( !event.rnamespace || handleObj.namespace === false ||4277 event.rnamespace.test( handleObj.namespace ) ) {4278 event.handleObj = handleObj;4279 event.data = handleObj.data;4280 ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||4281 handleObj.handler ).apply( matched.elem, args );4282 if ( ret !== undefined ) {4283 if ( ( event.result = ret ) === false ) {4284 event.preventDefault();4285 event.stopPropagation();4286 }4287 }4288 }4289 }4290 }4291 // Call the postDispatch hook for the mapped type4292 if ( special.postDispatch ) {4293 special.postDispatch.call( this, event );4294 }4295 return event.result;4296 },4297 handlers: function( event, handlers ) {4298 var i, handleObj, sel, matchedHandlers, matchedSelectors,4299 handlerQueue = [],4300 delegateCount = handlers.delegateCount,4301 cur = event.target;4302 // Find delegate handlers4303 if ( delegateCount &&4304 // Support: IE <=94305 // Black-hole SVG <use> instance trees (trac-13180)4306 cur.nodeType &&4307 // Support: Firefox <=424308 // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)4309 // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click4310 // Support: IE 11 only4311 // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)4312 !( event.type === "click" && event.button >= 1 ) ) {4313 for ( ; cur !== this; cur = cur.parentNode || this ) {4314 // Don't check non-elements (#13208)4315 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)4316 if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {4317 matchedHandlers = [];4318 matchedSelectors = {};4319 for ( i = 0; i < delegateCount; i++ ) {4320 handleObj = handlers[ i ];4321 // Don't conflict with Object.prototype properties (#13203)4322 sel = handleObj.selector + " ";4323 if ( matchedSelectors[ sel ] === undefined ) {4324 matchedSelectors[ sel ] = handleObj.needsContext ?4325 jQuery( sel, this ).index( cur ) > -1 :4326 jQuery.find( sel, this, null, [ cur ] ).length;4327 }4328 if ( matchedSelectors[ sel ] ) {4329 matchedHandlers.push( handleObj );4330 }4331 }4332 if ( matchedHandlers.length ) {4333 handlerQueue.push( { elem: cur, handlers: matchedHandlers } );4334 }4335 }4336 }4337 }4338 // Add the remaining (directly-bound) handlers4339 cur = this;4340 if ( delegateCount < handlers.length ) {4341 handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );4342 }4343 return handlerQueue;4344 },4345 addProp: function( name, hook ) {4346 Object.defineProperty( jQuery.Event.prototype, name, {4347 enumerable: true,4348 configurable: true,4349 get: isFunction( hook ) ?4350 function() {4351 if ( this.originalEvent ) {4352 return hook( this.originalEvent );4353 }4354 } :4355 function() {4356 if ( this.originalEvent ) {4357 return this.originalEvent[ name ];4358 }4359 },4360 set: function( value ) {4361 Object.defineProperty( this, name, {4362 enumerable: true,4363 configurable: true,4364 writable: true,4365 value: value4366 } );4367 }4368 } );4369 },4370 fix: function( originalEvent ) {4371 return originalEvent[ jQuery.expando ] ?4372 originalEvent :4373 new jQuery.Event( originalEvent );4374 },4375 special: {4376 load: {4377 // Prevent triggered image.load events from bubbling to window.load4378 noBubble: true4379 },4380 click: {4381 // Utilize native event to ensure correct state for checkable inputs4382 setup: function( data ) {4383 // For mutual compressibility with _default, replace `this` access with a local var.4384 // `|| data` is dead code meant only to preserve the variable through minification.4385 var el = this || data;4386 // Claim the first handler4387 if ( rcheckableType.test( el.type ) &&4388 el.click && nodeName( el, "input" ) ) {4389 // dataPriv.set( el, "click", ... )4390 leverageNative( el, "click", returnTrue );4391 }4392 // Return false to allow normal processing in the caller4393 return false;4394 },4395 trigger: function( data ) {4396 // For mutual compressibility with _default, replace `this` access with a local var.4397 // `|| data` is dead code meant only to preserve the variable through minification.4398 var el = this || data;4399 // Force setup before triggering a click4400 if ( rcheckableType.test( el.type ) &&4401 el.click && nodeName( el, "input" ) ) {4402 leverageNative( el, "click" );4403 }4404 // Return non-false to allow normal event-path propagation4405 return true;4406 },4407 // For cross-browser consistency, suppress native .click() on links4408 // Also prevent it if we're currently inside a leveraged native-event stack4409 _default: function( event ) {4410 var target = event.target;4411 return rcheckableType.test( target.type ) &&4412 target.click && nodeName( target, "input" ) &&4413 dataPriv.get( target, "click" ) ||4414 nodeName( target, "a" );4415 }4416 },4417 beforeunload: {4418 postDispatch: function( event ) {4419 // Support: Firefox 20+4420 // Firefox doesn't alert if the returnValue field is not set.4421 if ( event.result !== undefined && event.originalEvent ) {4422 event.originalEvent.returnValue = event.result;4423 }4424 }4425 }4426 }4427};4428// Ensure the presence of an event listener that handles manually-triggered4429// synthetic events by interrupting progress until reinvoked in response to4430// *native* events that it fires directly, ensuring that state changes have4431// already occurred before other listeners are invoked.4432function leverageNative( el, type, expectSync ) {4433 // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add4434 if ( !expectSync ) {4435 if ( dataPriv.get( el, type ) === undefined ) {4436 jQuery.event.add( el, type, returnTrue );4437 }4438 return;4439 }4440 // Register the controller as a special universal handler for all event namespaces4441 dataPriv.set( el, type, false );4442 jQuery.event.add( el, type, {4443 namespace: false,4444 handler: function( event ) {4445 var notAsync, result,4446 saved = dataPriv.get( this, type );4447 if ( ( event.isTrigger & 1 ) && this[ type ] ) {4448 // Interrupt processing of the outer synthetic .trigger()ed event4449 // Saved data should be false in such cases, but might be a leftover capture object4450 // from an async native handler (gh-4350)4451 if ( !saved.length ) {4452 // Store arguments for use when handling the inner native event4453 // There will always be at least one argument (an event object), so this array4454 // will not be confused with a leftover capture object.4455 saved = slice.call( arguments );4456 dataPriv.set( this, type, saved );4457 // Trigger the native event and capture its result4458 // Support: IE <=9 - 11+4459 // focus() and blur() are asynchronous4460 notAsync = expectSync( this, type );4461 this[ type ]();4462 result = dataPriv.get( this, type );4463 if ( saved !== result || notAsync ) {4464 dataPriv.set( this, type, false );4465 } else {4466 result = {};4467 }4468 if ( saved !== result ) {4469 // Cancel the outer synthetic event4470 event.stopImmediatePropagation();4471 event.preventDefault();4472 return result.value;4473 }4474 // If this is an inner synthetic event for an event with a bubbling surrogate4475 // (focus or blur), assume that the surrogate already propagated from triggering the4476 // native event and prevent that from happening again here.4477 // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the4478 // bubbling surrogate propagates *after* the non-bubbling base), but that seems4479 // less bad than duplication.4480 } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {4481 event.stopPropagation();4482 }4483 // If this is a native event triggered above, everything is now in order4484 // Fire an inner synthetic event with the original arguments4485 } else if ( saved.length ) {4486 // ...and capture the result4487 dataPriv.set( this, type, {4488 value: jQuery.event.trigger(4489 // Support: IE <=9 - 11+4490 // Extend with the prototype to reset the above stopImmediatePropagation()4491 jQuery.extend( saved[ 0 ], jQuery.Event.prototype ),4492 saved.slice( 1 ),4493 this4494 )4495 } );4496 // Abort handling of the native event4497 event.stopImmediatePropagation();4498 }4499 }4500 } );4501}4502jQuery.removeEvent = function( elem, type, handle ) {4503 // This "if" is needed for plain objects4504 if ( elem.removeEventListener ) {4505 elem.removeEventListener( type, handle );4506 }4507};4508jQuery.Event = function( src, props ) {4509 // Allow instantiation without the 'new' keyword4510 if ( !( this instanceof jQuery.Event ) ) {4511 return new jQuery.Event( src, props );4512 }4513 // Event object4514 if ( src && src.type ) {4515 this.originalEvent = src;4516 this.type = src.type;4517 // Events bubbling up the document may have been marked as prevented4518 // by a handler lower down the tree; reflect the correct value.4519 this.isDefaultPrevented = src.defaultPrevented ||4520 src.defaultPrevented === undefined &&4521 // Support: Android <=2.3 only4522 src.returnValue === false ?4523 returnTrue :4524 returnFalse;4525 // Create target properties4526 // Support: Safari <=6 - 7 only4527 // Target should not be a text node (#504, #13143)4528 this.target = ( src.target && src.target.nodeType === 3 ) ?4529 src.target.parentNode :4530 src.target;4531 this.currentTarget = src.currentTarget;4532 this.relatedTarget = src.relatedTarget;4533 // Event type4534 } else {4535 this.type = src;4536 }4537 // Put explicitly provided properties onto the event object4538 if ( props ) {4539 jQuery.extend( this, props );4540 }4541 // Create a timestamp if incoming event doesn't have one4542 this.timeStamp = src && src.timeStamp || Date.now();4543 // Mark it as fixed4544 this[ jQuery.expando ] = true;4545};4546// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding4547// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html4548jQuery.Event.prototype = {4549 constructor: jQuery.Event,4550 isDefaultPrevented: returnFalse,4551 isPropagationStopped: returnFalse,4552 isImmediatePropagationStopped: returnFalse,4553 isSimulated: false,4554 preventDefault: function() {4555 var e = this.originalEvent;4556 this.isDefaultPrevented = returnTrue;4557 if ( e && !this.isSimulated ) {4558 e.preventDefault();4559 }4560 },4561 stopPropagation: function() {4562 var e = this.originalEvent;4563 this.isPropagationStopped = returnTrue;4564 if ( e && !this.isSimulated ) {4565 e.stopPropagation();4566 }4567 },4568 stopImmediatePropagation: function() {4569 var e = this.originalEvent;4570 this.isImmediatePropagationStopped = returnTrue;4571 if ( e && !this.isSimulated ) {4572 e.stopImmediatePropagation();4573 }4574 this.stopPropagation();4575 }4576};4577// Includes all common event props including KeyEvent and MouseEvent specific props4578jQuery.each( {4579 altKey: true,4580 bubbles: true,4581 cancelable: true,4582 changedTouches: true,4583 ctrlKey: true,4584 detail: true,4585 eventPhase: true,4586 metaKey: true,4587 pageX: true,4588 pageY: true,4589 shiftKey: true,4590 view: true,4591 "char": true,4592 code: true,4593 charCode: true,4594 key: true,4595 keyCode: true,4596 button: true,4597 buttons: true,4598 clientX: true,4599 clientY: true,4600 offsetX: true,4601 offsetY: true,4602 pointerId: true,4603 pointerType: true,4604 screenX: true,4605 screenY: true,4606 targetTouches: true,4607 toElement: true,4608 touches: true,4609 which: function( event ) {4610 var button = event.button;4611 // Add which for key events4612 if ( event.which == null && rkeyEvent.test( event.type ) ) {4613 return event.charCode != null ? event.charCode : event.keyCode;4614 }4615 // Add which for click: 1 === left; 2 === middle; 3 === right4616 if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {4617 if ( button & 1 ) {4618 return 1;4619 }4620 if ( button & 2 ) {4621 return 3;4622 }4623 if ( button & 4 ) {4624 return 2;4625 }4626 return 0;4627 }4628 return event.which;4629 }4630}, jQuery.event.addProp );4631jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) {4632 jQuery.event.special[ type ] = {4633 // Utilize native event if possible so blur/focus sequence is correct4634 setup: function() {4635 // Claim the first handler4636 // dataPriv.set( this, "focus", ... )4637 // dataPriv.set( this, "blur", ... )4638 leverageNative( this, type, expectSync );4639 // Return false to allow normal processing in the caller4640 return false;4641 },4642 trigger: function() {4643 // Force setup before trigger4644 leverageNative( this, type );4645 // Return non-false to allow normal event-path propagation4646 return true;4647 },4648 delegateType: delegateType4649 };4650} );4651// Create mouseenter/leave events using mouseover/out and event-time checks4652// so that event delegation works in jQuery.4653// Do the same for pointerenter/pointerleave and pointerover/pointerout4654//4655// Support: Safari 7 only4656// Safari sends mouseenter too often; see:4657// https://bugs.chromium.org/p/chromium/issues/detail?id=4702584658// for the description of the bug (it existed in older Chrome versions as well).4659jQuery.each( {4660 mouseenter: "mouseover",4661 mouseleave: "mouseout",4662 pointerenter: "pointerover",4663 pointerleave: "pointerout"4664}, function( orig, fix ) {4665 jQuery.event.special[ orig ] = {4666 delegateType: fix,4667 bindType: fix,4668 handle: function( event ) {4669 var ret,4670 target = this,4671 related = event.relatedTarget,4672 handleObj = event.handleObj;4673 // For mouseenter/leave call the handler if related is outside the target.4674 // NB: No relatedTarget if the mouse left/entered the browser window4675 if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {4676 event.type = handleObj.origType;4677 ret = handleObj.handler.apply( this, arguments );4678 event.type = fix;4679 }4680 return ret;4681 }4682 };4683} );4684jQuery.fn.extend( {4685 on: function( types, selector, data, fn ) {4686 return on( this, types, selector, data, fn );4687 },4688 one: function( types, selector, data, fn ) {4689 return on( this, types, selector, data, fn, 1 );4690 },4691 off: function( types, selector, fn ) {4692 var handleObj, type;4693 if ( types && types.preventDefault && types.handleObj ) {4694 // ( event ) dispatched jQuery.Event4695 handleObj = types.handleObj;4696 jQuery( types.delegateTarget ).off(4697 handleObj.namespace ?4698 handleObj.origType + "." + handleObj.namespace :4699 handleObj.origType,4700 handleObj.selector,4701 handleObj.handler4702 );4703 return this;4704 }4705 if ( typeof types === "object" ) {4706 // ( types-object [, selector] )4707 for ( type in types ) {4708 this.off( type, selector, types[ type ] );4709 }4710 return this;4711 }4712 if ( selector === false || typeof selector === "function" ) {4713 // ( types [, fn] )4714 fn = selector;4715 selector = undefined;4716 }4717 if ( fn === false ) {4718 fn = returnFalse;4719 }4720 return this.each( function() {4721 jQuery.event.remove( this, types, fn, selector );4722 } );4723 }4724} );4725var4726 /* eslint-disable max-len */4727 // See https://github.com/eslint/eslint/issues/32294728 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,4729 /* eslint-enable */4730 // Support: IE <=10 - 11, Edge 12 - 13 only4731 // In IE/Edge using regex groups here causes severe slowdowns.4732 // See https://connect.microsoft.com/IE/feedback/details/1736512/4733 rnoInnerhtml = /<script|<style|<link/i,4734 // checked="checked" or checked4735 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,4736 rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;4737// Prefer a tbody over its parent table for containing new rows4738function manipulationTarget( elem, content ) {4739 if ( nodeName( elem, "table" ) &&4740 nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {4741 return jQuery( elem ).children( "tbody" )[ 0 ] || elem;4742 }4743 return elem;4744}4745// Replace/restore the type attribute of script elements for safe DOM manipulation4746function disableScript( elem ) {4747 elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;4748 return elem;4749}4750function restoreScript( elem ) {4751 if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) {4752 elem.type = elem.type.slice( 5 );4753 } else {4754 elem.removeAttribute( "type" );4755 }4756 return elem;4757}4758function cloneCopyEvent( src, dest ) {4759 var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;4760 if ( dest.nodeType !== 1 ) {4761 return;4762 }4763 // 1. Copy private data: events, handlers, etc.4764 if ( dataPriv.hasData( src ) ) {4765 pdataOld = dataPriv.access( src );4766 pdataCur = dataPriv.set( dest, pdataOld );4767 events = pdataOld.events;4768 if ( events ) {4769 delete pdataCur.handle;4770 pdataCur.events = {};4771 for ( type in events ) {4772 for ( i = 0, l = events[ type ].length; i < l; i++ ) {4773 jQuery.event.add( dest, type, events[ type ][ i ] );4774 }4775 }4776 }4777 }4778 // 2. Copy user data4779 if ( dataUser.hasData( src ) ) {4780 udataOld = dataUser.access( src );4781 udataCur = jQuery.extend( {}, udataOld );4782 dataUser.set( dest, udataCur );4783 }4784}4785// Fix IE bugs, see support tests4786function fixInput( src, dest ) {4787 var nodeName = dest.nodeName.toLowerCase();4788 // Fails to persist the checked state of a cloned checkbox or radio button.4789 if ( nodeName === "input" && rcheckableType.test( src.type ) ) {4790 dest.checked = src.checked;4791 // Fails to return the selected option to the default selected state when cloning options4792 } else if ( nodeName === "input" || nodeName === "textarea" ) {4793 dest.defaultValue = src.defaultValue;4794 }4795}4796function domManip( collection, args, callback, ignored ) {4797 // Flatten any nested arrays4798 args = concat.apply( [], args );4799 var fragment, first, scripts, hasScripts, node, doc,4800 i = 0,4801 l = collection.length,4802 iNoClone = l - 1,4803 value = args[ 0 ],4804 valueIsFunction = isFunction( value );4805 // We can't cloneNode fragments that contain checked, in WebKit4806 if ( valueIsFunction ||4807 ( l > 1 && typeof value === "string" &&4808 !support.checkClone && rchecked.test( value ) ) ) {4809 return collection.each( function( index ) {4810 var self = collection.eq( index );4811 if ( valueIsFunction ) {4812 args[ 0 ] = value.call( this, index, self.html() );4813 }4814 domManip( self, args, callback, ignored );4815 } );4816 }4817 if ( l ) {4818 fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );4819 first = fragment.firstChild;4820 if ( fragment.childNodes.length === 1 ) {4821 fragment = first;4822 }4823 // Require either new content or an interest in ignored elements to invoke the callback4824 if ( first || ignored ) {4825 scripts = jQuery.map( getAll( fragment, "script" ), disableScript );4826 hasScripts = scripts.length;4827 // Use the original fragment for the last item4828 // instead of the first because it can end up4829 // being emptied incorrectly in certain situations (#8070).4830 for ( ; i < l; i++ ) {4831 node = fragment;4832 if ( i !== iNoClone ) {4833 node = jQuery.clone( node, true, true );4834 // Keep references to cloned scripts for later restoration4835 if ( hasScripts ) {4836 // Support: Android <=4.0 only, PhantomJS 1 only4837 // push.apply(_, arraylike) throws on ancient WebKit4838 jQuery.merge( scripts, getAll( node, "script" ) );4839 }4840 }4841 callback.call( collection[ i ], node, i );4842 }4843 if ( hasScripts ) {4844 doc = scripts[ scripts.length - 1 ].ownerDocument;4845 // Reenable scripts4846 jQuery.map( scripts, restoreScript );4847 // Evaluate executable scripts on first document insertion4848 for ( i = 0; i < hasScripts; i++ ) {4849 node = scripts[ i ];4850 if ( rscriptType.test( node.type || "" ) &&4851 !dataPriv.access( node, "globalEval" ) &&4852 jQuery.contains( doc, node ) ) {4853 if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) {4854 // Optional AJAX dependency, but won't run scripts if not present4855 if ( jQuery._evalUrl && !node.noModule ) {4856 jQuery._evalUrl( node.src, {4857 nonce: node.nonce || node.getAttribute( "nonce" )4858 } );4859 }4860 } else {4861 DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc );4862 }4863 }4864 }4865 }4866 }4867 }4868 return collection;4869}4870function remove( elem, selector, keepData ) {4871 var node,4872 nodes = selector ? jQuery.filter( selector, elem ) : elem,4873 i = 0;4874 for ( ; ( node = nodes[ i ] ) != null; i++ ) {4875 if ( !keepData && node.nodeType === 1 ) {4876 jQuery.cleanData( getAll( node ) );4877 }4878 if ( node.parentNode ) {4879 if ( keepData && isAttached( node ) ) {4880 setGlobalEval( getAll( node, "script" ) );4881 }4882 node.parentNode.removeChild( node );4883 }4884 }4885 return elem;4886}4887jQuery.extend( {4888 htmlPrefilter: function( html ) {4889 return html.replace( rxhtmlTag, "<$1></$2>" );4890 },4891 clone: function( elem, dataAndEvents, deepDataAndEvents ) {4892 var i, l, srcElements, destElements,4893 clone = elem.cloneNode( true ),4894 inPage = isAttached( elem );4895 // Fix IE cloning issues4896 if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&4897 !jQuery.isXMLDoc( elem ) ) {4898 // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/24899 destElements = getAll( clone );4900 srcElements = getAll( elem );4901 for ( i = 0, l = srcElements.length; i < l; i++ ) {4902 fixInput( srcElements[ i ], destElements[ i ] );4903 }4904 }4905 // Copy the events from the original to the clone4906 if ( dataAndEvents ) {4907 if ( deepDataAndEvents ) {4908 srcElements = srcElements || getAll( elem );4909 destElements = destElements || getAll( clone );4910 for ( i = 0, l = srcElements.length; i < l; i++ ) {4911 cloneCopyEvent( srcElements[ i ], destElements[ i ] );4912 }4913 } else {4914 cloneCopyEvent( elem, clone );4915 }4916 }4917 // Preserve script evaluation history4918 destElements = getAll( clone, "script" );4919 if ( destElements.length > 0 ) {4920 setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );4921 }4922 // Return the cloned set4923 return clone;4924 },4925 cleanData: function( elems ) {4926 var data, elem, type,4927 special = jQuery.event.special,4928 i = 0;4929 for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {4930 if ( acceptData( elem ) ) {4931 if ( ( data = elem[ dataPriv.expando ] ) ) {4932 if ( data.events ) {4933 for ( type in data.events ) {4934 if ( special[ type ] ) {4935 jQuery.event.remove( elem, type );4936 // This is a shortcut to avoid jQuery.event.remove's overhead4937 } else {4938 jQuery.removeEvent( elem, type, data.handle );4939 }4940 }4941 }4942 // Support: Chrome <=35 - 45+4943 // Assign undefined instead of using delete, see Data#remove4944 elem[ dataPriv.expando ] = undefined;4945 }4946 if ( elem[ dataUser.expando ] ) {4947 // Support: Chrome <=35 - 45+4948 // Assign undefined instead of using delete, see Data#remove4949 elem[ dataUser.expando ] = undefined;4950 }4951 }4952 }4953 }4954} );4955jQuery.fn.extend( {4956 detach: function( selector ) {4957 return remove( this, selector, true );4958 },4959 remove: function( selector ) {4960 return remove( this, selector );4961 },4962 text: function( value ) {4963 return access( this, function( value ) {4964 return value === undefined ?4965 jQuery.text( this ) :4966 this.empty().each( function() {4967 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {4968 this.textContent = value;4969 }4970 } );4971 }, null, value, arguments.length );4972 },4973 append: function() {4974 return domManip( this, arguments, function( elem ) {4975 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {4976 var target = manipulationTarget( this, elem );4977 target.appendChild( elem );4978 }4979 } );4980 },4981 prepend: function() {4982 return domManip( this, arguments, function( elem ) {4983 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {4984 var target = manipulationTarget( this, elem );4985 target.insertBefore( elem, target.firstChild );4986 }4987 } );4988 },4989 before: function() {4990 return domManip( this, arguments, function( elem ) {4991 if ( this.parentNode ) {4992 this.parentNode.insertBefore( elem, this );4993 }4994 } );4995 },4996 after: function() {4997 return domManip( this, arguments, function( elem ) {4998 if ( this.parentNode ) {4999 this.parentNode.insertBefore( elem, this.nextSibling );5000 }5001 } );5002 },5003 empty: function() {5004 var elem,5005 i = 0;5006 for ( ; ( elem = this[ i ] ) != null; i++ ) {5007 if ( elem.nodeType === 1 ) {5008 // Prevent memory leaks5009 jQuery.cleanData( getAll( elem, false ) );5010 // Remove any remaining nodes5011 elem.textContent = "";5012 }5013 }5014 return this;5015 },5016 clone: function( dataAndEvents, deepDataAndEvents ) {5017 dataAndEvents = dataAndEvents == null ? false : dataAndEvents;5018 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;5019 return this.map( function() {5020 return jQuery.clone( this, dataAndEvents, deepDataAndEvents );5021 } );5022 },5023 html: function( value ) {5024 return access( this, function( value ) {5025 var elem = this[ 0 ] || {},5026 i = 0,5027 l = this.length;5028 if ( value === undefined && elem.nodeType === 1 ) {5029 return elem.innerHTML;5030 }5031 // See if we can take a shortcut and just use innerHTML5032 if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&5033 !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {5034 value = jQuery.htmlPrefilter( value );5035 try {5036 for ( ; i < l; i++ ) {5037 elem = this[ i ] || {};5038 // Remove element nodes and prevent memory leaks5039 if ( elem.nodeType === 1 ) {5040 jQuery.cleanData( getAll( elem, false ) );5041 elem.innerHTML = value;5042 }5043 }5044 elem = 0;5045 // If using innerHTML throws an exception, use the fallback method5046 } catch ( e ) {}5047 }5048 if ( elem ) {5049 this.empty().append( value );5050 }5051 }, null, value, arguments.length );5052 },5053 replaceWith: function() {5054 var ignored = [];5055 // Make the changes, replacing each non-ignored context element with the new content5056 return domManip( this, arguments, function( elem ) {5057 var parent = this.parentNode;5058 if ( jQuery.inArray( this, ignored ) < 0 ) {5059 jQuery.cleanData( getAll( this ) );5060 if ( parent ) {5061 parent.replaceChild( elem, this );5062 }5063 }5064 // Force callback invocation5065 }, ignored );5066 }5067} );5068jQuery.each( {5069 appendTo: "append",5070 prependTo: "prepend",5071 insertBefore: "before",5072 insertAfter: "after",5073 replaceAll: "replaceWith"5074}, function( name, original ) {5075 jQuery.fn[ name ] = function( selector ) {5076 var elems,5077 ret = [],5078 insert = jQuery( selector ),5079 last = insert.length - 1,5080 i = 0;5081 for ( ; i <= last; i++ ) {5082 elems = i === last ? this : this.clone( true );5083 jQuery( insert[ i ] )[ original ]( elems );5084 // Support: Android <=4.0 only, PhantomJS 1 only5085 // .get() because push.apply(_, arraylike) throws on ancient WebKit5086 push.apply( ret, elems.get() );5087 }5088 return this.pushStack( ret );5089 };5090} );5091var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );5092var getStyles = function( elem ) {5093 // Support: IE <=11 only, Firefox <=30 (#15098, #14150)5094 // IE throws on elements created in popups5095 // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"5096 var view = elem.ownerDocument.defaultView;5097 if ( !view || !view.opener ) {5098 view = window;5099 }5100 return view.getComputedStyle( elem );5101 };5102var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" );5103( function() {5104 // Executing both pixelPosition & boxSizingReliable tests require only one layout5105 // so they're executed at the same time to save the second computation.5106 function computeStyleTests() {5107 // This is a singleton, we need to execute it only once5108 if ( !div ) {5109 return;5110 }5111 container.style.cssText = "position:absolute;left:-11111px;width:60px;" +5112 "margin-top:1px;padding:0;border:0";5113 div.style.cssText =5114 "position:relative;display:block;box-sizing:border-box;overflow:scroll;" +5115 "margin:auto;border:1px;padding:1px;" +5116 "width:60%;top:1%";5117 documentElement.appendChild( container ).appendChild( div );5118 var divStyle = window.getComputedStyle( div );5119 pixelPositionVal = divStyle.top !== "1%";5120 // Support: Android 4.0 - 4.3 only, Firefox <=3 - 445121 reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;5122 // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.35123 // Some styles come back with percentage values, even though they shouldn't5124 div.style.right = "60%";5125 pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;5126 // Support: IE 9 - 11 only5127 // Detect misreporting of content dimensions for box-sizing:border-box elements5128 boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;5129 // Support: IE 9 only5130 // Detect overflow:scroll screwiness (gh-3699)5131 // Support: Chrome <=645132 // Don't get tricked when zoom affects offsetWidth (gh-4029)5133 div.style.position = "absolute";5134 scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;5135 documentElement.removeChild( container );5136 // Nullify the div so it wouldn't be stored in the memory and5137 // it will also be a sign that checks already performed5138 div = null;5139 }5140 function roundPixelMeasures( measure ) {5141 return Math.round( parseFloat( measure ) );5142 }5143 var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,5144 reliableMarginLeftVal,5145 container = document.createElement( "div" ),5146 div = document.createElement( "div" );5147 // Finish early in limited (non-browser) environments5148 if ( !div.style ) {5149 return;5150 }5151 // Support: IE <=9 - 11 only5152 // Style of cloned element affects source element cloned (#8908)5153 div.style.backgroundClip = "content-box";5154 div.cloneNode( true ).style.backgroundClip = "";5155 support.clearCloneStyle = div.style.backgroundClip === "content-box";5156 jQuery.extend( support, {5157 boxSizingReliable: function() {5158 computeStyleTests();5159 return boxSizingReliableVal;5160 },5161 pixelBoxStyles: function() {5162 computeStyleTests();5163 return pixelBoxStylesVal;5164 },5165 pixelPosition: function() {5166 computeStyleTests();5167 return pixelPositionVal;5168 },5169 reliableMarginLeft: function() {5170 computeStyleTests();5171 return reliableMarginLeftVal;5172 },5173 scrollboxSize: function() {5174 computeStyleTests();5175 return scrollboxSizeVal;5176 }5177 } );5178} )();5179function curCSS( elem, name, computed ) {5180 var width, minWidth, maxWidth, ret,5181 // Support: Firefox 51+5182 // Retrieving style before computed somehow5183 // fixes an issue with getting wrong values5184 // on detached elements5185 style = elem.style;5186 computed = computed || getStyles( elem );5187 // getPropertyValue is needed for:5188 // .css('filter') (IE 9 only, #12537)5189 // .css('--customProperty) (#3144)5190 if ( computed ) {5191 ret = computed.getPropertyValue( name ) || computed[ name ];5192 if ( ret === "" && !isAttached( elem ) ) {5193 ret = jQuery.style( elem, name );5194 }5195 // A tribute to the "awesome hack by Dean Edwards"5196 // Android Browser returns percentage for some values,5197 // but width seems to be reliably pixels.5198 // This is against the CSSOM draft spec:5199 // https://drafts.csswg.org/cssom/#resolved-values5200 if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {5201 // Remember the original values5202 width = style.width;5203 minWidth = style.minWidth;5204 maxWidth = style.maxWidth;5205 // Put in the new values to get a computed value out5206 style.minWidth = style.maxWidth = style.width = ret;5207 ret = computed.width;5208 // Revert the changed values5209 style.width = width;5210 style.minWidth = minWidth;5211 style.maxWidth = maxWidth;5212 }5213 }5214 return ret !== undefined ?5215 // Support: IE <=9 - 11 only5216 // IE returns zIndex value as an integer.5217 ret + "" :5218 ret;5219}5220function addGetHookIf( conditionFn, hookFn ) {5221 // Define the hook, we'll check on the first run if it's really needed.5222 return {5223 get: function() {5224 if ( conditionFn() ) {5225 // Hook not needed (or it's not possible to use it due5226 // to missing dependency), remove it.5227 delete this.get;5228 return;5229 }5230 // Hook needed; redefine it so that the support test is not executed again.5231 return ( this.get = hookFn ).apply( this, arguments );5232 }5233 };5234}5235var cssPrefixes = [ "Webkit", "Moz", "ms" ],5236 emptyStyle = document.createElement( "div" ).style,5237 vendorProps = {};5238// Return a vendor-prefixed property or undefined5239function vendorPropName( name ) {5240 // Check for vendor prefixed names5241 var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),5242 i = cssPrefixes.length;5243 while ( i-- ) {5244 name = cssPrefixes[ i ] + capName;5245 if ( name in emptyStyle ) {5246 return name;5247 }5248 }5249}5250// Return a potentially-mapped jQuery.cssProps or vendor prefixed property5251function finalPropName( name ) {5252 var final = jQuery.cssProps[ name ] || vendorProps[ name ];5253 if ( final ) {5254 return final;5255 }5256 if ( name in emptyStyle ) {5257 return name;5258 }5259 return vendorProps[ name ] = vendorPropName( name ) || name;5260}5261var5262 // Swappable if display is none or starts with table5263 // except "table", "table-cell", or "table-caption"5264 // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display5265 rdisplayswap = /^(none|table(?!-c[ea]).+)/,5266 rcustomProp = /^--/,5267 cssShow = { position: "absolute", visibility: "hidden", display: "block" },5268 cssNormalTransform = {5269 letterSpacing: "0",5270 fontWeight: "400"5271 };5272function setPositiveNumber( elem, value, subtract ) {5273 // Any relative (+/-) values have already been5274 // normalized at this point5275 var matches = rcssNum.exec( value );5276 return matches ?5277 // Guard against undefined "subtract", e.g., when used as in cssHooks5278 Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :5279 value;5280}5281function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {5282 var i = dimension === "width" ? 1 : 0,5283 extra = 0,5284 delta = 0;5285 // Adjustment may not be necessary5286 if ( box === ( isBorderBox ? "border" : "content" ) ) {5287 return 0;5288 }5289 for ( ; i < 4; i += 2 ) {5290 // Both box models exclude margin5291 if ( box === "margin" ) {5292 delta += jQuery.css( elem, box + cssExpand[ i ], true, styles );5293 }5294 // If we get here with a content-box, we're seeking "padding" or "border" or "margin"5295 if ( !isBorderBox ) {5296 // Add padding5297 delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );5298 // For "border" or "margin", add border5299 if ( box !== "padding" ) {5300 delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );5301 // But still keep track of it otherwise5302 } else {5303 extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );5304 }5305 // If we get here with a border-box (content + padding + border), we're seeking "content" or5306 // "padding" or "margin"5307 } else {5308 // For "content", subtract padding5309 if ( box === "content" ) {5310 delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );5311 }5312 // For "content" or "padding", subtract border5313 if ( box !== "margin" ) {5314 delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );5315 }5316 }5317 }5318 // Account for positive content-box scroll gutter when requested by providing computedVal5319 if ( !isBorderBox && computedVal >= 0 ) {5320 // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border5321 // Assuming integer scroll gutter, subtract the rest and round down5322 delta += Math.max( 0, Math.ceil(5323 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -5324 computedVal -5325 delta -5326 extra -5327 0.55328 // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter5329 // Use an explicit zero to avoid NaN (gh-3964)5330 ) ) || 0;5331 }5332 return delta;5333}5334function getWidthOrHeight( elem, dimension, extra ) {5335 // Start with computed style5336 var styles = getStyles( elem ),5337 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).5338 // Fake content-box until we know it's needed to know the true value.5339 boxSizingNeeded = !support.boxSizingReliable() || extra,5340 isBorderBox = boxSizingNeeded &&5341 jQuery.css( elem, "boxSizing", false, styles ) === "border-box",5342 valueIsBorderBox = isBorderBox,5343 val = curCSS( elem, dimension, styles ),5344 offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );5345 // Support: Firefox <=545346 // Return a confounding non-pixel value or feign ignorance, as appropriate.5347 if ( rnumnonpx.test( val ) ) {5348 if ( !extra ) {5349 return val;5350 }5351 val = "auto";5352 }5353 // Fall back to offsetWidth/offsetHeight when value is "auto"5354 // This happens for inline elements with no explicit setting (gh-3571)5355 // Support: Android <=4.1 - 4.3 only5356 // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)5357 // Support: IE 9-11 only5358 // Also use offsetWidth/offsetHeight for when box sizing is unreliable5359 // We use getClientRects() to check for hidden/disconnected.5360 // In those cases, the computed value can be trusted to be border-box5361 if ( ( !support.boxSizingReliable() && isBorderBox ||5362 val === "auto" ||5363 !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) &&5364 elem.getClientRects().length ) {5365 isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";5366 // Where available, offsetWidth/offsetHeight approximate border box dimensions.5367 // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the5368 // retrieved value as a content box dimension.5369 valueIsBorderBox = offsetProp in elem;5370 if ( valueIsBorderBox ) {5371 val = elem[ offsetProp ];5372 }5373 }5374 // Normalize "" and auto5375 val = parseFloat( val ) || 0;5376 // Adjust for the element's box model5377 return ( val +5378 boxModelAdjustment(5379 elem,5380 dimension,5381 extra || ( isBorderBox ? "border" : "content" ),5382 valueIsBorderBox,5383 styles,5384 // Provide the current computed size to request scroll gutter calculation (gh-3589)5385 val5386 )5387 ) + "px";5388}5389jQuery.extend( {5390 // Add in style property hooks for overriding the default5391 // behavior of getting and setting a style property5392 cssHooks: {5393 opacity: {5394 get: function( elem, computed ) {5395 if ( computed ) {5396 // We should always get a number back from opacity5397 var ret = curCSS( elem, "opacity" );5398 return ret === "" ? "1" : ret;5399 }5400 }5401 }5402 },5403 // Don't automatically add "px" to these possibly-unitless properties5404 cssNumber: {5405 "animationIterationCount": true,5406 "columnCount": true,5407 "fillOpacity": true,5408 "flexGrow": true,5409 "flexShrink": true,5410 "fontWeight": true,5411 "gridArea": true,5412 "gridColumn": true,5413 "gridColumnEnd": true,5414 "gridColumnStart": true,5415 "gridRow": true,5416 "gridRowEnd": true,5417 "gridRowStart": true,5418 "lineHeight": true,5419 "opacity": true,5420 "order": true,5421 "orphans": true,5422 "widows": true,5423 "zIndex": true,5424 "zoom": true5425 },5426 // Add in properties whose names you wish to fix before5427 // setting or getting the value5428 cssProps: {},5429 // Get and set the style property on a DOM Node5430 style: function( elem, name, value, extra ) {5431 // Don't set styles on text and comment nodes5432 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {5433 return;5434 }5435 // Make sure that we're working with the right name5436 var ret, type, hooks,5437 origName = camelCase( name ),5438 isCustomProp = rcustomProp.test( name ),5439 style = elem.style;5440 // Make sure that we're working with the right name. We don't5441 // want to query the value if it is a CSS custom property5442 // since they are user-defined.5443 if ( !isCustomProp ) {5444 name = finalPropName( origName );5445 }5446 // Gets hook for the prefixed version, then unprefixed version5447 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];5448 // Check if we're setting a value5449 if ( value !== undefined ) {5450 type = typeof value;5451 // Convert "+=" or "-=" to relative numbers (#7345)5452 if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {5453 value = adjustCSS( elem, name, ret );5454 // Fixes bug #92375455 type = "number";5456 }5457 // Make sure that null and NaN values aren't set (#7116)5458 if ( value == null || value !== value ) {5459 return;5460 }5461 // If a number was passed in, add the unit (except for certain CSS properties)5462 // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append5463 // "px" to a few hardcoded values.5464 if ( type === "number" && !isCustomProp ) {5465 value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );5466 }5467 // background-* props affect original clone's values5468 if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {5469 style[ name ] = "inherit";5470 }5471 // If a hook was provided, use that value, otherwise just set the specified value5472 if ( !hooks || !( "set" in hooks ) ||5473 ( value = hooks.set( elem, value, extra ) ) !== undefined ) {5474 if ( isCustomProp ) {5475 style.setProperty( name, value );5476 } else {5477 style[ name ] = value;5478 }5479 }5480 } else {5481 // If a hook was provided get the non-computed value from there5482 if ( hooks && "get" in hooks &&5483 ( ret = hooks.get( elem, false, extra ) ) !== undefined ) {5484 return ret;5485 }5486 // Otherwise just get the value from the style object5487 return style[ name ];5488 }5489 },5490 css: function( elem, name, extra, styles ) {5491 var val, num, hooks,5492 origName = camelCase( name ),5493 isCustomProp = rcustomProp.test( name );5494 // Make sure that we're working with the right name. We don't5495 // want to modify the value if it is a CSS custom property5496 // since they are user-defined.5497 if ( !isCustomProp ) {5498 name = finalPropName( origName );5499 }5500 // Try prefixed name followed by the unprefixed name5501 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];5502 // If a hook was provided get the computed value from there5503 if ( hooks && "get" in hooks ) {5504 val = hooks.get( elem, true, extra );5505 }5506 // Otherwise, if a way to get the computed value exists, use that5507 if ( val === undefined ) {5508 val = curCSS( elem, name, styles );5509 }5510 // Convert "normal" to computed value5511 if ( val === "normal" && name in cssNormalTransform ) {5512 val = cssNormalTransform[ name ];5513 }5514 // Make numeric if forced or a qualifier was provided and val looks numeric5515 if ( extra === "" || extra ) {5516 num = parseFloat( val );5517 return extra === true || isFinite( num ) ? num || 0 : val;5518 }5519 return val;5520 }5521} );5522jQuery.each( [ "height", "width" ], function( i, dimension ) {5523 jQuery.cssHooks[ dimension ] = {5524 get: function( elem, computed, extra ) {5525 if ( computed ) {5526 // Certain elements can have dimension info if we invisibly show them5527 // but it must have a current display style that would benefit5528 return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&5529 // Support: Safari 8+5530 // Table columns in Safari have non-zero offsetWidth & zero5531 // getBoundingClientRect().width unless display is changed.5532 // Support: IE <=11 only5533 // Running getBoundingClientRect on a disconnected node5534 // in IE throws an error.5535 ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?5536 swap( elem, cssShow, function() {5537 return getWidthOrHeight( elem, dimension, extra );5538 } ) :5539 getWidthOrHeight( elem, dimension, extra );5540 }5541 },5542 set: function( elem, value, extra ) {5543 var matches,5544 styles = getStyles( elem ),5545 // Only read styles.position if the test has a chance to fail5546 // to avoid forcing a reflow.5547 scrollboxSizeBuggy = !support.scrollboxSize() &&5548 styles.position === "absolute",5549 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)5550 boxSizingNeeded = scrollboxSizeBuggy || extra,5551 isBorderBox = boxSizingNeeded &&5552 jQuery.css( elem, "boxSizing", false, styles ) === "border-box",5553 subtract = extra ?5554 boxModelAdjustment(5555 elem,5556 dimension,5557 extra,5558 isBorderBox,5559 styles5560 ) :5561 0;5562 // Account for unreliable border-box dimensions by comparing offset* to computed and5563 // faking a content-box to get border and padding (gh-3699)5564 if ( isBorderBox && scrollboxSizeBuggy ) {5565 subtract -= Math.ceil(5566 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -5567 parseFloat( styles[ dimension ] ) -5568 boxModelAdjustment( elem, dimension, "border", false, styles ) -5569 0.55570 );5571 }5572 // Convert to pixels if value adjustment is needed5573 if ( subtract && ( matches = rcssNum.exec( value ) ) &&5574 ( matches[ 3 ] || "px" ) !== "px" ) {5575 elem.style[ dimension ] = value;5576 value = jQuery.css( elem, dimension );5577 }5578 return setPositiveNumber( elem, value, subtract );5579 }5580 };5581} );5582jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,5583 function( elem, computed ) {5584 if ( computed ) {5585 return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||5586 elem.getBoundingClientRect().left -5587 swap( elem, { marginLeft: 0 }, function() {5588 return elem.getBoundingClientRect().left;5589 } )5590 ) + "px";5591 }5592 }5593);5594// These hooks are used by animate to expand properties5595jQuery.each( {5596 margin: "",5597 padding: "",5598 border: "Width"5599}, function( prefix, suffix ) {5600 jQuery.cssHooks[ prefix + suffix ] = {5601 expand: function( value ) {5602 var i = 0,5603 expanded = {},5604 // Assumes a single number if not a string5605 parts = typeof value === "string" ? value.split( " " ) : [ value ];5606 for ( ; i < 4; i++ ) {5607 expanded[ prefix + cssExpand[ i ] + suffix ] =5608 parts[ i ] || parts[ i - 2 ] || parts[ 0 ];5609 }5610 return expanded;5611 }5612 };5613 if ( prefix !== "margin" ) {5614 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;5615 }5616} );5617jQuery.fn.extend( {5618 css: function( name, value ) {5619 return access( this, function( elem, name, value ) {5620 var styles, len,5621 map = {},5622 i = 0;5623 if ( Array.isArray( name ) ) {5624 styles = getStyles( elem );5625 len = name.length;5626 for ( ; i < len; i++ ) {5627 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );5628 }5629 return map;5630 }5631 return value !== undefined ?5632 jQuery.style( elem, name, value ) :5633 jQuery.css( elem, name );5634 }, name, value, arguments.length > 1 );5635 }5636} );5637function Tween( elem, options, prop, end, easing ) {5638 return new Tween.prototype.init( elem, options, prop, end, easing );5639}5640jQuery.Tween = Tween;5641Tween.prototype = {5642 constructor: Tween,5643 init: function( elem, options, prop, end, easing, unit ) {5644 this.elem = elem;5645 this.prop = prop;5646 this.easing = easing || jQuery.easing._default;5647 this.options = options;5648 this.start = this.now = this.cur();5649 this.end = end;5650 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );5651 },5652 cur: function() {5653 var hooks = Tween.propHooks[ this.prop ];5654 return hooks && hooks.get ?5655 hooks.get( this ) :5656 Tween.propHooks._default.get( this );5657 },5658 run: function( percent ) {5659 var eased,5660 hooks = Tween.propHooks[ this.prop ];5661 if ( this.options.duration ) {5662 this.pos = eased = jQuery.easing[ this.easing ](5663 percent, this.options.duration * percent, 0, 1, this.options.duration5664 );5665 } else {5666 this.pos = eased = percent;5667 }5668 this.now = ( this.end - this.start ) * eased + this.start;5669 if ( this.options.step ) {5670 this.options.step.call( this.elem, this.now, this );5671 }5672 if ( hooks && hooks.set ) {5673 hooks.set( this );5674 } else {5675 Tween.propHooks._default.set( this );5676 }5677 return this;5678 }5679};5680Tween.prototype.init.prototype = Tween.prototype;5681Tween.propHooks = {5682 _default: {5683 get: function( tween ) {5684 var result;5685 // Use a property on the element directly when it is not a DOM element,5686 // or when there is no matching style property that exists.5687 if ( tween.elem.nodeType !== 1 ||5688 tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {5689 return tween.elem[ tween.prop ];5690 }5691 // Passing an empty string as a 3rd parameter to .css will automatically5692 // attempt a parseFloat and fallback to a string if the parse fails.5693 // Simple values such as "10px" are parsed to Float;5694 // complex values such as "rotate(1rad)" are returned as-is.5695 result = jQuery.css( tween.elem, tween.prop, "" );5696 // Empty strings, null, undefined and "auto" are converted to 0.5697 return !result || result === "auto" ? 0 : result;5698 },5699 set: function( tween ) {5700 // Use step hook for back compat.5701 // Use cssHook if its there.5702 // Use .style if available and use plain properties where available.5703 if ( jQuery.fx.step[ tween.prop ] ) {5704 jQuery.fx.step[ tween.prop ]( tween );5705 } else if ( tween.elem.nodeType === 1 && (5706 jQuery.cssHooks[ tween.prop ] ||5707 tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {5708 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );5709 } else {5710 tween.elem[ tween.prop ] = tween.now;5711 }5712 }5713 }5714};5715// Support: IE <=9 only5716// Panic based approach to setting things on disconnected nodes5717Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {5718 set: function( tween ) {5719 if ( tween.elem.nodeType && tween.elem.parentNode ) {5720 tween.elem[ tween.prop ] = tween.now;5721 }5722 }5723};5724jQuery.easing = {5725 linear: function( p ) {5726 return p;5727 },5728 swing: function( p ) {5729 return 0.5 - Math.cos( p * Math.PI ) / 2;5730 },5731 _default: "swing"5732};5733jQuery.fx = Tween.prototype.init;5734// Back compat <1.8 extension point5735jQuery.fx.step = {};5736var5737 fxNow, inProgress,5738 rfxtypes = /^(?:toggle|show|hide)$/,5739 rrun = /queueHooks$/;5740function schedule() {5741 if ( inProgress ) {5742 if ( document.hidden === false && window.requestAnimationFrame ) {5743 window.requestAnimationFrame( schedule );5744 } else {5745 window.setTimeout( schedule, jQuery.fx.interval );5746 }5747 jQuery.fx.tick();5748 }5749}5750// Animations created synchronously will run synchronously5751function createFxNow() {5752 window.setTimeout( function() {5753 fxNow = undefined;5754 } );5755 return ( fxNow = Date.now() );5756}5757// Generate parameters to create a standard animation5758function genFx( type, includeWidth ) {5759 var which,5760 i = 0,5761 attrs = { height: type };5762 // If we include width, step value is 1 to do all cssExpand values,5763 // otherwise step value is 2 to skip over Left and Right5764 includeWidth = includeWidth ? 1 : 0;5765 for ( ; i < 4; i += 2 - includeWidth ) {5766 which = cssExpand[ i ];5767 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;5768 }5769 if ( includeWidth ) {5770 attrs.opacity = attrs.width = type;5771 }5772 return attrs;5773}5774function createTween( value, prop, animation ) {5775 var tween,5776 collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),5777 index = 0,5778 length = collection.length;5779 for ( ; index < length; index++ ) {5780 if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {5781 // We're done with this property5782 return tween;5783 }5784 }5785}5786function defaultPrefilter( elem, props, opts ) {5787 var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,5788 isBox = "width" in props || "height" in props,5789 anim = this,5790 orig = {},5791 style = elem.style,5792 hidden = elem.nodeType && isHiddenWithinTree( elem ),5793 dataShow = dataPriv.get( elem, "fxshow" );5794 // Queue-skipping animations hijack the fx hooks5795 if ( !opts.queue ) {5796 hooks = jQuery._queueHooks( elem, "fx" );5797 if ( hooks.unqueued == null ) {5798 hooks.unqueued = 0;5799 oldfire = hooks.empty.fire;5800 hooks.empty.fire = function() {5801 if ( !hooks.unqueued ) {5802 oldfire();5803 }5804 };5805 }5806 hooks.unqueued++;5807 anim.always( function() {5808 // Ensure the complete handler is called before this completes5809 anim.always( function() {5810 hooks.unqueued--;5811 if ( !jQuery.queue( elem, "fx" ).length ) {5812 hooks.empty.fire();5813 }5814 } );5815 } );5816 }5817 // Detect show/hide animations5818 for ( prop in props ) {5819 value = props[ prop ];5820 if ( rfxtypes.test( value ) ) {5821 delete props[ prop ];5822 toggle = toggle || value === "toggle";5823 if ( value === ( hidden ? "hide" : "show" ) ) {5824 // Pretend to be hidden if this is a "show" and5825 // there is still data from a stopped show/hide5826 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {5827 hidden = true;5828 // Ignore all other no-op show/hide data5829 } else {5830 continue;5831 }5832 }5833 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );5834 }5835 }5836 // Bail out if this is a no-op like .hide().hide()5837 propTween = !jQuery.isEmptyObject( props );5838 if ( !propTween && jQuery.isEmptyObject( orig ) ) {5839 return;5840 }5841 // Restrict "overflow" and "display" styles during box animations5842 if ( isBox && elem.nodeType === 1 ) {5843 // Support: IE <=9 - 11, Edge 12 - 155844 // Record all 3 overflow attributes because IE does not infer the shorthand5845 // from identically-valued overflowX and overflowY and Edge just mirrors5846 // the overflowX value there.5847 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];5848 // Identify a display type, preferring old show/hide data over the CSS cascade5849 restoreDisplay = dataShow && dataShow.display;5850 if ( restoreDisplay == null ) {5851 restoreDisplay = dataPriv.get( elem, "display" );5852 }5853 display = jQuery.css( elem, "display" );5854 if ( display === "none" ) {5855 if ( restoreDisplay ) {5856 display = restoreDisplay;5857 } else {5858 // Get nonempty value(s) by temporarily forcing visibility5859 showHide( [ elem ], true );5860 restoreDisplay = elem.style.display || restoreDisplay;5861 display = jQuery.css( elem, "display" );5862 showHide( [ elem ] );5863 }5864 }5865 // Animate inline elements as inline-block5866 if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {5867 if ( jQuery.css( elem, "float" ) === "none" ) {5868 // Restore the original display value at the end of pure show/hide animations5869 if ( !propTween ) {5870 anim.done( function() {5871 style.display = restoreDisplay;5872 } );5873 if ( restoreDisplay == null ) {5874 display = style.display;5875 restoreDisplay = display === "none" ? "" : display;5876 }5877 }5878 style.display = "inline-block";5879 }5880 }5881 }5882 if ( opts.overflow ) {5883 style.overflow = "hidden";5884 anim.always( function() {5885 style.overflow = opts.overflow[ 0 ];5886 style.overflowX = opts.overflow[ 1 ];5887 style.overflowY = opts.overflow[ 2 ];5888 } );5889 }5890 // Implement show/hide animations5891 propTween = false;5892 for ( prop in orig ) {5893 // General show/hide setup for this element animation5894 if ( !propTween ) {5895 if ( dataShow ) {5896 if ( "hidden" in dataShow ) {5897 hidden = dataShow.hidden;5898 }5899 } else {5900 dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );5901 }5902 // Store hidden/visible for toggle so `.stop().toggle()` "reverses"5903 if ( toggle ) {5904 dataShow.hidden = !hidden;5905 }5906 // Show elements before animating them5907 if ( hidden ) {5908 showHide( [ elem ], true );5909 }5910 /* eslint-disable no-loop-func */5911 anim.done( function() {5912 /* eslint-enable no-loop-func */5913 // The final step of a "hide" animation is actually hiding the element5914 if ( !hidden ) {5915 showHide( [ elem ] );5916 }5917 dataPriv.remove( elem, "fxshow" );5918 for ( prop in orig ) {5919 jQuery.style( elem, prop, orig[ prop ] );5920 }5921 } );5922 }5923 // Per-property setup5924 propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );5925 if ( !( prop in dataShow ) ) {5926 dataShow[ prop ] = propTween.start;5927 if ( hidden ) {5928 propTween.end = propTween.start;5929 propTween.start = 0;5930 }5931 }5932 }5933}5934function propFilter( props, specialEasing ) {5935 var index, name, easing, value, hooks;5936 // camelCase, specialEasing and expand cssHook pass5937 for ( index in props ) {5938 name = camelCase( index );5939 easing = specialEasing[ name ];5940 value = props[ index ];5941 if ( Array.isArray( value ) ) {5942 easing = value[ 1 ];5943 value = props[ index ] = value[ 0 ];5944 }5945 if ( index !== name ) {5946 props[ name ] = value;5947 delete props[ index ];5948 }5949 hooks = jQuery.cssHooks[ name ];5950 if ( hooks && "expand" in hooks ) {5951 value = hooks.expand( value );5952 delete props[ name ];5953 // Not quite $.extend, this won't overwrite existing keys.5954 // Reusing 'index' because we have the correct "name"5955 for ( index in value ) {5956 if ( !( index in props ) ) {5957 props[ index ] = value[ index ];5958 specialEasing[ index ] = easing;5959 }5960 }5961 } else {5962 specialEasing[ name ] = easing;5963 }5964 }5965}5966function Animation( elem, properties, options ) {5967 var result,5968 stopped,5969 index = 0,5970 length = Animation.prefilters.length,5971 deferred = jQuery.Deferred().always( function() {5972 // Don't match elem in the :animated selector5973 delete tick.elem;5974 } ),5975 tick = function() {5976 if ( stopped ) {5977 return false;5978 }5979 var currentTime = fxNow || createFxNow(),5980 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),5981 // Support: Android 2.3 only5982 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)5983 temp = remaining / animation.duration || 0,5984 percent = 1 - temp,5985 index = 0,5986 length = animation.tweens.length;5987 for ( ; index < length; index++ ) {5988 animation.tweens[ index ].run( percent );5989 }5990 deferred.notifyWith( elem, [ animation, percent, remaining ] );5991 // If there's more to do, yield5992 if ( percent < 1 && length ) {5993 return remaining;5994 }5995 // If this was an empty animation, synthesize a final progress notification5996 if ( !length ) {5997 deferred.notifyWith( elem, [ animation, 1, 0 ] );5998 }5999 // Resolve the animation and report its conclusion6000 deferred.resolveWith( elem, [ animation ] );6001 return false;6002 },6003 animation = deferred.promise( {6004 elem: elem,6005 props: jQuery.extend( {}, properties ),6006 opts: jQuery.extend( true, {6007 specialEasing: {},6008 easing: jQuery.easing._default6009 }, options ),6010 originalProperties: properties,6011 originalOptions: options,6012 startTime: fxNow || createFxNow(),6013 duration: options.duration,6014 tweens: [],6015 createTween: function( prop, end ) {6016 var tween = jQuery.Tween( elem, animation.opts, prop, end,6017 animation.opts.specialEasing[ prop ] || animation.opts.easing );6018 animation.tweens.push( tween );6019 return tween;6020 },6021 stop: function( gotoEnd ) {6022 var index = 0,6023 // If we are going to the end, we want to run all the tweens6024 // otherwise we skip this part6025 length = gotoEnd ? animation.tweens.length : 0;6026 if ( stopped ) {6027 return this;6028 }6029 stopped = true;6030 for ( ; index < length; index++ ) {6031 animation.tweens[ index ].run( 1 );6032 }6033 // Resolve when we played the last frame; otherwise, reject6034 if ( gotoEnd ) {6035 deferred.notifyWith( elem, [ animation, 1, 0 ] );6036 deferred.resolveWith( elem, [ animation, gotoEnd ] );6037 } else {6038 deferred.rejectWith( elem, [ animation, gotoEnd ] );6039 }6040 return this;6041 }6042 } ),6043 props = animation.props;6044 propFilter( props, animation.opts.specialEasing );6045 for ( ; index < length; index++ ) {6046 result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );6047 if ( result ) {6048 if ( isFunction( result.stop ) ) {6049 jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =6050 result.stop.bind( result );6051 }6052 return result;6053 }6054 }6055 jQuery.map( props, createTween, animation );6056 if ( isFunction( animation.opts.start ) ) {6057 animation.opts.start.call( elem, animation );6058 }6059 // Attach callbacks from options6060 animation6061 .progress( animation.opts.progress )6062 .done( animation.opts.done, animation.opts.complete )6063 .fail( animation.opts.fail )6064 .always( animation.opts.always );6065 jQuery.fx.timer(6066 jQuery.extend( tick, {6067 elem: elem,6068 anim: animation,6069 queue: animation.opts.queue6070 } )6071 );6072 return animation;6073}6074jQuery.Animation = jQuery.extend( Animation, {6075 tweeners: {6076 "*": [ function( prop, value ) {6077 var tween = this.createTween( prop, value );6078 adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );6079 return tween;6080 } ]6081 },6082 tweener: function( props, callback ) {6083 if ( isFunction( props ) ) {6084 callback = props;6085 props = [ "*" ];6086 } else {6087 props = props.match( rnothtmlwhite );6088 }6089 var prop,6090 index = 0,6091 length = props.length;6092 for ( ; index < length; index++ ) {6093 prop = props[ index ];6094 Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];6095 Animation.tweeners[ prop ].unshift( callback );6096 }6097 },6098 prefilters: [ defaultPrefilter ],6099 prefilter: function( callback, prepend ) {6100 if ( prepend ) {6101 Animation.prefilters.unshift( callback );6102 } else {6103 Animation.prefilters.push( callback );6104 }6105 }6106} );6107jQuery.speed = function( speed, easing, fn ) {6108 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {6109 complete: fn || !fn && easing ||6110 isFunction( speed ) && speed,6111 duration: speed,6112 easing: fn && easing || easing && !isFunction( easing ) && easing6113 };6114 // Go to the end state if fx are off6115 if ( jQuery.fx.off ) {6116 opt.duration = 0;6117 } else {6118 if ( typeof opt.duration !== "number" ) {6119 if ( opt.duration in jQuery.fx.speeds ) {6120 opt.duration = jQuery.fx.speeds[ opt.duration ];6121 } else {6122 opt.duration = jQuery.fx.speeds._default;6123 }6124 }6125 }6126 // Normalize opt.queue - true/undefined/null -> "fx"6127 if ( opt.queue == null || opt.queue === true ) {6128 opt.queue = "fx";6129 }6130 // Queueing6131 opt.old = opt.complete;6132 opt.complete = function() {6133 if ( isFunction( opt.old ) ) {6134 opt.old.call( this );6135 }6136 if ( opt.queue ) {6137 jQuery.dequeue( this, opt.queue );6138 }6139 };6140 return opt;6141};6142jQuery.fn.extend( {6143 fadeTo: function( speed, to, easing, callback ) {6144 // Show any hidden elements after setting opacity to 06145 return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()6146 // Animate to the value specified6147 .end().animate( { opacity: to }, speed, easing, callback );6148 },6149 animate: function( prop, speed, easing, callback ) {6150 var empty = jQuery.isEmptyObject( prop ),6151 optall = jQuery.speed( speed, easing, callback ),6152 doAnimation = function() {6153 // Operate on a copy of prop so per-property easing won't be lost6154 var anim = Animation( this, jQuery.extend( {}, prop ), optall );6155 // Empty animations, or finishing resolves immediately6156 if ( empty || dataPriv.get( this, "finish" ) ) {6157 anim.stop( true );6158 }6159 };6160 doAnimation.finish = doAnimation;6161 return empty || optall.queue === false ?6162 this.each( doAnimation ) :6163 this.queue( optall.queue, doAnimation );6164 },6165 stop: function( type, clearQueue, gotoEnd ) {6166 var stopQueue = function( hooks ) {6167 var stop = hooks.stop;6168 delete hooks.stop;6169 stop( gotoEnd );6170 };6171 if ( typeof type !== "string" ) {6172 gotoEnd = clearQueue;6173 clearQueue = type;6174 type = undefined;6175 }6176 if ( clearQueue && type !== false ) {6177 this.queue( type || "fx", [] );6178 }6179 return this.each( function() {6180 var dequeue = true,6181 index = type != null && type + "queueHooks",6182 timers = jQuery.timers,6183 data = dataPriv.get( this );6184 if ( index ) {6185 if ( data[ index ] && data[ index ].stop ) {6186 stopQueue( data[ index ] );6187 }6188 } else {6189 for ( index in data ) {6190 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {6191 stopQueue( data[ index ] );6192 }6193 }6194 }6195 for ( index = timers.length; index--; ) {6196 if ( timers[ index ].elem === this &&6197 ( type == null || timers[ index ].queue === type ) ) {6198 timers[ index ].anim.stop( gotoEnd );6199 dequeue = false;6200 timers.splice( index, 1 );6201 }6202 }6203 // Start the next in the queue if the last step wasn't forced.6204 // Timers currently will call their complete callbacks, which6205 // will dequeue but only if they were gotoEnd.6206 if ( dequeue || !gotoEnd ) {6207 jQuery.dequeue( this, type );6208 }6209 } );6210 },6211 finish: function( type ) {6212 if ( type !== false ) {6213 type = type || "fx";6214 }6215 return this.each( function() {6216 var index,6217 data = dataPriv.get( this ),6218 queue = data[ type + "queue" ],6219 hooks = data[ type + "queueHooks" ],6220 timers = jQuery.timers,6221 length = queue ? queue.length : 0;6222 // Enable finishing flag on private data6223 data.finish = true;6224 // Empty the queue first6225 jQuery.queue( this, type, [] );6226 if ( hooks && hooks.stop ) {6227 hooks.stop.call( this, true );6228 }6229 // Look for any active animations, and finish them6230 for ( index = timers.length; index--; ) {6231 if ( timers[ index ].elem === this && timers[ index ].queue === type ) {6232 timers[ index ].anim.stop( true );6233 timers.splice( index, 1 );6234 }6235 }6236 // Look for any animations in the old queue and finish them6237 for ( index = 0; index < length; index++ ) {6238 if ( queue[ index ] && queue[ index ].finish ) {6239 queue[ index ].finish.call( this );6240 }6241 }6242 // Turn off finishing flag6243 delete data.finish;6244 } );6245 }6246} );6247jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {6248 var cssFn = jQuery.fn[ name ];6249 jQuery.fn[ name ] = function( speed, easing, callback ) {6250 return speed == null || typeof speed === "boolean" ?6251 cssFn.apply( this, arguments ) :6252 this.animate( genFx( name, true ), speed, easing, callback );6253 };6254} );6255// Generate shortcuts for custom animations6256jQuery.each( {6257 slideDown: genFx( "show" ),6258 slideUp: genFx( "hide" ),6259 slideToggle: genFx( "toggle" ),6260 fadeIn: { opacity: "show" },6261 fadeOut: { opacity: "hide" },6262 fadeToggle: { opacity: "toggle" }6263}, function( name, props ) {6264 jQuery.fn[ name ] = function( speed, easing, callback ) {6265 return this.animate( props, speed, easing, callback );6266 };6267} );6268jQuery.timers = [];6269jQuery.fx.tick = function() {6270 var timer,6271 i = 0,6272 timers = jQuery.timers;6273 fxNow = Date.now();6274 for ( ; i < timers.length; i++ ) {6275 timer = timers[ i ];6276 // Run the timer and safely remove it when done (allowing for external removal)6277 if ( !timer() && timers[ i ] === timer ) {6278 timers.splice( i--, 1 );6279 }6280 }6281 if ( !timers.length ) {6282 jQuery.fx.stop();6283 }6284 fxNow = undefined;6285};6286jQuery.fx.timer = function( timer ) {6287 jQuery.timers.push( timer );6288 jQuery.fx.start();6289};6290jQuery.fx.interval = 13;6291jQuery.fx.start = function() {6292 if ( inProgress ) {6293 return;6294 }6295 inProgress = true;6296 schedule();6297};6298jQuery.fx.stop = function() {6299 inProgress = null;6300};6301jQuery.fx.speeds = {6302 slow: 600,6303 fast: 200,6304 // Default speed6305 _default: 4006306};6307// Based off of the plugin by Clint Helfers, with permission.6308// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/6309jQuery.fn.delay = function( time, type ) {6310 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;6311 type = type || "fx";6312 return this.queue( type, function( next, hooks ) {6313 var timeout = window.setTimeout( next, time );6314 hooks.stop = function() {6315 window.clearTimeout( timeout );6316 };6317 } );6318};6319( function() {6320 var input = document.createElement( "input" ),6321 select = document.createElement( "select" ),6322 opt = select.appendChild( document.createElement( "option" ) );6323 input.type = "checkbox";6324 // Support: Android <=4.3 only6325 // Default value for a checkbox should be "on"6326 support.checkOn = input.value !== "";6327 // Support: IE <=11 only6328 // Must access selectedIndex to make default options select6329 support.optSelected = opt.selected;6330 // Support: IE <=11 only6331 // An input loses its value after becoming a radio6332 input = document.createElement( "input" );6333 input.value = "t";6334 input.type = "radio";6335 support.radioValue = input.value === "t";6336} )();6337var boolHook,6338 attrHandle = jQuery.expr.attrHandle;6339jQuery.fn.extend( {6340 attr: function( name, value ) {6341 return access( this, jQuery.attr, name, value, arguments.length > 1 );6342 },6343 removeAttr: function( name ) {6344 return this.each( function() {6345 jQuery.removeAttr( this, name );6346 } );6347 }6348} );6349jQuery.extend( {6350 attr: function( elem, name, value ) {6351 var ret, hooks,6352 nType = elem.nodeType;6353 // Don't get/set attributes on text, comment and attribute nodes6354 if ( nType === 3 || nType === 8 || nType === 2 ) {6355 return;6356 }6357 // Fallback to prop when attributes are not supported6358 if ( typeof elem.getAttribute === "undefined" ) {6359 return jQuery.prop( elem, name, value );6360 }6361 // Attribute hooks are determined by the lowercase version6362 // Grab necessary hook if one is defined6363 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {6364 hooks = jQuery.attrHooks[ name.toLowerCase() ] ||6365 ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );6366 }6367 if ( value !== undefined ) {6368 if ( value === null ) {6369 jQuery.removeAttr( elem, name );6370 return;6371 }6372 if ( hooks && "set" in hooks &&6373 ( ret = hooks.set( elem, value, name ) ) !== undefined ) {6374 return ret;6375 }6376 elem.setAttribute( name, value + "" );6377 return value;6378 }6379 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {6380 return ret;6381 }6382 ret = jQuery.find.attr( elem, name );6383 // Non-existent attributes return null, we normalize to undefined6384 return ret == null ? undefined : ret;6385 },6386 attrHooks: {6387 type: {6388 set: function( elem, value ) {6389 if ( !support.radioValue && value === "radio" &&6390 nodeName( elem, "input" ) ) {6391 var val = elem.value;6392 elem.setAttribute( "type", value );6393 if ( val ) {6394 elem.value = val;6395 }6396 return value;6397 }6398 }6399 }6400 },6401 removeAttr: function( elem, value ) {6402 var name,6403 i = 0,6404 // Attribute names can contain non-HTML whitespace characters6405 // https://html.spec.whatwg.org/multipage/syntax.html#attributes-26406 attrNames = value && value.match( rnothtmlwhite );6407 if ( attrNames && elem.nodeType === 1 ) {6408 while ( ( name = attrNames[ i++ ] ) ) {6409 elem.removeAttribute( name );6410 }6411 }6412 }6413} );6414// Hooks for boolean attributes6415boolHook = {6416 set: function( elem, value, name ) {6417 if ( value === false ) {6418 // Remove boolean attributes when set to false6419 jQuery.removeAttr( elem, name );6420 } else {6421 elem.setAttribute( name, name );6422 }6423 return name;6424 }6425};6426jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {6427 var getter = attrHandle[ name ] || jQuery.find.attr;6428 attrHandle[ name ] = function( elem, name, isXML ) {6429 var ret, handle,6430 lowercaseName = name.toLowerCase();6431 if ( !isXML ) {6432 // Avoid an infinite loop by temporarily removing this function from the getter6433 handle = attrHandle[ lowercaseName ];6434 attrHandle[ lowercaseName ] = ret;6435 ret = getter( elem, name, isXML ) != null ?6436 lowercaseName :6437 null;6438 attrHandle[ lowercaseName ] = handle;6439 }6440 return ret;6441 };6442} );6443var rfocusable = /^(?:input|select|textarea|button)$/i,6444 rclickable = /^(?:a|area)$/i;6445jQuery.fn.extend( {6446 prop: function( name, value ) {6447 return access( this, jQuery.prop, name, value, arguments.length > 1 );6448 },6449 removeProp: function( name ) {6450 return this.each( function() {6451 delete this[ jQuery.propFix[ name ] || name ];6452 } );6453 }6454} );6455jQuery.extend( {6456 prop: function( elem, name, value ) {6457 var ret, hooks,6458 nType = elem.nodeType;6459 // Don't get/set properties on text, comment and attribute nodes6460 if ( nType === 3 || nType === 8 || nType === 2 ) {6461 return;6462 }6463 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {6464 // Fix name and attach hooks6465 name = jQuery.propFix[ name ] || name;6466 hooks = jQuery.propHooks[ name ];6467 }6468 if ( value !== undefined ) {6469 if ( hooks && "set" in hooks &&6470 ( ret = hooks.set( elem, value, name ) ) !== undefined ) {6471 return ret;6472 }6473 return ( elem[ name ] = value );6474 }6475 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {6476 return ret;6477 }6478 return elem[ name ];6479 },6480 propHooks: {6481 tabIndex: {6482 get: function( elem ) {6483 // Support: IE <=9 - 11 only6484 // elem.tabIndex doesn't always return the6485 // correct value when it hasn't been explicitly set6486 // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/6487 // Use proper attribute retrieval(#12072)6488 var tabindex = jQuery.find.attr( elem, "tabindex" );6489 if ( tabindex ) {6490 return parseInt( tabindex, 10 );6491 }6492 if (6493 rfocusable.test( elem.nodeName ) ||6494 rclickable.test( elem.nodeName ) &&6495 elem.href6496 ) {6497 return 0;6498 }6499 return -1;6500 }6501 }6502 },6503 propFix: {6504 "for": "htmlFor",6505 "class": "className"6506 }6507} );6508// Support: IE <=11 only6509// Accessing the selectedIndex property6510// forces the browser to respect setting selected6511// on the option6512// The getter ensures a default option is selected6513// when in an optgroup6514// eslint rule "no-unused-expressions" is disabled for this code6515// since it considers such accessions noop6516if ( !support.optSelected ) {6517 jQuery.propHooks.selected = {6518 get: function( elem ) {6519 /* eslint no-unused-expressions: "off" */6520 var parent = elem.parentNode;6521 if ( parent && parent.parentNode ) {6522 parent.parentNode.selectedIndex;6523 }6524 return null;6525 },6526 set: function( elem ) {6527 /* eslint no-unused-expressions: "off" */6528 var parent = elem.parentNode;6529 if ( parent ) {6530 parent.selectedIndex;6531 if ( parent.parentNode ) {6532 parent.parentNode.selectedIndex;6533 }6534 }6535 }6536 };6537}6538jQuery.each( [6539 "tabIndex",6540 "readOnly",6541 "maxLength",6542 "cellSpacing",6543 "cellPadding",6544 "rowSpan",6545 "colSpan",6546 "useMap",6547 "frameBorder",6548 "contentEditable"6549], function() {6550 jQuery.propFix[ this.toLowerCase() ] = this;6551} );6552 // Strip and collapse whitespace according to HTML spec6553 // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace6554 function stripAndCollapse( value ) {6555 var tokens = value.match( rnothtmlwhite ) || [];6556 return tokens.join( " " );6557 }6558function getClass( elem ) {6559 return elem.getAttribute && elem.getAttribute( "class" ) || "";6560}6561function classesToArray( value ) {6562 if ( Array.isArray( value ) ) {6563 return value;6564 }6565 if ( typeof value === "string" ) {6566 return value.match( rnothtmlwhite ) || [];6567 }6568 return [];6569}6570jQuery.fn.extend( {6571 addClass: function( value ) {6572 var classes, elem, cur, curValue, clazz, j, finalValue,6573 i = 0;6574 if ( isFunction( value ) ) {6575 return this.each( function( j ) {6576 jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );6577 } );6578 }6579 classes = classesToArray( value );6580 if ( classes.length ) {6581 while ( ( elem = this[ i++ ] ) ) {6582 curValue = getClass( elem );6583 cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );6584 if ( cur ) {6585 j = 0;6586 while ( ( clazz = classes[ j++ ] ) ) {6587 if ( cur.indexOf( " " + clazz + " " ) < 0 ) {6588 cur += clazz + " ";6589 }6590 }6591 // Only assign if different to avoid unneeded rendering.6592 finalValue = stripAndCollapse( cur );6593 if ( curValue !== finalValue ) {6594 elem.setAttribute( "class", finalValue );6595 }6596 }6597 }6598 }6599 return this;6600 },6601 removeClass: function( value ) {6602 var classes, elem, cur, curValue, clazz, j, finalValue,6603 i = 0;6604 if ( isFunction( value ) ) {6605 return this.each( function( j ) {6606 jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );6607 } );6608 }6609 if ( !arguments.length ) {6610 return this.attr( "class", "" );6611 }6612 classes = classesToArray( value );6613 if ( classes.length ) {6614 while ( ( elem = this[ i++ ] ) ) {6615 curValue = getClass( elem );6616 // This expression is here for better compressibility (see addClass)6617 cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );6618 if ( cur ) {6619 j = 0;6620 while ( ( clazz = classes[ j++ ] ) ) {6621 // Remove *all* instances6622 while ( cur.indexOf( " " + clazz + " " ) > -1 ) {6623 cur = cur.replace( " " + clazz + " ", " " );6624 }6625 }6626 // Only assign if different to avoid unneeded rendering.6627 finalValue = stripAndCollapse( cur );6628 if ( curValue !== finalValue ) {6629 elem.setAttribute( "class", finalValue );6630 }6631 }6632 }6633 }6634 return this;6635 },6636 toggleClass: function( value, stateVal ) {6637 var type = typeof value,6638 isValidValue = type === "string" || Array.isArray( value );6639 if ( typeof stateVal === "boolean" && isValidValue ) {6640 return stateVal ? this.addClass( value ) : this.removeClass( value );6641 }6642 if ( isFunction( value ) ) {6643 return this.each( function( i ) {6644 jQuery( this ).toggleClass(6645 value.call( this, i, getClass( this ), stateVal ),6646 stateVal6647 );6648 } );6649 }6650 return this.each( function() {6651 var className, i, self, classNames;6652 if ( isValidValue ) {6653 // Toggle individual class names6654 i = 0;6655 self = jQuery( this );6656 classNames = classesToArray( value );6657 while ( ( className = classNames[ i++ ] ) ) {6658 // Check each className given, space separated list6659 if ( self.hasClass( className ) ) {6660 self.removeClass( className );6661 } else {6662 self.addClass( className );6663 }6664 }6665 // Toggle whole class name6666 } else if ( value === undefined || type === "boolean" ) {6667 className = getClass( this );6668 if ( className ) {6669 // Store className if set6670 dataPriv.set( this, "__className__", className );6671 }6672 // If the element has a class name or if we're passed `false`,6673 // then remove the whole classname (if there was one, the above saved it).6674 // Otherwise bring back whatever was previously saved (if anything),6675 // falling back to the empty string if nothing was stored.6676 if ( this.setAttribute ) {6677 this.setAttribute( "class",6678 className || value === false ?6679 "" :6680 dataPriv.get( this, "__className__" ) || ""6681 );6682 }6683 }6684 } );6685 },6686 hasClass: function( selector ) {6687 var className, elem,6688 i = 0;6689 className = " " + selector + " ";6690 while ( ( elem = this[ i++ ] ) ) {6691 if ( elem.nodeType === 1 &&6692 ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {6693 return true;6694 }6695 }6696 return false;6697 }6698} );6699var rreturn = /\r/g;6700jQuery.fn.extend( {6701 val: function( value ) {6702 var hooks, ret, valueIsFunction,6703 elem = this[ 0 ];6704 if ( !arguments.length ) {6705 if ( elem ) {6706 hooks = jQuery.valHooks[ elem.type ] ||6707 jQuery.valHooks[ elem.nodeName.toLowerCase() ];6708 if ( hooks &&6709 "get" in hooks &&6710 ( ret = hooks.get( elem, "value" ) ) !== undefined6711 ) {6712 return ret;6713 }6714 ret = elem.value;6715 // Handle most common string cases6716 if ( typeof ret === "string" ) {6717 return ret.replace( rreturn, "" );6718 }6719 // Handle cases where value is null/undef or number6720 return ret == null ? "" : ret;6721 }6722 return;6723 }6724 valueIsFunction = isFunction( value );6725 return this.each( function( i ) {6726 var val;6727 if ( this.nodeType !== 1 ) {6728 return;6729 }6730 if ( valueIsFunction ) {6731 val = value.call( this, i, jQuery( this ).val() );6732 } else {6733 val = value;6734 }6735 // Treat null/undefined as ""; convert numbers to string6736 if ( val == null ) {6737 val = "";6738 } else if ( typeof val === "number" ) {6739 val += "";6740 } else if ( Array.isArray( val ) ) {6741 val = jQuery.map( val, function( value ) {6742 return value == null ? "" : value + "";6743 } );6744 }6745 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];6746 // If set returns undefined, fall back to normal setting6747 if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {6748 this.value = val;6749 }6750 } );6751 }6752} );6753jQuery.extend( {6754 valHooks: {6755 option: {6756 get: function( elem ) {6757 var val = jQuery.find.attr( elem, "value" );6758 return val != null ?6759 val :6760 // Support: IE <=10 - 11 only6761 // option.text throws exceptions (#14686, #14858)6762 // Strip and collapse whitespace6763 // https://html.spec.whatwg.org/#strip-and-collapse-whitespace6764 stripAndCollapse( jQuery.text( elem ) );6765 }6766 },6767 select: {6768 get: function( elem ) {6769 var value, option, i,6770 options = elem.options,6771 index = elem.selectedIndex,6772 one = elem.type === "select-one",6773 values = one ? null : [],6774 max = one ? index + 1 : options.length;6775 if ( index < 0 ) {6776 i = max;6777 } else {6778 i = one ? index : 0;6779 }6780 // Loop through all the selected options6781 for ( ; i < max; i++ ) {6782 option = options[ i ];6783 // Support: IE <=9 only6784 // IE8-9 doesn't update selected after form reset (#2551)6785 if ( ( option.selected || i === index ) &&6786 // Don't return options that are disabled or in a disabled optgroup6787 !option.disabled &&6788 ( !option.parentNode.disabled ||6789 !nodeName( option.parentNode, "optgroup" ) ) ) {6790 // Get the specific value for the option6791 value = jQuery( option ).val();6792 // We don't need an array for one selects6793 if ( one ) {6794 return value;6795 }6796 // Multi-Selects return an array6797 values.push( value );6798 }6799 }6800 return values;6801 },6802 set: function( elem, value ) {6803 var optionSet, option,6804 options = elem.options,6805 values = jQuery.makeArray( value ),6806 i = options.length;6807 while ( i-- ) {6808 option = options[ i ];6809 /* eslint-disable no-cond-assign */6810 if ( option.selected =6811 jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -16812 ) {6813 optionSet = true;6814 }6815 /* eslint-enable no-cond-assign */6816 }6817 // Force browsers to behave consistently when non-matching value is set6818 if ( !optionSet ) {6819 elem.selectedIndex = -1;6820 }6821 return values;6822 }6823 }6824 }6825} );6826// Radios and checkboxes getter/setter6827jQuery.each( [ "radio", "checkbox" ], function() {6828 jQuery.valHooks[ this ] = {6829 set: function( elem, value ) {6830 if ( Array.isArray( value ) ) {6831 return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );6832 }6833 }6834 };6835 if ( !support.checkOn ) {6836 jQuery.valHooks[ this ].get = function( elem ) {6837 return elem.getAttribute( "value" ) === null ? "on" : elem.value;6838 };6839 }6840} );6841// Return jQuery for attributes-only inclusion6842support.focusin = "onfocusin" in window;6843var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,6844 stopPropagationcallback = function( e ) {6845 e.stopPropagation();6846 };6847jQuery.extend( jQuery.event, {6848 trigger: function( event, data, elem, onlyHandlers ) {6849 var i, cur, tmp, bubbleType, ontype, handle, special, lastElement,6850 eventPath = [ elem || document ],6851 type = hasOwn.call( event, "type" ) ? event.type : event,6852 namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];6853 cur = lastElement = tmp = elem = elem || document;6854 // Don't do events on text and comment nodes6855 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {6856 return;6857 }6858 // focus/blur morphs to focusin/out; ensure we're not firing them right now6859 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {6860 return;6861 }6862 if ( type.indexOf( "." ) > -1 ) {6863 // Namespaced trigger; create a regexp to match event type in handle()6864 namespaces = type.split( "." );6865 type = namespaces.shift();6866 namespaces.sort();6867 }6868 ontype = type.indexOf( ":" ) < 0 && "on" + type;6869 // Caller can pass in a jQuery.Event object, Object, or just an event type string6870 event = event[ jQuery.expando ] ?6871 event :6872 new jQuery.Event( type, typeof event === "object" && event );6873 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)6874 event.isTrigger = onlyHandlers ? 2 : 3;6875 event.namespace = namespaces.join( "." );6876 event.rnamespace = event.namespace ?6877 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :6878 null;6879 // Clean up the event in case it is being reused6880 event.result = undefined;6881 if ( !event.target ) {6882 event.target = elem;6883 }6884 // Clone any incoming data and prepend the event, creating the handler arg list6885 data = data == null ?6886 [ event ] :6887 jQuery.makeArray( data, [ event ] );6888 // Allow special events to draw outside the lines6889 special = jQuery.event.special[ type ] || {};6890 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {6891 return;6892 }6893 // Determine event propagation path in advance, per W3C events spec (#9951)6894 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)6895 if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {6896 bubbleType = special.delegateType || type;6897 if ( !rfocusMorph.test( bubbleType + type ) ) {6898 cur = cur.parentNode;6899 }6900 for ( ; cur; cur = cur.parentNode ) {6901 eventPath.push( cur );6902 tmp = cur;6903 }6904 // Only add window if we got to document (e.g., not plain obj or detached DOM)6905 if ( tmp === ( elem.ownerDocument || document ) ) {6906 eventPath.push( tmp.defaultView || tmp.parentWindow || window );6907 }6908 }6909 // Fire handlers on the event path6910 i = 0;6911 while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {6912 lastElement = cur;6913 event.type = i > 1 ?6914 bubbleType :6915 special.bindType || type;6916 // jQuery handler6917 handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&6918 dataPriv.get( cur, "handle" );6919 if ( handle ) {6920 handle.apply( cur, data );6921 }6922 // Native handler6923 handle = ontype && cur[ ontype ];6924 if ( handle && handle.apply && acceptData( cur ) ) {6925 event.result = handle.apply( cur, data );6926 if ( event.result === false ) {6927 event.preventDefault();6928 }6929 }6930 }6931 event.type = type;6932 // If nobody prevented the default action, do it now6933 if ( !onlyHandlers && !event.isDefaultPrevented() ) {6934 if ( ( !special._default ||6935 special._default.apply( eventPath.pop(), data ) === false ) &&6936 acceptData( elem ) ) {6937 // Call a native DOM method on the target with the same name as the event.6938 // Don't do default actions on window, that's where global variables be (#6170)6939 if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {6940 // Don't re-trigger an onFOO event when we call its FOO() method6941 tmp = elem[ ontype ];6942 if ( tmp ) {6943 elem[ ontype ] = null;6944 }6945 // Prevent re-triggering of the same event, since we already bubbled it above6946 jQuery.event.triggered = type;6947 if ( event.isPropagationStopped() ) {6948 lastElement.addEventListener( type, stopPropagationcallback );6949 }6950 elem[ type ]();6951 if ( event.isPropagationStopped() ) {6952 lastElement.removeEventListener( type, stopPropagationcallback );6953 }6954 jQuery.event.triggered = undefined;6955 if ( tmp ) {6956 elem[ ontype ] = tmp;6957 }6958 }6959 }6960 }6961 return event.result;6962 },6963 // Piggyback on a donor event to simulate a different one6964 // Used only for `focus(in | out)` events6965 simulate: function( type, elem, event ) {6966 var e = jQuery.extend(6967 new jQuery.Event(),6968 event,6969 {6970 type: type,6971 isSimulated: true6972 }6973 );6974 jQuery.event.trigger( e, null, elem );6975 }6976} );6977jQuery.fn.extend( {6978 trigger: function( type, data ) {6979 return this.each( function() {6980 jQuery.event.trigger( type, data, this );6981 } );6982 },6983 triggerHandler: function( type, data ) {6984 var elem = this[ 0 ];6985 if ( elem ) {6986 return jQuery.event.trigger( type, data, elem, true );6987 }6988 }6989} );6990// Support: Firefox <=446991// Firefox doesn't have focus(in | out) events6992// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=6877876993//6994// Support: Chrome <=48 - 49, Safari <=9.0 - 9.16995// focus(in | out) events fire after focus & blur events,6996// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order6997// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=4498576998if ( !support.focusin ) {6999 jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {7000 // Attach a single capturing handler on the document while someone wants focusin/focusout7001 var handler = function( event ) {7002 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );7003 };7004 jQuery.event.special[ fix ] = {7005 setup: function() {7006 var doc = this.ownerDocument || this,7007 attaches = dataPriv.access( doc, fix );7008 if ( !attaches ) {7009 doc.addEventListener( orig, handler, true );7010 }7011 dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );7012 },7013 teardown: function() {7014 var doc = this.ownerDocument || this,7015 attaches = dataPriv.access( doc, fix ) - 1;7016 if ( !attaches ) {7017 doc.removeEventListener( orig, handler, true );7018 dataPriv.remove( doc, fix );7019 } else {7020 dataPriv.access( doc, fix, attaches );7021 }7022 }7023 };7024 } );7025}7026var location = window.location;7027var nonce = Date.now();7028var rquery = ( /\?/ );7029// Cross-browser xml parsing7030jQuery.parseXML = function( data ) {7031 var xml;7032 if ( !data || typeof data !== "string" ) {7033 return null;7034 }7035 // Support: IE 9 - 11 only7036 // IE throws on parseFromString with invalid input.7037 try {7038 xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );7039 } catch ( e ) {7040 xml = undefined;7041 }7042 if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {7043 jQuery.error( "Invalid XML: " + data );7044 }7045 return xml;7046};7047var7048 rbracket = /\[\]$/,7049 rCRLF = /\r?\n/g,7050 rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,7051 rsubmittable = /^(?:input|select|textarea|keygen)/i;7052function buildParams( prefix, obj, traditional, add ) {7053 var name;7054 if ( Array.isArray( obj ) ) {7055 // Serialize array item.7056 jQuery.each( obj, function( i, v ) {7057 if ( traditional || rbracket.test( prefix ) ) {7058 // Treat each array item as a scalar.7059 add( prefix, v );7060 } else {7061 // Item is non-scalar (array or object), encode its numeric index.7062 buildParams(7063 prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",7064 v,7065 traditional,7066 add7067 );7068 }7069 } );7070 } else if ( !traditional && toType( obj ) === "object" ) {7071 // Serialize object item.7072 for ( name in obj ) {7073 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );7074 }7075 } else {7076 // Serialize scalar item.7077 add( prefix, obj );7078 }7079}7080// Serialize an array of form elements or a set of7081// key/values into a query string7082jQuery.param = function( a, traditional ) {7083 var prefix,7084 s = [],7085 add = function( key, valueOrFunction ) {7086 // If value is a function, invoke it and use its return value7087 var value = isFunction( valueOrFunction ) ?7088 valueOrFunction() :7089 valueOrFunction;7090 s[ s.length ] = encodeURIComponent( key ) + "=" +7091 encodeURIComponent( value == null ? "" : value );7092 };7093 if ( a == null ) {7094 return "";7095 }7096 // If an array was passed in, assume that it is an array of form elements.7097 if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {7098 // Serialize the form elements7099 jQuery.each( a, function() {7100 add( this.name, this.value );7101 } );7102 } else {7103 // If traditional, encode the "old" way (the way 1.3.2 or older7104 // did it), otherwise encode params recursively.7105 for ( prefix in a ) {7106 buildParams( prefix, a[ prefix ], traditional, add );7107 }7108 }7109 // Return the resulting serialization7110 return s.join( "&" );7111};7112jQuery.fn.extend( {7113 serialize: function() {7114 return jQuery.param( this.serializeArray() );7115 },7116 serializeArray: function() {7117 return this.map( function() {7118 // Can add propHook for "elements" to filter or add form elements7119 var elements = jQuery.prop( this, "elements" );7120 return elements ? jQuery.makeArray( elements ) : this;7121 } )7122 .filter( function() {7123 var type = this.type;7124 // Use .is( ":disabled" ) so that fieldset[disabled] works7125 return this.name && !jQuery( this ).is( ":disabled" ) &&7126 rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&7127 ( this.checked || !rcheckableType.test( type ) );7128 } )7129 .map( function( i, elem ) {7130 var val = jQuery( this ).val();7131 if ( val == null ) {7132 return null;7133 }7134 if ( Array.isArray( val ) ) {7135 return jQuery.map( val, function( val ) {7136 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };7137 } );7138 }7139 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };7140 } ).get();7141 }7142} );7143var7144 r20 = /%20/g,7145 rhash = /#.*$/,7146 rantiCache = /([?&])_=[^&]*/,7147 rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,7148 // #7653, #8125, #8152: local protocol detection7149 rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,7150 rnoContent = /^(?:GET|HEAD)$/,7151 rprotocol = /^\/\//,7152 /* Prefilters7153 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)7154 * 2) These are called:7155 * - BEFORE asking for a transport7156 * - AFTER param serialization (s.data is a string if s.processData is true)7157 * 3) key is the dataType7158 * 4) the catchall symbol "*" can be used7159 * 5) execution will start with transport dataType and THEN continue down to "*" if needed7160 */7161 prefilters = {},7162 /* Transports bindings7163 * 1) key is the dataType7164 * 2) the catchall symbol "*" can be used7165 * 3) selection will start with transport dataType and THEN go to "*" if needed7166 */7167 transports = {},7168 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression7169 allTypes = "*/".concat( "*" ),7170 // Anchor tag for parsing the document origin7171 originAnchor = document.createElement( "a" );7172 originAnchor.href = location.href;7173// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport7174function addToPrefiltersOrTransports( structure ) {7175 // dataTypeExpression is optional and defaults to "*"7176 return function( dataTypeExpression, func ) {7177 if ( typeof dataTypeExpression !== "string" ) {7178 func = dataTypeExpression;7179 dataTypeExpression = "*";7180 }7181 var dataType,7182 i = 0,7183 dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];7184 if ( isFunction( func ) ) {7185 // For each dataType in the dataTypeExpression7186 while ( ( dataType = dataTypes[ i++ ] ) ) {7187 // Prepend if requested7188 if ( dataType[ 0 ] === "+" ) {7189 dataType = dataType.slice( 1 ) || "*";7190 ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );7191 // Otherwise append7192 } else {7193 ( structure[ dataType ] = structure[ dataType ] || [] ).push( func );7194 }7195 }7196 }7197 };7198}7199// Base inspection function for prefilters and transports7200function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {7201 var inspected = {},7202 seekingTransport = ( structure === transports );7203 function inspect( dataType ) {7204 var selected;7205 inspected[ dataType ] = true;7206 jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {7207 var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );7208 if ( typeof dataTypeOrTransport === "string" &&7209 !seekingTransport && !inspected[ dataTypeOrTransport ] ) {7210 options.dataTypes.unshift( dataTypeOrTransport );7211 inspect( dataTypeOrTransport );7212 return false;7213 } else if ( seekingTransport ) {7214 return !( selected = dataTypeOrTransport );7215 }7216 } );7217 return selected;7218 }7219 return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );7220}7221// A special extend for ajax options7222// that takes "flat" options (not to be deep extended)7223// Fixes #98877224function ajaxExtend( target, src ) {7225 var key, deep,7226 flatOptions = jQuery.ajaxSettings.flatOptions || {};7227 for ( key in src ) {7228 if ( src[ key ] !== undefined ) {7229 ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];7230 }7231 }7232 if ( deep ) {7233 jQuery.extend( true, target, deep );7234 }7235 return target;7236}7237/* Handles responses to an ajax request:7238 * - finds the right dataType (mediates between content-type and expected dataType)7239 * - returns the corresponding response7240 */7241function ajaxHandleResponses( s, jqXHR, responses ) {7242 var ct, type, finalDataType, firstDataType,7243 contents = s.contents,7244 dataTypes = s.dataTypes;7245 // Remove auto dataType and get content-type in the process7246 while ( dataTypes[ 0 ] === "*" ) {7247 dataTypes.shift();7248 if ( ct === undefined ) {7249 ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );7250 }7251 }7252 // Check if we're dealing with a known content-type7253 if ( ct ) {7254 for ( type in contents ) {7255 if ( contents[ type ] && contents[ type ].test( ct ) ) {7256 dataTypes.unshift( type );7257 break;7258 }7259 }7260 }7261 // Check to see if we have a response for the expected dataType7262 if ( dataTypes[ 0 ] in responses ) {7263 finalDataType = dataTypes[ 0 ];7264 } else {7265 // Try convertible dataTypes7266 for ( type in responses ) {7267 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {7268 finalDataType = type;7269 break;7270 }7271 if ( !firstDataType ) {7272 firstDataType = type;7273 }7274 }7275 // Or just use first one7276 finalDataType = finalDataType || firstDataType;7277 }7278 // If we found a dataType7279 // We add the dataType to the list if needed7280 // and return the corresponding response7281 if ( finalDataType ) {7282 if ( finalDataType !== dataTypes[ 0 ] ) {7283 dataTypes.unshift( finalDataType );7284 }7285 return responses[ finalDataType ];7286 }7287}7288/* Chain conversions given the request and the original response7289 * Also sets the responseXXX fields on the jqXHR instance7290 */7291function ajaxConvert( s, response, jqXHR, isSuccess ) {7292 var conv2, current, conv, tmp, prev,7293 converters = {},7294 // Work with a copy of dataTypes in case we need to modify it for conversion7295 dataTypes = s.dataTypes.slice();7296 // Create converters map with lowercased keys7297 if ( dataTypes[ 1 ] ) {7298 for ( conv in s.converters ) {7299 converters[ conv.toLowerCase() ] = s.converters[ conv ];7300 }7301 }7302 current = dataTypes.shift();7303 // Convert to each sequential dataType7304 while ( current ) {7305 if ( s.responseFields[ current ] ) {7306 jqXHR[ s.responseFields[ current ] ] = response;7307 }7308 // Apply the dataFilter if provided7309 if ( !prev && isSuccess && s.dataFilter ) {7310 response = s.dataFilter( response, s.dataType );7311 }7312 prev = current;7313 current = dataTypes.shift();7314 if ( current ) {7315 // There's only work to do if current dataType is non-auto7316 if ( current === "*" ) {7317 current = prev;7318 // Convert response if prev dataType is non-auto and differs from current7319 } else if ( prev !== "*" && prev !== current ) {7320 // Seek a direct converter7321 conv = converters[ prev + " " + current ] || converters[ "* " + current ];7322 // If none found, seek a pair7323 if ( !conv ) {7324 for ( conv2 in converters ) {7325 // If conv2 outputs current7326 tmp = conv2.split( " " );7327 if ( tmp[ 1 ] === current ) {7328 // If prev can be converted to accepted input7329 conv = converters[ prev + " " + tmp[ 0 ] ] ||7330 converters[ "* " + tmp[ 0 ] ];7331 if ( conv ) {7332 // Condense equivalence converters7333 if ( conv === true ) {7334 conv = converters[ conv2 ];7335 // Otherwise, insert the intermediate dataType7336 } else if ( converters[ conv2 ] !== true ) {7337 current = tmp[ 0 ];7338 dataTypes.unshift( tmp[ 1 ] );7339 }7340 break;7341 }7342 }7343 }7344 }7345 // Apply converter (if not an equivalence)7346 if ( conv !== true ) {7347 // Unless errors are allowed to bubble, catch and return them7348 if ( conv && s.throws ) {7349 response = conv( response );7350 } else {7351 try {7352 response = conv( response );7353 } catch ( e ) {7354 return {7355 state: "parsererror",7356 error: conv ? e : "No conversion from " + prev + " to " + current7357 };7358 }7359 }7360 }7361 }7362 }7363 }7364 return { state: "success", data: response };7365}7366jQuery.extend( {7367 // Counter for holding the number of active queries7368 active: 0,7369 // Last-Modified header cache for next request7370 lastModified: {},7371 etag: {},7372 ajaxSettings: {7373 url: location.href,7374 type: "GET",7375 isLocal: rlocalProtocol.test( location.protocol ),7376 global: true,7377 processData: true,7378 async: true,7379 contentType: "application/x-www-form-urlencoded; charset=UTF-8",7380 /*7381 timeout: 0,7382 data: null,7383 dataType: null,7384 username: null,7385 password: null,7386 cache: null,7387 throws: false,7388 traditional: false,7389 headers: {},7390 */7391 accepts: {7392 "*": allTypes,7393 text: "text/plain",7394 html: "text/html",7395 xml: "application/xml, text/xml",7396 json: "application/json, text/javascript"7397 },7398 contents: {7399 xml: /\bxml\b/,7400 html: /\bhtml/,7401 json: /\bjson\b/7402 },7403 responseFields: {7404 xml: "responseXML",7405 text: "responseText",7406 json: "responseJSON"7407 },7408 // Data converters7409 // Keys separate source (or catchall "*") and destination types with a single space7410 converters: {7411 // Convert anything to text7412 "* text": String,7413 // Text to html (true = no transformation)7414 "text html": true,7415 // Evaluate text as a json expression7416 "text json": JSON.parse,7417 // Parse text as xml7418 "text xml": jQuery.parseXML7419 },7420 // For options that shouldn't be deep extended:7421 // you can add your own custom options here if7422 // and when you create one that shouldn't be7423 // deep extended (see ajaxExtend)7424 flatOptions: {7425 url: true,7426 context: true7427 }7428 },7429 // Creates a full fledged settings object into target7430 // with both ajaxSettings and settings fields.7431 // If target is omitted, writes into ajaxSettings.7432 ajaxSetup: function( target, settings ) {7433 return settings ?7434 // Building a settings object7435 ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :7436 // Extending ajaxSettings7437 ajaxExtend( jQuery.ajaxSettings, target );7438 },7439 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),7440 ajaxTransport: addToPrefiltersOrTransports( transports ),7441 // Main method7442 ajax: function( url, options ) {7443 // If url is an object, simulate pre-1.5 signature7444 if ( typeof url === "object" ) {7445 options = url;7446 url = undefined;7447 }7448 // Force options to be an object7449 options = options || {};7450 var transport,7451 // URL without anti-cache param7452 cacheURL,7453 // Response headers7454 responseHeadersString,7455 responseHeaders,7456 // timeout handle7457 timeoutTimer,7458 // Url cleanup var7459 urlAnchor,7460 // Request state (becomes false upon send and true upon completion)7461 completed,7462 // To know if global events are to be dispatched7463 fireGlobals,7464 // Loop variable7465 i,7466 // uncached part of the url7467 uncached,7468 // Create the final options object7469 s = jQuery.ajaxSetup( {}, options ),7470 // callbacks context7471 callbackContext = s.context || s,7472 // Context for global events is callbackContext if it is a DOM node or jQuery collection7473 globalEventContext = s.context &&7474 ( callbackContext.nodeType || callbackContext.jquery ) ?7475 jQuery( callbackContext ) :7476 jQuery.event,7477 // Deferreds7478 deferred = jQuery.Deferred(),7479 completeDeferred = jQuery.callbacks( "once memory" ),7480 // Status-dependent callbacks7481 statusCode = s.statusCode || {},7482 // Headers (they are sent all at once)7483 requestHeaders = {},7484 requestHeadersNames = {},7485 // Default abort message7486 strAbort = "canceled",7487 // Fake xhr7488 jqXHR = {7489 readyState: 0,7490 // Builds headers hashtable if needed7491 getResponseHeader: function( key ) {7492 var match;7493 if ( completed ) {7494 if ( !responseHeaders ) {7495 responseHeaders = {};7496 while ( ( match = rheaders.exec( responseHeadersString ) ) ) {7497 responseHeaders[ match[ 1 ].toLowerCase() + " " ] =7498 ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] )7499 .concat( match[ 2 ] );7500 }7501 }7502 match = responseHeaders[ key.toLowerCase() + " " ];7503 }7504 return match == null ? null : match.join( ", " );7505 },7506 // Raw string7507 getAllResponseHeaders: function() {7508 return completed ? responseHeadersString : null;7509 },7510 // Caches the header7511 setRequestHeader: function( name, value ) {7512 if ( completed == null ) {7513 name = requestHeadersNames[ name.toLowerCase() ] =7514 requestHeadersNames[ name.toLowerCase() ] || name;7515 requestHeaders[ name ] = value;7516 }7517 return this;7518 },7519 // Overrides response content-type header7520 overrideMimeType: function( type ) {7521 if ( completed == null ) {7522 s.mimeType = type;7523 }7524 return this;7525 },7526 // Status-dependent callbacks7527 statusCode: function( map ) {7528 var code;7529 if ( map ) {7530 if ( completed ) {7531 // Execute the appropriate callbacks7532 jqXHR.always( map[ jqXHR.status ] );7533 } else {7534 // Lazy-add the new callbacks in a way that preserves old ones7535 for ( code in map ) {7536 statusCode[ code ] = [ statusCode[ code ], map[ code ] ];7537 }7538 }7539 }7540 return this;7541 },7542 // Cancel the request7543 abort: function( statusText ) {7544 var finalText = statusText || strAbort;7545 if ( transport ) {7546 transport.abort( finalText );7547 }7548 done( 0, finalText );7549 return this;7550 }7551 };7552 // Attach deferreds7553 deferred.promise( jqXHR );7554 // Add protocol if not provided (prefilters might expect it)7555 // Handle falsy url in the settings object (#10093: consistency with old signature)7556 // We also use the url parameter if available7557 s.url = ( ( url || s.url || location.href ) + "" )7558 .replace( rprotocol, location.protocol + "//" );7559 // Alias method option to type as per ticket #120047560 s.type = options.method || options.type || s.method || s.type;7561 // Extract dataTypes list7562 s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];7563 // A cross-domain request is in order when the origin doesn't match the current origin.7564 if ( s.crossDomain == null ) {7565 urlAnchor = document.createElement( "a" );7566 // Support: IE <=8 - 11, Edge 12 - 157567 // IE throws exception on accessing the href property if url is malformed,7568 // e.g. http://example.com:80x/7569 try {7570 urlAnchor.href = s.url;7571 // Support: IE <=8 - 11 only7572 // Anchor's host property isn't correctly set when s.url is relative7573 urlAnchor.href = urlAnchor.href;7574 s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==7575 urlAnchor.protocol + "//" + urlAnchor.host;7576 } catch ( e ) {7577 // If there is an error parsing the URL, assume it is crossDomain,7578 // it can be rejected by the transport if it is invalid7579 s.crossDomain = true;7580 }7581 }7582 // Convert data if not already a string7583 if ( s.data && s.processData && typeof s.data !== "string" ) {7584 s.data = jQuery.param( s.data, s.traditional );7585 }7586 // Apply prefilters7587 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );7588 // If request was aborted inside a prefilter, stop there7589 if ( completed ) {7590 return jqXHR;7591 }7592 // We can fire global events as of now if asked to7593 // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)7594 fireGlobals = jQuery.event && s.global;7595 // Watch for a new set of requests7596 if ( fireGlobals && jQuery.active++ === 0 ) {7597 jQuery.event.trigger( "ajaxStart" );7598 }7599 // Uppercase the type7600 s.type = s.type.toUpperCase();7601 // Determine if request has content7602 s.hasContent = !rnoContent.test( s.type );7603 // Save the URL in case we're toying with the If-Modified-Since7604 // and/or If-None-Match header later on7605 // Remove hash to simplify url manipulation7606 cacheURL = s.url.replace( rhash, "" );7607 // More options handling for requests with no content7608 if ( !s.hasContent ) {7609 // Remember the hash so we can put it back7610 uncached = s.url.slice( cacheURL.length );7611 // If data is available and should be processed, append data to url7612 if ( s.data && ( s.processData || typeof s.data === "string" ) ) {7613 cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;7614 // #9682: remove data so that it's not used in an eventual retry7615 delete s.data;7616 }7617 // Add or update anti-cache param if needed7618 if ( s.cache === false ) {7619 cacheURL = cacheURL.replace( rantiCache, "$1" );7620 uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached;7621 }7622 // Put hash and anti-cache on the URL that will be requested (gh-1732)7623 s.url = cacheURL + uncached;7624 // Change '%20' to '+' if this is encoded form body content (gh-2658)7625 } else if ( s.data && s.processData &&7626 ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {7627 s.data = s.data.replace( r20, "+" );7628 }7629 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.7630 if ( s.ifModified ) {7631 if ( jQuery.lastModified[ cacheURL ] ) {7632 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );7633 }7634 if ( jQuery.etag[ cacheURL ] ) {7635 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );7636 }7637 }7638 // Set the correct header, if data is being sent7639 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {7640 jqXHR.setRequestHeader( "Content-Type", s.contentType );7641 }7642 // Set the Accepts header for the server, depending on the dataType7643 jqXHR.setRequestHeader(7644 "Accept",7645 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?7646 s.accepts[ s.dataTypes[ 0 ] ] +7647 ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :7648 s.accepts[ "*" ]7649 );7650 // Check for headers option7651 for ( i in s.headers ) {7652 jqXHR.setRequestHeader( i, s.headers[ i ] );7653 }7654 // Allow custom headers/mimetypes and early abort7655 if ( s.beforeSend &&7656 ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {7657 // Abort if not done already and return7658 return jqXHR.abort();7659 }7660 // Aborting is no longer a cancellation7661 strAbort = "abort";7662 // Install callbacks on deferreds7663 completeDeferred.add( s.complete );7664 jqXHR.done( s.success );7665 jqXHR.fail( s.error );7666 // Get transport7667 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );7668 // If no transport, we auto-abort7669 if ( !transport ) {7670 done( -1, "No Transport" );7671 } else {7672 jqXHR.readyState = 1;7673 // Send global event7674 if ( fireGlobals ) {7675 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );7676 }7677 // If request was aborted inside ajaxSend, stop there7678 if ( completed ) {7679 return jqXHR;7680 }7681 // Timeout7682 if ( s.async && s.timeout > 0 ) {7683 timeoutTimer = window.setTimeout( function() {7684 jqXHR.abort( "timeout" );7685 }, s.timeout );7686 }7687 try {7688 completed = false;7689 transport.send( requestHeaders, done );7690 } catch ( e ) {7691 // Rethrow post-completion exceptions7692 if ( completed ) {7693 throw e;7694 }7695 // Propagate others as results7696 done( -1, e );7697 }7698 }7699 // callback for when everything is done7700 function done( status, nativeStatusText, responses, headers ) {7701 var isSuccess, success, error, response, modified,7702 statusText = nativeStatusText;7703 // Ignore repeat invocations7704 if ( completed ) {7705 return;7706 }7707 completed = true;7708 // Clear timeout if it exists7709 if ( timeoutTimer ) {7710 window.clearTimeout( timeoutTimer );7711 }7712 // Dereference transport for early garbage collection7713 // (no matter how long the jqXHR object will be used)7714 transport = undefined;7715 // Cache response headers7716 responseHeadersString = headers || "";7717 // Set readyState7718 jqXHR.readyState = status > 0 ? 4 : 0;7719 // Determine if successful7720 isSuccess = status >= 200 && status < 300 || status === 304;7721 // Get response data7722 if ( responses ) {7723 response = ajaxHandleResponses( s, jqXHR, responses );7724 }7725 // Convert no matter what (that way responseXXX fields are always set)7726 response = ajaxConvert( s, response, jqXHR, isSuccess );7727 // If successful, handle type chaining7728 if ( isSuccess ) {7729 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.7730 if ( s.ifModified ) {7731 modified = jqXHR.getResponseHeader( "Last-Modified" );7732 if ( modified ) {7733 jQuery.lastModified[ cacheURL ] = modified;7734 }7735 modified = jqXHR.getResponseHeader( "etag" );7736 if ( modified ) {7737 jQuery.etag[ cacheURL ] = modified;7738 }7739 }7740 // if no content7741 if ( status === 204 || s.type === "HEAD" ) {7742 statusText = "nocontent";7743 // if not modified7744 } else if ( status === 304 ) {7745 statusText = "notmodified";7746 // If we have data, let's convert it7747 } else {7748 statusText = response.state;7749 success = response.data;7750 error = response.error;7751 isSuccess = !error;7752 }7753 } else {7754 // Extract error from statusText and normalize for non-aborts7755 error = statusText;7756 if ( status || !statusText ) {7757 statusText = "error";7758 if ( status < 0 ) {7759 status = 0;7760 }7761 }7762 }7763 // Set data for the fake xhr object7764 jqXHR.status = status;7765 jqXHR.statusText = ( nativeStatusText || statusText ) + "";7766 // Success/Error7767 if ( isSuccess ) {7768 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );7769 } else {7770 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );7771 }7772 // Status-dependent callbacks7773 jqXHR.statusCode( statusCode );7774 statusCode = undefined;7775 if ( fireGlobals ) {7776 globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",7777 [ jqXHR, s, isSuccess ? success : error ] );7778 }7779 // Complete7780 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );7781 if ( fireGlobals ) {7782 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );7783 // Handle the global AJAX counter7784 if ( !( --jQuery.active ) ) {7785 jQuery.event.trigger( "ajaxStop" );7786 }7787 }7788 }7789 return jqXHR;7790 },7791 getJSON: function( url, data, callback ) {7792 return jQuery.get( url, data, callback, "json" );7793 },7794 getScript: function( url, callback ) {7795 return jQuery.get( url, undefined, callback, "script" );7796 }7797} );7798jQuery.each( [ "get", "post" ], function( i, method ) {7799 jQuery[ method ] = function( url, data, callback, type ) {7800 // Shift arguments if data argument was omitted7801 if ( isFunction( data ) ) {7802 type = type || callback;7803 callback = data;7804 data = undefined;7805 }7806 // The url can be an options object (which then must have .url)7807 return jQuery.ajax( jQuery.extend( {7808 url: url,7809 type: method,7810 dataType: type,7811 data: data,7812 success: callback7813 }, jQuery.isPlainObject( url ) && url ) );7814 };7815} );7816jQuery._evalUrl = function( url, options ) {7817 return jQuery.ajax( {7818 url: url,7819 // Make this explicit, since user can override this through ajaxSetup (#11264)7820 type: "GET",7821 dataType: "script",7822 cache: true,7823 async: false,7824 global: false,7825 // Only evaluate the response if it is successful (gh-4126)7826 // dataFilter is not invoked for failure responses, so using it instead7827 // of the default converter is kludgy but it works.7828 converters: {7829 "text script": function() {}7830 },7831 dataFilter: function( response ) {7832 jQuery.globalEval( response, options );7833 }7834 } );7835};7836jQuery.fn.extend( {7837 wrapAll: function( html ) {7838 var wrap;7839 if ( this[ 0 ] ) {7840 if ( isFunction( html ) ) {7841 html = html.call( this[ 0 ] );7842 }7843 // The elements to wrap the target around7844 wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );7845 if ( this[ 0 ].parentNode ) {7846 wrap.insertBefore( this[ 0 ] );7847 }7848 wrap.map( function() {7849 var elem = this;7850 while ( elem.firstElementChild ) {7851 elem = elem.firstElementChild;7852 }7853 return elem;7854 } ).append( this );7855 }7856 return this;7857 },7858 wrapInner: function( html ) {7859 if ( isFunction( html ) ) {7860 return this.each( function( i ) {7861 jQuery( this ).wrapInner( html.call( this, i ) );7862 } );7863 }7864 return this.each( function() {7865 var self = jQuery( this ),7866 contents = self.contents();7867 if ( contents.length ) {7868 contents.wrapAll( html );7869 } else {7870 self.append( html );7871 }7872 } );7873 },7874 wrap: function( html ) {7875 var htmlIsFunction = isFunction( html );7876 return this.each( function( i ) {7877 jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );7878 } );7879 },7880 unwrap: function( selector ) {7881 this.parent( selector ).not( "body" ).each( function() {7882 jQuery( this ).replaceWith( this.childNodes );7883 } );7884 return this;7885 }7886} );7887jQuery.expr.pseudos.hidden = function( elem ) {7888 return !jQuery.expr.pseudos.visible( elem );7889};7890jQuery.expr.pseudos.visible = function( elem ) {7891 return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );7892};7893jQuery.ajaxSettings.xhr = function() {7894 try {7895 return new window.XMLHttpRequest();7896 } catch ( e ) {}7897};7898var xhrSuccessStatus = {7899 // File protocol always yields status code 0, assume 2007900 0: 200,7901 // Support: IE <=9 only7902 // #1450: sometimes IE returns 1223 when it should be 2047903 1223: 2047904 },7905 xhrSupported = jQuery.ajaxSettings.xhr();7906support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );7907support.ajax = xhrSupported = !!xhrSupported;7908jQuery.ajaxTransport( function( options ) {7909 var callback, errorcallback;7910 // Cross domain only allowed if supported through XMLHttpRequest7911 if ( support.cors || xhrSupported && !options.crossDomain ) {7912 return {7913 send: function( headers, complete ) {7914 var i,7915 xhr = options.xhr();7916 xhr.open(7917 options.type,7918 options.url,7919 options.async,7920 options.username,7921 options.password7922 );7923 // Apply custom fields if provided7924 if ( options.xhrFields ) {7925 for ( i in options.xhrFields ) {7926 xhr[ i ] = options.xhrFields[ i ];7927 }7928 }7929 // Override mime type if needed7930 if ( options.mimeType && xhr.overrideMimeType ) {7931 xhr.overrideMimeType( options.mimeType );7932 }7933 // X-Requested-With header7934 // For cross-domain requests, seeing as conditions for a preflight are7935 // akin to a jigsaw puzzle, we simply never set it to be sure.7936 // (it can always be set on a per-request basis or even using ajaxSetup)7937 // For same-domain requests, won't change header if already provided.7938 if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {7939 headers[ "X-Requested-With" ] = "XMLHttpRequest";7940 }7941 // Set headers7942 for ( i in headers ) {7943 xhr.setRequestHeader( i, headers[ i ] );7944 }7945 // callback7946 callback = function( type ) {7947 return function() {7948 if ( callback ) {7949 callback = errorcallback = xhr.onload =7950 xhr.onerror = xhr.onabort = xhr.ontimeout =7951 xhr.onreadystatechange = null;7952 if ( type === "abort" ) {7953 xhr.abort();7954 } else if ( type === "error" ) {7955 // Support: IE <=9 only7956 // On a manual native abort, IE9 throws7957 // errors on any property access that is not readyState7958 if ( typeof xhr.status !== "number" ) {7959 complete( 0, "error" );7960 } else {7961 complete(7962 // File: protocol always yields status 0; see #8605, #142077963 xhr.status,7964 xhr.statusText7965 );7966 }7967 } else {7968 complete(7969 xhrSuccessStatus[ xhr.status ] || xhr.status,7970 xhr.statusText,7971 // Support: IE <=9 only7972 // IE9 has no XHR2 but throws on binary (trac-11426)7973 // For XHR2 non-text, let the caller handle it (gh-2498)7974 ( xhr.responseType || "text" ) !== "text" ||7975 typeof xhr.responseText !== "string" ?7976 { binary: xhr.response } :7977 { text: xhr.responseText },7978 xhr.getAllResponseHeaders()7979 );7980 }7981 }7982 };7983 };7984 // Listen to events7985 xhr.onload = callback();7986 errorcallback = xhr.onerror = xhr.ontimeout = callback( "error" );7987 // Support: IE 9 only7988 // Use onreadystatechange to replace onabort7989 // to handle uncaught aborts7990 if ( xhr.onabort !== undefined ) {7991 xhr.onabort = errorcallback;7992 } else {7993 xhr.onreadystatechange = function() {7994 // Check readyState before timeout as it changes7995 if ( xhr.readyState === 4 ) {7996 // Allow onerror to be called first,7997 // but that will not handle a native abort7998 // Also, save errorcallback to a variable7999 // as xhr.onerror cannot be accessed8000 window.setTimeout( function() {8001 if ( callback ) {8002 errorcallback();8003 }8004 } );8005 }8006 };8007 }8008 // Create the abort callback8009 callback = callback( "abort" );8010 try {8011 // Do send the request (this may raise an exception)8012 xhr.send( options.hasContent && options.data || null );8013 } catch ( e ) {8014 // #14683: Only rethrow if this hasn't been notified as an error yet8015 if ( callback ) {8016 throw e;8017 }8018 }8019 },8020 abort: function() {8021 if ( callback ) {8022 callback();8023 }8024 }8025 };8026 }8027} );8028// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)8029jQuery.ajaxPrefilter( function( s ) {8030 if ( s.crossDomain ) {8031 s.contents.script = false;8032 }8033} );8034// Install script dataType8035jQuery.ajaxSetup( {8036 accepts: {8037 script: "text/javascript, application/javascript, " +8038 "application/ecmascript, application/x-ecmascript"8039 },8040 contents: {8041 script: /\b(?:java|ecma)script\b/8042 },8043 converters: {8044 "text script": function( text ) {8045 jQuery.globalEval( text );8046 return text;8047 }8048 }8049} );8050// Handle cache's special case and crossDomain8051jQuery.ajaxPrefilter( "script", function( s ) {8052 if ( s.cache === undefined ) {8053 s.cache = false;8054 }8055 if ( s.crossDomain ) {8056 s.type = "GET";8057 }8058} );8059// Bind script tag hack transport8060jQuery.ajaxTransport( "script", function( s ) {8061 // This transport only deals with cross domain or forced-by-attrs requests8062 if ( s.crossDomain || s.scriptAttrs ) {8063 var script, callback;8064 return {8065 send: function( _, complete ) {8066 script = jQuery( "<script>" )8067 .attr( s.scriptAttrs || {} )8068 .prop( { charset: s.scriptCharset, src: s.url } )8069 .on( "load error", callback = function( evt ) {8070 script.remove();8071 callback = null;8072 if ( evt ) {8073 complete( evt.type === "error" ? 404 : 200, evt.type );8074 }8075 } );8076 // Use native DOM manipulation to avoid our domManip AJAX trickery8077 document.head.appendChild( script[ 0 ] );8078 },8079 abort: function() {8080 if ( callback ) {8081 callback();8082 }8083 }8084 };8085 }8086} );8087var oldcallbacks = [],8088 rjsonp = /(=)\?(?=&|$)|\?\?/;8089// Default jsonp settings8090jQuery.ajaxSetup( {8091 jsonp: "callback",8092 jsonpcallback: function() {8093 var callback = oldcallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );8094 this[ callback ] = true;8095 return callback;8096 }8097} );8098// Detect, normalize options and install callbacks for jsonp requests8099jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {8100 var callbackName, overwritten, responseContainer,8101 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?8102 "url" :8103 typeof s.data === "string" &&8104 ( s.contentType || "" )8105 .indexOf( "application/x-www-form-urlencoded" ) === 0 &&8106 rjsonp.test( s.data ) && "data"8107 );8108 // Handle iff the expected data type is "jsonp" or we have a parameter to set8109 if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {8110 // Get callback name, remembering preexisting value associated with it8111 callbackName = s.jsonpcallback = isFunction( s.jsonpcallback ) ?8112 s.jsonpcallback() :8113 s.jsonpcallback;8114 // Insert callback into url or form data8115 if ( jsonProp ) {8116 s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );8117 } else if ( s.jsonp !== false ) {8118 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;8119 }8120 // Use data converter to retrieve json after script execution8121 s.converters[ "script json" ] = function() {8122 if ( !responseContainer ) {8123 jQuery.error( callbackName + " was not called" );8124 }8125 return responseContainer[ 0 ];8126 };8127 // Force json dataType8128 s.dataTypes[ 0 ] = "json";8129 // Install callback8130 overwritten = window[ callbackName ];8131 window[ callbackName ] = function() {8132 responseContainer = arguments;8133 };8134 // Clean-up function (fires after converters)8135 jqXHR.always( function() {8136 // If previous value didn't exist - remove it8137 if ( overwritten === undefined ) {8138 jQuery( window ).removeProp( callbackName );8139 // Otherwise restore preexisting value8140 } else {8141 window[ callbackName ] = overwritten;8142 }8143 // Save back as free8144 if ( s[ callbackName ] ) {8145 // Make sure that re-using the options doesn't screw things around8146 s.jsonpcallback = originalSettings.jsonpcallback;8147 // Save the callback name for future use8148 oldcallbacks.push( callbackName );8149 }8150 // Call if it was a function and we have a response8151 if ( responseContainer && isFunction( overwritten ) ) {8152 overwritten( responseContainer[ 0 ] );8153 }8154 responseContainer = overwritten = undefined;8155 } );8156 // Delegate to script8157 return "script";8158 }8159} );8160// Support: Safari 8 only8161// In Safari 8 documents created via document.implementation.createHTMLDocument8162// collapse sibling forms: the second one becomes a child of the first one.8163// Because of that, this security measure has to be disabled in Safari 8.8164// https://bugs.webkit.org/show_bug.cgi?id=1373378165support.createHTMLDocument = ( function() {8166 var body = document.implementation.createHTMLDocument( "" ).body;8167 body.innerHTML = "<form></form><form></form>";8168 return body.childNodes.length === 2;8169} )();8170// Argument "data" should be string of html8171// context (optional): If specified, the fragment will be created in this context,8172// defaults to document8173// keepScripts (optional): If true, will include scripts passed in the html string8174jQuery.parseHTML = function( data, context, keepScripts ) {8175 if ( typeof data !== "string" ) {8176 return [];8177 }8178 if ( typeof context === "boolean" ) {8179 keepScripts = context;8180 context = false;8181 }8182 var base, parsed, scripts;8183 if ( !context ) {8184 // Stop scripts or inline event handlers from being executed immediately8185 // by using document.implementation8186 if ( support.createHTMLDocument ) {8187 context = document.implementation.createHTMLDocument( "" );8188 // Set the base href for the created document8189 // so any parsed elements with URLs8190 // are based on the document's URL (gh-2965)8191 base = context.createElement( "base" );8192 base.href = document.location.href;8193 context.head.appendChild( base );8194 } else {8195 context = document;8196 }8197 }8198 parsed = rsingleTag.exec( data );8199 scripts = !keepScripts && [];8200 // Single tag8201 if ( parsed ) {8202 return [ context.createElement( parsed[ 1 ] ) ];8203 }8204 parsed = buildFragment( [ data ], context, scripts );8205 if ( scripts && scripts.length ) {8206 jQuery( scripts ).remove();8207 }8208 return jQuery.merge( [], parsed.childNodes );8209};8210/**8211 * Load a url into a page8212 */8213jQuery.fn.load = function( url, params, callback ) {8214 var selector, type, response,8215 self = this,8216 off = url.indexOf( " " );8217 if ( off > -1 ) {8218 selector = stripAndCollapse( url.slice( off ) );8219 url = url.slice( 0, off );8220 }8221 // If it's a function8222 if ( isFunction( params ) ) {8223 // We assume that it's the callback8224 callback = params;8225 params = undefined;8226 // Otherwise, build a param string8227 } else if ( params && typeof params === "object" ) {8228 type = "POST";8229 }8230 // If we have elements to modify, make the request8231 if ( self.length > 0 ) {8232 jQuery.ajax( {8233 url: url,8234 // If "type" variable is undefined, then "GET" method will be used.8235 // Make value of this field explicit since8236 // user can override it through ajaxSetup method8237 type: type || "GET",8238 dataType: "html",8239 data: params8240 } ).done( function( responseText ) {8241 // Save response for use in complete callback8242 response = arguments;8243 self.html( selector ?8244 // If a selector was specified, locate the right elements in a dummy div8245 // Exclude scripts to avoid IE 'Permission Denied' errors8246 jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :8247 // Otherwise use the full result8248 responseText );8249 // If the request succeeds, this function gets "data", "status", "jqXHR"8250 // but they are ignored because response was set above.8251 // If it fails, this function gets "jqXHR", "status", "error"8252 } ).always( callback && function( jqXHR, status ) {8253 self.each( function() {8254 callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );8255 } );8256 } );8257 }8258 return this;8259};8260// Attach a bunch of functions for handling common AJAX events8261jQuery.each( [8262 "ajaxStart",8263 "ajaxStop",8264 "ajaxComplete",8265 "ajaxError",8266 "ajaxSuccess",8267 "ajaxSend"8268], function( i, type ) {8269 jQuery.fn[ type ] = function( fn ) {8270 return this.on( type, fn );8271 };8272} );8273jQuery.expr.pseudos.animated = function( elem ) {8274 return jQuery.grep( jQuery.timers, function( fn ) {8275 return elem === fn.elem;8276 } ).length;8277};8278jQuery.offset = {8279 setOffset: function( elem, options, i ) {8280 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,8281 position = jQuery.css( elem, "position" ),8282 curElem = jQuery( elem ),8283 props = {};8284 // Set position first, in-case top/left are set even on static elem8285 if ( position === "static" ) {8286 elem.style.position = "relative";8287 }8288 curOffset = curElem.offset();8289 curCSSTop = jQuery.css( elem, "top" );8290 curCSSLeft = jQuery.css( elem, "left" );8291 calculatePosition = ( position === "absolute" || position === "fixed" ) &&8292 ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;8293 // Need to be able to calculate position if either8294 // top or left is auto and position is either absolute or fixed8295 if ( calculatePosition ) {8296 curPosition = curElem.position();8297 curTop = curPosition.top;8298 curLeft = curPosition.left;8299 } else {8300 curTop = parseFloat( curCSSTop ) || 0;8301 curLeft = parseFloat( curCSSLeft ) || 0;8302 }8303 if ( isFunction( options ) ) {8304 // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)8305 options = options.call( elem, i, jQuery.extend( {}, curOffset ) );8306 }8307 if ( options.top != null ) {8308 props.top = ( options.top - curOffset.top ) + curTop;8309 }8310 if ( options.left != null ) {8311 props.left = ( options.left - curOffset.left ) + curLeft;8312 }8313 if ( "using" in options ) {8314 options.using.call( elem, props );8315 } else {8316 curElem.css( props );8317 }8318 }8319};8320jQuery.fn.extend( {8321 // offset() relates an element's border box to the document origin8322 offset: function( options ) {8323 // Preserve chaining for setter8324 if ( arguments.length ) {8325 return options === undefined ?8326 this :8327 this.each( function( i ) {8328 jQuery.offset.setOffset( this, options, i );8329 } );8330 }8331 var rect, win,8332 elem = this[ 0 ];8333 if ( !elem ) {8334 return;8335 }8336 // Return zeros for disconnected and hidden (display: none) elements (gh-2310)8337 // Support: IE <=11 only8338 // Running getBoundingClientRect on a8339 // disconnected node in IE throws an error8340 if ( !elem.getClientRects().length ) {8341 return { top: 0, left: 0 };8342 }8343 // Get document-relative position by adding viewport scroll to viewport-relative gBCR8344 rect = elem.getBoundingClientRect();8345 win = elem.ownerDocument.defaultView;8346 return {8347 top: rect.top + win.pageYOffset,8348 left: rect.left + win.pageXOffset8349 };8350 },8351 // position() relates an element's margin box to its offset parent's padding box8352 // This corresponds to the behavior of CSS absolute positioning8353 position: function() {8354 if ( !this[ 0 ] ) {8355 return;8356 }8357 var offsetParent, offset, doc,8358 elem = this[ 0 ],8359 parentOffset = { top: 0, left: 0 };8360 // position:fixed elements are offset from the viewport, which itself always has zero offset8361 if ( jQuery.css( elem, "position" ) === "fixed" ) {8362 // Assume position:fixed implies availability of getBoundingClientRect8363 offset = elem.getBoundingClientRect();8364 } else {8365 offset = this.offset();8366 // Account for the *real* offset parent, which can be the document or its root element8367 // when a statically positioned element is identified8368 doc = elem.ownerDocument;8369 offsetParent = elem.offsetParent || doc.documentElement;8370 while ( offsetParent &&8371 ( offsetParent === doc.body || offsetParent === doc.documentElement ) &&8372 jQuery.css( offsetParent, "position" ) === "static" ) {8373 offsetParent = offsetParent.parentNode;8374 }8375 if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {8376 // Incorporate borders into its offset, since they are outside its content origin8377 parentOffset = jQuery( offsetParent ).offset();8378 parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true );8379 parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true );8380 }8381 }8382 // Subtract parent offsets and element margins8383 return {8384 top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),8385 left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )8386 };8387 },8388 // This method will return documentElement in the following cases:8389 // 1) For the element inside the iframe without offsetParent, this method will return8390 // documentElement of the parent window8391 // 2) For the hidden or detached element8392 // 3) For body or html element, i.e. in case of the html node - it will return itself8393 //8394 // but those exceptions were never presented as a real life use-cases8395 // and might be considered as more preferable results.8396 //8397 // This logic, however, is not guaranteed and can change at any point in the future8398 offsetParent: function() {8399 return this.map( function() {8400 var offsetParent = this.offsetParent;8401 while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {8402 offsetParent = offsetParent.offsetParent;8403 }8404 return offsetParent || documentElement;8405 } );8406 }8407} );8408// Create scrollLeft and scrollTop methods8409jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {8410 var top = "pageYOffset" === prop;8411 jQuery.fn[ method ] = function( val ) {8412 return access( this, function( elem, method, val ) {8413 // Coalesce documents and windows8414 var win;8415 if ( isWindow( elem ) ) {8416 win = elem;8417 } else if ( elem.nodeType === 9 ) {8418 win = elem.defaultView;8419 }8420 if ( val === undefined ) {8421 return win ? win[ prop ] : elem[ method ];8422 }8423 if ( win ) {8424 win.scrollTo(8425 !top ? val : win.pageXOffset,8426 top ? val : win.pageYOffset8427 );8428 } else {8429 elem[ method ] = val;8430 }8431 }, method, val, arguments.length );8432 };8433} );8434// Support: Safari <=7 - 9.1, Chrome <=37 - 498435// Add the top/left cssHooks using jQuery.fn.position8436// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=290848437// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=5893478438// getComputedStyle returns percent when specified for top/left/bottom/right;8439// rather than make the css module depend on the offset module, just check for it here8440jQuery.each( [ "top", "left" ], function( i, prop ) {8441 jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,8442 function( elem, computed ) {8443 if ( computed ) {8444 computed = curCSS( elem, prop );8445 // If curCSS returns percentage, fallback to offset8446 return rnumnonpx.test( computed ) ?8447 jQuery( elem ).position()[ prop ] + "px" :8448 computed;8449 }8450 }8451 );8452} );8453// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods8454jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {8455 jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },8456 function( defaultExtra, funcName ) {8457 // Margin is only for outerHeight, outerWidth8458 jQuery.fn[ funcName ] = function( margin, value ) {8459 var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),8460 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );8461 return access( this, function( elem, type, value ) {8462 var doc;8463 if ( isWindow( elem ) ) {8464 // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)8465 return funcName.indexOf( "outer" ) === 0 ?8466 elem[ "inner" + name ] :8467 elem.document.documentElement[ "client" + name ];8468 }8469 // Get document width or height8470 if ( elem.nodeType === 9 ) {8471 doc = elem.documentElement;8472 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],8473 // whichever is greatest8474 return Math.max(8475 elem.body[ "scroll" + name ], doc[ "scroll" + name ],8476 elem.body[ "offset" + name ], doc[ "offset" + name ],8477 doc[ "client" + name ]8478 );8479 }8480 return value === undefined ?8481 // Get width or height on the element, requesting but not forcing parseFloat8482 jQuery.css( elem, type, extra ) :8483 // Set width or height on the element8484 jQuery.style( elem, type, value, extra );8485 }, type, chainable ? margin : undefined, chainable );8486 };8487 } );8488} );8489jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +8490 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +8491 "change select submit keydown keypress keyup contextmenu" ).split( " " ),8492 function( i, name ) {8493 // Handle event binding8494 jQuery.fn[ name ] = function( data, fn ) {8495 return arguments.length > 0 ?8496 this.on( name, null, data, fn ) :8497 this.trigger( name );8498 };8499} );8500jQuery.fn.extend( {8501 hover: function( fnOver, fnOut ) {8502 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );8503 }8504} );8505jQuery.fn.extend( {8506 bind: function( types, data, fn ) {8507 return this.on( types, null, data, fn );8508 },8509 unbind: function( types, fn ) {8510 return this.off( types, null, fn );8511 },8512 delegate: function( selector, types, data, fn ) {8513 return this.on( types, selector, data, fn );8514 },8515 undelegate: function( selector, types, fn ) {8516 // ( namespace ) or ( selector, types [, fn] )8517 return arguments.length === 1 ?8518 this.off( selector, "**" ) :8519 this.off( types, selector || "**", fn );8520 }8521} );8522// Bind a function to a context, optionally partially applying any8523// arguments.8524// jQuery.proxy is deprecated to promote standards (specifically Function#bind)8525// However, it is not slated for removal any time soon8526jQuery.proxy = function( fn, context ) {8527 var tmp, args, proxy;8528 if ( typeof context === "string" ) {8529 tmp = fn[ context ];8530 context = fn;8531 fn = tmp;8532 }8533 // Quick check to determine if target is callable, in the spec8534 // this throws a TypeError, but we will just return undefined.8535 if ( !isFunction( fn ) ) {8536 return undefined;8537 }8538 // Simulated bind8539 args = slice.call( arguments, 2 );8540 proxy = function() {8541 return fn.apply( context || this, args.concat( slice.call( arguments ) ) );8542 };8543 // Set the guid of unique handler to the same of original handler, so it can be removed8544 proxy.guid = fn.guid = fn.guid || jQuery.guid++;8545 return proxy;8546};8547jQuery.holdReady = function( hold ) {8548 if ( hold ) {8549 jQuery.readyWait++;8550 } else {8551 jQuery.ready( true );8552 }8553};8554jQuery.isArray = Array.isArray;8555jQuery.parseJSON = JSON.parse;8556jQuery.nodeName = nodeName;8557jQuery.isFunction = isFunction;8558jQuery.isWindow = isWindow;8559jQuery.camelCase = camelCase;8560jQuery.type = toType;8561jQuery.now = Date.now;8562jQuery.isNumeric = function( obj ) {8563 // As of jQuery 3.0, isNumeric is limited to8564 // strings and numbers (primitives or objects)8565 // that can be coerced to finite numbers (gh-2662)8566 var type = jQuery.type( obj );8567 return ( type === "number" || type === "string" ) &&8568 // parseFloat NaNs numeric-cast false positives ("")8569 // ...but misinterprets leading-number strings, particularly hex literals ("0x...")8570 // subtraction forces infinities to NaN8571 !isNaN( obj - parseFloat( obj ) );8572};8573// Register as a named AMD module, since jQuery can be concatenated with other8574// files that may use define, but not via a proper concatenation script that8575// understands anonymous AMD modules. A named AMD is safest and most robust8576// way to register. Lowercase jquery is used because AMD module names are8577// derived from file names, and jQuery is normally delivered in a lowercase8578// file name. Do this after creating the global so that if an AMD module wants8579// to call noConflict to hide this version of jQuery, it will work.8580// Note that for maximum portability, libraries that are not jQuery should8581// declare themselves as anonymous modules, and avoid setting a global if an8582// AMD loader is present. jQuery is a special case. For more information, see8583// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon8584if ( typeof define === "function" && define.amd ) {8585 define( "jquery", [], function() {8586 return jQuery;8587 } );8588}8589var8590 // Map over jQuery in case of overwrite8591 _jQuery = window.jQuery,8592 // Map over the $ in case of overwrite8593 _$ = window.$;8594jQuery.noConflict = function( deep ) {8595 if ( window.$ === jQuery ) {8596 window.$ = _$;8597 }8598 if ( deep && window.jQuery === jQuery ) {8599 window.jQuery = _jQuery;8600 }8601 return jQuery;8602};8603// Expose jQuery and $ identifiers, even in AMD8604// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)8605// and CommonJS for browser emulators (#13566)8606if ( !noGlobal ) {8607 window.jQuery = window.$ = jQuery;8608}8609return jQuery;...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1describe("My First Test", function() {2 it("Does not do much!", function() {3 expect(true).to.equal(true);4 });5});6Cypress.on("window:before:load", win => {7 delete win.fetch;8});9module.exports = (on, config) => {10 on("task", {11 "get:oldCallbacks": () => {12 return Cypress.oldCallbacks;13 }14 });15};16describe("My First Test", function() {17 it("Does not do much!", function() {18 cy.task("get:oldCallbacks").then(oldCallbacks => {19 oldCallbacks.pop();20 });21 });22});

Full Screen

Using AI Code Generation

copy

Full Screen

1Cypress.on('uncaught:exception', (err, runnable) => {2 })3 Cypress.on('uncaught:exception', (err, runnable) => {4 })5 Cypress.on('uncaught:exception', (err, runnable) => {6 })7 Cypress.on('uncaught:exception', (err, runnable) => {8 })9 Cypress.on('uncaught:exception', (err, runnable) => {10 })11 Cypress.on('uncaught:exception', (err, runnable) => {12 })13 Cypress.on('uncaught:exception', (err, runnable) => {14 })15 Cypress.on('uncaught:exception', (err, runnable) => {16 })17 Cypress.on('uncaught:exception', (err, runnable) => {18 })19 Cypress.on('uncaught:exception', (err, runnable) => {20 })21 Cypress.on('uncaught:exception', (err, runnable) => {22 })23 Cypress.on('uncaught:exception', (err, runnable) => {24 })25 Cypress.on('uncaught:exception', (err, runnable) => {26 })27 Cypress.on('uncaught:exception', (err, runnable) => {

Full Screen

Using AI Code Generation

copy

Full Screen

1describe("My First Test", () => {2 it("Visits the Kitchen Sink", () => {3 cy.contains("type").click();4 cy.url().should("include", "/commands/actions");5 cy.get(".action-email")6 .type("

Full Screen

Using AI Code Generation

copy

Full Screen

1Cypress.on('command:start', (command) => {2 console.log(command.attributes.name)3})4describe('My First Test', () => {5 it('Does not do much!', () => {6 expect(true).to.equal(true)7 })8 it('Does not do much!', () => {9 expect(true).to.equal(true)10 })11 it('Does not do much!', () => {12 expect(true).to.equal(true)13 })14 it('Does not do much!', () => {15 expect(true).to.equal(true)16 })17 it('Does not do much!', () => {18 expect(true).to.equal(true)19 })20})

Full Screen

Using AI Code Generation

copy

Full Screen

1Cypress.Commands.add('addCallback', function (callback) {2 Cypress.oldCallbacks = Cypress.oldCallbacks || [];3 Cypress.oldCallbacks.push(callback);4});5Cypress.Commands.overwrite('then', (originalFn, subject, callback) => {6 return originalFn(subject, (subject) => {7 Cypress.oldCallbacks = Cypress.oldCallbacks || [];8 Cypress.oldCallbacks.push(callback);9 return subject;10 });11});12Cypress.Commands.overwrite('log', (originalFn, options) => {13 if (options && options.consoleProps) {14 Cypress.oldCallbacks = Cypress.oldCallbacks || [];15 Cypress.oldCallbacks.push(() => {16 console.log(options.consoleProps);17 });18 }19 return originalFn(options);20});21Cypress.Commands.overwrite('wrap', (originalFn, subject, options) => {22 return originalFn(subject, options).then((subject) => {23 Cypress.oldCallbacks = Cypress.oldCallbacks || [];24 Cypress.oldCallbacks.push(() => {25 console.log(subject);26 });27 return subject;28 });29});30Cypress.Commands.overwrite('its', (originalFn, subject, alias) => {31 return originalFn(subject, alias).then((subject) => {32 Cypress.oldCallbacks = Cypress.oldCallbacks || [];33 Cypress.oldCallbacks.push(() => {34 console.log(subject);35 });36 return subject;37 });38});39Cypress.Commands.overwrite('invoke',

Full Screen

Using AI Code Generation

copy

Full Screen

1const oldCallbacks = Cypress.config('callbacks')2oldCallbacks.pop()3Cypress.config('callbacks', oldCallbacks)4const oldCallbacks = Cypress.config('callbacks')5oldCallbacks.pop()6Cypress.config('callbacks', oldCallbacks)7const oldCallbacks = Cypress.config('callbacks')8oldCallbacks.pop()9Cypress.config('callbacks', oldCallbacks)10const oldCallbacks = Cypress.config('callbacks')11oldCallbacks.pop()12Cypress.config('callbacks', oldCallbacks)13const oldCallbacks = Cypress.config('callbacks')14oldCallbacks.pop()15Cypress.config('callbacks', oldCallbacks)16const oldCallbacks = Cypress.config('callbacks')17oldCallbacks.pop()18Cypress.config('callbacks', oldCallbacks)19describe('Home page', () => {20 it('should load home page', () => {21 cy.visit('/')22 })23})24describe('About page', () => {25 it('should load about page', () => {26 cy.visit('/about')27 })28})29describe('Contact page', () => {

Full Screen

Using AI Code Generation

copy

Full Screen

1const oldCallbacks = Cypress.on.pop();2const newCallbacks = Cypress.on.pop();3const oldCallbacks = Cypress.on.pop();4const newCallbacks = Cypress.on.pop();5const oldCallbacks = Cypress.on.pop();6const newCallbacks = Cypress.on.pop();7const oldCallbacks = Cypress.on.pop();8const newCallbacks = Cypress.on.pop();9const oldCallbacks = Cypress.on.pop();10const newCallbacks = Cypress.on.pop();11const oldCallbacks = Cypress.on.pop();12const newCallbacks = Cypress.on.pop();

Full Screen

Cypress Tutorial

Cypress is a renowned Javascript-based open-source, easy-to-use end-to-end testing framework primarily used for testing web applications. Cypress is a relatively new player in the automation testing space and has been gaining much traction lately, as evidenced by the number of Forks (2.7K) and Stars (42.1K) for the project. LambdaTest’s Cypress Tutorial covers step-by-step guides that will help you learn from the basics till you run automation tests on LambdaTest.

Chapters:

  1. What is Cypress? -
  2. Why Cypress? - Learn why Cypress might be a good choice for testing your web applications.
  3. Features of Cypress Testing - Learn about features that make Cypress a powerful and flexible tool for testing web applications.
  4. Cypress Drawbacks - Although Cypress has many strengths, it has a few limitations that you should be aware of.
  5. Cypress Architecture - Learn more about Cypress architecture and how it is designed to be run directly in the browser, i.e., it does not have any additional servers.
  6. Browsers Supported by Cypress - Cypress is built on top of the Electron browser, supporting all modern web browsers. Learn browsers that support Cypress.
  7. Selenium vs Cypress: A Detailed Comparison - Compare and explore some key differences in terms of their design and features.
  8. Cypress Learning: Best Practices - Take a deep dive into some of the best practices you should use to avoid anti-patterns in your automation tests.
  9. How To Run Cypress Tests on LambdaTest? - Set up a LambdaTest account, and now you are all set to learn how to run Cypress tests.

Certification

You can elevate your expertise with end-to-end testing using the Cypress automation framework and stay one step ahead in your career by earning a Cypress certification. Check out our Cypress 101 Certification.

YouTube

Watch this 3 hours of complete tutorial to learn the basics of Cypress and various Cypress commands with the Cypress testing at LambdaTest.

Run Cypress automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful