source: dashboard/lib/js/jquery-latest.js@ 401

Last change on this file since 401 was 335, checked in by Rick van der Zwet, 13 years ago

New layout and UI

File size: 185.9 KB
RevLine 
[335]1/*!
2 * jQuery JavaScript Library v1.4.4
3 * http://jquery.com/
4 *
5 * Copyright 2010, 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 2010, The Dojo Foundation
12 * Released under the MIT, BSD, and GPL Licenses.
13 *
14 * Date: Thu Nov 11 19:04:53 2010 -0500
15 */
16(function( window, undefined ) {
17
18// Use the correct document accordingly with window argument (sandbox)
19var document = window.document;
20var jQuery = (function() {
21
22// Define a local copy of jQuery
23var jQuery = function( selector, context ) {
24 // The jQuery object is actually just the init constructor 'enhanced'
25 return new jQuery.fn.init( selector, context );
26 },
27
28 // Map over jQuery in case of overwrite
29 _jQuery = window.jQuery,
30
31 // Map over the $ in case of overwrite
32 _$ = window.$,
33
34 // A central reference to the root jQuery(document)
35 rootjQuery,
36
37 // A simple way to check for HTML strings or ID strings
38 // (both of which we optimize for)
39 quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,
40
41 // Is it a simple selector
42 isSimple = /^.[^:#\[\.,]*$/,
43
44 // Check if a string has a non-whitespace character in it
45 rnotwhite = /\S/,
46 rwhite = /\s/,
47
48 // Used for trimming whitespace
49 trimLeft = /^\s+/,
50 trimRight = /\s+$/,
51
52 // Check for non-word characters
53 rnonword = /\W/,
54
55 // Check for digits
56 rdigit = /\d/,
57
58 // Match a standalone tag
59 rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
60
61 // JSON RegExp
62 rvalidchars = /^[\],:{}\s]*$/,
63 rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
64 rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
65 rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
66
67 // Useragent RegExp
68 rwebkit = /(webkit)[ \/]([\w.]+)/,
69 ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
70 rmsie = /(msie) ([\w.]+)/,
71 rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
72
73 // Keep a UserAgent string for use with jQuery.browser
74 userAgent = navigator.userAgent,
75
76 // For matching the engine and version of the browser
77 browserMatch,
78
79 // Has the ready events already been bound?
80 readyBound = false,
81
82 // The functions to execute on DOM ready
83 readyList = [],
84
85 // The ready event handler
86 DOMContentLoaded,
87
88 // Save a reference to some core methods
89 toString = Object.prototype.toString,
90 hasOwn = Object.prototype.hasOwnProperty,
91 push = Array.prototype.push,
92 slice = Array.prototype.slice,
93 trim = String.prototype.trim,
94 indexOf = Array.prototype.indexOf,
95
96 // [[Class]] -> type pairs
97 class2type = {};
98
99jQuery.fn = jQuery.prototype = {
100 init: function( selector, context ) {
101 var match, elem, ret, doc;
102
103 // Handle $(""), $(null), or $(undefined)
104 if ( !selector ) {
105 return this;
106 }
107
108 // Handle $(DOMElement)
109 if ( selector.nodeType ) {
110 this.context = this[0] = selector;
111 this.length = 1;
112 return this;
113 }
114
115 // The body element only exists once, optimize finding it
116 if ( selector === "body" && !context && document.body ) {
117 this.context = document;
118 this[0] = document.body;
119 this.selector = "body";
120 this.length = 1;
121 return this;
122 }
123
124 // Handle HTML strings
125 if ( typeof selector === "string" ) {
126 // Are we dealing with HTML string or an ID?
127 match = quickExpr.exec( selector );
128
129 // Verify a match, and that no context was specified for #id
130 if ( match && (match[1] || !context) ) {
131
132 // HANDLE: $(html) -> $(array)
133 if ( match[1] ) {
134 doc = (context ? context.ownerDocument || context : document);
135
136 // If a single string is passed in and it's a single tag
137 // just do a createElement and skip the rest
138 ret = rsingleTag.exec( selector );
139
140 if ( ret ) {
141 if ( jQuery.isPlainObject( context ) ) {
142 selector = [ document.createElement( ret[1] ) ];
143 jQuery.fn.attr.call( selector, context, true );
144
145 } else {
146 selector = [ doc.createElement( ret[1] ) ];
147 }
148
149 } else {
150 ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
151 selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
152 }
153
154 return jQuery.merge( this, selector );
155
156 // HANDLE: $("#id")
157 } else {
158 elem = document.getElementById( match[2] );
159
160 // Check parentNode to catch when Blackberry 4.6 returns
161 // nodes that are no longer in the document #6963
162 if ( elem && elem.parentNode ) {
163 // Handle the case where IE and Opera return items
164 // by name instead of ID
165 if ( elem.id !== match[2] ) {
166 return rootjQuery.find( selector );
167 }
168
169 // Otherwise, we inject the element directly into the jQuery object
170 this.length = 1;
171 this[0] = elem;
172 }
173
174 this.context = document;
175 this.selector = selector;
176 return this;
177 }
178
179 // HANDLE: $("TAG")
180 } else if ( !context && !rnonword.test( selector ) ) {
181 this.selector = selector;
182 this.context = document;
183 selector = document.getElementsByTagName( selector );
184 return jQuery.merge( this, selector );
185
186 // HANDLE: $(expr, $(...))
187 } else if ( !context || context.jquery ) {
188 return (context || rootjQuery).find( selector );
189
190 // HANDLE: $(expr, context)
191 // (which is just equivalent to: $(context).find(expr)
192 } else {
193 return jQuery( context ).find( selector );
194 }
195
196 // HANDLE: $(function)
197 // Shortcut for document ready
198 } else if ( jQuery.isFunction( selector ) ) {
199 return rootjQuery.ready( selector );
200 }
201
202 if (selector.selector !== undefined) {
203 this.selector = selector.selector;
204 this.context = selector.context;
205 }
206
207 return jQuery.makeArray( selector, this );
208 },
209
210 // Start with an empty selector
211 selector: "",
212
213 // The current version of jQuery being used
214 jquery: "1.4.4",
215
216 // The default length of a jQuery object is 0
217 length: 0,
218
219 // The number of elements contained in the matched element set
220 size: function() {
221 return this.length;
222 },
223
224 toArray: function() {
225 return slice.call( this, 0 );
226 },
227
228 // Get the Nth element in the matched element set OR
229 // Get the whole matched element set as a clean array
230 get: function( num ) {
231 return num == null ?
232
233 // Return a 'clean' array
234 this.toArray() :
235
236 // Return just the object
237 ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
238 },
239
240 // Take an array of elements and push it onto the stack
241 // (returning the new matched element set)
242 pushStack: function( elems, name, selector ) {
243 // Build a new jQuery matched element set
244 var ret = jQuery();
245
246 if ( jQuery.isArray( elems ) ) {
247 push.apply( ret, elems );
248
249 } else {
250 jQuery.merge( ret, elems );
251 }
252
253 // Add the old object onto the stack (as a reference)
254 ret.prevObject = this;
255
256 ret.context = this.context;
257
258 if ( name === "find" ) {
259 ret.selector = this.selector + (this.selector ? " " : "") + selector;
260 } else if ( name ) {
261 ret.selector = this.selector + "." + name + "(" + selector + ")";
262 }
263
264 // Return the newly-formed element set
265 return ret;
266 },
267
268 // Execute a callback for every element in the matched set.
269 // (You can seed the arguments with an array of args, but this is
270 // only used internally.)
271 each: function( callback, args ) {
272 return jQuery.each( this, callback, args );
273 },
274
275 ready: function( fn ) {
276 // Attach the listeners
277 jQuery.bindReady();
278
279 // If the DOM is already ready
280 if ( jQuery.isReady ) {
281 // Execute the function immediately
282 fn.call( document, jQuery );
283
284 // Otherwise, remember the function for later
285 } else if ( readyList ) {
286 // Add the function to the wait list
287 readyList.push( fn );
288 }
289
290 return this;
291 },
292
293 eq: function( i ) {
294 return i === -1 ?
295 this.slice( i ) :
296 this.slice( i, +i + 1 );
297 },
298
299 first: function() {
300 return this.eq( 0 );
301 },
302
303 last: function() {
304 return this.eq( -1 );
305 },
306
307 slice: function() {
308 return this.pushStack( slice.apply( this, arguments ),
309 "slice", slice.call(arguments).join(",") );
310 },
311
312 map: function( callback ) {
313 return this.pushStack( jQuery.map(this, function( elem, i ) {
314 return callback.call( elem, i, elem );
315 }));
316 },
317
318 end: function() {
319 return this.prevObject || jQuery(null);
320 },
321
322 // For internal use only.
323 // Behaves like an Array's method, not like a jQuery method.
324 push: push,
325 sort: [].sort,
326 splice: [].splice
327};
328
329// Give the init function the jQuery prototype for later instantiation
330jQuery.fn.init.prototype = jQuery.fn;
331
332jQuery.extend = jQuery.fn.extend = function() {
333 var options, name, src, copy, copyIsArray, clone,
334 target = arguments[0] || {},
335 i = 1,
336 length = arguments.length,
337 deep = false;
338
339 // Handle a deep copy situation
340 if ( typeof target === "boolean" ) {
341 deep = target;
342 target = arguments[1] || {};
343 // skip the boolean and the target
344 i = 2;
345 }
346
347 // Handle case when target is a string or something (possible in deep copy)
348 if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
349 target = {};
350 }
351
352 // extend jQuery itself if only one argument is passed
353 if ( length === i ) {
354 target = this;
355 --i;
356 }
357
358 for ( ; i < length; i++ ) {
359 // Only deal with non-null/undefined values
360 if ( (options = arguments[ i ]) != null ) {
361 // Extend the base object
362 for ( name in options ) {
363 src = target[ name ];
364 copy = options[ name ];
365
366 // Prevent never-ending loop
367 if ( target === copy ) {
368 continue;
369 }
370
371 // Recurse if we're merging plain objects or arrays
372 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
373 if ( copyIsArray ) {
374 copyIsArray = false;
375 clone = src && jQuery.isArray(src) ? src : [];
376
377 } else {
378 clone = src && jQuery.isPlainObject(src) ? src : {};
379 }
380
381 // Never move original objects, clone them
382 target[ name ] = jQuery.extend( deep, clone, copy );
383
384 // Don't bring in undefined values
385 } else if ( copy !== undefined ) {
386 target[ name ] = copy;
387 }
388 }
389 }
390 }
391
392 // Return the modified object
393 return target;
394};
395
396jQuery.extend({
397 noConflict: function( deep ) {
398 window.$ = _$;
399
400 if ( deep ) {
401 window.jQuery = _jQuery;
402 }
403
404 return jQuery;
405 },
406
407 // Is the DOM ready to be used? Set to true once it occurs.
408 isReady: false,
409
410 // A counter to track how many items to wait for before
411 // the ready event fires. See #6781
412 readyWait: 1,
413
414 // Handle when the DOM is ready
415 ready: function( wait ) {
416 // A third-party is pushing the ready event forwards
417 if ( wait === true ) {
418 jQuery.readyWait--;
419 }
420
421 // Make sure that the DOM is not already loaded
422 if ( !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 if ( readyList ) {
438 // Execute all of them
439 var fn,
440 i = 0,
441 ready = readyList;
442
443 // Reset the list of functions
444 readyList = null;
445
446 while ( (fn = ready[ i++ ]) ) {
447 fn.call( document, jQuery );
448 }
449
450 // Trigger any bound ready events
451 if ( jQuery.fn.trigger ) {
452 jQuery( document ).trigger( "ready" ).unbind( "ready" );
453 }
454 }
455 }
456 },
457
458 bindReady: function() {
459 if ( readyBound ) {
460 return;
461 }
462
463 readyBound = true;
464
465 // Catch cases where $(document).ready() is called after the
466 // browser event has already occurred.
467 if ( document.readyState === "complete" ) {
468 // Handle it asynchronously to allow scripts the opportunity to delay ready
469 return setTimeout( jQuery.ready, 1 );
470 }
471
472 // Mozilla, Opera and webkit nightlies currently support this event
473 if ( document.addEventListener ) {
474 // Use the handy event callback
475 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
476
477 // A fallback to window.onload, that will always work
478 window.addEventListener( "load", jQuery.ready, false );
479
480 // If IE event model is used
481 } else if ( document.attachEvent ) {
482 // ensure firing before onload,
483 // maybe late but safe also for iframes
484 document.attachEvent("onreadystatechange", DOMContentLoaded);
485
486 // A fallback to window.onload, that will always work
487 window.attachEvent( "onload", jQuery.ready );
488
489 // If IE and not a frame
490 // continually check to see if the document is ready
491 var toplevel = false;
492
493 try {
494 toplevel = window.frameElement == null;
495 } catch(e) {}
496
497 if ( document.documentElement.doScroll && toplevel ) {
498 doScrollCheck();
499 }
500 }
501 },
502
503 // See test/unit/core.js for details concerning isFunction.
504 // Since version 1.3, DOM methods and functions like alert
505 // aren't supported. They return false on IE (#2968).
506 isFunction: function( obj ) {
507 return jQuery.type(obj) === "function";
508 },
509
510 isArray: Array.isArray || function( obj ) {
511 return jQuery.type(obj) === "array";
512 },
513
514 // A crude way of determining if an object is a window
515 isWindow: function( obj ) {
516 return obj && typeof obj === "object" && "setInterval" in obj;
517 },
518
519 isNaN: function( obj ) {
520 return obj == null || !rdigit.test( obj ) || isNaN( obj );
521 },
522
523 type: function( obj ) {
524 return obj == null ?
525 String( obj ) :
526 class2type[ toString.call(obj) ] || "object";
527 },
528
529 isPlainObject: function( obj ) {
530 // Must be an Object.
531 // Because of IE, we also have to check the presence of the constructor property.
532 // Make sure that DOM nodes and window objects don't pass through, as well
533 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
534 return false;
535 }
536
537 // Not own constructor property must be Object
538 if ( obj.constructor &&
539 !hasOwn.call(obj, "constructor") &&
540 !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
541 return false;
542 }
543
544 // Own properties are enumerated firstly, so to speed up,
545 // if last one is own, then all properties are own.
546
547 var key;
548 for ( key in obj ) {}
549
550 return key === undefined || hasOwn.call( obj, key );
551 },
552
553 isEmptyObject: function( obj ) {
554 for ( var name in obj ) {
555 return false;
556 }
557 return true;
558 },
559
560 error: function( msg ) {
561 throw msg;
562 },
563
564 parseJSON: function( data ) {
565 if ( typeof data !== "string" || !data ) {
566 return null;
567 }
568
569 // Make sure leading/trailing whitespace is removed (IE can't handle it)
570 data = jQuery.trim( data );
571
572 // Make sure the incoming data is actual JSON
573 // Logic borrowed from http://json.org/json2.js
574 if ( rvalidchars.test(data.replace(rvalidescape, "@")
575 .replace(rvalidtokens, "]")
576 .replace(rvalidbraces, "")) ) {
577
578 // Try to use the native JSON parser first
579 return window.JSON && window.JSON.parse ?
580 window.JSON.parse( data ) :
581 (new Function("return " + data))();
582
583 } else {
584 jQuery.error( "Invalid JSON: " + data );
585 }
586 },
587
588 noop: function() {},
589
590 // Evalulates a script in a global context
591 globalEval: function( data ) {
592 if ( data && rnotwhite.test(data) ) {
593 // Inspired by code by Andrea Giammarchi
594 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
595 var head = document.getElementsByTagName("head")[0] || document.documentElement,
596 script = document.createElement("script");
597
598 script.type = "text/javascript";
599
600 if ( jQuery.support.scriptEval ) {
601 script.appendChild( document.createTextNode( data ) );
602 } else {
603 script.text = data;
604 }
605
606 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
607 // This arises when a base node is used (#2709).
608 head.insertBefore( script, head.firstChild );
609 head.removeChild( script );
610 }
611 },
612
613 nodeName: function( elem, name ) {
614 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
615 },
616
617 // args is for internal usage only
618 each: function( object, callback, args ) {
619 var name, i = 0,
620 length = object.length,
621 isObj = length === undefined || jQuery.isFunction(object);
622
623 if ( args ) {
624 if ( isObj ) {
625 for ( name in object ) {
626 if ( callback.apply( object[ name ], args ) === false ) {
627 break;
628 }
629 }
630 } else {
631 for ( ; i < length; ) {
632 if ( callback.apply( object[ i++ ], args ) === false ) {
633 break;
634 }
635 }
636 }
637
638 // A special, fast, case for the most common use of each
639 } else {
640 if ( isObj ) {
641 for ( name in object ) {
642 if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
643 break;
644 }
645 }
646 } else {
647 for ( var value = object[0];
648 i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
649 }
650 }
651
652 return object;
653 },
654
655 // Use native String.trim function wherever possible
656 trim: trim ?
657 function( text ) {
658 return text == null ?
659 "" :
660 trim.call( text );
661 } :
662
663 // Otherwise use our own trimming functionality
664 function( text ) {
665 return text == null ?
666 "" :
667 text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
668 },
669
670 // results is for internal usage only
671 makeArray: function( array, results ) {
672 var ret = results || [];
673
674 if ( array != null ) {
675 // The window, strings (and functions) also have 'length'
676 // The extra typeof function check is to prevent crashes
677 // in Safari 2 (See: #3039)
678 // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
679 var type = jQuery.type(array);
680
681 if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
682 push.call( ret, array );
683 } else {
684 jQuery.merge( ret, array );
685 }
686 }
687
688 return ret;
689 },
690
691 inArray: function( elem, array ) {
692 if ( array.indexOf ) {
693 return array.indexOf( elem );
694 }
695
696 for ( var i = 0, length = array.length; i < length; i++ ) {
697 if ( array[ i ] === elem ) {
698 return i;
699 }
700 }
701
702 return -1;
703 },
704
705 merge: function( first, second ) {
706 var i = first.length,
707 j = 0;
708
709 if ( typeof second.length === "number" ) {
710 for ( var l = second.length; j < l; j++ ) {
711 first[ i++ ] = second[ j ];
712 }
713
714 } else {
715 while ( second[j] !== undefined ) {
716 first[ i++ ] = second[ j++ ];
717 }
718 }
719
720 first.length = i;
721
722 return first;
723 },
724
725 grep: function( elems, callback, inv ) {
726 var ret = [], retVal;
727 inv = !!inv;
728
729 // Go through the array, only saving the items
730 // that pass the validator function
731 for ( var i = 0, length = elems.length; i < length; i++ ) {
732 retVal = !!callback( elems[ i ], i );
733 if ( inv !== retVal ) {
734 ret.push( elems[ i ] );
735 }
736 }
737
738 return ret;
739 },
740
741 // arg is for internal usage only
742 map: function( elems, callback, arg ) {
743 var ret = [], value;
744
745 // Go through the array, translating each of the items to their
746 // new value (or values).
747 for ( var i = 0, length = elems.length; i < length; i++ ) {
748 value = callback( elems[ i ], i, arg );
749
750 if ( value != null ) {
751 ret[ ret.length ] = value;
752 }
753 }
754
755 return ret.concat.apply( [], ret );
756 },
757
758 // A global GUID counter for objects
759 guid: 1,
760
761 proxy: function( fn, proxy, thisObject ) {
762 if ( arguments.length === 2 ) {
763 if ( typeof proxy === "string" ) {
764 thisObject = fn;
765 fn = thisObject[ proxy ];
766 proxy = undefined;
767
768 } else if ( proxy && !jQuery.isFunction( proxy ) ) {
769 thisObject = proxy;
770 proxy = undefined;
771 }
772 }
773
774 if ( !proxy && fn ) {
775 proxy = function() {
776 return fn.apply( thisObject || this, arguments );
777 };
778 }
779
780 // Set the guid of unique handler to the same of original handler, so it can be removed
781 if ( fn ) {
782 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
783 }
784
785 // So proxy can be declared as an argument
786 return proxy;
787 },
788
789 // Mutifunctional method to get and set values to a collection
790 // The value/s can be optionally by executed if its a function
791 access: function( elems, key, value, exec, fn, pass ) {
792 var length = elems.length;
793
794 // Setting many attributes
795 if ( typeof key === "object" ) {
796 for ( var k in key ) {
797 jQuery.access( elems, k, key[k], exec, fn, value );
798 }
799 return elems;
800 }
801
802 // Setting one attribute
803 if ( value !== undefined ) {
804 // Optionally, function values get executed if exec is true
805 exec = !pass && exec && jQuery.isFunction(value);
806
807 for ( var i = 0; i < length; i++ ) {
808 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
809 }
810
811 return elems;
812 }
813
814 // Getting an attribute
815 return length ? fn( elems[0], key ) : undefined;
816 },
817
818 now: function() {
819 return (new Date()).getTime();
820 },
821
822 // Use of jQuery.browser is frowned upon.
823 // More details: http://docs.jquery.com/Utilities/jQuery.browser
824 uaMatch: function( ua ) {
825 ua = ua.toLowerCase();
826
827 var match = rwebkit.exec( ua ) ||
828 ropera.exec( ua ) ||
829 rmsie.exec( ua ) ||
830 ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
831 [];
832
833 return { browser: match[1] || "", version: match[2] || "0" };
834 },
835
836 browser: {}
837});
838
839// Populate the class2type map
840jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
841 class2type[ "[object " + name + "]" ] = name.toLowerCase();
842});
843
844browserMatch = jQuery.uaMatch( userAgent );
845if ( browserMatch.browser ) {
846 jQuery.browser[ browserMatch.browser ] = true;
847 jQuery.browser.version = browserMatch.version;
848}
849
850// Deprecated, use jQuery.browser.webkit instead
851if ( jQuery.browser.webkit ) {
852 jQuery.browser.safari = true;
853}
854
855if ( indexOf ) {
856 jQuery.inArray = function( elem, array ) {
857 return indexOf.call( array, elem );
858 };
859}
860
861// Verify that \s matches non-breaking spaces
862// (IE fails on this test)
863if ( !rwhite.test( "\xA0" ) ) {
864 trimLeft = /^[\s\xA0]+/;
865 trimRight = /[\s\xA0]+$/;
866}
867
868// All jQuery objects should point back to these
869rootjQuery = jQuery(document);
870
871// Cleanup functions for the document ready method
872if ( document.addEventListener ) {
873 DOMContentLoaded = function() {
874 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
875 jQuery.ready();
876 };
877
878} else if ( document.attachEvent ) {
879 DOMContentLoaded = function() {
880 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
881 if ( document.readyState === "complete" ) {
882 document.detachEvent( "onreadystatechange", DOMContentLoaded );
883 jQuery.ready();
884 }
885 };
886}
887
888// The DOM ready check for Internet Explorer
889function doScrollCheck() {
890 if ( jQuery.isReady ) {
891 return;
892 }
893
894 try {
895 // If IE is used, use the trick by Diego Perini
896 // http://javascript.nwbox.com/IEContentLoaded/
897 document.documentElement.doScroll("left");
898 } catch(e) {
899 setTimeout( doScrollCheck, 1 );
900 return;
901 }
902
903 // and execute any waiting functions
904 jQuery.ready();
905}
906
907// Expose jQuery to the global object
908return (window.jQuery = window.$ = jQuery);
909
910})();
911
912
913(function() {
914
915 jQuery.support = {};
916
917 var root = document.documentElement,
918 script = document.createElement("script"),
919 div = document.createElement("div"),
920 id = "script" + jQuery.now();
921
922 div.style.display = "none";
923 div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
924
925 var all = div.getElementsByTagName("*"),
926 a = div.getElementsByTagName("a")[0],
927 select = document.createElement("select"),
928 opt = select.appendChild( document.createElement("option") );
929
930 // Can't get basic test support
931 if ( !all || !all.length || !a ) {
932 return;
933 }
934
935 jQuery.support = {
936 // IE strips leading whitespace when .innerHTML is used
937 leadingWhitespace: div.firstChild.nodeType === 3,
938
939 // Make sure that tbody elements aren't automatically inserted
940 // IE will insert them into empty tables
941 tbody: !div.getElementsByTagName("tbody").length,
942
943 // Make sure that link elements get serialized correctly by innerHTML
944 // This requires a wrapper element in IE
945 htmlSerialize: !!div.getElementsByTagName("link").length,
946
947 // Get the style information from getAttribute
948 // (IE uses .cssText insted)
949 style: /red/.test( a.getAttribute("style") ),
950
951 // Make sure that URLs aren't manipulated
952 // (IE normalizes it by default)
953 hrefNormalized: a.getAttribute("href") === "/a",
954
955 // Make sure that element opacity exists
956 // (IE uses filter instead)
957 // Use a regex to work around a WebKit issue. See #5145
958 opacity: /^0.55$/.test( a.style.opacity ),
959
960 // Verify style float existence
961 // (IE uses styleFloat instead of cssFloat)
962 cssFloat: !!a.style.cssFloat,
963
964 // Make sure that if no value is specified for a checkbox
965 // that it defaults to "on".
966 // (WebKit defaults to "" instead)
967 checkOn: div.getElementsByTagName("input")[0].value === "on",
968
969 // Make sure that a selected-by-default option has a working selected property.
970 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
971 optSelected: opt.selected,
972
973 // Will be defined later
974 deleteExpando: true,
975 optDisabled: false,
976 checkClone: false,
977 scriptEval: false,
978 noCloneEvent: true,
979 boxModel: null,
980 inlineBlockNeedsLayout: false,
981 shrinkWrapBlocks: false,
982 reliableHiddenOffsets: true
983 };
984
985 // Make sure that the options inside disabled selects aren't marked as disabled
986 // (WebKit marks them as diabled)
987 select.disabled = true;
988 jQuery.support.optDisabled = !opt.disabled;
989
990 script.type = "text/javascript";
991 try {
992 script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
993 } catch(e) {}
994
995 root.insertBefore( script, root.firstChild );
996
997 // Make sure that the execution of code works by injecting a script
998 // tag with appendChild/createTextNode
999 // (IE doesn't support this, fails, and uses .text instead)
1000 if ( window[ id ] ) {
1001 jQuery.support.scriptEval = true;
1002 delete window[ id ];
1003 }
1004
1005 // Test to see if it's possible to delete an expando from an element
1006 // Fails in Internet Explorer
1007 try {
1008 delete script.test;
1009
1010 } catch(e) {
1011 jQuery.support.deleteExpando = false;
1012 }
1013
1014 root.removeChild( script );
1015
1016 if ( div.attachEvent && div.fireEvent ) {
1017 div.attachEvent("onclick", function click() {
1018 // Cloning a node shouldn't copy over any
1019 // bound event handlers (IE does this)
1020 jQuery.support.noCloneEvent = false;
1021 div.detachEvent("onclick", click);
1022 });
1023 div.cloneNode(true).fireEvent("onclick");
1024 }
1025
1026 div = document.createElement("div");
1027 div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
1028
1029 var fragment = document.createDocumentFragment();
1030 fragment.appendChild( div.firstChild );
1031
1032 // WebKit doesn't clone checked state correctly in fragments
1033 jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
1034
1035 // Figure out if the W3C box model works as expected
1036 // document.body must exist before we can do this
1037 jQuery(function() {
1038 var div = document.createElement("div");
1039 div.style.width = div.style.paddingLeft = "1px";
1040
1041 document.body.appendChild( div );
1042 jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
1043
1044 if ( "zoom" in div.style ) {
1045 // Check if natively block-level elements act like inline-block
1046 // elements when setting their display to 'inline' and giving
1047 // them layout
1048 // (IE < 8 does this)
1049 div.style.display = "inline";
1050 div.style.zoom = 1;
1051 jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2;
1052
1053 // Check if elements with layout shrink-wrap their children
1054 // (IE 6 does this)
1055 div.style.display = "";
1056 div.innerHTML = "<div style='width:4px;'></div>";
1057 jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2;
1058 }
1059
1060 div.innerHTML = "<table><tr><td style='padding:0;display:none'></td><td>t</td></tr></table>";
1061 var tds = div.getElementsByTagName("td");
1062
1063 // Check if table cells still have offsetWidth/Height when they are set
1064 // to display:none and there are still other visible table cells in a
1065 // table row; if so, offsetWidth/Height are not reliable for use when
1066 // determining if an element has been hidden directly using
1067 // display:none (it is still safe to use offsets if a parent element is
1068 // hidden; don safety goggles and see bug #4512 for more information).
1069 // (only IE 8 fails this test)
1070 jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0;
1071
1072 tds[0].style.display = "";
1073 tds[1].style.display = "none";
1074
1075 // Check if empty table cells still have offsetWidth/Height
1076 // (IE < 8 fail this test)
1077 jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0;
1078 div.innerHTML = "";
1079
1080 document.body.removeChild( div ).style.display = "none";
1081 div = tds = null;
1082 });
1083
1084 // Technique from Juriy Zaytsev
1085 // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
1086 var eventSupported = function( eventName ) {
1087 var el = document.createElement("div");
1088 eventName = "on" + eventName;
1089
1090 var isSupported = (eventName in el);
1091 if ( !isSupported ) {
1092 el.setAttribute(eventName, "return;");
1093 isSupported = typeof el[eventName] === "function";
1094 }
1095 el = null;
1096
1097 return isSupported;
1098 };
1099
1100 jQuery.support.submitBubbles = eventSupported("submit");
1101 jQuery.support.changeBubbles = eventSupported("change");
1102
1103 // release memory in IE
1104 root = script = div = all = a = null;
1105})();
1106
1107
1108
1109var windowData = {},
1110 rbrace = /^(?:\{.*\}|\[.*\])$/;
1111
1112jQuery.extend({
1113 cache: {},
1114
1115 // Please use with caution
1116 uuid: 0,
1117
1118 // Unique for each copy of jQuery on the page
1119 expando: "jQuery" + jQuery.now(),
1120
1121 // The following elements throw uncatchable exceptions if you
1122 // attempt to add expando properties to them.
1123 noData: {
1124 "embed": true,
1125 // Ban all objects except for Flash (which handle expandos)
1126 "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1127 "applet": true
1128 },
1129
1130 data: function( elem, name, data ) {
1131 if ( !jQuery.acceptData( elem ) ) {
1132 return;
1133 }
1134
1135 elem = elem == window ?
1136 windowData :
1137 elem;
1138
1139 var isNode = elem.nodeType,
1140 id = isNode ? elem[ jQuery.expando ] : null,
1141 cache = jQuery.cache, thisCache;
1142
1143 if ( isNode && !id && typeof name === "string" && data === undefined ) {
1144 return;
1145 }
1146
1147 // Get the data from the object directly
1148 if ( !isNode ) {
1149 cache = elem;
1150
1151 // Compute a unique ID for the element
1152 } else if ( !id ) {
1153 elem[ jQuery.expando ] = id = ++jQuery.uuid;
1154 }
1155
1156 // Avoid generating a new cache unless none exists and we
1157 // want to manipulate it.
1158 if ( typeof name === "object" ) {
1159 if ( isNode ) {
1160 cache[ id ] = jQuery.extend(cache[ id ], name);
1161
1162 } else {
1163 jQuery.extend( cache, name );
1164 }
1165
1166 } else if ( isNode && !cache[ id ] ) {
1167 cache[ id ] = {};
1168 }
1169
1170 thisCache = isNode ? cache[ id ] : cache;
1171
1172 // Prevent overriding the named cache with undefined values
1173 if ( data !== undefined ) {
1174 thisCache[ name ] = data;
1175 }
1176
1177 return typeof name === "string" ? thisCache[ name ] : thisCache;
1178 },
1179
1180 removeData: function( elem, name ) {
1181 if ( !jQuery.acceptData( elem ) ) {
1182 return;
1183 }
1184
1185 elem = elem == window ?
1186 windowData :
1187 elem;
1188
1189 var isNode = elem.nodeType,
1190 id = isNode ? elem[ jQuery.expando ] : elem,
1191 cache = jQuery.cache,
1192 thisCache = isNode ? cache[ id ] : id;
1193
1194 // If we want to remove a specific section of the element's data
1195 if ( name ) {
1196 if ( thisCache ) {
1197 // Remove the section of cache data
1198 delete thisCache[ name ];
1199
1200 // If we've removed all the data, remove the element's cache
1201 if ( isNode && jQuery.isEmptyObject(thisCache) ) {
1202 jQuery.removeData( elem );
1203 }
1204 }
1205
1206 // Otherwise, we want to remove all of the element's data
1207 } else {
1208 if ( isNode && jQuery.support.deleteExpando ) {
1209 delete elem[ jQuery.expando ];
1210
1211 } else if ( elem.removeAttribute ) {
1212 elem.removeAttribute( jQuery.expando );
1213
1214 // Completely remove the data cache
1215 } else if ( isNode ) {
1216 delete cache[ id ];
1217
1218 // Remove all fields from the object
1219 } else {
1220 for ( var n in elem ) {
1221 delete elem[ n ];
1222 }
1223 }
1224 }
1225 },
1226
1227 // A method for determining if a DOM node can handle the data expando
1228 acceptData: function( elem ) {
1229 if ( elem.nodeName ) {
1230 var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
1231
1232 if ( match ) {
1233 return !(match === true || elem.getAttribute("classid") !== match);
1234 }
1235 }
1236
1237 return true;
1238 }
1239});
1240
1241jQuery.fn.extend({
1242 data: function( key, value ) {
1243 var data = null;
1244
1245 if ( typeof key === "undefined" ) {
1246 if ( this.length ) {
1247 var attr = this[0].attributes, name;
1248 data = jQuery.data( this[0] );
1249
1250 for ( var i = 0, l = attr.length; i < l; i++ ) {
1251 name = attr[i].name;
1252
1253 if ( name.indexOf( "data-" ) === 0 ) {
1254 name = name.substr( 5 );
1255 dataAttr( this[0], name, data[ name ] );
1256 }
1257 }
1258 }
1259
1260 return data;
1261
1262 } else if ( typeof key === "object" ) {
1263 return this.each(function() {
1264 jQuery.data( this, key );
1265 });
1266 }
1267
1268 var parts = key.split(".");
1269 parts[1] = parts[1] ? "." + parts[1] : "";
1270
1271 if ( value === undefined ) {
1272 data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1273
1274 // Try to fetch any internally stored data first
1275 if ( data === undefined && this.length ) {
1276 data = jQuery.data( this[0], key );
1277 data = dataAttr( this[0], key, data );
1278 }
1279
1280 return data === undefined && parts[1] ?
1281 this.data( parts[0] ) :
1282 data;
1283
1284 } else {
1285 return this.each(function() {
1286 var $this = jQuery( this ),
1287 args = [ parts[0], value ];
1288
1289 $this.triggerHandler( "setData" + parts[1] + "!", args );
1290 jQuery.data( this, key, value );
1291 $this.triggerHandler( "changeData" + parts[1] + "!", args );
1292 });
1293 }
1294 },
1295
1296 removeData: function( key ) {
1297 return this.each(function() {
1298 jQuery.removeData( this, key );
1299 });
1300 }
1301});
1302
1303function dataAttr( elem, key, data ) {
1304 // If nothing was found internally, try to fetch any
1305 // data from the HTML5 data-* attribute
1306 if ( data === undefined && elem.nodeType === 1 ) {
1307 data = elem.getAttribute( "data-" + key );
1308
1309 if ( typeof data === "string" ) {
1310 try {
1311 data = data === "true" ? true :
1312 data === "false" ? false :
1313 data === "null" ? null :
1314 !jQuery.isNaN( data ) ? parseFloat( data ) :
1315 rbrace.test( data ) ? jQuery.parseJSON( data ) :
1316 data;
1317 } catch( e ) {}
1318
1319 // Make sure we set the data so it isn't changed later
1320 jQuery.data( elem, key, data );
1321
1322 } else {
1323 data = undefined;
1324 }
1325 }
1326
1327 return data;
1328}
1329
1330
1331
1332
1333jQuery.extend({
1334 queue: function( elem, type, data ) {
1335 if ( !elem ) {
1336 return;
1337 }
1338
1339 type = (type || "fx") + "queue";
1340 var q = jQuery.data( elem, type );
1341
1342 // Speed up dequeue by getting out quickly if this is just a lookup
1343 if ( !data ) {
1344 return q || [];
1345 }
1346
1347 if ( !q || jQuery.isArray(data) ) {
1348 q = jQuery.data( elem, type, jQuery.makeArray(data) );
1349
1350 } else {
1351 q.push( data );
1352 }
1353
1354 return q;
1355 },
1356
1357 dequeue: function( elem, type ) {
1358 type = type || "fx";
1359
1360 var queue = jQuery.queue( elem, type ),
1361 fn = queue.shift();
1362
1363 // If the fx queue is dequeued, always remove the progress sentinel
1364 if ( fn === "inprogress" ) {
1365 fn = queue.shift();
1366 }
1367
1368 if ( fn ) {
1369 // Add a progress sentinel to prevent the fx queue from being
1370 // automatically dequeued
1371 if ( type === "fx" ) {
1372 queue.unshift("inprogress");
1373 }
1374
1375 fn.call(elem, function() {
1376 jQuery.dequeue(elem, type);
1377 });
1378 }
1379 }
1380});
1381
1382jQuery.fn.extend({
1383 queue: function( type, data ) {
1384 if ( typeof type !== "string" ) {
1385 data = type;
1386 type = "fx";
1387 }
1388
1389 if ( data === undefined ) {
1390 return jQuery.queue( this[0], type );
1391 }
1392 return this.each(function( i ) {
1393 var queue = jQuery.queue( this, type, data );
1394
1395 if ( type === "fx" && queue[0] !== "inprogress" ) {
1396 jQuery.dequeue( this, type );
1397 }
1398 });
1399 },
1400 dequeue: function( type ) {
1401 return this.each(function() {
1402 jQuery.dequeue( this, type );
1403 });
1404 },
1405
1406 // Based off of the plugin by Clint Helfers, with permission.
1407 // http://blindsignals.com/index.php/2009/07/jquery-delay/
1408 delay: function( time, type ) {
1409 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
1410 type = type || "fx";
1411
1412 return this.queue( type, function() {
1413 var elem = this;
1414 setTimeout(function() {
1415 jQuery.dequeue( elem, type );
1416 }, time );
1417 });
1418 },
1419
1420 clearQueue: function( type ) {
1421 return this.queue( type || "fx", [] );
1422 }
1423});
1424
1425
1426
1427
1428var rclass = /[\n\t]/g,
1429 rspaces = /\s+/,
1430 rreturn = /\r/g,
1431 rspecialurl = /^(?:href|src|style)$/,
1432 rtype = /^(?:button|input)$/i,
1433 rfocusable = /^(?:button|input|object|select|textarea)$/i,
1434 rclickable = /^a(?:rea)?$/i,
1435 rradiocheck = /^(?:radio|checkbox)$/i;
1436
1437jQuery.props = {
1438 "for": "htmlFor",
1439 "class": "className",
1440 readonly: "readOnly",
1441 maxlength: "maxLength",
1442 cellspacing: "cellSpacing",
1443 rowspan: "rowSpan",
1444 colspan: "colSpan",
1445 tabindex: "tabIndex",
1446 usemap: "useMap",
1447 frameborder: "frameBorder"
1448};
1449
1450jQuery.fn.extend({
1451 attr: function( name, value ) {
1452 return jQuery.access( this, name, value, true, jQuery.attr );
1453 },
1454
1455 removeAttr: function( name, fn ) {
1456 return this.each(function(){
1457 jQuery.attr( this, name, "" );
1458 if ( this.nodeType === 1 ) {
1459 this.removeAttribute( name );
1460 }
1461 });
1462 },
1463
1464 addClass: function( value ) {
1465 if ( jQuery.isFunction(value) ) {
1466 return this.each(function(i) {
1467 var self = jQuery(this);
1468 self.addClass( value.call(this, i, self.attr("class")) );
1469 });
1470 }
1471
1472 if ( value && typeof value === "string" ) {
1473 var classNames = (value || "").split( rspaces );
1474
1475 for ( var i = 0, l = this.length; i < l; i++ ) {
1476 var elem = this[i];
1477
1478 if ( elem.nodeType === 1 ) {
1479 if ( !elem.className ) {
1480 elem.className = value;
1481
1482 } else {
1483 var className = " " + elem.className + " ",
1484 setClass = elem.className;
1485
1486 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1487 if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
1488 setClass += " " + classNames[c];
1489 }
1490 }
1491 elem.className = jQuery.trim( setClass );
1492 }
1493 }
1494 }
1495 }
1496
1497 return this;
1498 },
1499
1500 removeClass: function( value ) {
1501 if ( jQuery.isFunction(value) ) {
1502 return this.each(function(i) {
1503 var self = jQuery(this);
1504 self.removeClass( value.call(this, i, self.attr("class")) );
1505 });
1506 }
1507
1508 if ( (value && typeof value === "string") || value === undefined ) {
1509 var classNames = (value || "").split( rspaces );
1510
1511 for ( var i = 0, l = this.length; i < l; i++ ) {
1512 var elem = this[i];
1513
1514 if ( elem.nodeType === 1 && elem.className ) {
1515 if ( value ) {
1516 var className = (" " + elem.className + " ").replace(rclass, " ");
1517 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1518 className = className.replace(" " + classNames[c] + " ", " ");
1519 }
1520 elem.className = jQuery.trim( className );
1521
1522 } else {
1523 elem.className = "";
1524 }
1525 }
1526 }
1527 }
1528
1529 return this;
1530 },
1531
1532 toggleClass: function( value, stateVal ) {
1533 var type = typeof value,
1534 isBool = typeof stateVal === "boolean";
1535
1536 if ( jQuery.isFunction( value ) ) {
1537 return this.each(function(i) {
1538 var self = jQuery(this);
1539 self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
1540 });
1541 }
1542
1543 return this.each(function() {
1544 if ( type === "string" ) {
1545 // toggle individual class names
1546 var className,
1547 i = 0,
1548 self = jQuery( this ),
1549 state = stateVal,
1550 classNames = value.split( rspaces );
1551
1552 while ( (className = classNames[ i++ ]) ) {
1553 // check each className given, space seperated list
1554 state = isBool ? state : !self.hasClass( className );
1555 self[ state ? "addClass" : "removeClass" ]( className );
1556 }
1557
1558 } else if ( type === "undefined" || type === "boolean" ) {
1559 if ( this.className ) {
1560 // store className if set
1561 jQuery.data( this, "__className__", this.className );
1562 }
1563
1564 // toggle whole className
1565 this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
1566 }
1567 });
1568 },
1569
1570 hasClass: function( selector ) {
1571 var className = " " + selector + " ";
1572 for ( var i = 0, l = this.length; i < l; i++ ) {
1573 if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
1574 return true;
1575 }
1576 }
1577
1578 return false;
1579 },
1580
1581 val: function( value ) {
1582 if ( !arguments.length ) {
1583 var elem = this[0];
1584
1585 if ( elem ) {
1586 if ( jQuery.nodeName( elem, "option" ) ) {
1587 // attributes.value is undefined in Blackberry 4.7 but
1588 // uses .value. See #6932
1589 var val = elem.attributes.value;
1590 return !val || val.specified ? elem.value : elem.text;
1591 }
1592
1593 // We need to handle select boxes special
1594 if ( jQuery.nodeName( elem, "select" ) ) {
1595 var index = elem.selectedIndex,
1596 values = [],
1597 options = elem.options,
1598 one = elem.type === "select-one";
1599
1600 // Nothing was selected
1601 if ( index < 0 ) {
1602 return null;
1603 }
1604
1605 // Loop through all the selected options
1606 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
1607 var option = options[ i ];
1608
1609 // Don't return options that are disabled or in a disabled optgroup
1610 if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
1611 (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
1612
1613 // Get the specific value for the option
1614 value = jQuery(option).val();
1615
1616 // We don't need an array for one selects
1617 if ( one ) {
1618 return value;
1619 }
1620
1621 // Multi-Selects return an array
1622 values.push( value );
1623 }
1624 }
1625
1626 return values;
1627 }
1628
1629 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
1630 if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
1631 return elem.getAttribute("value") === null ? "on" : elem.value;
1632 }
1633
1634
1635 // Everything else, we just grab the value
1636 return (elem.value || "").replace(rreturn, "");
1637
1638 }
1639
1640 return undefined;
1641 }
1642
1643 var isFunction = jQuery.isFunction(value);
1644
1645 return this.each(function(i) {
1646 var self = jQuery(this), val = value;
1647
1648 if ( this.nodeType !== 1 ) {
1649 return;
1650 }
1651
1652 if ( isFunction ) {
1653 val = value.call(this, i, self.val());
1654 }
1655
1656 // Treat null/undefined as ""; convert numbers to string
1657 if ( val == null ) {
1658 val = "";
1659 } else if ( typeof val === "number" ) {
1660 val += "";
1661 } else if ( jQuery.isArray(val) ) {
1662 val = jQuery.map(val, function (value) {
1663 return value == null ? "" : value + "";
1664 });
1665 }
1666
1667 if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
1668 this.checked = jQuery.inArray( self.val(), val ) >= 0;
1669
1670 } else if ( jQuery.nodeName( this, "select" ) ) {
1671 var values = jQuery.makeArray(val);
1672
1673 jQuery( "option", this ).each(function() {
1674 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
1675 });
1676
1677 if ( !values.length ) {
1678 this.selectedIndex = -1;
1679 }
1680
1681 } else {
1682 this.value = val;
1683 }
1684 });
1685 }
1686});
1687
1688jQuery.extend({
1689 attrFn: {
1690 val: true,
1691 css: true,
1692 html: true,
1693 text: true,
1694 data: true,
1695 width: true,
1696 height: true,
1697 offset: true
1698 },
1699
1700 attr: function( elem, name, value, pass ) {
1701 // don't set attributes on text and comment nodes
1702 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
1703 return undefined;
1704 }
1705
1706 if ( pass && name in jQuery.attrFn ) {
1707 return jQuery(elem)[name](value);
1708 }
1709
1710 var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
1711 // Whether we are setting (or getting)
1712 set = value !== undefined;
1713
1714 // Try to normalize/fix the name
1715 name = notxml && jQuery.props[ name ] || name;
1716
1717 // These attributes require special treatment
1718 var special = rspecialurl.test( name );
1719
1720 // Safari mis-reports the default selected property of an option
1721 // Accessing the parent's selectedIndex property fixes it
1722 if ( name === "selected" && !jQuery.support.optSelected ) {
1723 var parent = elem.parentNode;
1724 if ( parent ) {
1725 parent.selectedIndex;
1726
1727 // Make sure that it also works with optgroups, see #5701
1728 if ( parent.parentNode ) {
1729 parent.parentNode.selectedIndex;
1730 }
1731 }
1732 }
1733
1734 // If applicable, access the attribute via the DOM 0 way
1735 // 'in' checks fail in Blackberry 4.7 #6931
1736 if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) {
1737 if ( set ) {
1738 // We can't allow the type property to be changed (since it causes problems in IE)
1739 if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
1740 jQuery.error( "type property can't be changed" );
1741 }
1742
1743 if ( value === null ) {
1744 if ( elem.nodeType === 1 ) {
1745 elem.removeAttribute( name );
1746 }
1747
1748 } else {
1749 elem[ name ] = value;
1750 }
1751 }
1752
1753 // browsers index elements by id/name on forms, give priority to attributes.
1754 if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
1755 return elem.getAttributeNode( name ).nodeValue;
1756 }
1757
1758 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
1759 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
1760 if ( name === "tabIndex" ) {
1761 var attributeNode = elem.getAttributeNode( "tabIndex" );
1762
1763 return attributeNode && attributeNode.specified ?
1764 attributeNode.value :
1765 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
1766 0 :
1767 undefined;
1768 }
1769
1770 return elem[ name ];
1771 }
1772
1773 if ( !jQuery.support.style && notxml && name === "style" ) {
1774 if ( set ) {
1775 elem.style.cssText = "" + value;
1776 }
1777
1778 return elem.style.cssText;
1779 }
1780
1781 if ( set ) {
1782 // convert the value to a string (all browsers do this but IE) see #1070
1783 elem.setAttribute( name, "" + value );
1784 }
1785
1786 // Ensure that missing attributes return undefined
1787 // Blackberry 4.7 returns "" from getAttribute #6938
1788 if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) {
1789 return undefined;
1790 }
1791
1792 var attr = !jQuery.support.hrefNormalized && notxml && special ?
1793 // Some attributes require a special call on IE
1794 elem.getAttribute( name, 2 ) :
1795 elem.getAttribute( name );
1796
1797 // Non-existent attributes return null, we normalize to undefined
1798 return attr === null ? undefined : attr;
1799 }
1800});
1801
1802
1803
1804
1805var rnamespaces = /\.(.*)$/,
1806 rformElems = /^(?:textarea|input|select)$/i,
1807 rperiod = /\./g,
1808 rspace = / /g,
1809 rescape = /[^\w\s.|`]/g,
1810 fcleanup = function( nm ) {
1811 return nm.replace(rescape, "\\$&");
1812 },
1813 focusCounts = { focusin: 0, focusout: 0 };
1814
1815/*
1816 * A number of helper functions used for managing events.
1817 * Many of the ideas behind this code originated from
1818 * Dean Edwards' addEvent library.
1819 */
1820jQuery.event = {
1821
1822 // Bind an event to an element
1823 // Original by Dean Edwards
1824 add: function( elem, types, handler, data ) {
1825 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
1826 return;
1827 }
1828
1829 // For whatever reason, IE has trouble passing the window object
1830 // around, causing it to be cloned in the process
1831 if ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) {
1832 elem = window;
1833 }
1834
1835 if ( handler === false ) {
1836 handler = returnFalse;
1837 } else if ( !handler ) {
1838 // Fixes bug #7229. Fix recommended by jdalton
1839 return;
1840 }
1841
1842 var handleObjIn, handleObj;
1843
1844 if ( handler.handler ) {
1845 handleObjIn = handler;
1846 handler = handleObjIn.handler;
1847 }
1848
1849 // Make sure that the function being executed has a unique ID
1850 if ( !handler.guid ) {
1851 handler.guid = jQuery.guid++;
1852 }
1853
1854 // Init the element's event structure
1855 var elemData = jQuery.data( elem );
1856
1857 // If no elemData is found then we must be trying to bind to one of the
1858 // banned noData elements
1859 if ( !elemData ) {
1860 return;
1861 }
1862
1863 // Use a key less likely to result in collisions for plain JS objects.
1864 // Fixes bug #7150.
1865 var eventKey = elem.nodeType ? "events" : "__events__",
1866 events = elemData[ eventKey ],
1867 eventHandle = elemData.handle;
1868
1869 if ( typeof events === "function" ) {
1870 // On plain objects events is a fn that holds the the data
1871 // which prevents this data from being JSON serialized
1872 // the function does not need to be called, it just contains the data
1873 eventHandle = events.handle;
1874 events = events.events;
1875
1876 } else if ( !events ) {
1877 if ( !elem.nodeType ) {
1878 // On plain objects, create a fn that acts as the holder
1879 // of the values to avoid JSON serialization of event data
1880 elemData[ eventKey ] = elemData = function(){};
1881 }
1882
1883 elemData.events = events = {};
1884 }
1885
1886 if ( !eventHandle ) {
1887 elemData.handle = eventHandle = function() {
1888 // Handle the second event of a trigger and when
1889 // an event is called after a page has unloaded
1890 return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
1891 jQuery.event.handle.apply( eventHandle.elem, arguments ) :
1892 undefined;
1893 };
1894 }
1895
1896 // Add elem as a property of the handle function
1897 // This is to prevent a memory leak with non-native events in IE.
1898 eventHandle.elem = elem;
1899
1900 // Handle multiple events separated by a space
1901 // jQuery(...).bind("mouseover mouseout", fn);
1902 types = types.split(" ");
1903
1904 var type, i = 0, namespaces;
1905
1906 while ( (type = types[ i++ ]) ) {
1907 handleObj = handleObjIn ?
1908 jQuery.extend({}, handleObjIn) :
1909 { handler: handler, data: data };
1910
1911 // Namespaced event handlers
1912 if ( type.indexOf(".") > -1 ) {
1913 namespaces = type.split(".");
1914 type = namespaces.shift();
1915 handleObj.namespace = namespaces.slice(0).sort().join(".");
1916
1917 } else {
1918 namespaces = [];
1919 handleObj.namespace = "";
1920 }
1921
1922 handleObj.type = type;
1923 if ( !handleObj.guid ) {
1924 handleObj.guid = handler.guid;
1925 }
1926
1927 // Get the current list of functions bound to this event
1928 var handlers = events[ type ],
1929 special = jQuery.event.special[ type ] || {};
1930
1931 // Init the event handler queue
1932 if ( !handlers ) {
1933 handlers = events[ type ] = [];
1934
1935 // Check for a special event handler
1936 // Only use addEventListener/attachEvent if the special
1937 // events handler returns false
1938 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
1939 // Bind the global event handler to the element
1940 if ( elem.addEventListener ) {
1941 elem.addEventListener( type, eventHandle, false );
1942
1943 } else if ( elem.attachEvent ) {
1944 elem.attachEvent( "on" + type, eventHandle );
1945 }
1946 }
1947 }
1948
1949 if ( special.add ) {
1950 special.add.call( elem, handleObj );
1951
1952 if ( !handleObj.handler.guid ) {
1953 handleObj.handler.guid = handler.guid;
1954 }
1955 }
1956
1957 // Add the function to the element's handler list
1958 handlers.push( handleObj );
1959
1960 // Keep track of which events have been used, for global triggering
1961 jQuery.event.global[ type ] = true;
1962 }
1963
1964 // Nullify elem to prevent memory leaks in IE
1965 elem = null;
1966 },
1967
1968 global: {},
1969
1970 // Detach an event or set of events from an element
1971 remove: function( elem, types, handler, pos ) {
1972 // don't do events on text and comment nodes
1973 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
1974 return;
1975 }
1976
1977 if ( handler === false ) {
1978 handler = returnFalse;
1979 }
1980
1981 var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
1982 eventKey = elem.nodeType ? "events" : "__events__",
1983 elemData = jQuery.data( elem ),
1984 events = elemData && elemData[ eventKey ];
1985
1986 if ( !elemData || !events ) {
1987 return;
1988 }
1989
1990 if ( typeof events === "function" ) {
1991 elemData = events;
1992 events = events.events;
1993 }
1994
1995 // types is actually an event object here
1996 if ( types && types.type ) {
1997 handler = types.handler;
1998 types = types.type;
1999 }
2000
2001 // Unbind all events for the element
2002 if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
2003 types = types || "";
2004
2005 for ( type in events ) {
2006 jQuery.event.remove( elem, type + types );
2007 }
2008
2009 return;
2010 }
2011
2012 // Handle multiple events separated by a space
2013 // jQuery(...).unbind("mouseover mouseout", fn);
2014 types = types.split(" ");
2015
2016 while ( (type = types[ i++ ]) ) {
2017 origType = type;
2018 handleObj = null;
2019 all = type.indexOf(".") < 0;
2020 namespaces = [];
2021
2022 if ( !all ) {
2023 // Namespaced event handlers
2024 namespaces = type.split(".");
2025 type = namespaces.shift();
2026
2027 namespace = new RegExp("(^|\\.)" +
2028 jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
2029 }
2030
2031 eventType = events[ type ];
2032
2033 if ( !eventType ) {
2034 continue;
2035 }
2036
2037 if ( !handler ) {
2038 for ( j = 0; j < eventType.length; j++ ) {
2039 handleObj = eventType[ j ];
2040
2041 if ( all || namespace.test( handleObj.namespace ) ) {
2042 jQuery.event.remove( elem, origType, handleObj.handler, j );
2043 eventType.splice( j--, 1 );
2044 }
2045 }
2046
2047 continue;
2048 }
2049
2050 special = jQuery.event.special[ type ] || {};
2051
2052 for ( j = pos || 0; j < eventType.length; j++ ) {
2053 handleObj = eventType[ j ];
2054
2055 if ( handler.guid === handleObj.guid ) {
2056 // remove the given handler for the given type
2057 if ( all || namespace.test( handleObj.namespace ) ) {
2058 if ( pos == null ) {
2059 eventType.splice( j--, 1 );
2060 }
2061
2062 if ( special.remove ) {
2063 special.remove.call( elem, handleObj );
2064 }
2065 }
2066
2067 if ( pos != null ) {
2068 break;
2069 }
2070 }
2071 }
2072
2073 // remove generic event handler if no more handlers exist
2074 if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
2075 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
2076 jQuery.removeEvent( elem, type, elemData.handle );
2077 }
2078
2079 ret = null;
2080 delete events[ type ];
2081 }
2082 }
2083
2084 // Remove the expando if it's no longer used
2085 if ( jQuery.isEmptyObject( events ) ) {
2086 var handle = elemData.handle;
2087 if ( handle ) {
2088 handle.elem = null;
2089 }
2090
2091 delete elemData.events;
2092 delete elemData.handle;
2093
2094 if ( typeof elemData === "function" ) {
2095 jQuery.removeData( elem, eventKey );
2096
2097 } else if ( jQuery.isEmptyObject( elemData ) ) {
2098 jQuery.removeData( elem );
2099 }
2100 }
2101 },
2102
2103 // bubbling is internal
2104 trigger: function( event, data, elem /*, bubbling */ ) {
2105 // Event object or event type
2106 var type = event.type || event,
2107 bubbling = arguments[3];
2108
2109 if ( !bubbling ) {
2110 event = typeof event === "object" ?
2111 // jQuery.Event object
2112 event[ jQuery.expando ] ? event :
2113 // Object literal
2114 jQuery.extend( jQuery.Event(type), event ) :
2115 // Just the event type (string)
2116 jQuery.Event(type);
2117
2118 if ( type.indexOf("!") >= 0 ) {
2119 event.type = type = type.slice(0, -1);
2120 event.exclusive = true;
2121 }
2122
2123 // Handle a global trigger
2124 if ( !elem ) {
2125 // Don't bubble custom events when global (to avoid too much overhead)
2126 event.stopPropagation();
2127
2128 // Only trigger if we've ever bound an event for it
2129 if ( jQuery.event.global[ type ] ) {
2130 jQuery.each( jQuery.cache, function() {
2131 if ( this.events && this.events[type] ) {
2132 jQuery.event.trigger( event, data, this.handle.elem );
2133 }
2134 });
2135 }
2136 }
2137
2138 // Handle triggering a single element
2139
2140 // don't do events on text and comment nodes
2141 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
2142 return undefined;
2143 }
2144
2145 // Clean up in case it is reused
2146 event.result = undefined;
2147 event.target = elem;
2148
2149 // Clone the incoming data, if any
2150 data = jQuery.makeArray( data );
2151 data.unshift( event );
2152 }
2153
2154 event.currentTarget = elem;
2155
2156 // Trigger the event, it is assumed that "handle" is a function
2157 var handle = elem.nodeType ?
2158 jQuery.data( elem, "handle" ) :
2159 (jQuery.data( elem, "__events__" ) || {}).handle;
2160
2161 if ( handle ) {
2162 handle.apply( elem, data );
2163 }
2164
2165 var parent = elem.parentNode || elem.ownerDocument;
2166
2167 // Trigger an inline bound script
2168 try {
2169 if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
2170 if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
2171 event.result = false;
2172 event.preventDefault();
2173 }
2174 }
2175
2176 // prevent IE from throwing an error for some elements with some event types, see #3533
2177 } catch (inlineError) {}
2178
2179 if ( !event.isPropagationStopped() && parent ) {
2180 jQuery.event.trigger( event, data, parent, true );
2181
2182 } else if ( !event.isDefaultPrevented() ) {
2183 var old,
2184 target = event.target,
2185 targetType = type.replace( rnamespaces, "" ),
2186 isClick = jQuery.nodeName( target, "a" ) && targetType === "click",
2187 special = jQuery.event.special[ targetType ] || {};
2188
2189 if ( (!special._default || special._default.call( elem, event ) === false) &&
2190 !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
2191
2192 try {
2193 if ( target[ targetType ] ) {
2194 // Make sure that we don't accidentally re-trigger the onFOO events
2195 old = target[ "on" + targetType ];
2196
2197 if ( old ) {
2198 target[ "on" + targetType ] = null;
2199 }
2200
2201 jQuery.event.triggered = true;
2202 target[ targetType ]();
2203 }
2204
2205 // prevent IE from throwing an error for some elements with some event types, see #3533
2206 } catch (triggerError) {}
2207
2208 if ( old ) {
2209 target[ "on" + targetType ] = old;
2210 }
2211
2212 jQuery.event.triggered = false;
2213 }
2214 }
2215 },
2216
2217 handle: function( event ) {
2218 var all, handlers, namespaces, namespace_re, events,
2219 namespace_sort = [],
2220 args = jQuery.makeArray( arguments );
2221
2222 event = args[0] = jQuery.event.fix( event || window.event );
2223 event.currentTarget = this;
2224
2225 // Namespaced event handlers
2226 all = event.type.indexOf(".") < 0 && !event.exclusive;
2227
2228 if ( !all ) {
2229 namespaces = event.type.split(".");
2230 event.type = namespaces.shift();
2231 namespace_sort = namespaces.slice(0).sort();
2232 namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)");
2233 }
2234
2235 event.namespace = event.namespace || namespace_sort.join(".");
2236
2237 events = jQuery.data(this, this.nodeType ? "events" : "__events__");
2238
2239 if ( typeof events === "function" ) {
2240 events = events.events;
2241 }
2242
2243 handlers = (events || {})[ event.type ];
2244
2245 if ( events && handlers ) {
2246 // Clone the handlers to prevent manipulation
2247 handlers = handlers.slice(0);
2248
2249 for ( var j = 0, l = handlers.length; j < l; j++ ) {
2250 var handleObj = handlers[ j ];
2251
2252 // Filter the functions by class
2253 if ( all || namespace_re.test( handleObj.namespace ) ) {
2254 // Pass in a reference to the handler function itself
2255 // So that we can later remove it
2256 event.handler = handleObj.handler;
2257 event.data = handleObj.data;
2258 event.handleObj = handleObj;
2259
2260 var ret = handleObj.handler.apply( this, args );
2261
2262 if ( ret !== undefined ) {
2263 event.result = ret;
2264 if ( ret === false ) {
2265 event.preventDefault();
2266 event.stopPropagation();
2267 }
2268 }
2269
2270 if ( event.isImmediatePropagationStopped() ) {
2271 break;
2272 }
2273 }
2274 }
2275 }
2276
2277 return event.result;
2278 },
2279
2280 props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
2281
2282 fix: function( event ) {
2283 if ( event[ jQuery.expando ] ) {
2284 return event;
2285 }
2286
2287 // store a copy of the original event object
2288 // and "clone" to set read-only properties
2289 var originalEvent = event;
2290 event = jQuery.Event( originalEvent );
2291
2292 for ( var i = this.props.length, prop; i; ) {
2293 prop = this.props[ --i ];
2294 event[ prop ] = originalEvent[ prop ];
2295 }
2296
2297 // Fix target property, if necessary
2298 if ( !event.target ) {
2299 // Fixes #1925 where srcElement might not be defined either
2300 event.target = event.srcElement || document;
2301 }
2302
2303 // check if target is a textnode (safari)
2304 if ( event.target.nodeType === 3 ) {
2305 event.target = event.target.parentNode;
2306 }
2307
2308 // Add relatedTarget, if necessary
2309 if ( !event.relatedTarget && event.fromElement ) {
2310 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
2311 }
2312
2313 // Calculate pageX/Y if missing and clientX/Y available
2314 if ( event.pageX == null && event.clientX != null ) {
2315 var doc = document.documentElement,
2316 body = document.body;
2317
2318 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
2319 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
2320 }
2321
2322 // Add which for key events
2323 if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
2324 event.which = event.charCode != null ? event.charCode : event.keyCode;
2325 }
2326
2327 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
2328 if ( !event.metaKey && event.ctrlKey ) {
2329 event.metaKey = event.ctrlKey;
2330 }
2331
2332 // Add which for click: 1 === left; 2 === middle; 3 === right
2333 // Note: button is not normalized, so don't use it
2334 if ( !event.which && event.button !== undefined ) {
2335 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
2336 }
2337
2338 return event;
2339 },
2340
2341 // Deprecated, use jQuery.guid instead
2342 guid: 1E8,
2343
2344 // Deprecated, use jQuery.proxy instead
2345 proxy: jQuery.proxy,
2346
2347 special: {
2348 ready: {
2349 // Make sure the ready event is setup
2350 setup: jQuery.bindReady,
2351 teardown: jQuery.noop
2352 },
2353
2354 live: {
2355 add: function( handleObj ) {
2356 jQuery.event.add( this,
2357 liveConvert( handleObj.origType, handleObj.selector ),
2358 jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
2359 },
2360
2361 remove: function( handleObj ) {
2362 jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
2363 }
2364 },
2365
2366 beforeunload: {
2367 setup: function( data, namespaces, eventHandle ) {
2368 // We only want to do this special case on windows
2369 if ( jQuery.isWindow( this ) ) {
2370 this.onbeforeunload = eventHandle;
2371 }
2372 },
2373
2374 teardown: function( namespaces, eventHandle ) {
2375 if ( this.onbeforeunload === eventHandle ) {
2376 this.onbeforeunload = null;
2377 }
2378 }
2379 }
2380 }
2381};
2382
2383jQuery.removeEvent = document.removeEventListener ?
2384 function( elem, type, handle ) {
2385 if ( elem.removeEventListener ) {
2386 elem.removeEventListener( type, handle, false );
2387 }
2388 } :
2389 function( elem, type, handle ) {
2390 if ( elem.detachEvent ) {
2391 elem.detachEvent( "on" + type, handle );
2392 }
2393 };
2394
2395jQuery.Event = function( src ) {
2396 // Allow instantiation without the 'new' keyword
2397 if ( !this.preventDefault ) {
2398 return new jQuery.Event( src );
2399 }
2400
2401 // Event object
2402 if ( src && src.type ) {
2403 this.originalEvent = src;
2404 this.type = src.type;
2405 // Event type
2406 } else {
2407 this.type = src;
2408 }
2409
2410 // timeStamp is buggy for some events on Firefox(#3843)
2411 // So we won't rely on the native value
2412 this.timeStamp = jQuery.now();
2413
2414 // Mark it as fixed
2415 this[ jQuery.expando ] = true;
2416};
2417
2418function returnFalse() {
2419 return false;
2420}
2421function returnTrue() {
2422 return true;
2423}
2424
2425// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
2426// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
2427jQuery.Event.prototype = {
2428 preventDefault: function() {
2429 this.isDefaultPrevented = returnTrue;
2430
2431 var e = this.originalEvent;
2432 if ( !e ) {
2433 return;
2434 }
2435
2436 // if preventDefault exists run it on the original event
2437 if ( e.preventDefault ) {
2438 e.preventDefault();
2439
2440 // otherwise set the returnValue property of the original event to false (IE)
2441 } else {
2442 e.returnValue = false;
2443 }
2444 },
2445 stopPropagation: function() {
2446 this.isPropagationStopped = returnTrue;
2447
2448 var e = this.originalEvent;
2449 if ( !e ) {
2450 return;
2451 }
2452 // if stopPropagation exists run it on the original event
2453 if ( e.stopPropagation ) {
2454 e.stopPropagation();
2455 }
2456 // otherwise set the cancelBubble property of the original event to true (IE)
2457 e.cancelBubble = true;
2458 },
2459 stopImmediatePropagation: function() {
2460 this.isImmediatePropagationStopped = returnTrue;
2461 this.stopPropagation();
2462 },
2463 isDefaultPrevented: returnFalse,
2464 isPropagationStopped: returnFalse,
2465 isImmediatePropagationStopped: returnFalse
2466};
2467
2468// Checks if an event happened on an element within another element
2469// Used in jQuery.event.special.mouseenter and mouseleave handlers
2470var withinElement = function( event ) {
2471 // Check if mouse(over|out) are still within the same parent element
2472 var parent = event.relatedTarget;
2473
2474 // Firefox sometimes assigns relatedTarget a XUL element
2475 // which we cannot access the parentNode property of
2476 try {
2477 // Traverse up the tree
2478 while ( parent && parent !== this ) {
2479 parent = parent.parentNode;
2480 }
2481
2482 if ( parent !== this ) {
2483 // set the correct event type
2484 event.type = event.data;
2485
2486 // handle event if we actually just moused on to a non sub-element
2487 jQuery.event.handle.apply( this, arguments );
2488 }
2489
2490 // assuming we've left the element since we most likely mousedover a xul element
2491 } catch(e) { }
2492},
2493
2494// In case of event delegation, we only need to rename the event.type,
2495// liveHandler will take care of the rest.
2496delegate = function( event ) {
2497 event.type = event.data;
2498 jQuery.event.handle.apply( this, arguments );
2499};
2500
2501// Create mouseenter and mouseleave events
2502jQuery.each({
2503 mouseenter: "mouseover",
2504 mouseleave: "mouseout"
2505}, function( orig, fix ) {
2506 jQuery.event.special[ orig ] = {
2507 setup: function( data ) {
2508 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
2509 },
2510 teardown: function( data ) {
2511 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
2512 }
2513 };
2514});
2515
2516// submit delegation
2517if ( !jQuery.support.submitBubbles ) {
2518
2519 jQuery.event.special.submit = {
2520 setup: function( data, namespaces ) {
2521 if ( this.nodeName.toLowerCase() !== "form" ) {
2522 jQuery.event.add(this, "click.specialSubmit", function( e ) {
2523 var elem = e.target,
2524 type = elem.type;
2525
2526 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
2527 e.liveFired = undefined;
2528 return trigger( "submit", this, arguments );
2529 }
2530 });
2531
2532 jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
2533 var elem = e.target,
2534 type = elem.type;
2535
2536 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
2537 e.liveFired = undefined;
2538 return trigger( "submit", this, arguments );
2539 }
2540 });
2541
2542 } else {
2543 return false;
2544 }
2545 },
2546
2547 teardown: function( namespaces ) {
2548 jQuery.event.remove( this, ".specialSubmit" );
2549 }
2550 };
2551
2552}
2553
2554// change delegation, happens here so we have bind.
2555if ( !jQuery.support.changeBubbles ) {
2556
2557 var changeFilters,
2558
2559 getVal = function( elem ) {
2560 var type = elem.type, val = elem.value;
2561
2562 if ( type === "radio" || type === "checkbox" ) {
2563 val = elem.checked;
2564
2565 } else if ( type === "select-multiple" ) {
2566 val = elem.selectedIndex > -1 ?
2567 jQuery.map( elem.options, function( elem ) {
2568 return elem.selected;
2569 }).join("-") :
2570 "";
2571
2572 } else if ( elem.nodeName.toLowerCase() === "select" ) {
2573 val = elem.selectedIndex;
2574 }
2575
2576 return val;
2577 },
2578
2579 testChange = function testChange( e ) {
2580 var elem = e.target, data, val;
2581
2582 if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
2583 return;
2584 }
2585
2586 data = jQuery.data( elem, "_change_data" );
2587 val = getVal(elem);
2588
2589 // the current data will be also retrieved by beforeactivate
2590 if ( e.type !== "focusout" || elem.type !== "radio" ) {
2591 jQuery.data( elem, "_change_data", val );
2592 }
2593
2594 if ( data === undefined || val === data ) {
2595 return;
2596 }
2597
2598 if ( data != null || val ) {
2599 e.type = "change";
2600 e.liveFired = undefined;
2601 return jQuery.event.trigger( e, arguments[1], elem );
2602 }
2603 };
2604
2605 jQuery.event.special.change = {
2606 filters: {
2607 focusout: testChange,
2608
2609 beforedeactivate: testChange,
2610
2611 click: function( e ) {
2612 var elem = e.target, type = elem.type;
2613
2614 if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
2615 return testChange.call( this, e );
2616 }
2617 },
2618
2619 // Change has to be called before submit
2620 // Keydown will be called before keypress, which is used in submit-event delegation
2621 keydown: function( e ) {
2622 var elem = e.target, type = elem.type;
2623
2624 if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
2625 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
2626 type === "select-multiple" ) {
2627 return testChange.call( this, e );
2628 }
2629 },
2630
2631 // Beforeactivate happens also before the previous element is blurred
2632 // with this event you can't trigger a change event, but you can store
2633 // information
2634 beforeactivate: function( e ) {
2635 var elem = e.target;
2636 jQuery.data( elem, "_change_data", getVal(elem) );
2637 }
2638 },
2639
2640 setup: function( data, namespaces ) {
2641 if ( this.type === "file" ) {
2642 return false;
2643 }
2644
2645 for ( var type in changeFilters ) {
2646 jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
2647 }
2648
2649 return rformElems.test( this.nodeName );
2650 },
2651
2652 teardown: function( namespaces ) {
2653 jQuery.event.remove( this, ".specialChange" );
2654
2655 return rformElems.test( this.nodeName );
2656 }
2657 };
2658
2659 changeFilters = jQuery.event.special.change.filters;
2660
2661 // Handle when the input is .focus()'d
2662 changeFilters.focus = changeFilters.beforeactivate;
2663}
2664
2665function trigger( type, elem, args ) {
2666 args[0].type = type;
2667 return jQuery.event.handle.apply( elem, args );
2668}
2669
2670// Create "bubbling" focus and blur events
2671if ( document.addEventListener ) {
2672 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
2673 jQuery.event.special[ fix ] = {
2674 setup: function() {
2675 if ( focusCounts[fix]++ === 0 ) {
2676 document.addEventListener( orig, handler, true );
2677 }
2678 },
2679 teardown: function() {
2680 if ( --focusCounts[fix] === 0 ) {
2681 document.removeEventListener( orig, handler, true );
2682 }
2683 }
2684 };
2685
2686 function handler( e ) {
2687 e = jQuery.event.fix( e );
2688 e.type = fix;
2689 return jQuery.event.trigger( e, null, e.target );
2690 }
2691 });
2692}
2693
2694jQuery.each(["bind", "one"], function( i, name ) {
2695 jQuery.fn[ name ] = function( type, data, fn ) {
2696 // Handle object literals
2697 if ( typeof type === "object" ) {
2698 for ( var key in type ) {
2699 this[ name ](key, data, type[key], fn);
2700 }
2701 return this;
2702 }
2703
2704 if ( jQuery.isFunction( data ) || data === false ) {
2705 fn = data;
2706 data = undefined;
2707 }
2708
2709 var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
2710 jQuery( this ).unbind( event, handler );
2711 return fn.apply( this, arguments );
2712 }) : fn;
2713
2714 if ( type === "unload" && name !== "one" ) {
2715 this.one( type, data, fn );
2716
2717 } else {
2718 for ( var i = 0, l = this.length; i < l; i++ ) {
2719 jQuery.event.add( this[i], type, handler, data );
2720 }
2721 }
2722
2723 return this;
2724 };
2725});
2726
2727jQuery.fn.extend({
2728 unbind: function( type, fn ) {
2729 // Handle object literals
2730 if ( typeof type === "object" && !type.preventDefault ) {
2731 for ( var key in type ) {
2732 this.unbind(key, type[key]);
2733 }
2734
2735 } else {
2736 for ( var i = 0, l = this.length; i < l; i++ ) {
2737 jQuery.event.remove( this[i], type, fn );
2738 }
2739 }
2740
2741 return this;
2742 },
2743
2744 delegate: function( selector, types, data, fn ) {
2745 return this.live( types, data, fn, selector );
2746 },
2747
2748 undelegate: function( selector, types, fn ) {
2749 if ( arguments.length === 0 ) {
2750 return this.unbind( "live" );
2751
2752 } else {
2753 return this.die( types, null, fn, selector );
2754 }
2755 },
2756
2757 trigger: function( type, data ) {
2758 return this.each(function() {
2759 jQuery.event.trigger( type, data, this );
2760 });
2761 },
2762
2763 triggerHandler: function( type, data ) {
2764 if ( this[0] ) {
2765 var event = jQuery.Event( type );
2766 event.preventDefault();
2767 event.stopPropagation();
2768 jQuery.event.trigger( event, data, this[0] );
2769 return event.result;
2770 }
2771 },
2772
2773 toggle: function( fn ) {
2774 // Save reference to arguments for access in closure
2775 var args = arguments,
2776 i = 1;
2777
2778 // link all the functions, so any of them can unbind this click handler
2779 while ( i < args.length ) {
2780 jQuery.proxy( fn, args[ i++ ] );
2781 }
2782
2783 return this.click( jQuery.proxy( fn, function( event ) {
2784 // Figure out which function to execute
2785 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
2786 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
2787
2788 // Make sure that clicks stop
2789 event.preventDefault();
2790
2791 // and execute the function
2792 return args[ lastToggle ].apply( this, arguments ) || false;
2793 }));
2794 },
2795
2796 hover: function( fnOver, fnOut ) {
2797 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
2798 }
2799});
2800
2801var liveMap = {
2802 focus: "focusin",
2803 blur: "focusout",
2804 mouseenter: "mouseover",
2805 mouseleave: "mouseout"
2806};
2807
2808jQuery.each(["live", "die"], function( i, name ) {
2809 jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
2810 var type, i = 0, match, namespaces, preType,
2811 selector = origSelector || this.selector,
2812 context = origSelector ? this : jQuery( this.context );
2813
2814 if ( typeof types === "object" && !types.preventDefault ) {
2815 for ( var key in types ) {
2816 context[ name ]( key, data, types[key], selector );
2817 }
2818
2819 return this;
2820 }
2821
2822 if ( jQuery.isFunction( data ) ) {
2823 fn = data;
2824 data = undefined;
2825 }
2826
2827 types = (types || "").split(" ");
2828
2829 while ( (type = types[ i++ ]) != null ) {
2830 match = rnamespaces.exec( type );
2831 namespaces = "";
2832
2833 if ( match ) {
2834 namespaces = match[0];
2835 type = type.replace( rnamespaces, "" );
2836 }
2837
2838 if ( type === "hover" ) {
2839 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
2840 continue;
2841 }
2842
2843 preType = type;
2844
2845 if ( type === "focus" || type === "blur" ) {
2846 types.push( liveMap[ type ] + namespaces );
2847 type = type + namespaces;
2848
2849 } else {
2850 type = (liveMap[ type ] || type) + namespaces;
2851 }
2852
2853 if ( name === "live" ) {
2854 // bind live handler
2855 for ( var j = 0, l = context.length; j < l; j++ ) {
2856 jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
2857 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
2858 }
2859
2860 } else {
2861 // unbind live handler
2862 context.unbind( "live." + liveConvert( type, selector ), fn );
2863 }
2864 }
2865
2866 return this;
2867 };
2868});
2869
2870function liveHandler( event ) {
2871 var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
2872 elems = [],
2873 selectors = [],
2874 events = jQuery.data( this, this.nodeType ? "events" : "__events__" );
2875
2876 if ( typeof events === "function" ) {
2877 events = events.events;
2878 }
2879
2880 // Make sure we avoid non-left-click bubbling in Firefox (#3861)
2881 if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
2882 return;
2883 }
2884
2885 if ( event.namespace ) {
2886 namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
2887 }
2888
2889 event.liveFired = this;
2890
2891 var live = events.live.slice(0);
2892
2893 for ( j = 0; j < live.length; j++ ) {
2894 handleObj = live[j];
2895
2896 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
2897 selectors.push( handleObj.selector );
2898
2899 } else {
2900 live.splice( j--, 1 );
2901 }
2902 }
2903
2904 match = jQuery( event.target ).closest( selectors, event.currentTarget );
2905
2906 for ( i = 0, l = match.length; i < l; i++ ) {
2907 close = match[i];
2908
2909 for ( j = 0; j < live.length; j++ ) {
2910 handleObj = live[j];
2911
2912 if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) ) {
2913 elem = close.elem;
2914 related = null;
2915
2916 // Those two events require additional checking
2917 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
2918 event.type = handleObj.preType;
2919 related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
2920 }
2921
2922 if ( !related || related !== elem ) {
2923 elems.push({ elem: elem, handleObj: handleObj, level: close.level });
2924 }
2925 }
2926 }
2927 }
2928
2929 for ( i = 0, l = elems.length; i < l; i++ ) {
2930 match = elems[i];
2931
2932 if ( maxLevel && match.level > maxLevel ) {
2933 break;
2934 }
2935
2936 event.currentTarget = match.elem;
2937 event.data = match.handleObj.data;
2938 event.handleObj = match.handleObj;
2939
2940 ret = match.handleObj.origHandler.apply( match.elem, arguments );
2941
2942 if ( ret === false || event.isPropagationStopped() ) {
2943 maxLevel = match.level;
2944
2945 if ( ret === false ) {
2946 stop = false;
2947 }
2948 if ( event.isImmediatePropagationStopped() ) {
2949 break;
2950 }
2951 }
2952 }
2953
2954 return stop;
2955}
2956
2957function liveConvert( type, selector ) {
2958 return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspace, "&");
2959}
2960
2961jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
2962 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
2963 "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
2964
2965 // Handle event binding
2966 jQuery.fn[ name ] = function( data, fn ) {
2967 if ( fn == null ) {
2968 fn = data;
2969 data = null;
2970 }
2971
2972 return arguments.length > 0 ?
2973 this.bind( name, data, fn ) :
2974 this.trigger( name );
2975 };
2976
2977 if ( jQuery.attrFn ) {
2978 jQuery.attrFn[ name ] = true;
2979 }
2980});
2981
2982// Prevent memory leaks in IE
2983// Window isn't included so as not to unbind existing unload events
2984// More info:
2985// - http://isaacschlueter.com/2006/10/msie-memory-leaks/
2986if ( window.attachEvent && !window.addEventListener ) {
2987 jQuery(window).bind("unload", function() {
2988 for ( var id in jQuery.cache ) {
2989 if ( jQuery.cache[ id ].handle ) {
2990 // Try/Catch is to handle iframes being unloaded, see #4280
2991 try {
2992 jQuery.event.remove( jQuery.cache[ id ].handle.elem );
2993 } catch(e) {}
2994 }
2995 }
2996 });
2997}
2998
2999
3000/*!
3001 * Sizzle CSS Selector Engine - v1.0
3002 * Copyright 2009, The Dojo Foundation
3003 * Released under the MIT, BSD, and GPL Licenses.
3004 * More information: http://sizzlejs.com/
3005 */
3006(function(){
3007
3008var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
3009 done = 0,
3010 toString = Object.prototype.toString,
3011 hasDuplicate = false,
3012 baseHasDuplicate = true;
3013
3014// Here we check if the JavaScript engine is using some sort of
3015// optimization where it does not always call our comparision
3016// function. If that is the case, discard the hasDuplicate value.
3017// Thus far that includes Google Chrome.
3018[0, 0].sort(function() {
3019 baseHasDuplicate = false;
3020 return 0;
3021});
3022
3023var Sizzle = function( selector, context, results, seed ) {
3024 results = results || [];
3025 context = context || document;
3026
3027 var origContext = context;
3028
3029 if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
3030 return [];
3031 }
3032
3033 if ( !selector || typeof selector !== "string" ) {
3034 return results;
3035 }
3036
3037 var m, set, checkSet, extra, ret, cur, pop, i,
3038 prune = true,
3039 contextXML = Sizzle.isXML( context ),
3040 parts = [],
3041 soFar = selector;
3042
3043 // Reset the position of the chunker regexp (start from head)
3044 do {
3045 chunker.exec( "" );
3046 m = chunker.exec( soFar );
3047
3048 if ( m ) {
3049 soFar = m[3];
3050
3051 parts.push( m[1] );
3052
3053 if ( m[2] ) {
3054 extra = m[3];
3055 break;
3056 }
3057 }
3058 } while ( m );
3059
3060 if ( parts.length > 1 && origPOS.exec( selector ) ) {
3061
3062 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
3063 set = posProcess( parts[0] + parts[1], context );
3064
3065 } else {
3066 set = Expr.relative[ parts[0] ] ?
3067 [ context ] :
3068 Sizzle( parts.shift(), context );
3069
3070 while ( parts.length ) {
3071 selector = parts.shift();
3072
3073 if ( Expr.relative[ selector ] ) {
3074 selector += parts.shift();
3075 }
3076
3077 set = posProcess( selector, set );
3078 }
3079 }
3080
3081 } else {
3082 // Take a shortcut and set the context if the root selector is an ID
3083 // (but not if it'll be faster if the inner selector is an ID)
3084 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
3085 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
3086
3087 ret = Sizzle.find( parts.shift(), context, contextXML );
3088 context = ret.expr ?
3089 Sizzle.filter( ret.expr, ret.set )[0] :
3090 ret.set[0];
3091 }
3092
3093 if ( context ) {
3094 ret = seed ?
3095 { expr: parts.pop(), set: makeArray(seed) } :
3096 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
3097
3098 set = ret.expr ?
3099 Sizzle.filter( ret.expr, ret.set ) :
3100 ret.set;
3101
3102 if ( parts.length > 0 ) {
3103 checkSet = makeArray( set );
3104
3105 } else {
3106 prune = false;
3107 }
3108
3109 while ( parts.length ) {
3110 cur = parts.pop();
3111 pop = cur;
3112
3113 if ( !Expr.relative[ cur ] ) {
3114 cur = "";
3115 } else {
3116 pop = parts.pop();
3117 }
3118
3119 if ( pop == null ) {
3120 pop = context;
3121 }
3122
3123 Expr.relative[ cur ]( checkSet, pop, contextXML );
3124 }
3125
3126 } else {
3127 checkSet = parts = [];
3128 }
3129 }
3130
3131 if ( !checkSet ) {
3132 checkSet = set;
3133 }
3134
3135 if ( !checkSet ) {
3136 Sizzle.error( cur || selector );
3137 }
3138
3139 if ( toString.call(checkSet) === "[object Array]" ) {
3140 if ( !prune ) {
3141 results.push.apply( results, checkSet );
3142
3143 } else if ( context && context.nodeType === 1 ) {
3144 for ( i = 0; checkSet[i] != null; i++ ) {
3145 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
3146 results.push( set[i] );
3147 }
3148 }
3149
3150 } else {
3151 for ( i = 0; checkSet[i] != null; i++ ) {
3152 if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
3153 results.push( set[i] );
3154 }
3155 }
3156 }
3157
3158 } else {
3159 makeArray( checkSet, results );
3160 }
3161
3162 if ( extra ) {
3163 Sizzle( extra, origContext, results, seed );
3164 Sizzle.uniqueSort( results );
3165 }
3166
3167 return results;
3168};
3169
3170Sizzle.uniqueSort = function( results ) {
3171 if ( sortOrder ) {
3172 hasDuplicate = baseHasDuplicate;
3173 results.sort( sortOrder );
3174
3175 if ( hasDuplicate ) {
3176 for ( var i = 1; i < results.length; i++ ) {
3177 if ( results[i] === results[ i - 1 ] ) {
3178 results.splice( i--, 1 );
3179 }
3180 }
3181 }
3182 }
3183
3184 return results;
3185};
3186
3187Sizzle.matches = function( expr, set ) {
3188 return Sizzle( expr, null, null, set );
3189};
3190
3191Sizzle.matchesSelector = function( node, expr ) {
3192 return Sizzle( expr, null, null, [node] ).length > 0;
3193};
3194
3195Sizzle.find = function( expr, context, isXML ) {
3196 var set;
3197
3198 if ( !expr ) {
3199 return [];
3200 }
3201
3202 for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
3203 var match,
3204 type = Expr.order[i];
3205
3206 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
3207 var left = match[1];
3208 match.splice( 1, 1 );
3209
3210 if ( left.substr( left.length - 1 ) !== "\\" ) {
3211 match[1] = (match[1] || "").replace(/\\/g, "");
3212 set = Expr.find[ type ]( match, context, isXML );
3213
3214 if ( set != null ) {
3215 expr = expr.replace( Expr.match[ type ], "" );
3216 break;
3217 }
3218 }
3219 }
3220 }
3221
3222 if ( !set ) {
3223 set = context.getElementsByTagName( "*" );
3224 }
3225
3226 return { set: set, expr: expr };
3227};
3228
3229Sizzle.filter = function( expr, set, inplace, not ) {
3230 var match, anyFound,
3231 old = expr,
3232 result = [],
3233 curLoop = set,
3234 isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
3235
3236 while ( expr && set.length ) {
3237 for ( var type in Expr.filter ) {
3238 if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
3239 var found, item,
3240 filter = Expr.filter[ type ],
3241 left = match[1];
3242
3243 anyFound = false;
3244
3245 match.splice(1,1);
3246
3247 if ( left.substr( left.length - 1 ) === "\\" ) {
3248 continue;
3249 }
3250
3251 if ( curLoop === result ) {
3252 result = [];
3253 }
3254
3255 if ( Expr.preFilter[ type ] ) {
3256 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
3257
3258 if ( !match ) {
3259 anyFound = found = true;
3260
3261 } else if ( match === true ) {
3262 continue;
3263 }
3264 }
3265
3266 if ( match ) {
3267 for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
3268 if ( item ) {
3269 found = filter( item, match, i, curLoop );
3270 var pass = not ^ !!found;
3271
3272 if ( inplace && found != null ) {
3273 if ( pass ) {
3274 anyFound = true;
3275
3276 } else {
3277 curLoop[i] = false;
3278 }
3279
3280 } else if ( pass ) {
3281 result.push( item );
3282 anyFound = true;
3283 }
3284 }
3285 }
3286 }
3287
3288 if ( found !== undefined ) {
3289 if ( !inplace ) {
3290 curLoop = result;
3291 }
3292
3293 expr = expr.replace( Expr.match[ type ], "" );
3294
3295 if ( !anyFound ) {
3296 return [];
3297 }
3298
3299 break;
3300 }
3301 }
3302 }
3303
3304 // Improper expression
3305 if ( expr === old ) {
3306 if ( anyFound == null ) {
3307 Sizzle.error( expr );
3308
3309 } else {
3310 break;
3311 }
3312 }
3313
3314 old = expr;
3315 }
3316
3317 return curLoop;
3318};
3319
3320Sizzle.error = function( msg ) {
3321 throw "Syntax error, unrecognized expression: " + msg;
3322};
3323
3324var Expr = Sizzle.selectors = {
3325 order: [ "ID", "NAME", "TAG" ],
3326
3327 match: {
3328 ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
3329 CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
3330 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
3331 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
3332 TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
3333 CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/,
3334 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
3335 PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
3336 },
3337
3338 leftMatch: {},
3339
3340 attrMap: {
3341 "class": "className",
3342 "for": "htmlFor"
3343 },
3344
3345 attrHandle: {
3346 href: function( elem ) {
3347 return elem.getAttribute( "href" );
3348 }
3349 },
3350
3351 relative: {
3352 "+": function(checkSet, part){
3353 var isPartStr = typeof part === "string",
3354 isTag = isPartStr && !/\W/.test( part ),
3355 isPartStrNotTag = isPartStr && !isTag;
3356
3357 if ( isTag ) {
3358 part = part.toLowerCase();
3359 }
3360
3361 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
3362 if ( (elem = checkSet[i]) ) {
3363 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
3364
3365 checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
3366 elem || false :
3367 elem === part;
3368 }
3369 }
3370
3371 if ( isPartStrNotTag ) {
3372 Sizzle.filter( part, checkSet, true );
3373 }
3374 },
3375
3376 ">": function( checkSet, part ) {
3377 var elem,
3378 isPartStr = typeof part === "string",
3379 i = 0,
3380 l = checkSet.length;
3381
3382 if ( isPartStr && !/\W/.test( part ) ) {
3383 part = part.toLowerCase();
3384
3385 for ( ; i < l; i++ ) {
3386 elem = checkSet[i];
3387
3388 if ( elem ) {
3389 var parent = elem.parentNode;
3390 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
3391 }
3392 }
3393
3394 } else {
3395 for ( ; i < l; i++ ) {
3396 elem = checkSet[i];
3397
3398 if ( elem ) {
3399 checkSet[i] = isPartStr ?
3400 elem.parentNode :
3401 elem.parentNode === part;
3402 }
3403 }
3404
3405 if ( isPartStr ) {
3406 Sizzle.filter( part, checkSet, true );
3407 }
3408 }
3409 },
3410
3411 "": function(checkSet, part, isXML){
3412 var nodeCheck,
3413 doneName = done++,
3414 checkFn = dirCheck;
3415
3416 if ( typeof part === "string" && !/\W/.test(part) ) {
3417 part = part.toLowerCase();
3418 nodeCheck = part;
3419 checkFn = dirNodeCheck;
3420 }
3421
3422 checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
3423 },
3424
3425 "~": function( checkSet, part, isXML ) {
3426 var nodeCheck,
3427 doneName = done++,
3428 checkFn = dirCheck;
3429
3430 if ( typeof part === "string" && !/\W/.test( part ) ) {
3431 part = part.toLowerCase();
3432 nodeCheck = part;
3433 checkFn = dirNodeCheck;
3434 }
3435
3436 checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
3437 }
3438 },
3439
3440 find: {
3441 ID: function( match, context, isXML ) {
3442 if ( typeof context.getElementById !== "undefined" && !isXML ) {
3443 var m = context.getElementById(match[1]);
3444 // Check parentNode to catch when Blackberry 4.6 returns
3445 // nodes that are no longer in the document #6963
3446 return m && m.parentNode ? [m] : [];
3447 }
3448 },
3449
3450 NAME: function( match, context ) {
3451 if ( typeof context.getElementsByName !== "undefined" ) {
3452 var ret = [],
3453 results = context.getElementsByName( match[1] );
3454
3455 for ( var i = 0, l = results.length; i < l; i++ ) {
3456 if ( results[i].getAttribute("name") === match[1] ) {
3457 ret.push( results[i] );
3458 }
3459 }
3460
3461 return ret.length === 0 ? null : ret;
3462 }
3463 },
3464
3465 TAG: function( match, context ) {
3466 return context.getElementsByTagName( match[1] );
3467 }
3468 },
3469 preFilter: {
3470 CLASS: function( match, curLoop, inplace, result, not, isXML ) {
3471 match = " " + match[1].replace(/\\/g, "") + " ";
3472
3473 if ( isXML ) {
3474 return match;
3475 }
3476
3477 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
3478 if ( elem ) {
3479 if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
3480 if ( !inplace ) {
3481 result.push( elem );
3482 }
3483
3484 } else if ( inplace ) {
3485 curLoop[i] = false;
3486 }
3487 }
3488 }
3489
3490 return false;
3491 },
3492
3493 ID: function( match ) {
3494 return match[1].replace(/\\/g, "");
3495 },
3496
3497 TAG: function( match, curLoop ) {
3498 return match[1].toLowerCase();
3499 },
3500
3501 CHILD: function( match ) {
3502 if ( match[1] === "nth" ) {
3503 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
3504 var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
3505 match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
3506 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
3507
3508 // calculate the numbers (first)n+(last) including if they are negative
3509 match[2] = (test[1] + (test[2] || 1)) - 0;
3510 match[3] = test[3] - 0;
3511 }
3512
3513 // TODO: Move to normal caching system
3514 match[0] = done++;
3515
3516 return match;
3517 },
3518
3519 ATTR: function( match, curLoop, inplace, result, not, isXML ) {
3520 var name = match[1].replace(/\\/g, "");
3521
3522 if ( !isXML && Expr.attrMap[name] ) {
3523 match[1] = Expr.attrMap[name];
3524 }
3525
3526 if ( match[2] === "~=" ) {
3527 match[4] = " " + match[4] + " ";
3528 }
3529
3530 return match;
3531 },
3532
3533 PSEUDO: function( match, curLoop, inplace, result, not ) {
3534 if ( match[1] === "not" ) {
3535 // If we're dealing with a complex expression, or a simple one
3536 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
3537 match[3] = Sizzle(match[3], null, null, curLoop);
3538
3539 } else {
3540 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
3541
3542 if ( !inplace ) {
3543 result.push.apply( result, ret );
3544 }
3545
3546 return false;
3547 }
3548
3549 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
3550 return true;
3551 }
3552
3553 return match;
3554 },
3555
3556 POS: function( match ) {
3557 match.unshift( true );
3558
3559 return match;
3560 }
3561 },
3562
3563 filters: {
3564 enabled: function( elem ) {
3565 return elem.disabled === false && elem.type !== "hidden";
3566 },
3567
3568 disabled: function( elem ) {
3569 return elem.disabled === true;
3570 },
3571
3572 checked: function( elem ) {
3573 return elem.checked === true;
3574 },
3575
3576 selected: function( elem ) {
3577 // Accessing this property makes selected-by-default
3578 // options in Safari work properly
3579 elem.parentNode.selectedIndex;
3580
3581 return elem.selected === true;
3582 },
3583
3584 parent: function( elem ) {
3585 return !!elem.firstChild;
3586 },
3587
3588 empty: function( elem ) {
3589 return !elem.firstChild;
3590 },
3591
3592 has: function( elem, i, match ) {
3593 return !!Sizzle( match[3], elem ).length;
3594 },
3595
3596 header: function( elem ) {
3597 return (/h\d/i).test( elem.nodeName );
3598 },
3599
3600 text: function( elem ) {
3601 return "text" === elem.type;
3602 },
3603 radio: function( elem ) {
3604 return "radio" === elem.type;
3605 },
3606
3607 checkbox: function( elem ) {
3608 return "checkbox" === elem.type;
3609 },
3610
3611 file: function( elem ) {
3612 return "file" === elem.type;
3613 },
3614 password: function( elem ) {
3615 return "password" === elem.type;
3616 },
3617
3618 submit: function( elem ) {
3619 return "submit" === elem.type;
3620 },
3621
3622 image: function( elem ) {
3623 return "image" === elem.type;
3624 },
3625
3626 reset: function( elem ) {
3627 return "reset" === elem.type;
3628 },
3629
3630 button: function( elem ) {
3631 return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
3632 },
3633
3634 input: function( elem ) {
3635 return (/input|select|textarea|button/i).test( elem.nodeName );
3636 }
3637 },
3638 setFilters: {
3639 first: function( elem, i ) {
3640 return i === 0;
3641 },
3642
3643 last: function( elem, i, match, array ) {
3644 return i === array.length - 1;
3645 },
3646
3647 even: function( elem, i ) {
3648 return i % 2 === 0;
3649 },
3650
3651 odd: function( elem, i ) {
3652 return i % 2 === 1;
3653 },
3654
3655 lt: function( elem, i, match ) {
3656 return i < match[3] - 0;
3657 },
3658
3659 gt: function( elem, i, match ) {
3660 return i > match[3] - 0;
3661 },
3662
3663 nth: function( elem, i, match ) {
3664 return match[3] - 0 === i;
3665 },
3666
3667 eq: function( elem, i, match ) {
3668 return match[3] - 0 === i;
3669 }
3670 },
3671 filter: {
3672 PSEUDO: function( elem, match, i, array ) {
3673 var name = match[1],
3674 filter = Expr.filters[ name ];
3675
3676 if ( filter ) {
3677 return filter( elem, i, match, array );
3678
3679 } else if ( name === "contains" ) {
3680 return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
3681
3682 } else if ( name === "not" ) {
3683 var not = match[3];
3684
3685 for ( var j = 0, l = not.length; j < l; j++ ) {
3686 if ( not[j] === elem ) {
3687 return false;
3688 }
3689 }
3690
3691 return true;
3692
3693 } else {
3694 Sizzle.error( "Syntax error, unrecognized expression: " + name );
3695 }
3696 },
3697
3698 CHILD: function( elem, match ) {
3699 var type = match[1],
3700 node = elem;
3701
3702 switch ( type ) {
3703 case "only":
3704 case "first":
3705 while ( (node = node.previousSibling) ) {
3706 if ( node.nodeType === 1 ) {
3707 return false;
3708 }
3709 }
3710
3711 if ( type === "first" ) {
3712 return true;
3713 }
3714
3715 node = elem;
3716
3717 case "last":
3718 while ( (node = node.nextSibling) ) {
3719 if ( node.nodeType === 1 ) {
3720 return false;
3721 }
3722 }
3723
3724 return true;
3725
3726 case "nth":
3727 var first = match[2],
3728 last = match[3];
3729
3730 if ( first === 1 && last === 0 ) {
3731 return true;
3732 }
3733
3734 var doneName = match[0],
3735 parent = elem.parentNode;
3736
3737 if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
3738 var count = 0;
3739
3740 for ( node = parent.firstChild; node; node = node.nextSibling ) {
3741 if ( node.nodeType === 1 ) {
3742 node.nodeIndex = ++count;
3743 }
3744 }
3745
3746 parent.sizcache = doneName;
3747 }
3748
3749 var diff = elem.nodeIndex - last;
3750
3751 if ( first === 0 ) {
3752 return diff === 0;
3753
3754 } else {
3755 return ( diff % first === 0 && diff / first >= 0 );
3756 }
3757 }
3758 },
3759
3760 ID: function( elem, match ) {
3761 return elem.nodeType === 1 && elem.getAttribute("id") === match;
3762 },
3763
3764 TAG: function( elem, match ) {
3765 return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
3766 },
3767
3768 CLASS: function( elem, match ) {
3769 return (" " + (elem.className || elem.getAttribute("class")) + " ")
3770 .indexOf( match ) > -1;
3771 },
3772
3773 ATTR: function( elem, match ) {
3774 var name = match[1],
3775 result = Expr.attrHandle[ name ] ?
3776 Expr.attrHandle[ name ]( elem ) :
3777 elem[ name ] != null ?
3778 elem[ name ] :
3779 elem.getAttribute( name ),
3780 value = result + "",
3781 type = match[2],
3782 check = match[4];
3783
3784 return result == null ?
3785 type === "!=" :
3786 type === "=" ?
3787 value === check :
3788 type === "*=" ?
3789 value.indexOf(check) >= 0 :
3790 type === "~=" ?
3791 (" " + value + " ").indexOf(check) >= 0 :
3792 !check ?
3793 value && result !== false :
3794 type === "!=" ?
3795 value !== check :
3796 type === "^=" ?
3797 value.indexOf(check) === 0 :
3798 type === "$=" ?
3799 value.substr(value.length - check.length) === check :
3800 type === "|=" ?
3801 value === check || value.substr(0, check.length + 1) === check + "-" :
3802 false;
3803 },
3804
3805 POS: function( elem, match, i, array ) {
3806 var name = match[2],
3807 filter = Expr.setFilters[ name ];
3808
3809 if ( filter ) {
3810 return filter( elem, i, match, array );
3811 }
3812 }
3813 }
3814};
3815
3816var origPOS = Expr.match.POS,
3817 fescape = function(all, num){
3818 return "\\" + (num - 0 + 1);
3819 };
3820
3821for ( var type in Expr.match ) {
3822 Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
3823 Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
3824}
3825
3826var makeArray = function( array, results ) {
3827 array = Array.prototype.slice.call( array, 0 );
3828
3829 if ( results ) {
3830 results.push.apply( results, array );
3831 return results;
3832 }
3833
3834 return array;
3835};
3836
3837// Perform a simple check to determine if the browser is capable of
3838// converting a NodeList to an array using builtin methods.
3839// Also verifies that the returned array holds DOM nodes
3840// (which is not the case in the Blackberry browser)
3841try {
3842 Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
3843
3844// Provide a fallback method if it does not work
3845} catch( e ) {
3846 makeArray = function( array, results ) {
3847 var i = 0,
3848 ret = results || [];
3849
3850 if ( toString.call(array) === "[object Array]" ) {
3851 Array.prototype.push.apply( ret, array );
3852
3853 } else {
3854 if ( typeof array.length === "number" ) {
3855 for ( var l = array.length; i < l; i++ ) {
3856 ret.push( array[i] );
3857 }
3858
3859 } else {
3860 for ( ; array[i]; i++ ) {
3861 ret.push( array[i] );
3862 }
3863 }
3864 }
3865
3866 return ret;
3867 };
3868}
3869
3870var sortOrder, siblingCheck;
3871
3872if ( document.documentElement.compareDocumentPosition ) {
3873 sortOrder = function( a, b ) {
3874 if ( a === b ) {
3875 hasDuplicate = true;
3876 return 0;
3877 }
3878
3879 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
3880 return a.compareDocumentPosition ? -1 : 1;
3881 }
3882
3883 return a.compareDocumentPosition(b) & 4 ? -1 : 1;
3884 };
3885
3886} else {
3887 sortOrder = function( a, b ) {
3888 var al, bl,
3889 ap = [],
3890 bp = [],
3891 aup = a.parentNode,
3892 bup = b.parentNode,
3893 cur = aup;
3894
3895 // The nodes are identical, we can exit early
3896 if ( a === b ) {
3897 hasDuplicate = true;
3898 return 0;
3899
3900 // If the nodes are siblings (or identical) we can do a quick check
3901 } else if ( aup === bup ) {
3902 return siblingCheck( a, b );
3903
3904 // If no parents were found then the nodes are disconnected
3905 } else if ( !aup ) {
3906 return -1;
3907
3908 } else if ( !bup ) {
3909 return 1;
3910 }
3911
3912 // Otherwise they're somewhere else in the tree so we need
3913 // to build up a full list of the parentNodes for comparison
3914 while ( cur ) {
3915 ap.unshift( cur );
3916 cur = cur.parentNode;
3917 }
3918
3919 cur = bup;
3920
3921 while ( cur ) {
3922 bp.unshift( cur );
3923 cur = cur.parentNode;
3924 }
3925
3926 al = ap.length;
3927 bl = bp.length;
3928
3929 // Start walking down the tree looking for a discrepancy
3930 for ( var i = 0; i < al && i < bl; i++ ) {
3931 if ( ap[i] !== bp[i] ) {
3932 return siblingCheck( ap[i], bp[i] );
3933 }
3934 }
3935
3936 // We ended someplace up the tree so do a sibling check
3937 return i === al ?
3938 siblingCheck( a, bp[i], -1 ) :
3939 siblingCheck( ap[i], b, 1 );
3940 };
3941
3942 siblingCheck = function( a, b, ret ) {
3943 if ( a === b ) {
3944 return ret;
3945 }
3946
3947 var cur = a.nextSibling;
3948
3949 while ( cur ) {
3950 if ( cur === b ) {
3951 return -1;
3952 }
3953
3954 cur = cur.nextSibling;
3955 }
3956
3957 return 1;
3958 };
3959}
3960
3961// Utility function for retreiving the text value of an array of DOM nodes
3962Sizzle.getText = function( elems ) {
3963 var ret = "", elem;
3964
3965 for ( var i = 0; elems[i]; i++ ) {
3966 elem = elems[i];
3967
3968 // Get the text from text nodes and CDATA nodes
3969 if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
3970 ret += elem.nodeValue;
3971
3972 // Traverse everything else, except comment nodes
3973 } else if ( elem.nodeType !== 8 ) {
3974 ret += Sizzle.getText( elem.childNodes );
3975 }
3976 }
3977
3978 return ret;
3979};
3980
3981// Check to see if the browser returns elements by name when
3982// querying by getElementById (and provide a workaround)
3983(function(){
3984 // We're going to inject a fake input element with a specified name
3985 var form = document.createElement("div"),
3986 id = "script" + (new Date()).getTime(),
3987 root = document.documentElement;
3988
3989 form.innerHTML = "<a name='" + id + "'/>";
3990
3991 // Inject it into the root element, check its status, and remove it quickly
3992 root.insertBefore( form, root.firstChild );
3993
3994 // The workaround has to do additional checks after a getElementById
3995 // Which slows things down for other browsers (hence the branching)
3996 if ( document.getElementById( id ) ) {
3997 Expr.find.ID = function( match, context, isXML ) {
3998 if ( typeof context.getElementById !== "undefined" && !isXML ) {
3999 var m = context.getElementById(match[1]);
4000
4001 return m ?
4002 m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
4003 [m] :
4004 undefined :
4005 [];
4006 }
4007 };
4008
4009 Expr.filter.ID = function( elem, match ) {
4010 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
4011
4012 return elem.nodeType === 1 && node && node.nodeValue === match;
4013 };
4014 }
4015
4016 root.removeChild( form );
4017
4018 // release memory in IE
4019 root = form = null;
4020})();
4021
4022(function(){
4023 // Check to see if the browser returns only elements
4024 // when doing getElementsByTagName("*")
4025
4026 // Create a fake element
4027 var div = document.createElement("div");
4028 div.appendChild( document.createComment("") );
4029
4030 // Make sure no comments are found
4031 if ( div.getElementsByTagName("*").length > 0 ) {
4032 Expr.find.TAG = function( match, context ) {
4033 var results = context.getElementsByTagName( match[1] );
4034
4035 // Filter out possible comments
4036 if ( match[1] === "*" ) {
4037 var tmp = [];
4038
4039 for ( var i = 0; results[i]; i++ ) {
4040 if ( results[i].nodeType === 1 ) {
4041 tmp.push( results[i] );
4042 }
4043 }
4044
4045 results = tmp;
4046 }
4047
4048 return results;
4049 };
4050 }
4051
4052 // Check to see if an attribute returns normalized href attributes
4053 div.innerHTML = "<a href='#'></a>";
4054
4055 if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
4056 div.firstChild.getAttribute("href") !== "#" ) {
4057
4058 Expr.attrHandle.href = function( elem ) {
4059 return elem.getAttribute( "href", 2 );
4060 };
4061 }
4062
4063 // release memory in IE
4064 div = null;
4065})();
4066
4067if ( document.querySelectorAll ) {
4068 (function(){
4069 var oldSizzle = Sizzle,
4070 div = document.createElement("div"),
4071 id = "__sizzle__";
4072
4073 div.innerHTML = "<p class='TEST'></p>";
4074
4075 // Safari can't handle uppercase or unicode characters when
4076 // in quirks mode.
4077 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
4078 return;
4079 }
4080
4081 Sizzle = function( query, context, extra, seed ) {
4082 context = context || document;
4083
4084 // Make sure that attribute selectors are quoted
4085 query = query.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
4086
4087 // Only use querySelectorAll on non-XML documents
4088 // (ID selectors don't work in non-HTML documents)
4089 if ( !seed && !Sizzle.isXML(context) ) {
4090 if ( context.nodeType === 9 ) {
4091 try {
4092 return makeArray( context.querySelectorAll(query), extra );
4093 } catch(qsaError) {}
4094
4095 // qSA works strangely on Element-rooted queries
4096 // We can work around this by specifying an extra ID on the root
4097 // and working up from there (Thanks to Andrew Dupont for the technique)
4098 // IE 8 doesn't work on object elements
4099 } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
4100 var old = context.getAttribute( "id" ),
4101 nid = old || id;
4102
4103 if ( !old ) {
4104 context.setAttribute( "id", nid );
4105 }
4106
4107 try {
4108 return makeArray( context.querySelectorAll( "#" + nid + " " + query ), extra );
4109
4110 } catch(pseudoError) {
4111 } finally {
4112 if ( !old ) {
4113 context.removeAttribute( "id" );
4114 }
4115 }
4116 }
4117 }
4118
4119 return oldSizzle(query, context, extra, seed);
4120 };
4121
4122 for ( var prop in oldSizzle ) {
4123 Sizzle[ prop ] = oldSizzle[ prop ];
4124 }
4125
4126 // release memory in IE
4127 div = null;
4128 })();
4129}
4130
4131(function(){
4132 var html = document.documentElement,
4133 matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector,
4134 pseudoWorks = false;
4135
4136 try {
4137 // This should fail with an exception
4138 // Gecko does not error, returns false instead
4139 matches.call( document.documentElement, "[test!='']:sizzle" );
4140
4141 } catch( pseudoError ) {
4142 pseudoWorks = true;
4143 }
4144
4145 if ( matches ) {
4146 Sizzle.matchesSelector = function( node, expr ) {
4147 // Make sure that attribute selectors are quoted
4148 expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
4149
4150 if ( !Sizzle.isXML( node ) ) {
4151 try {
4152 if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
4153 return matches.call( node, expr );
4154 }
4155 } catch(e) {}
4156 }
4157
4158 return Sizzle(expr, null, null, [node]).length > 0;
4159 };
4160 }
4161})();
4162
4163(function(){
4164 var div = document.createElement("div");
4165
4166 div.innerHTML = "<div class='test e'></div><div class='test'></div>";
4167
4168 // Opera can't find a second classname (in 9.6)
4169 // Also, make sure that getElementsByClassName actually exists
4170 if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
4171 return;
4172 }
4173
4174 // Safari caches class attributes, doesn't catch changes (in 3.2)
4175 div.lastChild.className = "e";
4176
4177 if ( div.getElementsByClassName("e").length === 1 ) {
4178 return;
4179 }
4180
4181 Expr.order.splice(1, 0, "CLASS");
4182 Expr.find.CLASS = function( match, context, isXML ) {
4183 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
4184 return context.getElementsByClassName(match[1]);
4185 }
4186 };
4187
4188 // release memory in IE
4189 div = null;
4190})();
4191
4192function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4193 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4194 var elem = checkSet[i];
4195
4196 if ( elem ) {
4197 var match = false;
4198
4199 elem = elem[dir];
4200
4201 while ( elem ) {
4202 if ( elem.sizcache === doneName ) {
4203 match = checkSet[elem.sizset];
4204 break;
4205 }
4206
4207 if ( elem.nodeType === 1 && !isXML ){
4208 elem.sizcache = doneName;
4209 elem.sizset = i;
4210 }
4211
4212 if ( elem.nodeName.toLowerCase() === cur ) {
4213 match = elem;
4214 break;
4215 }
4216
4217 elem = elem[dir];
4218 }
4219
4220 checkSet[i] = match;
4221 }
4222 }
4223}
4224
4225function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4226 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4227 var elem = checkSet[i];
4228
4229 if ( elem ) {
4230 var match = false;
4231
4232 elem = elem[dir];
4233
4234 while ( elem ) {
4235 if ( elem.sizcache === doneName ) {
4236 match = checkSet[elem.sizset];
4237 break;
4238 }
4239
4240 if ( elem.nodeType === 1 ) {
4241 if ( !isXML ) {
4242 elem.sizcache = doneName;
4243 elem.sizset = i;
4244 }
4245
4246 if ( typeof cur !== "string" ) {
4247 if ( elem === cur ) {
4248 match = true;
4249 break;
4250 }
4251
4252 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
4253 match = elem;
4254 break;
4255 }
4256 }
4257
4258 elem = elem[dir];
4259 }
4260
4261 checkSet[i] = match;
4262 }
4263 }
4264}
4265
4266if ( document.documentElement.contains ) {
4267 Sizzle.contains = function( a, b ) {
4268 return a !== b && (a.contains ? a.contains(b) : true);
4269 };
4270
4271} else if ( document.documentElement.compareDocumentPosition ) {
4272 Sizzle.contains = function( a, b ) {
4273 return !!(a.compareDocumentPosition(b) & 16);
4274 };
4275
4276} else {
4277 Sizzle.contains = function() {
4278 return false;
4279 };
4280}
4281
4282Sizzle.isXML = function( elem ) {
4283 // documentElement is verified for cases where it doesn't yet exist
4284 // (such as loading iframes in IE - #4833)
4285 var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
4286
4287 return documentElement ? documentElement.nodeName !== "HTML" : false;
4288};
4289
4290var posProcess = function( selector, context ) {
4291 var match,
4292 tmpSet = [],
4293 later = "",
4294 root = context.nodeType ? [context] : context;
4295
4296 // Position selectors must be done after the filter
4297 // And so must :not(positional) so we move all PSEUDOs to the end
4298 while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
4299 later += match[0];
4300 selector = selector.replace( Expr.match.PSEUDO, "" );
4301 }
4302
4303 selector = Expr.relative[selector] ? selector + "*" : selector;
4304
4305 for ( var i = 0, l = root.length; i < l; i++ ) {
4306 Sizzle( selector, root[i], tmpSet );
4307 }
4308
4309 return Sizzle.filter( later, tmpSet );
4310};
4311
4312// EXPOSE
4313jQuery.find = Sizzle;
4314jQuery.expr = Sizzle.selectors;
4315jQuery.expr[":"] = jQuery.expr.filters;
4316jQuery.unique = Sizzle.uniqueSort;
4317jQuery.text = Sizzle.getText;
4318jQuery.isXMLDoc = Sizzle.isXML;
4319jQuery.contains = Sizzle.contains;
4320
4321
4322})();
4323
4324
4325var runtil = /Until$/,
4326 rparentsprev = /^(?:parents|prevUntil|prevAll)/,
4327 // Note: This RegExp should be improved, or likely pulled from Sizzle
4328 rmultiselector = /,/,
4329 isSimple = /^.[^:#\[\.,]*$/,
4330 slice = Array.prototype.slice,
4331 POS = jQuery.expr.match.POS;
4332
4333jQuery.fn.extend({
4334 find: function( selector ) {
4335 var ret = this.pushStack( "", "find", selector ),
4336 length = 0;
4337
4338 for ( var i = 0, l = this.length; i < l; i++ ) {
4339 length = ret.length;
4340 jQuery.find( selector, this[i], ret );
4341
4342 if ( i > 0 ) {
4343 // Make sure that the results are unique
4344 for ( var n = length; n < ret.length; n++ ) {
4345 for ( var r = 0; r < length; r++ ) {
4346 if ( ret[r] === ret[n] ) {
4347 ret.splice(n--, 1);
4348 break;
4349 }
4350 }
4351 }
4352 }
4353 }
4354
4355 return ret;
4356 },
4357
4358 has: function( target ) {
4359 var targets = jQuery( target );
4360 return this.filter(function() {
4361 for ( var i = 0, l = targets.length; i < l; i++ ) {
4362 if ( jQuery.contains( this, targets[i] ) ) {
4363 return true;
4364 }
4365 }
4366 });
4367 },
4368
4369 not: function( selector ) {
4370 return this.pushStack( winnow(this, selector, false), "not", selector);
4371 },
4372
4373 filter: function( selector ) {
4374 return this.pushStack( winnow(this, selector, true), "filter", selector );
4375 },
4376
4377 is: function( selector ) {
4378 return !!selector && jQuery.filter( selector, this ).length > 0;
4379 },
4380
4381 closest: function( selectors, context ) {
4382 var ret = [], i, l, cur = this[0];
4383
4384 if ( jQuery.isArray( selectors ) ) {
4385 var match, selector,
4386 matches = {},
4387 level = 1;
4388
4389 if ( cur && selectors.length ) {
4390 for ( i = 0, l = selectors.length; i < l; i++ ) {
4391 selector = selectors[i];
4392
4393 if ( !matches[selector] ) {
4394 matches[selector] = jQuery.expr.match.POS.test( selector ) ?
4395 jQuery( selector, context || this.context ) :
4396 selector;
4397 }
4398 }
4399
4400 while ( cur && cur.ownerDocument && cur !== context ) {
4401 for ( selector in matches ) {
4402 match = matches[selector];
4403
4404 if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
4405 ret.push({ selector: selector, elem: cur, level: level });
4406 }
4407 }
4408
4409 cur = cur.parentNode;
4410 level++;
4411 }
4412 }
4413
4414 return ret;
4415 }
4416
4417 var pos = POS.test( selectors ) ?
4418 jQuery( selectors, context || this.context ) : null;
4419
4420 for ( i = 0, l = this.length; i < l; i++ ) {
4421 cur = this[i];
4422
4423 while ( cur ) {
4424 if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
4425 ret.push( cur );
4426 break;
4427
4428 } else {
4429 cur = cur.parentNode;
4430 if ( !cur || !cur.ownerDocument || cur === context ) {
4431 break;
4432 }
4433 }
4434 }
4435 }
4436
4437 ret = ret.length > 1 ? jQuery.unique(ret) : ret;
4438
4439 return this.pushStack( ret, "closest", selectors );
4440 },
4441
4442 // Determine the position of an element within
4443 // the matched set of elements
4444 index: function( elem ) {
4445 if ( !elem || typeof elem === "string" ) {
4446 return jQuery.inArray( this[0],
4447 // If it receives a string, the selector is used
4448 // If it receives nothing, the siblings are used
4449 elem ? jQuery( elem ) : this.parent().children() );
4450 }
4451 // Locate the position of the desired element
4452 return jQuery.inArray(
4453 // If it receives a jQuery object, the first element is used
4454 elem.jquery ? elem[0] : elem, this );
4455 },
4456
4457 add: function( selector, context ) {
4458 var set = typeof selector === "string" ?
4459 jQuery( selector, context || this.context ) :
4460 jQuery.makeArray( selector ),
4461 all = jQuery.merge( this.get(), set );
4462
4463 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
4464 all :
4465 jQuery.unique( all ) );
4466 },
4467
4468 andSelf: function() {
4469 return this.add( this.prevObject );
4470 }
4471});
4472
4473// A painfully simple check to see if an element is disconnected
4474// from a document (should be improved, where feasible).
4475function isDisconnected( node ) {
4476 return !node || !node.parentNode || node.parentNode.nodeType === 11;
4477}
4478
4479jQuery.each({
4480 parent: function( elem ) {
4481 var parent = elem.parentNode;
4482 return parent && parent.nodeType !== 11 ? parent : null;
4483 },
4484 parents: function( elem ) {
4485 return jQuery.dir( elem, "parentNode" );
4486 },
4487 parentsUntil: function( elem, i, until ) {
4488 return jQuery.dir( elem, "parentNode", until );
4489 },
4490 next: function( elem ) {
4491 return jQuery.nth( elem, 2, "nextSibling" );
4492 },
4493 prev: function( elem ) {
4494 return jQuery.nth( elem, 2, "previousSibling" );
4495 },
4496 nextAll: function( elem ) {
4497 return jQuery.dir( elem, "nextSibling" );
4498 },
4499 prevAll: function( elem ) {
4500 return jQuery.dir( elem, "previousSibling" );
4501 },
4502 nextUntil: function( elem, i, until ) {
4503 return jQuery.dir( elem, "nextSibling", until );
4504 },
4505 prevUntil: function( elem, i, until ) {
4506 return jQuery.dir( elem, "previousSibling", until );
4507 },
4508 siblings: function( elem ) {
4509 return jQuery.sibling( elem.parentNode.firstChild, elem );
4510 },
4511 children: function( elem ) {
4512 return jQuery.sibling( elem.firstChild );
4513 },
4514 contents: function( elem ) {
4515 return jQuery.nodeName( elem, "iframe" ) ?
4516 elem.contentDocument || elem.contentWindow.document :
4517 jQuery.makeArray( elem.childNodes );
4518 }
4519}, function( name, fn ) {
4520 jQuery.fn[ name ] = function( until, selector ) {
4521 var ret = jQuery.map( this, fn, until );
4522
4523 if ( !runtil.test( name ) ) {
4524 selector = until;
4525 }
4526
4527 if ( selector && typeof selector === "string" ) {
4528 ret = jQuery.filter( selector, ret );
4529 }
4530
4531 ret = this.length > 1 ? jQuery.unique( ret ) : ret;
4532
4533 if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
4534 ret = ret.reverse();
4535 }
4536
4537 return this.pushStack( ret, name, slice.call(arguments).join(",") );
4538 };
4539});
4540
4541jQuery.extend({
4542 filter: function( expr, elems, not ) {
4543 if ( not ) {
4544 expr = ":not(" + expr + ")";
4545 }
4546
4547 return elems.length === 1 ?
4548 jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
4549 jQuery.find.matches(expr, elems);
4550 },
4551
4552 dir: function( elem, dir, until ) {
4553 var matched = [],
4554 cur = elem[ dir ];
4555
4556 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
4557 if ( cur.nodeType === 1 ) {
4558 matched.push( cur );
4559 }
4560 cur = cur[dir];
4561 }
4562 return matched;
4563 },
4564
4565 nth: function( cur, result, dir, elem ) {
4566 result = result || 1;
4567 var num = 0;
4568
4569 for ( ; cur; cur = cur[dir] ) {
4570 if ( cur.nodeType === 1 && ++num === result ) {
4571 break;
4572 }
4573 }
4574
4575 return cur;
4576 },
4577
4578 sibling: function( n, elem ) {
4579 var r = [];
4580
4581 for ( ; n; n = n.nextSibling ) {
4582 if ( n.nodeType === 1 && n !== elem ) {
4583 r.push( n );
4584 }
4585 }
4586
4587 return r;
4588 }
4589});
4590
4591// Implement the identical functionality for filter and not
4592function winnow( elements, qualifier, keep ) {
4593 if ( jQuery.isFunction( qualifier ) ) {
4594 return jQuery.grep(elements, function( elem, i ) {
4595 var retVal = !!qualifier.call( elem, i, elem );
4596 return retVal === keep;
4597 });
4598
4599 } else if ( qualifier.nodeType ) {
4600 return jQuery.grep(elements, function( elem, i ) {
4601 return (elem === qualifier) === keep;
4602 });
4603
4604 } else if ( typeof qualifier === "string" ) {
4605 var filtered = jQuery.grep(elements, function( elem ) {
4606 return elem.nodeType === 1;
4607 });
4608
4609 if ( isSimple.test( qualifier ) ) {
4610 return jQuery.filter(qualifier, filtered, !keep);
4611 } else {
4612 qualifier = jQuery.filter( qualifier, filtered );
4613 }
4614 }
4615
4616 return jQuery.grep(elements, function( elem, i ) {
4617 return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
4618 });
4619}
4620
4621
4622
4623
4624var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
4625 rleadingWhitespace = /^\s+/,
4626 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
4627 rtagName = /<([\w:]+)/,
4628 rtbody = /<tbody/i,
4629 rhtml = /<|&#?\w+;/,
4630 rnocache = /<(?:script|object|embed|option|style)/i,
4631 // checked="checked" or checked (html5)
4632 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
4633 raction = /\=([^="'>\s]+\/)>/g,
4634 wrapMap = {
4635 option: [ 1, "<select multiple='multiple'>", "</select>" ],
4636 legend: [ 1, "<fieldset>", "</fieldset>" ],
4637 thead: [ 1, "<table>", "</table>" ],
4638 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4639 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4640 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
4641 area: [ 1, "<map>", "</map>" ],
4642 _default: [ 0, "", "" ]
4643 };
4644
4645wrapMap.optgroup = wrapMap.option;
4646wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4647wrapMap.th = wrapMap.td;
4648
4649// IE can't serialize <link> and <script> tags normally
4650if ( !jQuery.support.htmlSerialize ) {
4651 wrapMap._default = [ 1, "div<div>", "</div>" ];
4652}
4653
4654jQuery.fn.extend({
4655 text: function( text ) {
4656 if ( jQuery.isFunction(text) ) {
4657 return this.each(function(i) {
4658 var self = jQuery( this );
4659
4660 self.text( text.call(this, i, self.text()) );
4661 });
4662 }
4663
4664 if ( typeof text !== "object" && text !== undefined ) {
4665 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
4666 }
4667
4668 return jQuery.text( this );
4669 },
4670
4671 wrapAll: function( html ) {
4672 if ( jQuery.isFunction( html ) ) {
4673 return this.each(function(i) {
4674 jQuery(this).wrapAll( html.call(this, i) );
4675 });
4676 }
4677
4678 if ( this[0] ) {
4679 // The elements to wrap the target around
4680 var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
4681
4682 if ( this[0].parentNode ) {
4683 wrap.insertBefore( this[0] );
4684 }
4685
4686 wrap.map(function() {
4687 var elem = this;
4688
4689 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
4690 elem = elem.firstChild;
4691 }
4692
4693 return elem;
4694 }).append(this);
4695 }
4696
4697 return this;
4698 },
4699
4700 wrapInner: function( html ) {
4701 if ( jQuery.isFunction( html ) ) {
4702 return this.each(function(i) {
4703 jQuery(this).wrapInner( html.call(this, i) );
4704 });
4705 }
4706
4707 return this.each(function() {
4708 var self = jQuery( this ),
4709 contents = self.contents();
4710
4711 if ( contents.length ) {
4712 contents.wrapAll( html );
4713
4714 } else {
4715 self.append( html );
4716 }
4717 });
4718 },
4719
4720 wrap: function( html ) {
4721 return this.each(function() {
4722 jQuery( this ).wrapAll( html );
4723 });
4724 },
4725
4726 unwrap: function() {
4727 return this.parent().each(function() {
4728 if ( !jQuery.nodeName( this, "body" ) ) {
4729 jQuery( this ).replaceWith( this.childNodes );
4730 }
4731 }).end();
4732 },
4733
4734 append: function() {
4735 return this.domManip(arguments, true, function( elem ) {
4736 if ( this.nodeType === 1 ) {
4737 this.appendChild( elem );
4738 }
4739 });
4740 },
4741
4742 prepend: function() {
4743 return this.domManip(arguments, true, function( elem ) {
4744 if ( this.nodeType === 1 ) {
4745 this.insertBefore( elem, this.firstChild );
4746 }
4747 });
4748 },
4749
4750 before: function() {
4751 if ( this[0] && this[0].parentNode ) {
4752 return this.domManip(arguments, false, function( elem ) {
4753 this.parentNode.insertBefore( elem, this );
4754 });
4755 } else if ( arguments.length ) {
4756 var set = jQuery(arguments[0]);
4757 set.push.apply( set, this.toArray() );
4758 return this.pushStack( set, "before", arguments );
4759 }
4760 },
4761
4762 after: function() {
4763 if ( this[0] && this[0].parentNode ) {
4764 return this.domManip(arguments, false, function( elem ) {
4765 this.parentNode.insertBefore( elem, this.nextSibling );
4766 });
4767 } else if ( arguments.length ) {
4768 var set = this.pushStack( this, "after", arguments );
4769 set.push.apply( set, jQuery(arguments[0]).toArray() );
4770 return set;
4771 }
4772 },
4773
4774 // keepData is for internal use only--do not document
4775 remove: function( selector, keepData ) {
4776 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
4777 if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
4778 if ( !keepData && elem.nodeType === 1 ) {
4779 jQuery.cleanData( elem.getElementsByTagName("*") );
4780 jQuery.cleanData( [ elem ] );
4781 }
4782
4783 if ( elem.parentNode ) {
4784 elem.parentNode.removeChild( elem );
4785 }
4786 }
4787 }
4788
4789 return this;
4790 },
4791
4792 empty: function() {
4793 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
4794 // Remove element nodes and prevent memory leaks
4795 if ( elem.nodeType === 1 ) {
4796 jQuery.cleanData( elem.getElementsByTagName("*") );
4797 }
4798
4799 // Remove any remaining nodes
4800 while ( elem.firstChild ) {
4801 elem.removeChild( elem.firstChild );
4802 }
4803 }
4804
4805 return this;
4806 },
4807
4808 clone: function( events ) {
4809 // Do the clone
4810 var ret = this.map(function() {
4811 if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
4812 // IE copies events bound via attachEvent when
4813 // using cloneNode. Calling detachEvent on the
4814 // clone will also remove the events from the orignal
4815 // In order to get around this, we use innerHTML.
4816 // Unfortunately, this means some modifications to
4817 // attributes in IE that are actually only stored
4818 // as properties will not be copied (such as the
4819 // the name attribute on an input).
4820 var html = this.outerHTML,
4821 ownerDocument = this.ownerDocument;
4822
4823 if ( !html ) {
4824 var div = ownerDocument.createElement("div");
4825 div.appendChild( this.cloneNode(true) );
4826 html = div.innerHTML;
4827 }
4828
4829 return jQuery.clean([html.replace(rinlinejQuery, "")
4830 // Handle the case in IE 8 where action=/test/> self-closes a tag
4831 .replace(raction, '="$1">')
4832 .replace(rleadingWhitespace, "")], ownerDocument)[0];
4833 } else {
4834 return this.cloneNode(true);
4835 }
4836 });
4837
4838 // Copy the events from the original to the clone
4839 if ( events === true ) {
4840 cloneCopyEvent( this, ret );
4841 cloneCopyEvent( this.find("*"), ret.find("*") );
4842 }
4843
4844 // Return the cloned set
4845 return ret;
4846 },
4847
4848 html: function( value ) {
4849 if ( value === undefined ) {
4850 return this[0] && this[0].nodeType === 1 ?
4851 this[0].innerHTML.replace(rinlinejQuery, "") :
4852 null;
4853
4854 // See if we can take a shortcut and just use innerHTML
4855 } else if ( typeof value === "string" && !rnocache.test( value ) &&
4856 (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
4857 !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
4858
4859 value = value.replace(rxhtmlTag, "<$1></$2>");
4860
4861 try {
4862 for ( var i = 0, l = this.length; i < l; i++ ) {
4863 // Remove element nodes and prevent memory leaks
4864 if ( this[i].nodeType === 1 ) {
4865 jQuery.cleanData( this[i].getElementsByTagName("*") );
4866 this[i].innerHTML = value;
4867 }
4868 }
4869
4870 // If using innerHTML throws an exception, use the fallback method
4871 } catch(e) {
4872 this.empty().append( value );
4873 }
4874
4875 } else if ( jQuery.isFunction( value ) ) {
4876 this.each(function(i){
4877 var self = jQuery( this );
4878
4879 self.html( value.call(this, i, self.html()) );
4880 });
4881
4882 } else {
4883 this.empty().append( value );
4884 }
4885
4886 return this;
4887 },
4888
4889 replaceWith: function( value ) {
4890 if ( this[0] && this[0].parentNode ) {
4891 // Make sure that the elements are removed from the DOM before they are inserted
4892 // this can help fix replacing a parent with child elements
4893 if ( jQuery.isFunction( value ) ) {
4894 return this.each(function(i) {
4895 var self = jQuery(this), old = self.html();
4896 self.replaceWith( value.call( this, i, old ) );
4897 });
4898 }
4899
4900 if ( typeof value !== "string" ) {
4901 value = jQuery( value ).detach();
4902 }
4903
4904 return this.each(function() {
4905 var next = this.nextSibling,
4906 parent = this.parentNode;
4907
4908 jQuery( this ).remove();
4909
4910 if ( next ) {
4911 jQuery(next).before( value );
4912 } else {
4913 jQuery(parent).append( value );
4914 }
4915 });
4916 } else {
4917 return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value );
4918 }
4919 },
4920
4921 detach: function( selector ) {
4922 return this.remove( selector, true );
4923 },
4924
4925 domManip: function( args, table, callback ) {
4926 var results, first, fragment, parent,
4927 value = args[0],
4928 scripts = [];
4929
4930 // We can't cloneNode fragments that contain checked, in WebKit
4931 if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
4932 return this.each(function() {
4933 jQuery(this).domManip( args, table, callback, true );
4934 });
4935 }
4936
4937 if ( jQuery.isFunction(value) ) {
4938 return this.each(function(i) {
4939 var self = jQuery(this);
4940 args[0] = value.call(this, i, table ? self.html() : undefined);
4941 self.domManip( args, table, callback );
4942 });
4943 }
4944
4945 if ( this[0] ) {
4946 parent = value && value.parentNode;
4947
4948 // If we're in a fragment, just use that instead of building a new one
4949 if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
4950 results = { fragment: parent };
4951
4952 } else {
4953 results = jQuery.buildFragment( args, this, scripts );
4954 }
4955
4956 fragment = results.fragment;
4957
4958 if ( fragment.childNodes.length === 1 ) {
4959 first = fragment = fragment.firstChild;
4960 } else {
4961 first = fragment.firstChild;
4962 }
4963
4964 if ( first ) {
4965 table = table && jQuery.nodeName( first, "tr" );
4966
4967 for ( var i = 0, l = this.length; i < l; i++ ) {
4968 callback.call(
4969 table ?
4970 root(this[i], first) :
4971 this[i],
4972 i > 0 || results.cacheable || this.length > 1 ?
4973 fragment.cloneNode(true) :
4974 fragment
4975 );
4976 }
4977 }
4978
4979 if ( scripts.length ) {
4980 jQuery.each( scripts, evalScript );
4981 }
4982 }
4983
4984 return this;
4985 }
4986});
4987
4988function root( elem, cur ) {
4989 return jQuery.nodeName(elem, "table") ?
4990 (elem.getElementsByTagName("tbody")[0] ||
4991 elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
4992 elem;
4993}
4994
4995function cloneCopyEvent(orig, ret) {
4996 var i = 0;
4997
4998 ret.each(function() {
4999 if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) {
5000 return;
5001 }
5002
5003 var oldData = jQuery.data( orig[i++] ),
5004 curData = jQuery.data( this, oldData ),
5005 events = oldData && oldData.events;
5006
5007 if ( events ) {
5008 delete curData.handle;
5009 curData.events = {};
5010
5011 for ( var type in events ) {
5012 for ( var handler in events[ type ] ) {
5013 jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
5014 }
5015 }
5016 }
5017 });
5018}
5019
5020jQuery.buildFragment = function( args, nodes, scripts ) {
5021 var fragment, cacheable, cacheresults,
5022 doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
5023
5024 // Only cache "small" (1/2 KB) strings that are associated with the main document
5025 // Cloning options loses the selected state, so don't cache them
5026 // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
5027 // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
5028 if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
5029 !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
5030
5031 cacheable = true;
5032 cacheresults = jQuery.fragments[ args[0] ];
5033 if ( cacheresults ) {
5034 if ( cacheresults !== 1 ) {
5035 fragment = cacheresults;
5036 }
5037 }
5038 }
5039
5040 if ( !fragment ) {
5041 fragment = doc.createDocumentFragment();
5042 jQuery.clean( args, doc, fragment, scripts );
5043 }
5044
5045 if ( cacheable ) {
5046 jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
5047 }
5048
5049 return { fragment: fragment, cacheable: cacheable };
5050};
5051
5052jQuery.fragments = {};
5053
5054jQuery.each({
5055 appendTo: "append",
5056 prependTo: "prepend",
5057 insertBefore: "before",
5058 insertAfter: "after",
5059 replaceAll: "replaceWith"
5060}, function( name, original ) {
5061 jQuery.fn[ name ] = function( selector ) {
5062 var ret = [],
5063 insert = jQuery( selector ),
5064 parent = this.length === 1 && this[0].parentNode;
5065
5066 if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
5067 insert[ original ]( this[0] );
5068 return this;
5069
5070 } else {
5071 for ( var i = 0, l = insert.length; i < l; i++ ) {
5072 var elems = (i > 0 ? this.clone(true) : this).get();
5073 jQuery( insert[i] )[ original ]( elems );
5074 ret = ret.concat( elems );
5075 }
5076
5077 return this.pushStack( ret, name, insert.selector );
5078 }
5079 };
5080});
5081
5082jQuery.extend({
5083 clean: function( elems, context, fragment, scripts ) {
5084 context = context || document;
5085
5086 // !context.createElement fails in IE with an error but returns typeof 'object'
5087 if ( typeof context.createElement === "undefined" ) {
5088 context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
5089 }
5090
5091 var ret = [];
5092
5093 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
5094 if ( typeof elem === "number" ) {
5095 elem += "";
5096 }
5097
5098 if ( !elem ) {
5099 continue;
5100 }
5101
5102 // Convert html string into DOM nodes
5103 if ( typeof elem === "string" && !rhtml.test( elem ) ) {
5104 elem = context.createTextNode( elem );
5105
5106 } else if ( typeof elem === "string" ) {
5107 // Fix "XHTML"-style tags in all browsers
5108 elem = elem.replace(rxhtmlTag, "<$1></$2>");
5109
5110 // Trim whitespace, otherwise indexOf won't work as expected
5111 var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
5112 wrap = wrapMap[ tag ] || wrapMap._default,
5113 depth = wrap[0],
5114 div = context.createElement("div");
5115
5116 // Go to html and back, then peel off extra wrappers
5117 div.innerHTML = wrap[1] + elem + wrap[2];
5118
5119 // Move to the right depth
5120 while ( depth-- ) {
5121 div = div.lastChild;
5122 }
5123
5124 // Remove IE's autoinserted <tbody> from table fragments
5125 if ( !jQuery.support.tbody ) {
5126
5127 // String was a <table>, *may* have spurious <tbody>
5128 var hasBody = rtbody.test(elem),
5129 tbody = tag === "table" && !hasBody ?
5130 div.firstChild && div.firstChild.childNodes :
5131
5132 // String was a bare <thead> or <tfoot>
5133 wrap[1] === "<table>" && !hasBody ?
5134 div.childNodes :
5135 [];
5136
5137 for ( var j = tbody.length - 1; j >= 0 ; --j ) {
5138 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
5139 tbody[ j ].parentNode.removeChild( tbody[ j ] );
5140 }
5141 }
5142
5143 }
5144
5145 // IE completely kills leading whitespace when innerHTML is used
5146 if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
5147 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
5148 }
5149
5150 elem = div.childNodes;
5151 }
5152
5153 if ( elem.nodeType ) {
5154 ret.push( elem );
5155 } else {
5156 ret = jQuery.merge( ret, elem );
5157 }
5158 }
5159
5160 if ( fragment ) {
5161 for ( i = 0; ret[i]; i++ ) {
5162 if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
5163 scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
5164
5165 } else {
5166 if ( ret[i].nodeType === 1 ) {
5167 ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
5168 }
5169 fragment.appendChild( ret[i] );
5170 }
5171 }
5172 }
5173
5174 return ret;
5175 },
5176
5177 cleanData: function( elems ) {
5178 var data, id, cache = jQuery.cache,
5179 special = jQuery.event.special,
5180 deleteExpando = jQuery.support.deleteExpando;
5181
5182 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
5183 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
5184 continue;
5185 }
5186
5187 id = elem[ jQuery.expando ];
5188
5189 if ( id ) {
5190 data = cache[ id ];
5191
5192 if ( data && data.events ) {
5193 for ( var type in data.events ) {
5194 if ( special[ type ] ) {
5195 jQuery.event.remove( elem, type );
5196
5197 } else {
5198 jQuery.removeEvent( elem, type, data.handle );
5199 }
5200 }
5201 }
5202
5203 if ( deleteExpando ) {
5204 delete elem[ jQuery.expando ];
5205
5206 } else if ( elem.removeAttribute ) {
5207 elem.removeAttribute( jQuery.expando );
5208 }
5209
5210 delete cache[ id ];
5211 }
5212 }
5213 }
5214});
5215
5216function evalScript( i, elem ) {
5217 if ( elem.src ) {
5218 jQuery.ajax({
5219 url: elem.src,
5220 async: false,
5221 dataType: "script"
5222 });
5223 } else {
5224 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
5225 }
5226
5227 if ( elem.parentNode ) {
5228 elem.parentNode.removeChild( elem );
5229 }
5230}
5231
5232
5233
5234
5235var ralpha = /alpha\([^)]*\)/i,
5236 ropacity = /opacity=([^)]*)/,
5237 rdashAlpha = /-([a-z])/ig,
5238 rupper = /([A-Z])/g,
5239 rnumpx = /^-?\d+(?:px)?$/i,
5240 rnum = /^-?\d/,
5241
5242 cssShow = { position: "absolute", visibility: "hidden", display: "block" },
5243 cssWidth = [ "Left", "Right" ],
5244 cssHeight = [ "Top", "Bottom" ],
5245 curCSS,
5246
5247 getComputedStyle,
5248 currentStyle,
5249
5250 fcamelCase = function( all, letter ) {
5251 return letter.toUpperCase();
5252 };
5253
5254jQuery.fn.css = function( name, value ) {
5255 // Setting 'undefined' is a no-op
5256 if ( arguments.length === 2 && value === undefined ) {
5257 return this;
5258 }
5259
5260 return jQuery.access( this, name, value, true, function( elem, name, value ) {
5261 return value !== undefined ?
5262 jQuery.style( elem, name, value ) :
5263 jQuery.css( elem, name );
5264 });
5265};
5266
5267jQuery.extend({
5268 // Add in style property hooks for overriding the default
5269 // behavior of getting and setting a style property
5270 cssHooks: {
5271 opacity: {
5272 get: function( elem, computed ) {
5273 if ( computed ) {
5274 // We should always get a number back from opacity
5275 var ret = curCSS( elem, "opacity", "opacity" );
5276 return ret === "" ? "1" : ret;
5277
5278 } else {
5279 return elem.style.opacity;
5280 }
5281 }
5282 }
5283 },
5284
5285 // Exclude the following css properties to add px
5286 cssNumber: {
5287 "zIndex": true,
5288 "fontWeight": true,
5289 "opacity": true,
5290 "zoom": true,
5291 "lineHeight": true
5292 },
5293
5294 // Add in properties whose names you wish to fix before
5295 // setting or getting the value
5296 cssProps: {
5297 // normalize float css property
5298 "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
5299 },
5300
5301 // Get and set the style property on a DOM Node
5302 style: function( elem, name, value, extra ) {
5303 // Don't set styles on text and comment nodes
5304 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
5305 return;
5306 }
5307
5308 // Make sure that we're working with the right name
5309 var ret, origName = jQuery.camelCase( name ),
5310 style = elem.style, hooks = jQuery.cssHooks[ origName ];
5311
5312 name = jQuery.cssProps[ origName ] || origName;
5313
5314 // Check if we're setting a value
5315 if ( value !== undefined ) {
5316 // Make sure that NaN and null values aren't set. See: #7116
5317 if ( typeof value === "number" && isNaN( value ) || value == null ) {
5318 return;
5319 }
5320
5321 // If a number was passed in, add 'px' to the (except for certain CSS properties)
5322 if ( typeof value === "number" && !jQuery.cssNumber[ origName ] ) {
5323 value += "px";
5324 }
5325
5326 // If a hook was provided, use that value, otherwise just set the specified value
5327 if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
5328 // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
5329 // Fixes bug #5509
5330 try {
5331 style[ name ] = value;
5332 } catch(e) {}
5333 }
5334
5335 } else {
5336 // If a hook was provided get the non-computed value from there
5337 if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
5338 return ret;
5339 }
5340
5341 // Otherwise just get the value from the style object
5342 return style[ name ];
5343 }
5344 },
5345
5346 css: function( elem, name, extra ) {
5347 // Make sure that we're working with the right name
5348 var ret, origName = jQuery.camelCase( name ),
5349 hooks = jQuery.cssHooks[ origName ];
5350
5351 name = jQuery.cssProps[ origName ] || origName;
5352
5353 // If a hook was provided get the computed value from there
5354 if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
5355 return ret;
5356
5357 // Otherwise, if a way to get the computed value exists, use that
5358 } else if ( curCSS ) {
5359 return curCSS( elem, name, origName );
5360 }
5361 },
5362
5363 // A method for quickly swapping in/out CSS properties to get correct calculations
5364 swap: function( elem, options, callback ) {
5365 var old = {};
5366
5367 // Remember the old values, and insert the new ones
5368 for ( var name in options ) {
5369 old[ name ] = elem.style[ name ];
5370 elem.style[ name ] = options[ name ];
5371 }
5372
5373 callback.call( elem );
5374
5375 // Revert the old values
5376 for ( name in options ) {
5377 elem.style[ name ] = old[ name ];
5378 }
5379 },
5380
5381 camelCase: function( string ) {
5382 return string.replace( rdashAlpha, fcamelCase );
5383 }
5384});
5385
5386// DEPRECATED, Use jQuery.css() instead
5387jQuery.curCSS = jQuery.css;
5388
5389jQuery.each(["height", "width"], function( i, name ) {
5390 jQuery.cssHooks[ name ] = {
5391 get: function( elem, computed, extra ) {
5392 var val;
5393
5394 if ( computed ) {
5395 if ( elem.offsetWidth !== 0 ) {
5396 val = getWH( elem, name, extra );
5397
5398 } else {
5399 jQuery.swap( elem, cssShow, function() {
5400 val = getWH( elem, name, extra );
5401 });
5402 }
5403
5404 if ( val <= 0 ) {
5405 val = curCSS( elem, name, name );
5406
5407 if ( val === "0px" && currentStyle ) {
5408 val = currentStyle( elem, name, name );
5409 }
5410
5411 if ( val != null ) {
5412 // Should return "auto" instead of 0, use 0 for
5413 // temporary backwards-compat
5414 return val === "" || val === "auto" ? "0px" : val;
5415 }
5416 }
5417
5418 if ( val < 0 || val == null ) {
5419 val = elem.style[ name ];
5420
5421 // Should return "auto" instead of 0, use 0 for
5422 // temporary backwards-compat
5423 return val === "" || val === "auto" ? "0px" : val;
5424 }
5425
5426 return typeof val === "string" ? val : val + "px";
5427 }
5428 },
5429
5430 set: function( elem, value ) {
5431 if ( rnumpx.test( value ) ) {
5432 // ignore negative width and height values #1599
5433 value = parseFloat(value);
5434
5435 if ( value >= 0 ) {
5436 return value + "px";
5437 }
5438
5439 } else {
5440 return value;
5441 }
5442 }
5443 };
5444});
5445
5446if ( !jQuery.support.opacity ) {
5447 jQuery.cssHooks.opacity = {
5448 get: function( elem, computed ) {
5449 // IE uses filters for opacity
5450 return ropacity.test((computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "") ?
5451 (parseFloat(RegExp.$1) / 100) + "" :
5452 computed ? "1" : "";
5453 },
5454
5455 set: function( elem, value ) {
5456 var style = elem.style;
5457
5458 // IE has trouble with opacity if it does not have layout
5459 // Force it by setting the zoom level
5460 style.zoom = 1;
5461
5462 // Set the alpha filter to set the opacity
5463 var opacity = jQuery.isNaN(value) ?
5464 "" :
5465 "alpha(opacity=" + value * 100 + ")",
5466 filter = style.filter || "";
5467
5468 style.filter = ralpha.test(filter) ?
5469 filter.replace(ralpha, opacity) :
5470 style.filter + ' ' + opacity;
5471 }
5472 };
5473}
5474
5475if ( document.defaultView && document.defaultView.getComputedStyle ) {
5476 getComputedStyle = function( elem, newName, name ) {
5477 var ret, defaultView, computedStyle;
5478
5479 name = name.replace( rupper, "-$1" ).toLowerCase();
5480
5481 if ( !(defaultView = elem.ownerDocument.defaultView) ) {
5482 return undefined;
5483 }
5484
5485 if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
5486 ret = computedStyle.getPropertyValue( name );
5487 if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
5488 ret = jQuery.style( elem, name );
5489 }
5490 }
5491
5492 return ret;
5493 };
5494}
5495
5496if ( document.documentElement.currentStyle ) {
5497 currentStyle = function( elem, name ) {
5498 var left, rsLeft,
5499 ret = elem.currentStyle && elem.currentStyle[ name ],
5500 style = elem.style;
5501
5502 // From the awesome hack by Dean Edwards
5503 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
5504
5505 // If we're not dealing with a regular pixel number
5506 // but a number that has a weird ending, we need to convert it to pixels
5507 if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
5508 // Remember the original values
5509 left = style.left;
5510 rsLeft = elem.runtimeStyle.left;
5511
5512 // Put in the new values to get a computed value out
5513 elem.runtimeStyle.left = elem.currentStyle.left;
5514 style.left = name === "fontSize" ? "1em" : (ret || 0);
5515 ret = style.pixelLeft + "px";
5516
5517 // Revert the changed values
5518 style.left = left;
5519 elem.runtimeStyle.left = rsLeft;
5520 }
5521
5522 return ret === "" ? "auto" : ret;
5523 };
5524}
5525
5526curCSS = getComputedStyle || currentStyle;
5527
5528function getWH( elem, name, extra ) {
5529 var which = name === "width" ? cssWidth : cssHeight,
5530 val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
5531
5532 if ( extra === "border" ) {
5533 return val;
5534 }
5535
5536 jQuery.each( which, function() {
5537 if ( !extra ) {
5538 val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0;
5539 }
5540
5541 if ( extra === "margin" ) {
5542 val += parseFloat(jQuery.css( elem, "margin" + this )) || 0;
5543
5544 } else {
5545 val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0;
5546 }
5547 });
5548
5549 return val;
5550}
5551
5552if ( jQuery.expr && jQuery.expr.filters ) {
5553 jQuery.expr.filters.hidden = function( elem ) {
5554 var width = elem.offsetWidth,
5555 height = elem.offsetHeight;
5556
5557 return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
5558 };
5559
5560 jQuery.expr.filters.visible = function( elem ) {
5561 return !jQuery.expr.filters.hidden( elem );
5562 };
5563}
5564
5565
5566
5567
5568var jsc = jQuery.now(),
5569 rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
5570 rselectTextarea = /^(?:select|textarea)/i,
5571 rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
5572 rnoContent = /^(?:GET|HEAD)$/,
5573 rbracket = /\[\]$/,
5574 jsre = /\=\?(&|$)/,
5575 rquery = /\?/,
5576 rts = /([?&])_=[^&]*/,
5577 rurl = /^(\w+:)?\/\/([^\/?#]+)/,
5578 r20 = /%20/g,
5579 rhash = /#.*$/,
5580
5581 // Keep a copy of the old load method
5582 _load = jQuery.fn.load;
5583
5584jQuery.fn.extend({
5585 load: function( url, params, callback ) {
5586 if ( typeof url !== "string" && _load ) {
5587 return _load.apply( this, arguments );
5588
5589 // Don't do a request if no elements are being requested
5590 } else if ( !this.length ) {
5591 return this;
5592 }
5593
5594 var off = url.indexOf(" ");
5595 if ( off >= 0 ) {
5596 var selector = url.slice(off, url.length);
5597 url = url.slice(0, off);
5598 }
5599
5600 // Default to a GET request
5601 var type = "GET";
5602
5603 // If the second parameter was provided
5604 if ( params ) {
5605 // If it's a function
5606 if ( jQuery.isFunction( params ) ) {
5607 // We assume that it's the callback
5608 callback = params;
5609 params = null;
5610
5611 // Otherwise, build a param string
5612 } else if ( typeof params === "object" ) {
5613 params = jQuery.param( params, jQuery.ajaxSettings.traditional );
5614 type = "POST";
5615 }
5616 }
5617
5618 var self = this;
5619
5620 // Request the remote document
5621 jQuery.ajax({
5622 url: url,
5623 type: type,
5624 dataType: "html",
5625 data: params,
5626 complete: function( res, status ) {
5627 // If successful, inject the HTML into all the matched elements
5628 if ( status === "success" || status === "notmodified" ) {
5629 // See if a selector was specified
5630 self.html( selector ?
5631 // Create a dummy div to hold the results
5632 jQuery("<div>")
5633 // inject the contents of the document in, removing the scripts
5634 // to avoid any 'Permission Denied' errors in IE
5635 .append(res.responseText.replace(rscript, ""))
5636
5637 // Locate the specified elements
5638 .find(selector) :
5639
5640 // If not, just inject the full result
5641 res.responseText );
5642 }
5643
5644 if ( callback ) {
5645 self.each( callback, [res.responseText, status, res] );
5646 }
5647 }
5648 });
5649
5650 return this;
5651 },
5652
5653 serialize: function() {
5654 return jQuery.param(this.serializeArray());
5655 },
5656
5657 serializeArray: function() {
5658 return this.map(function() {
5659 return this.elements ? jQuery.makeArray(this.elements) : this;
5660 })
5661 .filter(function() {
5662 return this.name && !this.disabled &&
5663 (this.checked || rselectTextarea.test(this.nodeName) ||
5664 rinput.test(this.type));
5665 })
5666 .map(function( i, elem ) {
5667 var val = jQuery(this).val();
5668
5669 return val == null ?
5670 null :
5671 jQuery.isArray(val) ?
5672 jQuery.map( val, function( val, i ) {
5673 return { name: elem.name, value: val };
5674 }) :
5675 { name: elem.name, value: val };
5676 }).get();
5677 }
5678});
5679
5680// Attach a bunch of functions for handling common AJAX events
5681jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) {
5682 jQuery.fn[o] = function( f ) {
5683 return this.bind(o, f);
5684 };
5685});
5686
5687jQuery.extend({
5688 get: function( url, data, callback, type ) {
5689 // shift arguments if data argument was omited
5690 if ( jQuery.isFunction( data ) ) {
5691 type = type || callback;
5692 callback = data;
5693 data = null;
5694 }
5695
5696 return jQuery.ajax({
5697 type: "GET",
5698 url: url,
5699 data: data,
5700 success: callback,
5701 dataType: type
5702 });
5703 },
5704
5705 getScript: function( url, callback ) {
5706 return jQuery.get(url, null, callback, "script");
5707 },
5708
5709 getJSON: function( url, data, callback ) {
5710 return jQuery.get(url, data, callback, "json");
5711 },
5712
5713 post: function( url, data, callback, type ) {
5714 // shift arguments if data argument was omited
5715 if ( jQuery.isFunction( data ) ) {
5716 type = type || callback;
5717 callback = data;
5718 data = {};
5719 }
5720
5721 return jQuery.ajax({
5722 type: "POST",
5723 url: url,
5724 data: data,
5725 success: callback,
5726 dataType: type
5727 });
5728 },
5729
5730 ajaxSetup: function( settings ) {
5731 jQuery.extend( jQuery.ajaxSettings, settings );
5732 },
5733
5734 ajaxSettings: {
5735 url: location.href,
5736 global: true,
5737 type: "GET",
5738 contentType: "application/x-www-form-urlencoded",
5739 processData: true,
5740 async: true,
5741 /*
5742 timeout: 0,
5743 data: null,
5744 username: null,
5745 password: null,
5746 traditional: false,
5747 */
5748 // This function can be overriden by calling jQuery.ajaxSetup
5749 xhr: function() {
5750 return new window.XMLHttpRequest();
5751 },
5752 accepts: {
5753 xml: "application/xml, text/xml",
5754 html: "text/html",
5755 script: "text/javascript, application/javascript",
5756 json: "application/json, text/javascript",
5757 text: "text/plain",
5758 _default: "*/*"
5759 }
5760 },
5761
5762 ajax: function( origSettings ) {
5763 var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings),
5764 jsonp, status, data, type = s.type.toUpperCase(), noContent = rnoContent.test(type);
5765
5766 s.url = s.url.replace( rhash, "" );
5767
5768 // Use original (not extended) context object if it was provided
5769 s.context = origSettings && origSettings.context != null ? origSettings.context : s;
5770
5771 // convert data if not already a string
5772 if ( s.data && s.processData && typeof s.data !== "string" ) {
5773 s.data = jQuery.param( s.data, s.traditional );
5774 }
5775
5776 // Handle JSONP Parameter Callbacks
5777 if ( s.dataType === "jsonp" ) {
5778 if ( type === "GET" ) {
5779 if ( !jsre.test( s.url ) ) {
5780 s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";
5781 }
5782 } else if ( !s.data || !jsre.test(s.data) ) {
5783 s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
5784 }
5785 s.dataType = "json";
5786 }
5787
5788 // Build temporary JSONP function
5789 if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
5790 jsonp = s.jsonpCallback || ("jsonp" + jsc++);
5791
5792 // Replace the =? sequence both in the query string and the data
5793 if ( s.data ) {
5794 s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
5795 }
5796
5797 s.url = s.url.replace(jsre, "=" + jsonp + "$1");
5798
5799 // We need to make sure
5800 // that a JSONP style response is executed properly
5801 s.dataType = "script";
5802
5803 // Handle JSONP-style loading
5804 var customJsonp = window[ jsonp ];
5805
5806 window[ jsonp ] = function( tmp ) {
5807 if ( jQuery.isFunction( customJsonp ) ) {
5808 customJsonp( tmp );
5809
5810 } else {
5811 // Garbage collect
5812 window[ jsonp ] = undefined;
5813
5814 try {
5815 delete window[ jsonp ];
5816 } catch( jsonpError ) {}
5817 }
5818
5819 data = tmp;
5820 jQuery.handleSuccess( s, xhr, status, data );
5821 jQuery.handleComplete( s, xhr, status, data );
5822
5823 if ( head ) {
5824 head.removeChild( script );
5825 }
5826 };
5827 }
5828
5829 if ( s.dataType === "script" && s.cache === null ) {
5830 s.cache = false;
5831 }
5832
5833 if ( s.cache === false && noContent ) {
5834 var ts = jQuery.now();
5835
5836 // try replacing _= if it is there
5837 var ret = s.url.replace(rts, "$1_=" + ts);
5838
5839 // if nothing was replaced, add timestamp to the end
5840 s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
5841 }
5842
5843 // If data is available, append data to url for GET/HEAD requests
5844 if ( s.data && noContent ) {
5845 s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
5846 }
5847
5848 // Watch for a new set of requests
5849 if ( s.global && jQuery.active++ === 0 ) {
5850 jQuery.event.trigger( "ajaxStart" );
5851 }
5852
5853 // Matches an absolute URL, and saves the domain
5854 var parts = rurl.exec( s.url ),
5855 remote = parts && (parts[1] && parts[1].toLowerCase() !== location.protocol || parts[2].toLowerCase() !== location.host);
5856
5857 // If we're requesting a remote document
5858 // and trying to load JSON or Script with a GET
5859 if ( s.dataType === "script" && type === "GET" && remote ) {
5860 var head = document.getElementsByTagName("head")[0] || document.documentElement;
5861 var script = document.createElement("script");
5862 if ( s.scriptCharset ) {
5863 script.charset = s.scriptCharset;
5864 }
5865 script.src = s.url;
5866
5867 // Handle Script loading
5868 if ( !jsonp ) {
5869 var done = false;
5870
5871 // Attach handlers for all browsers
5872 script.onload = script.onreadystatechange = function() {
5873 if ( !done && (!this.readyState ||
5874 this.readyState === "loaded" || this.readyState === "complete") ) {
5875 done = true;
5876 jQuery.handleSuccess( s, xhr, status, data );
5877 jQuery.handleComplete( s, xhr, status, data );
5878
5879 // Handle memory leak in IE
5880 script.onload = script.onreadystatechange = null;
5881 if ( head && script.parentNode ) {
5882 head.removeChild( script );
5883 }
5884 }
5885 };
5886 }
5887
5888 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
5889 // This arises when a base node is used (#2709 and #4378).
5890 head.insertBefore( script, head.firstChild );
5891
5892 // We handle everything using the script element injection
5893 return undefined;
5894 }
5895
5896 var requestDone = false;
5897
5898 // Create the request object
5899 var xhr = s.xhr();
5900
5901 if ( !xhr ) {
5902 return;
5903 }
5904
5905 // Open the socket
5906 // Passing null username, generates a login popup on Opera (#2865)
5907 if ( s.username ) {
5908 xhr.open(type, s.url, s.async, s.username, s.password);
5909 } else {
5910 xhr.open(type, s.url, s.async);
5911 }
5912
5913 // Need an extra try/catch for cross domain requests in Firefox 3
5914 try {
5915 // Set content-type if data specified and content-body is valid for this type
5916 if ( (s.data != null && !noContent) || (origSettings && origSettings.contentType) ) {
5917 xhr.setRequestHeader("Content-Type", s.contentType);
5918 }
5919
5920 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
5921 if ( s.ifModified ) {
5922 if ( jQuery.lastModified[s.url] ) {
5923 xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);
5924 }
5925
5926 if ( jQuery.etag[s.url] ) {
5927 xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]);
5928 }
5929 }
5930
5931 // Set header so the called script knows that it's an XMLHttpRequest
5932 // Only send the header if it's not a remote XHR
5933 if ( !remote ) {
5934 xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
5935 }
5936
5937 // Set the Accepts header for the server, depending on the dataType
5938 xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
5939 s.accepts[ s.dataType ] + ", */*; q=0.01" :
5940 s.accepts._default );
5941 } catch( headerError ) {}
5942
5943 // Allow custom headers/mimetypes and early abort
5944 if ( s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false ) {
5945 // Handle the global AJAX counter
5946 if ( s.global && jQuery.active-- === 1 ) {
5947 jQuery.event.trigger( "ajaxStop" );
5948 }
5949
5950 // close opended socket
5951 xhr.abort();
5952 return false;
5953 }
5954
5955 if ( s.global ) {
5956 jQuery.triggerGlobal( s, "ajaxSend", [xhr, s] );
5957 }
5958
5959 // Wait for a response to come back
5960 var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {
5961 // The request was aborted
5962 if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) {
5963 // Opera doesn't call onreadystatechange before this point
5964 // so we simulate the call
5965 if ( !requestDone ) {
5966 jQuery.handleComplete( s, xhr, status, data );
5967 }
5968
5969 requestDone = true;
5970 if ( xhr ) {
5971 xhr.onreadystatechange = jQuery.noop;
5972 }
5973
5974 // The transfer is complete and the data is available, or the request timed out
5975 } else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
5976 requestDone = true;
5977 xhr.onreadystatechange = jQuery.noop;
5978
5979 status = isTimeout === "timeout" ?
5980 "timeout" :
5981 !jQuery.httpSuccess( xhr ) ?
5982 "error" :
5983 s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?
5984 "notmodified" :
5985 "success";
5986
5987 var errMsg;
5988
5989 if ( status === "success" ) {
5990 // Watch for, and catch, XML document parse errors
5991 try {
5992 // process the data (runs the xml through httpData regardless of callback)
5993 data = jQuery.httpData( xhr, s.dataType, s );
5994 } catch( parserError ) {
5995 status = "parsererror";
5996 errMsg = parserError;
5997 }
5998 }
5999
6000 // Make sure that the request was successful or notmodified
6001 if ( status === "success" || status === "notmodified" ) {
6002 // JSONP handles its own success callback
6003 if ( !jsonp ) {
6004 jQuery.handleSuccess( s, xhr, status, data );
6005 }
6006 } else {
6007 jQuery.handleError( s, xhr, status, errMsg );
6008 }
6009
6010 // Fire the complete handlers
6011 if ( !jsonp ) {
6012 jQuery.handleComplete( s, xhr, status, data );
6013 }
6014
6015 if ( isTimeout === "timeout" ) {
6016 xhr.abort();
6017 }
6018
6019 // Stop memory leaks
6020 if ( s.async ) {
6021 xhr = null;
6022 }
6023 }
6024 };
6025
6026 // Override the abort handler, if we can (IE 6 doesn't allow it, but that's OK)
6027 // Opera doesn't fire onreadystatechange at all on abort
6028 try {
6029 var oldAbort = xhr.abort;
6030 xhr.abort = function() {
6031 if ( xhr ) {
6032 // oldAbort has no call property in IE7 so
6033 // just do it this way, which works in all
6034 // browsers
6035 Function.prototype.call.call( oldAbort, xhr );
6036 }
6037
6038 onreadystatechange( "abort" );
6039 };
6040 } catch( abortError ) {}
6041
6042 // Timeout checker
6043 if ( s.async && s.timeout > 0 ) {
6044 setTimeout(function() {
6045 // Check to see if the request is still happening
6046 if ( xhr && !requestDone ) {
6047 onreadystatechange( "timeout" );
6048 }
6049 }, s.timeout);
6050 }
6051
6052 // Send the data
6053 try {
6054 xhr.send( noContent || s.data == null ? null : s.data );
6055
6056 } catch( sendError ) {
6057 jQuery.handleError( s, xhr, null, sendError );
6058
6059 // Fire the complete handlers
6060 jQuery.handleComplete( s, xhr, status, data );
6061 }
6062
6063 // firefox 1.5 doesn't fire statechange for sync requests
6064 if ( !s.async ) {
6065 onreadystatechange();
6066 }
6067
6068 // return XMLHttpRequest to allow aborting the request etc.
6069 return xhr;
6070 },
6071
6072 // Serialize an array of form elements or a set of
6073 // key/values into a query string
6074 param: function( a, traditional ) {
6075 var s = [],
6076 add = function( key, value ) {
6077 // If value is a function, invoke it and return its value
6078 value = jQuery.isFunction(value) ? value() : value;
6079 s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
6080 };
6081
6082 // Set traditional to true for jQuery <= 1.3.2 behavior.
6083 if ( traditional === undefined ) {
6084 traditional = jQuery.ajaxSettings.traditional;
6085 }
6086
6087 // If an array was passed in, assume that it is an array of form elements.
6088 if ( jQuery.isArray(a) || a.jquery ) {
6089 // Serialize the form elements
6090 jQuery.each( a, function() {
6091 add( this.name, this.value );
6092 });
6093
6094 } else {
6095 // If traditional, encode the "old" way (the way 1.3.2 or older
6096 // did it), otherwise encode params recursively.
6097 for ( var prefix in a ) {
6098 buildParams( prefix, a[prefix], traditional, add );
6099 }
6100 }
6101
6102 // Return the resulting serialization
6103 return s.join("&").replace(r20, "+");
6104 }
6105});
6106
6107function buildParams( prefix, obj, traditional, add ) {
6108 if ( jQuery.isArray(obj) && obj.length ) {
6109 // Serialize array item.
6110 jQuery.each( obj, function( i, v ) {
6111 if ( traditional || rbracket.test( prefix ) ) {
6112 // Treat each array item as a scalar.
6113 add( prefix, v );
6114
6115 } else {
6116 // If array item is non-scalar (array or object), encode its
6117 // numeric index to resolve deserialization ambiguity issues.
6118 // Note that rack (as of 1.0.0) can't currently deserialize
6119 // nested arrays properly, and attempting to do so may cause
6120 // a server error. Possible fixes are to modify rack's
6121 // deserialization algorithm or to provide an option or flag
6122 // to force array serialization to be shallow.
6123 buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
6124 }
6125 });
6126
6127 } else if ( !traditional && obj != null && typeof obj === "object" ) {
6128 if ( jQuery.isEmptyObject( obj ) ) {
6129 add( prefix, "" );
6130
6131 // Serialize object item.
6132 } else {
6133 jQuery.each( obj, function( k, v ) {
6134 buildParams( prefix + "[" + k + "]", v, traditional, add );
6135 });
6136 }
6137
6138 } else {
6139 // Serialize scalar item.
6140 add( prefix, obj );
6141 }
6142}
6143
6144// This is still on the jQuery object... for now
6145// Want to move this to jQuery.ajax some day
6146jQuery.extend({
6147
6148 // Counter for holding the number of active queries
6149 active: 0,
6150
6151 // Last-Modified header cache for next request
6152 lastModified: {},
6153 etag: {},
6154
6155 handleError: function( s, xhr, status, e ) {
6156 // If a local callback was specified, fire it
6157 if ( s.error ) {
6158 s.error.call( s.context, xhr, status, e );
6159 }
6160
6161 // Fire the global callback
6162 if ( s.global ) {
6163 jQuery.triggerGlobal( s, "ajaxError", [xhr, s, e] );
6164 }
6165 },
6166
6167 handleSuccess: function( s, xhr, status, data ) {
6168 // If a local callback was specified, fire it and pass it the data
6169 if ( s.success ) {
6170 s.success.call( s.context, data, status, xhr );
6171 }
6172
6173 // Fire the global callback
6174 if ( s.global ) {
6175 jQuery.triggerGlobal( s, "ajaxSuccess", [xhr, s] );
6176 }
6177 },
6178
6179 handleComplete: function( s, xhr, status ) {
6180 // Process result
6181 if ( s.complete ) {
6182 s.complete.call( s.context, xhr, status );
6183 }
6184
6185 // The request was completed
6186 if ( s.global ) {
6187 jQuery.triggerGlobal( s, "ajaxComplete", [xhr, s] );
6188 }
6189
6190 // Handle the global AJAX counter
6191 if ( s.global && jQuery.active-- === 1 ) {
6192 jQuery.event.trigger( "ajaxStop" );
6193 }
6194 },
6195
6196 triggerGlobal: function( s, type, args ) {
6197 (s.context && s.context.url == null ? jQuery(s.context) : jQuery.event).trigger(type, args);
6198 },
6199
6200 // Determines if an XMLHttpRequest was successful or not
6201 httpSuccess: function( xhr ) {
6202 try {
6203 // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
6204 return !xhr.status && location.protocol === "file:" ||
6205 xhr.status >= 200 && xhr.status < 300 ||
6206 xhr.status === 304 || xhr.status === 1223;
6207 } catch(e) {}
6208
6209 return false;
6210 },
6211
6212 // Determines if an XMLHttpRequest returns NotModified
6213 httpNotModified: function( xhr, url ) {
6214 var lastModified = xhr.getResponseHeader("Last-Modified"),
6215 etag = xhr.getResponseHeader("Etag");
6216
6217 if ( lastModified ) {
6218 jQuery.lastModified[url] = lastModified;
6219 }
6220
6221 if ( etag ) {
6222 jQuery.etag[url] = etag;
6223 }
6224
6225 return xhr.status === 304;
6226 },
6227
6228 httpData: function( xhr, type, s ) {
6229 var ct = xhr.getResponseHeader("content-type") || "",
6230 xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
6231 data = xml ? xhr.responseXML : xhr.responseText;
6232
6233 if ( xml && data.documentElement.nodeName === "parsererror" ) {
6234 jQuery.error( "parsererror" );
6235 }
6236
6237 // Allow a pre-filtering function to sanitize the response
6238 // s is checked to keep backwards compatibility
6239 if ( s && s.dataFilter ) {
6240 data = s.dataFilter( data, type );
6241 }
6242
6243 // The filter can actually parse the response
6244 if ( typeof data === "string" ) {
6245 // Get the JavaScript object, if JSON is used.
6246 if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {
6247 data = jQuery.parseJSON( data );
6248
6249 // If the type is "script", eval it in global context
6250 } else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {
6251 jQuery.globalEval( data );
6252 }
6253 }
6254
6255 return data;
6256 }
6257
6258});
6259
6260/*
6261 * Create the request object; Microsoft failed to properly
6262 * implement the XMLHttpRequest in IE7 (can't request local files),
6263 * so we use the ActiveXObject when it is available
6264 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
6265 * we need a fallback.
6266 */
6267if ( window.ActiveXObject ) {
6268 jQuery.ajaxSettings.xhr = function() {
6269 if ( window.location.protocol !== "file:" ) {
6270 try {
6271 return new window.XMLHttpRequest();
6272 } catch(xhrError) {}
6273 }
6274
6275 try {
6276 return new window.ActiveXObject("Microsoft.XMLHTTP");
6277 } catch(activeError) {}
6278 };
6279}
6280
6281// Does this browser support XHR requests?
6282jQuery.support.ajax = !!jQuery.ajaxSettings.xhr();
6283
6284
6285
6286
6287var elemdisplay = {},
6288 rfxtypes = /^(?:toggle|show|hide)$/,
6289 rfxnum = /^([+\-]=)?([\d+.\-]+)(.*)$/,
6290 timerId,
6291 fxAttrs = [
6292 // height animations
6293 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
6294 // width animations
6295 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
6296 // opacity animations
6297 [ "opacity" ]
6298 ];
6299
6300jQuery.fn.extend({
6301 show: function( speed, easing, callback ) {
6302 var elem, display;
6303
6304 if ( speed || speed === 0 ) {
6305 return this.animate( genFx("show", 3), speed, easing, callback);
6306
6307 } else {
6308 for ( var i = 0, j = this.length; i < j; i++ ) {
6309 elem = this[i];
6310 display = elem.style.display;
6311
6312 // Reset the inline display of this element to learn if it is
6313 // being hidden by cascaded rules or not
6314 if ( !jQuery.data(elem, "olddisplay") && display === "none" ) {
6315 display = elem.style.display = "";
6316 }
6317
6318 // Set elements which have been overridden with display: none
6319 // in a stylesheet to whatever the default browser style is
6320 // for such an element
6321 if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
6322 jQuery.data(elem, "olddisplay", defaultDisplay(elem.nodeName));
6323 }
6324 }
6325
6326 // Set the display of most of the elements in a second loop
6327 // to avoid the constant reflow
6328 for ( i = 0; i < j; i++ ) {
6329 elem = this[i];
6330 display = elem.style.display;
6331
6332 if ( display === "" || display === "none" ) {
6333 elem.style.display = jQuery.data(elem, "olddisplay") || "";
6334 }
6335 }
6336
6337 return this;
6338 }
6339 },
6340
6341 hide: function( speed, easing, callback ) {
6342 if ( speed || speed === 0 ) {
6343 return this.animate( genFx("hide", 3), speed, easing, callback);
6344
6345 } else {
6346 for ( var i = 0, j = this.length; i < j; i++ ) {
6347 var display = jQuery.css( this[i], "display" );
6348
6349 if ( display !== "none" ) {
6350 jQuery.data( this[i], "olddisplay", display );
6351 }
6352 }
6353
6354 // Set the display of the elements in a second loop
6355 // to avoid the constant reflow
6356 for ( i = 0; i < j; i++ ) {
6357 this[i].style.display = "none";
6358 }
6359
6360 return this;
6361 }
6362 },
6363
6364 // Save the old toggle function
6365 _toggle: jQuery.fn.toggle,
6366
6367 toggle: function( fn, fn2, callback ) {
6368 var bool = typeof fn === "boolean";
6369
6370 if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
6371 this._toggle.apply( this, arguments );
6372
6373 } else if ( fn == null || bool ) {
6374 this.each(function() {
6375 var state = bool ? fn : jQuery(this).is(":hidden");
6376 jQuery(this)[ state ? "show" : "hide" ]();
6377 });
6378
6379 } else {
6380 this.animate(genFx("toggle", 3), fn, fn2, callback);
6381 }
6382
6383 return this;
6384 },
6385
6386 fadeTo: function( speed, to, easing, callback ) {
6387 return this.filter(":hidden").css("opacity", 0).show().end()
6388 .animate({opacity: to}, speed, easing, callback);
6389 },
6390
6391 animate: function( prop, speed, easing, callback ) {
6392 var optall = jQuery.speed(speed, easing, callback);
6393
6394 if ( jQuery.isEmptyObject( prop ) ) {
6395 return this.each( optall.complete );
6396 }
6397
6398 return this[ optall.queue === false ? "each" : "queue" ](function() {
6399 // XXX 'this' does not always have a nodeName when running the
6400 // test suite
6401
6402 var opt = jQuery.extend({}, optall), p,
6403 isElement = this.nodeType === 1,
6404 hidden = isElement && jQuery(this).is(":hidden"),
6405 self = this;
6406
6407 for ( p in prop ) {
6408 var name = jQuery.camelCase( p );
6409
6410 if ( p !== name ) {
6411 prop[ name ] = prop[ p ];
6412 delete prop[ p ];
6413 p = name;
6414 }
6415
6416 if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) {
6417 return opt.complete.call(this);
6418 }
6419
6420 if ( isElement && ( p === "height" || p === "width" ) ) {
6421 // Make sure that nothing sneaks out
6422 // Record all 3 overflow attributes because IE does not
6423 // change the overflow attribute when overflowX and
6424 // overflowY are set to the same value
6425 opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
6426
6427 // Set display property to inline-block for height/width
6428 // animations on inline elements that are having width/height
6429 // animated
6430 if ( jQuery.css( this, "display" ) === "inline" &&
6431 jQuery.css( this, "float" ) === "none" ) {
6432 if ( !jQuery.support.inlineBlockNeedsLayout ) {
6433 this.style.display = "inline-block";
6434
6435 } else {
6436 var display = defaultDisplay(this.nodeName);
6437
6438 // inline-level elements accept inline-block;
6439 // block-level elements need to be inline with layout
6440 if ( display === "inline" ) {
6441 this.style.display = "inline-block";
6442
6443 } else {
6444 this.style.display = "inline";
6445 this.style.zoom = 1;
6446 }
6447 }
6448 }
6449 }
6450
6451 if ( jQuery.isArray( prop[p] ) ) {
6452 // Create (if needed) and add to specialEasing
6453 (opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];
6454 prop[p] = prop[p][0];
6455 }
6456 }
6457
6458 if ( opt.overflow != null ) {
6459 this.style.overflow = "hidden";
6460 }
6461
6462 opt.curAnim = jQuery.extend({}, prop);
6463
6464 jQuery.each( prop, function( name, val ) {
6465 var e = new jQuery.fx( self, opt, name );
6466
6467 if ( rfxtypes.test(val) ) {
6468 e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop );
6469
6470 } else {
6471 var parts = rfxnum.exec(val),
6472 start = e.cur() || 0;
6473
6474 if ( parts ) {
6475 var end = parseFloat( parts[2] ),
6476 unit = parts[3] || "px";
6477
6478 // We need to compute starting value
6479 if ( unit !== "px" ) {
6480 jQuery.style( self, name, (end || 1) + unit);
6481 start = ((end || 1) / e.cur()) * start;
6482 jQuery.style( self, name, start + unit);
6483 }
6484
6485 // If a +=/-= token was provided, we're doing a relative animation
6486 if ( parts[1] ) {
6487 end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
6488 }
6489
6490 e.custom( start, end, unit );
6491
6492 } else {
6493 e.custom( start, val, "" );
6494 }
6495 }
6496 });
6497
6498 // For JS strict compliance
6499 return true;
6500 });
6501 },
6502
6503 stop: function( clearQueue, gotoEnd ) {
6504 var timers = jQuery.timers;
6505
6506 if ( clearQueue ) {
6507 this.queue([]);
6508 }
6509
6510 this.each(function() {
6511 // go in reverse order so anything added to the queue during the loop is ignored
6512 for ( var i = timers.length - 1; i >= 0; i-- ) {
6513 if ( timers[i].elem === this ) {
6514 if (gotoEnd) {
6515 // force the next step to be the last
6516 timers[i](true);
6517 }
6518
6519 timers.splice(i, 1);
6520 }
6521 }
6522 });
6523
6524 // start the next in the queue if the last step wasn't forced
6525 if ( !gotoEnd ) {
6526 this.dequeue();
6527 }
6528
6529 return this;
6530 }
6531
6532});
6533
6534function genFx( type, num ) {
6535 var obj = {};
6536
6537 jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
6538 obj[ this ] = type;
6539 });
6540
6541 return obj;
6542}
6543
6544// Generate shortcuts for custom animations
6545jQuery.each({
6546 slideDown: genFx("show", 1),
6547 slideUp: genFx("hide", 1),
6548 slideToggle: genFx("toggle", 1),
6549 fadeIn: { opacity: "show" },
6550 fadeOut: { opacity: "hide" },
6551 fadeToggle: { opacity: "toggle" }
6552}, function( name, props ) {
6553 jQuery.fn[ name ] = function( speed, easing, callback ) {
6554 return this.animate( props, speed, easing, callback );
6555 };
6556});
6557
6558jQuery.extend({
6559 speed: function( speed, easing, fn ) {
6560 var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
6561 complete: fn || !fn && easing ||
6562 jQuery.isFunction( speed ) && speed,
6563 duration: speed,
6564 easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
6565 };
6566
6567 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
6568 opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
6569
6570 // Queueing
6571 opt.old = opt.complete;
6572 opt.complete = function() {
6573 if ( opt.queue !== false ) {
6574 jQuery(this).dequeue();
6575 }
6576 if ( jQuery.isFunction( opt.old ) ) {
6577 opt.old.call( this );
6578 }
6579 };
6580
6581 return opt;
6582 },
6583
6584 easing: {
6585 linear: function( p, n, firstNum, diff ) {
6586 return firstNum + diff * p;
6587 },
6588 swing: function( p, n, firstNum, diff ) {
6589 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
6590 }
6591 },
6592
6593 timers: [],
6594
6595 fx: function( elem, options, prop ) {
6596 this.options = options;
6597 this.elem = elem;
6598 this.prop = prop;
6599
6600 if ( !options.orig ) {
6601 options.orig = {};
6602 }
6603 }
6604
6605});
6606
6607jQuery.fx.prototype = {
6608 // Simple function for setting a style value
6609 update: function() {
6610 if ( this.options.step ) {
6611 this.options.step.call( this.elem, this.now, this );
6612 }
6613
6614 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
6615 },
6616
6617 // Get the current size
6618 cur: function() {
6619 if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
6620 return this.elem[ this.prop ];
6621 }
6622
6623 var r = parseFloat( jQuery.css( this.elem, this.prop ) );
6624 return r && r > -10000 ? r : 0;
6625 },
6626
6627 // Start an animation from one number to another
6628 custom: function( from, to, unit ) {
6629 var self = this,
6630 fx = jQuery.fx;
6631
6632 this.startTime = jQuery.now();
6633 this.start = from;
6634 this.end = to;
6635 this.unit = unit || this.unit || "px";
6636 this.now = this.start;
6637 this.pos = this.state = 0;
6638
6639 function t( gotoEnd ) {
6640 return self.step(gotoEnd);
6641 }
6642
6643 t.elem = this.elem;
6644
6645 if ( t() && jQuery.timers.push(t) && !timerId ) {
6646 timerId = setInterval(fx.tick, fx.interval);
6647 }
6648 },
6649
6650 // Simple 'show' function
6651 show: function() {
6652 // Remember where we started, so that we can go back to it later
6653 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
6654 this.options.show = true;
6655
6656 // Begin the animation
6657 // Make sure that we start at a small width/height to avoid any
6658 // flash of content
6659 this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
6660
6661 // Start by showing the element
6662 jQuery( this.elem ).show();
6663 },
6664
6665 // Simple 'hide' function
6666 hide: function() {
6667 // Remember where we started, so that we can go back to it later
6668 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
6669 this.options.hide = true;
6670
6671 // Begin the animation
6672 this.custom(this.cur(), 0);
6673 },
6674
6675 // Each step of an animation
6676 step: function( gotoEnd ) {
6677 var t = jQuery.now(), done = true;
6678
6679 if ( gotoEnd || t >= this.options.duration + this.startTime ) {
6680 this.now = this.end;
6681 this.pos = this.state = 1;
6682 this.update();
6683
6684 this.options.curAnim[ this.prop ] = true;
6685
6686 for ( var i in this.options.curAnim ) {
6687 if ( this.options.curAnim[i] !== true ) {
6688 done = false;
6689 }
6690 }
6691
6692 if ( done ) {
6693 // Reset the overflow
6694 if ( this.options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
6695 var elem = this.elem,
6696 options = this.options;
6697
6698 jQuery.each( [ "", "X", "Y" ], function (index, value) {
6699 elem.style[ "overflow" + value ] = options.overflow[index];
6700 } );
6701 }
6702
6703 // Hide the element if the "hide" operation was done
6704 if ( this.options.hide ) {
6705 jQuery(this.elem).hide();
6706 }
6707
6708 // Reset the properties, if the item has been hidden or shown
6709 if ( this.options.hide || this.options.show ) {
6710 for ( var p in this.options.curAnim ) {
6711 jQuery.style( this.elem, p, this.options.orig[p] );
6712 }
6713 }
6714
6715 // Execute the complete function
6716 this.options.complete.call( this.elem );
6717 }
6718
6719 return false;
6720
6721 } else {
6722 var n = t - this.startTime;
6723 this.state = n / this.options.duration;
6724
6725 // Perform the easing function, defaults to swing
6726 var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop];
6727 var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear");
6728 this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);
6729 this.now = this.start + ((this.end - this.start) * this.pos);
6730
6731 // Perform the next step of the animation
6732 this.update();
6733 }
6734
6735 return true;
6736 }
6737};
6738
6739jQuery.extend( jQuery.fx, {
6740 tick: function() {
6741 var timers = jQuery.timers;
6742
6743 for ( var i = 0; i < timers.length; i++ ) {
6744 if ( !timers[i]() ) {
6745 timers.splice(i--, 1);
6746 }
6747 }
6748
6749 if ( !timers.length ) {
6750 jQuery.fx.stop();
6751 }
6752 },
6753
6754 interval: 13,
6755
6756 stop: function() {
6757 clearInterval( timerId );
6758 timerId = null;
6759 },
6760
6761 speeds: {
6762 slow: 600,
6763 fast: 200,
6764 // Default speed
6765 _default: 400
6766 },
6767
6768 step: {
6769 opacity: function( fx ) {
6770 jQuery.style( fx.elem, "opacity", fx.now );
6771 },
6772
6773 _default: function( fx ) {
6774 if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
6775 fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
6776 } else {
6777 fx.elem[ fx.prop ] = fx.now;
6778 }
6779 }
6780 }
6781});
6782
6783if ( jQuery.expr && jQuery.expr.filters ) {
6784 jQuery.expr.filters.animated = function( elem ) {
6785 return jQuery.grep(jQuery.timers, function( fn ) {
6786 return elem === fn.elem;
6787 }).length;
6788 };
6789}
6790
6791function defaultDisplay( nodeName ) {
6792 if ( !elemdisplay[ nodeName ] ) {
6793 var elem = jQuery("<" + nodeName + ">").appendTo("body"),
6794 display = elem.css("display");
6795
6796 elem.remove();
6797
6798 if ( display === "none" || display === "" ) {
6799 display = "block";
6800 }
6801
6802 elemdisplay[ nodeName ] = display;
6803 }
6804
6805 return elemdisplay[ nodeName ];
6806}
6807
6808
6809
6810
6811var rtable = /^t(?:able|d|h)$/i,
6812 rroot = /^(?:body|html)$/i;
6813
6814if ( "getBoundingClientRect" in document.documentElement ) {
6815 jQuery.fn.offset = function( options ) {
6816 var elem = this[0], box;
6817
6818 if ( options ) {
6819 return this.each(function( i ) {
6820 jQuery.offset.setOffset( this, options, i );
6821 });
6822 }
6823
6824 if ( !elem || !elem.ownerDocument ) {
6825 return null;
6826 }
6827
6828 if ( elem === elem.ownerDocument.body ) {
6829 return jQuery.offset.bodyOffset( elem );
6830 }
6831
6832 try {
6833 box = elem.getBoundingClientRect();
6834 } catch(e) {}
6835
6836 var doc = elem.ownerDocument,
6837 docElem = doc.documentElement;
6838
6839 // Make sure we're not dealing with a disconnected DOM node
6840 if ( !box || !jQuery.contains( docElem, elem ) ) {
6841 return box || { top: 0, left: 0 };
6842 }
6843
6844 var body = doc.body,
6845 win = getWindow(doc),
6846 clientTop = docElem.clientTop || body.clientTop || 0,
6847 clientLeft = docElem.clientLeft || body.clientLeft || 0,
6848 scrollTop = (win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop ),
6849 scrollLeft = (win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft),
6850 top = box.top + scrollTop - clientTop,
6851 left = box.left + scrollLeft - clientLeft;
6852
6853 return { top: top, left: left };
6854 };
6855
6856} else {
6857 jQuery.fn.offset = function( options ) {
6858 var elem = this[0];
6859
6860 if ( options ) {
6861 return this.each(function( i ) {
6862 jQuery.offset.setOffset( this, options, i );
6863 });
6864 }
6865
6866 if ( !elem || !elem.ownerDocument ) {
6867 return null;
6868 }
6869
6870 if ( elem === elem.ownerDocument.body ) {
6871 return jQuery.offset.bodyOffset( elem );
6872 }
6873
6874 jQuery.offset.initialize();
6875
6876 var computedStyle,
6877 offsetParent = elem.offsetParent,
6878 prevOffsetParent = elem,
6879 doc = elem.ownerDocument,
6880 docElem = doc.documentElement,
6881 body = doc.body,
6882 defaultView = doc.defaultView,
6883 prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
6884 top = elem.offsetTop,
6885 left = elem.offsetLeft;
6886
6887 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
6888 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
6889 break;
6890 }
6891
6892 computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
6893 top -= elem.scrollTop;
6894 left -= elem.scrollLeft;
6895
6896 if ( elem === offsetParent ) {
6897 top += elem.offsetTop;
6898 left += elem.offsetLeft;
6899
6900 if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
6901 top += parseFloat( computedStyle.borderTopWidth ) || 0;
6902 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
6903 }
6904
6905 prevOffsetParent = offsetParent;
6906 offsetParent = elem.offsetParent;
6907 }
6908
6909 if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
6910 top += parseFloat( computedStyle.borderTopWidth ) || 0;
6911 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
6912 }
6913
6914 prevComputedStyle = computedStyle;
6915 }
6916
6917 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
6918 top += body.offsetTop;
6919 left += body.offsetLeft;
6920 }
6921
6922 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
6923 top += Math.max( docElem.scrollTop, body.scrollTop );
6924 left += Math.max( docElem.scrollLeft, body.scrollLeft );
6925 }
6926
6927 return { top: top, left: left };
6928 };
6929}
6930
6931jQuery.offset = {
6932 initialize: function() {
6933 var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
6934 html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
6935
6936 jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
6937
6938 container.innerHTML = html;
6939 body.insertBefore( container, body.firstChild );
6940 innerDiv = container.firstChild;
6941 checkDiv = innerDiv.firstChild;
6942 td = innerDiv.nextSibling.firstChild.firstChild;
6943
6944 this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
6945 this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
6946
6947 checkDiv.style.position = "fixed";
6948 checkDiv.style.top = "20px";
6949
6950 // safari subtracts parent border width here which is 5px
6951 this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
6952 checkDiv.style.position = checkDiv.style.top = "";
6953
6954 innerDiv.style.overflow = "hidden";
6955 innerDiv.style.position = "relative";
6956
6957 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
6958
6959 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
6960
6961 body.removeChild( container );
6962 body = container = innerDiv = checkDiv = table = td = null;
6963 jQuery.offset.initialize = jQuery.noop;
6964 },
6965
6966 bodyOffset: function( body ) {
6967 var top = body.offsetTop,
6968 left = body.offsetLeft;
6969
6970 jQuery.offset.initialize();
6971
6972 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
6973 top += parseFloat( jQuery.css(body, "marginTop") ) || 0;
6974 left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
6975 }
6976
6977 return { top: top, left: left };
6978 },
6979
6980 setOffset: function( elem, options, i ) {
6981 var position = jQuery.css( elem, "position" );
6982
6983 // set position first, in-case top/left are set even on static elem
6984 if ( position === "static" ) {
6985 elem.style.position = "relative";
6986 }
6987
6988 var curElem = jQuery( elem ),
6989 curOffset = curElem.offset(),
6990 curCSSTop = jQuery.css( elem, "top" ),
6991 curCSSLeft = jQuery.css( elem, "left" ),
6992 calculatePosition = (position === "absolute" && jQuery.inArray('auto', [curCSSTop, curCSSLeft]) > -1),
6993 props = {}, curPosition = {}, curTop, curLeft;
6994
6995 // need to be able to calculate position if either top or left is auto and position is absolute
6996 if ( calculatePosition ) {
6997 curPosition = curElem.position();
6998 }
6999
7000 curTop = calculatePosition ? curPosition.top : parseInt( curCSSTop, 10 ) || 0;
7001 curLeft = calculatePosition ? curPosition.left : parseInt( curCSSLeft, 10 ) || 0;
7002
7003 if ( jQuery.isFunction( options ) ) {
7004 options = options.call( elem, i, curOffset );
7005 }
7006
7007 if (options.top != null) {
7008 props.top = (options.top - curOffset.top) + curTop;
7009 }
7010 if (options.left != null) {
7011 props.left = (options.left - curOffset.left) + curLeft;
7012 }
7013
7014 if ( "using" in options ) {
7015 options.using.call( elem, props );
7016 } else {
7017 curElem.css( props );
7018 }
7019 }
7020};
7021
7022
7023jQuery.fn.extend({
7024 position: function() {
7025 if ( !this[0] ) {
7026 return null;
7027 }
7028
7029 var elem = this[0],
7030
7031 // Get *real* offsetParent
7032 offsetParent = this.offsetParent(),
7033
7034 // Get correct offsets
7035 offset = this.offset(),
7036 parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
7037
7038 // Subtract element margins
7039 // note: when an element has margin: auto the offsetLeft and marginLeft
7040 // are the same in Safari causing offset.left to incorrectly be 0
7041 offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
7042 offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
7043
7044 // Add offsetParent borders
7045 parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
7046 parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
7047
7048 // Subtract the two offsets
7049 return {
7050 top: offset.top - parentOffset.top,
7051 left: offset.left - parentOffset.left
7052 };
7053 },
7054
7055 offsetParent: function() {
7056 return this.map(function() {
7057 var offsetParent = this.offsetParent || document.body;
7058 while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
7059 offsetParent = offsetParent.offsetParent;
7060 }
7061 return offsetParent;
7062 });
7063 }
7064});
7065
7066
7067// Create scrollLeft and scrollTop methods
7068jQuery.each( ["Left", "Top"], function( i, name ) {
7069 var method = "scroll" + name;
7070
7071 jQuery.fn[ method ] = function(val) {
7072 var elem = this[0], win;
7073
7074 if ( !elem ) {
7075 return null;
7076 }
7077
7078 if ( val !== undefined ) {
7079 // Set the scroll offset
7080 return this.each(function() {
7081 win = getWindow( this );
7082
7083 if ( win ) {
7084 win.scrollTo(
7085 !i ? val : jQuery(win).scrollLeft(),
7086 i ? val : jQuery(win).scrollTop()
7087 );
7088
7089 } else {
7090 this[ method ] = val;
7091 }
7092 });
7093 } else {
7094 win = getWindow( elem );
7095
7096 // Return the scroll offset
7097 return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
7098 jQuery.support.boxModel && win.document.documentElement[ method ] ||
7099 win.document.body[ method ] :
7100 elem[ method ];
7101 }
7102 };
7103});
7104
7105function getWindow( elem ) {
7106 return jQuery.isWindow( elem ) ?
7107 elem :
7108 elem.nodeType === 9 ?
7109 elem.defaultView || elem.parentWindow :
7110 false;
7111}
7112
7113
7114
7115
7116// Create innerHeight, innerWidth, outerHeight and outerWidth methods
7117jQuery.each([ "Height", "Width" ], function( i, name ) {
7118
7119 var type = name.toLowerCase();
7120
7121 // innerHeight and innerWidth
7122 jQuery.fn["inner" + name] = function() {
7123 return this[0] ?
7124 parseFloat( jQuery.css( this[0], type, "padding" ) ) :
7125 null;
7126 };
7127
7128 // outerHeight and outerWidth
7129 jQuery.fn["outer" + name] = function( margin ) {
7130 return this[0] ?
7131 parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) :
7132 null;
7133 };
7134
7135 jQuery.fn[ type ] = function( size ) {
7136 // Get window width or height
7137 var elem = this[0];
7138 if ( !elem ) {
7139 return size == null ? null : this;
7140 }
7141
7142 if ( jQuery.isFunction( size ) ) {
7143 return this.each(function( i ) {
7144 var self = jQuery( this );
7145 self[ type ]( size.call( this, i, self[ type ]() ) );
7146 });
7147 }
7148
7149 if ( jQuery.isWindow( elem ) ) {
7150 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
7151 return elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
7152 elem.document.body[ "client" + name ];
7153
7154 // Get document width or height
7155 } else if ( elem.nodeType === 9 ) {
7156 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
7157 return Math.max(
7158 elem.documentElement["client" + name],
7159 elem.body["scroll" + name], elem.documentElement["scroll" + name],
7160 elem.body["offset" + name], elem.documentElement["offset" + name]
7161 );
7162
7163 // Get or set width or height on the element
7164 } else if ( size === undefined ) {
7165 var orig = jQuery.css( elem, type ),
7166 ret = parseFloat( orig );
7167
7168 return jQuery.isNaN( ret ) ? orig : ret;
7169
7170 // Set the width or height on the element (default to pixels if value is unitless)
7171 } else {
7172 return this.css( type, typeof size === "string" ? size : size + "px" );
7173 }
7174 };
7175
7176});
7177
7178
7179})(window);
Note: See TracBrowser for help on using the repository browser.