UNPKG

258 kBJavaScriptView Raw
1/*!
2 * jQuery JavaScript Library v1.7
3 * http://jquery.com/
4 *
5 * Copyright 2011, John Resig
6 * Dual licensed under the MIT or GPL Version 2 licenses.
7 * http://jquery.org/license
8 *
9 * Includes Sizzle.js
10 * http://sizzlejs.com/
11 * Copyright 2011, The Dojo Foundation
12 * Released under the MIT, BSD, and GPL Licenses.
13 *
14 * Date: Thu Nov 3 16:18:21 2011 -0400
15 */
16(function( window, undefined ) {
17
18// Use the correct document accordingly with window argument (sandbox)
19var document = window.document,
20 navigator = window.navigator,
21 location = window.location;
22var jQuery = (function() {
23
24// Define a local copy of jQuery
25var jQuery = function( selector, context ) {
26 // The jQuery object is actually just the init constructor 'enhanced'
27 return new jQuery.fn.init( selector, context, rootjQuery );
28 },
29
30 // Map over jQuery in case of overwrite
31 _jQuery = window.jQuery,
32
33 // Map over the $ in case of overwrite
34 _$ = window.$,
35
36 // A central reference to the root jQuery(document)
37 rootjQuery,
38
39 // A simple way to check for HTML strings or ID strings
40 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
41 quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
42
43 // Check if a string has a non-whitespace character in it
44 rnotwhite = /\S/,
45
46 // Used for trimming whitespace
47 trimLeft = /^\s+/,
48 trimRight = /\s+$/,
49
50 // Check for digits
51 rdigit = /\d/,
52
53 // Match a standalone tag
54 rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
55
56 // JSON RegExp
57 rvalidchars = /^[\],:{}\s]*$/,
58 rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
59 rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
60 rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
61
62 // Useragent RegExp
63 rwebkit = /(webkit)[ \/]([\w.]+)/,
64 ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
65 rmsie = /(msie) ([\w.]+)/,
66 rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
67
68 // Matches dashed string for camelizing
69 rdashAlpha = /-([a-z]|[0-9])/ig,
70 rmsPrefix = /^-ms-/,
71
72 // Used by jQuery.camelCase as callback to replace()
73 fcamelCase = function( all, letter ) {
74 return ( letter + "" ).toUpperCase();
75 },
76
77 // Keep a UserAgent string for use with jQuery.browser
78 userAgent = navigator.userAgent,
79
80 // For matching the engine and version of the browser
81 browserMatch,
82
83 // The deferred used on DOM ready
84 readyList,
85
86 // The ready event handler
87 DOMContentLoaded,
88
89 // Save a reference to some core methods
90 toString = Object.prototype.toString,
91 hasOwn = Object.prototype.hasOwnProperty,
92 push = Array.prototype.push,
93 slice = Array.prototype.slice,
94 trim = String.prototype.trim,
95 indexOf = Array.prototype.indexOf,
96
97 // [[Class]] -> type pairs
98 class2type = {};
99
100jQuery.fn = jQuery.prototype = {
101 constructor: jQuery,
102 init: function( selector, context, rootjQuery ) {
103 var match, elem, ret, doc;
104
105 // Handle $(""), $(null), or $(undefined)
106 if ( !selector ) {
107 return this;
108 }
109
110 // Handle $(DOMElement)
111 if ( selector.nodeType ) {
112 this.context = this[0] = selector;
113 this.length = 1;
114 return this;
115 }
116
117 // The body element only exists once, optimize finding it
118 if ( selector === "body" && !context && document.body ) {
119 this.context = document;
120 this[0] = document.body;
121 this.selector = selector;
122 this.length = 1;
123 return this;
124 }
125
126 // Handle HTML strings
127 if ( typeof selector === "string" ) {
128 // Are we dealing with HTML string or an ID?
129 if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
130 // Assume that strings that start and end with <> are HTML and skip the regex check
131 match = [ null, selector, null ];
132
133 } else {
134 match = quickExpr.exec( selector );
135 }
136
137 // Verify a match, and that no context was specified for #id
138 if ( match && (match[1] || !context) ) {
139
140 // HANDLE: $(html) -> $(array)
141 if ( match[1] ) {
142 context = context instanceof jQuery ? context[0] : context;
143 doc = ( context ? context.ownerDocument || context : document );
144
145 // If a single string is passed in and it's a single tag
146 // just do a createElement and skip the rest
147 ret = rsingleTag.exec( selector );
148
149 if ( ret ) {
150 if ( jQuery.isPlainObject( context ) ) {
151 selector = [ document.createElement( ret[1] ) ];
152 jQuery.fn.attr.call( selector, context, true );
153
154 } else {
155 selector = [ doc.createElement( ret[1] ) ];
156 }
157
158 } else {
159 ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
160 selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes;
161 }
162
163 return jQuery.merge( this, selector );
164
165 // HANDLE: $("#id")
166 } else {
167 elem = document.getElementById( match[2] );
168
169 // Check parentNode to catch when Blackberry 4.6 returns
170 // nodes that are no longer in the document #6963
171 if ( elem && elem.parentNode ) {
172 // Handle the case where IE and Opera return items
173 // by name instead of ID
174 if ( elem.id !== match[2] ) {
175 return rootjQuery.find( selector );
176 }
177
178 // Otherwise, we inject the element directly into the jQuery object
179 this.length = 1;
180 this[0] = elem;
181 }
182
183 this.context = document;
184 this.selector = selector;
185 return this;
186 }
187
188 // HANDLE: $(expr, $(...))
189 } else if ( !context || context.jquery ) {
190 return ( context || rootjQuery ).find( selector );
191
192 // HANDLE: $(expr, context)
193 // (which is just equivalent to: $(context).find(expr)
194 } else {
195 return this.constructor( context ).find( selector );
196 }
197
198 // HANDLE: $(function)
199 // Shortcut for document ready
200 } else if ( jQuery.isFunction( selector ) ) {
201 return rootjQuery.ready( selector );
202 }
203
204 if ( selector.selector !== undefined ) {
205 this.selector = selector.selector;
206 this.context = selector.context;
207 }
208
209 return jQuery.makeArray( selector, this );
210 },
211
212 // Start with an empty selector
213 selector: "",
214
215 // The current version of jQuery being used
216 jquery: "1.7",
217
218 // The default length of a jQuery object is 0
219 length: 0,
220
221 // The number of elements contained in the matched element set
222 size: function() {
223 return this.length;
224 },
225
226 toArray: function() {
227 return slice.call( this, 0 );
228 },
229
230 // Get the Nth element in the matched element set OR
231 // Get the whole matched element set as a clean array
232 get: function( num ) {
233 return num == null ?
234
235 // Return a 'clean' array
236 this.toArray() :
237
238 // Return just the object
239 ( num < 0 ? this[ this.length + num ] : this[ num ] );
240 },
241
242 // Take an array of elements and push it onto the stack
243 // (returning the new matched element set)
244 pushStack: function( elems, name, selector ) {
245 // Build a new jQuery matched element set
246 var ret = this.constructor();
247
248 if ( jQuery.isArray( elems ) ) {
249 push.apply( ret, elems );
250
251 } else {
252 jQuery.merge( ret, elems );
253 }
254
255 // Add the old object onto the stack (as a reference)
256 ret.prevObject = this;
257
258 ret.context = this.context;
259
260 if ( name === "find" ) {
261 ret.selector = this.selector + ( this.selector ? " " : "" ) + selector;
262 } else if ( name ) {
263 ret.selector = this.selector + "." + name + "(" + selector + ")";
264 }
265
266 // Return the newly-formed element set
267 return ret;
268 },
269
270 // Execute a callback for every element in the matched set.
271 // (You can seed the arguments with an array of args, but this is
272 // only used internally.)
273 each: function( callback, args ) {
274 return jQuery.each( this, callback, args );
275 },
276
277 ready: function( fn ) {
278 // Attach the listeners
279 jQuery.bindReady();
280
281 // Add the callback
282 readyList.add( fn );
283
284 return this;
285 },
286
287 eq: function( i ) {
288 return i === -1 ?
289 this.slice( i ) :
290 this.slice( i, +i + 1 );
291 },
292
293 first: function() {
294 return this.eq( 0 );
295 },
296
297 last: function() {
298 return this.eq( -1 );
299 },
300
301 slice: function() {
302 return this.pushStack( slice.apply( this, arguments ),
303 "slice", slice.call(arguments).join(",") );
304 },
305
306 map: function( callback ) {
307 return this.pushStack( jQuery.map(this, function( elem, i ) {
308 return callback.call( elem, i, elem );
309 }));
310 },
311
312 end: function() {
313 return this.prevObject || this.constructor(null);
314 },
315
316 // For internal use only.
317 // Behaves like an Array's method, not like a jQuery method.
318 push: push,
319 sort: [].sort,
320 splice: [].splice
321};
322
323// Give the init function the jQuery prototype for later instantiation
324jQuery.fn.init.prototype = jQuery.fn;
325
326jQuery.extend = jQuery.fn.extend = function() {
327 var options, name, src, copy, copyIsArray, clone,
328 target = arguments[0] || {},
329 i = 1,
330 length = arguments.length,
331 deep = false;
332
333 // Handle a deep copy situation
334 if ( typeof target === "boolean" ) {
335 deep = target;
336 target = arguments[1] || {};
337 // skip the boolean and the target
338 i = 2;
339 }
340
341 // Handle case when target is a string or something (possible in deep copy)
342 if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
343 target = {};
344 }
345
346 // extend jQuery itself if only one argument is passed
347 if ( length === i ) {
348 target = this;
349 --i;
350 }
351
352 for ( ; i < length; i++ ) {
353 // Only deal with non-null/undefined values
354 if ( (options = arguments[ i ]) != null ) {
355 // Extend the base object
356 for ( name in options ) {
357 src = target[ name ];
358 copy = options[ name ];
359
360 // Prevent never-ending loop
361 if ( target === copy ) {
362 continue;
363 }
364
365 // Recurse if we're merging plain objects or arrays
366 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
367 if ( copyIsArray ) {
368 copyIsArray = false;
369 clone = src && jQuery.isArray(src) ? src : [];
370
371 } else {
372 clone = src && jQuery.isPlainObject(src) ? src : {};
373 }
374
375 // Never move original objects, clone them
376 target[ name ] = jQuery.extend( deep, clone, copy );
377
378 // Don't bring in undefined values
379 } else if ( copy !== undefined ) {
380 target[ name ] = copy;
381 }
382 }
383 }
384 }
385
386 // Return the modified object
387 return target;
388};
389
390jQuery.extend({
391 noConflict: function( deep ) {
392 if ( window.$ === jQuery ) {
393 window.$ = _$;
394 }
395
396 if ( deep && window.jQuery === jQuery ) {
397 window.jQuery = _jQuery;
398 }
399
400 return jQuery;
401 },
402
403 // Is the DOM ready to be used? Set to true once it occurs.
404 isReady: false,
405
406 // A counter to track how many items to wait for before
407 // the ready event fires. See #6781
408 readyWait: 1,
409
410 // Hold (or release) the ready event
411 holdReady: function( hold ) {
412 if ( hold ) {
413 jQuery.readyWait++;
414 } else {
415 jQuery.ready( true );
416 }
417 },
418
419 // Handle when the DOM is ready
420 ready: function( wait ) {
421 // Either a released hold or an DOMready/load event and not yet ready
422 if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
423 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
424 if ( !document.body ) {
425 return setTimeout( jQuery.ready, 1 );
426 }
427
428 // Remember that the DOM is ready
429 jQuery.isReady = true;
430
431 // If a normal DOM Ready event fired, decrement, and wait if need be
432 if ( wait !== true && --jQuery.readyWait > 0 ) {
433 return;
434 }
435
436 // If there are functions bound, to execute
437 readyList.fireWith( document, [ jQuery ] );
438
439 // Trigger any bound ready events
440 if ( jQuery.fn.trigger ) {
441 jQuery( document ).trigger( "ready" ).unbind( "ready" );
442 }
443 }
444 },
445
446 bindReady: function() {
447 if ( readyList ) {
448 return;
449 }
450
451 readyList = jQuery.Callbacks( "once memory" );
452
453 // Catch cases where $(document).ready() is called after the
454 // browser event has already occurred.
455 if ( document.readyState === "complete" ) {
456 // Handle it asynchronously to allow scripts the opportunity to delay ready
457 return setTimeout( jQuery.ready, 1 );
458 }
459
460 // Mozilla, Opera and webkit nightlies currently support this event
461 if ( document.addEventListener ) {
462 // Use the handy event callback
463 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
464
465 // A fallback to window.onload, that will always work
466 window.addEventListener( "load", jQuery.ready, false );
467
468 // If IE event model is used
469 } else if ( document.attachEvent ) {
470 // ensure firing before onload,
471 // maybe late but safe also for iframes
472 document.attachEvent( "onreadystatechange", DOMContentLoaded );
473
474 // A fallback to window.onload, that will always work
475 window.attachEvent( "onload", jQuery.ready );
476
477 // If IE and not a frame
478 // continually check to see if the document is ready
479 var toplevel = false;
480
481 try {
482 toplevel = window.frameElement == null;
483 } catch(e) {}
484
485 if ( document.documentElement.doScroll && toplevel ) {
486 doScrollCheck();
487 }
488 }
489 },
490
491 // See test/unit/core.js for details concerning isFunction.
492 // Since version 1.3, DOM methods and functions like alert
493 // aren't supported. They return false on IE (#2968).
494 isFunction: function( obj ) {
495 return jQuery.type(obj) === "function";
496 },
497
498 isArray: Array.isArray || function( obj ) {
499 return jQuery.type(obj) === "array";
500 },
501
502 // A crude way of determining if an object is a window
503 isWindow: function( obj ) {
504 return obj && typeof obj === "object" && "setInterval" in obj;
505 },
506
507 isNumeric: function( obj ) {
508 return obj != null && rdigit.test( obj ) && !isNaN( obj );
509 },
510
511 type: function( obj ) {
512 return obj == null ?
513 String( obj ) :
514 class2type[ toString.call(obj) ] || "object";
515 },
516
517 isPlainObject: function( obj ) {
518 // Must be an Object.
519 // Because of IE, we also have to check the presence of the constructor property.
520 // Make sure that DOM nodes and window objects don't pass through, as well
521 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
522 return false;
523 }
524
525 try {
526 // Not own constructor property must be Object
527 if ( obj.constructor &&
528 !hasOwn.call(obj, "constructor") &&
529 !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
530 return false;
531 }
532 } catch ( e ) {
533 // IE8,9 Will throw exceptions on certain host objects #9897
534 return false;
535 }
536
537 // Own properties are enumerated firstly, so to speed up,
538 // if last one is own, then all properties are own.
539
540 var key;
541 for ( key in obj ) {}
542
543 return key === undefined || hasOwn.call( obj, key );
544 },
545
546 isEmptyObject: function( obj ) {
547 for ( var name in obj ) {
548 return false;
549 }
550 return true;
551 },
552
553 error: function( msg ) {
554 throw msg;
555 },
556
557 parseJSON: function( data ) {
558 if ( typeof data !== "string" || !data ) {
559 return null;
560 }
561
562 // Make sure leading/trailing whitespace is removed (IE can't handle it)
563 data = jQuery.trim( data );
564
565 // Attempt to parse using the native JSON parser first
566 if ( window.JSON && window.JSON.parse ) {
567 return window.JSON.parse( data );
568 }
569
570 // Make sure the incoming data is actual JSON
571 // Logic borrowed from http://json.org/json2.js
572 if ( rvalidchars.test( data.replace( rvalidescape, "@" )
573 .replace( rvalidtokens, "]" )
574 .replace( rvalidbraces, "")) ) {
575
576 return ( new Function( "return " + data ) )();
577
578 }
579 jQuery.error( "Invalid JSON: " + data );
580 },
581
582 // Cross-browser xml parsing
583 parseXML: function( data ) {
584 var xml, tmp;
585 try {
586 if ( window.DOMParser ) { // Standard
587 tmp = new DOMParser();
588 xml = tmp.parseFromString( data , "text/xml" );
589 } else { // IE
590 xml = new ActiveXObject( "Microsoft.XMLDOM" );
591 xml.async = "false";
592 xml.loadXML( data );
593 }
594 } catch( e ) {
595 xml = undefined;
596 }
597 if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
598 jQuery.error( "Invalid XML: " + data );
599 }
600 return xml;
601 },
602
603 noop: function() {},
604
605 // Evaluates a script in a global context
606 // Workarounds based on findings by Jim Driscoll
607 // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
608 globalEval: function( data ) {
609 if ( data && rnotwhite.test( data ) ) {
610 // We use execScript on Internet Explorer
611 // We use an anonymous function so that context is window
612 // rather than jQuery in Firefox
613 ( window.execScript || function( data ) {
614 window[ "eval" ].call( window, data );
615 } )( data );
616 }
617 },
618
619 // Convert dashed to camelCase; used by the css and data modules
620 // Microsoft forgot to hump their vendor prefix (#9572)
621 camelCase: function( string ) {
622 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
623 },
624
625 nodeName: function( elem, name ) {
626 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
627 },
628
629 // args is for internal usage only
630 each: function( object, callback, args ) {
631 var name, i = 0,
632 length = object.length,
633 isObj = length === undefined || jQuery.isFunction( object );
634
635 if ( args ) {
636 if ( isObj ) {
637 for ( name in object ) {
638 if ( callback.apply( object[ name ], args ) === false ) {
639 break;
640 }
641 }
642 } else {
643 for ( ; i < length; ) {
644 if ( callback.apply( object[ i++ ], args ) === false ) {
645 break;
646 }
647 }
648 }
649
650 // A special, fast, case for the most common use of each
651 } else {
652 if ( isObj ) {
653 for ( name in object ) {
654 if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
655 break;
656 }
657 }
658 } else {
659 for ( ; i < length; ) {
660 if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
661 break;
662 }
663 }
664 }
665 }
666
667 return object;
668 },
669
670 // Use native String.trim function wherever possible
671 trim: trim ?
672 function( text ) {
673 return text == null ?
674 "" :
675 trim.call( text );
676 } :
677
678 // Otherwise use our own trimming functionality
679 function( text ) {
680 return text == null ?
681 "" :
682 text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
683 },
684
685 // results is for internal usage only
686 makeArray: function( array, results ) {
687 var ret = results || [];
688
689 if ( array != null ) {
690 // The window, strings (and functions) also have 'length'
691 // The extra typeof function check is to prevent crashes
692 // in Safari 2 (See: #3039)
693 // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
694 var type = jQuery.type( array );
695
696 if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
697 push.call( ret, array );
698 } else {
699 jQuery.merge( ret, array );
700 }
701 }
702
703 return ret;
704 },
705
706 inArray: function( elem, array, i ) {
707 var len;
708
709 if ( array ) {
710 if ( indexOf ) {
711 return indexOf.call( array, elem, i );
712 }
713
714 len = array.length;
715 i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
716
717 for ( ; i < len; i++ ) {
718 // Skip accessing in sparse arrays
719 if ( i in array && array[ i ] === elem ) {
720 return i;
721 }
722 }
723 }
724
725 return -1;
726 },
727
728 merge: function( first, second ) {
729 var i = first.length,
730 j = 0;
731
732 if ( typeof second.length === "number" ) {
733 for ( var l = second.length; j < l; j++ ) {
734 first[ i++ ] = second[ j ];
735 }
736
737 } else {
738 while ( second[j] !== undefined ) {
739 first[ i++ ] = second[ j++ ];
740 }
741 }
742
743 first.length = i;
744
745 return first;
746 },
747
748 grep: function( elems, callback, inv ) {
749 var ret = [], retVal;
750 inv = !!inv;
751
752 // Go through the array, only saving the items
753 // that pass the validator function
754 for ( var i = 0, length = elems.length; i < length; i++ ) {
755 retVal = !!callback( elems[ i ], i );
756 if ( inv !== retVal ) {
757 ret.push( elems[ i ] );
758 }
759 }
760
761 return ret;
762 },
763
764 // arg is for internal usage only
765 map: function( elems, callback, arg ) {
766 var value, key, ret = [],
767 i = 0,
768 length = elems.length,
769 // jquery objects are treated as arrays
770 isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
771
772 // Go through the array, translating each of the items to their
773 if ( isArray ) {
774 for ( ; i < length; i++ ) {
775 value = callback( elems[ i ], i, arg );
776
777 if ( value != null ) {
778 ret[ ret.length ] = value;
779 }
780 }
781
782 // Go through every key on the object,
783 } else {
784 for ( key in elems ) {
785 value = callback( elems[ key ], key, arg );
786
787 if ( value != null ) {
788 ret[ ret.length ] = value;
789 }
790 }
791 }
792
793 // Flatten any nested arrays
794 return ret.concat.apply( [], ret );
795 },
796
797 // A global GUID counter for objects
798 guid: 1,
799
800 // Bind a function to a context, optionally partially applying any
801 // arguments.
802 proxy: function( fn, context ) {
803 if ( typeof context === "string" ) {
804 var tmp = fn[ context ];
805 context = fn;
806 fn = tmp;
807 }
808
809 // Quick check to determine if target is callable, in the spec
810 // this throws a TypeError, but we will just return undefined.
811 if ( !jQuery.isFunction( fn ) ) {
812 return undefined;
813 }
814
815 // Simulated bind
816 var args = slice.call( arguments, 2 ),
817 proxy = function() {
818 return fn.apply( context, args.concat( slice.call( arguments ) ) );
819 };
820
821 // Set the guid of unique handler to the same of original handler, so it can be removed
822 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
823
824 return proxy;
825 },
826
827 // Mutifunctional method to get and set values to a collection
828 // The value/s can optionally be executed if it's a function
829 access: function( elems, key, value, exec, fn, pass ) {
830 var length = elems.length;
831
832 // Setting many attributes
833 if ( typeof key === "object" ) {
834 for ( var k in key ) {
835 jQuery.access( elems, k, key[k], exec, fn, value );
836 }
837 return elems;
838 }
839
840 // Setting one attribute
841 if ( value !== undefined ) {
842 // Optionally, function values get executed if exec is true
843 exec = !pass && exec && jQuery.isFunction(value);
844
845 for ( var i = 0; i < length; i++ ) {
846 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
847 }
848
849 return elems;
850 }
851
852 // Getting an attribute
853 return length ? fn( elems[0], key ) : undefined;
854 },
855
856 now: function() {
857 return ( new Date() ).getTime();
858 },
859
860 // Use of jQuery.browser is frowned upon.
861 // More details: http://docs.jquery.com/Utilities/jQuery.browser
862 uaMatch: function( ua ) {
863 ua = ua.toLowerCase();
864
865 var match = rwebkit.exec( ua ) ||
866 ropera.exec( ua ) ||
867 rmsie.exec( ua ) ||
868 ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
869 [];
870
871 return { browser: match[1] || "", version: match[2] || "0" };
872 },
873
874 sub: function() {
875 function jQuerySub( selector, context ) {
876 return new jQuerySub.fn.init( selector, context );
877 }
878 jQuery.extend( true, jQuerySub, this );
879 jQuerySub.superclass = this;
880 jQuerySub.fn = jQuerySub.prototype = this();
881 jQuerySub.fn.constructor = jQuerySub;
882 jQuerySub.sub = this.sub;
883 jQuerySub.fn.init = function init( selector, context ) {
884 if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
885 context = jQuerySub( context );
886 }
887
888 return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
889 };
890 jQuerySub.fn.init.prototype = jQuerySub.fn;
891 var rootjQuerySub = jQuerySub(document);
892 return jQuerySub;
893 },
894
895 browser: {}
896});
897
898// Populate the class2type map
899jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
900 class2type[ "[object " + name + "]" ] = name.toLowerCase();
901});
902
903browserMatch = jQuery.uaMatch( userAgent );
904if ( browserMatch.browser ) {
905 jQuery.browser[ browserMatch.browser ] = true;
906 jQuery.browser.version = browserMatch.version;
907}
908
909// Deprecated, use jQuery.browser.webkit instead
910if ( jQuery.browser.webkit ) {
911 jQuery.browser.safari = true;
912}
913
914// IE doesn't match non-breaking spaces with \s
915if ( rnotwhite.test( "\xA0" ) ) {
916 trimLeft = /^[\s\xA0]+/;
917 trimRight = /[\s\xA0]+$/;
918}
919
920// All jQuery objects should point back to these
921rootjQuery = jQuery(document);
922
923// Cleanup functions for the document ready method
924if ( document.addEventListener ) {
925 DOMContentLoaded = function() {
926 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
927 jQuery.ready();
928 };
929
930} else if ( document.attachEvent ) {
931 DOMContentLoaded = function() {
932 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
933 if ( document.readyState === "complete" ) {
934 document.detachEvent( "onreadystatechange", DOMContentLoaded );
935 jQuery.ready();
936 }
937 };
938}
939
940// The DOM ready check for Internet Explorer
941function doScrollCheck() {
942 if ( jQuery.isReady ) {
943 return;
944 }
945
946 try {
947 // If IE is used, use the trick by Diego Perini
948 // http://javascript.nwbox.com/IEContentLoaded/
949 document.documentElement.doScroll("left");
950 } catch(e) {
951 setTimeout( doScrollCheck, 1 );
952 return;
953 }
954
955 // and execute any waiting functions
956 jQuery.ready();
957}
958
959// Expose jQuery as an AMD module, but only for AMD loaders that
960// understand the issues with loading multiple versions of jQuery
961// in a page that all might call define(). The loader will indicate
962// they have special allowances for multiple jQuery versions by
963// specifying define.amd.jQuery = true. Register as a named module,
964// since jQuery can be concatenated with other files that may use define,
965// but not use a proper concatenation script that understands anonymous
966// AMD modules. A named AMD is safest and most robust way to register.
967// Lowercase jquery is used because AMD module names are derived from
968// file names, and jQuery is normally delivered in a lowercase file name.
969if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
970 define( "jquery", [], function () { return jQuery; } );
971}
972
973return jQuery;
974
975})();
976
977
978// String to Object flags format cache
979var flagsCache = {};
980
981// Convert String-formatted flags into Object-formatted ones and store in cache
982function createFlags( flags ) {
983 var object = flagsCache[ flags ] = {},
984 i, length;
985 flags = flags.split( /\s+/ );
986 for ( i = 0, length = flags.length; i < length; i++ ) {
987 object[ flags[i] ] = true;
988 }
989 return object;
990}
991
992/*
993 * Create a callback list using the following parameters:
994 *
995 * flags: an optional list of space-separated flags that will change how
996 * the callback list behaves
997 *
998 * By default a callback list will act like an event callback list and can be
999 * "fired" multiple times.
1000 *
1001 * Possible flags:
1002 *
1003 * once: will ensure the callback list can only be fired once (like a Deferred)
1004 *
1005 * memory: will keep track of previous values and will call any callback added
1006 * after the list has been fired right away with the latest "memorized"
1007 * values (like a Deferred)
1008 *
1009 * unique: will ensure a callback can only be added once (no duplicate in the list)
1010 *
1011 * stopOnFalse: interrupt callings when a callback returns false
1012 *
1013 */
1014jQuery.Callbacks = function( flags ) {
1015
1016 // Convert flags from String-formatted to Object-formatted
1017 // (we check in cache first)
1018 flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {};
1019
1020 var // Actual callback list
1021 list = [],
1022 // Stack of fire calls for repeatable lists
1023 stack = [],
1024 // Last fire value (for non-forgettable lists)
1025 memory,
1026 // Flag to know if list is currently firing
1027 firing,
1028 // First callback to fire (used internally by add and fireWith)
1029 firingStart,
1030 // End of the loop when firing
1031 firingLength,
1032 // Index of currently firing callback (modified by remove if needed)
1033 firingIndex,
1034 // Add one or several callbacks to the list
1035 add = function( args ) {
1036 var i,
1037 length,
1038 elem,
1039 type,
1040 actual;
1041 for ( i = 0, length = args.length; i < length; i++ ) {
1042 elem = args[ i ];
1043 type = jQuery.type( elem );
1044 if ( type === "array" ) {
1045 // Inspect recursively
1046 add( elem );
1047 } else if ( type === "function" ) {
1048 // Add if not in unique mode and callback is not in
1049 if ( !flags.unique || !self.has( elem ) ) {
1050 list.push( elem );
1051 }
1052 }
1053 }
1054 },
1055 // Fire callbacks
1056 fire = function( context, args ) {
1057 args = args || [];
1058 memory = !flags.memory || [ context, args ];
1059 firing = true;
1060 firingIndex = firingStart || 0;
1061 firingStart = 0;
1062 firingLength = list.length;
1063 for ( ; list && firingIndex < firingLength; firingIndex++ ) {
1064 if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) {
1065 memory = true; // Mark as halted
1066 break;
1067 }
1068 }
1069 firing = false;
1070 if ( list ) {
1071 if ( !flags.once ) {
1072 if ( stack && stack.length ) {
1073 memory = stack.shift();
1074 self.fireWith( memory[ 0 ], memory[ 1 ] );
1075 }
1076 } else if ( memory === true ) {
1077 self.disable();
1078 } else {
1079 list = [];
1080 }
1081 }
1082 },
1083 // Actual Callbacks object
1084 self = {
1085 // Add a callback or a collection of callbacks to the list
1086 add: function() {
1087 if ( list ) {
1088 var length = list.length;
1089 add( arguments );
1090 // Do we need to add the callbacks to the
1091 // current firing batch?
1092 if ( firing ) {
1093 firingLength = list.length;
1094 // With memory, if we're not firing then
1095 // we should call right away, unless previous
1096 // firing was halted (stopOnFalse)
1097 } else if ( memory && memory !== true ) {
1098 firingStart = length;
1099 fire( memory[ 0 ], memory[ 1 ] );
1100 }
1101 }
1102 return this;
1103 },
1104 // Remove a callback from the list
1105 remove: function() {
1106 if ( list ) {
1107 var args = arguments,
1108 argIndex = 0,
1109 argLength = args.length;
1110 for ( ; argIndex < argLength ; argIndex++ ) {
1111 for ( var i = 0; i < list.length; i++ ) {
1112 if ( args[ argIndex ] === list[ i ] ) {
1113 // Handle firingIndex and firingLength
1114 if ( firing ) {
1115 if ( i <= firingLength ) {
1116 firingLength--;
1117 if ( i <= firingIndex ) {
1118 firingIndex--;
1119 }
1120 }
1121 }
1122 // Remove the element
1123 list.splice( i--, 1 );
1124 // If we have some unicity property then
1125 // we only need to do this once
1126 if ( flags.unique ) {
1127 break;
1128 }
1129 }
1130 }
1131 }
1132 }
1133 return this;
1134 },
1135 // Control if a given callback is in the list
1136 has: function( fn ) {
1137 if ( list ) {
1138 var i = 0,
1139 length = list.length;
1140 for ( ; i < length; i++ ) {
1141 if ( fn === list[ i ] ) {
1142 return true;
1143 }
1144 }
1145 }
1146 return false;
1147 },
1148 // Remove all callbacks from the list
1149 empty: function() {
1150 list = [];
1151 return this;
1152 },
1153 // Have the list do nothing anymore
1154 disable: function() {
1155 list = stack = memory = undefined;
1156 return this;
1157 },
1158 // Is it disabled?
1159 disabled: function() {
1160 return !list;
1161 },
1162 // Lock the list in its current state
1163 lock: function() {
1164 stack = undefined;
1165 if ( !memory || memory === true ) {
1166 self.disable();
1167 }
1168 return this;
1169 },
1170 // Is it locked?
1171 locked: function() {
1172 return !stack;
1173 },
1174 // Call all callbacks with the given context and arguments
1175 fireWith: function( context, args ) {
1176 if ( stack ) {
1177 if ( firing ) {
1178 if ( !flags.once ) {
1179 stack.push( [ context, args ] );
1180 }
1181 } else if ( !( flags.once && memory ) ) {
1182 fire( context, args );
1183 }
1184 }
1185 return this;
1186 },
1187 // Call all the callbacks with the given arguments
1188 fire: function() {
1189 self.fireWith( this, arguments );
1190 return this;
1191 },
1192 // To know if the callbacks have already been called at least once
1193 fired: function() {
1194 return !!memory;
1195 }
1196 };
1197
1198 return self;
1199};
1200
1201
1202
1203
1204var // Static reference to slice
1205 sliceDeferred = [].slice;
1206
1207jQuery.extend({
1208
1209 Deferred: function( func ) {
1210 var doneList = jQuery.Callbacks( "once memory" ),
1211 failList = jQuery.Callbacks( "once memory" ),
1212 progressList = jQuery.Callbacks( "memory" ),
1213 state = "pending",
1214 lists = {
1215 resolve: doneList,
1216 reject: failList,
1217 notify: progressList
1218 },
1219 promise = {
1220 done: doneList.add,
1221 fail: failList.add,
1222 progress: progressList.add,
1223
1224 state: function() {
1225 return state;
1226 },
1227
1228 // Deprecated
1229 isResolved: doneList.fired,
1230 isRejected: failList.fired,
1231
1232 then: function( doneCallbacks, failCallbacks, progressCallbacks ) {
1233 deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks );
1234 return this;
1235 },
1236 always: function() {
1237 return deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments );
1238 },
1239 pipe: function( fnDone, fnFail, fnProgress ) {
1240 return jQuery.Deferred(function( newDefer ) {
1241 jQuery.each( {
1242 done: [ fnDone, "resolve" ],
1243 fail: [ fnFail, "reject" ],
1244 progress: [ fnProgress, "notify" ]
1245 }, function( handler, data ) {
1246 var fn = data[ 0 ],
1247 action = data[ 1 ],
1248 returned;
1249 if ( jQuery.isFunction( fn ) ) {
1250 deferred[ handler ](function() {
1251 returned = fn.apply( this, arguments );
1252 if ( returned && jQuery.isFunction( returned.promise ) ) {
1253 returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify );
1254 } else {
1255 newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] );
1256 }
1257 });
1258 } else {
1259 deferred[ handler ]( newDefer[ action ] );
1260 }
1261 });
1262 }).promise();
1263 },
1264 // Get a promise for this deferred
1265 // If obj is provided, the promise aspect is added to the object
1266 promise: function( obj ) {
1267 if ( obj == null ) {
1268 obj = promise;
1269 } else {
1270 for ( var key in promise ) {
1271 obj[ key ] = promise[ key ];
1272 }
1273 }
1274 return obj;
1275 }
1276 },
1277 deferred = promise.promise({}),
1278 key;
1279
1280 for ( key in lists ) {
1281 deferred[ key ] = lists[ key ].fire;
1282 deferred[ key + "With" ] = lists[ key ].fireWith;
1283 }
1284
1285 // Handle state
1286 deferred.done( function() {
1287 state = "resolved";
1288 }, failList.disable, progressList.lock ).fail( function() {
1289 state = "rejected";
1290 }, doneList.disable, progressList.lock );
1291
1292 // Call given func if any
1293 if ( func ) {
1294 func.call( deferred, deferred );
1295 }
1296
1297 // All done!
1298 return deferred;
1299 },
1300
1301 // Deferred helper
1302 when: function( firstParam ) {
1303 var args = sliceDeferred.call( arguments, 0 ),
1304 i = 0,
1305 length = args.length,
1306 pValues = new Array( length ),
1307 count = length,
1308 pCount = length,
1309 deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
1310 firstParam :
1311 jQuery.Deferred(),
1312 promise = deferred.promise();
1313 function resolveFunc( i ) {
1314 return function( value ) {
1315 args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
1316 if ( !( --count ) ) {
1317 deferred.resolveWith( deferred, args );
1318 }
1319 };
1320 }
1321 function progressFunc( i ) {
1322 return function( value ) {
1323 pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
1324 deferred.notifyWith( promise, pValues );
1325 };
1326 }
1327 if ( length > 1 ) {
1328 for ( ; i < length; i++ ) {
1329 if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) {
1330 args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) );
1331 } else {
1332 --count;
1333 }
1334 }
1335 if ( !count ) {
1336 deferred.resolveWith( deferred, args );
1337 }
1338 } else if ( deferred !== firstParam ) {
1339 deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
1340 }
1341 return promise;
1342 }
1343});
1344
1345
1346
1347
1348jQuery.support = (function() {
1349
1350 var div = document.createElement( "div" ),
1351 documentElement = document.documentElement,
1352 all,
1353 a,
1354 select,
1355 opt,
1356 input,
1357 marginDiv,
1358 support,
1359 fragment,
1360 body,
1361 testElementParent,
1362 testElement,
1363 testElementStyle,
1364 tds,
1365 events,
1366 eventName,
1367 i,
1368 isSupported;
1369
1370 // Preliminary tests
1371 div.setAttribute("className", "t");
1372 div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/><nav></nav>";
1373
1374
1375 all = div.getElementsByTagName( "*" );
1376 a = div.getElementsByTagName( "a" )[ 0 ];
1377
1378 // Can't get basic test support
1379 if ( !all || !all.length || !a ) {
1380 return {};
1381 }
1382
1383 // First batch of supports tests
1384 select = document.createElement( "select" );
1385 opt = select.appendChild( document.createElement("option") );
1386 input = div.getElementsByTagName( "input" )[ 0 ];
1387
1388 support = {
1389 // IE strips leading whitespace when .innerHTML is used
1390 leadingWhitespace: ( div.firstChild.nodeType === 3 ),
1391
1392 // Make sure that tbody elements aren't automatically inserted
1393 // IE will insert them into empty tables
1394 tbody: !div.getElementsByTagName( "tbody" ).length,
1395
1396 // Make sure that link elements get serialized correctly by innerHTML
1397 // This requires a wrapper element in IE
1398 htmlSerialize: !!div.getElementsByTagName( "link" ).length,
1399
1400 // Get the style information from getAttribute
1401 // (IE uses .cssText instead)
1402 style: /top/.test( a.getAttribute("style") ),
1403
1404 // Make sure that URLs aren't manipulated
1405 // (IE normalizes it by default)
1406 hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
1407
1408 // Make sure that element opacity exists
1409 // (IE uses filter instead)
1410 // Use a regex to work around a WebKit issue. See #5145
1411 opacity: /^0.55/.test( a.style.opacity ),
1412
1413 // Verify style float existence
1414 // (IE uses styleFloat instead of cssFloat)
1415 cssFloat: !!a.style.cssFloat,
1416
1417 // Make sure unknown elements (like HTML5 elems) are handled appropriately
1418 unknownElems: !!div.getElementsByTagName( "nav" ).length,
1419
1420 // Make sure that if no value is specified for a checkbox
1421 // that it defaults to "on".
1422 // (WebKit defaults to "" instead)
1423 checkOn: ( input.value === "on" ),
1424
1425 // Make sure that a selected-by-default option has a working selected property.
1426 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
1427 optSelected: opt.selected,
1428
1429 // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
1430 getSetAttribute: div.className !== "t",
1431
1432 // Tests for enctype support on a form(#6743)
1433 enctype: !!document.createElement("form").enctype,
1434
1435 // Will be defined later
1436 submitBubbles: true,
1437 changeBubbles: true,
1438 focusinBubbles: false,
1439 deleteExpando: true,
1440 noCloneEvent: true,
1441 inlineBlockNeedsLayout: false,
1442 shrinkWrapBlocks: false,
1443 reliableMarginRight: true
1444 };
1445
1446 // Make sure checked status is properly cloned
1447 input.checked = true;
1448 support.noCloneChecked = input.cloneNode( true ).checked;
1449
1450 // Make sure that the options inside disabled selects aren't marked as disabled
1451 // (WebKit marks them as disabled)
1452 select.disabled = true;
1453 support.optDisabled = !opt.disabled;
1454
1455 // Test to see if it's possible to delete an expando from an element
1456 // Fails in Internet Explorer
1457 try {
1458 delete div.test;
1459 } catch( e ) {
1460 support.deleteExpando = false;
1461 }
1462
1463 if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
1464 div.attachEvent( "onclick", function() {
1465 // Cloning a node shouldn't copy over any
1466 // bound event handlers (IE does this)
1467 support.noCloneEvent = false;
1468 });
1469 div.cloneNode( true ).fireEvent( "onclick" );
1470 }
1471
1472 // Check if a radio maintains its value
1473 // after being appended to the DOM
1474 input = document.createElement("input");
1475 input.value = "t";
1476 input.setAttribute("type", "radio");
1477 support.radioValue = input.value === "t";
1478
1479 input.setAttribute("checked", "checked");
1480 div.appendChild( input );
1481 fragment = document.createDocumentFragment();
1482 fragment.appendChild( div.lastChild );
1483
1484 // WebKit doesn't clone checked state correctly in fragments
1485 support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
1486
1487 div.innerHTML = "";
1488
1489 // Figure out if the W3C box model works as expected
1490 div.style.width = div.style.paddingLeft = "1px";
1491
1492 // We don't want to do body-related feature tests on frameset
1493 // documents, which lack a body. So we use
1494 // document.getElementsByTagName("body")[0], which is undefined in
1495 // frameset documents, while document.body isn’t. (7398)
1496 body = document.getElementsByTagName("body")[ 0 ];
1497 // We use our own, invisible, body unless the body is already present
1498 // in which case we use a div (#9239)
1499 testElement = document.createElement( body ? "div" : "body" );
1500 testElementStyle = {
1501 visibility: "hidden",
1502 width: 0,
1503 height: 0,
1504 border: 0,
1505 margin: 0,
1506 background: "none"
1507 };
1508 if ( body ) {
1509 jQuery.extend( testElementStyle, {
1510 position: "absolute",
1511 left: "-999px",
1512 top: "-999px"
1513 });
1514 }
1515 for ( i in testElementStyle ) {
1516 testElement.style[ i ] = testElementStyle[ i ];
1517 }
1518 testElement.appendChild( div );
1519 testElementParent = body || documentElement;
1520 testElementParent.insertBefore( testElement, testElementParent.firstChild );
1521
1522 // Check if a disconnected checkbox will retain its checked
1523 // value of true after appended to the DOM (IE6/7)
1524 support.appendChecked = input.checked;
1525
1526 support.boxModel = div.offsetWidth === 2;
1527
1528 if ( "zoom" in div.style ) {
1529 // Check if natively block-level elements act like inline-block
1530 // elements when setting their display to 'inline' and giving
1531 // them layout
1532 // (IE < 8 does this)
1533 div.style.display = "inline";
1534 div.style.zoom = 1;
1535 support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
1536
1537 // Check if elements with layout shrink-wrap their children
1538 // (IE 6 does this)
1539 div.style.display = "";
1540 div.innerHTML = "<div style='width:4px;'></div>";
1541 support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
1542 }
1543
1544 div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
1545 tds = div.getElementsByTagName( "td" );
1546
1547 // Check if table cells still have offsetWidth/Height when they are set
1548 // to display:none and there are still other visible table cells in a
1549 // table row; if so, offsetWidth/Height are not reliable for use when
1550 // determining if an element has been hidden directly using
1551 // display:none (it is still safe to use offsets if a parent element is
1552 // hidden; don safety goggles and see bug #4512 for more information).
1553 // (only IE 8 fails this test)
1554 isSupported = ( tds[ 0 ].offsetHeight === 0 );
1555
1556 tds[ 0 ].style.display = "";
1557 tds[ 1 ].style.display = "none";
1558
1559 // Check if empty table cells still have offsetWidth/Height
1560 // (IE < 8 fail this test)
1561 support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
1562 div.innerHTML = "";
1563
1564 // Check if div with explicit width and no margin-right incorrectly
1565 // gets computed margin-right based on width of container. For more
1566 // info see bug #3333
1567 // Fails in WebKit before Feb 2011 nightlies
1568 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
1569 if ( document.defaultView && document.defaultView.getComputedStyle ) {
1570 marginDiv = document.createElement( "div" );
1571 marginDiv.style.width = "0";
1572 marginDiv.style.marginRight = "0";
1573 div.appendChild( marginDiv );
1574 support.reliableMarginRight =
1575 ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
1576 }
1577
1578 // Technique from Juriy Zaytsev
1579 // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/
1580 // We only care about the case where non-standard event systems
1581 // are used, namely in IE. Short-circuiting here helps us to
1582 // avoid an eval call (in setAttribute) which can cause CSP
1583 // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
1584 if ( div.attachEvent ) {
1585 for( i in {
1586 submit: 1,
1587 change: 1,
1588 focusin: 1
1589 } ) {
1590 eventName = "on" + i;
1591 isSupported = ( eventName in div );
1592 if ( !isSupported ) {
1593 div.setAttribute( eventName, "return;" );
1594 isSupported = ( typeof div[ eventName ] === "function" );
1595 }
1596 support[ i + "Bubbles" ] = isSupported;
1597 }
1598 }
1599
1600 // Run fixed position tests at doc ready to avoid a crash
1601 // related to the invisible body in IE8
1602 jQuery(function() {
1603 var container, outer, inner, table, td, offsetSupport,
1604 conMarginTop = 1,
1605 ptlm = "position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",
1606 vb = "visibility:hidden;border:0;",
1607 style = "style='" + ptlm + "border:5px solid #000;padding:0;'",
1608 html = "<div " + style + "><div></div></div>" +
1609 "<table " + style + " cellpadding='0' cellspacing='0'>" +
1610 "<tr><td></td></tr></table>";
1611
1612 // Reconstruct a container
1613 body = document.getElementsByTagName("body")[0];
1614 if ( !body ) {
1615 // Return for frameset docs that don't have a body
1616 // These tests cannot be done
1617 return;
1618 }
1619
1620 container = document.createElement("div");
1621 container.style.cssText = vb + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px";
1622 body.insertBefore( container, body.firstChild );
1623
1624 // Construct a test element
1625 testElement = document.createElement("div");
1626 testElement.style.cssText = ptlm + vb;
1627
1628 testElement.innerHTML = html;
1629 container.appendChild( testElement );
1630 outer = testElement.firstChild;
1631 inner = outer.firstChild;
1632 td = outer.nextSibling.firstChild.firstChild;
1633
1634 offsetSupport = {
1635 doesNotAddBorder: ( inner.offsetTop !== 5 ),
1636 doesAddBorderForTableAndCells: ( td.offsetTop === 5 )
1637 };
1638
1639 inner.style.position = "fixed";
1640 inner.style.top = "20px";
1641
1642 // safari subtracts parent border width here which is 5px
1643 offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 );
1644 inner.style.position = inner.style.top = "";
1645
1646 outer.style.overflow = "hidden";
1647 outer.style.position = "relative";
1648
1649 offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 );
1650 offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop );
1651
1652 body.removeChild( container );
1653 testElement = container = null;
1654
1655 jQuery.extend( support, offsetSupport );
1656 });
1657
1658 testElement.innerHTML = "";
1659 testElementParent.removeChild( testElement );
1660
1661 // Null connected elements to avoid leaks in IE
1662 testElement = fragment = select = opt = body = marginDiv = div = input = null;
1663
1664 return support;
1665})();
1666
1667// Keep track of boxModel
1668jQuery.boxModel = jQuery.support.boxModel;
1669
1670
1671
1672
1673var rbrace = /^(?:\{.*\}|\[.*\])$/,
1674 rmultiDash = /([A-Z])/g;
1675
1676jQuery.extend({
1677 cache: {},
1678
1679 // Please use with caution
1680 uuid: 0,
1681
1682 // Unique for each copy of jQuery on the page
1683 // Non-digits removed to match rinlinejQuery
1684 expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
1685
1686 // The following elements throw uncatchable exceptions if you
1687 // attempt to add expando properties to them.
1688 noData: {
1689 "embed": true,
1690 // Ban all objects except for Flash (which handle expandos)
1691 "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1692 "applet": true
1693 },
1694
1695 hasData: function( elem ) {
1696 elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
1697 return !!elem && !isEmptyDataObject( elem );
1698 },
1699
1700 data: function( elem, name, data, pvt /* Internal Use Only */ ) {
1701 if ( !jQuery.acceptData( elem ) ) {
1702 return;
1703 }
1704
1705 var privateCache, thisCache, ret,
1706 internalKey = jQuery.expando,
1707 getByName = typeof name === "string",
1708
1709 // We have to handle DOM nodes and JS objects differently because IE6-7
1710 // can't GC object references properly across the DOM-JS boundary
1711 isNode = elem.nodeType,
1712
1713 // Only DOM nodes need the global jQuery cache; JS object data is
1714 // attached directly to the object so GC can occur automatically
1715 cache = isNode ? jQuery.cache : elem,
1716
1717 // Only defining an ID for JS objects if its cache already exists allows
1718 // the code to shortcut on the same path as a DOM node with no cache
1719 id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando,
1720 isEvents = name === "events";
1721
1722 // Avoid doing any more work than we need to when trying to get data on an
1723 // object that has no data at all
1724 if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) {
1725 return;
1726 }
1727
1728 if ( !id ) {
1729 // Only DOM nodes need a new unique ID for each element since their data
1730 // ends up in the global cache
1731 if ( isNode ) {
1732 elem[ jQuery.expando ] = id = ++jQuery.uuid;
1733 } else {
1734 id = jQuery.expando;
1735 }
1736 }
1737
1738 if ( !cache[ id ] ) {
1739 cache[ id ] = {};
1740
1741 // Avoids exposing jQuery metadata on plain JS objects when the object
1742 // is serialized using JSON.stringify
1743 if ( !isNode ) {
1744 cache[ id ].toJSON = jQuery.noop;
1745 }
1746 }
1747
1748 // An object can be passed to jQuery.data instead of a key/value pair; this gets
1749 // shallow copied over onto the existing cache
1750 if ( typeof name === "object" || typeof name === "function" ) {
1751 if ( pvt ) {
1752 cache[ id ] = jQuery.extend( cache[ id ], name );
1753 } else {
1754 cache[ id ].data = jQuery.extend( cache[ id ].data, name );
1755 }
1756 }
1757
1758 privateCache = thisCache = cache[ id ];
1759
1760 // jQuery data() is stored in a separate object inside the object's internal data
1761 // cache in order to avoid key collisions between internal data and user-defined
1762 // data.
1763 if ( !pvt ) {
1764 if ( !thisCache.data ) {
1765 thisCache.data = {};
1766 }
1767
1768 thisCache = thisCache.data;
1769 }
1770
1771 if ( data !== undefined ) {
1772 thisCache[ jQuery.camelCase( name ) ] = data;
1773 }
1774
1775 // Users should not attempt to inspect the internal events object using jQuery.data,
1776 // it is undocumented and subject to change. But does anyone listen? No.
1777 if ( isEvents && !thisCache[ name ] ) {
1778 return privateCache.events;
1779 }
1780
1781 // Check for both converted-to-camel and non-converted data property names
1782 // If a data property was specified
1783 if ( getByName ) {
1784
1785 // First Try to find as-is property data
1786 ret = thisCache[ name ];
1787
1788 // Test for null|undefined property data
1789 if ( ret == null ) {
1790
1791 // Try to find the camelCased property
1792 ret = thisCache[ jQuery.camelCase( name ) ];
1793 }
1794 } else {
1795 ret = thisCache;
1796 }
1797
1798 return ret;
1799 },
1800
1801 removeData: function( elem, name, pvt /* Internal Use Only */ ) {
1802 if ( !jQuery.acceptData( elem ) ) {
1803 return;
1804 }
1805
1806 var thisCache, i, l,
1807
1808 // Reference to internal data cache key
1809 internalKey = jQuery.expando,
1810
1811 isNode = elem.nodeType,
1812
1813 // See jQuery.data for more information
1814 cache = isNode ? jQuery.cache : elem,
1815
1816 // See jQuery.data for more information
1817 id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
1818
1819 // If there is already no cache entry for this object, there is no
1820 // purpose in continuing
1821 if ( !cache[ id ] ) {
1822 return;
1823 }
1824
1825 if ( name ) {
1826
1827 thisCache = pvt ? cache[ id ] : cache[ id ].data;
1828
1829 if ( thisCache ) {
1830
1831 // Support space separated names
1832 if ( jQuery.isArray( name ) ) {
1833 name = name;
1834 } else if ( name in thisCache ) {
1835 name = [ name ];
1836 } else {
1837
1838 // split the camel cased version by spaces
1839 name = jQuery.camelCase( name );
1840 if ( name in thisCache ) {
1841 name = [ name ];
1842 } else {
1843 name = name.split( " " );
1844 }
1845 }
1846
1847 for ( i = 0, l = name.length; i < l; i++ ) {
1848 delete thisCache[ name[i] ];
1849 }
1850
1851 // If there is no data left in the cache, we want to continue
1852 // and let the cache object itself get destroyed
1853 if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) {
1854 return;
1855 }
1856 }
1857 }
1858
1859 // See jQuery.data for more information
1860 if ( !pvt ) {
1861 delete cache[ id ].data;
1862
1863 // Don't destroy the parent cache unless the internal data object
1864 // had been the only thing left in it
1865 if ( !isEmptyDataObject(cache[ id ]) ) {
1866 return;
1867 }
1868 }
1869
1870 // Browsers that fail expando deletion also refuse to delete expandos on
1871 // the window, but it will allow it on all other JS objects; other browsers
1872 // don't care
1873 // Ensure that `cache` is not a window object #10080
1874 if ( jQuery.support.deleteExpando || !cache.setInterval ) {
1875 delete cache[ id ];
1876 } else {
1877 cache[ id ] = null;
1878 }
1879
1880 // We destroyed the cache and need to eliminate the expando on the node to avoid
1881 // false lookups in the cache for entries that no longer exist
1882 if ( isNode ) {
1883 // IE does not allow us to delete expando properties from nodes,
1884 // nor does it have a removeAttribute function on Document nodes;
1885 // we must handle all of these cases
1886 if ( jQuery.support.deleteExpando ) {
1887 delete elem[ jQuery.expando ];
1888 } else if ( elem.removeAttribute ) {
1889 elem.removeAttribute( jQuery.expando );
1890 } else {
1891 elem[ jQuery.expando ] = null;
1892 }
1893 }
1894 },
1895
1896 // For internal use only.
1897 _data: function( elem, name, data ) {
1898 return jQuery.data( elem, name, data, true );
1899 },
1900
1901 // A method for determining if a DOM node can handle the data expando
1902 acceptData: function( elem ) {
1903 if ( elem.nodeName ) {
1904 var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
1905
1906 if ( match ) {
1907 return !(match === true || elem.getAttribute("classid") !== match);
1908 }
1909 }
1910
1911 return true;
1912 }
1913});
1914
1915jQuery.fn.extend({
1916 data: function( key, value ) {
1917 var parts, attr, name,
1918 data = null;
1919
1920 if ( typeof key === "undefined" ) {
1921 if ( this.length ) {
1922 data = jQuery.data( this[0] );
1923
1924 if ( this[0].nodeType === 1 && !jQuery._data( this[0], "parsedAttrs" ) ) {
1925 attr = this[0].attributes;
1926 for ( var i = 0, l = attr.length; i < l; i++ ) {
1927 name = attr[i].name;
1928
1929 if ( name.indexOf( "data-" ) === 0 ) {
1930 name = jQuery.camelCase( name.substring(5) );
1931
1932 dataAttr( this[0], name, data[ name ] );
1933 }
1934 }
1935 jQuery._data( this[0], "parsedAttrs", true );
1936 }
1937 }
1938
1939 return data;
1940
1941 } else if ( typeof key === "object" ) {
1942 return this.each(function() {
1943 jQuery.data( this, key );
1944 });
1945 }
1946
1947 parts = key.split(".");
1948 parts[1] = parts[1] ? "." + parts[1] : "";
1949
1950 if ( value === undefined ) {
1951 data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1952
1953 // Try to fetch any internally stored data first
1954 if ( data === undefined && this.length ) {
1955 data = jQuery.data( this[0], key );
1956 data = dataAttr( this[0], key, data );
1957 }
1958
1959 return data === undefined && parts[1] ?
1960 this.data( parts[0] ) :
1961 data;
1962
1963 } else {
1964 return this.each(function() {
1965 var $this = jQuery( this ),
1966 args = [ parts[0], value ];
1967
1968 $this.triggerHandler( "setData" + parts[1] + "!", args );
1969 jQuery.data( this, key, value );
1970 $this.triggerHandler( "changeData" + parts[1] + "!", args );
1971 });
1972 }
1973 },
1974
1975 removeData: function( key ) {
1976 return this.each(function() {
1977 jQuery.removeData( this, key );
1978 });
1979 }
1980});
1981
1982function dataAttr( elem, key, data ) {
1983 // If nothing was found internally, try to fetch any
1984 // data from the HTML5 data-* attribute
1985 if ( data === undefined && elem.nodeType === 1 ) {
1986
1987 var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
1988
1989 data = elem.getAttribute( name );
1990
1991 if ( typeof data === "string" ) {
1992 try {
1993 data = data === "true" ? true :
1994 data === "false" ? false :
1995 data === "null" ? null :
1996 jQuery.isNumeric( data ) ? parseFloat( data ) :
1997 rbrace.test( data ) ? jQuery.parseJSON( data ) :
1998 data;
1999 } catch( e ) {}
2000
2001 // Make sure we set the data so it isn't changed later
2002 jQuery.data( elem, key, data );
2003
2004 } else {
2005 data = undefined;
2006 }
2007 }
2008
2009 return data;
2010}
2011
2012// checks a cache object for emptiness
2013function isEmptyDataObject( obj ) {
2014 for ( var name in obj ) {
2015
2016 // if the public data object is empty, the private is still empty
2017 if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
2018 continue;
2019 }
2020 if ( name !== "toJSON" ) {
2021 return false;
2022 }
2023 }
2024
2025 return true;
2026}
2027
2028
2029
2030
2031function handleQueueMarkDefer( elem, type, src ) {
2032 var deferDataKey = type + "defer",
2033 queueDataKey = type + "queue",
2034 markDataKey = type + "mark",
2035 defer = jQuery._data( elem, deferDataKey );
2036 if ( defer &&
2037 ( src === "queue" || !jQuery._data(elem, queueDataKey) ) &&
2038 ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) {
2039 // Give room for hard-coded callbacks to fire first
2040 // and eventually mark/queue something else on the element
2041 setTimeout( function() {
2042 if ( !jQuery._data( elem, queueDataKey ) &&
2043 !jQuery._data( elem, markDataKey ) ) {
2044 jQuery.removeData( elem, deferDataKey, true );
2045 defer.fire();
2046 }
2047 }, 0 );
2048 }
2049}
2050
2051jQuery.extend({
2052
2053 _mark: function( elem, type ) {
2054 if ( elem ) {
2055 type = ( type || "fx" ) + "mark";
2056 jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 );
2057 }
2058 },
2059
2060 _unmark: function( force, elem, type ) {
2061 if ( force !== true ) {
2062 type = elem;
2063 elem = force;
2064 force = false;
2065 }
2066 if ( elem ) {
2067 type = type || "fx";
2068 var key = type + "mark",
2069 count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 );
2070 if ( count ) {
2071 jQuery._data( elem, key, count );
2072 } else {
2073 jQuery.removeData( elem, key, true );
2074 handleQueueMarkDefer( elem, type, "mark" );
2075 }
2076 }
2077 },
2078
2079 queue: function( elem, type, data ) {
2080 var q;
2081 if ( elem ) {
2082 type = ( type || "fx" ) + "queue";
2083 q = jQuery._data( elem, type );
2084
2085 // Speed up dequeue by getting out quickly if this is just a lookup
2086 if ( data ) {
2087 if ( !q || jQuery.isArray(data) ) {
2088 q = jQuery._data( elem, type, jQuery.makeArray(data) );
2089 } else {
2090 q.push( data );
2091 }
2092 }
2093 return q || [];
2094 }
2095 },
2096
2097 dequeue: function( elem, type ) {
2098 type = type || "fx";
2099
2100 var queue = jQuery.queue( elem, type ),
2101 fn = queue.shift(),
2102 hooks = {};
2103
2104 // If the fx queue is dequeued, always remove the progress sentinel
2105 if ( fn === "inprogress" ) {
2106 fn = queue.shift();
2107 }
2108
2109 if ( fn ) {
2110 // Add a progress sentinel to prevent the fx queue from being
2111 // automatically dequeued
2112 if ( type === "fx" ) {
2113 queue.unshift( "inprogress" );
2114 }
2115
2116 jQuery._data( elem, type + ".run", hooks );
2117 fn.call( elem, function() {
2118 jQuery.dequeue( elem, type );
2119 }, hooks );
2120 }
2121
2122 if ( !queue.length ) {
2123 jQuery.removeData( elem, type + "queue " + type + ".run", true );
2124 handleQueueMarkDefer( elem, type, "queue" );
2125 }
2126 }
2127});
2128
2129jQuery.fn.extend({
2130 queue: function( type, data ) {
2131 if ( typeof type !== "string" ) {
2132 data = type;
2133 type = "fx";
2134 }
2135
2136 if ( data === undefined ) {
2137 return jQuery.queue( this[0], type );
2138 }
2139 return this.each(function() {
2140 var queue = jQuery.queue( this, type, data );
2141
2142 if ( type === "fx" && queue[0] !== "inprogress" ) {
2143 jQuery.dequeue( this, type );
2144 }
2145 });
2146 },
2147 dequeue: function( type ) {
2148 return this.each(function() {
2149 jQuery.dequeue( this, type );
2150 });
2151 },
2152 // Based off of the plugin by Clint Helfers, with permission.
2153 // http://blindsignals.com/index.php/2009/07/jquery-delay/
2154 delay: function( time, type ) {
2155 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
2156 type = type || "fx";
2157
2158 return this.queue( type, function( next, hooks ) {
2159 var timeout = setTimeout( next, time );
2160 hooks.stop = function() {
2161 clearTimeout( timeout );
2162 };
2163 });
2164 },
2165 clearQueue: function( type ) {
2166 return this.queue( type || "fx", [] );
2167 },
2168 // Get a promise resolved when queues of a certain type
2169 // are emptied (fx is the type by default)
2170 promise: function( type, object ) {
2171 if ( typeof type !== "string" ) {
2172 object = type;
2173 type = undefined;
2174 }
2175 type = type || "fx";
2176 var defer = jQuery.Deferred(),
2177 elements = this,
2178 i = elements.length,
2179 count = 1,
2180 deferDataKey = type + "defer",
2181 queueDataKey = type + "queue",
2182 markDataKey = type + "mark",
2183 tmp;
2184 function resolve() {
2185 if ( !( --count ) ) {
2186 defer.resolveWith( elements, [ elements ] );
2187 }
2188 }
2189 while( i-- ) {
2190 if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
2191 ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
2192 jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
2193 jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) {
2194 count++;
2195 tmp.add( resolve );
2196 }
2197 }
2198 resolve();
2199 return defer.promise();
2200 }
2201});
2202
2203
2204
2205
2206var rclass = /[\n\t\r]/g,
2207 rspace = /\s+/,
2208 rreturn = /\r/g,
2209 rtype = /^(?:button|input)$/i,
2210 rfocusable = /^(?:button|input|object|select|textarea)$/i,
2211 rclickable = /^a(?:rea)?$/i,
2212 rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
2213 getSetAttribute = jQuery.support.getSetAttribute,
2214 nodeHook, boolHook, fixSpecified;
2215
2216jQuery.fn.extend({
2217 attr: function( name, value ) {
2218 return jQuery.access( this, name, value, true, jQuery.attr );
2219 },
2220
2221 removeAttr: function( name ) {
2222 return this.each(function() {
2223 jQuery.removeAttr( this, name );
2224 });
2225 },
2226
2227 prop: function( name, value ) {
2228 return jQuery.access( this, name, value, true, jQuery.prop );
2229 },
2230
2231 removeProp: function( name ) {
2232 name = jQuery.propFix[ name ] || name;
2233 return this.each(function() {
2234 // try/catch handles cases where IE balks (such as removing a property on window)
2235 try {
2236 this[ name ] = undefined;
2237 delete this[ name ];
2238 } catch( e ) {}
2239 });
2240 },
2241
2242 addClass: function( value ) {
2243 var classNames, i, l, elem,
2244 setClass, c, cl;
2245
2246 if ( jQuery.isFunction( value ) ) {
2247 return this.each(function( j ) {
2248 jQuery( this ).addClass( value.call(this, j, this.className) );
2249 });
2250 }
2251
2252 if ( value && typeof value === "string" ) {
2253 classNames = value.split( rspace );
2254
2255 for ( i = 0, l = this.length; i < l; i++ ) {
2256 elem = this[ i ];
2257
2258 if ( elem.nodeType === 1 ) {
2259 if ( !elem.className && classNames.length === 1 ) {
2260 elem.className = value;
2261
2262 } else {
2263 setClass = " " + elem.className + " ";
2264
2265 for ( c = 0, cl = classNames.length; c < cl; c++ ) {
2266 if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {
2267 setClass += classNames[ c ] + " ";
2268 }
2269 }
2270 elem.className = jQuery.trim( setClass );
2271 }
2272 }
2273 }
2274 }
2275
2276 return this;
2277 },
2278
2279 removeClass: function( value ) {
2280 var classNames, i, l, elem, className, c, cl;
2281
2282 if ( jQuery.isFunction( value ) ) {
2283 return this.each(function( j ) {
2284 jQuery( this ).removeClass( value.call(this, j, this.className) );
2285 });
2286 }
2287
2288 if ( (value && typeof value === "string") || value === undefined ) {
2289 classNames = ( value || "" ).split( rspace );
2290
2291 for ( i = 0, l = this.length; i < l; i++ ) {
2292 elem = this[ i ];
2293
2294 if ( elem.nodeType === 1 && elem.className ) {
2295 if ( value ) {
2296 className = (" " + elem.className + " ").replace( rclass, " " );
2297 for ( c = 0, cl = classNames.length; c < cl; c++ ) {
2298 className = className.replace(" " + classNames[ c ] + " ", " ");
2299 }
2300 elem.className = jQuery.trim( className );
2301
2302 } else {
2303 elem.className = "";
2304 }
2305 }
2306 }
2307 }
2308
2309 return this;
2310 },
2311
2312 toggleClass: function( value, stateVal ) {
2313 var type = typeof value,
2314 isBool = typeof stateVal === "boolean";
2315
2316 if ( jQuery.isFunction( value ) ) {
2317 return this.each(function( i ) {
2318 jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
2319 });
2320 }
2321
2322 return this.each(function() {
2323 if ( type === "string" ) {
2324 // toggle individual class names
2325 var className,
2326 i = 0,
2327 self = jQuery( this ),
2328 state = stateVal,
2329 classNames = value.split( rspace );
2330
2331 while ( (className = classNames[ i++ ]) ) {
2332 // check each className given, space seperated list
2333 state = isBool ? state : !self.hasClass( className );
2334 self[ state ? "addClass" : "removeClass" ]( className );
2335 }
2336
2337 } else if ( type === "undefined" || type === "boolean" ) {
2338 if ( this.className ) {
2339 // store className if set
2340 jQuery._data( this, "__className__", this.className );
2341 }
2342
2343 // toggle whole className
2344 this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
2345 }
2346 });
2347 },
2348
2349 hasClass: function( selector ) {
2350 var className = " " + selector + " ",
2351 i = 0,
2352 l = this.length;
2353 for ( ; i < l; i++ ) {
2354 if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
2355 return true;
2356 }
2357 }
2358
2359 return false;
2360 },
2361
2362 val: function( value ) {
2363 var hooks, ret, isFunction,
2364 elem = this[0];
2365
2366 if ( !arguments.length ) {
2367 if ( elem ) {
2368 hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
2369
2370 if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
2371 return ret;
2372 }
2373
2374 ret = elem.value;
2375
2376 return typeof ret === "string" ?
2377 // handle most common string cases
2378 ret.replace(rreturn, "") :
2379 // handle cases where value is null/undef or number
2380 ret == null ? "" : ret;
2381 }
2382
2383 return undefined;
2384 }
2385
2386 isFunction = jQuery.isFunction( value );
2387
2388 return this.each(function( i ) {
2389 var self = jQuery(this), val;
2390
2391 if ( this.nodeType !== 1 ) {
2392 return;
2393 }
2394
2395 if ( isFunction ) {
2396 val = value.call( this, i, self.val() );
2397 } else {
2398 val = value;
2399 }
2400
2401 // Treat null/undefined as ""; convert numbers to string
2402 if ( val == null ) {
2403 val = "";
2404 } else if ( typeof val === "number" ) {
2405 val += "";
2406 } else if ( jQuery.isArray( val ) ) {
2407 val = jQuery.map(val, function ( value ) {
2408 return value == null ? "" : value + "";
2409 });
2410 }
2411
2412 hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
2413
2414 // If set returns undefined, fall back to normal setting
2415 if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
2416 this.value = val;
2417 }
2418 });
2419 }
2420});
2421
2422jQuery.extend({
2423 valHooks: {
2424 option: {
2425 get: function( elem ) {
2426 // attributes.value is undefined in Blackberry 4.7 but
2427 // uses .value. See #6932
2428 var val = elem.attributes.value;
2429 return !val || val.specified ? elem.value : elem.text;
2430 }
2431 },
2432 select: {
2433 get: function( elem ) {
2434 var value, i, max, option,
2435 index = elem.selectedIndex,
2436 values = [],
2437 options = elem.options,
2438 one = elem.type === "select-one";
2439
2440 // Nothing was selected
2441 if ( index < 0 ) {
2442 return null;
2443 }
2444
2445 // Loop through all the selected options
2446 i = one ? index : 0;
2447 max = one ? index + 1 : options.length;
2448 for ( ; i < max; i++ ) {
2449 option = options[ i ];
2450
2451 // Don't return options that are disabled or in a disabled optgroup
2452 if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
2453 (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
2454
2455 // Get the specific value for the option
2456 value = jQuery( option ).val();
2457
2458 // We don't need an array for one selects
2459 if ( one ) {
2460 return value;
2461 }
2462
2463 // Multi-Selects return an array
2464 values.push( value );
2465 }
2466 }
2467
2468 // Fixes Bug #2551 -- select.val() broken in IE after form.reset()
2469 if ( one && !values.length && options.length ) {
2470 return jQuery( options[ index ] ).val();
2471 }
2472
2473 return values;
2474 },
2475
2476 set: function( elem, value ) {
2477 var values = jQuery.makeArray( value );
2478
2479 jQuery(elem).find("option").each(function() {
2480 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
2481 });
2482
2483 if ( !values.length ) {
2484 elem.selectedIndex = -1;
2485 }
2486 return values;
2487 }
2488 }
2489 },
2490
2491 attrFn: {
2492 val: true,
2493 css: true,
2494 html: true,
2495 text: true,
2496 data: true,
2497 width: true,
2498 height: true,
2499 offset: true
2500 },
2501
2502 attr: function( elem, name, value, pass ) {
2503 var ret, hooks, notxml,
2504 nType = elem.nodeType;
2505
2506 // don't get/set attributes on text, comment and attribute nodes
2507 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2508 return undefined;
2509 }
2510
2511 if ( pass && name in jQuery.attrFn ) {
2512 return jQuery( elem )[ name ]( value );
2513 }
2514
2515 // Fallback to prop when attributes are not supported
2516 if ( !("getAttribute" in elem) ) {
2517 return jQuery.prop( elem, name, value );
2518 }
2519
2520 notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2521
2522 // All attributes are lowercase
2523 // Grab necessary hook if one is defined
2524 if ( notxml ) {
2525 name = name.toLowerCase();
2526 hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );
2527 }
2528
2529 if ( value !== undefined ) {
2530
2531 if ( value === null ) {
2532 jQuery.removeAttr( elem, name );
2533 return undefined;
2534
2535 } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
2536 return ret;
2537
2538 } else {
2539 elem.setAttribute( name, "" + value );
2540 return value;
2541 }
2542
2543 } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {
2544 return ret;
2545
2546 } else {
2547
2548 ret = elem.getAttribute( name );
2549
2550 // Non-existent attributes return null, we normalize to undefined
2551 return ret === null ?
2552 undefined :
2553 ret;
2554 }
2555 },
2556
2557 removeAttr: function( elem, value ) {
2558 var propName, attrNames, name, l,
2559 i = 0;
2560
2561 if ( elem.nodeType === 1 ) {
2562 attrNames = ( value || "" ).split( rspace );
2563 l = attrNames.length;
2564
2565 for ( ; i < l; i++ ) {
2566 name = attrNames[ i ].toLowerCase();
2567 propName = jQuery.propFix[ name ] || name;
2568
2569 // See #9699 for explanation of this approach (setting first, then removal)
2570 jQuery.attr( elem, name, "" );
2571 elem.removeAttribute( getSetAttribute ? name : propName );
2572
2573 // Set corresponding property to false for boolean attributes
2574 if ( rboolean.test( name ) && propName in elem ) {
2575 elem[ propName ] = false;
2576 }
2577 }
2578 }
2579 },
2580
2581 attrHooks: {
2582 type: {
2583 set: function( elem, value ) {
2584 // We can't allow the type property to be changed (since it causes problems in IE)
2585 if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
2586 jQuery.error( "type property can't be changed" );
2587 } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
2588 // Setting the type on a radio button after the value resets the value in IE6-9
2589 // Reset value to it's default in case type is set after value
2590 // This is for element creation
2591 var val = elem.value;
2592 elem.setAttribute( "type", value );
2593 if ( val ) {
2594 elem.value = val;
2595 }
2596 return value;
2597 }
2598 }
2599 },
2600 // Use the value property for back compat
2601 // Use the nodeHook for button elements in IE6/7 (#1954)
2602 value: {
2603 get: function( elem, name ) {
2604 if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
2605 return nodeHook.get( elem, name );
2606 }
2607 return name in elem ?
2608 elem.value :
2609 null;
2610 },
2611 set: function( elem, value, name ) {
2612 if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
2613 return nodeHook.set( elem, value, name );
2614 }
2615 // Does not return so that setAttribute is also used
2616 elem.value = value;
2617 }
2618 }
2619 },
2620
2621 propFix: {
2622 tabindex: "tabIndex",
2623 readonly: "readOnly",
2624 "for": "htmlFor",
2625 "class": "className",
2626 maxlength: "maxLength",
2627 cellspacing: "cellSpacing",
2628 cellpadding: "cellPadding",
2629 rowspan: "rowSpan",
2630 colspan: "colSpan",
2631 usemap: "useMap",
2632 frameborder: "frameBorder",
2633 contenteditable: "contentEditable"
2634 },
2635
2636 prop: function( elem, name, value ) {
2637 var ret, hooks, notxml,
2638 nType = elem.nodeType;
2639
2640 // don't get/set properties on text, comment and attribute nodes
2641 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2642 return undefined;
2643 }
2644
2645 notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2646
2647 if ( notxml ) {
2648 // Fix name and attach hooks
2649 name = jQuery.propFix[ name ] || name;
2650 hooks = jQuery.propHooks[ name ];
2651 }
2652
2653 if ( value !== undefined ) {
2654 if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
2655 return ret;
2656
2657 } else {
2658 return ( elem[ name ] = value );
2659 }
2660
2661 } else {
2662 if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
2663 return ret;
2664
2665 } else {
2666 return elem[ name ];
2667 }
2668 }
2669 },
2670
2671 propHooks: {
2672 tabIndex: {
2673 get: function( elem ) {
2674 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
2675 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
2676 var attributeNode = elem.getAttributeNode("tabindex");
2677
2678 return attributeNode && attributeNode.specified ?
2679 parseInt( attributeNode.value, 10 ) :
2680 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
2681 0 :
2682 undefined;
2683 }
2684 }
2685 }
2686});
2687
2688// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional)
2689jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex;
2690
2691// Hook for boolean attributes
2692boolHook = {
2693 get: function( elem, name ) {
2694 // Align boolean attributes with corresponding properties
2695 // Fall back to attribute presence where some booleans are not supported
2696 var attrNode,
2697 property = jQuery.prop( elem, name );
2698 return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?
2699 name.toLowerCase() :
2700 undefined;
2701 },
2702 set: function( elem, value, name ) {
2703 var propName;
2704 if ( value === false ) {
2705 // Remove boolean attributes when set to false
2706 jQuery.removeAttr( elem, name );
2707 } else {
2708 // value is true since we know at this point it's type boolean and not false
2709 // Set boolean attributes to the same name and set the DOM property
2710 propName = jQuery.propFix[ name ] || name;
2711 if ( propName in elem ) {
2712 // Only set the IDL specifically if it already exists on the element
2713 elem[ propName ] = true;
2714 }
2715
2716 elem.setAttribute( name, name.toLowerCase() );
2717 }
2718 return name;
2719 }
2720};
2721
2722// IE6/7 do not support getting/setting some attributes with get/setAttribute
2723if ( !getSetAttribute ) {
2724
2725 fixSpecified = {
2726 name: true,
2727 id: true
2728 };
2729
2730 // Use this for any attribute in IE6/7
2731 // This fixes almost every IE6/7 issue
2732 nodeHook = jQuery.valHooks.button = {
2733 get: function( elem, name ) {
2734 var ret;
2735 ret = elem.getAttributeNode( name );
2736 return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ?
2737 ret.nodeValue :
2738 undefined;
2739 },
2740 set: function( elem, value, name ) {
2741 // Set the existing or create a new attribute node
2742 var ret = elem.getAttributeNode( name );
2743 if ( !ret ) {
2744 ret = document.createAttribute( name );
2745 elem.setAttributeNode( ret );
2746 }
2747 return ( ret.nodeValue = value + "" );
2748 }
2749 };
2750
2751 // Apply the nodeHook to tabindex
2752 jQuery.attrHooks.tabindex.set = nodeHook.set;
2753
2754 // Set width and height to auto instead of 0 on empty string( Bug #8150 )
2755 // This is for removals
2756 jQuery.each([ "width", "height" ], function( i, name ) {
2757 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2758 set: function( elem, value ) {
2759 if ( value === "" ) {
2760 elem.setAttribute( name, "auto" );
2761 return value;
2762 }
2763 }
2764 });
2765 });
2766
2767 // Set contenteditable to false on removals(#10429)
2768 // Setting to empty string throws an error as an invalid value
2769 jQuery.attrHooks.contenteditable = {
2770 get: nodeHook.get,
2771 set: function( elem, value, name ) {
2772 if ( value === "" ) {
2773 value = "false";
2774 }
2775 nodeHook.set( elem, value, name );
2776 }
2777 };
2778}
2779
2780
2781// Some attributes require a special call on IE
2782if ( !jQuery.support.hrefNormalized ) {
2783 jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
2784 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2785 get: function( elem ) {
2786 var ret = elem.getAttribute( name, 2 );
2787 return ret === null ? undefined : ret;
2788 }
2789 });
2790 });
2791}
2792
2793if ( !jQuery.support.style ) {
2794 jQuery.attrHooks.style = {
2795 get: function( elem ) {
2796 // Return undefined in the case of empty string
2797 // Normalize to lowercase since IE uppercases css property names
2798 return elem.style.cssText.toLowerCase() || undefined;
2799 },
2800 set: function( elem, value ) {
2801 return ( elem.style.cssText = "" + value );
2802 }
2803 };
2804}
2805
2806// Safari mis-reports the default selected property of an option
2807// Accessing the parent's selectedIndex property fixes it
2808if ( !jQuery.support.optSelected ) {
2809 jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
2810 get: function( elem ) {
2811 var parent = elem.parentNode;
2812
2813 if ( parent ) {
2814 parent.selectedIndex;
2815
2816 // Make sure that it also works with optgroups, see #5701
2817 if ( parent.parentNode ) {
2818 parent.parentNode.selectedIndex;
2819 }
2820 }
2821 return null;
2822 }
2823 });
2824}
2825
2826// IE6/7 call enctype encoding
2827if ( !jQuery.support.enctype ) {
2828 jQuery.propFix.enctype = "encoding";
2829}
2830
2831// Radios and checkboxes getter/setter
2832if ( !jQuery.support.checkOn ) {
2833 jQuery.each([ "radio", "checkbox" ], function() {
2834 jQuery.valHooks[ this ] = {
2835 get: function( elem ) {
2836 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
2837 return elem.getAttribute("value") === null ? "on" : elem.value;
2838 }
2839 };
2840 });
2841}
2842jQuery.each([ "radio", "checkbox" ], function() {
2843 jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
2844 set: function( elem, value ) {
2845 if ( jQuery.isArray( value ) ) {
2846 return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
2847 }
2848 }
2849 });
2850});
2851
2852
2853
2854
2855var rnamespaces = /\.(.*)$/,
2856 rformElems = /^(?:textarea|input|select)$/i,
2857 rperiod = /\./g,
2858 rspaces = / /g,
2859 rescape = /[^\w\s.|`]/g,
2860 rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/,
2861 rhoverHack = /\bhover(\.\S+)?/,
2862 rkeyEvent = /^key/,
2863 rmouseEvent = /^(?:mouse|contextmenu)|click/,
2864 rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,
2865 quickParse = function( selector ) {
2866 var quick = rquickIs.exec( selector );
2867 if ( quick ) {
2868 // 0 1 2 3
2869 // [ _, tag, id, class ]
2870 quick[1] = ( quick[1] || "" ).toLowerCase();
2871 quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" );
2872 }
2873 return quick;
2874 },
2875 quickIs = function( elem, m ) {
2876 return (
2877 (!m[1] || elem.nodeName.toLowerCase() === m[1]) &&
2878 (!m[2] || elem.id === m[2]) &&
2879 (!m[3] || m[3].test( elem.className ))
2880 );
2881 },
2882 hoverHack = function( events ) {
2883 return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );
2884 };
2885
2886/*
2887 * Helper functions for managing events -- not part of the public interface.
2888 * Props to Dean Edwards' addEvent library for many of the ideas.
2889 */
2890jQuery.event = {
2891
2892 add: function( elem, types, handler, data, selector ) {
2893
2894 var elemData, eventHandle, events,
2895 t, tns, type, namespaces, handleObj,
2896 handleObjIn, quick, handlers, special;
2897
2898 // Don't attach events to noData or text/comment nodes (allow plain objects tho)
2899 if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) {
2900 return;
2901 }
2902
2903 // Caller can pass in an object of custom data in lieu of the handler
2904 if ( handler.handler ) {
2905 handleObjIn = handler;
2906 handler = handleObjIn.handler;
2907 }
2908
2909 // Make sure that the handler has a unique ID, used to find/remove it later
2910 if ( !handler.guid ) {
2911 handler.guid = jQuery.guid++;
2912 }
2913
2914 // Init the element's event structure and main handler, if this is the first
2915 events = elemData.events;
2916 if ( !events ) {
2917 elemData.events = events = {};
2918 }
2919 eventHandle = elemData.handle;
2920 if ( !eventHandle ) {
2921 elemData.handle = eventHandle = function( e ) {
2922 // Discard the second event of a jQuery.event.trigger() and
2923 // when an event is called after a page has unloaded
2924 return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
2925 jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
2926 undefined;
2927 };
2928 // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
2929 eventHandle.elem = elem;
2930 }
2931
2932 // Handle multiple events separated by a space
2933 // jQuery(...).bind("mouseover mouseout", fn);
2934 types = hoverHack(types).split( " " );
2935 for ( t = 0; t < types.length; t++ ) {
2936
2937 tns = rtypenamespace.exec( types[t] ) || [];
2938 type = tns[1];
2939 namespaces = ( tns[2] || "" ).split( "." ).sort();
2940
2941 // If event changes its type, use the special event handlers for the changed type
2942 special = jQuery.event.special[ type ] || {};
2943
2944 // If selector defined, determine special event api type, otherwise given type
2945 type = ( selector ? special.delegateType : special.bindType ) || type;
2946
2947 // Update special based on newly reset type
2948 special = jQuery.event.special[ type ] || {};
2949
2950 // handleObj is passed to all event handlers
2951 handleObj = jQuery.extend({
2952 type: type,
2953 origType: tns[1],
2954 data: data,
2955 handler: handler,
2956 guid: handler.guid,
2957 selector: selector,
2958 namespace: namespaces.join(".")
2959 }, handleObjIn );
2960
2961 // Delegated event; pre-analyze selector so it's processed quickly on event dispatch
2962 if ( selector ) {
2963 handleObj.quick = quickParse( selector );
2964 if ( !handleObj.quick && jQuery.expr.match.POS.test( selector ) ) {
2965 handleObj.isPositional = true;
2966 }
2967 }
2968
2969 // Init the event handler queue if we're the first
2970 handlers = events[ type ];
2971 if ( !handlers ) {
2972 handlers = events[ type ] = [];
2973 handlers.delegateCount = 0;
2974
2975 // Only use addEventListener/attachEvent if the special events handler returns false
2976 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
2977 // Bind the global event handler to the element
2978 if ( elem.addEventListener ) {
2979 elem.addEventListener( type, eventHandle, false );
2980
2981 } else if ( elem.attachEvent ) {
2982 elem.attachEvent( "on" + type, eventHandle );
2983 }
2984 }
2985 }
2986
2987 if ( special.add ) {
2988 special.add.call( elem, handleObj );
2989
2990 if ( !handleObj.handler.guid ) {
2991 handleObj.handler.guid = handler.guid;
2992 }
2993 }
2994
2995 // Add to the element's handler list, delegates in front
2996 if ( selector ) {
2997 handlers.splice( handlers.delegateCount++, 0, handleObj );
2998 } else {
2999 handlers.push( handleObj );
3000 }
3001
3002 // Keep track of which events have ever been used, for event optimization
3003 jQuery.event.global[ type ] = true;
3004 }
3005
3006 // Nullify elem to prevent memory leaks in IE
3007 elem = null;
3008 },
3009
3010 global: {},
3011
3012 // Detach an event or set of events from an element
3013 remove: function( elem, types, handler, selector ) {
3014
3015 var elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
3016 t, tns, type, namespaces, origCount,
3017 j, events, special, handle, eventType, handleObj;
3018
3019 if ( !elemData || !(events = elemData.events) ) {
3020 return;
3021 }
3022
3023 // Once for each type.namespace in types; type may be omitted
3024 types = hoverHack( types || "" ).split(" ");
3025 for ( t = 0; t < types.length; t++ ) {
3026 tns = rtypenamespace.exec( types[t] ) || [];
3027 type = tns[1];
3028 namespaces = tns[2];
3029
3030 // Unbind all events (on this namespace, if provided) for the element
3031 if ( !type ) {
3032 namespaces = namespaces? "." + namespaces : "";
3033 for ( j in events ) {
3034 jQuery.event.remove( elem, j + namespaces, handler, selector );
3035 }
3036 return;
3037 }
3038
3039 special = jQuery.event.special[ type ] || {};
3040 type = ( selector? special.delegateType : special.bindType ) || type;
3041 eventType = events[ type ] || [];
3042 origCount = eventType.length;
3043 namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null;
3044
3045 // Only need to loop for special events or selective removal
3046 if ( handler || namespaces || selector || special.remove ) {
3047 for ( j = 0; j < eventType.length; j++ ) {
3048 handleObj = eventType[ j ];
3049
3050 if ( !handler || handler.guid === handleObj.guid ) {
3051 if ( !namespaces || namespaces.test( handleObj.namespace ) ) {
3052 if ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) {
3053 eventType.splice( j--, 1 );
3054
3055 if ( handleObj.selector ) {
3056 eventType.delegateCount--;
3057 }
3058 if ( special.remove ) {
3059 special.remove.call( elem, handleObj );
3060 }
3061 }
3062 }
3063 }
3064 }
3065 } else {
3066 // Removing all events
3067 eventType.length = 0;
3068 }
3069
3070 // Remove generic event handler if we removed something and no more handlers exist
3071 // (avoids potential for endless recursion during removal of special event handlers)
3072 if ( eventType.length === 0 && origCount !== eventType.length ) {
3073 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
3074 jQuery.removeEvent( elem, type, elemData.handle );
3075 }
3076
3077 delete events[ type ];
3078 }
3079 }
3080
3081 // Remove the expando if it's no longer used
3082 if ( jQuery.isEmptyObject( events ) ) {
3083 handle = elemData.handle;
3084 if ( handle ) {
3085 handle.elem = null;
3086 }
3087
3088 // removeData also checks for emptiness and clears the expando if empty
3089 // so use it instead of delete
3090 jQuery.removeData( elem, [ "events", "handle" ], true );
3091 }
3092 },
3093
3094 // Events that are safe to short-circuit if no handlers are attached.
3095 // Native DOM events should not be added, they may have inline handlers.
3096 customEvent: {
3097 "getData": true,
3098 "setData": true,
3099 "changeData": true
3100 },
3101
3102 trigger: function( event, data, elem, onlyHandlers ) {
3103 // Don't do events on text and comment nodes
3104 if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) {
3105 return;
3106 }
3107
3108 // Event object or event type
3109 var type = event.type || event,
3110 namespaces = [],
3111 cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType;
3112
3113 if ( type.indexOf( "!" ) >= 0 ) {
3114 // Exclusive events trigger only for the exact event (no namespaces)
3115 type = type.slice(0, -1);
3116 exclusive = true;
3117 }
3118
3119 if ( type.indexOf( "." ) >= 0 ) {
3120 // Namespaced trigger; create a regexp to match event type in handle()
3121 namespaces = type.split(".");
3122 type = namespaces.shift();
3123 namespaces.sort();
3124 }
3125
3126 if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
3127 // No jQuery handlers for this event type, and it can't have inline handlers
3128 return;
3129 }
3130
3131 // Caller can pass in an Event, Object, or just an event type string
3132 event = typeof event === "object" ?
3133 // jQuery.Event object
3134 event[ jQuery.expando ] ? event :
3135 // Object literal
3136 new jQuery.Event( type, event ) :
3137 // Just the event type (string)
3138 new jQuery.Event( type );
3139
3140 event.type = type;
3141 event.isTrigger = true;
3142 event.exclusive = exclusive;
3143 event.namespace = namespaces.join( "." );
3144 event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null;
3145 ontype = type.indexOf( ":" ) < 0 ? "on" + type : "";
3146
3147 // triggerHandler() and global events don't bubble or run the default action
3148 if ( onlyHandlers || !elem ) {
3149 event.preventDefault();
3150 }
3151
3152 // Handle a global trigger
3153 if ( !elem ) {
3154
3155 // TODO: Stop taunting the data cache; remove global events and always attach to document
3156 cache = jQuery.cache;
3157 for ( i in cache ) {
3158 if ( cache[ i ].events && cache[ i ].events[ type ] ) {
3159 jQuery.event.trigger( event, data, cache[ i ].handle.elem, true );
3160 }
3161 }
3162 return;
3163 }
3164
3165 // Clean up the event in case it is being reused
3166 event.result = undefined;
3167 if ( !event.target ) {
3168 event.target = elem;
3169 }
3170
3171 // Clone any incoming data and prepend the event, creating the handler arg list
3172 data = data != null ? jQuery.makeArray( data ) : [];
3173 data.unshift( event );
3174
3175 // Allow special events to draw outside the lines
3176 special = jQuery.event.special[ type ] || {};
3177 if ( special.trigger && special.trigger.apply( elem, data ) === false ) {
3178 return;
3179 }
3180
3181 // Determine event propagation path in advance, per W3C events spec (#9951)
3182 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
3183 eventPath = [[ elem, special.bindType || type ]];
3184 if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
3185
3186 bubbleType = special.delegateType || type;
3187 old = null;
3188 for ( cur = elem.parentNode; cur; cur = cur.parentNode ) {
3189 eventPath.push([ cur, bubbleType ]);
3190 old = cur;
3191 }
3192
3193 // Only add window if we got to document (e.g., not plain obj or detached DOM)
3194 if ( old && old === elem.ownerDocument ) {
3195 eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]);
3196 }
3197 }
3198
3199 // Fire handlers on the event path
3200 for ( i = 0; i < eventPath.length; i++ ) {
3201
3202 cur = eventPath[i][0];
3203 event.type = eventPath[i][1];
3204
3205 handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
3206 if ( handle ) {
3207 handle.apply( cur, data );
3208 }
3209 handle = ontype && cur[ ontype ];
3210 if ( handle && jQuery.acceptData( cur ) ) {
3211 handle.apply( cur, data );
3212 }
3213
3214 if ( event.isPropagationStopped() ) {
3215 break;
3216 }
3217 }
3218 event.type = type;
3219
3220 // If nobody prevented the default action, do it now
3221 if ( !event.isDefaultPrevented() ) {
3222
3223 if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) &&
3224 !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
3225
3226 // Call a native DOM method on the target with the same name name as the event.
3227 // Can't use an .isFunction() check here because IE6/7 fails that test.
3228 // Don't do default actions on window, that's where global variables be (#6170)
3229 // IE<9 dies on focus/blur to hidden element (#1486)
3230 if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) {
3231
3232 // Don't re-trigger an onFOO event when we call its FOO() method
3233 old = elem[ ontype ];
3234
3235 if ( old ) {
3236 elem[ ontype ] = null;
3237 }
3238
3239 // Prevent re-triggering of the same event, since we already bubbled it above
3240 jQuery.event.triggered = type;
3241 elem[ type ]();
3242 jQuery.event.triggered = undefined;
3243
3244 if ( old ) {
3245 elem[ ontype ] = old;
3246 }
3247 }
3248 }
3249 }
3250
3251 return event.result;
3252 },
3253
3254 dispatch: function( event ) {
3255
3256 // Make a writable jQuery.Event from the native event object
3257 event = jQuery.event.fix( event || window.event );
3258
3259 var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []),
3260 delegateCount = handlers.delegateCount,
3261 args = [].slice.call( arguments, 0 ),
3262 run_all = !event.exclusive && !event.namespace,
3263 specialHandle = ( jQuery.event.special[ event.type ] || {} ).handle,
3264 handlerQueue = [],
3265 i, j, cur, ret, selMatch, matched, matches, handleObj, sel, hit, related;
3266
3267 // Use the fix-ed jQuery.Event rather than the (read-only) native event
3268 args[0] = event;
3269 event.delegateTarget = this;
3270
3271 // Determine handlers that should run if there are delegated events
3272 // Avoid disabled elements in IE (#6911) and non-left-click bubbling in Firefox (#3861)
3273 if ( delegateCount && !event.target.disabled && !(event.button && event.type === "click") ) {
3274
3275 for ( cur = event.target; cur != this; cur = cur.parentNode || this ) {
3276 selMatch = {};
3277 matches = [];
3278 for ( i = 0; i < delegateCount; i++ ) {
3279 handleObj = handlers[ i ];
3280 sel = handleObj.selector;
3281 hit = selMatch[ sel ];
3282
3283 if ( handleObj.isPositional ) {
3284 // Since .is() does not work for positionals; see http://jsfiddle.net/eJ4yd/3/
3285 hit = ( hit || (selMatch[ sel ] = jQuery( sel )) ).index( cur ) >= 0;
3286 } else if ( hit === undefined ) {
3287 hit = selMatch[ sel ] = ( handleObj.quick ? quickIs( cur, handleObj.quick ) : jQuery( cur ).is( sel ) );
3288 }
3289 if ( hit ) {
3290 matches.push( handleObj );
3291 }
3292 }
3293 if ( matches.length ) {
3294 handlerQueue.push({ elem: cur, matches: matches });
3295 }
3296 }
3297 }
3298
3299 // Add the remaining (directly-bound) handlers
3300 if ( handlers.length > delegateCount ) {
3301 handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) });
3302 }
3303
3304 // Run delegates first; they may want to stop propagation beneath us
3305 for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) {
3306 matched = handlerQueue[ i ];
3307 event.currentTarget = matched.elem;
3308
3309 for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) {
3310 handleObj = matched.matches[ j ];
3311
3312 // Triggered event must either 1) be non-exclusive and have no namespace, or
3313 // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
3314 if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) {
3315
3316 event.data = handleObj.data;
3317 event.handleObj = handleObj;
3318
3319 ret = ( specialHandle || handleObj.handler ).apply( matched.elem, args );
3320
3321 if ( ret !== undefined ) {
3322 event.result = ret;
3323 if ( ret === false ) {
3324 event.preventDefault();
3325 event.stopPropagation();
3326 }
3327 }
3328 }
3329 }
3330 }
3331
3332 return event.result;
3333 },
3334
3335 // Includes some event props shared by KeyEvent and MouseEvent
3336 // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 ***
3337 props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
3338
3339 fixHooks: {},
3340
3341 keyHooks: {
3342 props: "char charCode key keyCode".split(" "),
3343 filter: function( event, original ) {
3344
3345 // Add which for key events
3346 if ( event.which == null ) {
3347 event.which = original.charCode != null ? original.charCode : original.keyCode;
3348 }
3349
3350 return event;
3351 }
3352 },
3353
3354 mouseHooks: {
3355 props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement wheelDelta".split(" "),
3356 filter: function( event, original ) {
3357 var eventDoc, doc, body,
3358 button = original.button,
3359 fromElement = original.fromElement;
3360
3361 // Calculate pageX/Y if missing and clientX/Y available
3362 if ( event.pageX == null && original.clientX != null ) {
3363 eventDoc = event.target.ownerDocument || document;
3364 doc = eventDoc.documentElement;
3365 body = eventDoc.body;
3366
3367 event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
3368 event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );
3369 }
3370
3371 // Add relatedTarget, if necessary
3372 if ( !event.relatedTarget && fromElement ) {
3373 event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
3374 }
3375
3376 // Add which for click: 1 === left; 2 === middle; 3 === right
3377 // Note: button is not normalized, so don't use it
3378 if ( !event.which && button !== undefined ) {
3379 event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
3380 }
3381
3382 return event;
3383 }
3384 },
3385
3386 fix: function( event ) {
3387 if ( event[ jQuery.expando ] ) {
3388 return event;
3389 }
3390
3391 // Create a writable copy of the event object and normalize some properties
3392 var i, prop,
3393 originalEvent = event,
3394 fixHook = jQuery.event.fixHooks[ event.type ] || {},
3395 copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
3396
3397 event = jQuery.Event( originalEvent );
3398
3399 for ( i = copy.length; i; ) {
3400 prop = copy[ --i ];
3401 event[ prop ] = originalEvent[ prop ];
3402 }
3403
3404 // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2)
3405 if ( !event.target ) {
3406 event.target = originalEvent.srcElement || document;
3407 }
3408
3409 // Target should not be a text node (#504, Safari)
3410 if ( event.target.nodeType === 3 ) {
3411 event.target = event.target.parentNode;
3412 }
3413
3414 // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8)
3415 if ( event.metaKey === undefined ) {
3416 event.metaKey = event.ctrlKey;
3417 }
3418
3419 return fixHook.filter? fixHook.filter( event, originalEvent ) : event;
3420 },
3421
3422 special: {
3423 ready: {
3424 // Make sure the ready event is setup
3425 setup: jQuery.bindReady
3426 },
3427
3428 focus: {
3429 delegateType: "focusin",
3430 noBubble: true
3431 },
3432 blur: {
3433 delegateType: "focusout",
3434 noBubble: true
3435 },
3436
3437 beforeunload: {
3438 setup: function( data, namespaces, eventHandle ) {
3439 // We only want to do this special case on windows
3440 if ( jQuery.isWindow( this ) ) {
3441 this.onbeforeunload = eventHandle;
3442 }
3443 },
3444
3445 teardown: function( namespaces, eventHandle ) {
3446 if ( this.onbeforeunload === eventHandle ) {
3447 this.onbeforeunload = null;
3448 }
3449 }
3450 }
3451 },
3452
3453 simulate: function( type, elem, event, bubble ) {
3454 // Piggyback on a donor event to simulate a different one.
3455 // Fake originalEvent to avoid donor's stopPropagation, but if the
3456 // simulated event prevents default then we do the same on the donor.
3457 var e = jQuery.extend(
3458 new jQuery.Event(),
3459 event,
3460 { type: type,
3461 isSimulated: true,
3462 originalEvent: {}
3463 }
3464 );
3465 if ( bubble ) {
3466 jQuery.event.trigger( e, null, elem );
3467 } else {
3468 jQuery.event.dispatch.call( elem, e );
3469 }
3470 if ( e.isDefaultPrevented() ) {
3471 event.preventDefault();
3472 }
3473 }
3474};
3475
3476// Some plugins are using, but it's undocumented/deprecated and will be removed.
3477// The 1.7 special event interface should provide all the hooks needed now.
3478jQuery.event.handle = jQuery.event.dispatch;
3479
3480jQuery.removeEvent = document.removeEventListener ?
3481 function( elem, type, handle ) {
3482 if ( elem.removeEventListener ) {
3483 elem.removeEventListener( type, handle, false );
3484 }
3485 } :
3486 function( elem, type, handle ) {
3487 if ( elem.detachEvent ) {
3488 elem.detachEvent( "on" + type, handle );
3489 }
3490 };
3491
3492jQuery.Event = function( src, props ) {
3493 // Allow instantiation without the 'new' keyword
3494 if ( !(this instanceof jQuery.Event) ) {
3495 return new jQuery.Event( src, props );
3496 }
3497
3498 // Event object
3499 if ( src && src.type ) {
3500 this.originalEvent = src;
3501 this.type = src.type;
3502
3503 // Events bubbling up the document may have been marked as prevented
3504 // by a handler lower down the tree; reflect the correct value.
3505 this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||
3506 src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;
3507
3508 // Event type
3509 } else {
3510 this.type = src;
3511 }
3512
3513 // Put explicitly provided properties onto the event object
3514 if ( props ) {
3515 jQuery.extend( this, props );
3516 }
3517
3518 // Create a timestamp if incoming event doesn't have one
3519 this.timeStamp = src && src.timeStamp || jQuery.now();
3520
3521 // Mark it as fixed
3522 this[ jQuery.expando ] = true;
3523};
3524
3525function returnFalse() {
3526 return false;
3527}
3528function returnTrue() {
3529 return true;
3530}
3531
3532// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
3533// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
3534jQuery.Event.prototype = {
3535 preventDefault: function() {
3536 this.isDefaultPrevented = returnTrue;
3537
3538 var e = this.originalEvent;
3539 if ( !e ) {
3540 return;
3541 }
3542
3543 // if preventDefault exists run it on the original event
3544 if ( e.preventDefault ) {
3545 e.preventDefault();
3546
3547 // otherwise set the returnValue property of the original event to false (IE)
3548 } else {
3549 e.returnValue = false;
3550 }
3551 },
3552 stopPropagation: function() {
3553 this.isPropagationStopped = returnTrue;
3554
3555 var e = this.originalEvent;
3556 if ( !e ) {
3557 return;
3558 }
3559 // if stopPropagation exists run it on the original event
3560 if ( e.stopPropagation ) {
3561 e.stopPropagation();
3562 }
3563 // otherwise set the cancelBubble property of the original event to true (IE)
3564 e.cancelBubble = true;
3565 },
3566 stopImmediatePropagation: function() {
3567 this.isImmediatePropagationStopped = returnTrue;
3568 this.stopPropagation();
3569 },
3570 isDefaultPrevented: returnFalse,
3571 isPropagationStopped: returnFalse,
3572 isImmediatePropagationStopped: returnFalse
3573};
3574
3575// Create mouseenter/leave events using mouseover/out and event-time checks
3576jQuery.each({
3577 mouseenter: "mouseover",
3578 mouseleave: "mouseout"
3579}, function( orig, fix ) {
3580 jQuery.event.special[ orig ] = jQuery.event.special[ fix ] = {
3581 delegateType: fix,
3582 bindType: fix,
3583
3584 handle: function( event ) {
3585 var target = this,
3586 related = event.relatedTarget,
3587 handleObj = event.handleObj,
3588 selector = handleObj.selector,
3589 oldType, ret;
3590
3591 // For a real mouseover/out, always call the handler; for
3592 // mousenter/leave call the handler if related is outside the target.
3593 // NB: No relatedTarget if the mouse left/entered the browser window
3594 if ( !related || handleObj.origType === event.type || (related !== target && !jQuery.contains( target, related )) ) {
3595 oldType = event.type;
3596 event.type = handleObj.origType;
3597 ret = handleObj.handler.apply( this, arguments );
3598 event.type = oldType;
3599 }
3600 return ret;
3601 }
3602 };
3603});
3604
3605// IE submit delegation
3606if ( !jQuery.support.submitBubbles ) {
3607
3608 jQuery.event.special.submit = {
3609 setup: function() {
3610 // Only need this for delegated form submit events
3611 if ( jQuery.nodeName( this, "form" ) ) {
3612 return false;
3613 }
3614
3615 // Lazy-add a submit handler when a descendant form may potentially be submitted
3616 jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
3617 // Node name check avoids a VML-related crash in IE (#9807)
3618 var elem = e.target,
3619 form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
3620 if ( form && !form._submit_attached ) {
3621 jQuery.event.add( form, "submit._submit", function( event ) {
3622 // Form was submitted, bubble the event up the tree
3623 if ( this.parentNode ) {
3624 jQuery.event.simulate( "submit", this.parentNode, event, true );
3625 }
3626 });
3627 form._submit_attached = true;
3628 }
3629 });
3630 // return undefined since we don't need an event listener
3631 },
3632
3633 teardown: function() {
3634 // Only need this for delegated form submit events
3635 if ( jQuery.nodeName( this, "form" ) ) {
3636 return false;
3637 }
3638
3639 // Remove delegated handlers; cleanData eventually reaps submit handlers attached above
3640 jQuery.event.remove( this, "._submit" );
3641 }
3642 };
3643}
3644
3645// IE change delegation and checkbox/radio fix
3646if ( !jQuery.support.changeBubbles ) {
3647
3648 jQuery.event.special.change = {
3649
3650 setup: function() {
3651
3652 if ( rformElems.test( this.nodeName ) ) {
3653 // IE doesn't fire change on a check/radio until blur; trigger it on click
3654 // after a propertychange. Eat the blur-change in special.change.handle.
3655 // This still fires onchange a second time for check/radio after blur.
3656 if ( this.type === "checkbox" || this.type === "radio" ) {
3657 jQuery.event.add( this, "propertychange._change", function( event ) {
3658 if ( event.originalEvent.propertyName === "checked" ) {
3659 this._just_changed = true;
3660 }
3661 });
3662 jQuery.event.add( this, "click._change", function( event ) {
3663 if ( this._just_changed ) {
3664 this._just_changed = false;
3665 jQuery.event.simulate( "change", this, event, true );
3666 }
3667 });
3668 }
3669 return false;
3670 }
3671 // Delegated event; lazy-add a change handler on descendant inputs
3672 jQuery.event.add( this, "beforeactivate._change", function( e ) {
3673 var elem = e.target;
3674
3675 if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) {
3676 jQuery.event.add( elem, "change._change", function( event ) {
3677 if ( this.parentNode && !event.isSimulated ) {
3678 jQuery.event.simulate( "change", this.parentNode, event, true );
3679 }
3680 });
3681 elem._change_attached = true;
3682 }
3683 });
3684 },
3685
3686 handle: function( event ) {
3687 var elem = event.target;
3688
3689 // Swallow native change events from checkbox/radio, we already triggered them above
3690 if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
3691 return event.handleObj.handler.apply( this, arguments );
3692 }
3693 },
3694
3695 teardown: function() {
3696 jQuery.event.remove( this, "._change" );
3697
3698 return rformElems.test( this.nodeName );
3699 }
3700 };
3701}
3702
3703// Create "bubbling" focus and blur events
3704if ( !jQuery.support.focusinBubbles ) {
3705 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
3706
3707 // Attach a single capturing handler while someone wants focusin/focusout
3708 var attaches = 0,
3709 handler = function( event ) {
3710 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
3711 };
3712
3713 jQuery.event.special[ fix ] = {
3714 setup: function() {
3715 if ( attaches++ === 0 ) {
3716 document.addEventListener( orig, handler, true );
3717 }
3718 },
3719 teardown: function() {
3720 if ( --attaches === 0 ) {
3721 document.removeEventListener( orig, handler, true );
3722 }
3723 }
3724 };
3725 });
3726}
3727
3728jQuery.fn.extend({
3729
3730 on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
3731 var origFn, type;
3732
3733 // Types can be a map of types/handlers
3734 if ( typeof types === "object" ) {
3735 // ( types-Object, selector, data )
3736 if ( typeof selector !== "string" ) {
3737 // ( types-Object, data )
3738 data = selector;
3739 selector = undefined;
3740 }
3741 for ( type in types ) {
3742 this.on( type, selector, data, types[ type ], one );
3743 }
3744 return this;
3745 }
3746
3747 if ( data == null && fn == null ) {
3748 // ( types, fn )
3749 fn = selector;
3750 data = selector = undefined;
3751 } else if ( fn == null ) {
3752 if ( typeof selector === "string" ) {
3753 // ( types, selector, fn )
3754 fn = data;
3755 data = undefined;
3756 } else {
3757 // ( types, data, fn )
3758 fn = data;
3759 data = selector;
3760 selector = undefined;
3761 }
3762 }
3763 if ( fn === false ) {
3764 fn = returnFalse;
3765 } else if ( !fn ) {
3766 return this;
3767 }
3768
3769 if ( one === 1 ) {
3770 origFn = fn;
3771 fn = function( event ) {
3772 // Can use an empty set, since event contains the info
3773 jQuery().off( event );
3774 return origFn.apply( this, arguments );
3775 };
3776 // Use same guid so caller can remove using origFn
3777 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
3778 }
3779 return this.each( function() {
3780 jQuery.event.add( this, types, fn, data, selector );
3781 });
3782 },
3783 one: function( types, selector, data, fn ) {
3784 return this.on.call( this, types, selector, data, fn, 1 );
3785 },
3786 off: function( types, selector, fn ) {
3787 if ( types && types.preventDefault && types.handleObj ) {
3788 // ( event ) dispatched jQuery.Event
3789 var handleObj = types.handleObj;
3790 jQuery( types.delegateTarget ).off(
3791 handleObj.namespace? handleObj.type + "." + handleObj.namespace : handleObj.type,
3792 handleObj.selector,
3793 handleObj.handler
3794 );
3795 return this;
3796 }
3797 if ( typeof types === "object" ) {
3798 // ( types-object [, selector] )
3799 for ( var type in types ) {
3800 this.off( type, selector, types[ type ] );
3801 }
3802 return this;
3803 }
3804 if ( selector === false || typeof selector === "function" ) {
3805 // ( types [, fn] )
3806 fn = selector;
3807 selector = undefined;
3808 }
3809 if ( fn === false ) {
3810 fn = returnFalse;
3811 }
3812 return this.each(function() {
3813 jQuery.event.remove( this, types, fn, selector );
3814 });
3815 },
3816
3817 bind: function( types, data, fn ) {
3818 return this.on( types, null, data, fn );
3819 },
3820 unbind: function( types, fn ) {
3821 return this.off( types, null, fn );
3822 },
3823
3824 live: function( types, data, fn ) {
3825 jQuery( this.context ).on( types, this.selector, data, fn );
3826 return this;
3827 },
3828 die: function( types, fn ) {
3829 jQuery( this.context ).off( types, this.selector || "**", fn );
3830 return this;
3831 },
3832
3833 delegate: function( selector, types, data, fn ) {
3834 return this.on( types, selector, data, fn );
3835 },
3836 undelegate: function( selector, types, fn ) {
3837 // ( namespace ) or ( selector, types [, fn] )
3838 return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn );
3839 },
3840
3841 trigger: function( type, data ) {
3842 return this.each(function() {
3843 jQuery.event.trigger( type, data, this );
3844 });
3845 },
3846 triggerHandler: function( type, data ) {
3847 if ( this[0] ) {
3848 return jQuery.event.trigger( type, data, this[0], true );
3849 }
3850 },
3851
3852 toggle: function( fn ) {
3853 // Save reference to arguments for access in closure
3854 var args = arguments,
3855 guid = fn.guid || jQuery.guid++,
3856 i = 0,
3857 toggler = function( event ) {
3858 // Figure out which function to execute
3859 var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
3860 jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
3861
3862 // Make sure that clicks stop
3863 event.preventDefault();
3864
3865 // and execute the function
3866 return args[ lastToggle ].apply( this, arguments ) || false;
3867 };
3868
3869 // link all the functions, so any of them can unbind this click handler
3870 toggler.guid = guid;
3871 while ( i < args.length ) {
3872 args[ i++ ].guid = guid;
3873 }
3874
3875 return this.click( toggler );
3876 },
3877
3878 hover: function( fnOver, fnOut ) {
3879 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
3880 }
3881});
3882
3883jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
3884 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
3885 "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
3886
3887 // Handle event binding
3888 jQuery.fn[ name ] = function( data, fn ) {
3889 if ( fn == null ) {
3890 fn = data;
3891 data = null;
3892 }
3893
3894 return arguments.length > 0 ?
3895 this.bind( name, data, fn ) :
3896 this.trigger( name );
3897 };
3898
3899 if ( jQuery.attrFn ) {
3900 jQuery.attrFn[ name ] = true;
3901 }
3902
3903 if ( rkeyEvent.test( name ) ) {
3904 jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks;
3905 }
3906
3907 if ( rmouseEvent.test( name ) ) {
3908 jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks;
3909 }
3910});
3911
3912
3913
3914/*!
3915 * Sizzle CSS Selector Engine
3916 * Copyright 2011, The Dojo Foundation
3917 * Released under the MIT, BSD, and GPL Licenses.
3918 * More information: http://sizzlejs.com/
3919 */
3920(function(){
3921
3922var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
3923 expando = "sizcache" + (Math.random() + '').replace('.', ''),
3924 done = 0,
3925 toString = Object.prototype.toString,
3926 hasDuplicate = false,
3927 baseHasDuplicate = true,
3928 rBackslash = /\\/g,
3929 rReturn = /\r\n/g,
3930 rNonWord = /\W/;
3931
3932// Here we check if the JavaScript engine is using some sort of
3933// optimization where it does not always call our comparision
3934// function. If that is the case, discard the hasDuplicate value.
3935// Thus far that includes Google Chrome.
3936[0, 0].sort(function() {
3937 baseHasDuplicate = false;
3938 return 0;
3939});
3940
3941var Sizzle = function( selector, context, results, seed ) {
3942 results = results || [];
3943 context = context || document;
3944
3945 var origContext = context;
3946
3947 if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
3948 return [];
3949 }
3950
3951 if ( !selector || typeof selector !== "string" ) {
3952 return results;
3953 }
3954
3955 var m, set, checkSet, extra, ret, cur, pop, i,
3956 prune = true,
3957 contextXML = Sizzle.isXML( context ),
3958 parts = [],
3959 soFar = selector;
3960
3961 // Reset the position of the chunker regexp (start from head)
3962 do {
3963 chunker.exec( "" );
3964 m = chunker.exec( soFar );
3965
3966 if ( m ) {
3967 soFar = m[3];
3968
3969 parts.push( m[1] );
3970
3971 if ( m[2] ) {
3972 extra = m[3];
3973 break;
3974 }
3975 }
3976 } while ( m );
3977
3978 if ( parts.length > 1 && origPOS.exec( selector ) ) {
3979
3980 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
3981 set = posProcess( parts[0] + parts[1], context, seed );
3982
3983 } else {
3984 set = Expr.relative[ parts[0] ] ?
3985 [ context ] :
3986 Sizzle( parts.shift(), context );
3987
3988 while ( parts.length ) {
3989 selector = parts.shift();
3990
3991 if ( Expr.relative[ selector ] ) {
3992 selector += parts.shift();
3993 }
3994
3995 set = posProcess( selector, set, seed );
3996 }
3997 }
3998
3999 } else {
4000 // Take a shortcut and set the context if the root selector is an ID
4001 // (but not if it'll be faster if the inner selector is an ID)
4002 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
4003 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
4004
4005 ret = Sizzle.find( parts.shift(), context, contextXML );
4006 context = ret.expr ?
4007 Sizzle.filter( ret.expr, ret.set )[0] :
4008 ret.set[0];
4009 }
4010
4011 if ( context ) {
4012 ret = seed ?
4013 { expr: parts.pop(), set: makeArray(seed) } :
4014 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
4015
4016 set = ret.expr ?
4017 Sizzle.filter( ret.expr, ret.set ) :
4018 ret.set;
4019
4020 if ( parts.length > 0 ) {
4021 checkSet = makeArray( set );
4022
4023 } else {
4024 prune = false;
4025 }
4026
4027 while ( parts.length ) {
4028 cur = parts.pop();
4029 pop = cur;
4030
4031 if ( !Expr.relative[ cur ] ) {
4032 cur = "";
4033 } else {
4034 pop = parts.pop();
4035 }
4036
4037 if ( pop == null ) {
4038 pop = context;
4039 }
4040
4041 Expr.relative[ cur ]( checkSet, pop, contextXML );
4042 }
4043
4044 } else {
4045 checkSet = parts = [];
4046 }
4047 }
4048
4049 if ( !checkSet ) {
4050 checkSet = set;
4051 }
4052
4053 if ( !checkSet ) {
4054 Sizzle.error( cur || selector );
4055 }
4056
4057 if ( toString.call(checkSet) === "[object Array]" ) {
4058 if ( !prune ) {
4059 results.push.apply( results, checkSet );
4060
4061 } else if ( context && context.nodeType === 1 ) {
4062 for ( i = 0; checkSet[i] != null; i++ ) {
4063 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
4064 results.push( set[i] );
4065 }
4066 }
4067
4068 } else {
4069 for ( i = 0; checkSet[i] != null; i++ ) {
4070 if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
4071 results.push( set[i] );
4072 }
4073 }
4074 }
4075
4076 } else {
4077 makeArray( checkSet, results );
4078 }
4079
4080 if ( extra ) {
4081 Sizzle( extra, origContext, results, seed );
4082 Sizzle.uniqueSort( results );
4083 }
4084
4085 return results;
4086};
4087
4088Sizzle.uniqueSort = function( results ) {
4089 if ( sortOrder ) {
4090 hasDuplicate = baseHasDuplicate;
4091 results.sort( sortOrder );
4092
4093 if ( hasDuplicate ) {
4094 for ( var i = 1; i < results.length; i++ ) {
4095 if ( results[i] === results[ i - 1 ] ) {
4096 results.splice( i--, 1 );
4097 }
4098 }
4099 }
4100 }
4101
4102 return results;
4103};
4104
4105Sizzle.matches = function( expr, set ) {
4106 return Sizzle( expr, null, null, set );
4107};
4108
4109Sizzle.matchesSelector = function( node, expr ) {
4110 return Sizzle( expr, null, null, [node] ).length > 0;
4111};
4112
4113Sizzle.find = function( expr, context, isXML ) {
4114 var set, i, len, match, type, left;
4115
4116 if ( !expr ) {
4117 return [];
4118 }
4119
4120 for ( i = 0, len = Expr.order.length; i < len; i++ ) {
4121 type = Expr.order[i];
4122
4123 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
4124 left = match[1];
4125 match.splice( 1, 1 );
4126
4127 if ( left.substr( left.length - 1 ) !== "\\" ) {
4128 match[1] = (match[1] || "").replace( rBackslash, "" );
4129 set = Expr.find[ type ]( match, context, isXML );
4130
4131 if ( set != null ) {
4132 expr = expr.replace( Expr.match[ type ], "" );
4133 break;
4134 }
4135 }
4136 }
4137 }
4138
4139 if ( !set ) {
4140 set = typeof context.getElementsByTagName !== "undefined" ?
4141 context.getElementsByTagName( "*" ) :
4142 [];
4143 }
4144
4145 return { set: set, expr: expr };
4146};
4147
4148Sizzle.filter = function( expr, set, inplace, not ) {
4149 var match, anyFound,
4150 type, found, item, filter, left,
4151 i, pass,
4152 old = expr,
4153 result = [],
4154 curLoop = set,
4155 isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
4156
4157 while ( expr && set.length ) {
4158 for ( type in Expr.filter ) {
4159 if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
4160 filter = Expr.filter[ type ];
4161 left = match[1];
4162
4163 anyFound = false;
4164
4165 match.splice(1,1);
4166
4167 if ( left.substr( left.length - 1 ) === "\\" ) {
4168 continue;
4169 }
4170
4171 if ( curLoop === result ) {
4172 result = [];
4173 }
4174
4175 if ( Expr.preFilter[ type ] ) {
4176 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
4177
4178 if ( !match ) {
4179 anyFound = found = true;
4180
4181 } else if ( match === true ) {
4182 continue;
4183 }
4184 }
4185
4186 if ( match ) {
4187 for ( i = 0; (item = curLoop[i]) != null; i++ ) {
4188 if ( item ) {
4189 found = filter( item, match, i, curLoop );
4190 pass = not ^ found;
4191
4192 if ( inplace && found != null ) {
4193 if ( pass ) {
4194 anyFound = true;
4195
4196 } else {
4197 curLoop[i] = false;
4198 }
4199
4200 } else if ( pass ) {
4201 result.push( item );
4202 anyFound = true;
4203 }
4204 }
4205 }
4206 }
4207
4208 if ( found !== undefined ) {
4209 if ( !inplace ) {
4210 curLoop = result;
4211 }
4212
4213 expr = expr.replace( Expr.match[ type ], "" );
4214
4215 if ( !anyFound ) {
4216 return [];
4217 }
4218
4219 break;
4220 }
4221 }
4222 }
4223
4224 // Improper expression
4225 if ( expr === old ) {
4226 if ( anyFound == null ) {
4227 Sizzle.error( expr );
4228
4229 } else {
4230 break;
4231 }
4232 }
4233
4234 old = expr;
4235 }
4236
4237 return curLoop;
4238};
4239
4240Sizzle.error = function( msg ) {
4241 throw "Syntax error, unrecognized expression: " + msg;
4242};
4243
4244/**
4245 * Utility function for retreiving the text value of an array of DOM nodes
4246 * @param {Array|Element} elem
4247 */
4248var getText = Sizzle.getText = function( elem ) {
4249 var i, node,
4250 nodeType = elem.nodeType,
4251 ret = "";
4252
4253 if ( nodeType ) {
4254 if ( nodeType === 1 ) {
4255 // Use textContent || innerText for elements
4256 if ( typeof elem.textContent === 'string' ) {
4257 return elem.textContent;
4258 } else if ( typeof elem.innerText === 'string' ) {
4259 // Replace IE's carriage returns
4260 return elem.innerText.replace( rReturn, '' );
4261 } else {
4262 // Traverse it's children
4263 for ( elem = elem.firstChild; elem; elem = elem.nextSibling) {
4264 ret += getText( elem );
4265 }
4266 }
4267 } else if ( nodeType === 3 || nodeType === 4 ) {
4268 return elem.nodeValue;
4269 }
4270 } else {
4271
4272 // If no nodeType, this is expected to be an array
4273 for ( i = 0; (node = elem[i]); i++ ) {
4274 // Do not traverse comment nodes
4275 if ( node.nodeType !== 8 ) {
4276 ret += getText( node );
4277 }
4278 }
4279 }
4280 return ret;
4281};
4282
4283var Expr = Sizzle.selectors = {
4284 order: [ "ID", "NAME", "TAG" ],
4285
4286 match: {
4287 ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4288 CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4289 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
4290 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
4291 TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
4292 CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
4293 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
4294 PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
4295 },
4296
4297 leftMatch: {},
4298
4299 attrMap: {
4300 "class": "className",
4301 "for": "htmlFor"
4302 },
4303
4304 attrHandle: {
4305 href: function( elem ) {
4306 return elem.getAttribute( "href" );
4307 },
4308 type: function( elem ) {
4309 return elem.getAttribute( "type" );
4310 }
4311 },
4312
4313 relative: {
4314 "+": function(checkSet, part){
4315 var isPartStr = typeof part === "string",
4316 isTag = isPartStr && !rNonWord.test( part ),
4317 isPartStrNotTag = isPartStr && !isTag;
4318
4319 if ( isTag ) {
4320 part = part.toLowerCase();
4321 }
4322
4323 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
4324 if ( (elem = checkSet[i]) ) {
4325 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
4326
4327 checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
4328 elem || false :
4329 elem === part;
4330 }
4331 }
4332
4333 if ( isPartStrNotTag ) {
4334 Sizzle.filter( part, checkSet, true );
4335 }
4336 },
4337
4338 ">": function( checkSet, part ) {
4339 var elem,
4340 isPartStr = typeof part === "string",
4341 i = 0,
4342 l = checkSet.length;
4343
4344 if ( isPartStr && !rNonWord.test( part ) ) {
4345 part = part.toLowerCase();
4346
4347 for ( ; i < l; i++ ) {
4348 elem = checkSet[i];
4349
4350 if ( elem ) {
4351 var parent = elem.parentNode;
4352 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
4353 }
4354 }
4355
4356 } else {
4357 for ( ; i < l; i++ ) {
4358 elem = checkSet[i];
4359
4360 if ( elem ) {
4361 checkSet[i] = isPartStr ?
4362 elem.parentNode :
4363 elem.parentNode === part;
4364 }
4365 }
4366
4367 if ( isPartStr ) {
4368 Sizzle.filter( part, checkSet, true );
4369 }
4370 }
4371 },
4372
4373 "": function(checkSet, part, isXML){
4374 var nodeCheck,
4375 doneName = done++,
4376 checkFn = dirCheck;
4377
4378 if ( typeof part === "string" && !rNonWord.test( part ) ) {
4379 part = part.toLowerCase();
4380 nodeCheck = part;
4381 checkFn = dirNodeCheck;
4382 }
4383
4384 checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
4385 },
4386
4387 "~": function( checkSet, part, isXML ) {
4388 var nodeCheck,
4389 doneName = done++,
4390 checkFn = dirCheck;
4391
4392 if ( typeof part === "string" && !rNonWord.test( part ) ) {
4393 part = part.toLowerCase();
4394 nodeCheck = part;
4395 checkFn = dirNodeCheck;
4396 }
4397
4398 checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
4399 }
4400 },
4401
4402 find: {
4403 ID: function( match, context, isXML ) {
4404 if ( typeof context.getElementById !== "undefined" && !isXML ) {
4405 var m = context.getElementById(match[1]);
4406 // Check parentNode to catch when Blackberry 4.6 returns
4407 // nodes that are no longer in the document #6963
4408 return m && m.parentNode ? [m] : [];
4409 }
4410 },
4411
4412 NAME: function( match, context ) {
4413 if ( typeof context.getElementsByName !== "undefined" ) {
4414 var ret = [],
4415 results = context.getElementsByName( match[1] );
4416
4417 for ( var i = 0, l = results.length; i < l; i++ ) {
4418 if ( results[i].getAttribute("name") === match[1] ) {
4419 ret.push( results[i] );
4420 }
4421 }
4422
4423 return ret.length === 0 ? null : ret;
4424 }
4425 },
4426
4427 TAG: function( match, context ) {
4428 if ( typeof context.getElementsByTagName !== "undefined" ) {
4429 return context.getElementsByTagName( match[1] );
4430 }
4431 }
4432 },
4433 preFilter: {
4434 CLASS: function( match, curLoop, inplace, result, not, isXML ) {
4435 match = " " + match[1].replace( rBackslash, "" ) + " ";
4436
4437 if ( isXML ) {
4438 return match;
4439 }
4440
4441 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
4442 if ( elem ) {
4443 if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
4444 if ( !inplace ) {
4445 result.push( elem );
4446 }
4447
4448 } else if ( inplace ) {
4449 curLoop[i] = false;
4450 }
4451 }
4452 }
4453
4454 return false;
4455 },
4456
4457 ID: function( match ) {
4458 return match[1].replace( rBackslash, "" );
4459 },
4460
4461 TAG: function( match, curLoop ) {
4462 return match[1].replace( rBackslash, "" ).toLowerCase();
4463 },
4464
4465 CHILD: function( match ) {
4466 if ( match[1] === "nth" ) {
4467 if ( !match[2] ) {
4468 Sizzle.error( match[0] );
4469 }
4470
4471 match[2] = match[2].replace(/^\+|\s*/g, '');
4472
4473 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
4474 var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
4475 match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
4476 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
4477
4478 // calculate the numbers (first)n+(last) including if they are negative
4479 match[2] = (test[1] + (test[2] || 1)) - 0;
4480 match[3] = test[3] - 0;
4481 }
4482 else if ( match[2] ) {
4483 Sizzle.error( match[0] );
4484 }
4485
4486 // TODO: Move to normal caching system
4487 match[0] = done++;
4488
4489 return match;
4490 },
4491
4492 ATTR: function( match, curLoop, inplace, result, not, isXML ) {
4493 var name = match[1] = match[1].replace( rBackslash, "" );
4494
4495 if ( !isXML && Expr.attrMap[name] ) {
4496 match[1] = Expr.attrMap[name];
4497 }
4498
4499 // Handle if an un-quoted value was used
4500 match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
4501
4502 if ( match[2] === "~=" ) {
4503 match[4] = " " + match[4] + " ";
4504 }
4505
4506 return match;
4507 },
4508
4509 PSEUDO: function( match, curLoop, inplace, result, not ) {
4510 if ( match[1] === "not" ) {
4511 // If we're dealing with a complex expression, or a simple one
4512 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
4513 match[3] = Sizzle(match[3], null, null, curLoop);
4514
4515 } else {
4516 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
4517
4518 if ( !inplace ) {
4519 result.push.apply( result, ret );
4520 }
4521
4522 return false;
4523 }
4524
4525 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
4526 return true;
4527 }
4528
4529 return match;
4530 },
4531
4532 POS: function( match ) {
4533 match.unshift( true );
4534
4535 return match;
4536 }
4537 },
4538
4539 filters: {
4540 enabled: function( elem ) {
4541 return elem.disabled === false && elem.type !== "hidden";
4542 },
4543
4544 disabled: function( elem ) {
4545 return elem.disabled === true;
4546 },
4547
4548 checked: function( elem ) {
4549 return elem.checked === true;
4550 },
4551
4552 selected: function( elem ) {
4553 // Accessing this property makes selected-by-default
4554 // options in Safari work properly
4555 if ( elem.parentNode ) {
4556 elem.parentNode.selectedIndex;
4557 }
4558
4559 return elem.selected === true;
4560 },
4561
4562 parent: function( elem ) {
4563 return !!elem.firstChild;
4564 },
4565
4566 empty: function( elem ) {
4567 return !elem.firstChild;
4568 },
4569
4570 has: function( elem, i, match ) {
4571 return !!Sizzle( match[3], elem ).length;
4572 },
4573
4574 header: function( elem ) {
4575 return (/h\d/i).test( elem.nodeName );
4576 },
4577
4578 text: function( elem ) {
4579 var attr = elem.getAttribute( "type" ), type = elem.type;
4580 // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
4581 // use getAttribute instead to test this case
4582 return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
4583 },
4584
4585 radio: function( elem ) {
4586 return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
4587 },
4588
4589 checkbox: function( elem ) {
4590 return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
4591 },
4592
4593 file: function( elem ) {
4594 return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
4595 },
4596
4597 password: function( elem ) {
4598 return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
4599 },
4600
4601 submit: function( elem ) {
4602 var name = elem.nodeName.toLowerCase();
4603 return (name === "input" || name === "button") && "submit" === elem.type;
4604 },
4605
4606 image: function( elem ) {
4607 return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
4608 },
4609
4610 reset: function( elem ) {
4611 var name = elem.nodeName.toLowerCase();
4612 return (name === "input" || name === "button") && "reset" === elem.type;
4613 },
4614
4615 button: function( elem ) {
4616 var name = elem.nodeName.toLowerCase();
4617 return name === "input" && "button" === elem.type || name === "button";
4618 },
4619
4620 input: function( elem ) {
4621 return (/input|select|textarea|button/i).test( elem.nodeName );
4622 },
4623
4624 focus: function( elem ) {
4625 return elem === elem.ownerDocument.activeElement;
4626 }
4627 },
4628 setFilters: {
4629 first: function( elem, i ) {
4630 return i === 0;
4631 },
4632
4633 last: function( elem, i, match, array ) {
4634 return i === array.length - 1;
4635 },
4636
4637 even: function( elem, i ) {
4638 return i % 2 === 0;
4639 },
4640
4641 odd: function( elem, i ) {
4642 return i % 2 === 1;
4643 },
4644
4645 lt: function( elem, i, match ) {
4646 return i < match[3] - 0;
4647 },
4648
4649 gt: function( elem, i, match ) {
4650 return i > match[3] - 0;
4651 },
4652
4653 nth: function( elem, i, match ) {
4654 return match[3] - 0 === i;
4655 },
4656
4657 eq: function( elem, i, match ) {
4658 return match[3] - 0 === i;
4659 }
4660 },
4661 filter: {
4662 PSEUDO: function( elem, match, i, array ) {
4663 var name = match[1],
4664 filter = Expr.filters[ name ];
4665
4666 if ( filter ) {
4667 return filter( elem, i, match, array );
4668
4669 } else if ( name === "contains" ) {
4670 return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;
4671
4672 } else if ( name === "not" ) {
4673 var not = match[3];
4674
4675 for ( var j = 0, l = not.length; j < l; j++ ) {
4676 if ( not[j] === elem ) {
4677 return false;
4678 }
4679 }
4680
4681 return true;
4682
4683 } else {
4684 Sizzle.error( name );
4685 }
4686 },
4687
4688 CHILD: function( elem, match ) {
4689 var first, last,
4690 doneName, parent, cache,
4691 count, diff,
4692 type = match[1],
4693 node = elem;
4694
4695 switch ( type ) {
4696 case "only":
4697 case "first":
4698 while ( (node = node.previousSibling) ) {
4699 if ( node.nodeType === 1 ) {
4700 return false;
4701 }
4702 }
4703
4704 if ( type === "first" ) {
4705 return true;
4706 }
4707
4708 node = elem;
4709
4710 case "last":
4711 while ( (node = node.nextSibling) ) {
4712 if ( node.nodeType === 1 ) {
4713 return false;
4714 }
4715 }
4716
4717 return true;
4718
4719 case "nth":
4720 first = match[2];
4721 last = match[3];
4722
4723 if ( first === 1 && last === 0 ) {
4724 return true;
4725 }
4726
4727 doneName = match[0];
4728 parent = elem.parentNode;
4729
4730 if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) {
4731 count = 0;
4732
4733 for ( node = parent.firstChild; node; node = node.nextSibling ) {
4734 if ( node.nodeType === 1 ) {
4735 node.nodeIndex = ++count;
4736 }
4737 }
4738
4739 parent[ expando ] = doneName;
4740 }
4741
4742 diff = elem.nodeIndex - last;
4743
4744 if ( first === 0 ) {
4745 return diff === 0;
4746
4747 } else {
4748 return ( diff % first === 0 && diff / first >= 0 );
4749 }
4750 }
4751 },
4752
4753 ID: function( elem, match ) {
4754 return elem.nodeType === 1 && elem.getAttribute("id") === match;
4755 },
4756
4757 TAG: function( elem, match ) {
4758 return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match;
4759 },
4760
4761 CLASS: function( elem, match ) {
4762 return (" " + (elem.className || elem.getAttribute("class")) + " ")
4763 .indexOf( match ) > -1;
4764 },
4765
4766 ATTR: function( elem, match ) {
4767 var name = match[1],
4768 result = Sizzle.attr ?
4769 Sizzle.attr( elem, name ) :
4770 Expr.attrHandle[ name ] ?
4771 Expr.attrHandle[ name ]( elem ) :
4772 elem[ name ] != null ?
4773 elem[ name ] :
4774 elem.getAttribute( name ),
4775 value = result + "",
4776 type = match[2],
4777 check = match[4];
4778
4779 return result == null ?
4780 type === "!=" :
4781 !type && Sizzle.attr ?
4782 result != null :
4783 type === "=" ?
4784 value === check :
4785 type === "*=" ?
4786 value.indexOf(check) >= 0 :
4787 type === "~=" ?
4788 (" " + value + " ").indexOf(check) >= 0 :
4789 !check ?
4790 value && result !== false :
4791 type === "!=" ?
4792 value !== check :
4793 type === "^=" ?
4794 value.indexOf(check) === 0 :
4795 type === "$=" ?
4796 value.substr(value.length - check.length) === check :
4797 type === "|=" ?
4798 value === check || value.substr(0, check.length + 1) === check + "-" :
4799 false;
4800 },
4801
4802 POS: function( elem, match, i, array ) {
4803 var name = match[2],
4804 filter = Expr.setFilters[ name ];
4805
4806 if ( filter ) {
4807 return filter( elem, i, match, array );
4808 }
4809 }
4810 }
4811};
4812
4813var origPOS = Expr.match.POS,
4814 fescape = function(all, num){
4815 return "\\" + (num - 0 + 1);
4816 };
4817
4818for ( var type in Expr.match ) {
4819 Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
4820 Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
4821}
4822
4823var makeArray = function( array, results ) {
4824 array = Array.prototype.slice.call( array, 0 );
4825
4826 if ( results ) {
4827 results.push.apply( results, array );
4828 return results;
4829 }
4830
4831 return array;
4832};
4833
4834// Perform a simple check to determine if the browser is capable of
4835// converting a NodeList to an array using builtin methods.
4836// Also verifies that the returned array holds DOM nodes
4837// (which is not the case in the Blackberry browser)
4838try {
4839 Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
4840
4841// Provide a fallback method if it does not work
4842} catch( e ) {
4843 makeArray = function( array, results ) {
4844 var i = 0,
4845 ret = results || [];
4846
4847 if ( toString.call(array) === "[object Array]" ) {
4848 Array.prototype.push.apply( ret, array );
4849
4850 } else {
4851 if ( typeof array.length === "number" ) {
4852 for ( var l = array.length; i < l; i++ ) {
4853 ret.push( array[i] );
4854 }
4855
4856 } else {
4857 for ( ; array[i]; i++ ) {
4858 ret.push( array[i] );
4859 }
4860 }
4861 }
4862
4863 return ret;
4864 };
4865}
4866
4867var sortOrder, siblingCheck;
4868
4869if ( document.documentElement.compareDocumentPosition ) {
4870 sortOrder = function( a, b ) {
4871 if ( a === b ) {
4872 hasDuplicate = true;
4873 return 0;
4874 }
4875
4876 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
4877 return a.compareDocumentPosition ? -1 : 1;
4878 }
4879
4880 return a.compareDocumentPosition(b) & 4 ? -1 : 1;
4881 };
4882
4883} else {
4884 sortOrder = function( a, b ) {
4885 // The nodes are identical, we can exit early
4886 if ( a === b ) {
4887 hasDuplicate = true;
4888 return 0;
4889
4890 // Fallback to using sourceIndex (in IE) if it's available on both nodes
4891 } else if ( a.sourceIndex && b.sourceIndex ) {
4892 return a.sourceIndex - b.sourceIndex;
4893 }
4894
4895 var al, bl,
4896 ap = [],
4897 bp = [],
4898 aup = a.parentNode,
4899 bup = b.parentNode,
4900 cur = aup;
4901
4902 // If the nodes are siblings (or identical) we can do a quick check
4903 if ( aup === bup ) {
4904 return siblingCheck( a, b );
4905
4906 // If no parents were found then the nodes are disconnected
4907 } else if ( !aup ) {
4908 return -1;
4909
4910 } else if ( !bup ) {
4911 return 1;
4912 }
4913
4914 // Otherwise they're somewhere else in the tree so we need
4915 // to build up a full list of the parentNodes for comparison
4916 while ( cur ) {
4917 ap.unshift( cur );
4918 cur = cur.parentNode;
4919 }
4920
4921 cur = bup;
4922
4923 while ( cur ) {
4924 bp.unshift( cur );
4925 cur = cur.parentNode;
4926 }
4927
4928 al = ap.length;
4929 bl = bp.length;
4930
4931 // Start walking down the tree looking for a discrepancy
4932 for ( var i = 0; i < al && i < bl; i++ ) {
4933 if ( ap[i] !== bp[i] ) {
4934 return siblingCheck( ap[i], bp[i] );
4935 }
4936 }
4937
4938 // We ended someplace up the tree so do a sibling check
4939 return i === al ?
4940 siblingCheck( a, bp[i], -1 ) :
4941 siblingCheck( ap[i], b, 1 );
4942 };
4943
4944 siblingCheck = function( a, b, ret ) {
4945 if ( a === b ) {
4946 return ret;
4947 }
4948
4949 var cur = a.nextSibling;
4950
4951 while ( cur ) {
4952 if ( cur === b ) {
4953 return -1;
4954 }
4955
4956 cur = cur.nextSibling;
4957 }
4958
4959 return 1;
4960 };
4961}
4962
4963// Check to see if the browser returns elements by name when
4964// querying by getElementById (and provide a workaround)
4965(function(){
4966 // We're going to inject a fake input element with a specified name
4967 var form = document.createElement("div"),
4968 id = "script" + (new Date()).getTime(),
4969 root = document.documentElement;
4970
4971 form.innerHTML = "<a name='" + id + "'/>";
4972
4973 // Inject it into the root element, check its status, and remove it quickly
4974 root.insertBefore( form, root.firstChild );
4975
4976 // The workaround has to do additional checks after a getElementById
4977 // Which slows things down for other browsers (hence the branching)
4978 if ( document.getElementById( id ) ) {
4979 Expr.find.ID = function( match, context, isXML ) {
4980 if ( typeof context.getElementById !== "undefined" && !isXML ) {
4981 var m = context.getElementById(match[1]);
4982
4983 return m ?
4984 m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
4985 [m] :
4986 undefined :
4987 [];
4988 }
4989 };
4990
4991 Expr.filter.ID = function( elem, match ) {
4992 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
4993
4994 return elem.nodeType === 1 && node && node.nodeValue === match;
4995 };
4996 }
4997
4998 root.removeChild( form );
4999
5000 // release memory in IE
5001 root = form = null;
5002})();
5003
5004(function(){
5005 // Check to see if the browser returns only elements
5006 // when doing getElementsByTagName("*")
5007
5008 // Create a fake element
5009 var div = document.createElement("div");
5010 div.appendChild( document.createComment("") );
5011
5012 // Make sure no comments are found
5013 if ( div.getElementsByTagName("*").length > 0 ) {
5014 Expr.find.TAG = function( match, context ) {
5015 var results = context.getElementsByTagName( match[1] );
5016
5017 // Filter out possible comments
5018 if ( match[1] === "*" ) {
5019 var tmp = [];
5020
5021 for ( var i = 0; results[i]; i++ ) {
5022 if ( results[i].nodeType === 1 ) {
5023 tmp.push( results[i] );
5024 }
5025 }
5026
5027 results = tmp;
5028 }
5029
5030 return results;
5031 };
5032 }
5033
5034 // Check to see if an attribute returns normalized href attributes
5035 div.innerHTML = "<a href='#'></a>";
5036
5037 if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
5038 div.firstChild.getAttribute("href") !== "#" ) {
5039
5040 Expr.attrHandle.href = function( elem ) {
5041 return elem.getAttribute( "href", 2 );
5042 };
5043 }
5044
5045 // release memory in IE
5046 div = null;
5047})();
5048
5049if ( document.querySelectorAll ) {
5050 (function(){
5051 var oldSizzle = Sizzle,
5052 div = document.createElement("div"),
5053 id = "__sizzle__";
5054
5055 div.innerHTML = "<p class='TEST'></p>";
5056
5057 // Safari can't handle uppercase or unicode characters when
5058 // in quirks mode.
5059 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
5060 return;
5061 }
5062
5063 Sizzle = function( query, context, extra, seed ) {
5064 context = context || document;
5065
5066 // Only use querySelectorAll on non-XML documents
5067 // (ID selectors don't work in non-HTML documents)
5068 if ( !seed && !Sizzle.isXML(context) ) {
5069 // See if we find a selector to speed up
5070 var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
5071
5072 if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
5073 // Speed-up: Sizzle("TAG")
5074 if ( match[1] ) {
5075 return makeArray( context.getElementsByTagName( query ), extra );
5076
5077 // Speed-up: Sizzle(".CLASS")
5078 } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
5079 return makeArray( context.getElementsByClassName( match[2] ), extra );
5080 }
5081 }
5082
5083 if ( context.nodeType === 9 ) {
5084 // Speed-up: Sizzle("body")
5085 // The body element only exists once, optimize finding it
5086 if ( query === "body" && context.body ) {
5087 return makeArray( [ context.body ], extra );
5088
5089 // Speed-up: Sizzle("#ID")
5090 } else if ( match && match[3] ) {
5091 var elem = context.getElementById( match[3] );
5092
5093 // Check parentNode to catch when Blackberry 4.6 returns
5094 // nodes that are no longer in the document #6963
5095 if ( elem && elem.parentNode ) {
5096 // Handle the case where IE and Opera return items
5097 // by name instead of ID
5098 if ( elem.id === match[3] ) {
5099 return makeArray( [ elem ], extra );
5100 }
5101
5102 } else {
5103 return makeArray( [], extra );
5104 }
5105 }
5106
5107 try {
5108 return makeArray( context.querySelectorAll(query), extra );
5109 } catch(qsaError) {}
5110
5111 // qSA works strangely on Element-rooted queries
5112 // We can work around this by specifying an extra ID on the root
5113 // and working up from there (Thanks to Andrew Dupont for the technique)
5114 // IE 8 doesn't work on object elements
5115 } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
5116 var oldContext = context,
5117 old = context.getAttribute( "id" ),
5118 nid = old || id,
5119 hasParent = context.parentNode,
5120 relativeHierarchySelector = /^\s*[+~]/.test( query );
5121
5122 if ( !old ) {
5123 context.setAttribute( "id", nid );
5124 } else {
5125 nid = nid.replace( /'/g, "\\$&" );
5126 }
5127 if ( relativeHierarchySelector && hasParent ) {
5128 context = context.parentNode;
5129 }
5130
5131 try {
5132 if ( !relativeHierarchySelector || hasParent ) {
5133 return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
5134 }
5135
5136 } catch(pseudoError) {
5137 } finally {
5138 if ( !old ) {
5139 oldContext.removeAttribute( "id" );
5140 }
5141 }
5142 }
5143 }
5144
5145 return oldSizzle(query, context, extra, seed);
5146 };
5147
5148 for ( var prop in oldSizzle ) {
5149 Sizzle[ prop ] = oldSizzle[ prop ];
5150 }
5151
5152 // release memory in IE
5153 div = null;
5154 })();
5155}
5156
5157(function(){
5158 var html = document.documentElement,
5159 matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
5160
5161 if ( matches ) {
5162 // Check to see if it's possible to do matchesSelector
5163 // on a disconnected node (IE 9 fails this)
5164 var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
5165 pseudoWorks = false;
5166
5167 try {
5168 // This should fail with an exception
5169 // Gecko does not error, returns false instead
5170 matches.call( document.documentElement, "[test!='']:sizzle" );
5171
5172 } catch( pseudoError ) {
5173 pseudoWorks = true;
5174 }
5175
5176 Sizzle.matchesSelector = function( node, expr ) {
5177 // Make sure that attribute selectors are quoted
5178 expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
5179
5180 if ( !Sizzle.isXML( node ) ) {
5181 try {
5182 if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
5183 var ret = matches.call( node, expr );
5184
5185 // IE 9's matchesSelector returns false on disconnected nodes
5186 if ( ret || !disconnectedMatch ||
5187 // As well, disconnected nodes are said to be in a document
5188 // fragment in IE 9, so check for that
5189 node.document && node.document.nodeType !== 11 ) {
5190 return ret;
5191 }
5192 }
5193 } catch(e) {}
5194 }
5195
5196 return Sizzle(expr, null, null, [node]).length > 0;
5197 };
5198 }
5199})();
5200
5201(function(){
5202 var div = document.createElement("div");
5203
5204 div.innerHTML = "<div class='test e'></div><div class='test'></div>";
5205
5206 // Opera can't find a second classname (in 9.6)
5207 // Also, make sure that getElementsByClassName actually exists
5208 if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
5209 return;
5210 }
5211
5212 // Safari caches class attributes, doesn't catch changes (in 3.2)
5213 div.lastChild.className = "e";
5214
5215 if ( div.getElementsByClassName("e").length === 1 ) {
5216 return;
5217 }
5218
5219 Expr.order.splice(1, 0, "CLASS");
5220 Expr.find.CLASS = function( match, context, isXML ) {
5221 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
5222 return context.getElementsByClassName(match[1]);
5223 }
5224 };
5225
5226 // release memory in IE
5227 div = null;
5228})();
5229
5230function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5231 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5232 var elem = checkSet[i];
5233
5234 if ( elem ) {
5235 var match = false;
5236
5237 elem = elem[dir];
5238
5239 while ( elem ) {
5240 if ( elem[ expando ] === doneName ) {
5241 match = checkSet[elem.sizset];
5242 break;
5243 }
5244
5245 if ( elem.nodeType === 1 && !isXML ){
5246 elem[ expando ] = doneName;
5247 elem.sizset = i;
5248 }
5249
5250 if ( elem.nodeName.toLowerCase() === cur ) {
5251 match = elem;
5252 break;
5253 }
5254
5255 elem = elem[dir];
5256 }
5257
5258 checkSet[i] = match;
5259 }
5260 }
5261}
5262
5263function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5264 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5265 var elem = checkSet[i];
5266
5267 if ( elem ) {
5268 var match = false;
5269
5270 elem = elem[dir];
5271
5272 while ( elem ) {
5273 if ( elem[ expando ] === doneName ) {
5274 match = checkSet[elem.sizset];
5275 break;
5276 }
5277
5278 if ( elem.nodeType === 1 ) {
5279 if ( !isXML ) {
5280 elem[ expando ] = doneName;
5281 elem.sizset = i;
5282 }
5283
5284 if ( typeof cur !== "string" ) {
5285 if ( elem === cur ) {
5286 match = true;
5287 break;
5288 }
5289
5290 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
5291 match = elem;
5292 break;
5293 }
5294 }
5295
5296 elem = elem[dir];
5297 }
5298
5299 checkSet[i] = match;
5300 }
5301 }
5302}
5303
5304if ( document.documentElement.contains ) {
5305 Sizzle.contains = function( a, b ) {
5306 return a !== b && (a.contains ? a.contains(b) : true);
5307 };
5308
5309} else if ( document.documentElement.compareDocumentPosition ) {
5310 Sizzle.contains = function( a, b ) {
5311 return !!(a.compareDocumentPosition(b) & 16);
5312 };
5313
5314} else {
5315 Sizzle.contains = function() {
5316 return false;
5317 };
5318}
5319
5320Sizzle.isXML = function( elem ) {
5321 // documentElement is verified for cases where it doesn't yet exist
5322 // (such as loading iframes in IE - #4833)
5323 var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
5324
5325 return documentElement ? documentElement.nodeName !== "HTML" : false;
5326};
5327
5328var posProcess = function( selector, context, seed ) {
5329 var match,
5330 tmpSet = [],
5331 later = "",
5332 root = context.nodeType ? [context] : context;
5333
5334 // Position selectors must be done after the filter
5335 // And so must :not(positional) so we move all PSEUDOs to the end
5336 while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
5337 later += match[0];
5338 selector = selector.replace( Expr.match.PSEUDO, "" );
5339 }
5340
5341 selector = Expr.relative[selector] ? selector + "*" : selector;
5342
5343 for ( var i = 0, l = root.length; i < l; i++ ) {
5344 Sizzle( selector, root[i], tmpSet, seed );
5345 }
5346
5347 return Sizzle.filter( later, tmpSet );
5348};
5349
5350// EXPOSE
5351// Override sizzle attribute retrieval
5352Sizzle.attr = jQuery.attr;
5353Sizzle.selectors.attrMap = {};
5354jQuery.find = Sizzle;
5355jQuery.expr = Sizzle.selectors;
5356jQuery.expr[":"] = jQuery.expr.filters;
5357jQuery.unique = Sizzle.uniqueSort;
5358jQuery.text = Sizzle.getText;
5359jQuery.isXMLDoc = Sizzle.isXML;
5360jQuery.contains = Sizzle.contains;
5361
5362
5363})();
5364
5365
5366var runtil = /Until$/,
5367 rparentsprev = /^(?:parents|prevUntil|prevAll)/,
5368 // Note: This RegExp should be improved, or likely pulled from Sizzle
5369 rmultiselector = /,/,
5370 isSimple = /^.[^:#\[\.,]*$/,
5371 slice = Array.prototype.slice,
5372 POS = jQuery.expr.match.POS,
5373 // methods guaranteed to produce a unique set when starting from a unique set
5374 guaranteedUnique = {
5375 children: true,
5376 contents: true,
5377 next: true,
5378 prev: true
5379 };
5380
5381jQuery.fn.extend({
5382 find: function( selector ) {
5383 var self = this,
5384 i, l;
5385
5386 if ( typeof selector !== "string" ) {
5387 return jQuery( selector ).filter(function() {
5388 for ( i = 0, l = self.length; i < l; i++ ) {
5389 if ( jQuery.contains( self[ i ], this ) ) {
5390 return true;
5391 }
5392 }
5393 });
5394 }
5395
5396 var ret = this.pushStack( "", "find", selector ),
5397 length, n, r;
5398
5399 for ( i = 0, l = this.length; i < l; i++ ) {
5400 length = ret.length;
5401 jQuery.find( selector, this[i], ret );
5402
5403 if ( i > 0 ) {
5404 // Make sure that the results are unique
5405 for ( n = length; n < ret.length; n++ ) {
5406 for ( r = 0; r < length; r++ ) {
5407 if ( ret[r] === ret[n] ) {
5408 ret.splice(n--, 1);
5409 break;
5410 }
5411 }
5412 }
5413 }
5414 }
5415
5416 return ret;
5417 },
5418
5419 has: function( target ) {
5420 var targets = jQuery( target );
5421 return this.filter(function() {
5422 for ( var i = 0, l = targets.length; i < l; i++ ) {
5423 if ( jQuery.contains( this, targets[i] ) ) {
5424 return true;
5425 }
5426 }
5427 });
5428 },
5429
5430 not: function( selector ) {
5431 return this.pushStack( winnow(this, selector, false), "not", selector);
5432 },
5433
5434 filter: function( selector ) {
5435 return this.pushStack( winnow(this, selector, true), "filter", selector );
5436 },
5437
5438 is: function( selector ) {
5439 return !!selector && (
5440 typeof selector === "string" ?
5441 // If this is a positional selector, check membership in the returned set
5442 // so $("p:first").is("p:last") won't return true for a doc with two "p".
5443 POS.test( selector ) ?
5444 jQuery( selector, this.context ).index( this[0] ) >= 0 :
5445 jQuery.filter( selector, this ).length > 0 :
5446 this.filter( selector ).length > 0 );
5447 },
5448
5449 closest: function( selectors, context ) {
5450 var ret = [], i, l, cur = this[0];
5451
5452 // Array (deprecated as of jQuery 1.7)
5453 if ( jQuery.isArray( selectors ) ) {
5454 var level = 1;
5455
5456 while ( cur && cur.ownerDocument && cur !== context ) {
5457 for ( i = 0; i < selectors.length; i++ ) {
5458
5459 if ( jQuery( cur ).is( selectors[ i ] ) ) {
5460 ret.push({ selector: selectors[ i ], elem: cur, level: level });
5461 }
5462 }
5463
5464 cur = cur.parentNode;
5465 level++;
5466 }
5467
5468 return ret;
5469 }
5470
5471 // String
5472 var pos = POS.test( selectors ) || typeof selectors !== "string" ?
5473 jQuery( selectors, context || this.context ) :
5474 0;
5475
5476 for ( i = 0, l = this.length; i < l; i++ ) {
5477 cur = this[i];
5478
5479 while ( cur ) {
5480 if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
5481 ret.push( cur );
5482 break;
5483
5484 } else {
5485 cur = cur.parentNode;
5486 if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
5487 break;
5488 }
5489 }
5490 }
5491 }
5492
5493 ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
5494
5495 return this.pushStack( ret, "closest", selectors );
5496 },
5497
5498 // Determine the position of an element within
5499 // the matched set of elements
5500 index: function( elem ) {
5501
5502 // No argument, return index in parent
5503 if ( !elem ) {
5504 return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1;
5505 }
5506
5507 // index in selector
5508 if ( typeof elem === "string" ) {
5509 return jQuery.inArray( this[0], jQuery( elem ) );
5510 }
5511
5512 // Locate the position of the desired element
5513 return jQuery.inArray(
5514 // If it receives a jQuery object, the first element is used
5515 elem.jquery ? elem[0] : elem, this );
5516 },
5517
5518 add: function( selector, context ) {
5519 var set = typeof selector === "string" ?
5520 jQuery( selector, context ) :
5521 jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
5522 all = jQuery.merge( this.get(), set );
5523
5524 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
5525 all :
5526 jQuery.unique( all ) );
5527 },
5528
5529 andSelf: function() {
5530 return this.add( this.prevObject );
5531 }
5532});
5533
5534// A painfully simple check to see if an element is disconnected
5535// from a document (should be improved, where feasible).
5536function isDisconnected( node ) {
5537 return !node || !node.parentNode || node.parentNode.nodeType === 11;
5538}
5539
5540jQuery.each({
5541 parent: function( elem ) {
5542 var parent = elem.parentNode;
5543 return parent && parent.nodeType !== 11 ? parent : null;
5544 },
5545 parents: function( elem ) {
5546 return jQuery.dir( elem, "parentNode" );
5547 },
5548 parentsUntil: function( elem, i, until ) {
5549 return jQuery.dir( elem, "parentNode", until );
5550 },
5551 next: function( elem ) {
5552 return jQuery.nth( elem, 2, "nextSibling" );
5553 },
5554 prev: function( elem ) {
5555 return jQuery.nth( elem, 2, "previousSibling" );
5556 },
5557 nextAll: function( elem ) {
5558 return jQuery.dir( elem, "nextSibling" );
5559 },
5560 prevAll: function( elem ) {
5561 return jQuery.dir( elem, "previousSibling" );
5562 },
5563 nextUntil: function( elem, i, until ) {
5564 return jQuery.dir( elem, "nextSibling", until );
5565 },
5566 prevUntil: function( elem, i, until ) {
5567 return jQuery.dir( elem, "previousSibling", until );
5568 },
5569 siblings: function( elem ) {
5570 return jQuery.sibling( elem.parentNode.firstChild, elem );
5571 },
5572 children: function( elem ) {
5573 return jQuery.sibling( elem.firstChild );
5574 },
5575 contents: function( elem ) {
5576 return jQuery.nodeName( elem, "iframe" ) ?
5577 elem.contentDocument || elem.contentWindow.document :
5578 jQuery.makeArray( elem.childNodes );
5579 }
5580}, function( name, fn ) {
5581 jQuery.fn[ name ] = function( until, selector ) {
5582 var ret = jQuery.map( this, fn, until ),
5583 // The variable 'args' was introduced in
5584 // https://github.com/jquery/jquery/commit/52a0238
5585 // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed.
5586 // http://code.google.com/p/v8/issues/detail?id=1050
5587 args = slice.call(arguments);
5588
5589 if ( !runtil.test( name ) ) {
5590 selector = until;
5591 }
5592
5593 if ( selector && typeof selector === "string" ) {
5594 ret = jQuery.filter( selector, ret );
5595 }
5596
5597 ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
5598
5599 if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
5600 ret = ret.reverse();
5601 }
5602
5603 return this.pushStack( ret, name, args.join(",") );
5604 };
5605});
5606
5607jQuery.extend({
5608 filter: function( expr, elems, not ) {
5609 if ( not ) {
5610 expr = ":not(" + expr + ")";
5611 }
5612
5613 return elems.length === 1 ?
5614 jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
5615 jQuery.find.matches(expr, elems);
5616 },
5617
5618 dir: function( elem, dir, until ) {
5619 var matched = [],
5620 cur = elem[ dir ];
5621
5622 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
5623 if ( cur.nodeType === 1 ) {
5624 matched.push( cur );
5625 }
5626 cur = cur[dir];
5627 }
5628 return matched;
5629 },
5630
5631 nth: function( cur, result, dir, elem ) {
5632 result = result || 1;
5633 var num = 0;
5634
5635 for ( ; cur; cur = cur[dir] ) {
5636 if ( cur.nodeType === 1 && ++num === result ) {
5637 break;
5638 }
5639 }
5640
5641 return cur;
5642 },
5643
5644 sibling: function( n, elem ) {
5645 var r = [];
5646
5647 for ( ; n; n = n.nextSibling ) {
5648 if ( n.nodeType === 1 && n !== elem ) {
5649 r.push( n );
5650 }
5651 }
5652
5653 return r;
5654 }
5655});
5656
5657// Implement the identical functionality for filter and not
5658function winnow( elements, qualifier, keep ) {
5659
5660 // Can't pass null or undefined to indexOf in Firefox 4
5661 // Set to 0 to skip string check
5662 qualifier = qualifier || 0;
5663
5664 if ( jQuery.isFunction( qualifier ) ) {
5665 return jQuery.grep(elements, function( elem, i ) {
5666 var retVal = !!qualifier.call( elem, i, elem );
5667 return retVal === keep;
5668 });
5669
5670 } else if ( qualifier.nodeType ) {
5671 return jQuery.grep(elements, function( elem, i ) {
5672 return ( elem === qualifier ) === keep;
5673 });
5674
5675 } else if ( typeof qualifier === "string" ) {
5676 var filtered = jQuery.grep(elements, function( elem ) {
5677 return elem.nodeType === 1;
5678 });
5679
5680 if ( isSimple.test( qualifier ) ) {
5681 return jQuery.filter(qualifier, filtered, !keep);
5682 } else {
5683 qualifier = jQuery.filter( qualifier, filtered );
5684 }
5685 }
5686
5687 return jQuery.grep(elements, function( elem, i ) {
5688 return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep;
5689 });
5690}
5691
5692
5693
5694
5695function createSafeFragment( document ) {
5696 var list = nodeNames.split( " " ),
5697 safeFrag = document.createDocumentFragment();
5698
5699 if ( safeFrag.createElement ) {
5700 while ( list.length ) {
5701 safeFrag.createElement(
5702 list.pop()
5703 );
5704 }
5705 }
5706 return safeFrag;
5707}
5708
5709var nodeNames = "abbr article aside audio canvas datalist details figcaption figure footer " +
5710 "header hgroup mark meter nav output progress section summary time video",
5711 rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
5712 rleadingWhitespace = /^\s+/,
5713 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
5714 rtagName = /<([\w:]+)/,
5715 rtbody = /<tbody/i,
5716 rhtml = /<|&#?\w+;/,
5717 rnoInnerhtml = /<(?:script|style)/i,
5718 rnocache = /<(?:script|object|embed|option|style)/i,
5719 rnoshimcache = new RegExp("<(?:" + nodeNames.replace(" ", "|") + ")", "i"),
5720 // checked="checked" or checked
5721 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5722 rscriptType = /\/(java|ecma)script/i,
5723 rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/,
5724 wrapMap = {
5725 option: [ 1, "<select multiple='multiple'>", "</select>" ],
5726 legend: [ 1, "<fieldset>", "</fieldset>" ],
5727 thead: [ 1, "<table>", "</table>" ],
5728 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
5729 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
5730 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
5731 area: [ 1, "<map>", "</map>" ],
5732 _default: [ 0, "", "" ]
5733 },
5734 safeFragment = createSafeFragment( document );
5735
5736wrapMap.optgroup = wrapMap.option;
5737wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5738wrapMap.th = wrapMap.td;
5739
5740// IE can't serialize <link> and <script> tags normally
5741if ( !jQuery.support.htmlSerialize ) {
5742 wrapMap._default = [ 1, "div<div>", "</div>" ];
5743}
5744
5745jQuery.fn.extend({
5746 text: function( text ) {
5747 if ( jQuery.isFunction(text) ) {
5748 return this.each(function(i) {
5749 var self = jQuery( this );
5750
5751 self.text( text.call(this, i, self.text()) );
5752 });
5753 }
5754
5755 if ( typeof text !== "object" && text !== undefined ) {
5756 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
5757 }
5758
5759 return jQuery.text( this );
5760 },
5761
5762 wrapAll: function( html ) {
5763 if ( jQuery.isFunction( html ) ) {
5764 return this.each(function(i) {
5765 jQuery(this).wrapAll( html.call(this, i) );
5766 });
5767 }
5768
5769 if ( this[0] ) {
5770 // The elements to wrap the target around
5771 var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
5772
5773 if ( this[0].parentNode ) {
5774 wrap.insertBefore( this[0] );
5775 }
5776
5777 wrap.map(function() {
5778 var elem = this;
5779
5780 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
5781 elem = elem.firstChild;
5782 }
5783
5784 return elem;
5785 }).append( this );
5786 }
5787
5788 return this;
5789 },
5790
5791 wrapInner: function( html ) {
5792 if ( jQuery.isFunction( html ) ) {
5793 return this.each(function(i) {
5794 jQuery(this).wrapInner( html.call(this, i) );
5795 });
5796 }
5797
5798 return this.each(function() {
5799 var self = jQuery( this ),
5800 contents = self.contents();
5801
5802 if ( contents.length ) {
5803 contents.wrapAll( html );
5804
5805 } else {
5806 self.append( html );
5807 }
5808 });
5809 },
5810
5811 wrap: function( html ) {
5812 return this.each(function() {
5813 jQuery( this ).wrapAll( html );
5814 });
5815 },
5816
5817 unwrap: function() {
5818 return this.parent().each(function() {
5819 if ( !jQuery.nodeName( this, "body" ) ) {
5820 jQuery( this ).replaceWith( this.childNodes );
5821 }
5822 }).end();
5823 },
5824
5825 append: function() {
5826 return this.domManip(arguments, true, function( elem ) {
5827 if ( this.nodeType === 1 ) {
5828 this.appendChild( elem );
5829 }
5830 });
5831 },
5832
5833 prepend: function() {
5834 return this.domManip(arguments, true, function( elem ) {
5835 if ( this.nodeType === 1 ) {
5836 this.insertBefore( elem, this.firstChild );
5837 }
5838 });
5839 },
5840
5841 before: function() {
5842 if ( this[0] && this[0].parentNode ) {
5843 return this.domManip(arguments, false, function( elem ) {
5844 this.parentNode.insertBefore( elem, this );
5845 });
5846 } else if ( arguments.length ) {
5847 var set = jQuery(arguments[0]);
5848 set.push.apply( set, this.toArray() );
5849 return this.pushStack( set, "before", arguments );
5850 }
5851 },
5852
5853 after: function() {
5854 if ( this[0] && this[0].parentNode ) {
5855 return this.domManip(arguments, false, function( elem ) {
5856 this.parentNode.insertBefore( elem, this.nextSibling );
5857 });
5858 } else if ( arguments.length ) {
5859 var set = this.pushStack( this, "after", arguments );
5860 set.push.apply( set, jQuery(arguments[0]).toArray() );
5861 return set;
5862 }
5863 },
5864
5865 // keepData is for internal use only--do not document
5866 remove: function( selector, keepData ) {
5867 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5868 if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
5869 if ( !keepData && elem.nodeType === 1 ) {
5870 jQuery.cleanData( elem.getElementsByTagName("*") );
5871 jQuery.cleanData( [ elem ] );
5872 }
5873
5874 if ( elem.parentNode ) {
5875 elem.parentNode.removeChild( elem );
5876 }
5877 }
5878 }
5879
5880 return this;
5881 },
5882
5883 empty: function() {
5884 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5885 // Remove element nodes and prevent memory leaks
5886 if ( elem.nodeType === 1 ) {
5887 jQuery.cleanData( elem.getElementsByTagName("*") );
5888 }
5889
5890 // Remove any remaining nodes
5891 while ( elem.firstChild ) {
5892 elem.removeChild( elem.firstChild );
5893 }
5894 }
5895
5896 return this;
5897 },
5898
5899 clone: function( dataAndEvents, deepDataAndEvents ) {
5900 dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5901 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5902
5903 return this.map( function () {
5904 return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5905 });
5906 },
5907
5908 html: function( value ) {
5909 if ( value === undefined ) {
5910 return this[0] && this[0].nodeType === 1 ?
5911 this[0].innerHTML.replace(rinlinejQuery, "") :
5912 null;
5913
5914 // See if we can take a shortcut and just use innerHTML
5915 } else if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
5916 (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
5917 !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
5918
5919 value = value.replace(rxhtmlTag, "<$1></$2>");
5920
5921 try {
5922 for ( var i = 0, l = this.length; i < l; i++ ) {
5923 // Remove element nodes and prevent memory leaks
5924 if ( this[i].nodeType === 1 ) {
5925 jQuery.cleanData( this[i].getElementsByTagName("*") );
5926 this[i].innerHTML = value;
5927 }
5928 }
5929
5930 // If using innerHTML throws an exception, use the fallback method
5931 } catch(e) {
5932 this.empty().append( value );
5933 }
5934
5935 } else if ( jQuery.isFunction( value ) ) {
5936 this.each(function(i){
5937 var self = jQuery( this );
5938
5939 self.html( value.call(this, i, self.html()) );
5940 });
5941
5942 } else {
5943 this.empty().append( value );
5944 }
5945
5946 return this;
5947 },
5948
5949 replaceWith: function( value ) {
5950 if ( this[0] && this[0].parentNode ) {
5951 // Make sure that the elements are removed from the DOM before they are inserted
5952 // this can help fix replacing a parent with child elements
5953 if ( jQuery.isFunction( value ) ) {
5954 return this.each(function(i) {
5955 var self = jQuery(this), old = self.html();
5956 self.replaceWith( value.call( this, i, old ) );
5957 });
5958 }
5959
5960 if ( typeof value !== "string" ) {
5961 value = jQuery( value ).detach();
5962 }
5963
5964 return this.each(function() {
5965 var next = this.nextSibling,
5966 parent = this.parentNode;
5967
5968 jQuery( this ).remove();
5969
5970 if ( next ) {
5971 jQuery(next).before( value );
5972 } else {
5973 jQuery(parent).append( value );
5974 }
5975 });
5976 } else {
5977 return this.length ?
5978 this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
5979 this;
5980 }
5981 },
5982
5983 detach: function( selector ) {
5984 return this.remove( selector, true );
5985 },
5986
5987 domManip: function( args, table, callback ) {
5988 var results, first, fragment, parent,
5989 value = args[0],
5990 scripts = [];
5991
5992 // We can't cloneNode fragments that contain checked, in WebKit
5993 if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
5994 return this.each(function() {
5995 jQuery(this).domManip( args, table, callback, true );
5996 });
5997 }
5998
5999 if ( jQuery.isFunction(value) ) {
6000 return this.each(function(i) {
6001 var self = jQuery(this);
6002 args[0] = value.call(this, i, table ? self.html() : undefined);
6003 self.domManip( args, table, callback );
6004 });
6005 }
6006
6007 if ( this[0] ) {
6008 parent = value && value.parentNode;
6009
6010 // If we're in a fragment, just use that instead of building a new one
6011 if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
6012 results = { fragment: parent };
6013
6014 } else {
6015 results = jQuery.buildFragment( args, this, scripts );
6016 }
6017
6018 fragment = results.fragment;
6019
6020 if ( fragment.childNodes.length === 1 ) {
6021 first = fragment = fragment.firstChild;
6022 } else {
6023 first = fragment.firstChild;
6024 }
6025
6026 if ( first ) {
6027 table = table && jQuery.nodeName( first, "tr" );
6028
6029 for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {
6030 callback.call(
6031 table ?
6032 root(this[i], first) :
6033 this[i],
6034 // Make sure that we do not leak memory by inadvertently discarding
6035 // the original fragment (which might have attached data) instead of
6036 // using it; in addition, use the original fragment object for the last
6037 // item instead of first because it can end up being emptied incorrectly
6038 // in certain situations (Bug #8070).
6039 // Fragments from the fragment cache must always be cloned and never used
6040 // in place.
6041 results.cacheable || ( l > 1 && i < lastIndex ) ?
6042 jQuery.clone( fragment, true, true ) :
6043 fragment
6044 );
6045 }
6046 }
6047
6048 if ( scripts.length ) {
6049 jQuery.each( scripts, evalScript );
6050 }
6051 }
6052
6053 return this;
6054 }
6055});
6056
6057function root( elem, cur ) {
6058 return jQuery.nodeName(elem, "table") ?
6059 (elem.getElementsByTagName("tbody")[0] ||
6060 elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
6061 elem;
6062}
6063
6064function cloneCopyEvent( src, dest ) {
6065
6066 if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
6067 return;
6068 }
6069
6070 var type, i, l,
6071 oldData = jQuery._data( src ),
6072 curData = jQuery._data( dest, oldData ),
6073 events = oldData.events;
6074
6075 if ( events ) {
6076 delete curData.handle;
6077 curData.events = {};
6078
6079 for ( type in events ) {
6080 for ( i = 0, l = events[ type ].length; i < l; i++ ) {
6081 jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data );
6082 }
6083 }
6084 }
6085
6086 // make the cloned public data object a copy from the original
6087 if ( curData.data ) {
6088 curData.data = jQuery.extend( {}, curData.data );
6089 }
6090}
6091
6092function cloneFixAttributes( src, dest ) {
6093 var nodeName;
6094
6095 // We do not need to do anything for non-Elements
6096 if ( dest.nodeType !== 1 ) {
6097 return;
6098 }
6099
6100 // clearAttributes removes the attributes, which we don't want,
6101 // but also removes the attachEvent events, which we *do* want
6102 if ( dest.clearAttributes ) {
6103 dest.clearAttributes();
6104 }
6105
6106 // mergeAttributes, in contrast, only merges back on the
6107 // original attributes, not the events
6108 if ( dest.mergeAttributes ) {
6109 dest.mergeAttributes( src );
6110 }
6111
6112 nodeName = dest.nodeName.toLowerCase();
6113
6114 // IE6-8 fail to clone children inside object elements that use
6115 // the proprietary classid attribute value (rather than the type
6116 // attribute) to identify the type of content to display
6117 if ( nodeName === "object" ) {
6118 dest.outerHTML = src.outerHTML;
6119
6120 } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
6121 // IE6-8 fails to persist the checked state of a cloned checkbox
6122 // or radio button. Worse, IE6-7 fail to give the cloned element
6123 // a checked appearance if the defaultChecked value isn't also set
6124 if ( src.checked ) {
6125 dest.defaultChecked = dest.checked = src.checked;
6126 }
6127
6128 // IE6-7 get confused and end up setting the value of a cloned
6129 // checkbox/radio button to an empty string instead of "on"
6130 if ( dest.value !== src.value ) {
6131 dest.value = src.value;
6132 }
6133
6134 // IE6-8 fails to return the selected option to the default selected
6135 // state when cloning options
6136 } else if ( nodeName === "option" ) {
6137 dest.selected = src.defaultSelected;
6138
6139 // IE6-8 fails to set the defaultValue to the correct value when
6140 // cloning other types of input fields
6141 } else if ( nodeName === "input" || nodeName === "textarea" ) {
6142 dest.defaultValue = src.defaultValue;
6143 }
6144
6145 // Event data gets referenced instead of copied if the expando
6146 // gets copied too
6147 dest.removeAttribute( jQuery.expando );
6148}
6149
6150jQuery.buildFragment = function( args, nodes, scripts ) {
6151 var fragment, cacheable, cacheresults, doc,
6152 first = args[ 0 ];
6153
6154 // nodes may contain either an explicit document object,
6155 // a jQuery collection or context object.
6156 // If nodes[0] contains a valid object to assign to doc
6157 if ( nodes && nodes[0] ) {
6158 doc = nodes[0].ownerDocument || nodes[0];
6159 }
6160
6161 // Ensure that an attr object doesn't incorrectly stand in as a document object
6162 // Chrome and Firefox seem to allow this to occur and will throw exception
6163 // Fixes #8950
6164 if ( !doc.createDocumentFragment ) {
6165 doc = document;
6166 }
6167
6168 // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
6169 // Cloning options loses the selected state, so don't cache them
6170 // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
6171 // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
6172 // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501
6173 if ( args.length === 1 && typeof first === "string" && first.length < 512 && doc === document &&
6174 first.charAt(0) === "<" && !rnocache.test( first ) &&
6175 (jQuery.support.checkClone || !rchecked.test( first )) &&
6176 (!jQuery.support.unknownElems && rnoshimcache.test( first )) ) {
6177
6178 cacheable = true;
6179
6180 cacheresults = jQuery.fragments[ first ];
6181 if ( cacheresults && cacheresults !== 1 ) {
6182 fragment = cacheresults;
6183 }
6184 }
6185
6186 if ( !fragment ) {
6187 fragment = doc.createDocumentFragment();
6188 jQuery.clean( args, doc, fragment, scripts );
6189 }
6190
6191 if ( cacheable ) {
6192 jQuery.fragments[ first ] = cacheresults ? fragment : 1;
6193 }
6194
6195 return { fragment: fragment, cacheable: cacheable };
6196};
6197
6198jQuery.fragments = {};
6199
6200jQuery.each({
6201 appendTo: "append",
6202 prependTo: "prepend",
6203 insertBefore: "before",
6204 insertAfter: "after",
6205 replaceAll: "replaceWith"
6206}, function( name, original ) {
6207 jQuery.fn[ name ] = function( selector ) {
6208 var ret = [],
6209 insert = jQuery( selector ),
6210 parent = this.length === 1 && this[0].parentNode;
6211
6212 if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
6213 insert[ original ]( this[0] );
6214 return this;
6215
6216 } else {
6217 for ( var i = 0, l = insert.length; i < l; i++ ) {
6218 var elems = ( i > 0 ? this.clone(true) : this ).get();
6219 jQuery( insert[i] )[ original ]( elems );
6220 ret = ret.concat( elems );
6221 }
6222
6223 return this.pushStack( ret, name, insert.selector );
6224 }
6225 };
6226});
6227
6228function getAll( elem ) {
6229 if ( typeof elem.getElementsByTagName !== "undefined" ) {
6230 return elem.getElementsByTagName( "*" );
6231
6232 } else if ( typeof elem.querySelectorAll !== "undefined" ) {
6233 return elem.querySelectorAll( "*" );
6234
6235 } else {
6236 return [];
6237 }
6238}
6239
6240// Used in clean, fixes the defaultChecked property
6241function fixDefaultChecked( elem ) {
6242 if ( elem.type === "checkbox" || elem.type === "radio" ) {
6243 elem.defaultChecked = elem.checked;
6244 }
6245}
6246// Finds all inputs and passes them to fixDefaultChecked
6247function findInputs( elem ) {
6248 var nodeName = ( elem.nodeName || "" ).toLowerCase();
6249 if ( nodeName === "input" ) {
6250 fixDefaultChecked( elem );
6251 // Skip scripts, get other children
6252 } else if ( nodeName !== "script" && typeof elem.getElementsByTagName !== "undefined" ) {
6253 jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
6254 }
6255}
6256
6257jQuery.extend({
6258 clone: function( elem, dataAndEvents, deepDataAndEvents ) {
6259 var clone = elem.cloneNode(true),
6260 srcElements,
6261 destElements,
6262 i;
6263
6264 if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
6265 (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
6266 // IE copies events bound via attachEvent when using cloneNode.
6267 // Calling detachEvent on the clone will also remove the events
6268 // from the original. In order to get around this, we use some
6269 // proprietary methods to clear the events. Thanks to MooTools
6270 // guys for this hotness.
6271
6272 cloneFixAttributes( elem, clone );
6273
6274 // Using Sizzle here is crazy slow, so we use getElementsByTagName
6275 // instead
6276 srcElements = getAll( elem );
6277 destElements = getAll( clone );
6278
6279 // Weird iteration because IE will replace the length property
6280 // with an element if you are cloning the body and one of the
6281 // elements on the page has a name or id of "length"
6282 for ( i = 0; srcElements[i]; ++i ) {
6283 // Ensure that the destination node is not null; Fixes #9587
6284 if ( destElements[i] ) {
6285 cloneFixAttributes( srcElements[i], destElements[i] );
6286 }
6287 }
6288 }
6289
6290 // Copy the events from the original to the clone
6291 if ( dataAndEvents ) {
6292 cloneCopyEvent( elem, clone );
6293
6294 if ( deepDataAndEvents ) {
6295 srcElements = getAll( elem );
6296 destElements = getAll( clone );
6297
6298 for ( i = 0; srcElements[i]; ++i ) {
6299 cloneCopyEvent( srcElements[i], destElements[i] );
6300 }
6301 }
6302 }
6303
6304 srcElements = destElements = null;
6305
6306 // Return the cloned set
6307 return clone;
6308 },
6309
6310 clean: function( elems, context, fragment, scripts ) {
6311 var checkScriptType;
6312
6313 context = context || document;
6314
6315 // !context.createElement fails in IE with an error but returns typeof 'object'
6316 if ( typeof context.createElement === "undefined" ) {
6317 context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
6318 }
6319
6320 var ret = [], j;
6321
6322 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6323 if ( typeof elem === "number" ) {
6324 elem += "";
6325 }
6326
6327 if ( !elem ) {
6328 continue;
6329 }
6330
6331 // Convert html string into DOM nodes
6332 if ( typeof elem === "string" ) {
6333 if ( !rhtml.test( elem ) ) {
6334 elem = context.createTextNode( elem );
6335 } else {
6336 // Fix "XHTML"-style tags in all browsers
6337 elem = elem.replace(rxhtmlTag, "<$1></$2>");
6338
6339 // Trim whitespace, otherwise indexOf won't work as expected
6340 var tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(),
6341 wrap = wrapMap[ tag ] || wrapMap._default,
6342 depth = wrap[0],
6343 div = context.createElement("div");
6344
6345 // Append wrapper element to unknown element safe doc fragment
6346 if ( context === document ) {
6347 // Use the fragment we've already created for this document
6348 safeFragment.appendChild( div );
6349 } else {
6350 // Use a fragment created with the owner document
6351 createSafeFragment( context ).appendChild( div );
6352 }
6353
6354 // Go to html and back, then peel off extra wrappers
6355 div.innerHTML = wrap[1] + elem + wrap[2];
6356
6357 // Move to the right depth
6358 while ( depth-- ) {
6359 div = div.lastChild;
6360 }
6361
6362 // Remove IE's autoinserted <tbody> from table fragments
6363 if ( !jQuery.support.tbody ) {
6364
6365 // String was a <table>, *may* have spurious <tbody>
6366 var hasBody = rtbody.test(elem),
6367 tbody = tag === "table" && !hasBody ?
6368 div.firstChild && div.firstChild.childNodes :
6369
6370 // String was a bare <thead> or <tfoot>
6371 wrap[1] === "<table>" && !hasBody ?
6372 div.childNodes :
6373 [];
6374
6375 for ( j = tbody.length - 1; j >= 0 ; --j ) {
6376 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
6377 tbody[ j ].parentNode.removeChild( tbody[ j ] );
6378 }
6379 }
6380 }
6381
6382 // IE completely kills leading whitespace when innerHTML is used
6383 if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
6384 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
6385 }
6386
6387 elem = div.childNodes;
6388 }
6389 }
6390
6391 // Resets defaultChecked for any radios and checkboxes
6392 // about to be appended to the DOM in IE 6/7 (#8060)
6393 var len;
6394 if ( !jQuery.support.appendChecked ) {
6395 if ( elem[0] && typeof (len = elem.length) === "number" ) {
6396 for ( j = 0; j < len; j++ ) {
6397 findInputs( elem[j] );
6398 }
6399 } else {
6400 findInputs( elem );
6401 }
6402 }
6403
6404 if ( elem.nodeType ) {
6405 ret.push( elem );
6406 } else {
6407 ret = jQuery.merge( ret, elem );
6408 }
6409 }
6410
6411 if ( fragment ) {
6412 checkScriptType = function( elem ) {
6413 return !elem.type || rscriptType.test( elem.type );
6414 };
6415 for ( i = 0; ret[i]; i++ ) {
6416 if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
6417 scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
6418
6419 } else {
6420 if ( ret[i].nodeType === 1 ) {
6421 var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType );
6422
6423 ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
6424 }
6425 fragment.appendChild( ret[i] );
6426 }
6427 }
6428 }
6429
6430 return ret;
6431 },
6432
6433 cleanData: function( elems ) {
6434 var data, id,
6435 cache = jQuery.cache,
6436 special = jQuery.event.special,
6437 deleteExpando = jQuery.support.deleteExpando;
6438
6439 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6440 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
6441 continue;
6442 }
6443
6444 id = elem[ jQuery.expando ];
6445
6446 if ( id ) {
6447 data = cache[ id ];
6448
6449 if ( data && data.events ) {
6450 for ( var type in data.events ) {
6451 if ( special[ type ] ) {
6452 jQuery.event.remove( elem, type );
6453
6454 // This is a shortcut to avoid jQuery.event.remove's overhead
6455 } else {
6456 jQuery.removeEvent( elem, type, data.handle );
6457 }
6458 }
6459
6460 // Null the DOM reference to avoid IE6/7/8 leak (#7054)
6461 if ( data.handle ) {
6462 data.handle.elem = null;
6463 }
6464 }
6465
6466 if ( deleteExpando ) {
6467 delete elem[ jQuery.expando ];
6468
6469 } else if ( elem.removeAttribute ) {
6470 elem.removeAttribute( jQuery.expando );
6471 }
6472
6473 delete cache[ id ];
6474 }
6475 }
6476 }
6477});
6478
6479function evalScript( i, elem ) {
6480 if ( elem.src ) {
6481 jQuery.ajax({
6482 url: elem.src,
6483 async: false,
6484 dataType: "script"
6485 });
6486 } else {
6487 jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) );
6488 }
6489
6490 if ( elem.parentNode ) {
6491 elem.parentNode.removeChild( elem );
6492 }
6493}
6494
6495
6496
6497
6498var ralpha = /alpha\([^)]*\)/i,
6499 ropacity = /opacity=([^)]*)/,
6500 // fixed for IE9, see #8346
6501 rupper = /([A-Z]|^ms)/g,
6502 rnumpx = /^-?\d+(?:px)?$/i,
6503 rnum = /^-?\d/,
6504 rrelNum = /^([\-+])=([\-+.\de]+)/,
6505
6506 cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6507 cssWidth = [ "Left", "Right" ],
6508 cssHeight = [ "Top", "Bottom" ],
6509 curCSS,
6510
6511 getComputedStyle,
6512 currentStyle;
6513
6514jQuery.fn.css = function( name, value ) {
6515 // Setting 'undefined' is a no-op
6516 if ( arguments.length === 2 && value === undefined ) {
6517 return this;
6518 }
6519
6520 return jQuery.access( this, name, value, true, function( elem, name, value ) {
6521 return value !== undefined ?
6522 jQuery.style( elem, name, value ) :
6523 jQuery.css( elem, name );
6524 });
6525};
6526
6527jQuery.extend({
6528 // Add in style property hooks for overriding the default
6529 // behavior of getting and setting a style property
6530 cssHooks: {
6531 opacity: {
6532 get: function( elem, computed ) {
6533 if ( computed ) {
6534 // We should always get a number back from opacity
6535 var ret = curCSS( elem, "opacity", "opacity" );
6536 return ret === "" ? "1" : ret;
6537
6538 } else {
6539 return elem.style.opacity;
6540 }
6541 }
6542 }
6543 },
6544
6545 // Exclude the following css properties to add px
6546 cssNumber: {
6547 "fillOpacity": true,
6548 "fontWeight": true,
6549 "lineHeight": true,
6550 "opacity": true,
6551 "orphans": true,
6552 "widows": true,
6553 "zIndex": true,
6554 "zoom": true
6555 },
6556
6557 // Add in properties whose names you wish to fix before
6558 // setting or getting the value
6559 cssProps: {
6560 // normalize float css property
6561 "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
6562 },
6563
6564 // Get and set the style property on a DOM Node
6565 style: function( elem, name, value, extra ) {
6566 // Don't set styles on text and comment nodes
6567 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6568 return;
6569 }
6570
6571 // Make sure that we're working with the right name
6572 var ret, type, origName = jQuery.camelCase( name ),
6573 style = elem.style, hooks = jQuery.cssHooks[ origName ];
6574
6575 name = jQuery.cssProps[ origName ] || origName;
6576
6577 // Check if we're setting a value
6578 if ( value !== undefined ) {
6579 type = typeof value;
6580
6581 // convert relative number strings (+= or -=) to relative numbers. #7345
6582 if ( type === "string" && (ret = rrelNum.exec( value )) ) {
6583 value = ( +( ret[1] + 1) * +ret[2] ) + parseFloat( jQuery.css( elem, name ) );
6584 // Fixes bug #9237
6585 type = "number";
6586 }
6587
6588 // Make sure that NaN and null values aren't set. See: #7116
6589 if ( value == null || type === "number" && isNaN( value ) ) {
6590 return;
6591 }
6592
6593 // If a number was passed in, add 'px' to the (except for certain CSS properties)
6594 if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
6595 value += "px";
6596 }
6597
6598 // If a hook was provided, use that value, otherwise just set the specified value
6599 if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
6600 // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
6601 // Fixes bug #5509
6602 try {
6603 style[ name ] = value;
6604 } catch(e) {}
6605 }
6606
6607 } else {
6608 // If a hook was provided get the non-computed value from there
6609 if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6610 return ret;
6611 }
6612
6613 // Otherwise just get the value from the style object
6614 return style[ name ];
6615 }
6616 },
6617
6618 css: function( elem, name, extra ) {
6619 var ret, hooks;
6620
6621 // Make sure that we're working with the right name
6622 name = jQuery.camelCase( name );
6623 hooks = jQuery.cssHooks[ name ];
6624 name = jQuery.cssProps[ name ] || name;
6625
6626 // cssFloat needs a special treatment
6627 if ( name === "cssFloat" ) {
6628 name = "float";
6629 }
6630
6631 // If a hook was provided get the computed value from there
6632 if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
6633 return ret;
6634
6635 // Otherwise, if a way to get the computed value exists, use that
6636 } else if ( curCSS ) {
6637 return curCSS( elem, name );
6638 }
6639 },
6640
6641 // A method for quickly swapping in/out CSS properties to get correct calculations
6642 swap: function( elem, options, callback ) {
6643 var old = {};
6644
6645 // Remember the old values, and insert the new ones
6646 for ( var name in options ) {
6647 old[ name ] = elem.style[ name ];
6648 elem.style[ name ] = options[ name ];
6649 }
6650
6651 callback.call( elem );
6652
6653 // Revert the old values
6654 for ( name in options ) {
6655 elem.style[ name ] = old[ name ];
6656 }
6657 }
6658});
6659
6660// DEPRECATED, Use jQuery.css() instead
6661jQuery.curCSS = jQuery.css;
6662
6663jQuery.each(["height", "width"], function( i, name ) {
6664 jQuery.cssHooks[ name ] = {
6665 get: function( elem, computed, extra ) {
6666 var val;
6667
6668 if ( computed ) {
6669 if ( elem.offsetWidth !== 0 ) {
6670 return getWH( elem, name, extra );
6671 } else {
6672 jQuery.swap( elem, cssShow, function() {
6673 val = getWH( elem, name, extra );
6674 });
6675 }
6676
6677 return val;
6678 }
6679 },
6680
6681 set: function( elem, value ) {
6682 if ( rnumpx.test( value ) ) {
6683 // ignore negative width and height values #1599
6684 value = parseFloat( value );
6685
6686 if ( value >= 0 ) {
6687 return value + "px";
6688 }
6689
6690 } else {
6691 return value;
6692 }
6693 }
6694 };
6695});
6696
6697if ( !jQuery.support.opacity ) {
6698 jQuery.cssHooks.opacity = {
6699 get: function( elem, computed ) {
6700 // IE uses filters for opacity
6701 return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
6702 ( parseFloat( RegExp.$1 ) / 100 ) + "" :
6703 computed ? "1" : "";
6704 },
6705
6706 set: function( elem, value ) {
6707 var style = elem.style,
6708 currentStyle = elem.currentStyle,
6709 opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
6710 filter = currentStyle && currentStyle.filter || style.filter || "";
6711
6712 // IE has trouble with opacity if it does not have layout
6713 // Force it by setting the zoom level
6714 style.zoom = 1;
6715
6716 // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
6717 if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" ) {
6718
6719 // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
6720 // if "filter:" is present at all, clearType is disabled, we want to avoid this
6721 // style.removeAttribute is IE Only, but so apparently is this code path...
6722 style.removeAttribute( "filter" );
6723
6724 // if there there is no filter style applied in a css rule, we are done
6725 if ( currentStyle && !currentStyle.filter ) {
6726 return;
6727 }
6728 }
6729
6730 // otherwise, set new filter values
6731 style.filter = ralpha.test( filter ) ?
6732 filter.replace( ralpha, opacity ) :
6733 filter + " " + opacity;
6734 }
6735 };
6736}
6737
6738jQuery(function() {
6739 // This hook cannot be added until DOM ready because the support test
6740 // for it is not run until after DOM ready
6741 if ( !jQuery.support.reliableMarginRight ) {
6742 jQuery.cssHooks.marginRight = {
6743 get: function( elem, computed ) {
6744 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6745 // Work around by temporarily setting element display to inline-block
6746 var ret;
6747 jQuery.swap( elem, { "display": "inline-block" }, function() {
6748 if ( computed ) {
6749 ret = curCSS( elem, "margin-right", "marginRight" );
6750 } else {
6751 ret = elem.style.marginRight;
6752 }
6753 });
6754 return ret;
6755 }
6756 };
6757 }
6758});
6759
6760if ( document.defaultView && document.defaultView.getComputedStyle ) {
6761 getComputedStyle = function( elem, name ) {
6762 var ret, defaultView, computedStyle;
6763
6764 name = name.replace( rupper, "-$1" ).toLowerCase();
6765
6766 if ( !(defaultView = elem.ownerDocument.defaultView) ) {
6767 return undefined;
6768 }
6769
6770 if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
6771 ret = computedStyle.getPropertyValue( name );
6772 if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
6773 ret = jQuery.style( elem, name );
6774 }
6775 }
6776
6777 return ret;
6778 };
6779}
6780
6781if ( document.documentElement.currentStyle ) {
6782 currentStyle = function( elem, name ) {
6783 var left, rsLeft, uncomputed,
6784 ret = elem.currentStyle && elem.currentStyle[ name ],
6785 style = elem.style;
6786
6787 // Avoid setting ret to empty string here
6788 // so we don't default to auto
6789 if ( ret === null && style && (uncomputed = style[ name ]) ) {
6790 ret = uncomputed;
6791 }
6792
6793 // From the awesome hack by Dean Edwards
6794 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6795
6796 // If we're not dealing with a regular pixel number
6797 // but a number that has a weird ending, we need to convert it to pixels
6798 if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
6799
6800 // Remember the original values
6801 left = style.left;
6802 rsLeft = elem.runtimeStyle && elem.runtimeStyle.left;
6803
6804 // Put in the new values to get a computed value out
6805 if ( rsLeft ) {
6806 elem.runtimeStyle.left = elem.currentStyle.left;
6807 }
6808 style.left = name === "fontSize" ? "1em" : ( ret || 0 );
6809 ret = style.pixelLeft + "px";
6810
6811 // Revert the changed values
6812 style.left = left;
6813 if ( rsLeft ) {
6814 elem.runtimeStyle.left = rsLeft;
6815 }
6816 }
6817
6818 return ret === "" ? "auto" : ret;
6819 };
6820}
6821
6822curCSS = getComputedStyle || currentStyle;
6823
6824function getWH( elem, name, extra ) {
6825
6826 // Start with offset property
6827 var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
6828 which = name === "width" ? cssWidth : cssHeight;
6829
6830 if ( val > 0 ) {
6831 if ( extra !== "border" ) {
6832 jQuery.each( which, function() {
6833 if ( !extra ) {
6834 val -= parseFloat( jQuery.css( elem, "padding" + this ) ) || 0;
6835 }
6836 if ( extra === "margin" ) {
6837 val += parseFloat( jQuery.css( elem, extra + this ) ) || 0;
6838 } else {
6839 val -= parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0;
6840 }
6841 });
6842 }
6843
6844 return val + "px";
6845 }
6846
6847 // Fall back to computed then uncomputed css if necessary
6848 val = curCSS( elem, name, name );
6849 if ( val < 0 || val == null ) {
6850 val = elem.style[ name ] || 0;
6851 }
6852 // Normalize "", auto, and prepare for extra
6853 val = parseFloat( val ) || 0;
6854
6855 // Add padding, border, margin
6856 if ( extra ) {
6857 jQuery.each( which, function() {
6858 val += parseFloat( jQuery.css( elem, "padding" + this ) ) || 0;
6859 if ( extra !== "padding" ) {
6860 val += parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0;
6861 }
6862 if ( extra === "margin" ) {
6863 val += parseFloat( jQuery.css( elem, extra + this ) ) || 0;
6864 }
6865 });
6866 }
6867
6868 return val + "px";
6869}
6870
6871if ( jQuery.expr && jQuery.expr.filters ) {
6872 jQuery.expr.filters.hidden = function( elem ) {
6873 var width = elem.offsetWidth,
6874 height = elem.offsetHeight;
6875
6876 return ( width === 0 && height === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
6877 };
6878
6879 jQuery.expr.filters.visible = function( elem ) {
6880 return !jQuery.expr.filters.hidden( elem );
6881 };
6882}
6883
6884
6885
6886
6887var r20 = /%20/g,
6888 rbracket = /\[\]$/,
6889 rCRLF = /\r?\n/g,
6890 rhash = /#.*$/,
6891 rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
6892 rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
6893 // #7653, #8125, #8152: local protocol detection
6894 rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,
6895 rnoContent = /^(?:GET|HEAD)$/,
6896 rprotocol = /^\/\//,
6897 rquery = /\?/,
6898 rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
6899 rselectTextarea = /^(?:select|textarea)/i,
6900 rspacesAjax = /\s+/,
6901 rts = /([?&])_=[^&]*/,
6902 rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
6903
6904 // Keep a copy of the old load method
6905 _load = jQuery.fn.load,
6906
6907 /* Prefilters
6908 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
6909 * 2) These are called:
6910 * - BEFORE asking for a transport
6911 * - AFTER param serialization (s.data is a string if s.processData is true)
6912 * 3) key is the dataType
6913 * 4) the catchall symbol "*" can be used
6914 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
6915 */
6916 prefilters = {},
6917
6918 /* Transports bindings
6919 * 1) key is the dataType
6920 * 2) the catchall symbol "*" can be used
6921 * 3) selection will start with transport dataType and THEN go to "*" if needed
6922 */
6923 transports = {},
6924
6925 // Document location
6926 ajaxLocation,
6927
6928 // Document location segments
6929 ajaxLocParts,
6930
6931 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
6932 allTypes = ["*/"] + ["*"];
6933
6934// #8138, IE may throw an exception when accessing
6935// a field from window.location if document.domain has been set
6936try {
6937 ajaxLocation = location.href;
6938} catch( e ) {
6939 // Use the href attribute of an A element
6940 // since IE will modify it given document.location
6941 ajaxLocation = document.createElement( "a" );
6942 ajaxLocation.href = "";
6943 ajaxLocation = ajaxLocation.href;
6944}
6945
6946// Segment location into parts
6947ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
6948
6949// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
6950function addToPrefiltersOrTransports( structure ) {
6951
6952 // dataTypeExpression is optional and defaults to "*"
6953 return function( dataTypeExpression, func ) {
6954
6955 if ( typeof dataTypeExpression !== "string" ) {
6956 func = dataTypeExpression;
6957 dataTypeExpression = "*";
6958 }
6959
6960 if ( jQuery.isFunction( func ) ) {
6961 var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),
6962 i = 0,
6963 length = dataTypes.length,
6964 dataType,
6965 list,
6966 placeBefore;
6967
6968 // For each dataType in the dataTypeExpression
6969 for ( ; i < length; i++ ) {
6970 dataType = dataTypes[ i ];
6971 // We control if we're asked to add before
6972 // any existing element
6973 placeBefore = /^\+/.test( dataType );
6974 if ( placeBefore ) {
6975 dataType = dataType.substr( 1 ) || "*";
6976 }
6977 list = structure[ dataType ] = structure[ dataType ] || [];
6978 // then we add to the structure accordingly
6979 list[ placeBefore ? "unshift" : "push" ]( func );
6980 }
6981 }
6982 };
6983}
6984
6985// Base inspection function for prefilters and transports
6986function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
6987 dataType /* internal */, inspected /* internal */ ) {
6988
6989 dataType = dataType || options.dataTypes[ 0 ];
6990 inspected = inspected || {};
6991
6992 inspected[ dataType ] = true;
6993
6994 var list = structure[ dataType ],
6995 i = 0,
6996 length = list ? list.length : 0,
6997 executeOnly = ( structure === prefilters ),
6998 selection;
6999
7000 for ( ; i < length && ( executeOnly || !selection ); i++ ) {
7001 selection = list[ i ]( options, originalOptions, jqXHR );
7002 // If we got redirected to another dataType
7003 // we try there if executing only and not done already
7004 if ( typeof selection === "string" ) {
7005 if ( !executeOnly || inspected[ selection ] ) {
7006 selection = undefined;
7007 } else {
7008 options.dataTypes.unshift( selection );
7009 selection = inspectPrefiltersOrTransports(
7010 structure, options, originalOptions, jqXHR, selection, inspected );
7011 }
7012 }
7013 }
7014 // If we're only executing or nothing was selected
7015 // we try the catchall dataType if not done already
7016 if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
7017 selection = inspectPrefiltersOrTransports(
7018 structure, options, originalOptions, jqXHR, "*", inspected );
7019 }
7020 // unnecessary when only executing (prefilters)
7021 // but it'll be ignored by the caller in that case
7022 return selection;
7023}
7024
7025// A special extend for ajax options
7026// that takes "flat" options (not to be deep extended)
7027// Fixes #9887
7028function ajaxExtend( target, src ) {
7029 var key, deep,
7030 flatOptions = jQuery.ajaxSettings.flatOptions || {};
7031 for ( key in src ) {
7032 if ( src[ key ] !== undefined ) {
7033 ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
7034 }
7035 }
7036 if ( deep ) {
7037 jQuery.extend( true, target, deep );
7038 }
7039}
7040
7041jQuery.fn.extend({
7042 load: function( url, params, callback ) {
7043 if ( typeof url !== "string" && _load ) {
7044 return _load.apply( this, arguments );
7045
7046 // Don't do a request if no elements are being requested
7047 } else if ( !this.length ) {
7048 return this;
7049 }
7050
7051 var off = url.indexOf( " " );
7052 if ( off >= 0 ) {
7053 var selector = url.slice( off, url.length );
7054 url = url.slice( 0, off );
7055 }
7056
7057 // Default to a GET request
7058 var type = "GET";
7059
7060 // If the second parameter was provided
7061 if ( params ) {
7062 // If it's a function
7063 if ( jQuery.isFunction( params ) ) {
7064 // We assume that it's the callback
7065 callback = params;
7066 params = undefined;
7067
7068 // Otherwise, build a param string
7069 } else if ( typeof params === "object" ) {
7070 params = jQuery.param( params, jQuery.ajaxSettings.traditional );
7071 type = "POST";
7072 }
7073 }
7074
7075 var self = this;
7076
7077 // Request the remote document
7078 jQuery.ajax({
7079 url: url,
7080 type: type,
7081 dataType: "html",
7082 data: params,
7083 // Complete callback (responseText is used internally)
7084 complete: function( jqXHR, status, responseText ) {
7085 // Store the response as specified by the jqXHR object
7086 responseText = jqXHR.responseText;
7087 // If successful, inject the HTML into all the matched elements
7088 if ( jqXHR.isResolved() ) {
7089 // #4825: Get the actual response in case
7090 // a dataFilter is present in ajaxSettings
7091 jqXHR.done(function( r ) {
7092 responseText = r;
7093 });
7094 // See if a selector was specified
7095 self.html( selector ?
7096 // Create a dummy div to hold the results
7097 jQuery("<div>")
7098 // inject the contents of the document in, removing the scripts
7099 // to avoid any 'Permission Denied' errors in IE
7100 .append(responseText.replace(rscript, ""))
7101
7102 // Locate the specified elements
7103 .find(selector) :
7104
7105 // If not, just inject the full result
7106 responseText );
7107 }
7108
7109 if ( callback ) {
7110 self.each( callback, [ responseText, status, jqXHR ] );
7111 }
7112 }
7113 });
7114
7115 return this;
7116 },
7117
7118 serialize: function() {
7119 return jQuery.param( this.serializeArray() );
7120 },
7121
7122 serializeArray: function() {
7123 return this.map(function(){
7124 return this.elements ? jQuery.makeArray( this.elements ) : this;
7125 })
7126 .filter(function(){
7127 return this.name && !this.disabled &&
7128 ( this.checked || rselectTextarea.test( this.nodeName ) ||
7129 rinput.test( this.type ) );
7130 })
7131 .map(function( i, elem ){
7132 var val = jQuery( this ).val();
7133
7134 return val == null ?
7135 null :
7136 jQuery.isArray( val ) ?
7137 jQuery.map( val, function( val, i ){
7138 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
7139 }) :
7140 { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
7141 }).get();
7142 }
7143});
7144
7145// Attach a bunch of functions for handling common AJAX events
7146jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
7147 jQuery.fn[ o ] = function( f ){
7148 return this.bind( o, f );
7149 };
7150});
7151
7152jQuery.each( [ "get", "post" ], function( i, method ) {
7153 jQuery[ method ] = function( url, data, callback, type ) {
7154 // shift arguments if data argument was omitted
7155 if ( jQuery.isFunction( data ) ) {
7156 type = type || callback;
7157 callback = data;
7158 data = undefined;
7159 }
7160
7161 return jQuery.ajax({
7162 type: method,
7163 url: url,
7164 data: data,
7165 success: callback,
7166 dataType: type
7167 });
7168 };
7169});
7170
7171jQuery.extend({
7172
7173 getScript: function( url, callback ) {
7174 return jQuery.get( url, undefined, callback, "script" );
7175 },
7176
7177 getJSON: function( url, data, callback ) {
7178 return jQuery.get( url, data, callback, "json" );
7179 },
7180
7181 // Creates a full fledged settings object into target
7182 // with both ajaxSettings and settings fields.
7183 // If target is omitted, writes into ajaxSettings.
7184 ajaxSetup: function( target, settings ) {
7185 if ( settings ) {
7186 // Building a settings object
7187 ajaxExtend( target, jQuery.ajaxSettings );
7188 } else {
7189 // Extending ajaxSettings
7190 settings = target;
7191 target = jQuery.ajaxSettings;
7192 }
7193 ajaxExtend( target, settings );
7194 return target;
7195 },
7196
7197 ajaxSettings: {
7198 url: ajaxLocation,
7199 isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
7200 global: true,
7201 type: "GET",
7202 contentType: "application/x-www-form-urlencoded",
7203 processData: true,
7204 async: true,
7205 /*
7206 timeout: 0,
7207 data: null,
7208 dataType: null,
7209 username: null,
7210 password: null,
7211 cache: null,
7212 traditional: false,
7213 headers: {},
7214 */
7215
7216 accepts: {
7217 xml: "application/xml, text/xml",
7218 html: "text/html",
7219 text: "text/plain",
7220 json: "application/json, text/javascript",
7221 "*": allTypes
7222 },
7223
7224 contents: {
7225 xml: /xml/,
7226 html: /html/,
7227 json: /json/
7228 },
7229
7230 responseFields: {
7231 xml: "responseXML",
7232 text: "responseText"
7233 },
7234
7235 // List of data converters
7236 // 1) key format is "source_type destination_type" (a single space in-between)
7237 // 2) the catchall symbol "*" can be used for source_type
7238 converters: {
7239
7240 // Convert anything to text
7241 "* text": window.String,
7242
7243 // Text to html (true = no transformation)
7244 "text html": true,
7245
7246 // Evaluate text as a json expression
7247 "text json": jQuery.parseJSON,
7248
7249 // Parse text as xml
7250 "text xml": jQuery.parseXML
7251 },
7252
7253 // For options that shouldn't be deep extended:
7254 // you can add your own custom options here if
7255 // and when you create one that shouldn't be
7256 // deep extended (see ajaxExtend)
7257 flatOptions: {
7258 context: true,
7259 url: true
7260 }
7261 },
7262
7263 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
7264 ajaxTransport: addToPrefiltersOrTransports( transports ),
7265
7266 // Main method
7267 ajax: function( url, options ) {
7268
7269 // If url is an object, simulate pre-1.5 signature
7270 if ( typeof url === "object" ) {
7271 options = url;
7272 url = undefined;
7273 }
7274
7275 // Force options to be an object
7276 options = options || {};
7277
7278 var // Create the final options object
7279 s = jQuery.ajaxSetup( {}, options ),
7280 // Callbacks context
7281 callbackContext = s.context || s,
7282 // Context for global events
7283 // It's the callbackContext if one was provided in the options
7284 // and if it's a DOM node or a jQuery collection
7285 globalEventContext = callbackContext !== s &&
7286 ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
7287 jQuery( callbackContext ) : jQuery.event,
7288 // Deferreds
7289 deferred = jQuery.Deferred(),
7290 completeDeferred = jQuery.Callbacks( "once memory" ),
7291 // Status-dependent callbacks
7292 statusCode = s.statusCode || {},
7293 // ifModified key
7294 ifModifiedKey,
7295 // Headers (they are sent all at once)
7296 requestHeaders = {},
7297 requestHeadersNames = {},
7298 // Response headers
7299 responseHeadersString,
7300 responseHeaders,
7301 // transport
7302 transport,
7303 // timeout handle
7304 timeoutTimer,
7305 // Cross-domain detection vars
7306 parts,
7307 // The jqXHR state
7308 state = 0,
7309 // To know if global events are to be dispatched
7310 fireGlobals,
7311 // Loop variable
7312 i,
7313 // Fake xhr
7314 jqXHR = {
7315
7316 readyState: 0,
7317
7318 // Caches the header
7319 setRequestHeader: function( name, value ) {
7320 if ( !state ) {
7321 var lname = name.toLowerCase();
7322 name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
7323 requestHeaders[ name ] = value;
7324 }
7325 return this;
7326 },
7327
7328 // Raw string
7329 getAllResponseHeaders: function() {
7330 return state === 2 ? responseHeadersString : null;
7331 },
7332
7333 // Builds headers hashtable if needed
7334 getResponseHeader: function( key ) {
7335 var match;
7336 if ( state === 2 ) {
7337 if ( !responseHeaders ) {
7338 responseHeaders = {};
7339 while( ( match = rheaders.exec( responseHeadersString ) ) ) {
7340 responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
7341 }
7342 }
7343 match = responseHeaders[ key.toLowerCase() ];
7344 }
7345 return match === undefined ? null : match;
7346 },
7347
7348 // Overrides response content-type header
7349 overrideMimeType: function( type ) {
7350 if ( !state ) {
7351 s.mimeType = type;
7352 }
7353 return this;
7354 },
7355
7356 // Cancel the request
7357 abort: function( statusText ) {
7358 statusText = statusText || "abort";
7359 if ( transport ) {
7360 transport.abort( statusText );
7361 }
7362 done( 0, statusText );
7363 return this;
7364 }
7365 };
7366
7367 // Callback for when everything is done
7368 // It is defined here because jslint complains if it is declared
7369 // at the end of the function (which would be more logical and readable)
7370 function done( status, nativeStatusText, responses, headers ) {
7371
7372 // Called once
7373 if ( state === 2 ) {
7374 return;
7375 }
7376
7377 // State is "done" now
7378 state = 2;
7379
7380 // Clear timeout if it exists
7381 if ( timeoutTimer ) {
7382 clearTimeout( timeoutTimer );
7383 }
7384
7385 // Dereference transport for early garbage collection
7386 // (no matter how long the jqXHR object will be used)
7387 transport = undefined;
7388
7389 // Cache response headers
7390 responseHeadersString = headers || "";
7391
7392 // Set readyState
7393 jqXHR.readyState = status > 0 ? 4 : 0;
7394
7395 var isSuccess,
7396 success,
7397 error,
7398 statusText = nativeStatusText,
7399 response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
7400 lastModified,
7401 etag;
7402
7403 // If successful, handle type chaining
7404 if ( status >= 200 && status < 300 || status === 304 ) {
7405
7406 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7407 if ( s.ifModified ) {
7408
7409 if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {
7410 jQuery.lastModified[ ifModifiedKey ] = lastModified;
7411 }
7412 if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {
7413 jQuery.etag[ ifModifiedKey ] = etag;
7414 }
7415 }
7416
7417 // If not modified
7418 if ( status === 304 ) {
7419
7420 statusText = "notmodified";
7421 isSuccess = true;
7422
7423 // If we have data
7424 } else {
7425
7426 try {
7427 success = ajaxConvert( s, response );
7428 statusText = "success";
7429 isSuccess = true;
7430 } catch(e) {
7431 // We have a parsererror
7432 statusText = "parsererror";
7433 error = e;
7434 }
7435 }
7436 } else {
7437 // We extract error from statusText
7438 // then normalize statusText and status for non-aborts
7439 error = statusText;
7440 if ( !statusText || status ) {
7441 statusText = "error";
7442 if ( status < 0 ) {
7443 status = 0;
7444 }
7445 }
7446 }
7447
7448 // Set data for the fake xhr object
7449 jqXHR.status = status;
7450 jqXHR.statusText = "" + ( nativeStatusText || statusText );
7451
7452 // Success/Error
7453 if ( isSuccess ) {
7454 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
7455 } else {
7456 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
7457 }
7458
7459 // Status-dependent callbacks
7460 jqXHR.statusCode( statusCode );
7461 statusCode = undefined;
7462
7463 if ( fireGlobals ) {
7464 globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
7465 [ jqXHR, s, isSuccess ? success : error ] );
7466 }
7467
7468 // Complete
7469 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
7470
7471 if ( fireGlobals ) {
7472 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
7473 // Handle the global AJAX counter
7474 if ( !( --jQuery.active ) ) {
7475 jQuery.event.trigger( "ajaxStop" );
7476 }
7477 }
7478 }
7479
7480 // Attach deferreds
7481 deferred.promise( jqXHR );
7482 jqXHR.success = jqXHR.done;
7483 jqXHR.error = jqXHR.fail;
7484 jqXHR.complete = completeDeferred.add;
7485
7486 // Status-dependent callbacks
7487 jqXHR.statusCode = function( map ) {
7488 if ( map ) {
7489 var tmp;
7490 if ( state < 2 ) {
7491 for ( tmp in map ) {
7492 statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
7493 }
7494 } else {
7495 tmp = map[ jqXHR.status ];
7496 jqXHR.then( tmp, tmp );
7497 }
7498 }
7499 return this;
7500 };
7501
7502 // Remove hash character (#7531: and string promotion)
7503 // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
7504 // We also use the url parameter if available
7505 s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
7506
7507 // Extract dataTypes list
7508 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
7509
7510 // Determine if a cross-domain request is in order
7511 if ( s.crossDomain == null ) {
7512 parts = rurl.exec( s.url.toLowerCase() );
7513 s.crossDomain = !!( parts &&
7514 ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
7515 ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
7516 ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
7517 );
7518 }
7519
7520 // Convert data if not already a string
7521 if ( s.data && s.processData && typeof s.data !== "string" ) {
7522 s.data = jQuery.param( s.data, s.traditional );
7523 }
7524
7525 // Apply prefilters
7526 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
7527
7528 // If request was aborted inside a prefiler, stop there
7529 if ( state === 2 ) {
7530 return false;
7531 }
7532
7533 // We can fire global events as of now if asked to
7534 fireGlobals = s.global;
7535
7536 // Uppercase the type
7537 s.type = s.type.toUpperCase();
7538
7539 // Determine if request has content
7540 s.hasContent = !rnoContent.test( s.type );
7541
7542 // Watch for a new set of requests
7543 if ( fireGlobals && jQuery.active++ === 0 ) {
7544 jQuery.event.trigger( "ajaxStart" );
7545 }
7546
7547 // More options handling for requests with no content
7548 if ( !s.hasContent ) {
7549
7550 // If data is available, append data to url
7551 if ( s.data ) {
7552 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
7553 // #9682: remove data so that it's not used in an eventual retry
7554 delete s.data;
7555 }
7556
7557 // Get ifModifiedKey before adding the anti-cache parameter
7558 ifModifiedKey = s.url;
7559
7560 // Add anti-cache in url if needed
7561 if ( s.cache === false ) {
7562
7563 var ts = jQuery.now(),
7564 // try replacing _= if it is there
7565 ret = s.url.replace( rts, "$1_=" + ts );
7566
7567 // if nothing was replaced, add timestamp to the end
7568 s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
7569 }
7570 }
7571
7572 // Set the correct header, if data is being sent
7573 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
7574 jqXHR.setRequestHeader( "Content-Type", s.contentType );
7575 }
7576
7577 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7578 if ( s.ifModified ) {
7579 ifModifiedKey = ifModifiedKey || s.url;
7580 if ( jQuery.lastModified[ ifModifiedKey ] ) {
7581 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
7582 }
7583 if ( jQuery.etag[ ifModifiedKey ] ) {
7584 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
7585 }
7586 }
7587
7588 // Set the Accepts header for the server, depending on the dataType
7589 jqXHR.setRequestHeader(
7590 "Accept",
7591 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
7592 s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
7593 s.accepts[ "*" ]
7594 );
7595
7596 // Check for headers option
7597 for ( i in s.headers ) {
7598 jqXHR.setRequestHeader( i, s.headers[ i ] );
7599 }
7600
7601 // Allow custom headers/mimetypes and early abort
7602 if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
7603 // Abort if not done already
7604 jqXHR.abort();
7605 return false;
7606
7607 }
7608
7609 // Install callbacks on deferreds
7610 for ( i in { success: 1, error: 1, complete: 1 } ) {
7611 jqXHR[ i ]( s[ i ] );
7612 }
7613
7614 // Get transport
7615 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
7616
7617 // If no transport, we auto-abort
7618 if ( !transport ) {
7619 done( -1, "No Transport" );
7620 } else {
7621 jqXHR.readyState = 1;
7622 // Send global event
7623 if ( fireGlobals ) {
7624 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
7625 }
7626 // Timeout
7627 if ( s.async && s.timeout > 0 ) {
7628 timeoutTimer = setTimeout( function(){
7629 jqXHR.abort( "timeout" );
7630 }, s.timeout );
7631 }
7632
7633 try {
7634 state = 1;
7635 transport.send( requestHeaders, done );
7636 } catch (e) {
7637 // Propagate exception as error if not done
7638 if ( state < 2 ) {
7639 done( -1, e );
7640 // Simply rethrow otherwise
7641 } else {
7642 jQuery.error( e );
7643 }
7644 }
7645 }
7646
7647 return jqXHR;
7648 },
7649
7650 // Serialize an array of form elements or a set of
7651 // key/values into a query string
7652 param: function( a, traditional ) {
7653 var s = [],
7654 add = function( key, value ) {
7655 // If value is a function, invoke it and return its value
7656 value = jQuery.isFunction( value ) ? value() : value;
7657 s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
7658 };
7659
7660 // Set traditional to true for jQuery <= 1.3.2 behavior.
7661 if ( traditional === undefined ) {
7662 traditional = jQuery.ajaxSettings.traditional;
7663 }
7664
7665 // If an array was passed in, assume that it is an array of form elements.
7666 if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
7667 // Serialize the form elements
7668 jQuery.each( a, function() {
7669 add( this.name, this.value );
7670 });
7671
7672 } else {
7673 // If traditional, encode the "old" way (the way 1.3.2 or older
7674 // did it), otherwise encode params recursively.
7675 for ( var prefix in a ) {
7676 buildParams( prefix, a[ prefix ], traditional, add );
7677 }
7678 }
7679
7680 // Return the resulting serialization
7681 return s.join( "&" ).replace( r20, "+" );
7682 }
7683});
7684
7685function buildParams( prefix, obj, traditional, add ) {
7686 if ( jQuery.isArray( obj ) ) {
7687 // Serialize array item.
7688 jQuery.each( obj, function( i, v ) {
7689 if ( traditional || rbracket.test( prefix ) ) {
7690 // Treat each array item as a scalar.
7691 add( prefix, v );
7692
7693 } else {
7694 // If array item is non-scalar (array or object), encode its
7695 // numeric index to resolve deserialization ambiguity issues.
7696 // Note that rack (as of 1.0.0) can't currently deserialize
7697 // nested arrays properly, and attempting to do so may cause
7698 // a server error. Possible fixes are to modify rack's
7699 // deserialization algorithm or to provide an option or flag
7700 // to force array serialization to be shallow.
7701 buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
7702 }
7703 });
7704
7705 } else if ( !traditional && obj != null && typeof obj === "object" ) {
7706 // Serialize object item.
7707 for ( var name in obj ) {
7708 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
7709 }
7710
7711 } else {
7712 // Serialize scalar item.
7713 add( prefix, obj );
7714 }
7715}
7716
7717// This is still on the jQuery object... for now
7718// Want to move this to jQuery.ajax some day
7719jQuery.extend({
7720
7721 // Counter for holding the number of active queries
7722 active: 0,
7723
7724 // Last-Modified header cache for next request
7725 lastModified: {},
7726 etag: {}
7727
7728});
7729
7730/* Handles responses to an ajax request:
7731 * - sets all responseXXX fields accordingly
7732 * - finds the right dataType (mediates between content-type and expected dataType)
7733 * - returns the corresponding response
7734 */
7735function ajaxHandleResponses( s, jqXHR, responses ) {
7736
7737 var contents = s.contents,
7738 dataTypes = s.dataTypes,
7739 responseFields = s.responseFields,
7740 ct,
7741 type,
7742 finalDataType,
7743 firstDataType;
7744
7745 // Fill responseXXX fields
7746 for ( type in responseFields ) {
7747 if ( type in responses ) {
7748 jqXHR[ responseFields[type] ] = responses[ type ];
7749 }
7750 }
7751
7752 // Remove auto dataType and get content-type in the process
7753 while( dataTypes[ 0 ] === "*" ) {
7754 dataTypes.shift();
7755 if ( ct === undefined ) {
7756 ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
7757 }
7758 }
7759
7760 // Check if we're dealing with a known content-type
7761 if ( ct ) {
7762 for ( type in contents ) {
7763 if ( contents[ type ] && contents[ type ].test( ct ) ) {
7764 dataTypes.unshift( type );
7765 break;
7766 }
7767 }
7768 }
7769
7770 // Check to see if we have a response for the expected dataType
7771 if ( dataTypes[ 0 ] in responses ) {
7772 finalDataType = dataTypes[ 0 ];
7773 } else {
7774 // Try convertible dataTypes
7775 for ( type in responses ) {
7776 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
7777 finalDataType = type;
7778 break;
7779 }
7780 if ( !firstDataType ) {
7781 firstDataType = type;
7782 }
7783 }
7784 // Or just use first one
7785 finalDataType = finalDataType || firstDataType;
7786 }
7787
7788 // If we found a dataType
7789 // We add the dataType to the list if needed
7790 // and return the corresponding response
7791 if ( finalDataType ) {
7792 if ( finalDataType !== dataTypes[ 0 ] ) {
7793 dataTypes.unshift( finalDataType );
7794 }
7795 return responses[ finalDataType ];
7796 }
7797}
7798
7799// Chain conversions given the request and the original response
7800function ajaxConvert( s, response ) {
7801
7802 // Apply the dataFilter if provided
7803 if ( s.dataFilter ) {
7804 response = s.dataFilter( response, s.dataType );
7805 }
7806
7807 var dataTypes = s.dataTypes,
7808 converters = {},
7809 i,
7810 key,
7811 length = dataTypes.length,
7812 tmp,
7813 // Current and previous dataTypes
7814 current = dataTypes[ 0 ],
7815 prev,
7816 // Conversion expression
7817 conversion,
7818 // Conversion function
7819 conv,
7820 // Conversion functions (transitive conversion)
7821 conv1,
7822 conv2;
7823
7824 // For each dataType in the chain
7825 for ( i = 1; i < length; i++ ) {
7826
7827 // Create converters map
7828 // with lowercased keys
7829 if ( i === 1 ) {
7830 for ( key in s.converters ) {
7831 if ( typeof key === "string" ) {
7832 converters[ key.toLowerCase() ] = s.converters[ key ];
7833 }
7834 }
7835 }
7836
7837 // Get the dataTypes
7838 prev = current;
7839 current = dataTypes[ i ];
7840
7841 // If current is auto dataType, update it to prev
7842 if ( current === "*" ) {
7843 current = prev;
7844 // If no auto and dataTypes are actually different
7845 } else if ( prev !== "*" && prev !== current ) {
7846
7847 // Get the converter
7848 conversion = prev + " " + current;
7849 conv = converters[ conversion ] || converters[ "* " + current ];
7850
7851 // If there is no direct converter, search transitively
7852 if ( !conv ) {
7853 conv2 = undefined;
7854 for ( conv1 in converters ) {
7855 tmp = conv1.split( " " );
7856 if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {
7857 conv2 = converters[ tmp[1] + " " + current ];
7858 if ( conv2 ) {
7859 conv1 = converters[ conv1 ];
7860 if ( conv1 === true ) {
7861 conv = conv2;
7862 } else if ( conv2 === true ) {
7863 conv = conv1;
7864 }
7865 break;
7866 }
7867 }
7868 }
7869 }
7870 // If we found no converter, dispatch an error
7871 if ( !( conv || conv2 ) ) {
7872 jQuery.error( "No conversion from " + conversion.replace(" "," to ") );
7873 }
7874 // If found converter is not an equivalence
7875 if ( conv !== true ) {
7876 // Convert with 1 or 2 converters accordingly
7877 response = conv ? conv( response ) : conv2( conv1(response) );
7878 }
7879 }
7880 }
7881 return response;
7882}
7883
7884
7885
7886
7887var jsc = jQuery.now(),
7888 jsre = /(\=)\?(&|$)|\?\?/i;
7889
7890// Default jsonp settings
7891jQuery.ajaxSetup({
7892 jsonp: "callback",
7893 jsonpCallback: function() {
7894 return jQuery.expando + "_" + ( jsc++ );
7895 }
7896});
7897
7898// Detect, normalize options and install callbacks for jsonp requests
7899jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
7900
7901 var inspectData = s.contentType === "application/x-www-form-urlencoded" &&
7902 ( typeof s.data === "string" );
7903
7904 if ( s.dataTypes[ 0 ] === "jsonp" ||
7905 s.jsonp !== false && ( jsre.test( s.url ) ||
7906 inspectData && jsre.test( s.data ) ) ) {
7907
7908 var responseContainer,
7909 jsonpCallback = s.jsonpCallback =
7910 jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
7911 previous = window[ jsonpCallback ],
7912 url = s.url,
7913 data = s.data,
7914 replace = "$1" + jsonpCallback + "$2";
7915
7916 if ( s.jsonp !== false ) {
7917 url = url.replace( jsre, replace );
7918 if ( s.url === url ) {
7919 if ( inspectData ) {
7920 data = data.replace( jsre, replace );
7921 }
7922 if ( s.data === data ) {
7923 // Add callback manually
7924 url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
7925 }
7926 }
7927 }
7928
7929 s.url = url;
7930 s.data = data;
7931
7932 // Install callback
7933 window[ jsonpCallback ] = function( response ) {
7934 responseContainer = [ response ];
7935 };
7936
7937 // Clean-up function
7938 jqXHR.always(function() {
7939 // Set callback back to previous value
7940 window[ jsonpCallback ] = previous;
7941 // Call if it was a function and we have a response
7942 if ( responseContainer && jQuery.isFunction( previous ) ) {
7943 window[ jsonpCallback ]( responseContainer[ 0 ] );
7944 }
7945 });
7946
7947 // Use data converter to retrieve json after script execution
7948 s.converters["script json"] = function() {
7949 if ( !responseContainer ) {
7950 jQuery.error( jsonpCallback + " was not called" );
7951 }
7952 return responseContainer[ 0 ];
7953 };
7954
7955 // force json dataType
7956 s.dataTypes[ 0 ] = "json";
7957
7958 // Delegate to script
7959 return "script";
7960 }
7961});
7962
7963
7964
7965
7966// Install script dataType
7967jQuery.ajaxSetup({
7968 accepts: {
7969 script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
7970 },
7971 contents: {
7972 script: /javascript|ecmascript/
7973 },
7974 converters: {
7975 "text script": function( text ) {
7976 jQuery.globalEval( text );
7977 return text;
7978 }
7979 }
7980});
7981
7982// Handle cache's special case and global
7983jQuery.ajaxPrefilter( "script", function( s ) {
7984 if ( s.cache === undefined ) {
7985 s.cache = false;
7986 }
7987 if ( s.crossDomain ) {
7988 s.type = "GET";
7989 s.global = false;
7990 }
7991});
7992
7993// Bind script tag hack transport
7994jQuery.ajaxTransport( "script", function(s) {
7995
7996 // This transport only deals with cross domain requests
7997 if ( s.crossDomain ) {
7998
7999 var script,
8000 head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
8001
8002 return {
8003
8004 send: function( _, callback ) {
8005
8006 script = document.createElement( "script" );
8007
8008 script.async = "async";
8009
8010 if ( s.scriptCharset ) {
8011 script.charset = s.scriptCharset;
8012 }
8013
8014 script.src = s.url;
8015
8016 // Attach handlers for all browsers
8017 script.onload = script.onreadystatechange = function( _, isAbort ) {
8018
8019 if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
8020
8021 // Handle memory leak in IE
8022 script.onload = script.onreadystatechange = null;
8023
8024 // Remove the script
8025 if ( head && script.parentNode ) {
8026 head.removeChild( script );
8027 }
8028
8029 // Dereference the script
8030 script = undefined;
8031
8032 // Callback if not abort
8033 if ( !isAbort ) {
8034 callback( 200, "success" );
8035 }
8036 }
8037 };
8038 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
8039 // This arises when a base node is used (#2709 and #4378).
8040 head.insertBefore( script, head.firstChild );
8041 },
8042
8043 abort: function() {
8044 if ( script ) {
8045 script.onload( 0, 1 );
8046 }
8047 }
8048 };
8049 }
8050});
8051
8052
8053
8054
8055var // #5280: Internet Explorer will keep connections alive if we don't abort on unload
8056 xhrOnUnloadAbort = window.ActiveXObject ? function() {
8057 // Abort all pending requests
8058 for ( var key in xhrCallbacks ) {
8059 xhrCallbacks[ key ]( 0, 1 );
8060 }
8061 } : false,
8062 xhrId = 0,
8063 xhrCallbacks;
8064
8065// Functions to create xhrs
8066function createStandardXHR() {
8067 try {
8068 return new window.XMLHttpRequest();
8069 } catch( e ) {}
8070}
8071
8072function createActiveXHR() {
8073 try {
8074 return new window.ActiveXObject( "Microsoft.XMLHTTP" );
8075 } catch( e ) {}
8076}
8077
8078// Create the request object
8079// (This is still attached to ajaxSettings for backward compatibility)
8080jQuery.ajaxSettings.xhr = window.ActiveXObject ?
8081 /* Microsoft failed to properly
8082 * implement the XMLHttpRequest in IE7 (can't request local files),
8083 * so we use the ActiveXObject when it is available
8084 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
8085 * we need a fallback.
8086 */
8087 function() {
8088 return !this.isLocal && createStandardXHR() || createActiveXHR();
8089 } :
8090 // For all other browsers, use the standard XMLHttpRequest object
8091 createStandardXHR;
8092
8093// Determine support properties
8094(function( xhr ) {
8095 jQuery.extend( jQuery.support, {
8096 ajax: !!xhr,
8097 cors: !!xhr && ( "withCredentials" in xhr )
8098 });
8099})( jQuery.ajaxSettings.xhr() );
8100
8101// Create transport if the browser can provide an xhr
8102if ( jQuery.support.ajax ) {
8103
8104 jQuery.ajaxTransport(function( s ) {
8105 // Cross domain only allowed if supported through XMLHttpRequest
8106 if ( !s.crossDomain || jQuery.support.cors ) {
8107
8108 var callback;
8109
8110 return {
8111 send: function( headers, complete ) {
8112
8113 // Get a new xhr
8114 var xhr = s.xhr(),
8115 handle,
8116 i;
8117
8118 // Open the socket
8119 // Passing null username, generates a login popup on Opera (#2865)
8120 if ( s.username ) {
8121 xhr.open( s.type, s.url, s.async, s.username, s.password );
8122 } else {
8123 xhr.open( s.type, s.url, s.async );
8124 }
8125
8126 // Apply custom fields if provided
8127 if ( s.xhrFields ) {
8128 for ( i in s.xhrFields ) {
8129 xhr[ i ] = s.xhrFields[ i ];
8130 }
8131 }
8132
8133 // Override mime type if needed
8134 if ( s.mimeType && xhr.overrideMimeType ) {
8135 xhr.overrideMimeType( s.mimeType );
8136 }
8137
8138 // X-Requested-With header
8139 // For cross-domain requests, seeing as conditions for a preflight are
8140 // akin to a jigsaw puzzle, we simply never set it to be sure.
8141 // (it can always be set on a per-request basis or even using ajaxSetup)
8142 // For same-domain requests, won't change header if already provided.
8143 if ( !s.crossDomain && !headers["X-Requested-With"] ) {
8144 headers[ "X-Requested-With" ] = "XMLHttpRequest";
8145 }
8146
8147 // Need an extra try/catch for cross domain requests in Firefox 3
8148 try {
8149 for ( i in headers ) {
8150 xhr.setRequestHeader( i, headers[ i ] );
8151 }
8152 } catch( _ ) {}
8153
8154 // Do send the request
8155 // This may raise an exception which is actually
8156 // handled in jQuery.ajax (so no try/catch here)
8157 xhr.send( ( s.hasContent && s.data ) || null );
8158
8159 // Listener
8160 callback = function( _, isAbort ) {
8161
8162 var status,
8163 statusText,
8164 responseHeaders,
8165 responses,
8166 xml;
8167
8168 // Firefox throws exceptions when accessing properties
8169 // of an xhr when a network error occured
8170 // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
8171 try {
8172
8173 // Was never called and is aborted or complete
8174 if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
8175
8176 // Only called once
8177 callback = undefined;
8178
8179 // Do not keep as active anymore
8180 if ( handle ) {
8181 xhr.onreadystatechange = jQuery.noop;
8182 if ( xhrOnUnloadAbort ) {
8183 delete xhrCallbacks[ handle ];
8184 }
8185 }
8186
8187 // If it's an abort
8188 if ( isAbort ) {
8189 // Abort it manually if needed
8190 if ( xhr.readyState !== 4 ) {
8191 xhr.abort();
8192 }
8193 } else {
8194 status = xhr.status;
8195 responseHeaders = xhr.getAllResponseHeaders();
8196 responses = {};
8197 xml = xhr.responseXML;
8198
8199 // Construct response list
8200 if ( xml && xml.documentElement /* #4958 */ ) {
8201 responses.xml = xml;
8202 }
8203 responses.text = xhr.responseText;
8204
8205 // Firefox throws an exception when accessing
8206 // statusText for faulty cross-domain requests
8207 try {
8208 statusText = xhr.statusText;
8209 } catch( e ) {
8210 // We normalize with Webkit giving an empty statusText
8211 statusText = "";
8212 }
8213
8214 // Filter status for non standard behaviors
8215
8216 // If the request is local and we have data: assume a success
8217 // (success with no data won't get notified, that's the best we
8218 // can do given current implementations)
8219 if ( !status && s.isLocal && !s.crossDomain ) {
8220 status = responses.text ? 200 : 404;
8221 // IE - #1450: sometimes returns 1223 when it should be 204
8222 } else if ( status === 1223 ) {
8223 status = 204;
8224 }
8225 }
8226 }
8227 } catch( firefoxAccessException ) {
8228 if ( !isAbort ) {
8229 complete( -1, firefoxAccessException );
8230 }
8231 }
8232
8233 // Call complete if needed
8234 if ( responses ) {
8235 complete( status, statusText, responses, responseHeaders );
8236 }
8237 };
8238
8239 // if we're in sync mode or it's in cache
8240 // and has been retrieved directly (IE6 & IE7)
8241 // we need to manually fire the callback
8242 if ( !s.async || xhr.readyState === 4 ) {
8243 callback();
8244 } else {
8245 handle = ++xhrId;
8246 if ( xhrOnUnloadAbort ) {
8247 // Create the active xhrs callbacks list if needed
8248 // and attach the unload handler
8249 if ( !xhrCallbacks ) {
8250 xhrCallbacks = {};
8251 jQuery( window ).unload( xhrOnUnloadAbort );
8252 }
8253 // Add to list of active xhrs callbacks
8254 xhrCallbacks[ handle ] = callback;
8255 }
8256 xhr.onreadystatechange = callback;
8257 }
8258 },
8259
8260 abort: function() {
8261 if ( callback ) {
8262 callback(0,1);
8263 }
8264 }
8265 };
8266 }
8267 });
8268}
8269
8270
8271
8272
8273var elemdisplay = {},
8274 iframe, iframeDoc,
8275 rfxtypes = /^(?:toggle|show|hide)$/,
8276 rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
8277 timerId,
8278 fxAttrs = [
8279 // height animations
8280 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
8281 // width animations
8282 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
8283 // opacity animations
8284 [ "opacity" ]
8285 ],
8286 fxNow;
8287
8288jQuery.fn.extend({
8289 show: function( speed, easing, callback ) {
8290 var elem, display;
8291
8292 if ( speed || speed === 0 ) {
8293 return this.animate( genFx("show", 3), speed, easing, callback );
8294
8295 } else {
8296 for ( var i = 0, j = this.length; i < j; i++ ) {
8297 elem = this[ i ];
8298
8299 if ( elem.style ) {
8300 display = elem.style.display;
8301
8302 // Reset the inline display of this element to learn if it is
8303 // being hidden by cascaded rules or not
8304 if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
8305 display = elem.style.display = "";
8306 }
8307
8308 // Set elements which have been overridden with display: none
8309 // in a stylesheet to whatever the default browser style is
8310 // for such an element
8311 if ( display === "" && jQuery.css(elem, "display") === "none" ) {
8312 jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) );
8313 }
8314 }
8315 }
8316
8317 // Set the display of most of the elements in a second loop
8318 // to avoid the constant reflow
8319 for ( i = 0; i < j; i++ ) {
8320 elem = this[ i ];
8321
8322 if ( elem.style ) {
8323 display = elem.style.display;
8324
8325 if ( display === "" || display === "none" ) {
8326 elem.style.display = jQuery._data( elem, "olddisplay" ) || "";
8327 }
8328 }
8329 }
8330
8331 return this;
8332 }
8333 },
8334
8335 hide: function( speed, easing, callback ) {
8336 if ( speed || speed === 0 ) {
8337 return this.animate( genFx("hide", 3), speed, easing, callback);
8338
8339 } else {
8340 var elem, display,
8341 i = 0,
8342 j = this.length;
8343
8344 for ( ; i < j; i++ ) {
8345 elem = this[i];
8346 if ( elem.style ) {
8347 display = jQuery.css( elem, "display" );
8348
8349 if ( display !== "none" && !jQuery._data( elem, "olddisplay" ) ) {
8350 jQuery._data( elem, "olddisplay", display );
8351 }
8352 }
8353 }
8354
8355 // Set the display of the elements in a second loop
8356 // to avoid the constant reflow
8357 for ( i = 0; i < j; i++ ) {
8358 if ( this[i].style ) {
8359 this[i].style.display = "none";
8360 }
8361 }
8362
8363 return this;
8364 }
8365 },
8366
8367 // Save the old toggle function
8368 _toggle: jQuery.fn.toggle,
8369
8370 toggle: function( fn, fn2, callback ) {
8371 var bool = typeof fn === "boolean";
8372
8373 if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
8374 this._toggle.apply( this, arguments );
8375
8376 } else if ( fn == null || bool ) {
8377 this.each(function() {
8378 var state = bool ? fn : jQuery(this).is(":hidden");
8379 jQuery(this)[ state ? "show" : "hide" ]();
8380 });
8381
8382 } else {
8383 this.animate(genFx("toggle", 3), fn, fn2, callback);
8384 }
8385
8386 return this;
8387 },
8388
8389 fadeTo: function( speed, to, easing, callback ) {
8390 return this.filter(":hidden").css("opacity", 0).show().end()
8391 .animate({opacity: to}, speed, easing, callback);
8392 },
8393
8394 animate: function( prop, speed, easing, callback ) {
8395 var optall = jQuery.speed( speed, easing, callback );
8396
8397 if ( jQuery.isEmptyObject( prop ) ) {
8398 return this.each( optall.complete, [ false ] );
8399 }
8400
8401 // Do not change referenced properties as per-property easing will be lost
8402 prop = jQuery.extend( {}, prop );
8403
8404 function doAnimation() {
8405 // XXX 'this' does not always have a nodeName when running the
8406 // test suite
8407
8408 if ( optall.queue === false ) {
8409 jQuery._mark( this );
8410 }
8411
8412 var opt = jQuery.extend( {}, optall ),
8413 isElement = this.nodeType === 1,
8414 hidden = isElement && jQuery(this).is(":hidden"),
8415 name, val, p, e,
8416 parts, start, end, unit,
8417 method;
8418
8419 // will store per property easing and be used to determine when an animation is complete
8420 opt.animatedProperties = {};
8421
8422 for ( p in prop ) {
8423
8424 // property name normalization
8425 name = jQuery.camelCase( p );
8426 if ( p !== name ) {
8427 prop[ name ] = prop[ p ];
8428 delete prop[ p ];
8429 }
8430
8431 val = prop[ name ];
8432
8433 // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
8434 if ( jQuery.isArray( val ) ) {
8435 opt.animatedProperties[ name ] = val[ 1 ];
8436 val = prop[ name ] = val[ 0 ];
8437 } else {
8438 opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';
8439 }
8440
8441 if ( val === "hide" && hidden || val === "show" && !hidden ) {
8442 return opt.complete.call( this );
8443 }
8444
8445 if ( isElement && ( name === "height" || name === "width" ) ) {
8446 // Make sure that nothing sneaks out
8447 // Record all 3 overflow attributes because IE does not
8448 // change the overflow attribute when overflowX and
8449 // overflowY are set to the same value
8450 opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
8451
8452 // Set display property to inline-block for height/width
8453 // animations on inline elements that are having width/height animated
8454 if ( jQuery.css( this, "display" ) === "inline" &&
8455 jQuery.css( this, "float" ) === "none" ) {
8456
8457 // inline-level elements accept inline-block;
8458 // block-level elements need to be inline with layout
8459 if ( !jQuery.support.inlineBlockNeedsLayout || defaultDisplay( this.nodeName ) === "inline" ) {
8460 this.style.display = "inline-block";
8461
8462 } else {
8463 this.style.zoom = 1;
8464 }
8465 }
8466 }
8467 }
8468
8469 if ( opt.overflow != null ) {
8470 this.style.overflow = "hidden";
8471 }
8472
8473 for ( p in prop ) {
8474 e = new jQuery.fx( this, opt, p );
8475 val = prop[ p ];
8476
8477 if ( rfxtypes.test( val ) ) {
8478
8479 // Tracks whether to show or hide based on private
8480 // data attached to the element
8481 method = jQuery._data( this, "toggle" + p ) || ( val === "toggle" ? hidden ? "show" : "hide" : 0 );
8482 if ( method ) {
8483 jQuery._data( this, "toggle" + p, method === "show" ? "hide" : "show" );
8484 e[ method ]();
8485 } else {
8486 e[ val ]();
8487 }
8488
8489 } else {
8490 parts = rfxnum.exec( val );
8491 start = e.cur();
8492
8493 if ( parts ) {
8494 end = parseFloat( parts[2] );
8495 unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );
8496
8497 // We need to compute starting value
8498 if ( unit !== "px" ) {
8499 jQuery.style( this, p, (end || 1) + unit);
8500 start = ( (end || 1) / e.cur() ) * start;
8501 jQuery.style( this, p, start + unit);
8502 }
8503
8504 // If a +=/-= token was provided, we're doing a relative animation
8505 if ( parts[1] ) {
8506 end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start;
8507 }
8508
8509 e.custom( start, end, unit );
8510
8511 } else {
8512 e.custom( start, val, "" );
8513 }
8514 }
8515 }
8516
8517 // For JS strict compliance
8518 return true;
8519 }
8520
8521 return optall.queue === false ?
8522 this.each( doAnimation ) :
8523 this.queue( optall.queue, doAnimation );
8524 },
8525
8526 stop: function( type, clearQueue, gotoEnd ) {
8527 if ( typeof type !== "string" ) {
8528 gotoEnd = clearQueue;
8529 clearQueue = type;
8530 type = undefined;
8531 }
8532 if ( clearQueue && type !== false ) {
8533 this.queue( type || "fx", [] );
8534 }
8535
8536 return this.each(function() {
8537 var i,
8538 hadTimers = false,
8539 timers = jQuery.timers,
8540 data = jQuery._data( this );
8541
8542 // clear marker counters if we know they won't be
8543 if ( !gotoEnd ) {
8544 jQuery._unmark( true, this );
8545 }
8546
8547 function stopQueue( elem, data, i ) {
8548 var hooks = data[ i ];
8549 jQuery.removeData( elem, i, true );
8550 hooks.stop( gotoEnd );
8551 }
8552
8553 if ( type == null ) {
8554 for ( i in data ) {
8555 if ( data[ i ].stop && i.indexOf(".run") === i.length - 4 ) {
8556 stopQueue( this, data, i );
8557 }
8558 }
8559 } else if ( data[ i = type + ".run" ] && data[ i ].stop ){
8560 stopQueue( this, data, i );
8561 }
8562
8563 for ( i = timers.length; i--; ) {
8564 if ( timers[ i ].elem === this && (type == null || timers[ i ].queue === type) ) {
8565 if ( gotoEnd ) {
8566
8567 // force the next step to be the last
8568 timers[ i ]( true );
8569 } else {
8570 timers[ i ].saveState();
8571 }
8572 hadTimers = true;
8573 timers.splice( i, 1 );
8574 }
8575 }
8576
8577 // start the next in the queue if the last step wasn't forced
8578 // timers currently will call their complete callbacks, which will dequeue
8579 // but only if they were gotoEnd
8580 if ( !( gotoEnd && hadTimers ) ) {
8581 jQuery.dequeue( this, type );
8582 }
8583 });
8584 }
8585
8586});
8587
8588// Animations created synchronously will run synchronously
8589function createFxNow() {
8590 setTimeout( clearFxNow, 0 );
8591 return ( fxNow = jQuery.now() );
8592}
8593
8594function clearFxNow() {
8595 fxNow = undefined;
8596}
8597
8598// Generate parameters to create a standard animation
8599function genFx( type, num ) {
8600 var obj = {};
8601
8602 jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice( 0, num )), function() {
8603 obj[ this ] = type;
8604 });
8605
8606 return obj;
8607}
8608
8609// Generate shortcuts for custom animations
8610jQuery.each({
8611 slideDown: genFx( "show", 1 ),
8612 slideUp: genFx( "hide", 1 ),
8613 slideToggle: genFx( "toggle", 1 ),
8614 fadeIn: { opacity: "show" },
8615 fadeOut: { opacity: "hide" },
8616 fadeToggle: { opacity: "toggle" }
8617}, function( name, props ) {
8618 jQuery.fn[ name ] = function( speed, easing, callback ) {
8619 return this.animate( props, speed, easing, callback );
8620 };
8621});
8622
8623jQuery.extend({
8624 speed: function( speed, easing, fn ) {
8625 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
8626 complete: fn || !fn && easing ||
8627 jQuery.isFunction( speed ) && speed,
8628 duration: speed,
8629 easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
8630 };
8631
8632 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
8633 opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
8634
8635 // normalize opt.queue - true/undefined/null -> "fx"
8636 if ( opt.queue == null || opt.queue === true ) {
8637 opt.queue = "fx";
8638 }
8639
8640 // Queueing
8641 opt.old = opt.complete;
8642
8643 opt.complete = function( noUnmark ) {
8644 if ( jQuery.isFunction( opt.old ) ) {
8645 opt.old.call( this );
8646 }
8647
8648 if ( opt.queue ) {
8649 jQuery.dequeue( this, opt.queue );
8650 } else if ( noUnmark !== false ) {
8651 jQuery._unmark( this );
8652 }
8653 };
8654
8655 return opt;
8656 },
8657
8658 easing: {
8659 linear: function( p, n, firstNum, diff ) {
8660 return firstNum + diff * p;
8661 },
8662 swing: function( p, n, firstNum, diff ) {
8663 return ( ( -Math.cos( p*Math.PI ) / 2 ) + 0.5 ) * diff + firstNum;
8664 }
8665 },
8666
8667 timers: [],
8668
8669 fx: function( elem, options, prop ) {
8670 this.options = options;
8671 this.elem = elem;
8672 this.prop = prop;
8673
8674 options.orig = options.orig || {};
8675 }
8676
8677});
8678
8679jQuery.fx.prototype = {
8680 // Simple function for setting a style value
8681 update: function() {
8682 if ( this.options.step ) {
8683 this.options.step.call( this.elem, this.now, this );
8684 }
8685
8686 ( jQuery.fx.step[ this.prop ] || jQuery.fx.step._default )( this );
8687 },
8688
8689 // Get the current size
8690 cur: function() {
8691 if ( this.elem[ this.prop ] != null && (!this.elem.style || this.elem.style[ this.prop ] == null) ) {
8692 return this.elem[ this.prop ];
8693 }
8694
8695 var parsed,
8696 r = jQuery.css( this.elem, this.prop );
8697 // Empty strings, null, undefined and "auto" are converted to 0,
8698 // complex values such as "rotate(1rad)" are returned as is,
8699 // simple values such as "10px" are parsed to Float.
8700 return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;
8701 },
8702
8703 // Start an animation from one number to another
8704 custom: function( from, to, unit ) {
8705 var self = this,
8706 fx = jQuery.fx;
8707
8708 this.startTime = fxNow || createFxNow();
8709 this.end = to;
8710 this.now = this.start = from;
8711 this.pos = this.state = 0;
8712 this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
8713
8714 function t( gotoEnd ) {
8715 return self.step( gotoEnd );
8716 }
8717
8718 t.queue = this.options.queue;
8719 t.elem = this.elem;
8720 t.saveState = function() {
8721 if ( self.options.hide && jQuery._data( self.elem, "fxshow" + self.prop ) === undefined ) {
8722 jQuery._data( self.elem, "fxshow" + self.prop, self.start );
8723 }
8724 };
8725
8726 if ( t() && jQuery.timers.push(t) && !timerId ) {
8727 timerId = setInterval( fx.tick, fx.interval );
8728 }
8729 },
8730
8731 // Simple 'show' function
8732 show: function() {
8733 var dataShow = jQuery._data( this.elem, "fxshow" + this.prop );
8734
8735 // Remember where we started, so that we can go back to it later
8736 this.options.orig[ this.prop ] = dataShow || jQuery.style( this.elem, this.prop );
8737 this.options.show = true;
8738
8739 // Begin the animation
8740 // Make sure that we start at a small width/height to avoid any flash of content
8741 if ( dataShow !== undefined ) {
8742 // This show is picking up where a previous hide or show left off
8743 this.custom( this.cur(), dataShow );
8744 } else {
8745 this.custom( this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur() );
8746 }
8747
8748 // Start by showing the element
8749 jQuery( this.elem ).show();
8750 },
8751
8752 // Simple 'hide' function
8753 hide: function() {
8754 // Remember where we started, so that we can go back to it later
8755 this.options.orig[ this.prop ] = jQuery._data( this.elem, "fxshow" + this.prop ) || jQuery.style( this.elem, this.prop );
8756 this.options.hide = true;
8757
8758 // Begin the animation
8759 this.custom( this.cur(), 0 );
8760 },
8761
8762 // Each step of an animation
8763 step: function( gotoEnd ) {
8764 var p, n, complete,
8765 t = fxNow || createFxNow(),
8766 done = true,
8767 elem = this.elem,
8768 options = this.options;
8769
8770 if ( gotoEnd || t >= options.duration + this.startTime ) {
8771 this.now = this.end;
8772 this.pos = this.state = 1;
8773 this.update();
8774
8775 options.animatedProperties[ this.prop ] = true;
8776
8777 for ( p in options.animatedProperties ) {
8778 if ( options.animatedProperties[ p ] !== true ) {
8779 done = false;
8780 }
8781 }
8782
8783 if ( done ) {
8784 // Reset the overflow
8785 if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
8786
8787 jQuery.each( [ "", "X", "Y" ], function( index, value ) {
8788 elem.style[ "overflow" + value ] = options.overflow[ index ];
8789 });
8790 }
8791
8792 // Hide the element if the "hide" operation was done
8793 if ( options.hide ) {
8794 jQuery( elem ).hide();
8795 }
8796
8797 // Reset the properties, if the item has been hidden or shown
8798 if ( options.hide || options.show ) {
8799 for ( p in options.animatedProperties ) {
8800 jQuery.style( elem, p, options.orig[ p ] );
8801 jQuery.removeData( elem, "fxshow" + p, true );
8802 // Toggle data is no longer needed
8803 jQuery.removeData( elem, "toggle" + p, true );
8804 }
8805 }
8806
8807 // Execute the complete function
8808 // in the event that the complete function throws an exception
8809 // we must ensure it won't be called twice. #5684
8810
8811 complete = options.complete;
8812 if ( complete ) {
8813
8814 options.complete = false;
8815 complete.call( elem );
8816 }
8817 }
8818
8819 return false;
8820
8821 } else {
8822 // classical easing cannot be used with an Infinity duration
8823 if ( options.duration == Infinity ) {
8824 this.now = t;
8825 } else {
8826 n = t - this.startTime;
8827 this.state = n / options.duration;
8828
8829 // Perform the easing function, defaults to swing
8830 this.pos = jQuery.easing[ options.animatedProperties[this.prop] ]( this.state, n, 0, 1, options.duration );
8831 this.now = this.start + ( (this.end - this.start) * this.pos );
8832 }
8833 // Perform the next step of the animation
8834 this.update();
8835 }
8836
8837 return true;
8838 }
8839};
8840
8841jQuery.extend( jQuery.fx, {
8842 tick: function() {
8843 var timer,
8844 timers = jQuery.timers,
8845 i = 0;
8846
8847 for ( ; i < timers.length; i++ ) {
8848 timer = timers[ i ];
8849 // Checks the timer has not already been removed
8850 if ( !timer() && timers[ i ] === timer ) {
8851 timers.splice( i--, 1 );
8852 }
8853 }
8854
8855 if ( !timers.length ) {
8856 jQuery.fx.stop();
8857 }
8858 },
8859
8860 interval: 13,
8861
8862 stop: function() {
8863 clearInterval( timerId );
8864 timerId = null;
8865 },
8866
8867 speeds: {
8868 slow: 600,
8869 fast: 200,
8870 // Default speed
8871 _default: 400
8872 },
8873
8874 step: {
8875 opacity: function( fx ) {
8876 jQuery.style( fx.elem, "opacity", fx.now );
8877 },
8878
8879 _default: function( fx ) {
8880 if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
8881 fx.elem.style[ fx.prop ] = fx.now + fx.unit;
8882 } else {
8883 fx.elem[ fx.prop ] = fx.now;
8884 }
8885 }
8886 }
8887});
8888
8889// Adds width/height step functions
8890// Do not set anything below 0
8891jQuery.each([ "width", "height" ], function( i, prop ) {
8892 jQuery.fx.step[ prop ] = function( fx ) {
8893 jQuery.style( fx.elem, prop, Math.max(0, fx.now) );
8894 };
8895});
8896
8897if ( jQuery.expr && jQuery.expr.filters ) {
8898 jQuery.expr.filters.animated = function( elem ) {
8899 return jQuery.grep(jQuery.timers, function( fn ) {
8900 return elem === fn.elem;
8901 }).length;
8902 };
8903}
8904
8905// Try to restore the default display value of an element
8906function defaultDisplay( nodeName ) {
8907
8908 if ( !elemdisplay[ nodeName ] ) {
8909
8910 var body = document.body,
8911 elem = jQuery( "<" + nodeName + ">" ).appendTo( body ),
8912 display = elem.css( "display" );
8913 elem.remove();
8914
8915 // If the simple way fails,
8916 // get element's real default display by attaching it to a temp iframe
8917 if ( display === "none" || display === "" ) {
8918 // No iframe to use yet, so create it
8919 if ( !iframe ) {
8920 iframe = document.createElement( "iframe" );
8921 iframe.frameBorder = iframe.width = iframe.height = 0;
8922 }
8923
8924 body.appendChild( iframe );
8925
8926 // Create a cacheable copy of the iframe document on first call.
8927 // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML
8928 // document to it; WebKit & Firefox won't allow reusing the iframe document.
8929 if ( !iframeDoc || !iframe.createElement ) {
8930 iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
8931 iframeDoc.write( ( document.compatMode === "CSS1Compat" ? "<!doctype html>" : "" ) + "<html><body>" );
8932 iframeDoc.close();
8933 }
8934
8935 elem = iframeDoc.createElement( nodeName );
8936
8937 iframeDoc.body.appendChild( elem );
8938
8939 display = jQuery.css( elem, "display" );
8940 body.removeChild( iframe );
8941 }
8942
8943 // Store the correct default display
8944 elemdisplay[ nodeName ] = display;
8945 }
8946
8947 return elemdisplay[ nodeName ];
8948}
8949
8950
8951
8952
8953var rtable = /^t(?:able|d|h)$/i,
8954 rroot = /^(?:body|html)$/i;
8955
8956if ( "getBoundingClientRect" in document.documentElement ) {
8957 jQuery.fn.offset = function( options ) {
8958 var elem = this[0], box;
8959
8960 if ( options ) {
8961 return this.each(function( i ) {
8962 jQuery.offset.setOffset( this, options, i );
8963 });
8964 }
8965
8966 if ( !elem || !elem.ownerDocument ) {
8967 return null;
8968 }
8969
8970 if ( elem === elem.ownerDocument.body ) {
8971 return jQuery.offset.bodyOffset( elem );
8972 }
8973
8974 try {
8975 box = elem.getBoundingClientRect();
8976 } catch(e) {}
8977
8978 var doc = elem.ownerDocument,
8979 docElem = doc.documentElement;
8980
8981 // Make sure we're not dealing with a disconnected DOM node
8982 if ( !box || !jQuery.contains( docElem, elem ) ) {
8983 return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
8984 }
8985
8986 var body = doc.body,
8987 win = getWindow(doc),
8988 clientTop = docElem.clientTop || body.clientTop || 0,
8989 clientLeft = docElem.clientLeft || body.clientLeft || 0,
8990 scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop,
8991 scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
8992 top = box.top + scrollTop - clientTop,
8993 left = box.left + scrollLeft - clientLeft;
8994
8995 return { top: top, left: left };
8996 };
8997
8998} else {
8999 jQuery.fn.offset = function( options ) {
9000 var elem = this[0];
9001
9002 if ( options ) {
9003 return this.each(function( i ) {
9004 jQuery.offset.setOffset( this, options, i );
9005 });
9006 }
9007
9008 if ( !elem || !elem.ownerDocument ) {
9009 return null;
9010 }
9011
9012 if ( elem === elem.ownerDocument.body ) {
9013 return jQuery.offset.bodyOffset( elem );
9014 }
9015
9016 var computedStyle,
9017 offsetParent = elem.offsetParent,
9018 prevOffsetParent = elem,
9019 doc = elem.ownerDocument,
9020 docElem = doc.documentElement,
9021 body = doc.body,
9022 defaultView = doc.defaultView,
9023 prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
9024 top = elem.offsetTop,
9025 left = elem.offsetLeft;
9026
9027 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
9028 if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) {
9029 break;
9030 }
9031
9032 computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
9033 top -= elem.scrollTop;
9034 left -= elem.scrollLeft;
9035
9036 if ( elem === offsetParent ) {
9037 top += elem.offsetTop;
9038 left += elem.offsetLeft;
9039
9040 if ( jQuery.support.doesNotAddBorder && !(jQuery.support.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
9041 top += parseFloat( computedStyle.borderTopWidth ) || 0;
9042 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
9043 }
9044
9045 prevOffsetParent = offsetParent;
9046 offsetParent = elem.offsetParent;
9047 }
9048
9049 if ( jQuery.support.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
9050 top += parseFloat( computedStyle.borderTopWidth ) || 0;
9051 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
9052 }
9053
9054 prevComputedStyle = computedStyle;
9055 }
9056
9057 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
9058 top += body.offsetTop;
9059 left += body.offsetLeft;
9060 }
9061
9062 if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) {
9063 top += Math.max( docElem.scrollTop, body.scrollTop );
9064 left += Math.max( docElem.scrollLeft, body.scrollLeft );
9065 }
9066
9067 return { top: top, left: left };
9068 };
9069}
9070
9071jQuery.offset = {
9072
9073 bodyOffset: function( body ) {
9074 var top = body.offsetTop,
9075 left = body.offsetLeft;
9076
9077 if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) {
9078 top += parseFloat( jQuery.css(body, "marginTop") ) || 0;
9079 left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
9080 }
9081
9082 return { top: top, left: left };
9083 },
9084
9085 setOffset: function( elem, options, i ) {
9086 var position = jQuery.css( elem, "position" );
9087
9088 // set position first, in-case top/left are set even on static elem
9089 if ( position === "static" ) {
9090 elem.style.position = "relative";
9091 }
9092
9093 var curElem = jQuery( elem ),
9094 curOffset = curElem.offset(),
9095 curCSSTop = jQuery.css( elem, "top" ),
9096 curCSSLeft = jQuery.css( elem, "left" ),
9097 calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
9098 props = {}, curPosition = {}, curTop, curLeft;
9099
9100 // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
9101 if ( calculatePosition ) {
9102 curPosition = curElem.position();
9103 curTop = curPosition.top;
9104 curLeft = curPosition.left;
9105 } else {
9106 curTop = parseFloat( curCSSTop ) || 0;
9107 curLeft = parseFloat( curCSSLeft ) || 0;
9108 }
9109
9110 if ( jQuery.isFunction( options ) ) {
9111 options = options.call( elem, i, curOffset );
9112 }
9113
9114 if ( options.top != null ) {
9115 props.top = ( options.top - curOffset.top ) + curTop;
9116 }
9117 if ( options.left != null ) {
9118 props.left = ( options.left - curOffset.left ) + curLeft;
9119 }
9120
9121 if ( "using" in options ) {
9122 options.using.call( elem, props );
9123 } else {
9124 curElem.css( props );
9125 }
9126 }
9127};
9128
9129
9130jQuery.fn.extend({
9131
9132 position: function() {
9133 if ( !this[0] ) {
9134 return null;
9135 }
9136
9137 var elem = this[0],
9138
9139 // Get *real* offsetParent
9140 offsetParent = this.offsetParent(),
9141
9142 // Get correct offsets
9143 offset = this.offset(),
9144 parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
9145
9146 // Subtract element margins
9147 // note: when an element has margin: auto the offsetLeft and marginLeft
9148 // are the same in Safari causing offset.left to incorrectly be 0
9149 offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
9150 offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
9151
9152 // Add offsetParent borders
9153 parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
9154 parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
9155
9156 // Subtract the two offsets
9157 return {
9158 top: offset.top - parentOffset.top,
9159 left: offset.left - parentOffset.left
9160 };
9161 },
9162
9163 offsetParent: function() {
9164 return this.map(function() {
9165 var offsetParent = this.offsetParent || document.body;
9166 while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
9167 offsetParent = offsetParent.offsetParent;
9168 }
9169 return offsetParent;
9170 });
9171 }
9172});
9173
9174
9175// Create scrollLeft and scrollTop methods
9176jQuery.each( ["Left", "Top"], function( i, name ) {
9177 var method = "scroll" + name;
9178
9179 jQuery.fn[ method ] = function( val ) {
9180 var elem, win;
9181
9182 if ( val === undefined ) {
9183 elem = this[ 0 ];
9184
9185 if ( !elem ) {
9186 return null;
9187 }
9188
9189 win = getWindow( elem );
9190
9191 // Return the scroll offset
9192 return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
9193 jQuery.support.boxModel && win.document.documentElement[ method ] ||
9194 win.document.body[ method ] :
9195 elem[ method ];
9196 }
9197
9198 // Set the scroll offset
9199 return this.each(function() {
9200 win = getWindow( this );
9201
9202 if ( win ) {
9203 win.scrollTo(
9204 !i ? val : jQuery( win ).scrollLeft(),
9205 i ? val : jQuery( win ).scrollTop()
9206 );
9207
9208 } else {
9209 this[ method ] = val;
9210 }
9211 });
9212 };
9213});
9214
9215function getWindow( elem ) {
9216 return jQuery.isWindow( elem ) ?
9217 elem :
9218 elem.nodeType === 9 ?
9219 elem.defaultView || elem.parentWindow :
9220 false;
9221}
9222
9223
9224
9225
9226// Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods
9227jQuery.each([ "Height", "Width" ], function( i, name ) {
9228
9229 var type = name.toLowerCase();
9230
9231 // innerHeight and innerWidth
9232 jQuery.fn[ "inner" + name ] = function() {
9233 var elem = this[0];
9234 return elem ?
9235 elem.style ?
9236 parseFloat( jQuery.css( elem, type, "padding" ) ) :
9237 this[ type ]() :
9238 null;
9239 };
9240
9241 // outerHeight and outerWidth
9242 jQuery.fn[ "outer" + name ] = function( margin ) {
9243 var elem = this[0];
9244 return elem ?
9245 elem.style ?
9246 parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) :
9247 this[ type ]() :
9248 null;
9249 };
9250
9251 jQuery.fn[ type ] = function( size ) {
9252 // Get window width or height
9253 var elem = this[0];
9254 if ( !elem ) {
9255 return size == null ? null : this;
9256 }
9257
9258 if ( jQuery.isFunction( size ) ) {
9259 return this.each(function( i ) {
9260 var self = jQuery( this );
9261 self[ type ]( size.call( this, i, self[ type ]() ) );
9262 });
9263 }
9264
9265 if ( jQuery.isWindow( elem ) ) {
9266 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
9267 // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
9268 var docElemProp = elem.document.documentElement[ "client" + name ],
9269 body = elem.document.body;
9270 return elem.document.compatMode === "CSS1Compat" && docElemProp ||
9271 body && body[ "client" + name ] || docElemProp;
9272
9273 // Get document width or height
9274 } else if ( elem.nodeType === 9 ) {
9275 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
9276 return Math.max(
9277 elem.documentElement["client" + name],
9278 elem.body["scroll" + name], elem.documentElement["scroll" + name],
9279 elem.body["offset" + name], elem.documentElement["offset" + name]
9280 );
9281
9282 // Get or set width or height on the element
9283 } else if ( size === undefined ) {
9284 var orig = jQuery.css( elem, type ),
9285 ret = parseFloat( orig );
9286
9287 return jQuery.isNumeric( ret ) ? ret : orig;
9288
9289 // Set the width or height on the element (default to pixels if value is unitless)
9290 } else {
9291 return this.css( type, typeof size === "string" ? size : size + "px" );
9292 }
9293 };
9294
9295});
9296
9297
9298// Expose jQuery to the global object
9299window.jQuery = window.$ = jQuery;
9300})( window );