WordPress source code - jquery (jquery-1.2.3.js)

1(function(){
2 /*
3 * jQuery 1.2.3 - New Wave Javascript
4 *
5 * Copyright (c) 2008 John Resig (jquery.com)
6 * Dual licensed under the MIT (MIT-LICENSE.txt)
7 * and GPL (GPL-LICENSE.txt) licenses.
8 *
9 * $Date: 2008-02-06 00:21:25 -0500 (Wed, 06 Feb 2008) $
10 * $Rev: 4663 $
11 */
12
13 // Map over jQuery in case of overwrite
14 if ( window.jQuery )
15 var _jQuery = window.jQuery;
16
17 var jQuery = window.jQuery = function( selector, context ) {
18 // The jQuery object is actually just the init constructor 'enhanced'
19 return new jQuery.prototype.init( selector, context );
20 };
21
22 // Map over the $ in case of overwrite
23 if ( window.$ )
24 var _$ = window.$;
25
26 // Map the jQuery namespace to the '$' one
27 window.$ = jQuery;
28
29 // A simple way to check for HTML strings or ID strings
30 // (both of which we optimize for)
31 var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;
32
33 // Is it a simple selector
34 var isSimple = /^.[^:#\[\.]*$/;
35
36 jQuery.fn = jQuery.prototype = {
37 init: function( selector, context ) {
38 // Make sure that a selection was provided
39 selector = selector || document;
40
41 // Handle $(DOMElement)
42 if ( selector.nodeType ) {
43 this[0] = selector;
44 this.length = 1;
45 return this;
46
47 // Handle HTML strings
48 } else if ( typeof selector == "string" ) {
49 // Are we dealing with HTML string or an ID?
50 var match = quickExpr.exec( selector );
51
52 // Verify a match, and that no context was specified for #id
53 if ( match && (match[1] || !context) ) {
54
55 // HANDLE: $(html) -> $(array)
56 if ( match[1] )
57 selector = jQuery.clean( [ match[1] ], context );
58
59 // HANDLE: $("#id")
60 else {
61 var elem = document.getElementById( match[3] );
62
63 // Make sure an element was located
64 if ( elem )
65 // Handle the case where IE and Opera return items
66 // by name instead of ID
67 if ( elem.id != match[3] )
68 return jQuery().find( selector );
69
70 // Otherwise, we inject the element directly into the jQuery object
71 else {
72 this[0] = elem;
73 this.length = 1;
74 return this;
75 }
76
77 else
78 selector = [];
79 }
80
81 // HANDLE: $(expr, [context])
82 // (which is just equivalent to: $(content).find(expr)
83 } else
84 return new jQuery( context ).find( selector );
85
86 // HANDLE: $(function)
87 // Shortcut for document ready
88 } else if ( jQuery.isFunction( selector ) )
89 return new jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector );
90
91 return this.setArray(
92 // HANDLE: $(array)
93 selector.constructor == Array && selector ||
94
95 // HANDLE: $(arraylike)
96 // Watch for when an array-like object, contains DOM nodes, is passed in as the selector
97 (selector.jquery || selector.length && selector != window && !selector.nodeType && selector[0] != undefined && selector[0].nodeType) && jQuery.makeArray( selector ) ||
98
99 // HANDLE: $(*)
100 [ selector ] );
101 },
102
103 // The current version of jQuery being used
104 jquery: "1.2.3",
105
106 // The number of elements contained in the matched element set
107 size: function() {
108 return this.length;
109 },
110
111 // The number of elements contained in the matched element set
112 length: 0,
113
114 // Get the Nth element in the matched element set OR
115 // Get the whole matched element set as a clean array
116 get: function( num ) {
117 return num == undefined ?
118
119 // Return a 'clean' array
120 jQuery.makeArray( this ) :
121
122 // Return just the object
123 this[ num ];
124 },
125
126 // Take an array of elements and push it onto the stack
127 // (returning the new matched element set)
128 pushStack: function( elems ) {
129 // Build a new jQuery matched element set
130 var ret = jQuery( elems );
131
132 // Add the old object onto the stack (as a reference)
133 ret.prevObject = this;
134
135 // Return the newly-formed element set
136 return ret;
137 },
138
139 // Force the current matched set of elements to become
140 // the specified array of elements (destroying the stack in the process)
141 // You should use pushStack() in order to do this, but maintain the stack
142 setArray: function( elems ) {
143 // Resetting the length to 0, then using the native Array push
144 // is a super-fast way to populate an object with array-like properties
145 this.length = 0;
146 Array.prototype.push.apply( this, elems );
147
148 return this;
149 },
150
151 // Execute a callback for every element in the matched set.
152 // (You can seed the arguments with an array of args, but this is
153 // only used internally.)
154 each: function( callback, args ) {
155 return jQuery.each( this, callback, args );
156 },
157
158 // Determine the position of an element within
159 // the matched set of elements
160 index: function( elem ) {
161 var ret = -1;
162
163 // Locate the position of the desired element
164 this.each(function(i){
165 if ( this == elem )
166 ret = i;
167 });
168
169 return ret;
170 },
171
172 attr: function( name, value, type ) {
173 var options = name;
174
175 // Look for the case where we're accessing a style value
176 if ( name.constructor == String )
177 if ( value == undefined )
178 return this.length && jQuery[ type || "attr" ]( this[0], name ) || undefined;
179
180 else {
181 options = {};
182 options[ name ] = value;
183 }
184
185 // Check to see if we're setting style values
186 return this.each(function(i){
187 // Set all the styles
188 for ( name in options )
189 jQuery.attr(
190 type ?
191 this.style :
192 this,
193 name, jQuery.prop( this, options[ name ], type, i, name )
194 );
195 });
196 },
197
198 css: function( key, value ) {
199 // ignore negative width and height values
200 if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
201 value = undefined;
202 return this.attr( key, value, "curCSS" );
203 },
204
205 text: function( text ) {
206 if ( typeof text != "object" && text != null )
207 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
208
209 var ret = "";
210
211 jQuery.each( text || this, function(){
212 jQuery.each( this.childNodes, function(){
213 if ( this.nodeType != 8 )
214 ret += this.nodeType != 1 ?
215 this.nodeValue :
216 jQuery.fn.text( [ this ] );
217 });
218 });
219
220 return ret;
221 },
222
223 wrapAll: function( html ) {
224 if ( this[0] )
225 // The elements to wrap the target around
226 jQuery( html, this[0].ownerDocument )
227 .clone()
228 .insertBefore( this[0] )
229 .map(function(){
230 var elem = this;
231
232 while ( elem.firstChild )
233 elem = elem.firstChild;
234
235 return elem;
236 })
237 .append(this);
238
239 return this;
240 },
241
242 wrapInner: function( html ) {
243 return this.each(function(){
244 jQuery( this ).contents().wrapAll( html );
245 });
246 },
247
248 wrap: function( html ) {
249 return this.each(function(){
250 jQuery( this ).wrapAll( html );
251 });
252 },
253
254 append: function() {
255 return this.domManip(arguments, true, false, function(elem){
256 if (this.nodeType == 1)
257 this.appendChild( elem );
258 });
259 },
260
261 prepend: function() {
262 return this.domManip(arguments, true, true, function(elem){
263 if (this.nodeType == 1)
264 this.insertBefore( elem, this.firstChild );
265 });
266 },
267
268 before: function() {
269 return this.domManip(arguments, false, false, function(elem){
270 this.parentNode.insertBefore( elem, this );
271 });
272 },
273
274 after: function() {
275 return this.domManip(arguments, false, true, function(elem){
276 this.parentNode.insertBefore( elem, this.nextSibling );
277 });
278 },
279
280 end: function() {
281 return this.prevObject || jQuery( [] );
282 },
283
284 find: function( selector ) {
285 var elems = jQuery.map(this, function(elem){
286 return jQuery.find( selector, elem );
287 });
288
289 return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ?
290 jQuery.unique( elems ) :
291 elems );
292 },
293
294 clone: function( events ) {
295 // Do the clone
296 var ret = this.map(function(){
297 if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) {
298 // IE copies events bound via attachEvent when
299 // using cloneNode. Calling detachEvent on the
300 // clone will also remove the events from the orignal
301 // In order to get around this, we use innerHTML.
302 // Unfortunately, this means some modifications to
303 // attributes in IE that are actually only stored
304 // as properties will not be copied (such as the
305 // the name attribute on an input).
306 var clone = this.cloneNode(true),
307 container = document.createElement("div");
308 container.appendChild(clone);
309 return jQuery.clean([container.innerHTML])[0];
310 } else
311 return this.cloneNode(true);
312 });
313
314 // Need to set the expando to null on the cloned set if it exists
315 // removeData doesn't work here, IE removes it from the original as well
316 // this is primarily for IE but the data expando shouldn't be copied over in any browser
317 var clone = ret.find("*").andSelf().each(function(){
318 if ( this[ expando ] != undefined )
319 this[ expando ] = null;
320 });
321
322 // Copy the events from the original to the clone
323 if ( events === true )
324 this.find("*").andSelf().each(function(i){
325 if (this.nodeType == 3)
326 return;
327 var events = jQuery.data( this, "events" );
328
329 for ( var type in events )
330 for ( var handler in events[ type ] )
331 jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );
332 });
333
334 // Return the cloned set
335 return ret;
336 },
337
338 filter: function( selector ) {
339 return this.pushStack(
340 jQuery.isFunction( selector ) &&
341 jQuery.grep(this, function(elem, i){
342 return selector.call( elem, i );
343 }) ||
344
345 jQuery.multiFilter( selector, this ) );
346 },
347
348 not: function( selector ) {
349 if ( selector.constructor == String )
350 // test special case where just one selector is passed in
351 if ( isSimple.test( selector ) )
352 return this.pushStack( jQuery.multiFilter( selector, this, true ) );
353 else
354 selector = jQuery.multiFilter( selector, this );
355
356 var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
357 return this.filter(function() {
358 return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
359 });
360 },
361
362 add: function( selector ) {
363 return !selector ? this : this.pushStack( jQuery.merge(
364 this.get(),
365 selector.constructor == String ?
366 jQuery( selector ).get() :
367 selector.length != undefined && (!selector.nodeName || jQuery.nodeName(selector, "form")) ?
368 selector : [selector] ) );
369 },
370
371 is: function( selector ) {
372 return selector ?
373 jQuery.multiFilter( selector, this ).length > 0 :
374 false;
375 },
376
377 hasClass: function( selector ) {
378 return this.is( "." + selector );
379 },
380
381 val: function( value ) {
382 if ( value == undefined ) {
383
384 if ( this.length ) {
385 var elem = this[0];
386
387 // We need to handle select boxes special
388 if ( jQuery.nodeName( elem, "select" ) ) {
389 var index = elem.selectedIndex,
390 values = [],
391 options = elem.options,
392 one = elem.type == "select-one";
393
394 // Nothing was selected
395 if ( index < 0 )
396 return null;
397
398 // Loop through all the selected options
399 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
400 var option = options[ i ];
401
402 if ( option.selected ) {
403 // Get the specifc value for the option
404 value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value;
405
406 // We don't need an array for one selects
407 if ( one )
408 return value;
409
410 // Multi-Selects return an array
411 values.push( value );
412 }
413 }
414
415 return values;
416
417 // Everything else, we just grab the value
418 } else
419 return (this[0].value || "").replace(/\r/g, "");
420
421 }
422
423 return undefined;
424 }
425
426 return this.each(function(){
427 if ( this.nodeType != 1 )
428 return;
429
430 if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )
431 this.checked = (jQuery.inArray(this.value, value) >= 0 ||
432 jQuery.inArray(this.name, value) >= 0);
433
434 else if ( jQuery.nodeName( this, "select" ) ) {
435 var values = value.constructor == Array ?
436 value :
437 [ value ];
438
439 jQuery( "option", this ).each(function(){
440 this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
441 jQuery.inArray( this.text, values ) >= 0);
442 });
443
444 if ( !values.length )
445 this.selectedIndex = -1;
446
447 } else
448 this.value = value;
449 });
450 },
451
452 html: function( value ) {
453 return value == undefined ?
454 (this.length ?
455 this[0].innerHTML :
456 null) :
457 this.empty().append( value );
458 },
459
460 replaceWith: function( value ) {
461 return this.after( value ).remove();
462 },
463
464 eq: function( i ) {
465 return this.slice( i, i + 1 );
466 },
467
468 slice: function() {
469 return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
470 },
471
472 map: function( callback ) {
473 return this.pushStack( jQuery.map(this, function(elem, i){
474 return callback.call( elem, i, elem );
475 }));
476 },
477
478 andSelf: function() {
479 return this.add( this.prevObject );
480 },
481
482 data: function( key, value ){
483 var parts = key.split(".");
484 parts[1] = parts[1] ? "." + parts[1] : "";
485
486 if ( value == null ) {
487 var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
488
489 if ( data == undefined && this.length )
490 data = jQuery.data( this[0], key );
491
492 return data == null && parts[1] ?
493 this.data( parts[0] ) :
494 data;
495 } else
496 return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
497 jQuery.data( this, key, value );
498 });
499 },
500
501 removeData: function( key ){
502 return this.each(function(){
503 jQuery.removeData( this, key );
504 });
505 },
506
507 domManip: function( args, table, reverse, callback ) {
508 var clone = this.length > 1, elems;
509
510 return this.each(function(){
511 if ( !elems ) {
512 elems = jQuery.clean( args, this.ownerDocument );
513
514 if ( reverse )
515 elems.reverse();
516 }
517
518 var obj = this;
519
520 if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) )
521 obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") );
522
523 var scripts = jQuery( [] );
524
525 jQuery.each(elems, function(){
526 var elem = clone ?
527 jQuery( this ).clone( true )[0] :
528 this;
529
530 // execute all scripts after the elements have been injected
531 if ( jQuery.nodeName( elem, "script" ) ) {
532 scripts = scripts.add( elem );
533 } else {
534 // Remove any inner scripts for later evaluation
535 if ( elem.nodeType == 1 )
536 scripts = scripts.add( jQuery( "script", elem ).remove() );
537
538 // Inject the elements into the document
539 callback.call( obj, elem );
540 }
541 });
542
543 scripts.each( evalScript );
544 });
545 }
546 };
547
548 // Give the init function the jQuery prototype for later instantiation
549 jQuery.prototype.init.prototype = jQuery.prototype;
550
551 function evalScript( i, elem ) {
552 if ( elem.src )
553 jQuery.ajax({
554 url: elem.src,
555 async: false,
556 dataType: "script"
557 });
558
559 else
560 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
561
562 if ( elem.parentNode )
563 elem.parentNode.removeChild( elem );
564 }
565
566 jQuery.extend = jQuery.fn.extend = function() {
567 // copy reference to target object
568 var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
569
570 // Handle a deep copy situation
571 if ( target.constructor == Boolean ) {
572 deep = target;
573 target = arguments[1] || {};
574 // skip the boolean and the target
575 i = 2;
576 }
577
578 // Handle case when target is a string or something (possible in deep copy)
579 if ( typeof target != "object" && typeof target != "function" )
580 target = {};
581
582 // extend jQuery itself if only one argument is passed
583 if ( length == 1 ) {
584 target = this;
585 i = 0;
586 }
587
588 for ( ; i < length; i++ )
589 // Only deal with non-null/undefined values
590 if ( (options = arguments[ i ]) != null )
591 // Extend the base object
592 for ( var name in options ) {
593 // Prevent never-ending loop
594 if ( target === options[ name ] )
595 continue;
596
597 // Recurse if we're merging object values
598 if ( deep && options[ name ] && typeof options[ name ] == "object" && target[ name ] && !options[ name ].nodeType )
599 target[ name ] = jQuery.extend( target[ name ], options[ name ] );
600
601 // Don't bring in undefined values
602 else if ( options[ name ] != undefined )
603 target[ name ] = options[ name ];
604
605 }
606
607 // Return the modified object
608 return target;
609 };
610
611 var expando = "jQuery" + (new Date()).getTime(), uuid = 0, windowData = {};
612
613 // exclude the following css properties to add px
614 var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i;
615
616 jQuery.extend({
617 noConflict: function( deep ) {
618 window.$ = _$;
619
620 if ( deep )
621 window.jQuery = _jQuery;
622
623 return jQuery;
624 },
625
626 // See test/unit/core.js for details concerning this function.
627 isFunction: function( fn ) {
628 return !!fn && typeof fn != "string" && !fn.nodeName &&
629 fn.constructor != Array && /function/i.test( fn + "" );
630 },
631
632 // check if an element is in a (or is an) XML document
633 isXMLDoc: function( elem ) {
634 return elem.documentElement && !elem.body ||
635 elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
636 },
637
638 // Evalulates a script in a global context
639 globalEval: function( data ) {
640 data = jQuery.trim( data );
641
642 if ( data ) {
643 // Inspired by code by Andrea Giammarchi
644 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
645 var head = document.getElementsByTagName("head")[0] || document.documentElement,
646 script = document.createElement("script");
647
648 script.type = "text/javascript";
649 if ( jQuery.browser.msie )
650 script.text = data;
651 else
652 script.appendChild( document.createTextNode( data ) );
653
654 head.appendChild( script );
655 head.removeChild( script );
656 }
657 },
658
659 nodeName: function( elem, name ) {
660 return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
661 },
662
663 cache: {},
664
665 data: function( elem, name, data ) {
666 elem = elem == window ?
667 windowData :
668 elem;
669
670 var id = elem[ expando ];
671
672 // Compute a unique ID for the element
673 if ( !id )
674 id = elem[ expando ] = ++uuid;
675
676 // Only generate the data cache if we're
677 // trying to access or manipulate it
678 if ( name && !jQuery.cache[ id ] )
679 jQuery.cache[ id ] = {};
680
681 // Prevent overriding the named cache with undefined values
682 if ( data != undefined )
683 jQuery.cache[ id ][ name ] = data;
684
685 // Return the named cache data, or the ID for the element
686 return name ?
687 jQuery.cache[ id ][ name ] :
688 id;
689 },
690
691 removeData: function( elem, name ) {
692 elem = elem == window ?
693 windowData :
694 elem;
695
696 var id = elem[ expando ];
697
698 // If we want to remove a specific section of the element's data
699 if ( name ) {
700 if ( jQuery.cache[ id ] ) {
701 // Remove the section of cache data
702 delete jQuery.cache[ id ][ name ];
703
704 // If we've removed all the data, remove the element's cache
705 name = "";
706
707 for ( name in jQuery.cache[ id ] )
708 break;
709
710 if ( !name )
711 jQuery.removeData( elem );
712 }
713
714 // Otherwise, we want to remove all of the element's data
715 } else {
716 // Clean up the element expando
717 try {
718 delete elem[ expando ];
719 } catch(e){
720 // IE has trouble directly removing the expando
721 // but it's ok with using removeAttribute
722 if ( elem.removeAttribute )
723 elem.removeAttribute( expando );
724 }
725
726 // Completely remove the data cache
727 delete jQuery.cache[ id ];
728 }
729 },
730
731 // args is for internal usage only
732 each: function( object, callback, args ) {
733 if ( args ) {
734 if ( object.length == undefined ) {
735 for ( var name in object )
736 if ( callback.apply( object[ name ], args ) === false )
737 break;
738 } else
739 for ( var i = 0, length = object.length; i < length; i++ )
740 if ( callback.apply( object[ i ], args ) === false )
741 break;
742
743 // A special, fast, case for the most common use of each
744 } else {
745 if ( object.length == undefined ) {
746 for ( var name in object )
747 if ( callback.call( object[ name ], name, object[ name ] ) === false )
748 break;
749 } else
750 for ( var i = 0, length = object.length, value = object[0];
751 i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
752 }
753
754 return object;
755 },
756
757 prop: function( elem, value, type, i, name ) {
758 // Handle executable functions
759 if ( jQuery.isFunction( value ) )
760 value = value.call( elem, i );
761
762 // Handle passing in a number to a CSS property
763 return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ?
764 value + "px" :
765 value;
766 },
767
768 className: {
769 // internal only, use addClass("class")
770 add: function( elem, classNames ) {
771 jQuery.each((classNames || "").split(/\s+/), function(i, className){
772 if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
773 elem.className += (elem.className ? " " : "") + className;
774 });
775 },
776
777 // internal only, use removeClass("class")
778 remove: function( elem, classNames ) {
779 if (elem.nodeType == 1)
780 elem.className = classNames != undefined ?
781 jQuery.grep(elem.className.split(/\s+/), function(className){
782 return !jQuery.className.has( classNames, className );
783 }).join(" ") :
784 "";
785 },
786
787 // internal only, use is(".class")
788 has: function( elem, className ) {
789 return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
790 }
791 },
792
793 // A method for quickly swapping in/out CSS properties to get correct calculations
794 swap: function( elem, options, callback ) {
795 var old = {};
796 // Remember the old values, and insert the new ones
797 for ( var name in options ) {
798 old[ name ] = elem.style[ name ];
799 elem.style[ name ] = options[ name ];
800 }
801
802 callback.call( elem );
803
804 // Revert the old values
805 for ( var name in options )
806 elem.style[ name ] = old[ name ];
807 },
808
809 css: function( elem, name, force ) {
810 if ( name == "width" || name == "height" ) {
811 var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
812
813 function getWH() {
814 val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
815 var padding = 0, border = 0;
816 jQuery.each( which, function() {
817 padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
818 border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
819 });
820 val -= Math.round(padding + border);
821 }
822
823 if ( jQuery(elem).is(":visible") )
824 getWH();
825 else
826 jQuery.swap( elem, props, getWH );
827
828 return Math.max(0, val);
829 }
830
831 return jQuery.curCSS( elem, name, force );
832 },
833
834 curCSS: function( elem, name, force ) {
835 var ret;
836
837 // A helper method for determining if an element's values are broken
838 function color( elem ) {
839 if ( !jQuery.browser.safari )
840 return false;
841
842 var ret = document.defaultView.getComputedStyle( elem, null );
843 return !ret || ret.getPropertyValue("color") == "";
844 }
845
846 // We need to handle opacity special in IE
847 if ( name == "opacity" && jQuery.browser.msie ) {
848 ret = jQuery.attr( elem.style, "opacity" );
849
850 return ret == "" ?
851 "1" :
852 ret;
853 }
854 // Opera sometimes will give the wrong display answer, this fixes it, see #2037
855 if ( jQuery.browser.opera && name == "display" ) {
856 var save = elem.style.outline;
857 elem.style.outline = "0 solid black";
858 elem.style.outline = save;
859 }
860
861 // Make sure we're using the right name for getting the float value
862 if ( name.match( /float/i ) )
863 name = styleFloat;
864
865 if ( !force && elem.style && elem.style[ name ] )
866 ret = elem.style[ name ];
867
868 else if ( document.defaultView && document.defaultView.getComputedStyle ) {
869
870 // Only "float" is needed here
871 if ( name.match( /float/i ) )
872 name = "float";
873
874 name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
875
876 var getComputedStyle = document.defaultView.getComputedStyle( elem, null );
877
878 if ( getComputedStyle && !color( elem ) )
879 ret = getComputedStyle.getPropertyValue( name );
880
881 // If the element isn't reporting its values properly in Safari
882 // then some display: none elements are involved
883 else {
884 var swap = [], stack = [];
885
886 // Locate all of the parent display: none elements
887 for ( var a = elem; a && color(a); a = a.parentNode )
888 stack.unshift(a);
889
890 // Go through and make them visible, but in reverse
891 // (It would be better if we knew the exact display type that they had)
892 for ( var i = 0; i < stack.length; i++ )
893 if ( color( stack[ i ] ) ) {
894 swap[ i ] = stack[ i ].style.display;
895 stack[ i ].style.display = "block";
896 }
897
898 // Since we flip the display style, we have to handle that
899 // one special, otherwise get the value
900 ret = name == "display" && swap[ stack.length - 1 ] != null ?
901 "none" :
902 ( getComputedStyle && getComputedStyle.getPropertyValue( name ) ) || "";
903
904 // Finally, revert the display styles back
905 for ( var i = 0; i < swap.length; i++ )
906 if ( swap[ i ] != null )
907 stack[ i ].style.display = swap[ i ];
908 }
909
910 // We should always get a number back from opacity
911 if ( name == "opacity" && ret == "" )
912 ret = "1";
913
914 } else if ( elem.currentStyle ) {
915 var camelCase = name.replace(/\-(\w)/g, function(all, letter){
916 return letter.toUpperCase();
917 });
918
919 ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
920
921 // From the awesome hack by Dean Edwards
922 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
923
924 // If we're not dealing with a regular pixel number
925 // but a number that has a weird ending, we need to convert it to pixels
926 if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
927 // Remember the original values
928 var style = elem.style.left, runtimeStyle = elem.runtimeStyle.left;
929
930 // Put in the new values to get a computed value out
931 elem.runtimeStyle.left = elem.currentStyle.left;
932 elem.style.left = ret || 0;
933 ret = elem.style.pixelLeft + "px";
934
935 // Revert the changed values
936 elem.style.left = style;
937 elem.runtimeStyle.left = runtimeStyle;
938 }
939 }
940
941 return ret;
942 },
943
944 clean: function( elems, context ) {
945 var ret = [];
946 context = context || document;
947 // !context.createElement fails in IE with an error but returns typeof 'object'
948 if (typeof context.createElement == 'undefined')
949 context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
950
951 jQuery.each(elems, function(i, elem){
952 if ( !elem )
953 return;
954
955 if ( elem.constructor == Number )
956 elem = elem.toString();
957
958 // Convert html string into DOM nodes
959 if ( typeof elem == "string" ) {
960 // Fix "XHTML"-style tags in all browsers
961 elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
962 return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
963 all :
964 front + "></" + tag + ">";
965 });
966
967 // Trim whitespace, otherwise indexOf won't work as expected
968 var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div");
969
970 var wrap =
971 // option or optgroup
972 !tags.indexOf("<opt") &&
973 [ 1, "<select multiple='multiple'>", "</select>" ] ||
974
975 !tags.indexOf("<leg") &&
976 [ 1, "<fieldset>", "</fieldset>" ] ||
977
978 tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
979 [ 1, "<table>", "</table>" ] ||
980
981 !tags.indexOf("<tr") &&
982 [ 2, "<table><tbody>", "</tbody></table>" ] ||
983
984 // <thead> matched above
985 (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
986 [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
987
988 !tags.indexOf("<col") &&
989 [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
990
991 // IE can't serialize <link> and <script> tags normally
992 jQuery.browser.msie &&
993 [ 1, "div<div>", "</div>" ] ||
994
995 [ 0, "", "" ];
996
997 // Go to html and back, then peel off extra wrappers
998 div.innerHTML = wrap[1] + elem + wrap[2];
999
1000 // Move to the right depth
1001 while ( wrap[0]-- )
1002 div = div.lastChild;
1003
1004 // Remove IE's autoinserted <tbody> from table fragments
1005 if ( jQuery.browser.msie ) {
1006
1007 // String was a <table>, *may* have spurious <tbody>
1008 var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ?
1009 div.firstChild && div.firstChild.childNodes :
1010
1011 // String was a bare <thead> or <tfoot>
1012 wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ?
1013 div.childNodes :
1014 [];
1015
1016 for ( var j = tbody.length - 1; j >= 0 ; --j )
1017 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
1018 tbody[ j ].parentNode.removeChild( tbody[ j ] );
1019
1020 // IE completely kills leading whitespace when innerHTML is used
1021 if ( /^\s/.test( elem ) )
1022 div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
1023
1024 }
1025
1026 elem = jQuery.makeArray( div.childNodes );
1027 }
1028
1029 if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) )
1030 return;
1031
1032 if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options )
1033 ret.push( elem );
1034
1035 else
1036 ret = jQuery.merge( ret, elem );
1037
1038 });
1039
1040 return ret;
1041 },
1042
1043 attr: function( elem, name, value ) {
1044 // don't set attributes on text and comment nodes
1045 if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
1046 return undefined;
1047
1048 var fix = jQuery.isXMLDoc( elem ) ?
1049 {} :
1050 jQuery.props;
1051
1052 // Safari mis-reports the default selected property of a hidden option
1053 // Accessing the parent's selectedIndex property fixes it
1054 if ( name == "selected" && jQuery.browser.safari )
1055 elem.parentNode.selectedIndex;
1056
1057 // Certain attributes only work when accessed via the old DOM 0 way
1058 if ( fix[ name ] ) {
1059 if ( value != undefined )
1060 elem[ fix[ name ] ] = value;
1061
1062 return elem[ fix[ name ] ];
1063
1064 } else if ( jQuery.browser.msie && name == "style" )
1065 return jQuery.attr( elem.style, "cssText", value );
1066
1067 else if ( value == undefined && jQuery.browser.msie && jQuery.nodeName( elem, "form" ) && (name == "action" || name == "method") )
1068 return elem.getAttributeNode( name ).nodeValue;
1069
1070 // IE elem.getAttribute passes even for style
1071 else if ( elem.tagName ) {
1072
1073 if ( value != undefined ) {
1074 // We can't allow the type property to be changed (since it causes problems in IE)
1075 if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
1076 throw "type property can't be changed";
1077
1078 // convert the value to a string (all browsers do this but IE) see #1070
1079 elem.setAttribute( name, "" + value );
1080 }
1081
1082 if ( jQuery.browser.msie && /href|src/.test( name ) && !jQuery.isXMLDoc( elem ) )
1083 return elem.getAttribute( name, 2 );
1084
1085 return elem.getAttribute( name );
1086
1087 // elem is actually elem.style ... set the style
1088 } else {
1089 // IE actually uses filters for opacity
1090 if ( name == "opacity" && jQuery.browser.msie ) {
1091 if ( value != undefined ) {
1092 // IE has trouble with opacity if it does not have layout
1093 // Force it by setting the zoom level
1094 elem.zoom = 1;
1095
1096 // Set the alpha filter to set the opacity
1097 elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
1098 (parseFloat( value ).toString() == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
1099 }
1100
1101 return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
1102 (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100).toString() :
1103 "";
1104 }
1105
1106 name = name.replace(/-([a-z])/ig, function(all, letter){
1107 return letter.toUpperCase();
1108 });
1109
1110 if ( value != undefined )
1111 elem[ name ] = value;
1112
1113 return elem[ name ];
1114 }
1115 },
1116
1117 trim: function( text ) {
1118 return (text || "").replace( /^\s+|\s+$/g, "" );
1119 },
1120
1121 makeArray: function( array ) {
1122 var ret = [];
1123
1124 // Need to use typeof to fight Safari childNodes crashes
1125 if ( typeof array != "array" )
1126 for ( var i = 0, length = array.length; i < length; i++ )
1127 ret.push( array[ i ] );
1128 else
1129 ret = array.slice( 0 );
1130
1131 return ret;
1132 },
1133
1134 inArray: function( elem, array ) {
1135 for ( var i = 0, length = array.length; i < length; i++ )
1136 if ( array[ i ] == elem )
1137 return i;
1138
1139 return -1;
1140 },
1141
1142 merge: function( first, second ) {
1143 // We have to loop this way because IE & Opera overwrite the length
1144 // expando of getElementsByTagName
1145
1146 // Also, we need to make sure that the correct elements are being returned
1147 // (IE returns comment nodes in a '*' query)
1148 if ( jQuery.browser.msie ) {
1149 for ( var i = 0; second[ i ]; i++ )
1150 if ( second[ i ].nodeType != 8 )
1151 first.push( second[ i ] );
1152
1153 } else
1154 for ( var i = 0; second[ i ]; i++ )
1155 first.push( second[ i ] );
1156
1157 return first;
1158 },
1159
1160 unique: function( array ) {
1161 var ret = [], done = {};
1162
1163 try {
1164
1165 for ( var i = 0, length = array.length; i < length; i++ ) {
1166 var id = jQuery.data( array[ i ] );
1167
1168 if ( !done[ id ] ) {
1169 done[ id ] = true;
1170 ret.push( array[ i ] );
1171 }
1172 }
1173
1174 } catch( e ) {
1175 ret = array;
1176 }
1177
1178 return ret;
1179 },
1180
1181 grep: function( elems, callback, inv ) {
1182 var ret = [];
1183
1184 // Go through the array, only saving the items
1185 // that pass the validator function
1186 for ( var i = 0, length = elems.length; i < length; i++ )
1187 if ( !inv && callback( elems[ i ], i ) || inv && !callback( elems[ i ], i ) )
1188 ret.push( elems[ i ] );
1189
1190 return ret;
1191 },
1192
1193 map: function( elems, callback ) {
1194 var ret = [];
1195
1196 // Go through the array, translating each of the items to their
1197 // new value (or values).
1198 for ( var i = 0, length = elems.length; i < length; i++ ) {
1199 var value = callback( elems[ i ], i );
1200
1201 if ( value !== null && value != undefined ) {
1202 if ( value.constructor != Array )
1203 value = [ value ];
1204
1205 ret = ret.concat( value );
1206 }
1207 }
1208
1209 return ret;
1210 }
1211 });
1212
1213 var userAgent = navigator.userAgent.toLowerCase();
1214
1215 // Figure out what browser is being used
1216 jQuery.browser = {
1217 version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],
1218 safari: /webkit/.test( userAgent ),
1219 opera: /opera/.test( userAgent ),
1220 msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
1221 mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
1222 };
1223
1224 var styleFloat = jQuery.browser.msie ?
1225 "styleFloat" :
1226 "cssFloat";
1227
1228 jQuery.extend({
1229 // Check to see if the W3C box model is being used
1230 boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
1231
1232 props: {
1233 "for": "htmlFor",
1234 "class": "className",
1235 "float": styleFloat,
1236 cssFloat: styleFloat,
1237 styleFloat: styleFloat,
1238 innerHTML: "innerHTML",
1239 className: "className",
1240 value: "value",
1241 disabled: "disabled",
1242 checked: "checked",
1243 readonly: "readOnly",
1244 selected: "selected",
1245 maxlength: "maxLength",
1246 selectedIndex: "selectedIndex",
1247 defaultValue: "defaultValue",
1248 tagName: "tagName",
1249 nodeName: "nodeName"
1250 }
1251 });
1252
1253 jQuery.each({
1254 parent: function(elem){return elem.parentNode;},
1255 parents: function(elem){return jQuery.dir(elem,"parentNode");},
1256 next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
1257 prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
1258 nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
1259 prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
1260 siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
1261 children: function(elem){return jQuery.sibling(elem.firstChild);},
1262 contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
1263 }, function(name, fn){
1264 jQuery.fn[ name ] = function( selector ) {
1265 var ret = jQuery.map( this, fn );
1266
1267 if ( selector && typeof selector == "string" )
1268 ret = jQuery.multiFilter( selector, ret );
1269
1270 return this.pushStack( jQuery.unique( ret ) );
1271 };
1272 });
1273
1274 jQuery.each({
1275 appendTo: "append",
1276 prependTo: "prepend",
1277 insertBefore: "before",
1278 insertAfter: "after",
1279 replaceAll: "replaceWith"
1280 }, function(name, original){
1281 jQuery.fn[ name ] = function() {
1282 var args = arguments;
1283
1284 return this.each(function(){
1285 for ( var i = 0, length = args.length; i < length; i++ )
1286 jQuery( args[ i ] )[ original ]( this );
1287 });
1288 };
1289 });
1290
1291 jQuery.each({
1292 removeAttr: function( name ) {
1293 jQuery.attr( this, name, "" );
1294 if (this.nodeType == 1)
1295 this.removeAttribute( name );
1296 },
1297
1298 addClass: function( classNames ) {
1299 jQuery.className.add( this, classNames );
1300 },
1301
1302 removeClass: function( classNames ) {
1303 jQuery.className.remove( this, classNames );
1304 },
1305
1306 toggleClass: function( classNames ) {
1307 jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames );
1308 },
1309
1310 remove: function( selector ) {
1311 if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) {
1312 // Prevent memory leaks
1313 jQuery( "*", this ).add(this).each(function(){
1314 jQuery.event.remove(this);
1315 jQuery.removeData(this);
1316 });
1317 if (this.parentNode)
1318 this.parentNode.removeChild( this );
1319 }
1320 },
1321
1322 empty: function() {
1323 // Remove element nodes and prevent memory leaks
1324 jQuery( ">*", this ).remove();
1325
1326 // Remove any remaining nodes
1327 while ( this.firstChild )
1328 this.removeChild( this.firstChild );
1329 }
1330 }, function(name, fn){
1331 jQuery.fn[ name ] = function(){
1332 return this.each( fn, arguments );
1333 };
1334 });
1335
1336 jQuery.each([ "Height", "Width" ], function(i, name){
1337 var type = name.toLowerCase();
1338
1339 jQuery.fn[ type ] = function( size ) {
1340 // Get window width or height
1341 return this[0] == window ?
1342 // Opera reports document.body.client[Width/Height] properly in both quirks and standards
1343 jQuery.browser.opera && document.body[ "client" + name ] ||
1344
1345 // Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths)
1346 jQuery.browser.safari && window[ "inner" + name ] ||
1347
1348 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
1349 document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] :
1350
1351 // Get document width or height
1352 this[0] == document ?
1353 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
1354 Math.max(
1355 Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]),
1356 Math.max(document.body["offset" + name], document.documentElement["offset" + name])
1357 ) :
1358
1359 // Get or set width or height on the element
1360 size == undefined ?
1361 // Get width or height on the element
1362 (this.length ? jQuery.css( this[0], type ) : null) :
1363
1364 // Set the width or height on the element (default to pixels if value is unitless)
1365 this.css( type, size.constructor == String ? size : size + "px" );
1366 };
1367 });
1368
1369 var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ?
1370 "(?:[\\w*_-]|\\\\.)" :
1371 "(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",
1372 quickChild = new RegExp("^>\\s*(" + chars + "+)"),
1373 quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"),
1374 quickClass = new RegExp("^([#.]?)(" + chars + "*)");
1375
1376 jQuery.extend({
1377 expr: {
1378 "": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},
1379 "#": function(a,i,m){return a.getAttribute("id")==m[2];},
1380 ":": {
1381 // Position Checks
1382 lt: function(a,i,m){return i<m[3]-0;},
1383 gt: function(a,i,m){return i>m[3]-0;},
1384 nth: function(a,i,m){return m[3]-0==i;},
1385 eq: function(a,i,m){return m[3]-0==i;},
1386 first: function(a,i){return i==0;},
1387 last: function(a,i,m,r){return i==r.length-1;},
1388 even: function(a,i){return i%2==0;},
1389 odd: function(a,i){return i%2;},
1390
1391 // Child Checks
1392 "first-child": function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},
1393 "last-child": function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},
1394 "only-child": function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},
1395
1396 // Parent Checks
1397 parent: function(a){return a.firstChild;},
1398 empty: function(a){return !a.firstChild;},
1399
1400 // Text Check
1401 contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},
1402
1403 // Visibility
1404 visible: function(a){return "hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},
1405 hidden: function(a){return "hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},
1406
1407 // Form attributes
1408 enabled: function(a){return !a.disabled;},
1409 disabled: function(a){return a.disabled;},
1410 checked: function(a){return a.checked;},
1411 selected: function(a){return a.selected||jQuery.attr(a,"selected");},
1412
1413 // Form elements
1414 text: function(a){return "text"==a.type;},
1415 radio: function(a){return "radio"==a.type;},
1416 checkbox: function(a){return "checkbox"==a.type;},
1417 file: function(a){return "file"==a.type;},
1418 password: function(a){return "password"==a.type;},
1419 submit: function(a){return "submit"==a.type;},
1420 image: function(a){return "image"==a.type;},
1421 reset: function(a){return "reset"==a.type;},
1422 button: function(a){return "button"==a.type||jQuery.nodeName(a,"button");},
1423 input: function(a){return /input|select|textarea|button/i.test(a.nodeName);},
1424
1425 // :has()
1426 has: function(a,i,m){return jQuery.find(m[3],a).length;},
1427
1428 // :header
1429 header: function(a){return /h\d/i.test(a.nodeName);},
1430
1431 // :animated
1432 animated: function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}
1433 }
1434 },
1435
1436 // The regular expressions that power the parsing engine
1437 parse: [
1438 // Match: [@value='test'], [@foo]
1439 /^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,
1440
1441 // Match: :contains('foo')
1442 /^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,
1443
1444 // Match: :even, :last-chlid, #id, .class
1445 new RegExp("^([:.#]*)(" + chars + "+)")
1446 ],
1447
1448 multiFilter: function( expr, elems, not ) {
1449 var old, cur = [];
1450
1451 while ( expr && expr != old ) {
1452 old = expr;
1453 var f = jQuery.filter( expr, elems, not );
1454 expr = f.t.replace(/^\s*,\s*/, "" );
1455 cur = not ? elems = f.r : jQuery.merge( cur, f.r );
1456 }
1457
1458 return cur;
1459 },
1460
1461 find: function( t, context ) {
1462 // Quickly handle non-string expressions
1463 if ( typeof t != "string" )
1464 return [ t ];
1465
1466 // check to make sure context is a DOM element or a document
1467 if ( context && context.nodeType != 1 && context.nodeType != 9)
1468 return [ ];
1469
1470 // Set the correct context (if none is provided)
1471 context = context || document;
1472
1473 // Initialize the search
1474 var ret = [context], done = [], last, nodeName;
1475
1476 // Continue while a selector expression exists, and while
1477 // we're no longer looping upon ourselves
1478 while ( t && last != t ) {
1479 var r = [];
1480 last = t;
1481
1482 t = jQuery.trim(t);
1483
1484 var foundToken = false;
1485
1486 // An attempt at speeding up child selectors that
1487 // point to a specific element tag
1488 var re = quickChild;
1489 var m = re.exec(t);
1490
1491 if ( m ) {
1492 nodeName = m[1].toUpperCase();
1493
1494 // Perform our own iteration and filter
1495 for ( var i = 0; ret[i]; i++ )
1496 for ( var c = ret[i].firstChild; c; c = c.nextSibling )
1497 if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) )
1498 r.push( c );
1499
1500 ret = r;
1501 t = t.replace( re, "" );
1502 if ( t.indexOf(" ") == 0 ) continue;
1503 foundToken = true;
1504 } else {
1505 re = /^([>+~])\s*(\w*)/i;
1506
1507 if ( (m = re.exec(t)) != null ) {
1508 r = [];
1509
1510 var merge = {};
1511 nodeName = m[2].toUpperCase();
1512 m = m[1];
1513
1514 for ( var j = 0, rl = ret.length; j < rl; j++ ) {
1515 var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild;
1516 for ( ; n; n = n.nextSibling )
1517 if ( n.nodeType == 1 ) {
1518 var id = jQuery.data(n);
1519
1520 if ( m == "~" && merge[id] ) break;
1521
1522 if (!nodeName || n.nodeName.toUpperCase() == nodeName ) {
1523 if ( m == "~" ) merge[id] = true;
1524 r.push( n );
1525 }
1526
1527 if ( m == "+" ) break;
1528 }
1529 }
1530
1531 ret = r;
1532
1533 // And remove the token
1534 t = jQuery.trim( t.replace( re, "" ) );
1535 foundToken = true;
1536 }
1537 }
1538
1539 // See if there's still an expression, and that we haven't already
1540 // matched a token
1541 if ( t && !foundToken ) {
1542 // Handle multiple expressions
1543 if ( !t.indexOf(",") ) {
1544 // Clean the result set
1545 if ( context == ret[0] ) ret.shift();
1546
1547 // Merge the result sets
1548 done = jQuery.merge( done, ret );
1549
1550 // Reset the context
1551 r = ret = [context];
1552
1553 // Touch up the selector string
1554 t = " " + t.substr(1,t.length);
1555
1556 } else {
1557 // Optimize for the case nodeName#idName
1558 var re2 = quickID;
1559 var m = re2.exec(t);
1560
1561 // Re-organize the results, so that they're consistent
1562 if ( m ) {
1563 m = [ 0, m[2], m[3], m[1] ];
1564
1565 } else {
1566 // Otherwise, do a traditional filter check for
1567 // ID, class, and element selectors
1568 re2 = quickClass;
1569 m = re2.exec(t);
1570 }
1571
1572 m[2] = m[2].replace(/\\/g, "");
1573
1574 var elem = ret[ret.length-1];
1575
1576 // Try to do a global search by ID, where we can
1577 if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) {
1578 // Optimization for HTML document case
1579 var oid = elem.getElementById(m[2]);
1580
1581 // Do a quick check for the existence of the actual ID attribute
1582 // to avoid selecting by the name attribute in IE
1583 // also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form
1584 if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] )
1585 oid = jQuery('[@id="'+m[2]+'"]', elem)[0];
1586
1587 // Do a quick check for node name (where applicable) so
1588 // that div#foo searches will be really fast
1589 ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : [];
1590 } else {
1591 // We need to find all descendant elements
1592 for ( var i = 0; ret[i]; i++ ) {
1593 // Grab the tag name being searched for
1594 var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2];
1595
1596 // Handle IE7 being really dumb about <object>s
1597 if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" )
1598 tag = "param";
1599
1600 r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));
1601 }
1602
1603 // It's faster to filter by class and be done with it
1604 if ( m[1] == "." )
1605 r = jQuery.classFilter( r, m[2] );
1606
1607 // Same with ID filtering
1608 if ( m[1] == "#" ) {
1609 var tmp = [];
1610
1611 // Try to find the element with the ID
1612 for ( var i = 0; r[i]; i++ )
1613 if ( r[i].getAttribute("id") == m[2] ) {
1614 tmp = [ r[i] ];
1615 break;
1616 }
1617
1618 r = tmp;
1619 }
1620
1621 ret = r;
1622 }
1623
1624 t = t.replace( re2, "" );
1625 }
1626
1627 }
1628
1629 // If a selector string still exists
1630 if ( t ) {
1631 // Attempt to filter it
1632 var val = jQuery.filter(t,r);
1633 ret = r = val.r;
1634 t = jQuery.trim(val.t);
1635 }
1636 }
1637
1638 // An error occurred with the selector;
1639 // just return an empty set instead
1640 if ( t )
1641 ret = [];
1642
1643 // Remove the root context
1644 if ( ret && context == ret[0] )
1645 ret.shift();
1646
1647 // And combine the results
1648 done = jQuery.merge( done, ret );
1649
1650 return done;
1651 },
1652
1653 classFilter: function(r,m,not){
1654 m = " " + m + " ";
1655 var tmp = [];
1656 for ( var i = 0; r[i]; i++ ) {
1657 var pass = (" " + r[i].className + " ").indexOf( m ) >= 0;
1658 if ( !not && pass || not && !pass )
1659 tmp.push( r[i] );
1660 }
1661 return tmp;
1662 },
1663
1664 filter: function(t,r,not) {
1665 var last;
1666
1667 // Look for common filter expressions
1668 while ( t && t != last ) {
1669 last = t;
1670
1671 var p = jQuery.parse, m;
1672
1673 for ( var i = 0; p[i]; i++ ) {
1674 m = p[i].exec( t );
1675
1676 if ( m ) {
1677 // Remove what we just matched
1678 t = t.substring( m[0].length );
1679
1680 m[2] = m[2].replace(/\\/g, "");
1681 break;
1682 }
1683 }
1684
1685 if ( !m )
1686 break;
1687
1688 // :not() is a special case that can be optimized by
1689 // keeping it out of the expression list
1690 if ( m[1] == ":" && m[2] == "not" )
1691 // optimize if only one selector found (most common case)
1692 r = isSimple.test( m[3] ) ?
1693 jQuery.filter(m[3], r, true).r :
1694 jQuery( r ).not( m[3] );
1695
1696 // We can get a big speed boost by filtering by class here
1697 else if ( m[1] == "." )
1698 r = jQuery.classFilter(r, m[2], not);
1699
1700 else if ( m[1] == "[" ) {
1701 var tmp = [], type = m[3];
1702
1703 for ( var i = 0, rl = r.length; i < rl; i++ ) {
1704 var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ];
1705
1706 if ( z == null || /href|src|selected/.test(m[2]) )
1707 z = jQuery.attr(a,m[2]) || '';
1708
1709 if ( (type == "" && !!z ||
1710 type == "=" && z == m[5] ||
1711 type == "!=" && z != m[5] ||
1712 type == "^=" && z && !z.indexOf(m[5]) ||
1713 type == "$=" && z.substr(z.length - m[5].length) == m[5] ||
1714 (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not )
1715 tmp.push( a );
1716 }
1717
1718 r = tmp;
1719
1720 // We can get a speed boost by handling nth-child here
1721 } else if ( m[1] == ":" && m[2] == "nth-child" ) {
1722 var merge = {}, tmp = [],
1723 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
1724 test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
1725 m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||
1726 !/\D/.test(m[3]) && "0n+" + m[3] || m[3]),
1727 // calculate the numbers (first)n+(last) including if they are negative
1728 first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0;
1729
1730 // loop through all the elements left in the jQuery object
1731 for ( var i = 0, rl = r.length; i < rl; i++ ) {
1732 var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode);
1733
1734 if ( !merge[id] ) {
1735 var c = 1;
1736
1737 for ( var n = parentNode.firstChild; n; n = n.nextSibling )
1738 if ( n.nodeType == 1 )
1739 n.nodeIndex = c++;
1740
1741 merge[id] = true;
1742 }
1743
1744 var add = false;
1745
1746 if ( first == 0 ) {
1747 if ( node.nodeIndex == last )
1748 add = true;
1749 } else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 )
1750 add = true;
1751
1752 if ( add ^ not )
1753 tmp.push( node );
1754 }
1755
1756 r = tmp;
1757
1758 // Otherwise, find the expression to execute
1759 } else {
1760 var fn = jQuery.expr[ m[1] ];
1761 if ( typeof fn == "object" )
1762 fn = fn[ m[2] ];
1763
1764 if ( typeof fn == "string" )
1765 fn = eval("false||function(a,i){return " + fn + ";}");
1766
1767 // Execute it against the current filter
1768 r = jQuery.grep( r, function(elem, i){
1769 return fn(elem, i, m, r);
1770 }, not );
1771 }
1772 }
1773
1774 // Return an array of filtered elements (r)
1775 // and the modified expression string (t)
1776 return { r: r, t: t };
1777 },
1778
1779 dir: function( elem, dir ){
1780 var matched = [];
1781 var cur = elem[dir];
1782 while ( cur && cur != document ) {
1783 if ( cur.nodeType == 1 )
1784 matched.push( cur );
1785 cur = cur[dir];
1786 }
1787 return matched;
1788 },
1789
1790 nth: function(cur,result,dir,elem){
1791 result = result || 1;
1792 var num = 0;
1793
1794 for ( ; cur; cur = cur[dir] )
1795 if ( cur.nodeType == 1 && ++num == result )
1796 break;
1797
1798 return cur;
1799 },
1800
1801 sibling: function( n, elem ) {
1802 var r = [];
1803
1804 for ( ; n; n = n.nextSibling ) {
1805 if ( n.nodeType == 1 && (!elem || n != elem) )
1806 r.push( n );
1807 }
1808
1809 return r;
1810 }
1811 });
1812
1813 /*
1814 * A number of helper functions used for managing events.
1815 * Many of the ideas behind this code orignated from
1816 * Dean Edwards' addEvent library.
1817 */
1818 jQuery.event = {
1819
1820 // Bind an event to an element
1821 // Original by Dean Edwards
1822 add: function(elem, types, handler, data) {
1823 if ( elem.nodeType == 3 || elem.nodeType == 8 )
1824 return;
1825
1826 // For whatever reason, IE has trouble passing the window object
1827 // around, causing it to be cloned in the process
1828 if ( jQuery.browser.msie && elem.setInterval != undefined )
1829 elem = window;
1830
1831 // Make sure that the function being executed has a unique ID
1832 if ( !handler.guid )
1833 handler.guid = this.guid++;
1834
1835 // if data is passed, bind to handler
1836 if( data != undefined ) {
1837 // Create temporary function pointer to original handler
1838 var fn = handler;
1839
1840 // Create unique handler function, wrapped around original handler
1841 handler = function() {
1842 // Pass arguments and context to original handler
1843 return fn.apply(this, arguments);
1844 };
1845
1846 // Store data in unique handler
1847 handler.data = data;
1848
1849 // Set the guid of unique handler to the same of original handler, so it can be removed
1850 handler.guid = fn.guid;
1851 }
1852
1853 // Init the element's event structure
1854 var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
1855 handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
1856 // returned undefined or false
1857 var val;
1858
1859 // Handle the second event of a trigger and when
1860 // an event is called after a page has unloaded
1861 if ( typeof jQuery == "undefined" || jQuery.event.triggered )
1862 return val;
1863
1864 val = jQuery.event.handle.apply(arguments.callee.elem, arguments);
1865
1866 return val;
1867 });
1868 // Add elem as a property of the handle function
1869 // This is to prevent a memory leak with non-native
1870 // event in IE.
1871 handle.elem = elem;
1872
1873 // Handle multiple events seperated by a space
1874 // jQuery(...).bind("mouseover mouseout", fn);
1875 jQuery.each(types.split(/\s+/), function(index, type) {
1876 // Namespaced event handlers
1877 var parts = type.split(".");
1878 type = parts[0];
1879 handler.type = parts[1];
1880
1881 // Get the current list of functions bound to this event
1882 var handlers = events[type];
1883
1884 // Init the event handler queue
1885 if (!handlers) {
1886 handlers = events[type] = {};
1887
1888 // Check for a special event handler
1889 // Only use addEventListener/attachEvent if the special
1890 // events handler returns false
1891 if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) {
1892 // Bind the global event handler to the element
1893 if (elem.addEventListener)
1894 elem.addEventListener(type, handle, false);
1895 else if (elem.attachEvent)
1896 elem.attachEvent("on" + type, handle);
1897 }
1898 }
1899
1900 // Add the function to the element's handler list
1901 handlers[handler.guid] = handler;
1902
1903 // Keep track of which events have been used, for global triggering
1904 jQuery.event.global[type] = true;
1905 });
1906
1907 // Nullify elem to prevent memory leaks in IE
1908 elem = null;
1909 },
1910
1911 guid: 1,
1912 global: {},
1913
1914 // Detach an event or set of events from an element
1915 remove: function(elem, types, handler) {
1916 // don't do events on text and comment nodes
1917 if ( elem.nodeType == 3 || elem.nodeType == 8 )
1918 return;
1919
1920 var events = jQuery.data(elem, "events"), ret, index;
1921
1922 if ( events ) {
1923 // Unbind all events for the element
1924 if ( types == undefined || (typeof types == "string" && types.charAt(0) == ".") )
1925 for ( var type in events )
1926 this.remove( elem, type + (types || "") );
1927 else {
1928 // types is actually an event object here
1929 if ( types.type ) {
1930 handler = types.handler;
1931 types = types.type;
1932 }
1933
1934 // Handle multiple events seperated by a space
1935 // jQuery(...).unbind("mouseover mouseout", fn);
1936 jQuery.each(types.split(/\s+/), function(index, type){
1937 // Namespaced event handlers
1938 var parts = type.split(".");
1939 type = parts[0];
1940
1941 if ( events[type] ) {
1942 // remove the given handler for the given type
1943 if ( handler )
1944 delete events[type][handler.guid];
1945
1946 // remove all handlers for the given type
1947 else
1948 for ( handler in events[type] )
1949 // Handle the removal of namespaced events
1950 if ( !parts[1] || events[type][handler].type == parts[1] )
1951 delete events[type][handler];
1952
1953 // remove generic event handler if no more handlers exist
1954 for ( ret in events[type] ) break;
1955 if ( !ret ) {
1956 if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) {
1957 if (elem.removeEventListener)
1958 elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
1959 else if (elem.detachEvent)
1960 elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
1961 }
1962 ret = null;
1963 delete events[type];
1964 }
1965 }
1966 });
1967 }
1968
1969 // Remove the expando if it's no longer used
1970 for ( ret in events ) break;
1971 if ( !ret ) {
1972 var handle = jQuery.data( elem, "handle" );
1973 if ( handle ) handle.elem = null;
1974 jQuery.removeData( elem, "events" );
1975 jQuery.removeData( elem, "handle" );
1976 }
1977 }
1978 },
1979
1980 trigger: function(type, data, elem, donative, extra) {
1981 // Clone the incoming data, if any
1982 data = jQuery.makeArray(data || []);
1983
1984 if ( type.indexOf("!") >= 0 ) {
1985 type = type.slice(0, -1);
1986 var exclusive = true;
1987 }
1988
1989 // Handle a global trigger
1990 if ( !elem ) {
1991 // Only trigger if we've ever bound an event for it
1992 if ( this.global[type] )
1993 jQuery("*").add([window, document]).trigger(type, data);
1994
1995 // Handle triggering a single element
1996 } else {
1997 // don't do events on text and comment nodes
1998 if ( elem.nodeType == 3 || elem.nodeType == 8 )
1999 return undefined;
2000
2001 var val, ret, fn = jQuery.isFunction( elem[ type ] || null ),
2002 // Check to see if we need to provide a fake event, or not
2003 event = !data[0] || !data[0].preventDefault;
2004
2005 // Pass along a fake event
2006 if ( event )
2007 data.unshift( this.fix({ type: type, target: elem }) );
2008
2009 // Enforce the right trigger type
2010 data[0].type = type;
2011 if ( exclusive )
2012 data[0].exclusive = true;
2013
2014 // Trigger the event
2015 if ( jQuery.isFunction( jQuery.data(elem, "handle") ) )
2016 val = jQuery.data(elem, "handle").apply( elem, data );
2017
2018 // Handle triggering native .onfoo handlers
2019 if ( !fn && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
2020 val = false;
2021
2022 // Extra functions don't get the custom event object
2023 if ( event )
2024 data.shift();
2025
2026 // Handle triggering of extra function
2027 if ( extra && jQuery.isFunction( extra ) ) {
2028 // call the extra function and tack the current return value on the end for possible inspection
2029 ret = extra.apply( elem, val == null ? data : data.concat( val ) );
2030 // if anything is returned, give it precedence and have it overwrite the previous value
2031 if (ret !== undefined)
2032 val = ret;
2033 }
2034
2035 // Trigger the native events (except for clicks on links)
2036 if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
2037 this.triggered = true;
2038 try {
2039 elem[ type ]();
2040 // prevent IE from throwing an error for some hidden elements
2041 } catch (e) {}
2042 }
2043
2044 this.triggered = false;
2045 }
2046
2047 return val;
2048 },
2049
2050 handle: function(event) {
2051 // returned undefined or false
2052 var val;
2053
2054 // Empty object is for triggered events with no data
2055 event = jQuery.event.fix( event || window.event || {} );
2056
2057 // Namespaced event handlers
2058 var parts = event.type.split(".");
2059 event.type = parts[0];
2060
2061 var handlers = jQuery.data(this, "events") && jQuery.data(this, "events")[event.type], args = Array.prototype.slice.call( arguments, 1 );
2062 args.unshift( event );
2063
2064 for ( var j in handlers ) {
2065 var handler = handlers[j];
2066 // Pass in a reference to the handler function itself
2067 // So that we can later remove it
2068 args[0].handler = handler;
2069 args[0].data = handler.data;
2070
2071 // Filter the functions by class
2072 if ( !parts[1] && !event.exclusive || handler.type == parts[1] ) {
2073 var ret = handler.apply( this, args );
2074
2075 if ( val !== false )
2076 val = ret;
2077
2078 if ( ret === false ) {
2079 event.preventDefault();
2080 event.stopPropagation();
2081 }
2082 }
2083 }
2084
2085 // Clean up added properties in IE to prevent memory leak
2086 if (jQuery.browser.msie)
2087 event.target = event.preventDefault = event.stopPropagation =
2088 event.handler = event.data = null;
2089
2090 return val;
2091 },
2092
2093 fix: function(event) {
2094 // store a copy of the original event object
2095 // and clone to set read-only properties
2096 var originalEvent = event;
2097 event = jQuery.extend({}, originalEvent);
2098
2099 // add preventDefault and stopPropagation since
2100 // they will not work on the clone
2101 event.preventDefault = function() {
2102 // if preventDefault exists run it on the original event
2103 if (originalEvent.preventDefault)
2104 originalEvent.preventDefault();
2105 // otherwise set the returnValue property of the original event to false (IE)
2106 originalEvent.returnValue = false;
2107 };
2108 event.stopPropagation = function() {
2109 // if stopPropagation exists run it on the original event
2110 if (originalEvent.stopPropagation)
2111 originalEvent.stopPropagation();
2112 // otherwise set the cancelBubble property of the original event to true (IE)
2113 originalEvent.cancelBubble = true;
2114 };
2115
2116 // Fix target property, if necessary
2117 if ( !event.target )
2118 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
2119
2120 // check if target is a textnode (safari)
2121 if ( event.target.nodeType == 3 )
2122 event.target = originalEvent.target.parentNode;
2123
2124 // Add relatedTarget, if necessary
2125 if ( !event.relatedTarget && event.fromElement )
2126 event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
2127
2128 // Calculate pageX/Y if missing and clientX/Y available
2129 if ( event.pageX == null && event.clientX != null ) {
2130 var doc = document.documentElement, body = document.body;
2131 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
2132 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
2133 }
2134
2135 // Add which for key events
2136 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
2137 event.which = event.charCode || event.keyCode;
2138
2139 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
2140 if ( !event.metaKey && event.ctrlKey )
2141 event.metaKey = event.ctrlKey;
2142
2143 // Add which for click: 1 == left; 2 == middle; 3 == right
2144 // Note: button is not normalized, so don't use it
2145 if ( !event.which && event.button )
2146 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
2147
2148 return event;
2149 },
2150
2151 special: {
2152 ready: {
2153 setup: function() {
2154 // Make sure the ready event is setup
2155 bindReady();
2156 return;
2157 },
2158
2159 teardown: function() { return; }
2160 },
2161
2162 mouseenter: {
2163 setup: function() {
2164 if ( jQuery.browser.msie ) return false;
2165 jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler);
2166 return true;
2167 },
2168
2169 teardown: function() {
2170 if ( jQuery.browser.msie ) return false;
2171 jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler);
2172 return true;
2173 },
2174
2175 handler: function(event) {
2176 // If we actually just moused on to a sub-element, ignore it
2177 if ( withinElement(event, this) ) return true;
2178 // Execute the right handlers by setting the event type to mouseenter
2179 arguments[0].type = "mouseenter";
2180 return jQuery.event.handle.apply(this, arguments);
2181 }
2182 },
2183
2184 mouseleave: {
2185 setup: function() {
2186 if ( jQuery.browser.msie ) return false;
2187 jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler);
2188 return true;
2189 },
2190
2191 teardown: function() {
2192 if ( jQuery.browser.msie ) return false;
2193 jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler);
2194 return true;
2195 },
2196
2197 handler: function(event) {
2198 // If we actually just moused on to a sub-element, ignore it
2199 if ( withinElement(event, this) ) return true;
2200 // Execute the right handlers by setting the event type to mouseleave
2201 arguments[0].type = "mouseleave";
2202 return jQuery.event.handle.apply(this, arguments);
2203 }
2204 }
2205 }
2206 };
2207
2208 jQuery.fn.extend({
2209 bind: function( type, data, fn ) {
2210 return type == "unload" ? this.one(type, data, fn) : this.each(function(){
2211 jQuery.event.add( this, type, fn || data, fn && data );
2212 });
2213 },
2214
2215 one: function( type, data, fn ) {
2216 return this.each(function(){
2217 jQuery.event.add( this, type, function(event) {
2218 jQuery(this).unbind(event);
2219 return (fn || data).apply( this, arguments);
2220 }, fn && data);
2221 });
2222 },
2223
2224 unbind: function( type, fn ) {
2225 return this.each(function(){
2226 jQuery.event.remove( this, type, fn );
2227 });
2228 },
2229
2230 trigger: function( type, data, fn ) {
2231 return this.each(function(){
2232 jQuery.event.trigger( type, data, this, true, fn );
2233 });
2234 },
2235
2236 triggerHandler: function( type, data, fn ) {
2237 if ( this[0] )
2238 return jQuery.event.trigger( type, data, this[0], false, fn );
2239 return undefined;
2240 },
2241
2242 toggle: function() {
2243 // Save reference to arguments for access in closure
2244 var args = arguments;
2245
2246 return this.click(function(event) {
2247 // Figure out which function to execute
2248 this.lastToggle = 0 == this.lastToggle ? 1 : 0;
2249
2250 // Make sure that clicks stop
2251 event.preventDefault();
2252
2253 // and execute the function
2254 return args[this.lastToggle].apply( this, arguments ) || false;
2255 });
2256 },
2257
2258 hover: function(fnOver, fnOut) {
2259 return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut);
2260 },
2261
2262 ready: function(fn) {
2263 // Attach the listeners
2264 bindReady();
2265
2266 // If the DOM is already ready
2267 if ( jQuery.isReady )
2268 // Execute the function immediately
2269 fn.call( document, jQuery );
2270
2271 // Otherwise, remember the function for later
2272 else
2273 // Add the function to the wait list
2274 jQuery.readyList.push( function() { return fn.call(this, jQuery); } );
2275
2276 return this;
2277 }
2278 });
2279
2280 jQuery.extend({
2281 isReady: false,
2282 readyList: [],
2283 // Handle when the DOM is ready
2284 ready: function() {
2285 // Make sure that the DOM is not already loaded
2286 if ( !jQuery.isReady ) {
2287 // Remember that the DOM is ready
2288 jQuery.isReady = true;
2289
2290 // If there are functions bound, to execute
2291 if ( jQuery.readyList ) {
2292 // Execute all of them
2293 jQuery.each( jQuery.readyList, function(){
2294 this.apply( document );
2295 });
2296
2297 // Reset the list of functions
2298 jQuery.readyList = null;
2299 }
2300
2301 // Trigger any bound ready events
2302 jQuery(document).triggerHandler("ready");
2303 }
2304 }
2305 });
2306
2307 var readyBound = false;
2308
2309 function bindReady(){
2310 if ( readyBound ) return;
2311 readyBound = true;
2312
2313 // Mozilla, Opera (see further below for it) and webkit nightlies currently support this event
2314 if ( document.addEventListener && !jQuery.browser.opera)
2315 // Use the handy event callback
2316 document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
2317
2318 // If IE is used and is not in a frame
2319 // Continually check to see if the document is ready
2320 if ( jQuery.browser.msie && window == top ) (function(){
2321 if (jQuery.isReady) return;
2322 try {
2323 // If IE is used, use the trick by Diego Perini
2324 // http://javascript.nwbox.com/IEContentLoaded/
2325 document.documentElement.doScroll("left");
2326 } catch( error ) {
2327 setTimeout( arguments.callee, 0 );
2328 return;
2329 }
2330 // and execute any waiting functions
2331 jQuery.ready();
2332 })();
2333
2334 if ( jQuery.browser.opera )
2335 document.addEventListener( "DOMContentLoaded", function () {
2336 if (jQuery.isReady) return;
2337 for (var i = 0; i < document.styleSheets.length; i++)
2338 if (document.styleSheets[i].disabled) {
2339 setTimeout( arguments.callee, 0 );
2340 return;
2341 }
2342 // and execute any waiting functions
2343 jQuery.ready();
2344 }, false);
2345
2346 if ( jQuery.browser.safari ) {
2347 var numStyles;
2348 (function(){
2349 if (jQuery.isReady) return;
2350 if ( document.readyState != "loaded" && document.readyState != "complete" ) {
2351 setTimeout( arguments.callee, 0 );
2352 return;
2353 }
2354 if ( numStyles === undefined )
2355 numStyles = jQuery("style, link[rel=stylesheet]").length;
2356 if ( document.styleSheets.length != numStyles ) {
2357 setTimeout( arguments.callee, 0 );
2358 return;
2359 }
2360 // and execute any waiting functions
2361 jQuery.ready();
2362 })();
2363 }
2364
2365 // A fallback to window.onload, that will always work
2366 jQuery.event.add( window, "load", jQuery.ready );
2367 }
2368
2369 jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
2370 "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
2371 "submit,keydown,keypress,keyup,error").split(","), function(i, name){
2372
2373 // Handle event binding
2374 jQuery.fn[name] = function(fn){
2375 return fn ? this.bind(name, fn) : this.trigger(name);
2376 };
2377 });
2378
2379 // Checks if an event happened on an element within another element
2380 // Used in jQuery.event.special.mouseenter and mouseleave handlers
2381 var withinElement = function(event, elem) {
2382 // Check if mouse(over|out) are still within the same parent element
2383 var parent = event.relatedTarget;
2384 // Traverse up the tree
2385 while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; }
2386 // Return true if we actually just moused on to a sub-element
2387 return parent == elem;
2388 };
2389
2390 // Prevent memory leaks in IE
2391 // And prevent errors on refresh with events like mouseover in other browsers
2392 // Window isn't included so as not to unbind existing unload events
2393 jQuery(window).bind("unload", function() {
2394 jQuery("*").add(document).unbind();
2395 });
2396 jQuery.fn.extend({
2397 load: function( url, params, callback ) {
2398 if ( jQuery.isFunction( url ) )
2399 return this.bind("load", url);
2400
2401 var off = url.indexOf(" ");
2402 if ( off >= 0 ) {
2403 var selector = url.slice(off, url.length);
2404 url = url.slice(0, off);
2405 }
2406
2407 callback = callback || function(){};
2408
2409 // Default to a GET request
2410 var type = "GET";
2411
2412 // If the second parameter was provided
2413 if ( params )
2414 // If it's a function
2415 if ( jQuery.isFunction( params ) ) {
2416 // We assume that it's the callback
2417 callback = params;
2418 params = null;
2419
2420 // Otherwise, build a param string
2421 } else {
2422 params = jQuery.param( params );
2423 type = "POST";
2424 }
2425
2426 var self = this;
2427
2428 // Request the remote document
2429 jQuery.ajax({
2430 url: url,
2431 type: type,
2432 dataType: "html",
2433 data: params,
2434 complete: function(res, status){
2435 // If successful, inject the HTML into all the matched elements
2436 if ( status == "success" || status == "notmodified" )
2437 // See if a selector was specified
2438 self.html( selector ?
2439 // Create a dummy div to hold the results
2440 jQuery("<div/>")
2441 // inject the contents of the document in, removing the scripts
2442 // to avoid any 'Permission Denied' errors in IE
2443 .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
2444
2445 // Locate the specified elements
2446 .find(selector) :
2447
2448 // If not, just inject the full result
2449 res.responseText );
2450
2451 self.each( callback, [res.responseText, status, res] );
2452 }
2453 });
2454 return this;
2455 },
2456
2457 serialize: function() {
2458 return jQuery.param(this.serializeArray());
2459 },
2460 serializeArray: function() {
2461 return this.map(function(){
2462 return jQuery.nodeName(this, "form") ?
2463 jQuery.makeArray(this.elements) : this;
2464 })
2465 .filter(function(){
2466 return this.name && !this.disabled &&
2467 (this.checked || /select|textarea/i.test(this.nodeName) ||
2468 /text|hidden|password/i.test(this.type));
2469 })
2470 .map(function(i, elem){
2471 var val = jQuery(this).val();
2472 return val == null ? null :
2473 val.constructor == Array ?
2474 jQuery.map( val, function(val, i){
2475 return {name: elem.name, value: val};
2476 }) :
2477 {name: elem.name, value: val};
2478 }).get();
2479 }
2480 });
2481
2482 // Attach a bunch of functions for handling common AJAX events
2483 jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
2484 jQuery.fn[o] = function(f){
2485 return this.bind(o, f);
2486 };
2487 });
2488
2489 var jsc = (new Date).getTime();
2490
2491 jQuery.extend({
2492 get: function( url, data, callback, type ) {
2493 // shift arguments if data argument was ommited
2494 if ( jQuery.isFunction( data ) ) {
2495 callback = data;
2496 data = null;
2497 }
2498
2499 return jQuery.ajax({
2500 type: "GET",
2501 url: url,
2502 data: data,
2503 success: callback,
2504 dataType: type
2505 });
2506 },
2507
2508 getScript: function( url, callback ) {
2509 return jQuery.get(url, null, callback, "script");
2510 },
2511
2512 getJSON: function( url, data, callback ) {
2513 return jQuery.get(url, data, callback, "json");
2514 },
2515
2516 post: function( url, data, callback, type ) {
2517 if ( jQuery.isFunction( data ) ) {
2518 callback = data;
2519 data = {};
2520 }
2521
2522 return jQuery.ajax({
2523 type: "POST",
2524 url: url,
2525 data: data,
2526 success: callback,
2527 dataType: type
2528 });
2529 },
2530
2531 ajaxSetup: function( settings ) {
2532 jQuery.extend( jQuery.ajaxSettings, settings );
2533 },
2534
2535 ajaxSettings: {
2536 global: true,
2537 type: "GET",
2538 timeout: 0,
2539 contentType: "application/x-www-form-urlencoded",
2540 processData: true,
2541 async: true,
2542 data: null,
2543 username: null,
2544 password: null,
2545 accepts: {
2546 xml: "application/xml, text/xml",
2547 html: "text/html",
2548 script: "text/javascript, application/javascript",
2549 json: "application/json, text/javascript",
2550 text: "text/plain",
2551 _default: "*/*"
2552 }
2553 },
2554
2555 // Last-Modified header cache for next request
2556 lastModified: {},
2557
2558 ajax: function( s ) {
2559 var jsonp, jsre = /=\?(&|$)/g, status, data;
2560
2561 // Extend the settings, but re-extend 's' so that it can be
2562 // checked again later (in the test suite, specifically)
2563 s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
2564
2565 // convert data if not already a string
2566 if ( s.data && s.processData && typeof s.data != "string" )
2567 s.data = jQuery.param(s.data);
2568
2569 // Handle JSONP Parameter Callbacks
2570 if ( s.dataType == "jsonp" ) {
2571 if ( s.type.toLowerCase() == "get" ) {
2572 if ( !s.url.match(jsre) )
2573 s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
2574 } else if ( !s.data || !s.data.match(jsre) )
2575 s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
2576 s.dataType = "json";
2577 }
2578
2579 // Build temporary JSONP function
2580 if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
2581 jsonp = "jsonp" + jsc++;
2582
2583 // Replace the =? sequence both in the query string and the data
2584 if ( s.data )
2585 s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
2586 s.url = s.url.replace(jsre, "=" + jsonp + "$1");
2587
2588 // We need to make sure
2589 // that a JSONP style response is executed properly
2590 s.dataType = "script";
2591
2592 // Handle JSONP-style loading
2593 window[ jsonp ] = function(tmp){
2594 data = tmp;
2595 success();
2596 complete();
2597 // Garbage collect
2598 window[ jsonp ] = undefined;
2599 try{ delete window[ jsonp ]; } catch(e){}
2600 if ( head )
2601 head.removeChild( script );
2602 };
2603 }
2604
2605 if ( s.dataType == "script" && s.cache == null )
2606 s.cache = false;
2607
2608 if ( s.cache === false && s.type.toLowerCase() == "get" ) {
2609 var ts = (new Date()).getTime();
2610 // try replacing _= if it is there
2611 var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
2612 // if nothing was replaced, add timestamp to the end
2613 s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
2614 }
2615
2616 // If data is available, append data to url for get requests
2617 if ( s.data && s.type.toLowerCase() == "get" ) {
2618 s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
2619
2620 // IE likes to send both get and post data, prevent this
2621 s.data = null;
2622 }
2623
2624 // Watch for a new set of requests
2625 if ( s.global && ! jQuery.active++ )
2626 jQuery.event.trigger( "ajaxStart" );
2627
2628 // If we're requesting a remote document
2629 // and trying to load JSON or Script with a GET
2630 if ( (!s.url.indexOf("http") || !s.url.indexOf("//")) && s.dataType == "script" && s.type.toLowerCase() == "get" ) {
2631 var head = document.getElementsByTagName("head")[0];
2632 var script = document.createElement("script");
2633 script.src = s.url;
2634 if (s.scriptCharset)
2635 script.charset = s.scriptCharset;
2636
2637 // Handle Script loading
2638 if ( !jsonp ) {
2639 var done = false;
2640
2641 // Attach handlers for all browsers
2642 script.onload = script.onreadystatechange = function(){
2643 if ( !done && (!this.readyState ||
2644 this.readyState == "loaded" || this.readyState == "complete") ) {
2645 done = true;
2646 success();
2647 complete();
2648 head.removeChild( script );
2649 }
2650 };
2651 }
2652
2653 head.appendChild(script);
2654
2655 // We handle everything using the script element injection
2656 return undefined;
2657 }
2658
2659 var requestDone = false;
2660
2661 // Create the request object; Microsoft failed to properly
2662 // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
2663 var xml = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
2664
2665 // Open the socket
2666 xml.open(s.type, s.url, s.async, s.username, s.password);
2667
2668 // Need an extra try/catch for cross domain requests in Firefox 3
2669 try {
2670 // Set the correct header, if data is being sent
2671 if ( s.data )
2672 xml.setRequestHeader("Content-Type", s.contentType);
2673
2674 // Set the If-Modified-Since header, if ifModified mode.
2675 if ( s.ifModified )
2676 xml.setRequestHeader("If-Modified-Since",
2677 jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
2678
2679 // Set header so the called script knows that it's an XMLHttpRequest
2680 xml.setRequestHeader("X-Requested-With", "XMLHttpRequest");
2681
2682 // Set the Accepts header for the server, depending on the dataType
2683 xml.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
2684 s.accepts[ s.dataType ] + ", */*" :
2685 s.accepts._default );
2686 } catch(e){}
2687
2688 // Allow custom headers/mimetypes
2689 if ( s.beforeSend )
2690 s.beforeSend(xml);
2691
2692 if ( s.global )
2693 jQuery.event.trigger("ajaxSend", [xml, s]);
2694
2695 // Wait for a response to come back
2696 var onreadystatechange = function(isTimeout){
2697 // The transfer is complete and the data is available, or the request timed out
2698 if ( !requestDone && xml && (xml.readyState == 4 || isTimeout == "timeout") ) {
2699 requestDone = true;
2700
2701 // clear poll interval
2702 if (ival) {
2703 clearInterval(ival);
2704 ival = null;
2705 }
2706
2707 status = isTimeout == "timeout" && "timeout" ||
2708 !jQuery.httpSuccess( xml ) && "error" ||
2709 s.ifModified && jQuery.httpNotModified( xml, s.url ) && "notmodified" ||
2710 "success";
2711
2712 if ( status == "success" ) {
2713 // Watch for, and catch, XML document parse errors
2714 try {
2715 // process the data (runs the xml through httpData regardless of callback)
2716 data = jQuery.httpData( xml, s.dataType );
2717 } catch(e) {
2718 status = "parsererror";
2719 }
2720 }
2721
2722 // Make sure that the request was successful or notmodified
2723 if ( status == "success" ) {
2724 // Cache Last-Modified header, if ifModified mode.
2725 var modRes;
2726 try {
2727 modRes = xml.getResponseHeader("Last-Modified");
2728 } catch(e) {} // swallow exception thrown by FF if header is not available
2729
2730 if ( s.ifModified && modRes )
2731 jQuery.lastModified[s.url] = modRes;
2732
2733 // JSONP handles its own success callback
2734 if ( !jsonp )
2735 success();
2736 } else
2737 jQuery.handleError(s, xml, status);
2738
2739 // Fire the complete handlers
2740 complete();
2741
2742 // Stop memory leaks
2743 if ( s.async )
2744 xml = null;
2745 }
2746 };
2747
2748 if ( s.async ) {
2749 // don't attach the handler to the request, just poll it instead
2750 var ival = setInterval(onreadystatechange, 13);
2751
2752 // Timeout checker
2753 if ( s.timeout > 0 )
2754 setTimeout(function(){
2755 // Check to see if the request is still happening
2756 if ( xml ) {
2757 // Cancel the request
2758 xml.abort();
2759
2760 if( !requestDone )
2761 onreadystatechange( "timeout" );
2762 }
2763 }, s.timeout);
2764 }
2765
2766 // Send the data
2767 try {
2768 xml.send(s.data);
2769 } catch(e) {
2770 jQuery.handleError(s, xml, null, e);
2771 }
2772
2773 // firefox 1.5 doesn't fire statechange for sync requests
2774 if ( !s.async )
2775 onreadystatechange();
2776
2777 function success(){
2778 // If a local callback was specified, fire it and pass it the data
2779 if ( s.success )
2780 s.success( data, status );
2781
2782 // Fire the global callback
2783 if ( s.global )
2784 jQuery.event.trigger( "ajaxSuccess", [xml, s] );
2785 }
2786
2787 function complete(){
2788 // Process result
2789 if ( s.complete )
2790 s.complete(xml, status);
2791
2792 // The request was completed
2793 if ( s.global )
2794 jQuery.event.trigger( "ajaxComplete", [xml, s] );
2795
2796 // Handle the global AJAX counter
2797 if ( s.global && ! --jQuery.active )
2798 jQuery.event.trigger( "ajaxStop" );
2799 }
2800
2801 // return XMLHttpRequest to allow aborting the request etc.
2802 return xml;
2803 },
2804
2805 handleError: function( s, xml, status, e ) {
2806 // If a local callback was specified, fire it
2807 if ( s.error ) s.error( xml, status, e );
2808
2809 // Fire the global callback
2810 if ( s.global )
2811 jQuery.event.trigger( "ajaxError", [xml, s, e] );
2812 },
2813
2814 // Counter for holding the number of active queries
2815 active: 0,
2816
2817 // Determines if an XMLHttpRequest was successful or not
2818 httpSuccess: function( r ) {
2819 try {
2820 // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
2821 return !r.status && location.protocol == "file:" ||
2822 ( r.status >= 200 && r.status < 300 ) || r.status == 304 || r.status == 1223 ||
2823 jQuery.browser.safari && r.status == undefined;
2824 } catch(e){}
2825 return false;
2826 },
2827
2828 // Determines if an XMLHttpRequest returns NotModified
2829 httpNotModified: function( xml, url ) {
2830 try {
2831 var xmlRes = xml.getResponseHeader("Last-Modified");
2832
2833 // Firefox always returns 200. check Last-Modified date
2834 return xml.status == 304 || xmlRes == jQuery.lastModified[url] ||
2835 jQuery.browser.safari && xml.status == undefined;
2836 } catch(e){}
2837 return false;
2838 },
2839
2840 httpData: function( r, type ) {
2841 var ct = r.getResponseHeader("content-type");
2842 var xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0;
2843 var data = xml ? r.responseXML : r.responseText;
2844
2845 if ( xml && data.documentElement.tagName == "parsererror" )
2846 throw "parsererror";
2847
2848 // If the type is "script", eval it in global context
2849 if ( type == "script" )
2850 jQuery.globalEval( data );
2851
2852 // Get the JavaScript object, if JSON is used.
2853 if ( type == "json" )
2854 data = eval("(" + data + ")");
2855
2856 return data;
2857 },
2858
2859 // Serialize an array of form elements or a set of
2860 // key/values into a query string
2861 param: function( a ) {
2862 var s = [];
2863
2864 // If an array was passed in, assume that it is an array
2865 // of form elements
2866 if ( a.constructor == Array || a.jquery )
2867 // Serialize the form elements
2868 jQuery.each( a, function(){
2869 s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) );
2870 });
2871
2872 // Otherwise, assume that it's an object of key/value pairs
2873 else
2874 // Serialize the key/values
2875 for ( var j in a )
2876 // If the value is an array then the key names need to be repeated
2877 if ( a[j] && a[j].constructor == Array )
2878 jQuery.each( a[j], function(){
2879 s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) );
2880 });
2881 else
2882 s.push( encodeURIComponent(j) + "=" + encodeURIComponent( a[j] ) );
2883
2884 // Return the resulting serialization
2885 return s.join("&").replace(/%20/g, "+");
2886 }
2887
2888 });
2889 jQuery.fn.extend({
2890 show: function(speed,callback){
2891 return speed ?
2892 this.animate({
2893 height: "show", width: "show", opacity: "show"
2894 }, speed, callback) :
2895
2896 this.filter(":hidden").each(function(){
2897 this.style.display = this.oldblock || "";
2898 if ( jQuery.css(this,"display") == "none" ) {
2899 var elem = jQuery("<" + this.tagName + " />").appendTo("body");
2900 this.style.display = elem.css("display");
2901 // handle an edge condition where css is - div { display:none; } or similar
2902 if (this.style.display == "none")
2903 this.style.display = "block";
2904 elem.remove();
2905 }
2906 }).end();
2907 },
2908
2909 hide: function(speed,callback){
2910 return speed ?
2911 this.animate({
2912 height: "hide", width: "hide", opacity: "hide"
2913 }, speed, callback) :
2914
2915 this.filter(":visible").each(function(){
2916 this.oldblock = this.oldblock || jQuery.css(this,"display");
2917 this.style.display = "none";
2918 }).end();
2919 },
2920
2921 // Save the old toggle function
2922 _toggle: jQuery.fn.toggle,
2923
2924 toggle: function( fn, fn2 ){
2925 return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
2926 this._toggle( fn, fn2 ) :
2927 fn ?
2928 this.animate({
2929 height: "toggle", width: "toggle", opacity: "toggle"
2930 }, fn, fn2) :
2931 this.each(function(){
2932 jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
2933 });
2934 },
2935
2936 slideDown: function(speed,callback){
2937 return this.animate({height: "show"}, speed, callback);
2938 },
2939
2940 slideUp: function(speed,callback){
2941 return this.animate({height: "hide"}, speed, callback);
2942 },
2943
2944 slideToggle: function(speed, callback){
2945 return this.animate({height: "toggle"}, speed, callback);
2946 },
2947
2948 fadeIn: function(speed, callback){
2949 return this.animate({opacity: "show"}, speed, callback);
2950 },
2951
2952 fadeOut: function(speed, callback){
2953 return this.animate({opacity: "hide"}, speed, callback);
2954 },
2955
2956 fadeTo: function(speed,to,callback){
2957 return this.animate({opacity: to}, speed, callback);
2958 },
2959
2960 animate: function( prop, speed, easing, callback ) {
2961 var optall = jQuery.speed(speed, easing, callback);
2962
2963 return this[ optall.queue === false ? "each" : "queue" ](function(){
2964 if ( this.nodeType != 1)
2965 return false;
2966
2967 var opt = jQuery.extend({}, optall);
2968 var hidden = jQuery(this).is(":hidden"), self = this;
2969
2970 for ( var p in prop ) {
2971 if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
2972 return jQuery.isFunction(opt.complete) && opt.complete.apply(this);
2973
2974 if ( p == "height" || p == "width" ) {
2975 // Store display property
2976 opt.display = jQuery.css(this, "display");
2977
2978 // Make sure that nothing sneaks out
2979 opt.overflow = this.style.overflow;
2980 }
2981 }
2982
2983 if ( opt.overflow != null )
2984 this.style.overflow = "hidden";
2985
2986 opt.curAnim = jQuery.extend({}, prop);
2987
2988 jQuery.each( prop, function(name, val){
2989 var e = new jQuery.fx( self, opt, name );
2990
2991 if ( /toggle|show|hide/.test(val) )
2992 e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
2993 else {
2994 var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
2995 start = e.cur(true) || 0;
2996
2997 if ( parts ) {
2998 var end = parseFloat(parts[2]),
2999 unit = parts[3] || "px";
3000
3001 // We need to compute starting value
3002 if ( unit != "px" ) {
3003 self.style[ name ] = (end || 1) + unit;
3004 start = ((end || 1) / e.cur(true)) * start;
3005 self.style[ name ] = start + unit;
3006 }
3007
3008 // If a +=/-= token was provided, we're doing a relative animation
3009 if ( parts[1] )
3010 end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
3011
3012 e.custom( start, end, unit );
3013 } else
3014 e.custom( start, val, "" );
3015 }
3016 });
3017
3018 // For JS strict compliance
3019 return true;
3020 });
3021 },
3022
3023 queue: function(type, fn){
3024 if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) {
3025 fn = type;
3026 type = "fx";
3027 }
3028
3029 if ( !type || (typeof type == "string" && !fn) )
3030 return queue( this[0], type );
3031
3032 return this.each(function(){
3033 if ( fn.constructor == Array )
3034 queue(this, type, fn);
3035 else {
3036 queue(this, type).push( fn );
3037
3038 if ( queue(this, type).length == 1 )
3039 fn.apply(this);
3040 }
3041 });
3042 },
3043
3044 stop: function(clearQueue, gotoEnd){
3045 var timers = jQuery.timers;
3046
3047 if (clearQueue)
3048 this.queue([]);
3049
3050 this.each(function(){
3051 // go in reverse order so anything added to the queue during the loop is ignored
3052 for ( var i = timers.length - 1; i >= 0; i-- )
3053 if ( timers[i].elem == this ) {
3054 if (gotoEnd)
3055 // force the next step to be the last
3056 timers[i](true);
3057 timers.splice(i, 1);
3058 }
3059 });
3060
3061 // start the next in the queue if the last step wasn't forced
3062 if (!gotoEnd)
3063 this.dequeue();
3064
3065 return this;
3066 }
3067
3068 });
3069
3070 var queue = function( elem, type, array ) {
3071 if ( !elem )
3072 return undefined;
3073
3074 type = type || "fx";
3075
3076 var q = jQuery.data( elem, type + "queue" );
3077
3078 if ( !q || array )
3079 q = jQuery.data( elem, type + "queue",
3080 array ? jQuery.makeArray(array) : [] );
3081
3082 return q;
3083 };
3084
3085 jQuery.fn.dequeue = function(type){
3086 type = type || "fx";
3087
3088 return this.each(function(){
3089 var q = queue(this, type);
3090
3091 q.shift();
3092
3093 if ( q.length )
3094 q[0].apply( this );
3095 });
3096 };
3097
3098 jQuery.extend({
3099
3100 speed: function(speed, easing, fn) {
3101 var opt = speed && speed.constructor == Object ? speed : {
3102 complete: fn || !fn && easing ||
3103 jQuery.isFunction( speed ) && speed,
3104 duration: speed,
3105 easing: fn && easing || easing && easing.constructor != Function && easing
3106 };
3107
3108 opt.duration = (opt.duration && opt.duration.constructor == Number ?
3109 opt.duration :
3110 { slow: 600, fast: 200 }[opt.duration]) || 400;
3111
3112 // Queueing
3113 opt.old = opt.complete;
3114 opt.complete = function(){
3115 if ( opt.queue !== false )
3116 jQuery(this).dequeue();
3117 if ( jQuery.isFunction( opt.old ) )
3118 opt.old.apply( this );
3119 };
3120
3121 return opt;
3122 },
3123
3124 easing: {
3125 linear: function( p, n, firstNum, diff ) {
3126 return firstNum + diff * p;
3127 },
3128 swing: function( p, n, firstNum, diff ) {
3129 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
3130 }
3131 },
3132
3133 timers: [],
3134 timerId: null,
3135
3136 fx: function( elem, options, prop ){
3137 this.options = options;
3138 this.elem = elem;
3139 this.prop = prop;
3140
3141 if ( !options.orig )
3142 options.orig = {};
3143 }
3144
3145 });
3146
3147 jQuery.fx.prototype = {
3148
3149 // Simple function for setting a style value
3150 update: function(){
3151 if ( this.options.step )
3152 this.options.step.apply( this.elem, [ this.now, this ] );
3153
3154 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
3155
3156 // Set display property to block for height/width animations
3157 if ( this.prop == "height" || this.prop == "width" )
3158 this.elem.style.display = "block";
3159 },
3160
3161 // Get the current size
3162 cur: function(force){
3163 if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )
3164 return this.elem[ this.prop ];
3165
3166 var r = parseFloat(jQuery.css(this.elem, this.prop, force));
3167 return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
3168 },
3169
3170 // Start an animation from one number to another
3171 custom: function(from, to, unit){
3172 this.startTime = (new Date()).getTime();
3173 this.start = from;
3174 this.end = to;
3175 this.unit = unit || this.unit || "px";
3176 this.now = this.start;
3177 this.pos = this.state = 0;
3178 this.update();
3179
3180 var self = this;
3181 function t(gotoEnd){
3182 return self.step(gotoEnd);
3183 }
3184
3185 t.elem = this.elem;
3186
3187 jQuery.timers.push(t);
3188
3189 if ( jQuery.timerId == null ) {
3190 jQuery.timerId = setInterval(function(){
3191 var timers = jQuery.timers;
3192
3193 for ( var i = 0; i < timers.length; i++ )
3194 if ( !timers[i]() )
3195 timers.splice(i--, 1);
3196
3197 if ( !timers.length ) {
3198 clearInterval( jQuery.timerId );
3199 jQuery.timerId = null;
3200 }
3201 }, 13);
3202 }
3203 },
3204
3205 // Simple 'show' function
3206 show: function(){
3207 // Remember where we started, so that we can go back to it later
3208 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
3209 this.options.show = true;
3210
3211 // Begin the animation
3212 this.custom(0, this.cur());
3213
3214 // Make sure that we start at a small width/height to avoid any
3215 // flash of content
3216 if ( this.prop == "width" || this.prop == "height" )
3217 this.elem.style[this.prop] = "1px";
3218
3219 // Start by showing the element
3220 jQuery(this.elem).show();
3221 },
3222
3223 // Simple 'hide' function
3224 hide: function(){
3225 // Remember where we started, so that we can go back to it later
3226 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
3227 this.options.hide = true;
3228
3229 // Begin the animation
3230 this.custom(this.cur(), 0);
3231 },
3232
3233 // Each step of an animation
3234 step: function(gotoEnd){
3235 var t = (new Date()).getTime();
3236
3237 if ( gotoEnd || t > this.options.duration + this.startTime ) {
3238 this.now = this.end;
3239 this.pos = this.state = 1;
3240 this.update();
3241
3242 this.options.curAnim[ this.prop ] = true;
3243
3244 var done = true;
3245 for ( var i in this.options.curAnim )
3246 if ( this.options.curAnim[i] !== true )
3247 done = false;
3248
3249 if ( done ) {
3250 if ( this.options.display != null ) {
3251 // Reset the overflow
3252 this.elem.style.overflow = this.options.overflow;
3253
3254 // Reset the display
3255 this.elem.style.display = this.options.display;
3256 if ( jQuery.css(this.elem, "display") == "none" )
3257 this.elem.style.display = "block";
3258 }
3259
3260 // Hide the element if the "hide" operation was done
3261 if ( this.options.hide )
3262 this.elem.style.display = "none";
3263
3264 // Reset the properties, if the item has been hidden or shown
3265 if ( this.options.hide || this.options.show )
3266 for ( var p in this.options.curAnim )
3267 jQuery.attr(this.elem.style, p, this.options.orig[p]);
3268 }
3269
3270 // If a callback was provided, execute it
3271 if ( done && jQuery.isFunction( this.options.complete ) )
3272 // Execute the complete function
3273 this.options.complete.apply( this.elem );
3274
3275 return false;
3276 } else {
3277 var n = t - this.startTime;
3278 this.state = n / this.options.duration;
3279
3280 // Perform the easing function, defaults to swing
3281 this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
3282 this.now = this.start + ((this.end - this.start) * this.pos);
3283
3284 // Perform the next step of the animation
3285 this.update();
3286 }
3287
3288 return true;
3289 }
3290
3291 };
3292
3293 jQuery.fx.step = {
3294 scrollLeft: function(fx){
3295 fx.elem.scrollLeft = fx.now;
3296 },
3297
3298 scrollTop: function(fx){
3299 fx.elem.scrollTop = fx.now;
3300 },
3301
3302 opacity: function(fx){
3303 jQuery.attr(fx.elem.style, "opacity", fx.now);
3304 },
3305
3306 _default: function(fx){
3307 fx.elem.style[ fx.prop ] = fx.now + fx.unit;
3308 }
3309 };
3310 // The Offset Method
3311 // Originally By Brandon Aaron, part of the Dimension Plugin
3312 // http://jquery.com/plugins/project/dimensions
3313 jQuery.fn.offset = function() {
3314 var left = 0, top = 0, elem = this[0], results;
3315
3316 if ( elem ) with ( jQuery.browser ) {
3317 var parent = elem.parentNode,
3318 offsetChild = elem,
3319 offsetParent = elem.offsetParent,
3320 doc = elem.ownerDocument,
3321 safari2 = safari && parseInt(version) < 522 && !/adobeair/i.test(userAgent),
3322 fixed = jQuery.css(elem, "position") == "fixed";
3323
3324 // Use getBoundingClientRect if available
3325 if ( elem.getBoundingClientRect ) {
3326 var box = elem.getBoundingClientRect();
3327
3328 // Add the document scroll offsets
3329 add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
3330 box.top + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop));
3331
3332 // IE adds the HTML element's border, by default it is medium which is 2px
3333 // IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; }
3334 // IE 7 standards mode, the border is always 2px
3335 // This border/offset is typically represented by the clientLeft and clientTop properties
3336 // However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS
3337 // Therefore this method will be off by 2px in IE while in quirksmode
3338 add( -doc.documentElement.clientLeft, -doc.documentElement.clientTop );
3339
3340 // Otherwise loop through the offsetParents and parentNodes
3341 } else {
3342
3343 // Initial element offsets
3344 add( elem.offsetLeft, elem.offsetTop );
3345
3346 // Get parent offsets
3347 while ( offsetParent ) {
3348 // Add offsetParent offsets
3349 add( offsetParent.offsetLeft, offsetParent.offsetTop );
3350
3351 // Mozilla and Safari > 2 does not include the border on offset parents
3352 // However Mozilla adds the border for table or table cells
3353 if ( mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2 )
3354 border( offsetParent );
3355
3356 // Add the document scroll offsets if position is fixed on any offsetParent
3357 if ( !fixed && jQuery.css(offsetParent, "position") == "fixed" )
3358 fixed = true;
3359
3360 // Set offsetChild to previous offsetParent unless it is the body element
3361 offsetChild = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent;
3362 // Get next offsetParent
3363 offsetParent = offsetParent.offsetParent;
3364 }
3365
3366 // Get parent scroll offsets
3367 while ( parent && parent.tagName && !/^body|html$/i.test(parent.tagName) ) {
3368 // Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug
3369 if ( !/^inline|table.*$/i.test(jQuery.css(parent, "display")) )
3370 // Subtract parent scroll offsets
3371 add( -parent.scrollLeft, -parent.scrollTop );
3372
3373 // Mozilla does not add the border for a parent that has overflow != visible
3374 if ( mozilla && jQuery.css(parent, "overflow") != "visible" )
3375 border( parent );
3376
3377 // Get next parent
3378 parent = parent.parentNode;
3379 }
3380
3381 // Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild
3382 // Mozilla doubles body offsets with a non-absolutely positioned offsetChild
3383 if ( (safari2 && (fixed || jQuery.css(offsetChild, "position") == "absolute")) ||
3384 (mozilla && jQuery.css(offsetChild, "position") != "absolute") )
3385 add( -doc.body.offsetLeft, -doc.body.offsetTop );
3386
3387 // Add the document scroll offsets if position is fixed
3388 if ( fixed )
3389 add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
3390 Math.max(doc.documentElement.scrollTop, doc.body.scrollTop));
3391 }
3392
3393 // Return an object with top and left properties
3394 results = { top: top, left: left };
3395 }
3396
3397 function border(elem) {
3398 add( jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true) );
3399 }
3400
3401 function add(l, t) {
3402 left += parseInt(l) || 0;
3403 top += parseInt(t) || 0;
3404 }
3405
3406 return results;
3407 };
3408 })();
1(function(){
2  /*
3   * jQuery 1.2.3 - New Wave Javascript
4   *
5   * Copyright (c) 2008 John Resig (jquery.com)
6   * Dual licensed under the MIT (MIT-LICENSE.txt)
7   * and GPL (GPL-LICENSE.txt) licenses.
8   *
9   * $Date: 2008-02-06 00:21:25 -0500 (Wed, 06 Feb 2008) $
10   * $Rev: 4663 $
11   */
12  
13  // Map over jQuery in case of overwrite
14  if ( window.jQuery )
15          var _jQuery = window.jQuery;
16  
17  var jQuery = window.jQuery = function( selector, context ) {
18          // The jQuery object is actually just the init constructor 'enhanced'
19          return new jQuery.prototype.init( selector, context );
20  };
21  
22  // Map over the $ in case of overwrite
23  if ( window.$ )
24          var _$ = window.$;
25         
26  // Map the jQuery namespace to the '$' one
27  window.$ = jQuery;
28  
29  // A simple way to check for HTML strings or ID strings
30  // (both of which we optimize for)
31  var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;
32  
33  // Is it a simple selector
34  var isSimple = /^.[^:#\[\.]*$/;
35  
36  jQuery.fn = jQuery.prototype = {
37          init: function( selector, context ) {
38                  // Make sure that a selection was provided
39                  selector = selector || document;
40  
41                  // Handle $(DOMElement)
42                  if ( selector.nodeType ) {
43                          this[0] = selector;
44                          this.length = 1;
45                          return this;
46  
47                  // Handle HTML strings
48                  } else if ( typeof selector == "string" ) {
49                          // Are we dealing with HTML string or an ID?
50                          var match = quickExpr.exec( selector );
51  
52                          // Verify a match, and that no context was specified for #id
53                          if ( match && (match[1] || !context) ) {
54  
55                                  // HANDLE: $(html) -> $(array)
56                                  if ( match[1] )
57                                          selector = jQuery.clean( [ match[1] ], context );
58  
59                                  // HANDLE: $("#id")
60                                  else {
61                                          var elem = document.getElementById( match[3] );
62  
63                                          // Make sure an element was located
64                                          if ( elem )
65                                                  // Handle the case where IE and Opera return items
66                                                  // by name instead of ID
67                                                  if ( elem.id != match[3] )
68                                                          return jQuery().find( selector );
69  
70                                                  // Otherwise, we inject the element directly into the jQuery object
71                                                  else {
72                                                          this[0] = elem;
73                                                          this.length = 1;
74                                                          return this;
75                                                  }
76  
77                                          else
78                                                  selector = [];
79                                  }
80  
81                          // HANDLE: $(expr, [context])
82                          // (which is just equivalent to: $(content).find(expr)
83                          } else
84                                  return new jQuery( context ).find( selector );
85  
86                  // HANDLE: $(function)
87                  // Shortcut for document ready
88                  } else if ( jQuery.isFunction( selector ) )
89                          return new jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector );
90  
91                  return this.setArray(
92                          // HANDLE: $(array)
93                          selector.constructor == Array && selector ||
94  
95                          // HANDLE: $(arraylike)
96                          // Watch for when an array-like object, contains DOM nodes, is passed in as the selector
97                          (selector.jquery || selector.length && selector != window && !selector.nodeType && selector[0] != undefined && selector[0].nodeType) && jQuery.makeArray( selector ) ||
98  
99                          // HANDLE: $(*)
100                          [ selector ] );
101          },
102         
103          // The current version of jQuery being used
104          jquery: "1.2.3",
105  
106          // The number of elements contained in the matched element set
107          size: function() {
108                  return this.length;
109          },
110         
111          // The number of elements contained in the matched element set
112          length: 0,
113  
114          // Get the Nth element in the matched element set OR
115          // Get the whole matched element set as a clean array
116          get: function( num ) {
117                  return num == undefined ?
118  
119                          // Return a 'clean' array
120                          jQuery.makeArray( this ) :
121  
122                          // Return just the object
123                          this[ num ];
124          },
125         
126          // Take an array of elements and push it onto the stack
127          // (returning the new matched element set)
128          pushStack: function( elems ) {
129                  // Build a new jQuery matched element set
130                  var ret = jQuery( elems );
131  
132                  // Add the old object onto the stack (as a reference)
133                  ret.prevObject = this;
134  
135                  // Return the newly-formed element set
136                  return ret;
137          },
138         
139          // Force the current matched set of elements to become
140          // the specified array of elements (destroying the stack in the process)
141          // You should use pushStack() in order to do this, but maintain the stack
142          setArray: function( elems ) {
143                  // Resetting the length to 0, then using the native Array push
144                  // is a super-fast way to populate an object with array-like properties
145                  this.length = 0;
146                  Array.prototype.push.apply( this, elems );
147                 
148                  return this;
149          },
150  
151          // Execute a callback for every element in the matched set.
152          // (You can seed the arguments with an array of args, but this is
153          // only used internally.)
154          each: function( callback, args ) {
155                  return jQuery.each( this, callback, args );
156          },
157  
158          // Determine the position of an element within
159          // the matched set of elements
160          index: function( elem ) {
161                  var ret = -1;
162  
163                  // Locate the position of the desired element
164                  this.each(function(i){
165                          if ( this == elem )
166                                  ret = i;
167                  });
168  
169                  return ret;
170          },
171  
172          attr: function( name, value, type ) {
173                  var options = name;
174                 
175                  // Look for the case where we're accessing a style value
176                  if ( name.constructor == String )
177                          if ( value == undefined )
178                                  return this.length && jQuery[ type || "attr" ]( this[0], name ) || undefined;
179  
180                          else {
181                                  options = {};
182                                  options[ name ] = value;
183                          }
184                 
185                  // Check to see if we're setting style values
186                  return this.each(function(i){
187                          // Set all the styles
188                          for ( name in options )
189                                  jQuery.attr(
190                                          type ?
191                                                  this.style :
192                                                  this,
193                                          name, jQuery.prop( this, options[ name ], type, i, name )
194                                  );
195                  });
196          },
197  
198          css: function( key, value ) {
199                  // ignore negative width and height values
200                  if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
201                          value = undefined;
202                  return this.attr( key, value, "curCSS" );
203          },
204  
205          text: function( text ) {
206                  if ( typeof text != "object" && text != null )
207                          return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
208  
209                  var ret = "";
210  
211                  jQuery.each( text || this, function(){
212                          jQuery.each( this.childNodes, function(){
213                                  if ( this.nodeType != 8 )
214                                          ret += this.nodeType != 1 ?
215                                                  this.nodeValue :
216                                                  jQuery.fn.text( [ this ] );
217                          });
218                  });
219  
220                  return ret;
221          },
222  
223          wrapAll: function( html ) {
224                  if ( this[0] )
225                          // The elements to wrap the target around
226                          jQuery( html, this[0].ownerDocument )
227                                  .clone()
228                                  .insertBefore( this[0] )
229                                  .map(function(){
230                                          var elem = this;
231  
232                                          while ( elem.firstChild )
233                                                  elem = elem.firstChild;
234  
235                                          return elem;
236                                  })
237                                  .append(this);
238  
239                  return this;
240          },
241  
242          wrapInner: function( html ) {
243                  return this.each(function(){
244                          jQuery( this ).contents().wrapAll( html );
245                  });
246          },
247  
248          wrap: function( html ) {
249                  return this.each(function(){
250                          jQuery( this ).wrapAll( html );
251                  });
252          },
253  
254          append: function() {
255                  return this.domManip(arguments, true, false, function(elem){
256                          if (this.nodeType == 1)
257                                  this.appendChild( elem );
258                  });
259          },
260  
261          prepend: function() {
262                  return this.domManip(arguments, true, true, function(elem){
263                          if (this.nodeType == 1)
264                                  this.insertBefore( elem, this.firstChild );
265                  });
266          },
267         
268          before: function() {
269                  return this.domManip(arguments, false, false, function(elem){
270                          this.parentNode.insertBefore( elem, this );
271                  });
272          },
273  
274          after: function() {
275                  return this.domManip(arguments, false, true, function(elem){
276                          this.parentNode.insertBefore( elem, this.nextSibling );
277                  });
278          },
279  
280          end: function() {
281                  return this.prevObject || jQuery( [] );
282          },
283  
284          find: function( selector ) {
285                  var elems = jQuery.map(this, function(elem){
286                          return jQuery.find( selector, elem );
287                  });
288  
289                  return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ?
290                          jQuery.unique( elems ) :
291                          elems );
292          },
293  
294          clone: function( events ) {
295                  // Do the clone
296                  var ret = this.map(function(){
297                          if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) {
298                                  // IE copies events bound via attachEvent when
299                                  // using cloneNode. Calling detachEvent on the
300                                  // clone will also remove the events from the orignal
301                                  // In order to get around this, we use innerHTML.
302                                  // Unfortunately, this means some modifications to
303                                  // attributes in IE that are actually only stored
304                                  // as properties will not be copied (such as the
305                                  // the name attribute on an input).
306                                  var clone = this.cloneNode(true),
307                                          container = document.createElement("div");
308                                  container.appendChild(clone);
309                                  return jQuery.clean([container.innerHTML])[0];
310                          } else
311                                  return this.cloneNode(true);
312                  });
313  
314                  // Need to set the expando to null on the cloned set if it exists
315                  // removeData doesn't work here, IE removes it from the original as well
316                  // this is primarily for IE but the data expando shouldn't be copied over in any browser
317                  var clone = ret.find("*").andSelf().each(function(){
318                          if ( this[ expando ] != undefined )
319                                  this[ expando ] = null;
320                  });
321                 
322                  // Copy the events from the original to the clone
323                  if ( events === true )
324                          this.find("*").andSelf().each(function(i){
325                                  if (this.nodeType == 3)
326                                          return;
327                                  var events = jQuery.data( this, "events" );
328  
329                                  for ( var type in events )
330                                          for ( var handler in events[ type ] )
331                                                  jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );
332                          });
333  
334                  // Return the cloned set
335                  return ret;
336          },
337  
338          filter: function( selector ) {
339                  return this.pushStack(
340                          jQuery.isFunction( selector ) &&
341                          jQuery.grep(this, function(elem, i){
342                                  return selector.call( elem, i );
343                          }) ||
344  
345                          jQuery.multiFilter( selector, this ) );
346          },
347  
348          not: function( selector ) {
349                  if ( selector.constructor == String )
350                          // test special case where just one selector is passed in
351                          if ( isSimple.test( selector ) )
352                                  return this.pushStack( jQuery.multiFilter( selector, this, true ) );
353                          else
354                                  selector = jQuery.multiFilter( selector, this );
355  
356                  var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
357                  return this.filter(function() {
358                          return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
359                  });
360          },
361  
362          add: function( selector ) {
363                  return !selector ? this : this.pushStack( jQuery.merge( 
364                          this.get(),
365                          selector.constructor == String ? 
366                                  jQuery( selector ).get() :
367                                  selector.length != undefined && (!selector.nodeName || jQuery.nodeName(selector, "form")) ?
368                                          selector : [selector] ) );
369          },
370  
371          is: function( selector ) {
372                  return selector ?
373                          jQuery.multiFilter( selector, this ).length > 0 :
374                          false;
375          },
376  
377          hasClass: function( selector ) {
378                  return this.is( "." + selector );
379          },
380         
381          val: function( value ) {
382                  if ( value == undefined ) {
383  
384                          if ( this.length ) {
385                                  var elem = this[0];
386  
387                                  // We need to handle select boxes special
388                                  if ( jQuery.nodeName( elem, "select" ) ) {
389                                          var index = elem.selectedIndex,
390                                                  values = [],
391                                                  options = elem.options,
392                                                  one = elem.type == "select-one";
393                                         
394                                          // Nothing was selected
395                                          if ( index < 0 )
396                                                  return null;
397  
398                                          // Loop through all the selected options
399                                          for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
400                                                  var option = options[ i ];
401  
402                                                  if ( option.selected ) {
403                                                          // Get the specifc value for the option
404                                                          value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value;
405                                                         
406                                                          // We don't need an array for one selects
407                                                          if ( one )
408                                                                  return value;
409                                                         
410                                                          // Multi-Selects return an array
411                                                          values.push( value );
412                                                  }
413                                          }
414                                         
415                                          return values;
416                                         
417                                  // Everything else, we just grab the value
418                                  } else
419                                          return (this[0].value || "").replace(/\r/g, "");
420  
421                          }
422  
423                          return undefined;
424                  }
425  
426                  return this.each(function(){
427                          if ( this.nodeType != 1 )
428                                  return;
429  
430                          if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )
431                                  this.checked = (jQuery.inArray(this.value, value) >= 0 ||
432                                          jQuery.inArray(this.name, value) >= 0);
433  
434                          else if ( jQuery.nodeName( this, "select" ) ) {
435                                  var values = value.constructor == Array ?
436                                          value :
437                                          [ value ];
438  
439                                  jQuery( "option", this ).each(function(){
440                                          this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
441                                                  jQuery.inArray( this.text, values ) >= 0);
442                                  });
443  
444                                  if ( !values.length )
445                                          this.selectedIndex = -1;
446  
447                          } else
448                                  this.value = value;
449                  });
450          },
451         
452          html: function( value ) {
453                  return value == undefined ?
454                          (this.length ?
455                                  this[0].innerHTML :
456                                  null) :
457                          this.empty().append( value );
458          },
459  
460          replaceWith: function( value ) {
461                  return this.after( value ).remove();
462          },
463  
464          eq: function( i ) {
465                  return this.slice( i, i + 1 );
466          },
467  
468          slice: function() {
469                  return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
470          },
471  
472          map: function( callback ) {
473                  return this.pushStack( jQuery.map(this, function(elem, i){
474                          return callback.call( elem, i, elem );
475                  }));
476          },
477  
478          andSelf: function() {
479                  return this.add( this.prevObject );
480          },
481  
482          data: function( key, value ){
483                  var parts = key.split(".");
484                  parts[1] = parts[1] ? "." + parts[1] : "";
485  
486                  if ( value == null ) {
487                          var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
488                         
489                          if ( data == undefined && this.length )
490                                  data = jQuery.data( this[0], key );
491  
492                          return data == null && parts[1] ?
493                                  this.data( parts[0] ) :
494                                  data;
495                  } else
496                          return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
497                                  jQuery.data( this, key, value );
498                          });
499          },
500  
501          removeData: function( key ){
502                  return this.each(function(){
503                          jQuery.removeData( this, key );
504                  });
505          },
506         
507          domManip: function( args, table, reverse, callback ) {
508                  var clone = this.length > 1, elems; 
509  
510                  return this.each(function(){
511                          if ( !elems ) {
512                                  elems = jQuery.clean( args, this.ownerDocument );
513  
514                                  if ( reverse )
515                                          elems.reverse();
516                          }
517  
518                          var obj = this;
519  
520                          if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) )
521                                  obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") );
522  
523                          var scripts = jQuery( [] );
524  
525                          jQuery.each(elems, function(){
526                                  var elem = clone ?
527                                          jQuery( this ).clone( true )[0] :
528                                          this;
529  
530                                  // execute all scripts after the elements have been injected
531                                  if ( jQuery.nodeName( elem, "script" ) ) {
532                                          scripts = scripts.add( elem );
533                                  } else {
534                                          // Remove any inner scripts for later evaluation
535                                          if ( elem.nodeType == 1 )
536                                                  scripts = scripts.add( jQuery( "script", elem ).remove() );
537  
538                                          // Inject the elements into the document
539                                          callback.call( obj, elem );
540                                  }
541                          });
542  
543                          scripts.each( evalScript );
544                  });
545          }
546  };
547  
548  // Give the init function the jQuery prototype for later instantiation
549  jQuery.prototype.init.prototype = jQuery.prototype;
550  
551  function evalScript( i, elem ) {
552          if ( elem.src )
553                  jQuery.ajax({
554                          url: elem.src,
555                          async: false,
556                          dataType: "script"
557                  });
558  
559          else
560                  jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
561  
562          if ( elem.parentNode )
563                  elem.parentNode.removeChild( elem );
564  }
565  
566  jQuery.extend = jQuery.fn.extend = function() {
567          // copy reference to target object
568          var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
569  
570          // Handle a deep copy situation
571          if ( target.constructor == Boolean ) {
572                  deep = target;
573                  target = arguments[1] || {};
574                  // skip the boolean and the target
575                  i = 2;
576          }
577  
578          // Handle case when target is a string or something (possible in deep copy)
579          if ( typeof target != "object" && typeof target != "function" )
580                  target = {};
581  
582          // extend jQuery itself if only one argument is passed
583          if ( length == 1 ) {
584                  target = this;
585                  i = 0;
586          }
587  
588          for ( ; i < length; i++ )
589                  // Only deal with non-null/undefined values
590                  if ( (options = arguments[ i ]) != null )
591                          // Extend the base object
592                          for ( var name in options ) {
593                                  // Prevent never-ending loop
594                                  if ( target === options[ name ] )
595                                          continue;
596  
597                                  // Recurse if we're merging object values
598                                  if ( deep && options[ name ] && typeof options[ name ] == "object" && target[ name ] && !options[ name ].nodeType )
599                                          target[ name ] = jQuery.extend( target[ name ], options[ name ] );
600  
601                                  // Don't bring in undefined values
602                                  else if ( options[ name ] != undefined )
603                                          target[ name ] = options[ name ];
604  
605                          }
606  
607          // Return the modified object
608          return target;
609  };
610  
611  var expando = "jQuery" + (new Date()).getTime(), uuid = 0, windowData = {};
612  
613  // exclude the following css properties to add px
614  var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i;
615  
616  jQuery.extend({
617          noConflict: function( deep ) {
618                  window.$ = _$;
619  
620                  if ( deep )
621                          window.jQuery = _jQuery;
622  
623                  return jQuery;
624          },
625  
626          // See test/unit/core.js for details concerning this function.
627          isFunction: function( fn ) {
628                  return !!fn && typeof fn != "string" && !fn.nodeName && 
629                          fn.constructor != Array && /function/i.test( fn + "" );
630          },
631         
632          // check if an element is in a (or is an) XML document
633          isXMLDoc: function( elem ) {
634                  return elem.documentElement && !elem.body ||
635                          elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
636          },
637  
638          // Evalulates a script in a global context
639          globalEval: function( data ) {
640                  data = jQuery.trim( data );
641  
642                  if ( data ) {
643                          // Inspired by code by Andrea Giammarchi
644                          // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
645                          var head = document.getElementsByTagName("head")[0] || document.documentElement,
646                                  script = document.createElement("script");
647  
648                          script.type = "text/javascript";
649                          if ( jQuery.browser.msie )
650                                  script.text = data;
651                          else
652                                  script.appendChild( document.createTextNode( data ) );
653  
654                          head.appendChild( script );
655                          head.removeChild( script );
656                  }
657          },
658  
659          nodeName: function( elem, name ) {
660                  return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
661          },
662         
663          cache: {},
664         
665          data: function( elem, name, data ) {
666                  elem = elem == window ?
667                          windowData :
668                          elem;
669  
670                  var id = elem[ expando ];
671  
672                  // Compute a unique ID for the element
673                  if ( !id ) 
674                          id = elem[ expando ] = ++uuid;
675  
676                  // Only generate the data cache if we're
677                  // trying to access or manipulate it
678                  if ( name && !jQuery.cache[ id ] )
679                          jQuery.cache[ id ] = {};
680                 
681                  // Prevent overriding the named cache with undefined values
682                  if ( data != undefined )
683                          jQuery.cache[ id ][ name ] = data;
684                 
685                  // Return the named cache data, or the ID for the element       
686                  return name ?
687                          jQuery.cache[ id ][ name ] :
688                          id;
689          },
690         
691          removeData: function( elem, name ) {
692                  elem = elem == window ?
693                          windowData :
694                          elem;
695  
696                  var id = elem[ expando ];
697  
698                  // If we want to remove a specific section of the element's data
699                  if ( name ) {
700                          if ( jQuery.cache[ id ] ) {
701                                  // Remove the section of cache data
702                                  delete jQuery.cache[ id ][ name ];
703  
704                                  // If we've removed all the data, remove the element's cache
705                                  name = "";
706  
707                                  for ( name in jQuery.cache[ id ] )
708                                          break;
709  
710                                  if ( !name )
711                                          jQuery.removeData( elem );
712                          }
713  
714                  // Otherwise, we want to remove all of the element's data
715                  } else {
716                          // Clean up the element expando
717                          try {
718                                  delete elem[ expando ];
719                          } catch(e){
720                                  // IE has trouble directly removing the expando
721                                  // but it's ok with using removeAttribute
722                                  if ( elem.removeAttribute )
723                                          elem.removeAttribute( expando );
724                          }
725  
726                          // Completely remove the data cache
727                          delete jQuery.cache[ id ];
728                  }
729          },
730  
731          // args is for internal usage only
732          each: function( object, callback, args ) {
733                  if ( args ) {
734                          if ( object.length == undefined ) {
735                                  for ( var name in object )
736                                          if ( callback.apply( object[ name ], args ) === false )
737                                                  break;
738                          } else
739                                  for ( var i = 0, length = object.length; i < length; i++ )
740                                          if ( callback.apply( object[ i ], args ) === false )
741                                                  break;
742  
743                  // A special, fast, case for the most common use of each
744                  } else {
745                          if ( object.length == undefined ) {
746                                  for ( var name in object )
747                                          if ( callback.call( object[ name ], name, object[ name ] ) === false )
748                                                  break;
749                          } else
750                                  for ( var i = 0, length = object.length, value = object[0]; 
751                                          i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
752                  }
753  
754                  return object;
755          },
756         
757          prop: function( elem, value, type, i, name ) {
758                          // Handle executable functions
759                          if ( jQuery.isFunction( value ) )
760                                  value = value.call( elem, i );
761                                 
762                          // Handle passing in a number to a CSS property
763                          return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ?
764                                  value + "px" :
765                                  value;
766          },
767  
768          className: {
769                  // internal only, use addClass("class")
770                  add: function( elem, classNames ) {
771                          jQuery.each((classNames || "").split(/\s+/), function(i, className){
772                                  if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
773                                          elem.className += (elem.className ? " " : "") + className;
774                          });
775                  },
776  
777                  // internal only, use removeClass("class")
778                  remove: function( elem, classNames ) {
779                          if (elem.nodeType == 1)
780                                  elem.className = classNames != undefined ?
781                                          jQuery.grep(elem.className.split(/\s+/), function(className){
782                                                  return !jQuery.className.has( classNames, className ); 
783                                          }).join(" ") :
784                                          "";
785                  },
786  
787                  // internal only, use is(".class")
788                  has: function( elem, className ) {
789                          return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
790                  }
791          },
792  
793          // A method for quickly swapping in/out CSS properties to get correct calculations
794          swap: function( elem, options, callback ) {
795                  var old = {};
796                  // Remember the old values, and insert the new ones
797                  for ( var name in options ) {
798                          old[ name ] = elem.style[ name ];
799                          elem.style[ name ] = options[ name ];
800                  }
801  
802                  callback.call( elem );
803  
804                  // Revert the old values
805                  for ( var name in options )
806                          elem.style[ name ] = old[ name ];
807          },
808  
809          css: function( elem, name, force ) {
810                  if ( name == "width" || name == "height" ) {
811                          var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
812                 
813                          function getWH() {
814                                  val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
815                                  var padding = 0, border = 0;
816                                  jQuery.each( which, function() {
817                                          padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
818                                          border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
819                                  });
820                                  val -= Math.round(padding + border);
821                          }
822                 
823                          if ( jQuery(elem).is(":visible") )
824                                  getWH();
825                          else
826                                  jQuery.swap( elem, props, getWH );
827                         
828                          return Math.max(0, val);
829                  }
830                 
831                  return jQuery.curCSS( elem, name, force );
832          },
833  
834          curCSS: function( elem, name, force ) {
835                  var ret;
836  
837                  // A helper method for determining if an element's values are broken
838                  function color( elem ) {
839                          if ( !jQuery.browser.safari )
840                                  return false;
841  
842                          var ret = document.defaultView.getComputedStyle( elem, null );
843                          return !ret || ret.getPropertyValue("color") == "";
844                  }
845  
846                  // We need to handle opacity special in IE
847                  if ( name == "opacity" && jQuery.browser.msie ) {
848                          ret = jQuery.attr( elem.style, "opacity" );
849  
850                          return ret == "" ?
851                                  "1" :
852                                  ret;
853                  }
854                  // Opera sometimes will give the wrong display answer, this fixes it, see #2037
855                  if ( jQuery.browser.opera && name == "display" ) {
856                          var save = elem.style.outline;
857                          elem.style.outline = "0 solid black";
858                          elem.style.outline = save;
859                  }
860                 
861                  // Make sure we're using the right name for getting the float value
862                  if ( name.match( /float/i ) )
863                          name = styleFloat;
864  
865                  if ( !force && elem.style && elem.style[ name ] )
866                          ret = elem.style[ name ];
867  
868                  else if ( document.defaultView && document.defaultView.getComputedStyle ) {
869  
870                          // Only "float" is needed here
871                          if ( name.match( /float/i ) )
872                                  name = "float";
873  
874                          name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
875  
876                          var getComputedStyle = document.defaultView.getComputedStyle( elem, null );
877  
878                          if ( getComputedStyle && !color( elem ) )
879                                  ret = getComputedStyle.getPropertyValue( name );
880  
881                          // If the element isn't reporting its values properly in Safari
882                          // then some display: none elements are involved
883                          else {
884                                  var swap = [], stack = [];
885  
886                                  // Locate all of the parent display: none elements
887                                  for ( var a = elem; a && color(a); a = a.parentNode )
888                                          stack.unshift(a);
889  
890                                  // Go through and make them visible, but in reverse
891                                  // (It would be better if we knew the exact display type that they had)
892                                  for ( var i = 0; i < stack.length; i++ )
893                                          if ( color( stack[ i ] ) ) {
894                                                  swap[ i ] = stack[ i ].style.display;
895                                                  stack[ i ].style.display = "block";
896                                          }
897  
898                                  // Since we flip the display style, we have to handle that
899                                  // one special, otherwise get the value
900                                  ret = name == "display" && swap[ stack.length - 1 ] != null ?
901                                          "none" :
902                                          ( getComputedStyle && getComputedStyle.getPropertyValue( name ) ) || "";
903  
904                                  // Finally, revert the display styles back
905                                  for ( var i = 0; i < swap.length; i++ )
906                                          if ( swap[ i ] != null )
907                                                  stack[ i ].style.display = swap[ i ];
908                          }
909  
910                          // We should always get a number back from opacity
911                          if ( name == "opacity" && ret == "" )
912                                  ret = "1";
913  
914                  } else if ( elem.currentStyle ) {
915                          var camelCase = name.replace(/\-(\w)/g, function(all, letter){
916                                  return letter.toUpperCase();
917                          });
918  
919                          ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
920  
921                          // From the awesome hack by Dean Edwards
922                          // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
923  
924                          // If we're not dealing with a regular pixel number
925                          // but a number that has a weird ending, we need to convert it to pixels
926                          if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
927                                  // Remember the original values
928                                  var style = elem.style.left, runtimeStyle = elem.runtimeStyle.left;
929  
930                                  // Put in the new values to get a computed value out
931                                  elem.runtimeStyle.left = elem.currentStyle.left;
932                                  elem.style.left = ret || 0;
933                                  ret = elem.style.pixelLeft + "px";
934  
935                                  // Revert the changed values
936                                  elem.style.left = style;
937                                  elem.runtimeStyle.left = runtimeStyle;
938                          }
939                  }
940  
941                  return ret;
942          },
943         
944          clean: function( elems, context ) {
945                  var ret = [];
946                  context = context || document;
947                  // !context.createElement fails in IE with an error but returns typeof 'object'
948                  if (typeof context.createElement == 'undefined') 
949                          context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
950  
951                  jQuery.each(elems, function(i, elem){
952                          if ( !elem )
953                                  return;
954  
955                          if ( elem.constructor == Number )
956                                  elem = elem.toString();
957                         
958                          // Convert html string into DOM nodes
959                          if ( typeof elem == "string" ) {
960                                  // Fix "XHTML"-style tags in all browsers
961                                  elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
962                                          return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
963                                                  all :
964                                                  front + "></" + tag + ">";
965                                  });
966  
967                                  // Trim whitespace, otherwise indexOf won't work as expected
968                                  var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div");
969  
970                                  var wrap =
971                                          // option or optgroup
972                                          !tags.indexOf("<opt") &&
973                                          [ 1, "<select multiple='multiple'>", "</select>" ] ||
974                                         
975                                          !tags.indexOf("<leg") &&
976                                          [ 1, "<fieldset>", "</fieldset>" ] ||
977                                         
978                                          tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
979                                          [ 1, "<table>", "</table>" ] ||
980                                         
981                                          !tags.indexOf("<tr") &&
982                                          [ 2, "<table><tbody>", "</tbody></table>" ] ||
983                                         
984                                          // <thead> matched above
985                                          (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
986                                          [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
987                                         
988                                          !tags.indexOf("<col") &&
989                                          [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
990  
991                                          // IE can't serialize <link> and <script> tags normally
992                                          jQuery.browser.msie &&
993                                          [ 1, "div<div>", "</div>" ] ||
994                                         
995                                          [ 0, "", "" ];
996  
997                                  // Go to html and back, then peel off extra wrappers
998                                  div.innerHTML = wrap[1] + elem + wrap[2];
999                                 
1000                                  // Move to the right depth
1001                                  while ( wrap[0]-- )
1002                                          div = div.lastChild;
1003                                 
1004                                  // Remove IE's autoinserted <tbody> from table fragments
1005                                  if ( jQuery.browser.msie ) {
1006                                         
1007                                          // String was a <table>, *may* have spurious <tbody>
1008                                          var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ?
1009                                                  div.firstChild && div.firstChild.childNodes :
1010                                                 
1011                                                  // String was a bare <thead> or <tfoot>
1012                                                  wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ?
1013                                                          div.childNodes :
1014                                                          [];
1015                                 
1016                                          for ( var j = tbody.length - 1; j >= 0 ; --j )
1017                                                  if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
1018                                                          tbody[ j ].parentNode.removeChild( tbody[ j ] );
1019                                         
1020                                          // IE completely kills leading whitespace when innerHTML is used       
1021                                          if ( /^\s/.test( elem ) )       
1022                                                  div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
1023                                 
1024                                  }
1025                                 
1026                                  elem = jQuery.makeArray( div.childNodes );
1027                          }
1028  
1029                          if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) )
1030                                  return;
1031  
1032                          if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options )
1033                                  ret.push( elem );
1034  
1035                          else
1036                                  ret = jQuery.merge( ret, elem );
1037  
1038                  });
1039  
1040                  return ret;
1041          },
1042         
1043          attr: function( elem, name, value ) {
1044                  // don't set attributes on text and comment nodes
1045                  if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
1046                          return undefined;
1047  
1048                  var fix = jQuery.isXMLDoc( elem ) ?
1049                          {} :
1050                          jQuery.props;
1051  
1052                  // Safari mis-reports the default selected property of a hidden option
1053                  // Accessing the parent's selectedIndex property fixes it
1054                  if ( name == "selected" && jQuery.browser.safari )
1055                          elem.parentNode.selectedIndex;
1056                 
1057                  // Certain attributes only work when accessed via the old DOM 0 way
1058                  if ( fix[ name ] ) {
1059                          if ( value != undefined )
1060                                  elem[ fix[ name ] ] = value;
1061  
1062                          return elem[ fix[ name ] ];
1063  
1064                  } else if ( jQuery.browser.msie && name == "style" )
1065                          return jQuery.attr( elem.style, "cssText", value );
1066  
1067                  else if ( value == undefined && jQuery.browser.msie && jQuery.nodeName( elem, "form" ) && (name == "action" || name == "method") )
1068                          return elem.getAttributeNode( name ).nodeValue;
1069  
1070                  // IE elem.getAttribute passes even for style
1071                  else if ( elem.tagName ) {
1072  
1073                          if ( value != undefined ) {
1074                                  // We can't allow the type property to be changed (since it causes problems in IE)
1075                                  if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
1076                                          throw "type property can't be changed";
1077  
1078                                  // convert the value to a string (all browsers do this but IE) see #1070
1079                                  elem.setAttribute( name, "" + value );
1080                          }
1081  
1082                          if ( jQuery.browser.msie && /href|src/.test( name ) && !jQuery.isXMLDoc( elem ) ) 
1083                                  return elem.getAttribute( name, 2 );
1084  
1085                          return elem.getAttribute( name );
1086  
1087                  // elem is actually elem.style ... set the style
1088                  } else {
1089                          // IE actually uses filters for opacity
1090                          if ( name == "opacity" && jQuery.browser.msie ) {
1091                                  if ( value != undefined ) {
1092                                          // IE has trouble with opacity if it does not have layout
1093                                          // Force it by setting the zoom level
1094                                          elem.zoom = 1; 
1095         
1096                                          // Set the alpha filter to set the opacity
1097                                          elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
1098                                                  (parseFloat( value ).toString() == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
1099                                  }
1100         
1101                                  return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
1102                                          (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100).toString() :
1103                                          "";
1104                          }
1105  
1106                          name = name.replace(/-([a-z])/ig, function(all, letter){
1107                                  return letter.toUpperCase();
1108                          });
1109  
1110                          if ( value != undefined )
1111                                  elem[ name ] = value;
1112  
1113                          return elem[ name ];
1114                  }
1115          },
1116         
1117          trim: function( text ) {
1118                  return (text || "").replace( /^\s+|\s+$/g, "" );
1119          },
1120  
1121          makeArray: function( array ) {
1122                  var ret = [];
1123  
1124                  // Need to use typeof to fight Safari childNodes crashes
1125                  if ( typeof array != "array" )
1126                          for ( var i = 0, length = array.length; i < length; i++ )
1127                                  ret.push( array[ i ] );
1128                  else
1129                          ret = array.slice( 0 );
1130  
1131                  return ret;
1132          },
1133  
1134          inArray: function( elem, array ) {
1135                  for ( var i = 0, length = array.length; i < length; i++ )
1136                          if ( array[ i ] == elem )
1137                                  return i;
1138  
1139                  return -1;
1140          },
1141  
1142          merge: function( first, second ) {
1143                  // We have to loop this way because IE & Opera overwrite the length
1144                  // expando of getElementsByTagName
1145  
1146                  // Also, we need to make sure that the correct elements are being returned
1147                  // (IE returns comment nodes in a '*' query)
1148                  if ( jQuery.browser.msie ) {
1149                          for ( var i = 0; second[ i ]; i++ )
1150                                  if ( second[ i ].nodeType != 8 )
1151                                          first.push( second[ i ] );
1152  
1153                  } else
1154                          for ( var i = 0; second[ i ]; i++ )
1155                                  first.push( second[ i ] );
1156  
1157                  return first;
1158          },
1159  
1160          unique: function( array ) {
1161                  var ret = [], done = {};
1162  
1163                  try {
1164  
1165                          for ( var i = 0, length = array.length; i < length; i++ ) {
1166                                  var id = jQuery.data( array[ i ] );
1167  
1168                                  if ( !done[ id ] ) {
1169                                          done[ id ] = true;
1170                                          ret.push( array[ i ] );
1171                                  }
1172                          }
1173  
1174                  } catch( e ) {
1175                          ret = array;
1176                  }
1177  
1178                  return ret;
1179          },
1180  
1181          grep: function( elems, callback, inv ) {
1182                  var ret = [];
1183  
1184                  // Go through the array, only saving the items
1185                  // that pass the validator function
1186                  for ( var i = 0, length = elems.length; i < length; i++ )
1187                          if ( !inv && callback( elems[ i ], i ) || inv && !callback( elems[ i ], i ) )
1188                                  ret.push( elems[ i ] );
1189  
1190                  return ret;
1191          },
1192  
1193          map: function( elems, callback ) {
1194                  var ret = [];
1195  
1196                  // Go through the array, translating each of the items to their
1197                  // new value (or values).
1198                  for ( var i = 0, length = elems.length; i < length; i++ ) {
1199                          var value = callback( elems[ i ], i );
1200  
1201                          if ( value !== null && value != undefined ) {
1202                                  if ( value.constructor != Array )
1203                                          value = [ value ];
1204  
1205                                  ret = ret.concat( value );
1206                          }
1207                  }
1208  
1209                  return ret;
1210          }
1211  });
1212  
1213  var userAgent = navigator.userAgent.toLowerCase();
1214  
1215  // Figure out what browser is being used
1216  jQuery.browser = {
1217          version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],
1218          safari: /webkit/.test( userAgent ),
1219          opera: /opera/.test( userAgent ),
1220          msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
1221          mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
1222  };
1223  
1224  var styleFloat = jQuery.browser.msie ?
1225          "styleFloat" :
1226          "cssFloat";
1227         
1228  jQuery.extend({
1229          // Check to see if the W3C box model is being used
1230          boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
1231         
1232          props: {
1233                  "for": "htmlFor",
1234                  "class": "className",
1235                  "float": styleFloat,
1236                  cssFloat: styleFloat,
1237                  styleFloat: styleFloat,
1238                  innerHTML: "innerHTML",
1239                  className: "className",
1240                  value: "value",
1241                  disabled: "disabled",
1242                  checked: "checked",
1243                  readonly: "readOnly",
1244                  selected: "selected",
1245                  maxlength: "maxLength",
1246                  selectedIndex: "selectedIndex",
1247                  defaultValue: "defaultValue",
1248                  tagName: "tagName",
1249                  nodeName: "nodeName"
1250          }
1251  });
1252  
1253  jQuery.each({
1254          parent: function(elem){return elem.parentNode;},
1255          parents: function(elem){return jQuery.dir(elem,"parentNode");},
1256          next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
1257          prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
1258          nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
1259          prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
1260          siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
1261          children: function(elem){return jQuery.sibling(elem.firstChild);},
1262          contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
1263  }, function(name, fn){
1264          jQuery.fn[ name ] = function( selector ) {
1265                  var ret = jQuery.map( this, fn );
1266  
1267                  if ( selector && typeof selector == "string" )
1268                          ret = jQuery.multiFilter( selector, ret );
1269  
1270                  return this.pushStack( jQuery.unique( ret ) );
1271          };
1272  });
1273  
1274  jQuery.each({
1275          appendTo: "append",
1276          prependTo: "prepend",
1277          insertBefore: "before",
1278          insertAfter: "after",
1279          replaceAll: "replaceWith"
1280  }, function(name, original){
1281          jQuery.fn[ name ] = function() {
1282                  var args = arguments;
1283  
1284                  return this.each(function(){
1285                          for ( var i = 0, length = args.length; i < length; i++ )
1286                                  jQuery( args[ i ] )[ original ]( this );
1287                  });
1288          };
1289  });
1290  
1291  jQuery.each({
1292          removeAttr: function( name ) {
1293                  jQuery.attr( this, name, "" );
1294                  if (this.nodeType == 1) 
1295                          this.removeAttribute( name );
1296          },
1297  
1298          addClass: function( classNames ) {
1299                  jQuery.className.add( this, classNames );
1300          },
1301  
1302          removeClass: function( classNames ) {
1303                  jQuery.className.remove( this, classNames );
1304          },
1305  
1306          toggleClass: function( classNames ) {
1307                  jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames );
1308          },
1309  
1310          remove: function( selector ) {
1311                  if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) {
1312                          // Prevent memory leaks
1313                          jQuery( "*", this ).add(this).each(function(){
1314                                  jQuery.event.remove(this);
1315                                  jQuery.removeData(this);
1316                          });
1317                          if (this.parentNode)
1318                                  this.parentNode.removeChild( this );
1319                  }
1320          },
1321  
1322          empty: function() {
1323                  // Remove element nodes and prevent memory leaks
1324                  jQuery( ">*", this ).remove();
1325                 
1326                  // Remove any remaining nodes
1327                  while ( this.firstChild )
1328                          this.removeChild( this.firstChild );
1329          }
1330  }, function(name, fn){
1331          jQuery.fn[ name ] = function(){
1332                  return this.each( fn, arguments );
1333          };
1334  });
1335  
1336  jQuery.each([ "Height", "Width" ], function(i, name){
1337          var type = name.toLowerCase();
1338         
1339          jQuery.fn[ type ] = function( size ) {
1340                  // Get window width or height
1341                  return this[0] == window ?
1342                          // Opera reports document.body.client[Width/Height] properly in both quirks and standards
1343                          jQuery.browser.opera && document.body[ "client" + name ] || 
1344                         
1345                          // Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths)
1346                          jQuery.browser.safari && window[ "inner" + name ] ||
1347                         
1348                          // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
1349                          document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] :
1350                 
1351                          // Get document width or height
1352                          this[0] == document ?
1353                                  // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
1354                                  Math.max( 
1355                                          Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]), 
1356                                          Math.max(document.body["offset" + name], document.documentElement["offset" + name]) 
1357                                  ) :
1358  
1359                                  // Get or set width or height on the element
1360                                  size == undefined ?
1361                                          // Get width or height on the element
1362                                          (this.length ? jQuery.css( this[0], type ) : null) :
1363  
1364                                          // Set the width or height on the element (default to pixels if value is unitless)
1365                                          this.css( type, size.constructor == String ? size : size + "px" );
1366          };
1367  });
1368  
1369  var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ?
1370                  "(?:[\\w*_-]|\\\\.)" :
1371                  "(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",
1372          quickChild = new RegExp("^>\\s*(" + chars + "+)"),
1373          quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"),
1374          quickClass = new RegExp("^([#.]?)(" + chars + "*)");
1375  
1376  jQuery.extend({
1377          expr: {
1378                  "": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},
1379                  "#": function(a,i,m){return a.getAttribute("id")==m[2];},
1380                  ":": {
1381                          // Position Checks
1382                          lt: function(a,i,m){return i<m[3]-0;},
1383                          gt: function(a,i,m){return i>m[3]-0;},
1384                          nth: function(a,i,m){return m[3]-0==i;},
1385                          eq: function(a,i,m){return m[3]-0==i;},
1386                          first: function(a,i){return i==0;},
1387                          last: function(a,i,m,r){return i==r.length-1;},
1388                          even: function(a,i){return i%2==0;},
1389                          odd: function(a,i){return i%2;},
1390  
1391                          // Child Checks
1392                          "first-child": function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},
1393                          "last-child": function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},
1394                          "only-child": function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},
1395  
1396                          // Parent Checks
1397                          parent: function(a){return a.firstChild;},
1398                          empty: function(a){return !a.firstChild;},
1399  
1400                          // Text Check
1401                          contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},
1402  
1403                          // Visibility
1404                          visible: function(a){return "hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},
1405                          hidden: function(a){return "hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},
1406  
1407                          // Form attributes
1408                          enabled: function(a){return !a.disabled;},
1409                          disabled: function(a){return a.disabled;},
1410                          checked: function(a){return a.checked;},
1411                          selected: function(a){return a.selected||jQuery.attr(a,"selected");},
1412  
1413                          // Form elements
1414                          text: function(a){return "text"==a.type;},
1415                          radio: function(a){return "radio"==a.type;},
1416                          checkbox: function(a){return "checkbox"==a.type;},
1417                          file: function(a){return "file"==a.type;},
1418                          password: function(a){return "password"==a.type;},
1419                          submit: function(a){return "submit"==a.type;},
1420                          image: function(a){return "image"==a.type;},
1421                          reset: function(a){return "reset"==a.type;},
1422                          button: function(a){return "button"==a.type||jQuery.nodeName(a,"button");},
1423                          input: function(a){return /input|select|textarea|button/i.test(a.nodeName);},
1424  
1425                          // :has()
1426                          has: function(a,i,m){return jQuery.find(m[3],a).length;},
1427  
1428                          // :header
1429                          header: function(a){return /h\d/i.test(a.nodeName);},
1430  
1431                          // :animated
1432                          animated: function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}
1433                  }
1434          },
1435         
1436          // The regular expressions that power the parsing engine
1437          parse: [
1438                  // Match: [@value='test'], [@foo]
1439                  /^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,
1440  
1441                  // Match: :contains('foo')
1442                  /^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,
1443  
1444                  // Match: :even, :last-chlid, #id, .class
1445                  new RegExp("^([:.#]*)(" + chars + "+)")
1446          ],
1447  
1448          multiFilter: function( expr, elems, not ) {
1449                  var old, cur = [];
1450  
1451                  while ( expr && expr != old ) {
1452                          old = expr;
1453                          var f = jQuery.filter( expr, elems, not );
1454                          expr = f.t.replace(/^\s*,\s*/, "" );
1455                          cur = not ? elems = f.r : jQuery.merge( cur, f.r );
1456                  }
1457  
1458                  return cur;
1459          },
1460  
1461          find: function( t, context ) {
1462                  // Quickly handle non-string expressions
1463                  if ( typeof t != "string" )
1464                          return [ t ];
1465  
1466                  // check to make sure context is a DOM element or a document
1467                  if ( context && context.nodeType != 1 && context.nodeType != 9)
1468                          return [ ];
1469  
1470                  // Set the correct context (if none is provided)
1471                  context = context || document;
1472  
1473                  // Initialize the search
1474                  var ret = [context], done = [], last, nodeName;
1475  
1476                  // Continue while a selector expression exists, and while
1477                  // we're no longer looping upon ourselves
1478                  while ( t && last != t ) {
1479                          var r = [];
1480                          last = t;
1481  
1482                          t = jQuery.trim(t);
1483  
1484                          var foundToken = false;
1485  
1486                          // An attempt at speeding up child selectors that
1487                          // point to a specific element tag
1488                          var re = quickChild;
1489                          var m = re.exec(t);
1490  
1491                          if ( m ) {
1492                                  nodeName = m[1].toUpperCase();
1493  
1494                                  // Perform our own iteration and filter
1495                                  for ( var i = 0; ret[i]; i++ )
1496                                          for ( var c = ret[i].firstChild; c; c = c.nextSibling )
1497                                                  if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) )
1498                                                          r.push( c );
1499  
1500                                  ret = r;
1501                                  t = t.replace( re, "" );
1502                                  if ( t.indexOf(" ") == 0 ) continue;
1503                                  foundToken = true;
1504                          } else {
1505                                  re = /^([>+~])\s*(\w*)/i;
1506  
1507                                  if ( (m = re.exec(t)) != null ) {
1508                                          r = [];
1509  
1510                                          var merge = {};
1511                                          nodeName = m[2].toUpperCase();
1512                                          m = m[1];
1513  
1514                                          for ( var j = 0, rl = ret.length; j < rl; j++ ) {
1515                                                  var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild;
1516                                                  for ( ; n; n = n.nextSibling )
1517                                                          if ( n.nodeType == 1 ) {
1518                                                                  var id = jQuery.data(n);
1519  
1520                                                                  if ( m == "~" && merge[id] ) break;
1521                                                                 
1522                                                                  if (!nodeName || n.nodeName.toUpperCase() == nodeName ) {
1523                                                                          if ( m == "~" ) merge[id] = true;
1524                                                                          r.push( n );
1525                                                                  }
1526                                                                 
1527                                                                  if ( m == "+" ) break;
1528                                                          }
1529                                          }
1530  
1531                                          ret = r;
1532  
1533                                          // And remove the token
1534                                          t = jQuery.trim( t.replace( re, "" ) );
1535                                          foundToken = true;
1536                                  }
1537                          }
1538  
1539                          // See if there's still an expression, and that we haven't already
1540                          // matched a token
1541                          if ( t && !foundToken ) {
1542                                  // Handle multiple expressions
1543                                  if ( !t.indexOf(",") ) {
1544                                          // Clean the result set
1545                                          if ( context == ret[0] ) ret.shift();
1546  
1547                                          // Merge the result sets
1548                                          done = jQuery.merge( done, ret );
1549  
1550                                          // Reset the context
1551                                          r = ret = [context];
1552  
1553                                          // Touch up the selector string
1554                                          t = " " + t.substr(1,t.length);
1555  
1556                                  } else {
1557                                          // Optimize for the case nodeName#idName
1558                                          var re2 = quickID;
1559                                          var m = re2.exec(t);
1560                                         
1561                                          // Re-organize the results, so that they're consistent
1562                                          if ( m ) {
1563                                                  m = [ 0, m[2], m[3], m[1] ];
1564  
1565                                          } else {
1566                                                  // Otherwise, do a traditional filter check for
1567                                                  // ID, class, and element selectors
1568                                                  re2 = quickClass;
1569                                                  m = re2.exec(t);
1570                                          }
1571  
1572                                          m[2] = m[2].replace(/\\/g, "");
1573  
1574                                          var elem = ret[ret.length-1];
1575  
1576                                          // Try to do a global search by ID, where we can
1577                                          if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) {
1578                                                  // Optimization for HTML document case
1579                                                  var oid = elem.getElementById(m[2]);
1580                                                 
1581                                                  // Do a quick check for the existence of the actual ID attribute
1582                                                  // to avoid selecting by the name attribute in IE
1583                                                  // also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form
1584                                                  if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] )
1585                                                          oid = jQuery('[@id="'+m[2]+'"]', elem)[0];
1586  
1587                                                  // Do a quick check for node name (where applicable) so
1588                                                  // that div#foo searches will be really fast
1589                                                  ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : [];
1590                                          } else {
1591                                                  // We need to find all descendant elements
1592                                                  for ( var i = 0; ret[i]; i++ ) {
1593                                                          // Grab the tag name being searched for
1594                                                          var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2];
1595  
1596                                                          // Handle IE7 being really dumb about <object>s
1597                                                          if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" )
1598                                                                  tag = "param";
1599  
1600                                                          r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));
1601                                                  }
1602  
1603                                                  // It's faster to filter by class and be done with it
1604                                                  if ( m[1] == "." )
1605                                                          r = jQuery.classFilter( r, m[2] );
1606  
1607                                                  // Same with ID filtering
1608                                                  if ( m[1] == "#" ) {
1609                                                          var tmp = [];
1610  
1611                                                          // Try to find the element with the ID
1612                                                          for ( var i = 0; r[i]; i++ )
1613                                                                  if ( r[i].getAttribute("id") == m[2] ) {
1614                                                                          tmp = [ r[i] ];
1615                                                                          break;
1616                                                                  }
1617  
1618                                                          r = tmp;
1619                                                  }
1620  
1621                                                  ret = r;
1622                                          }
1623  
1624                                          t = t.replace( re2, "" );
1625                                  }
1626  
1627                          }
1628  
1629                          // If a selector string still exists
1630                          if ( t ) {
1631                                  // Attempt to filter it
1632                                  var val = jQuery.filter(t,r);
1633                                  ret = r = val.r;
1634                                  t = jQuery.trim(val.t);
1635                          }
1636                  }
1637  
1638                  // An error occurred with the selector;
1639                  // just return an empty set instead
1640                  if ( t )
1641                          ret = [];
1642  
1643                  // Remove the root context
1644                  if ( ret && context == ret[0] )
1645                          ret.shift();
1646  
1647                  // And combine the results
1648                  done = jQuery.merge( done, ret );
1649  
1650                  return done;
1651          },
1652  
1653          classFilter: function(r,m,not){
1654                  m = " " + m + " ";
1655                  var tmp = [];
1656                  for ( var i = 0; r[i]; i++ ) {
1657                          var pass = (" " + r[i].className + " ").indexOf( m ) >= 0;
1658                          if ( !not && pass || not && !pass )
1659                                  tmp.push( r[i] );
1660                  }
1661                  return tmp;
1662          },
1663  
1664          filter: function(t,r,not) {
1665                  var last;
1666  
1667                  // Look for common filter expressions
1668                  while ( t && t != last ) {
1669                          last = t;
1670  
1671                          var p = jQuery.parse, m;
1672  
1673                          for ( var i = 0; p[i]; i++ ) {
1674                                  m = p[i].exec( t );
1675  
1676                                  if ( m ) {
1677                                          // Remove what we just matched
1678                                          t = t.substring( m[0].length );
1679  
1680                                          m[2] = m[2].replace(/\\/g, "");
1681                                          break;
1682                                  }
1683                          }
1684  
1685                          if ( !m )
1686                                  break;
1687  
1688                          // :not() is a special case that can be optimized by
1689                          // keeping it out of the expression list
1690                          if ( m[1] == ":" && m[2] == "not" )
1691                                  // optimize if only one selector found (most common case)
1692                                  r = isSimple.test( m[3] ) ?
1693                                          jQuery.filter(m[3], r, true).r :
1694                                          jQuery( r ).not( m[3] );
1695  
1696                          // We can get a big speed boost by filtering by class here
1697                          else if ( m[1] == "." )
1698                                  r = jQuery.classFilter(r, m[2], not);
1699  
1700                          else if ( m[1] == "[" ) {
1701                                  var tmp = [], type = m[3];
1702                                 
1703                                  for ( var i = 0, rl = r.length; i < rl; i++ ) {
1704                                          var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ];
1705                                         
1706                                          if ( z == null || /href|src|selected/.test(m[2]) )
1707                                                  z = jQuery.attr(a,m[2]) || '';
1708  
1709                                          if ( (type == "" && !!z ||
1710                                                   type == "=" && z == m[5] ||
1711                                                   type == "!=" && z != m[5] ||
1712                                                   type == "^=" && z && !z.indexOf(m[5]) ||
1713                                                   type == "$=" && z.substr(z.length - m[5].length) == m[5] ||
1714                                                   (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not )
1715                                                          tmp.push( a );
1716                                  }
1717                                 
1718                                  r = tmp;
1719  
1720                          // We can get a speed boost by handling nth-child here
1721                          } else if ( m[1] == ":" && m[2] == "nth-child" ) {
1722                                  var merge = {}, tmp = [],
1723                                          // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
1724                                          test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
1725                                                  m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||
1726                                                  !/\D/.test(m[3]) && "0n+" + m[3] || m[3]),
1727                                          // calculate the numbers (first)n+(last) including if they are negative
1728                                          first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0;
1729   
1730                                  // loop through all the elements left in the jQuery object
1731                                  for ( var i = 0, rl = r.length; i < rl; i++ ) {
1732                                          var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode);
1733  
1734                                          if ( !merge[id] ) {
1735                                                  var c = 1;
1736  
1737                                                  for ( var n = parentNode.firstChild; n; n = n.nextSibling )
1738                                                          if ( n.nodeType == 1 )
1739                                                                  n.nodeIndex = c++;
1740  
1741                                                  merge[id] = true;
1742                                          }
1743  
1744                                          var add = false;
1745  
1746                                          if ( first == 0 ) {
1747                                                  if ( node.nodeIndex == last )
1748                                                          add = true;
1749                                          } else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 )
1750                                                  add = true;
1751  
1752                                          if ( add ^ not )
1753                                                  tmp.push( node );
1754                                  }
1755  
1756                                  r = tmp;
1757  
1758                          // Otherwise, find the expression to execute
1759                          } else {
1760                                  var fn = jQuery.expr[ m[1] ];
1761                                  if ( typeof fn == "object" )
1762                                          fn = fn[ m[2] ];
1763  
1764                                  if ( typeof fn == "string" )
1765                                          fn = eval("false||function(a,i){return " + fn + ";}");
1766  
1767                                  // Execute it against the current filter
1768                                  r = jQuery.grep( r, function(elem, i){
1769                                          return fn(elem, i, m, r);
1770                                  }, not );
1771                          }
1772                  }
1773  
1774                  // Return an array of filtered elements (r)
1775                  // and the modified expression string (t)
1776                  return { r: r, t: t };
1777          },
1778  
1779          dir: function( elem, dir ){
1780                  var matched = [];
1781                  var cur = elem[dir];
1782                  while ( cur && cur != document ) {
1783                          if ( cur.nodeType == 1 )
1784                                  matched.push( cur );
1785                          cur = cur[dir];
1786                  }
1787                  return matched;
1788          },
1789         
1790          nth: function(cur,result,dir,elem){
1791                  result = result || 1;
1792                  var num = 0;
1793  
1794                  for ( ; cur; cur = cur[dir] )
1795                          if ( cur.nodeType == 1 && ++num == result )
1796                                  break;
1797  
1798                  return cur;
1799          },
1800         
1801          sibling: function( n, elem ) {
1802                  var r = [];
1803  
1804                  for ( ; n; n = n.nextSibling ) {
1805                          if ( n.nodeType == 1 && (!elem || n != elem) )
1806                                  r.push( n );
1807                  }
1808  
1809                  return r;
1810          }
1811  });
1812  
1813  /*
1814   * A number of helper functions used for managing events.
1815   * Many of the ideas behind this code orignated from
1816   * Dean Edwards' addEvent library.
1817   */
1818  jQuery.event = {
1819  
1820          // Bind an event to an element
1821          // Original by Dean Edwards
1822          add: function(elem, types, handler, data) {
1823                  if ( elem.nodeType == 3 || elem.nodeType == 8 )
1824                          return;
1825  
1826                  // For whatever reason, IE has trouble passing the window object
1827                  // around, causing it to be cloned in the process
1828                  if ( jQuery.browser.msie && elem.setInterval != undefined )
1829                          elem = window;
1830  
1831                  // Make sure that the function being executed has a unique ID
1832                  if ( !handler.guid )
1833                          handler.guid = this.guid++;
1834                         
1835                  // if data is passed, bind to handler
1836                  if( data != undefined ) { 
1837                          // Create temporary function pointer to original handler
1838                          var fn = handler; 
1839  
1840                          // Create unique handler function, wrapped around original handler
1841                          handler = function() { 
1842                                  // Pass arguments and context to original handler
1843                                  return fn.apply(this, arguments); 
1844                          };
1845  
1846                          // Store data in unique handler
1847                          handler.data = data;
1848  
1849                          // Set the guid of unique handler to the same of original handler, so it can be removed
1850                          handler.guid = fn.guid;
1851                  }
1852  
1853                  // Init the element's event structure
1854                  var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
1855                          handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
1856                                  // returned undefined or false
1857                                  var val;
1858  
1859                                  // Handle the second event of a trigger and when
1860                                  // an event is called after a page has unloaded
1861                                  if ( typeof jQuery == "undefined" || jQuery.event.triggered )
1862                                          return val;
1863                 
1864                                  val = jQuery.event.handle.apply(arguments.callee.elem, arguments);
1865                 
1866                                  return val;
1867                          });
1868                  // Add elem as a property of the handle function
1869                  // This is to prevent a memory leak with non-native
1870                  // event in IE.
1871                  handle.elem = elem;
1872                         
1873                          // Handle multiple events seperated by a space
1874                          // jQuery(...).bind("mouseover mouseout", fn);
1875                          jQuery.each(types.split(/\s+/), function(index, type) {
1876                                  // Namespaced event handlers
1877                                  var parts = type.split(".");
1878                                  type = parts[0];
1879                                  handler.type = parts[1];
1880  
1881                                  // Get the current list of functions bound to this event
1882                                  var handlers = events[type];
1883  
1884                                  // Init the event handler queue
1885                                  if (!handlers) {
1886                                          handlers = events[type] = {};
1887                 
1888                                          // Check for a special event handler
1889                                          // Only use addEventListener/attachEvent if the special
1890                                          // events handler returns false
1891                                          if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) {
1892                                                  // Bind the global event handler to the element
1893                                                  if (elem.addEventListener)
1894                                                          elem.addEventListener(type, handle, false);
1895                                                  else if (elem.attachEvent)
1896                                                          elem.attachEvent("on" + type, handle);
1897                                          }
1898                                  }
1899  
1900                                  // Add the function to the element's handler list
1901                                  handlers[handler.guid] = handler;
1902  
1903                                  // Keep track of which events have been used, for global triggering
1904                                  jQuery.event.global[type] = true;
1905                          });
1906                 
1907                  // Nullify elem to prevent memory leaks in IE
1908                  elem = null;
1909          },
1910  
1911          guid: 1,
1912          global: {},
1913  
1914          // Detach an event or set of events from an element
1915          remove: function(elem, types, handler) {
1916                  // don't do events on text and comment nodes
1917                  if ( elem.nodeType == 3 || elem.nodeType == 8 )
1918                          return;
1919  
1920                  var events = jQuery.data(elem, "events"), ret, index;
1921  
1922                  if ( events ) {
1923                          // Unbind all events for the element
1924                          if ( types == undefined || (typeof types == "string" && types.charAt(0) == ".") )
1925                                  for ( var type in events )
1926                                          this.remove( elem, type + (types || "") );
1927                          else {
1928                                  // types is actually an event object here
1929                                  if ( types.type ) {
1930                                          handler = types.handler;
1931                                          types = types.type;
1932                                  }
1933                                 
1934                                  // Handle multiple events seperated by a space
1935                                  // jQuery(...).unbind("mouseover mouseout", fn);
1936                                  jQuery.each(types.split(/\s+/), function(index, type){
1937                                          // Namespaced event handlers
1938                                          var parts = type.split(".");
1939                                          type = parts[0];
1940                                         
1941                                          if ( events[type] ) {
1942                                                  // remove the given handler for the given type
1943                                                  if ( handler )
1944                                                          delete events[type][handler.guid];
1945                         
1946                                                  // remove all handlers for the given type
1947                                                  else
1948                                                          for ( handler in events[type] )
1949                                                                  // Handle the removal of namespaced events
1950                                                                  if ( !parts[1] || events[type][handler].type == parts[1] )
1951                                                                          delete events[type][handler];
1952  
1953                                                  // remove generic event handler if no more handlers exist
1954                                                  for ( ret in events[type] ) break;
1955                                                  if ( !ret ) {
1956                                                          if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) {
1957                                                                  if (elem.removeEventListener)
1958                                                                          elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
1959                                                                  else if (elem.detachEvent)
1960                                                                          elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
1961                                                          }
1962                                                          ret = null;
1963                                                          delete events[type];
1964                                                  }
1965                                          }
1966                                  });
1967                          }
1968  
1969                          // Remove the expando if it's no longer used
1970                          for ( ret in events ) break;
1971                          if ( !ret ) {
1972                                  var handle = jQuery.data( elem, "handle" );
1973                                  if ( handle ) handle.elem = null;
1974                                  jQuery.removeData( elem, "events" );
1975                                  jQuery.removeData( elem, "handle" );
1976                          }
1977                  }
1978          },
1979  
1980          trigger: function(type, data, elem, donative, extra) {
1981                  // Clone the incoming data, if any
1982                  data = jQuery.makeArray(data || []);
1983  
1984                  if ( type.indexOf("!") >= 0 ) {
1985                          type = type.slice(0, -1);
1986                          var exclusive = true;
1987                  }
1988  
1989                  // Handle a global trigger
1990                  if ( !elem ) {
1991                          // Only trigger if we've ever bound an event for it
1992                          if ( this.global[type] )
1993                                  jQuery("*").add([window, document]).trigger(type, data);
1994  
1995                  // Handle triggering a single element
1996                  } else {
1997                          // don't do events on text and comment nodes
1998                          if ( elem.nodeType == 3 || elem.nodeType == 8 )
1999                                  return undefined;
2000  
2001                          var val, ret, fn = jQuery.isFunction( elem[ type ] || null ),
2002                                  // Check to see if we need to provide a fake event, or not
2003                                  event = !data[0] || !data[0].preventDefault;
2004                         
2005                          // Pass along a fake event
2006                          if ( event )
2007                                  data.unshift( this.fix({ type: type, target: elem }) );
2008  
2009                          // Enforce the right trigger type
2010                          data[0].type = type;
2011                          if ( exclusive )
2012                                  data[0].exclusive = true;
2013  
2014                          // Trigger the event
2015                          if ( jQuery.isFunction( jQuery.data(elem, "handle") ) )
2016                                  val = jQuery.data(elem, "handle").apply( elem, data );
2017  
2018                          // Handle triggering native .onfoo handlers
2019                          if ( !fn && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
2020                                  val = false;
2021  
2022                          // Extra functions don't get the custom event object
2023                          if ( event )
2024                                  data.shift();
2025  
2026                          // Handle triggering of extra function
2027                          if ( extra && jQuery.isFunction( extra ) ) {
2028                                  // call the extra function and tack the current return value on the end for possible inspection
2029                                  ret = extra.apply( elem, val == null ? data : data.concat( val ) );
2030                                  // if anything is returned, give it precedence and have it overwrite the previous value
2031                                  if (ret !== undefined)
2032                                          val = ret;
2033                          }
2034  
2035                          // Trigger the native events (except for clicks on links)
2036                          if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
2037                                  this.triggered = true;
2038                                  try {
2039                                          elem[ type ]();
2040                                  // prevent IE from throwing an error for some hidden elements
2041                                  } catch (e) {}
2042                          }
2043  
2044                          this.triggered = false;
2045                  }
2046  
2047                  return val;
2048          },
2049  
2050          handle: function(event) {
2051                  // returned undefined or false
2052                  var val;
2053  
2054                  // Empty object is for triggered events with no data
2055                  event = jQuery.event.fix( event || window.event || {} ); 
2056  
2057                  // Namespaced event handlers
2058                  var parts = event.type.split(".");
2059                  event.type = parts[0];
2060  
2061                  var handlers = jQuery.data(this, "events") && jQuery.data(this, "events")[event.type], args = Array.prototype.slice.call( arguments, 1 );
2062                  args.unshift( event );
2063  
2064                  for ( var j in handlers ) {
2065                          var handler = handlers[j];
2066                          // Pass in a reference to the handler function itself
2067                          // So that we can later remove it
2068                          args[0].handler = handler;
2069                          args[0].data = handler.data;
2070  
2071                          // Filter the functions by class
2072                          if ( !parts[1] && !event.exclusive || handler.type == parts[1] ) {
2073                                  var ret = handler.apply( this, args );
2074  
2075                                  if ( val !== false )
2076                                          val = ret;
2077  
2078                                  if ( ret === false ) {
2079                                          event.preventDefault();
2080                                          event.stopPropagation();
2081                                  }
2082                          }
2083                  }
2084  
2085                  // Clean up added properties in IE to prevent memory leak
2086                  if (jQuery.browser.msie)
2087                          event.target = event.preventDefault = event.stopPropagation =
2088                                  event.handler = event.data = null;
2089  
2090                  return val;
2091          },
2092  
2093          fix: function(event) {
2094                  // store a copy of the original event object
2095                  // and clone to set read-only properties
2096                  var originalEvent = event;
2097                  event = jQuery.extend({}, originalEvent);
2098                 
2099                  // add preventDefault and stopPropagation since
2100                  // they will not work on the clone
2101                  event.preventDefault = function() {
2102                          // if preventDefault exists run it on the original event
2103                          if (originalEvent.preventDefault)
2104                                  originalEvent.preventDefault();
2105                          // otherwise set the returnValue property of the original event to false (IE)
2106                          originalEvent.returnValue = false;
2107                  };
2108                  event.stopPropagation = function() {
2109                          // if stopPropagation exists run it on the original event
2110                          if (originalEvent.stopPropagation)
2111                                  originalEvent.stopPropagation();
2112                          // otherwise set the cancelBubble property of the original event to true (IE)
2113                          originalEvent.cancelBubble = true;
2114                  };
2115                 
2116                  // Fix target property, if necessary
2117                  if ( !event.target )
2118                          event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
2119                                 
2120                  // check if target is a textnode (safari)
2121                  if ( event.target.nodeType == 3 )
2122                          event.target = originalEvent.target.parentNode;
2123  
2124                  // Add relatedTarget, if necessary
2125                  if ( !event.relatedTarget && event.fromElement )
2126                          event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
2127  
2128                  // Calculate pageX/Y if missing and clientX/Y available
2129                  if ( event.pageX == null && event.clientX != null ) {
2130                          var doc = document.documentElement, body = document.body;
2131                          event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
2132                          event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
2133                  }
2134                         
2135                  // Add which for key events
2136                  if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
2137                          event.which = event.charCode || event.keyCode;
2138                 
2139                  // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
2140                  if ( !event.metaKey && event.ctrlKey )
2141                          event.metaKey = event.ctrlKey;
2142  
2143                  // Add which for click: 1 == left; 2 == middle; 3 == right
2144                  // Note: button is not normalized, so don't use it
2145                  if ( !event.which && event.button )
2146                          event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
2147                         
2148                  return event;
2149          },
2150         
2151          special: {
2152                  ready: {
2153                          setup: function() {
2154                                  // Make sure the ready event is setup
2155                                  bindReady();
2156                                  return;
2157                          },
2158                         
2159                          teardown: function() { return; }
2160                  },
2161                 
2162                  mouseenter: {
2163                          setup: function() {
2164                                  if ( jQuery.browser.msie ) return false;
2165                                  jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler);
2166                                  return true;
2167                          },
2168                 
2169                          teardown: function() {
2170                                  if ( jQuery.browser.msie ) return false;
2171                                  jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler);
2172                                  return true;
2173                          },
2174                         
2175                          handler: function(event) {
2176                                  // If we actually just moused on to a sub-element, ignore it
2177                                  if ( withinElement(event, this) ) return true;
2178                                  // Execute the right handlers by setting the event type to mouseenter
2179                                  arguments[0].type = "mouseenter";
2180                                  return jQuery.event.handle.apply(this, arguments);
2181                          }
2182                  },
2183         
2184                  mouseleave: {
2185                          setup: function() {
2186                                  if ( jQuery.browser.msie ) return false;
2187                                  jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler);
2188                                  return true;
2189                          },
2190                 
2191                          teardown: function() {
2192                                  if ( jQuery.browser.msie ) return false;
2193                                  jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler);
2194                                  return true;
2195                          },
2196                         
2197                          handler: function(event) {
2198                                  // If we actually just moused on to a sub-element, ignore it
2199                                  if ( withinElement(event, this) ) return true;
2200                                  // Execute the right handlers by setting the event type to mouseleave
2201                                  arguments[0].type = "mouseleave";
2202                                  return jQuery.event.handle.apply(this, arguments);
2203                          }
2204                  }
2205          }
2206  };
2207  
2208  jQuery.fn.extend({
2209          bind: function( type, data, fn ) {
2210                  return type == "unload" ? this.one(type, data, fn) : this.each(function(){
2211                          jQuery.event.add( this, type, fn || data, fn && data );
2212                  });
2213          },
2214         
2215          one: function( type, data, fn ) {
2216                  return this.each(function(){
2217                          jQuery.event.add( this, type, function(event) {
2218                                  jQuery(this).unbind(event);
2219                                  return (fn || data).apply( this, arguments);
2220                          }, fn && data);
2221                  });
2222          },
2223  
2224          unbind: function( type, fn ) {
2225                  return this.each(function(){
2226                          jQuery.event.remove( this, type, fn );
2227                  });
2228          },
2229  
2230          trigger: function( type, data, fn ) {
2231                  return this.each(function(){
2232                          jQuery.event.trigger( type, data, this, true, fn );
2233                  });
2234          },
2235  
2236          triggerHandler: function( type, data, fn ) {
2237                  if ( this[0] )
2238                          return jQuery.event.trigger( type, data, this[0], false, fn );
2239                  return undefined;
2240          },
2241  
2242          toggle: function() {
2243                  // Save reference to arguments for access in closure
2244                  var args = arguments;
2245  
2246                  return this.click(function(event) {
2247                          // Figure out which function to execute
2248                          this.lastToggle = 0 == this.lastToggle ? 1 : 0;
2249                         
2250                          // Make sure that clicks stop
2251                          event.preventDefault();
2252                         
2253                          // and execute the function
2254                          return args[this.lastToggle].apply( this, arguments ) || false;
2255                  });
2256          },
2257  
2258          hover: function(fnOver, fnOut) {
2259                  return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut);
2260          },
2261         
2262          ready: function(fn) {
2263                  // Attach the listeners
2264                  bindReady();
2265  
2266                  // If the DOM is already ready
2267                  if ( jQuery.isReady )
2268                          // Execute the function immediately
2269                          fn.call( document, jQuery );
2270                         
2271                  // Otherwise, remember the function for later
2272                  else
2273                          // Add the function to the wait list
2274                          jQuery.readyList.push( function() { return fn.call(this, jQuery); } );
2275         
2276                  return this;
2277          }
2278  });
2279  
2280  jQuery.extend({
2281          isReady: false,
2282          readyList: [],
2283          // Handle when the DOM is ready
2284          ready: function() {
2285                  // Make sure that the DOM is not already loaded
2286                  if ( !jQuery.isReady ) {
2287                          // Remember that the DOM is ready
2288                          jQuery.isReady = true;
2289                         
2290                          // If there are functions bound, to execute
2291                          if ( jQuery.readyList ) {
2292                                  // Execute all of them
2293                                  jQuery.each( jQuery.readyList, function(){
2294                                          this.apply( document );
2295                                  });
2296                                 
2297                                  // Reset the list of functions
2298                                  jQuery.readyList = null;
2299                          }
2300                 
2301                          // Trigger any bound ready events
2302                          jQuery(document).triggerHandler("ready");
2303                  }
2304          }
2305  });
2306  
2307  var readyBound = false;
2308  
2309  function bindReady(){
2310          if ( readyBound ) return;
2311          readyBound = true;
2312  
2313          // Mozilla, Opera (see further below for it) and webkit nightlies currently support this event
2314          if ( document.addEventListener && !jQuery.browser.opera)
2315                  // Use the handy event callback
2316                  document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
2317         
2318          // If IE is used and is not in a frame
2319          // Continually check to see if the document is ready
2320          if ( jQuery.browser.msie && window == top ) (function(){
2321                  if (jQuery.isReady) return;
2322                  try {
2323                          // If IE is used, use the trick by Diego Perini
2324                          // http://javascript.nwbox.com/IEContentLoaded/
2325                          document.documentElement.doScroll("left");
2326                  } catch( error ) {
2327                          setTimeout( arguments.callee, 0 );
2328                          return;
2329                  }
2330                  // and execute any waiting functions
2331                  jQuery.ready();
2332          })();
2333  
2334          if ( jQuery.browser.opera )
2335                  document.addEventListener( "DOMContentLoaded", function () {
2336                          if (jQuery.isReady) return;
2337                          for (var i = 0; i < document.styleSheets.length; i++)
2338                                  if (document.styleSheets[i].disabled) {
2339                                          setTimeout( arguments.callee, 0 );
2340                                          return;
2341                                  }
2342                          // and execute any waiting functions
2343                          jQuery.ready();
2344                  }, false);
2345  
2346          if ( jQuery.browser.safari ) {
2347                  var numStyles;
2348                  (function(){
2349                          if (jQuery.isReady) return;
2350                          if ( document.readyState != "loaded" && document.readyState != "complete" ) {
2351                                  setTimeout( arguments.callee, 0 );
2352                                  return;
2353                          }
2354                          if ( numStyles === undefined )
2355                                  numStyles = jQuery("style, link[rel=stylesheet]").length;
2356                          if ( document.styleSheets.length != numStyles ) {
2357                                  setTimeout( arguments.callee, 0 );
2358                                  return;
2359                          }
2360                          // and execute any waiting functions
2361                          jQuery.ready();
2362                  })();
2363          }
2364  
2365          // A fallback to window.onload, that will always work
2366          jQuery.event.add( window, "load", jQuery.ready );
2367  }
2368  
2369  jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
2370          "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," + 
2371          "submit,keydown,keypress,keyup,error").split(","), function(i, name){
2372         
2373          // Handle event binding
2374          jQuery.fn[name] = function(fn){
2375                  return fn ? this.bind(name, fn) : this.trigger(name);
2376          };
2377  });
2378  
2379  // Checks if an event happened on an element within another element
2380  // Used in jQuery.event.special.mouseenter and mouseleave handlers
2381  var withinElement = function(event, elem) {
2382          // Check if mouse(over|out) are still within the same parent element
2383          var parent = event.relatedTarget;
2384          // Traverse up the tree
2385          while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; }
2386          // Return true if we actually just moused on to a sub-element
2387          return parent == elem;
2388  };
2389  
2390  // Prevent memory leaks in IE
2391  // And prevent errors on refresh with events like mouseover in other browsers
2392  // Window isn't included so as not to unbind existing unload events
2393  jQuery(window).bind("unload", function() {
2394          jQuery("*").add(document).unbind();
2395  });
2396  jQuery.fn.extend({
2397          load: function( url, params, callback ) {
2398                  if ( jQuery.isFunction( url ) )
2399                          return this.bind("load", url);
2400  
2401                  var off = url.indexOf(" ");
2402                  if ( off >= 0 ) {
2403                          var selector = url.slice(off, url.length);
2404                          url = url.slice(0, off);
2405                  }
2406  
2407                  callback = callback || function(){};
2408  
2409                  // Default to a GET request
2410                  var type = "GET";
2411  
2412                  // If the second parameter was provided
2413                  if ( params )
2414                          // If it's a function
2415                          if ( jQuery.isFunction( params ) ) {
2416                                  // We assume that it's the callback
2417                                  callback = params;
2418                                  params = null;
2419  
2420                          // Otherwise, build a param string
2421                          } else {
2422                                  params = jQuery.param( params );
2423                                  type = "POST";
2424                          }
2425  
2426                  var self = this;
2427  
2428                  // Request the remote document
2429                  jQuery.ajax({
2430                          url: url,
2431                          type: type,
2432                          dataType: "html",
2433                          data: params,
2434                          complete: function(res, status){
2435                                  // If successful, inject the HTML into all the matched elements
2436                                  if ( status == "success" || status == "notmodified" )
2437                                          // See if a selector was specified
2438                                          self.html( selector ?
2439                                                  // Create a dummy div to hold the results
2440                                                  jQuery("<div/>")
2441                                                          // inject the contents of the document in, removing the scripts
2442                                                          // to avoid any 'Permission Denied' errors in IE
2443                                                          .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
2444  
2445                                                          // Locate the specified elements
2446                                                          .find(selector) :
2447  
2448                                                  // If not, just inject the full result
2449                                                  res.responseText );
2450  
2451                                  self.each( callback, [res.responseText, status, res] );
2452                          }
2453                  });
2454                  return this;
2455          },
2456  
2457          serialize: function() {
2458                  return jQuery.param(this.serializeArray());
2459          },
2460          serializeArray: function() {
2461                  return this.map(function(){
2462                          return jQuery.nodeName(this, "form") ?
2463                                  jQuery.makeArray(this.elements) : this;
2464                  })
2465                  .filter(function(){
2466                          return this.name && !this.disabled && 
2467                                  (this.checked || /select|textarea/i.test(this.nodeName) || 
2468                                          /text|hidden|password/i.test(this.type));
2469                  })
2470                  .map(function(i, elem){
2471                          var val = jQuery(this).val();
2472                          return val == null ? null :
2473                                  val.constructor == Array ?
2474                                          jQuery.map( val, function(val, i){
2475                                                  return {name: elem.name, value: val};
2476                                          }) :
2477                                          {name: elem.name, value: val};
2478                  }).get();
2479          }
2480  });
2481  
2482  // Attach a bunch of functions for handling common AJAX events
2483  jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
2484          jQuery.fn[o] = function(f){
2485                  return this.bind(o, f);
2486          };
2487  });
2488  
2489  var jsc = (new Date).getTime();
2490  
2491  jQuery.extend({
2492          get: function( url, data, callback, type ) {
2493                  // shift arguments if data argument was ommited
2494                  if ( jQuery.isFunction( data ) ) {
2495                          callback = data;
2496                          data = null;
2497                  }
2498                 
2499                  return jQuery.ajax({
2500                          type: "GET",
2501                          url: url,
2502                          data: data,
2503                          success: callback,
2504                          dataType: type
2505                  });
2506          },
2507  
2508          getScript: function( url, callback ) {
2509                  return jQuery.get(url, null, callback, "script");
2510          },
2511  
2512          getJSON: function( url, data, callback ) {
2513                  return jQuery.get(url, data, callback, "json");
2514          },
2515  
2516          post: function( url, data, callback, type ) {
2517                  if ( jQuery.isFunction( data ) ) {
2518                          callback = data;
2519                          data = {};
2520                  }
2521  
2522                  return jQuery.ajax({
2523                          type: "POST",
2524                          url: url,
2525                          data: data,
2526                          success: callback,
2527                          dataType: type
2528                  });
2529          },
2530  
2531          ajaxSetup: function( settings ) {
2532                  jQuery.extend( jQuery.ajaxSettings, settings );
2533          },
2534  
2535          ajaxSettings: {
2536                  global: true,
2537                  type: "GET",
2538                  timeout: 0,
2539                  contentType: "application/x-www-form-urlencoded",
2540                  processData: true,
2541                  async: true,
2542                  data: null,
2543                  username: null,
2544                  password: null,
2545                  accepts: {
2546                          xml: "application/xml, text/xml",
2547                          html: "text/html",
2548                          script: "text/javascript, application/javascript",
2549                          json: "application/json, text/javascript",
2550                          text: "text/plain",
2551                          _default: "*/*"
2552                  }
2553          },
2554         
2555          // Last-Modified header cache for next request
2556          lastModified: {},
2557  
2558          ajax: function( s ) {
2559                  var jsonp, jsre = /=\?(&|$)/g, status, data;
2560  
2561                  // Extend the settings, but re-extend 's' so that it can be
2562                  // checked again later (in the test suite, specifically)
2563                  s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
2564  
2565                  // convert data if not already a string
2566                  if ( s.data && s.processData && typeof s.data != "string" )
2567                          s.data = jQuery.param(s.data);
2568  
2569                  // Handle JSONP Parameter Callbacks
2570                  if ( s.dataType == "jsonp" ) {
2571                          if ( s.type.toLowerCase() == "get" ) {
2572                                  if ( !s.url.match(jsre) )
2573                                          s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
2574                          } else if ( !s.data || !s.data.match(jsre) )
2575                                  s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
2576                          s.dataType = "json";
2577                  }
2578  
2579                  // Build temporary JSONP function
2580                  if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
2581                          jsonp = "jsonp" + jsc++;
2582  
2583                          // Replace the =? sequence both in the query string and the data
2584                          if ( s.data )
2585                                  s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
2586                          s.url = s.url.replace(jsre, "=" + jsonp + "$1");
2587  
2588                          // We need to make sure
2589                          // that a JSONP style response is executed properly
2590                          s.dataType = "script";
2591  
2592                          // Handle JSONP-style loading
2593                          window[ jsonp ] = function(tmp){
2594                                  data = tmp;
2595                                  success();
2596                                  complete();
2597                                  // Garbage collect
2598                                  window[ jsonp ] = undefined;
2599                                  try{ delete window[ jsonp ]; } catch(e){}
2600                                  if ( head )
2601                                          head.removeChild( script );
2602                          };
2603                  }
2604  
2605                  if ( s.dataType == "script" && s.cache == null )
2606                          s.cache = false;
2607  
2608                  if ( s.cache === false && s.type.toLowerCase() == "get" ) {
2609                          var ts = (new Date()).getTime();
2610                          // try replacing _= if it is there
2611                          var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
2612                          // if nothing was replaced, add timestamp to the end
2613                          s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
2614                  }
2615  
2616                  // If data is available, append data to url for get requests
2617                  if ( s.data && s.type.toLowerCase() == "get" ) {
2618                          s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
2619  
2620                          // IE likes to send both get and post data, prevent this
2621                          s.data = null;
2622                  }
2623  
2624                  // Watch for a new set of requests
2625                  if ( s.global && ! jQuery.active++ )
2626                          jQuery.event.trigger( "ajaxStart" );
2627  
2628                  // If we're requesting a remote document
2629                  // and trying to load JSON or Script with a GET
2630                  if ( (!s.url.indexOf("http") || !s.url.indexOf("//")) && s.dataType == "script" && s.type.toLowerCase() == "get" ) {
2631                          var head = document.getElementsByTagName("head")[0];
2632                          var script = document.createElement("script");
2633                          script.src = s.url;
2634                          if (s.scriptCharset)
2635                                  script.charset = s.scriptCharset;
2636  
2637                          // Handle Script loading
2638                          if ( !jsonp ) {
2639                                  var done = false;
2640  
2641                                  // Attach handlers for all browsers
2642                                  script.onload = script.onreadystatechange = function(){
2643                                          if ( !done && (!this.readyState || 
2644                                                          this.readyState == "loaded" || this.readyState == "complete") ) {
2645                                                  done = true;
2646                                                  success();
2647                                                  complete();
2648                                                  head.removeChild( script );
2649                                          }
2650                                  };
2651                          }
2652  
2653                          head.appendChild(script);
2654  
2655                          // We handle everything using the script element injection
2656                          return undefined;
2657                  }
2658  
2659                  var requestDone = false;
2660  
2661                  // Create the request object; Microsoft failed to properly
2662                  // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
2663                  var xml = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
2664  
2665                  // Open the socket
2666                  xml.open(s.type, s.url, s.async, s.username, s.password);
2667  
2668                  // Need an extra try/catch for cross domain requests in Firefox 3
2669                  try {
2670                          // Set the correct header, if data is being sent
2671                          if ( s.data )
2672                                  xml.setRequestHeader("Content-Type", s.contentType);
2673  
2674                          // Set the If-Modified-Since header, if ifModified mode.
2675                          if ( s.ifModified )
2676                                  xml.setRequestHeader("If-Modified-Since",
2677                                          jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
2678  
2679                          // Set header so the called script knows that it's an XMLHttpRequest
2680                          xml.setRequestHeader("X-Requested-With", "XMLHttpRequest");
2681  
2682                          // Set the Accepts header for the server, depending on the dataType
2683                          xml.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
2684                                  s.accepts[ s.dataType ] + ", */*" :
2685                                  s.accepts._default );
2686                  } catch(e){}
2687  
2688                  // Allow custom headers/mimetypes
2689                  if ( s.beforeSend )
2690                          s.beforeSend(xml);
2691                         
2692                  if ( s.global )
2693                          jQuery.event.trigger("ajaxSend", [xml, s]);
2694  
2695                  // Wait for a response to come back
2696                  var onreadystatechange = function(isTimeout){
2697                          // The transfer is complete and the data is available, or the request timed out
2698                          if ( !requestDone && xml && (xml.readyState == 4 || isTimeout == "timeout") ) {
2699                                  requestDone = true;
2700                                 
2701                                  // clear poll interval
2702                                  if (ival) {
2703                                          clearInterval(ival);
2704                                          ival = null;
2705                                  }
2706                                 
2707                                  status = isTimeout == "timeout" && "timeout" ||
2708                                          !jQuery.httpSuccess( xml ) && "error" ||
2709                                          s.ifModified && jQuery.httpNotModified( xml, s.url ) && "notmodified" ||
2710                                          "success";
2711  
2712                                  if ( status == "success" ) {
2713                                          // Watch for, and catch, XML document parse errors
2714                                          try {
2715                                                  // process the data (runs the xml through httpData regardless of callback)
2716                                                  data = jQuery.httpData( xml, s.dataType );
2717                                          } catch(e) {
2718                                                  status = "parsererror";
2719                                          }
2720                                  }
2721  
2722                                  // Make sure that the request was successful or notmodified
2723                                  if ( status == "success" ) {
2724                                          // Cache Last-Modified header, if ifModified mode.
2725                                          var modRes;
2726                                          try {
2727                                                  modRes = xml.getResponseHeader("Last-Modified");
2728                                          } catch(e) {} // swallow exception thrown by FF if header is not available
2729         
2730                                          if ( s.ifModified && modRes )
2731                                                  jQuery.lastModified[s.url] = modRes;
2732  
2733                                          // JSONP handles its own success callback
2734                                          if ( !jsonp )
2735                                                  success();     
2736                                  } else
2737                                          jQuery.handleError(s, xml, status);
2738  
2739                                  // Fire the complete handlers
2740                                  complete();
2741  
2742                                  // Stop memory leaks
2743                                  if ( s.async )
2744                                          xml = null;
2745                          }
2746                  };
2747                 
2748                  if ( s.async ) {
2749                          // don't attach the handler to the request, just poll it instead
2750                          var ival = setInterval(onreadystatechange, 13); 
2751  
2752                          // Timeout checker
2753                          if ( s.timeout > 0 )
2754                                  setTimeout(function(){
2755                                          // Check to see if the request is still happening
2756                                          if ( xml ) {
2757                                                  // Cancel the request
2758                                                  xml.abort();
2759         
2760                                                  if( !requestDone )
2761                                                          onreadystatechange( "timeout" );
2762                                          }
2763                                  }, s.timeout);
2764                  }
2765                         
2766                  // Send the data
2767                  try {
2768                          xml.send(s.data);
2769                  } catch(e) {
2770                          jQuery.handleError(s, xml, null, e);
2771                  }
2772                 
2773                  // firefox 1.5 doesn't fire statechange for sync requests
2774                  if ( !s.async )
2775                          onreadystatechange();
2776  
2777                  function success(){
2778                          // If a local callback was specified, fire it and pass it the data
2779                          if ( s.success )
2780                                  s.success( data, status );
2781  
2782                          // Fire the global callback
2783                          if ( s.global )
2784                                  jQuery.event.trigger( "ajaxSuccess", [xml, s] );
2785                  }
2786  
2787                  function complete(){
2788                          // Process result
2789                          if ( s.complete )
2790                                  s.complete(xml, status);
2791  
2792                          // The request was completed
2793                          if ( s.global )
2794                                  jQuery.event.trigger( "ajaxComplete", [xml, s] );
2795  
2796                          // Handle the global AJAX counter
2797                          if ( s.global && ! --jQuery.active )
2798                                  jQuery.event.trigger( "ajaxStop" );
2799                  }
2800                 
2801                  // return XMLHttpRequest to allow aborting the request etc.
2802                  return xml;
2803          },
2804  
2805          handleError: function( s, xml, status, e ) {
2806                  // If a local callback was specified, fire it
2807                  if ( s.error ) s.error( xml, status, e );
2808  
2809                  // Fire the global callback
2810                  if ( s.global )
2811                          jQuery.event.trigger( "ajaxError", [xml, s, e] );
2812          },
2813  
2814          // Counter for holding the number of active queries
2815          active: 0,
2816  
2817          // Determines if an XMLHttpRequest was successful or not
2818          httpSuccess: function( r ) {
2819                  try {
2820                          // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
2821                          return !r.status && location.protocol == "file:" ||
2822                                  ( r.status >= 200 && r.status < 300 ) || r.status == 304 || r.status == 1223 ||
2823                                  jQuery.browser.safari && r.status == undefined;
2824                  } catch(e){}
2825                  return false;
2826          },
2827  
2828          // Determines if an XMLHttpRequest returns NotModified
2829          httpNotModified: function( xml, url ) {
2830                  try {
2831                          var xmlRes = xml.getResponseHeader("Last-Modified");
2832  
2833                          // Firefox always returns 200. check Last-Modified date
2834                          return xml.status == 304 || xmlRes == jQuery.lastModified[url] ||
2835                                  jQuery.browser.safari && xml.status == undefined;
2836                  } catch(e){}
2837                  return false;
2838          },
2839  
2840          httpData: function( r, type ) {
2841                  var ct = r.getResponseHeader("content-type");
2842                  var xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0;
2843                  var data = xml ? r.responseXML : r.responseText;
2844  
2845                  if ( xml && data.documentElement.tagName == "parsererror" )
2846                          throw "parsererror";
2847  
2848                  // If the type is "script", eval it in global context
2849                  if ( type == "script" )
2850                          jQuery.globalEval( data );
2851  
2852                  // Get the JavaScript object, if JSON is used.
2853                  if ( type == "json" )
2854                          data = eval("(" + data + ")");
2855  
2856                  return data;
2857          },
2858  
2859          // Serialize an array of form elements or a set of
2860          // key/values into a query string
2861          param: function( a ) {
2862                  var s = [];
2863  
2864                  // If an array was passed in, assume that it is an array
2865                  // of form elements
2866                  if ( a.constructor == Array || a.jquery )
2867                          // Serialize the form elements
2868                          jQuery.each( a, function(){
2869                                  s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) );
2870                          });
2871  
2872                  // Otherwise, assume that it's an object of key/value pairs
2873                  else
2874                          // Serialize the key/values
2875                          for ( var j in a )
2876                                  // If the value is an array then the key names need to be repeated
2877                                  if ( a[j] && a[j].constructor == Array )
2878                                          jQuery.each( a[j], function(){
2879                                                  s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) );
2880                                          });
2881                                  else
2882                                          s.push( encodeURIComponent(j) + "=" + encodeURIComponent( a[j] ) );
2883  
2884                  // Return the resulting serialization
2885                  return s.join("&").replace(/%20/g, "+");
2886          }
2887  
2888  });
2889  jQuery.fn.extend({
2890          show: function(speed,callback){
2891                  return speed ?
2892                          this.animate({
2893                                  height: "show", width: "show", opacity: "show"
2894                          }, speed, callback) :
2895                         
2896                          this.filter(":hidden").each(function(){
2897                                  this.style.display = this.oldblock || "";
2898                                  if ( jQuery.css(this,"display") == "none" ) {
2899                                          var elem = jQuery("<" + this.tagName + " />").appendTo("body");
2900                                          this.style.display = elem.css("display");
2901                                          // handle an edge condition where css is - div { display:none; } or similar
2902                                          if (this.style.display == "none")
2903                                                  this.style.display = "block";
2904                                          elem.remove();
2905                                  }
2906                          }).end();
2907          },
2908         
2909          hide: function(speed,callback){
2910                  return speed ?
2911                          this.animate({
2912                                  height: "hide", width: "hide", opacity: "hide"
2913                          }, speed, callback) :
2914                         
2915                          this.filter(":visible").each(function(){
2916                                  this.oldblock = this.oldblock || jQuery.css(this,"display");
2917                                  this.style.display = "none";
2918                          }).end();
2919          },
2920  
2921          // Save the old toggle function
2922          _toggle: jQuery.fn.toggle,
2923         
2924          toggle: function( fn, fn2 ){
2925                  return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
2926                          this._toggle( fn, fn2 ) :
2927                          fn ?
2928                                  this.animate({
2929                                          height: "toggle", width: "toggle", opacity: "toggle"
2930                                  }, fn, fn2) :
2931                                  this.each(function(){
2932                                          jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
2933                                  });
2934          },
2935         
2936          slideDown: function(speed,callback){
2937                  return this.animate({height: "show"}, speed, callback);
2938          },
2939         
2940          slideUp: function(speed,callback){
2941                  return this.animate({height: "hide"}, speed, callback);
2942          },
2943  
2944          slideToggle: function(speed, callback){
2945                  return this.animate({height: "toggle"}, speed, callback);
2946          },
2947         
2948          fadeIn: function(speed, callback){
2949                  return this.animate({opacity: "show"}, speed, callback);
2950          },
2951         
2952          fadeOut: function(speed, callback){
2953                  return this.animate({opacity: "hide"}, speed, callback);
2954          },
2955         
2956          fadeTo: function(speed,to,callback){
2957                  return this.animate({opacity: to}, speed, callback);
2958          },
2959         
2960          animate: function( prop, speed, easing, callback ) {
2961                  var optall = jQuery.speed(speed, easing, callback);
2962  
2963                  return this[ optall.queue === false ? "each" : "queue" ](function(){
2964                          if ( this.nodeType != 1)
2965                                  return false;
2966  
2967                          var opt = jQuery.extend({}, optall);
2968                          var hidden = jQuery(this).is(":hidden"), self = this;
2969                         
2970                          for ( var p in prop ) {
2971                                  if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
2972                                          return jQuery.isFunction(opt.complete) && opt.complete.apply(this);
2973  
2974                                  if ( p == "height" || p == "width" ) {
2975                                          // Store display property
2976                                          opt.display = jQuery.css(this, "display");
2977  
2978                                          // Make sure that nothing sneaks out
2979                                          opt.overflow = this.style.overflow;
2980                                  }
2981                          }
2982  
2983                          if ( opt.overflow != null )
2984                                  this.style.overflow = "hidden";
2985  
2986                          opt.curAnim = jQuery.extend({}, prop);
2987                         
2988                          jQuery.each( prop, function(name, val){
2989                                  var e = new jQuery.fx( self, opt, name );
2990  
2991                                  if ( /toggle|show|hide/.test(val) )
2992                                          e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
2993                                  else {
2994                                          var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
2995                                                  start = e.cur(true) || 0;
2996  
2997                                          if ( parts ) {
2998                                                  var end = parseFloat(parts[2]),
2999                                                          unit = parts[3] || "px";
3000  
3001                                                  // We need to compute starting value
3002                                                  if ( unit != "px" ) {
3003                                                          self.style[ name ] = (end || 1) + unit;
3004                                                          start = ((end || 1) / e.cur(true)) * start;
3005                                                          self.style[ name ] = start + unit;
3006                                                  }
3007  
3008                                                  // If a +=/-= token was provided, we're doing a relative animation
3009                                                  if ( parts[1] )
3010                                                          end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
3011  
3012                                                  e.custom( start, end, unit );
3013                                          } else
3014                                                  e.custom( start, val, "" );
3015                                  }
3016                          });
3017  
3018                          // For JS strict compliance
3019                          return true;
3020                  });
3021          },
3022         
3023          queue: function(type, fn){
3024                  if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) {
3025                          fn = type;
3026                          type = "fx";
3027                  }
3028  
3029                  if ( !type || (typeof type == "string" && !fn) )
3030                          return queue( this[0], type );
3031  
3032                  return this.each(function(){
3033                          if ( fn.constructor == Array )
3034                                  queue(this, type, fn);
3035                          else {
3036                                  queue(this, type).push( fn );
3037                         
3038                                  if ( queue(this, type).length == 1 )
3039                                          fn.apply(this);
3040                          }
3041                  });
3042          },
3043  
3044          stop: function(clearQueue, gotoEnd){
3045                  var timers = jQuery.timers;
3046  
3047                  if (clearQueue)
3048                          this.queue([]);
3049  
3050                  this.each(function(){
3051                          // go in reverse order so anything added to the queue during the loop is ignored
3052                          for ( var i = timers.length - 1; i >= 0; i-- )
3053                                  if ( timers[i].elem == this ) {
3054                                          if (gotoEnd)
3055                                                  // force the next step to be the last
3056                                                  timers[i](true);
3057                                          timers.splice(i, 1);
3058                                  }
3059                  });
3060  
3061                  // start the next in the queue if the last step wasn't forced
3062                  if (!gotoEnd)
3063                          this.dequeue();
3064  
3065                  return this;
3066          }
3067  
3068  });
3069  
3070  var queue = function( elem, type, array ) {
3071          if ( !elem )
3072                  return undefined;
3073  
3074          type = type || "fx";
3075  
3076          var q = jQuery.data( elem, type + "queue" );
3077  
3078          if ( !q || array )
3079                  q = jQuery.data( elem, type + "queue", 
3080                          array ? jQuery.makeArray(array) : [] );
3081  
3082          return q;
3083  };
3084  
3085  jQuery.fn.dequeue = function(type){
3086          type = type || "fx";
3087  
3088          return this.each(function(){
3089                  var q = queue(this, type);
3090  
3091                  q.shift();
3092  
3093                  if ( q.length )
3094                          q[0].apply( this );
3095          });
3096  };
3097  
3098  jQuery.extend({
3099         
3100          speed: function(speed, easing, fn) {
3101                  var opt = speed && speed.constructor == Object ? speed : {
3102                          complete: fn || !fn && easing || 
3103                                  jQuery.isFunction( speed ) && speed,
3104                          duration: speed,
3105                          easing: fn && easing || easing && easing.constructor != Function && easing
3106                  };
3107  
3108                  opt.duration = (opt.duration && opt.duration.constructor == Number ? 
3109                          opt.duration : 
3110                          { slow: 600, fast: 200 }[opt.duration]) || 400;
3111         
3112                  // Queueing
3113                  opt.old = opt.complete;
3114                  opt.complete = function(){
3115                          if ( opt.queue !== false )
3116                                  jQuery(this).dequeue();
3117                          if ( jQuery.isFunction( opt.old ) )
3118                                  opt.old.apply( this );
3119                  };
3120         
3121                  return opt;
3122          },
3123         
3124          easing: {
3125                  linear: function( p, n, firstNum, diff ) {
3126                          return firstNum + diff * p;
3127                  },
3128                  swing: function( p, n, firstNum, diff ) {
3129                          return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
3130                  }
3131          },
3132         
3133          timers: [],
3134          timerId: null,
3135  
3136          fx: function( elem, options, prop ){
3137                  this.options = options;
3138                  this.elem = elem;
3139                  this.prop = prop;
3140  
3141                  if ( !options.orig )
3142                          options.orig = {};
3143          }
3144  
3145  });
3146  
3147  jQuery.fx.prototype = {
3148  
3149          // Simple function for setting a style value
3150          update: function(){
3151                  if ( this.options.step )
3152                          this.options.step.apply( this.elem, [ this.now, this ] );
3153  
3154                  (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
3155  
3156                  // Set display property to block for height/width animations
3157                  if ( this.prop == "height" || this.prop == "width" )
3158                          this.elem.style.display = "block";
3159          },
3160  
3161          // Get the current size
3162          cur: function(force){
3163                  if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )
3164                          return this.elem[ this.prop ];
3165  
3166                  var r = parseFloat(jQuery.css(this.elem, this.prop, force));
3167                  return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
3168          },
3169  
3170          // Start an animation from one number to another
3171          custom: function(from, to, unit){
3172                  this.startTime = (new Date()).getTime();
3173                  this.start = from;
3174                  this.end = to;
3175                  this.unit = unit || this.unit || "px";
3176                  this.now = this.start;
3177                  this.pos = this.state = 0;
3178                  this.update();
3179  
3180                  var self = this;
3181                  function t(gotoEnd){
3182                          return self.step(gotoEnd);
3183                  }
3184  
3185                  t.elem = this.elem;
3186  
3187                  jQuery.timers.push(t);
3188  
3189                  if ( jQuery.timerId == null ) {
3190                          jQuery.timerId = setInterval(function(){
3191                                  var timers = jQuery.timers;
3192                                 
3193                                  for ( var i = 0; i < timers.length; i++ )
3194                                          if ( !timers[i]() )
3195                                                  timers.splice(i--, 1);
3196  
3197                                  if ( !timers.length ) {
3198                                          clearInterval( jQuery.timerId );
3199                                          jQuery.timerId = null;
3200                                  }
3201                          }, 13);
3202                  }
3203          },
3204  
3205          // Simple 'show' function
3206          show: function(){
3207                  // Remember where we started, so that we can go back to it later
3208                  this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
3209                  this.options.show = true;
3210  
3211                  // Begin the animation
3212                  this.custom(0, this.cur());
3213  
3214                  // Make sure that we start at a small width/height to avoid any
3215                  // flash of content
3216                  if ( this.prop == "width" || this.prop == "height" )
3217                          this.elem.style[this.prop] = "1px";
3218                 
3219                  // Start by showing the element
3220                  jQuery(this.elem).show();
3221          },
3222  
3223          // Simple 'hide' function
3224          hide: function(){
3225                  // Remember where we started, so that we can go back to it later
3226                  this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
3227                  this.options.hide = true;
3228  
3229                  // Begin the animation
3230                  this.custom(this.cur(), 0);
3231          },
3232  
3233          // Each step of an animation
3234          step: function(gotoEnd){
3235                  var t = (new Date()).getTime();
3236  
3237                  if ( gotoEnd || t > this.options.duration + this.startTime ) {
3238                          this.now = this.end;
3239                          this.pos = this.state = 1;
3240                          this.update();
3241  
3242                          this.options.curAnim[ this.prop ] = true;
3243  
3244                          var done = true;
3245                          for ( var i in this.options.curAnim )
3246                                  if ( this.options.curAnim[i] !== true )
3247                                          done = false;
3248  
3249                          if ( done ) {
3250                                  if ( this.options.display != null ) {
3251                                          // Reset the overflow
3252                                          this.elem.style.overflow = this.options.overflow;
3253                                 
3254                                          // Reset the display
3255                                          this.elem.style.display = this.options.display;
3256                                          if ( jQuery.css(this.elem, "display") == "none" )
3257                                                  this.elem.style.display = "block";
3258                                  }
3259  
3260                                  // Hide the element if the "hide" operation was done
3261                                  if ( this.options.hide )
3262                                          this.elem.style.display = "none";
3263  
3264                                  // Reset the properties, if the item has been hidden or shown
3265                                  if ( this.options.hide || this.options.show )
3266                                          for ( var p in this.options.curAnim )
3267                                                  jQuery.attr(this.elem.style, p, this.options.orig[p]);
3268                          }
3269  
3270                          // If a callback was provided, execute it
3271                          if ( done && jQuery.isFunction( this.options.complete ) )
3272                                  // Execute the complete function
3273                                  this.options.complete.apply( this.elem );
3274  
3275                          return false;
3276                  } else {
3277                          var n = t - this.startTime;
3278                          this.state = n / this.options.duration;
3279  
3280                          // Perform the easing function, defaults to swing
3281                          this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
3282                          this.now = this.start + ((this.end - this.start) * this.pos);
3283  
3284                          // Perform the next step of the animation
3285                          this.update();
3286                  }
3287  
3288                  return true;
3289          }
3290  
3291  };
3292  
3293  jQuery.fx.step = {
3294          scrollLeft: function(fx){
3295                  fx.elem.scrollLeft = fx.now;
3296          },
3297  
3298          scrollTop: function(fx){
3299                  fx.elem.scrollTop = fx.now;
3300          },
3301  
3302          opacity: function(fx){
3303                  jQuery.attr(fx.elem.style, "opacity", fx.now);
3304          },
3305  
3306          _default: function(fx){
3307                  fx.elem.style[ fx.prop ] = fx.now + fx.unit;
3308          }
3309  };
3310  // The Offset Method
3311  // Originally By Brandon Aaron, part of the Dimension Plugin
3312  // http://jquery.com/plugins/project/dimensions
3313  jQuery.fn.offset = function() {
3314          var left = 0, top = 0, elem = this[0], results;
3315         
3316          if ( elem ) with ( jQuery.browser ) {
3317                  var parent       = elem.parentNode, 
3318                      offsetChild  = elem,
3319                      offsetParent = elem.offsetParent, 
3320                      doc          = elem.ownerDocument,
3321                      safari2      = safari && parseInt(version) < 522 && !/adobeair/i.test(userAgent),
3322                      fixed        = jQuery.css(elem, "position") == "fixed";
3323         
3324                  // Use getBoundingClientRect if available
3325                  if ( elem.getBoundingClientRect ) {
3326                          var box = elem.getBoundingClientRect();
3327                 
3328                          // Add the document scroll offsets
3329                          add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
3330                                  box.top  + Math.max(doc.documentElement.scrollTop,  doc.body.scrollTop));
3331                 
3332                          // IE adds the HTML element's border, by default it is medium which is 2px
3333                          // IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; }
3334                          // IE 7 standards mode, the border is always 2px
3335                          // This border/offset is typically represented by the clientLeft and clientTop properties
3336                          // However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS
3337                          // Therefore this method will be off by 2px in IE while in quirksmode
3338                          add( -doc.documentElement.clientLeft, -doc.documentElement.clientTop );
3339         
3340                  // Otherwise loop through the offsetParents and parentNodes
3341                  } else {
3342                 
3343                          // Initial element offsets
3344                          add( elem.offsetLeft, elem.offsetTop );
3345                         
3346                          // Get parent offsets
3347                          while ( offsetParent ) {
3348                                  // Add offsetParent offsets
3349                                  add( offsetParent.offsetLeft, offsetParent.offsetTop );
3350                         
3351                                  // Mozilla and Safari > 2 does not include the border on offset parents
3352                                  // However Mozilla adds the border for table or table cells
3353                                  if ( mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2 )
3354                                          border( offsetParent );
3355                                         
3356                                  // Add the document scroll offsets if position is fixed on any offsetParent
3357                                  if ( !fixed && jQuery.css(offsetParent, "position") == "fixed" )
3358                                          fixed = true;
3359                         
3360                                  // Set offsetChild to previous offsetParent unless it is the body element
3361                                  offsetChild  = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent;
3362                                  // Get next offsetParent
3363                                  offsetParent = offsetParent.offsetParent;
3364                          }
3365                 
3366                          // Get parent scroll offsets
3367                          while ( parent && parent.tagName && !/^body|html$/i.test(parent.tagName) ) {
3368                                  // Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug
3369                                  if ( !/^inline|table.*$/i.test(jQuery.css(parent, "display")) )
3370                                          // Subtract parent scroll offsets
3371                                          add( -parent.scrollLeft, -parent.scrollTop );
3372                         
3373                                  // Mozilla does not add the border for a parent that has overflow != visible
3374                                  if ( mozilla && jQuery.css(parent, "overflow") != "visible" )
3375                                          border( parent );
3376                         
3377                                  // Get next parent
3378                                  parent = parent.parentNode;
3379                          }
3380                 
3381                          // Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild
3382                          // Mozilla doubles body offsets with a non-absolutely positioned offsetChild
3383                          if ( (safari2 && (fixed || jQuery.css(offsetChild, "position") == "absolute")) || 
3384                                  (mozilla && jQuery.css(offsetChild, "position") != "absolute") )
3385                                          add( -doc.body.offsetLeft, -doc.body.offsetTop );
3386                         
3387                          // Add the document scroll offsets if position is fixed
3388                          if ( fixed )
3389                                  add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
3390                                          Math.max(doc.documentElement.scrollTop,  doc.body.scrollTop));
3391                  }
3392  
3393                  // Return an object with top and left properties
3394                  results = { top: top, left: left };
3395          }
3396  
3397          function border(elem) {
3398                  add( jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true) );
3399          }
3400  
3401          function add(l, t) {
3402                  left += parseInt(l) || 0;
3403                  top += parseInt(t) || 0;
3404          }
3405  
3406          return results;
3407  };
3408  })();
1(function(){ 2 /* 3 * jQuery 1.2.3 - New Wave Javascript 4 * 5 * Copyright (c) 2008 John Resig (jquery.com) 6 * Dual licensed under the MIT (MIT-LICENSE.txt) 7 * and GPL (GPL-LICENSE.txt) licenses. 8 * 9 * $Date: 2008-02-06 00:21:25 -0500 (Wed, 06 Feb 2008) $ 10 * $Rev: 4663 $ 11 */ 12 13 // Map over jQuery in case of overwrite 14 if ( window.jQuery ) 15 var _jQuery = window.jQuery; 16 17 var jQuery = window.jQuery = function( selector, context ) { 18 // The jQuery object is actually just the init constructor 'enhanced' 19 return new jQuery.prototype.init( selector, context ); 20 }; 21 22 // Map over the $ in case of overwrite 23 if ( window.$ ) 24 var _$ = window.$; 25 26 // Map the jQuery namespace to the '$' one 27 window.$ = jQuery; 28 29 // A simple way to check for HTML strings or ID strings 30 // (both of which we optimize for) 31 var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/; 32 33 // Is it a simple selector 34 var isSimple = /^.[^:#\[\.]*$/; 35 36 jQuery.fn = jQuery.prototype = { 37 init: function( selector, context ) { 38 // Make sure that a selection was provided 39 selector = selector || document; 40 41 // Handle $(DOMElement) 42 if ( selector.nodeType ) { 43 this[0] = selector; 44 this.length = 1; 45 return this; 46 47 // Handle HTML strings 48 } else if ( typeof selector == "string" ) { 49 // Are we dealing with HTML string or an ID? 50 var match = quickExpr.exec( selector ); 51 52 // Verify a match, and that no context was specified for #id 53 if ( match && (match[1] || !context) ) { 54 55 // HANDLE: $(html) -> $(array) 56 if ( match[1] ) 57 selector = jQuery.clean( [ match[1] ], context ); 58 59 // HANDLE: $("#id") 60 else { 61 var elem = document.getElementById( match[3] ); 62 63 // Make sure an element was located 64 if ( elem ) 65 // Handle the case where IE and Opera return items 66 // by name instead of ID 67 if ( elem.id != match[3] ) 68 return jQuery().find( selector ); 69 70 // Otherwise, we inject the element directly into the jQuery object 71 else { 72 this[0] = elem; 73 this.length = 1; 74 return this; 75 } 76 77 else 78 selector = []; 79 } 80 81 // HANDLE: $(expr, [context]) 82 // (which is just equivalent to: $(content).find(expr) 83 } else 84 return new jQuery( context ).find( selector ); 85 86 // HANDLE: $(function) 87 // Shortcut for document ready 88 } else if ( jQuery.isFunction( selector ) ) 89 return new jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector ); 90 91 return this.setArray( 92 // HANDLE: $(array) 93 selector.constructor == Array && selector || 94 95 // HANDLE: $(arraylike) 96 // Watch for when an array-like object, contains DOM nodes, is passed in as the selector 97 (selector.jquery || selector.length && selector != window && !selector.nodeType && selector[0] != undefined && selector[0].nodeType) && jQuery.makeArray( selector ) || 98 99 // HANDLE: $(*) 100 [ selector ] ); 101 }, 102 103 // The current version of jQuery being used 104 jquery: "1.2.3", 105 106 // The number of elements contained in the matched element set 107 size: function() { 108 return this.length; 109 }, 110 111 // The number of elements contained in the matched element set 112 length: 0, 113 114 // Get the Nth element in the matched element set OR 115 // Get the whole matched element set as a clean array 116 get: function( num ) { 117 return num == undefined ? 118 119 // Return a 'clean' array 120 jQuery.makeArray( this ) : 121 122 // Return just the object 123 this[ num ]; 124 }, 125 126 // Take an array of elements and push it onto the stack 127 // (returning the new matched element set) 128 pushStack: function( elems ) { 129 // Build a new jQuery matched element set 130 var ret = jQuery( elems ); 131 132 // Add the old object onto the stack (as a reference) 133 ret.prevObject = this; 134 135 // Return the newly-formed element set 136 return ret; 137 }, 138 139 // Force the current matched set of elements to become 140 // the specified array of elements (destroying the stack in the process) 141 // You should use pushStack() in order to do this, but maintain the stack 142 setArray: function( elems ) { 143 // Resetting the length to 0, then using the native Array push 144 // is a super-fast way to populate an object with array-like properties 145 this.length = 0; 146 Array.prototype.push.apply( this, elems ); 147 148 return this; 149 }, 150 151 // Execute a callback for every element in the matched set. 152 // (You can seed the arguments with an array of args, but this is 153 // only used internally.) 154 each: function( callback, args ) { 155 return jQuery.each( this, callback, args ); 156 }, 157 158 // Determine the position of an element within 159 // the matched set of elements 160 index: function( elem ) { 161 var ret = -1; 162 163 // Locate the position of the desired element 164 this.each(function(i){ 165 if ( this == elem ) 166 ret = i; 167 }); 168 169 return ret; 170 }, 171 172 attr: function( name, value, type ) { 173 var options = name; 174 175 // Look for the case where we're accessing a style value 176 if ( name.constructor == String ) 177 if ( value == undefined ) 178 return this.length && jQuery[ type || "attr" ]( this[0], name ) || undefined; 179 180 else { 181 options = {}; 182 options[ name ] = value; 183 } 184 185 // Check to see if we're setting style values 186 return this.each(function(i){ 187 // Set all the styles 188 for ( name in options ) 189 jQuery.attr( 190 type ? 191 this.style : 192 this, 193 name, jQuery.prop( this, options[ name ], type, i, name ) 194 ); 195 }); 196 }, 197 198 css: function( key, value ) { 199 // ignore negative width and height values 200 if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 ) 201 value = undefined; 202 return this.attr( key, value, "curCSS" ); 203 }, 204 205 text: function( text ) { 206 if ( typeof text != "object" && text != null ) 207 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); 208 209 var ret = ""; 210 211 jQuery.each( text || this, function(){ 212 jQuery.each( this.childNodes, function(){ 213 if ( this.nodeType != 8 ) 214 ret += this.nodeType != 1 ? 215 this.nodeValue : 216 jQuery.fn.text( [ this ] ); 217 }); 218 }); 219 220 return ret; 221 }, 222 223 wrapAll: function( html ) { 224 if ( this[0] ) 225 // The elements to wrap the target around 226 jQuery( html, this[0].ownerDocument ) 227 .clone() 228 .insertBefore( this[0] ) 229 .map(function(){ 230 var elem = this; 231 232 while ( elem.firstChild ) 233 elem = elem.firstChild; 234 235 return elem; 236 }) 237 .append(this); 238 239 return this; 240 }, 241 242 wrapInner: function( html ) { 243 return this.each(function(){ 244 jQuery( this ).contents().wrapAll( html ); 245 }); 246 }, 247 248 wrap: function( html ) { 249 return this.each(function(){ 250 jQuery( this ).wrapAll( html ); 251 }); 252 }, 253 254 append: function() { 255 return this.domManip(arguments, true, false, function(elem){ 256 if (this.nodeType == 1) 257 this.appendChild( elem ); 258 }); 259 }, 260 261 prepend: function() { 262 return this.domManip(arguments, true, true, function(elem){ 263 if (this.nodeType == 1) 264 this.insertBefore( elem, this.firstChild ); 265 }); 266 }, 267 268 before: function() { 269 return this.domManip(arguments, false, false, function(elem){ 270 this.parentNode.insertBefore( elem, this ); 271 }); 272 }, 273 274 after: function() { 275 return this.domManip(arguments, false, true, function(elem){ 276 this.parentNode.insertBefore( elem, this.nextSibling ); 277 }); 278 }, 279 280 end: function() { 281 return this.prevObject || jQuery( [] ); 282 }, 283 284 find: function( selector ) { 285 var elems = jQuery.map(this, function(elem){ 286 return jQuery.find( selector, elem ); 287 }); 288 289 return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ? 290 jQuery.unique( elems ) : 291 elems ); 292 }, 293 294 clone: function( events ) { 295 // Do the clone 296 var ret = this.map(function(){ 297 if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) { 298 // IE copies events bound via attachEvent when 299 // using cloneNode. Calling detachEvent on the 300 // clone will also remove the events from the orignal 301 // In order to get around this, we use innerHTML. 302 // Unfortunately, this means some modifications to 303 // attributes in IE that are actually only stored 304 // as properties will not be copied (such as the 305 // the name attribute on an input). 306 var clone = this.cloneNode(true), 307 container = document.createElement("div"); 308 container.appendChild(clone); 309 return jQuery.clean([container.innerHTML])[0]; 310 } else 311 return this.cloneNode(true); 312 }); 313 314 // Need to set the expando to null on the cloned set if it exists 315 // removeData doesn't work here, IE removes it from the original as well 316 // this is primarily for IE but the data expando shouldn't be copied over in any browser 317 var clone = ret.find("*").andSelf().each(function(){ 318 if ( this[ expando ] != undefined ) 319 this[ expando ] = null; 320 }); 321 322 // Copy the events from the original to the clone 323 if ( events === true ) 324 this.find("*").andSelf().each(function(i){ 325 if (this.nodeType == 3) 326 return; 327 var events = jQuery.data( this, "events" ); 328 329 for ( var type in events ) 330 for ( var handler in events[ type ] ) 331 jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data ); 332 }); 333 334 // Return the cloned set 335 return ret; 336 }, 337 338 filter: function( selector ) { 339 return this.pushStack( 340 jQuery.isFunction( selector ) && 341 jQuery.grep(this, function(elem, i){ 342 return selector.call( elem, i ); 343 }) || 344 345 jQuery.multiFilter( selector, this ) ); 346 }, 347 348 not: function( selector ) { 349 if ( selector.constructor == String ) 350 // test special case where just one selector is passed in 351 if ( isSimple.test( selector ) ) 352 return this.pushStack( jQuery.multiFilter( selector, this, true ) ); 353 else 354 selector = jQuery.multiFilter( selector, this ); 355 356 var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType; 357 return this.filter(function() { 358 return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector; 359 }); 360 }, 361 362 add: function( selector ) { 363 return !selector ? this : this.pushStack( jQuery.merge( 364 this.get(), 365 selector.constructor == String ? 366 jQuery( selector ).get() : 367 selector.length != undefined && (!selector.nodeName || jQuery.nodeName(selector, "form")) ? 368 selector : [selector] ) ); 369 }, 370 371 is: function( selector ) { 372 return selector ? 373 jQuery.multiFilter( selector, this ).length > 0 : 374 false; 375 }, 376 377 hasClass: function( selector ) { 378 return this.is( "." + selector ); 379 }, 380 381 val: function( value ) { 382 if ( value == undefined ) { 383 384 if ( this.length ) { 385 var elem = this[0]; 386 387 // We need to handle select boxes special 388 if ( jQuery.nodeName( elem, "select" ) ) { 389 var index = elem.selectedIndex, 390 values = [], 391 options = elem.options, 392 one = elem.type == "select-one"; 393 394 // Nothing was selected 395 if ( index < 0 ) 396 return null; 397 398 // Loop through all the selected options 399 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { 400 var option = options[ i ]; 401 402 if ( option.selected ) { 403 // Get the specifc value for the option 404 value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value; 405 406 // We don't need an array for one selects 407 if ( one ) 408 return value; 409 410 // Multi-Selects return an array 411 values.push( value ); 412 } 413 } 414 415 return values; 416 417 // Everything else, we just grab the value 418 } else 419 return (this[0].value || "").replace(/\r/g, ""); 420 421 } 422 423 return undefined; 424 } 425 426 return this.each(function(){ 427 if ( this.nodeType != 1 ) 428 return; 429 430 if ( value.constructor == Array && /radio|checkbox/.test( this.type ) ) 431 this.checked = (jQuery.inArray(this.value, value) >= 0 || 432 jQuery.inArray(this.name, value) >= 0); 433 434 else if ( jQuery.nodeName( this, "select" ) ) { 435 var values = value.constructor == Array ? 436 value : 437 [ value ]; 438 439 jQuery( "option", this ).each(function(){ 440 this.selected = (jQuery.inArray( this.value, values ) >= 0 || 441 jQuery.inArray( this.text, values ) >= 0); 442 }); 443 444 if ( !values.length ) 445 this.selectedIndex = -1; 446 447 } else 448 this.value = value; 449 }); 450 }, 451 452 html: function( value ) { 453 return value == undefined ? 454 (this.length ? 455 this[0].innerHTML : 456 null) : 457 this.empty().append( value ); 458 }, 459 460 replaceWith: function( value ) { 461 return this.after( value ).remove(); 462 }, 463 464 eq: function( i ) { 465 return this.slice( i, i + 1 ); 466 }, 467 468 slice: function() { 469 return this.pushStack( Array.prototype.slice.apply( this, arguments ) ); 470 }, 471 472 map: function( callback ) { 473 return this.pushStack( jQuery.map(this, function(elem, i){ 474 return callback.call( elem, i, elem ); 475 })); 476 }, 477 478 andSelf: function() { 479 return this.add( this.prevObject ); 480 }, 481 482 data: function( key, value ){ 483 var parts = key.split("."); 484 parts[1] = parts[1] ? "." + parts[1] : ""; 485 486 if ( value == null ) { 487 var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); 488 489 if ( data == undefined && this.length ) 490 data = jQuery.data( this[0], key ); 491 492 return data == null && parts[1] ? 493 this.data( parts[0] ) : 494 data; 495 } else 496 return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){ 497 jQuery.data( this, key, value ); 498 }); 499 }, 500 501 removeData: function( key ){ 502 return this.each(function(){ 503 jQuery.removeData( this, key ); 504 }); 505 }, 506 507 domManip: function( args, table, reverse, callback ) { 508 var clone = this.length > 1, elems; 509 510 return this.each(function(){ 511 if ( !elems ) { 512 elems = jQuery.clean( args, this.ownerDocument ); 513 514 if ( reverse ) 515 elems.reverse(); 516 } 517 518 var obj = this; 519 520 if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) ) 521 obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") ); 522 523 var scripts = jQuery( [] ); 524 525 jQuery.each(elems, function(){ 526 var elem = clone ? 527 jQuery( this ).clone( true )[0] : 528 this; 529 530 // execute all scripts after the elements have been injected 531 if ( jQuery.nodeName( elem, "script" ) ) { 532 scripts = scripts.add( elem ); 533 } else { 534 // Remove any inner scripts for later evaluation 535 if ( elem.nodeType == 1 ) 536 scripts = scripts.add( jQuery( "script", elem ).remove() ); 537 538 // Inject the elements into the document 539 callback.call( obj, elem ); 540 } 541 }); 542 543 scripts.each( evalScript ); 544 }); 545 } 546 }; 547 548 // Give the init function the jQuery prototype for later instantiation 549 jQuery.prototype.init.prototype = jQuery.prototype; 550 551 function evalScript( i, elem ) { 552 if ( elem.src ) 553 jQuery.ajax({ 554 url: elem.src, 555 async: false, 556 dataType: "script" 557 }); 558 559 else 560 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); 561 562 if ( elem.parentNode ) 563 elem.parentNode.removeChild( elem ); 564 } 565 566 jQuery.extend = jQuery.fn.extend = function() { 567 // copy reference to target object 568 var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options; 569 570 // Handle a deep copy situation 571 if ( target.constructor == Boolean ) { 572 deep = target; 573 target = arguments[1] || {}; 574 // skip the boolean and the target 575 i = 2; 576 } 577 578 // Handle case when target is a string or something (possible in deep copy) 579 if ( typeof target != "object" && typeof target != "function" ) 580 target = {}; 581 582 // extend jQuery itself if only one argument is passed 583 if ( length == 1 ) { 584 target = this; 585 i = 0; 586 } 587 588 for ( ; i < length; i++ ) 589 // Only deal with non-null/undefined values 590 if ( (options = arguments[ i ]) != null ) 591 // Extend the base object 592 for ( var name in options ) { 593 // Prevent never-ending loop 594 if ( target === options[ name ] ) 595 continue; 596 597 // Recurse if we're merging object values 598 if ( deep && options[ name ] && typeof options[ name ] == "object" && target[ name ] && !options[ name ].nodeType ) 599 target[ name ] = jQuery.extend( target[ name ], options[ name ] ); 600 601 // Don't bring in undefined values 602 else if ( options[ name ] != undefined ) 603 target[ name ] = options[ name ]; 604 605 } 606 607 // Return the modified object 608 return target; 609 }; 610 611 var expando = "jQuery" + (new Date()).getTime(), uuid = 0, windowData = {}; 612 613 // exclude the following css properties to add px 614 var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i; 615 616 jQuery.extend({ 617 noConflict: function( deep ) { 618 window.$ = _$; 619 620 if ( deep ) 621 window.jQuery = _jQuery; 622 623 return jQuery; 624 }, 625 626 // See test/unit/core.js for details concerning this function. 627 isFunction: function( fn ) { 628 return !!fn && typeof fn != "string" && !fn.nodeName && 629 fn.constructor != Array && /function/i.test( fn + "" ); 630 }, 631 632 // check if an element is in a (or is an) XML document 633 isXMLDoc: function( elem ) { 634 return elem.documentElement && !elem.body || 635 elem.tagName && elem.ownerDocument && !elem.ownerDocument.body; 636 }, 637 638 // Evalulates a script in a global context 639 globalEval: function( data ) { 640 data = jQuery.trim( data ); 641 642 if ( data ) { 643 // Inspired by code by Andrea Giammarchi 644 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html 645 var head = document.getElementsByTagName("head")[0] || document.documentElement, 646 script = document.createElement("script"); 647 648 script.type = "text/javascript"; 649 if ( jQuery.browser.msie ) 650 script.text = data; 651 else 652 script.appendChild( document.createTextNode( data ) ); 653 654 head.appendChild( script ); 655 head.removeChild( script ); 656 } 657 }, 658 659 nodeName: function( elem, name ) { 660 return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase(); 661 }, 662 663 cache: {}, 664 665 data: function( elem, name, data ) { 666 elem = elem == window ? 667 windowData : 668 elem; 669 670 var id = elem[ expando ]; 671 672 // Compute a unique ID for the element 673 if ( !id ) 674 id = elem[ expando ] = ++uuid; 675 676 // Only generate the data cache if we're 677 // trying to access or manipulate it 678 if ( name && !jQuery.cache[ id ] ) 679 jQuery.cache[ id ] = {}; 680 681 // Prevent overriding the named cache with undefined values 682 if ( data != undefined ) 683 jQuery.cache[ id ][ name ] = data; 684 685 // Return the named cache data, or the ID for the element 686 return name ? 687 jQuery.cache[ id ][ name ] : 688 id; 689 }, 690 691 removeData: function( elem, name ) { 692 elem = elem == window ? 693 windowData : 694 elem; 695 696 var id = elem[ expando ]; 697 698 // If we want to remove a specific section of the element's data 699 if ( name ) { 700 if ( jQuery.cache[ id ] ) { 701 // Remove the section of cache data 702 delete jQuery.cache[ id ][ name ]; 703 704 // If we've removed all the data, remove the element's cache 705 name = ""; 706 707 for ( name in jQuery.cache[ id ] ) 708 break; 709 710 if ( !name ) 711 jQuery.removeData( elem ); 712 } 713 714 // Otherwise, we want to remove all of the element's data 715 } else { 716 // Clean up the element expando 717 try { 718 delete elem[ expando ]; 719 } catch(e){ 720 // IE has trouble directly removing the expando 721 // but it's ok with using removeAttribute 722 if ( elem.removeAttribute ) 723 elem.removeAttribute( expando ); 724 } 725 726 // Completely remove the data cache 727 delete jQuery.cache[ id ]; 728 } 729 }, 730 731 // args is for internal usage only 732 each: function( object, callback, args ) { 733 if ( args ) { 734 if ( object.length == undefined ) { 735 for ( var name in object ) 736 if ( callback.apply( object[ name ], args ) === false ) 737 break; 738 } else 739 for ( var i = 0, length = object.length; i < length; i++ ) 740 if ( callback.apply( object[ i ], args ) === false ) 741 break; 742 743 // A special, fast, case for the most common use of each 744 } else { 745 if ( object.length == undefined ) { 746 for ( var name in object ) 747 if ( callback.call( object[ name ], name, object[ name ] ) === false ) 748 break; 749 } else 750 for ( var i = 0, length = object.length, value = object[0]; 751 i < length && callback.call( value, i, value ) !== false; value = object[++i] ){} 752 } 753 754 return object; 755 }, 756 757 prop: function( elem, value, type, i, name ) { 758 // Handle executable functions 759 if ( jQuery.isFunction( value ) ) 760 value = value.call( elem, i ); 761 762 // Handle passing in a number to a CSS property 763 return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ? 764 value + "px" : 765 value; 766 }, 767 768 className: { 769 // internal only, use addClass("class") 770 add: function( elem, classNames ) { 771 jQuery.each((classNames || "").split(/\s+/), function(i, className){ 772 if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) ) 773 elem.className += (elem.className ? " " : "") + className; 774 }); 775 }, 776 777 // internal only, use removeClass("class") 778 remove: function( elem, classNames ) { 779 if (elem.nodeType == 1) 780 elem.className = classNames != undefined ? 781 jQuery.grep(elem.className.split(/\s+/), function(className){ 782 return !jQuery.className.has( classNames, className ); 783 }).join(" ") : 784 ""; 785 }, 786 787 // internal only, use is(".class") 788 has: function( elem, className ) { 789 return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1; 790 } 791 }, 792 793 // A method for quickly swapping in/out CSS properties to get correct calculations 794 swap: function( elem, options, callback ) { 795 var old = {}; 796 // Remember the old values, and insert the new ones 797 for ( var name in options ) { 798 old[ name ] = elem.style[ name ]; 799 elem.style[ name ] = options[ name ]; 800 } 801 802 callback.call( elem ); 803 804 // Revert the old values 805 for ( var name in options ) 806 elem.style[ name ] = old[ name ]; 807 }, 808 809 css: function( elem, name, force ) { 810 if ( name == "width" || name == "height" ) { 811 var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ]; 812 813 function getWH() { 814 val = name == "width" ? elem.offsetWidth : elem.offsetHeight; 815 var padding = 0, border = 0; 816 jQuery.each( which, function() { 817 padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0; 818 border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0; 819 }); 820 val -= Math.round(padding + border); 821 } 822 823 if ( jQuery(elem).is(":visible") ) 824 getWH(); 825 else 826 jQuery.swap( elem, props, getWH ); 827 828 return Math.max(0, val); 829 } 830 831 return jQuery.curCSS( elem, name, force ); 832 }, 833 834 curCSS: function( elem, name, force ) { 835 var ret; 836 837 // A helper method for determining if an element's values are broken 838 function color( elem ) { 839 if ( !jQuery.browser.safari ) 840 return false; 841 842 var ret = document.defaultView.getComputedStyle( elem, null ); 843 return !ret || ret.getPropertyValue("color") == ""; 844 } 845 846 // We need to handle opacity special in IE 847 if ( name == "opacity" && jQuery.browser.msie ) { 848 ret = jQuery.attr( elem.style, "opacity" ); 849 850 return ret == "" ? 851 "1" : 852 ret; 853 } 854 // Opera sometimes will give the wrong display answer, this fixes it, see #2037 855 if ( jQuery.browser.opera && name == "display" ) { 856 var save = elem.style.outline; 857 elem.style.outline = "0 solid black"; 858 elem.style.outline = save; 859 } 860 861 // Make sure we're using the right name for getting the float value 862 if ( name.match( /float/i ) ) 863 name = styleFloat; 864 865 if ( !force && elem.style && elem.style[ name ] ) 866 ret = elem.style[ name ]; 867 868 else if ( document.defaultView && document.defaultView.getComputedStyle ) { 869 870 // Only "float" is needed here 871 if ( name.match( /float/i ) ) 872 name = "float"; 873 874 name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase(); 875 876 var getComputedStyle = document.defaultView.getComputedStyle( elem, null ); 877 878 if ( getComputedStyle && !color( elem ) ) 879 ret = getComputedStyle.getPropertyValue( name ); 880 881 // If the element isn't reporting its values properly in Safari 882 // then some display: none elements are involved 883 else { 884 var swap = [], stack = []; 885 886 // Locate all of the parent display: none elements 887 for ( var a = elem; a && color(a); a = a.parentNode ) 888 stack.unshift(a); 889 890 // Go through and make them visible, but in reverse 891 // (It would be better if we knew the exact display type that they had) 892 for ( var i = 0; i < stack.length; i++ ) 893 if ( color( stack[ i ] ) ) { 894 swap[ i ] = stack[ i ].style.display; 895 stack[ i ].style.display = "block"; 896 } 897 898 // Since we flip the display style, we have to handle that 899 // one special, otherwise get the value 900 ret = name == "display" && swap[ stack.length - 1 ] != null ? 901 "none" : 902 ( getComputedStyle && getComputedStyle.getPropertyValue( name ) ) || ""; 903 904 // Finally, revert the display styles back 905 for ( var i = 0; i < swap.length; i++ ) 906 if ( swap[ i ] != null ) 907 stack[ i ].style.display = swap[ i ]; 908 } 909 910 // We should always get a number back from opacity 911 if ( name == "opacity" && ret == "" ) 912 ret = "1"; 913 914 } else if ( elem.currentStyle ) { 915 var camelCase = name.replace(/\-(\w)/g, function(all, letter){ 916 return letter.toUpperCase(); 917 }); 918 919 ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ]; 920 921 // From the awesome hack by Dean Edwards 922 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 923 924 // If we're not dealing with a regular pixel number 925 // but a number that has a weird ending, we need to convert it to pixels 926 if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) { 927 // Remember the original values 928 var style = elem.style.left, runtimeStyle = elem.runtimeStyle.left; 929 930 // Put in the new values to get a computed value out 931 elem.runtimeStyle.left = elem.currentStyle.left; 932 elem.style.left = ret || 0; 933 ret = elem.style.pixelLeft + "px"; 934 935 // Revert the changed values 936 elem.style.left = style; 937 elem.runtimeStyle.left = runtimeStyle; 938 } 939 } 940 941 return ret; 942 }, 943 944 clean: function( elems, context ) { 945 var ret = []; 946 context = context || document; 947 // !context.createElement fails in IE with an error but returns typeof 'object' 948 if (typeof context.createElement == 'undefined') 949 context = context.ownerDocument || context[0] && context[0].ownerDocument || document; 950 951 jQuery.each(elems, function(i, elem){ 952 if ( !elem ) 953 return; 954 955 if ( elem.constructor == Number ) 956 elem = elem.toString(); 957 958 // Convert html string into DOM nodes 959 if ( typeof elem == "string" ) { 960 // Fix "XHTML"-style tags in all browsers 961 elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){ 962 return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ? 963 all : 964 front + "></" + tag + ">"; 965 }); 966 967 // Trim whitespace, otherwise indexOf won't work as expected 968 var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div"); 969 970 var wrap = 971 // option or optgroup 972 !tags.indexOf("<opt") && 973 [ 1, "<select multiple='multiple'>", "</select>" ] || 974 975 !tags.indexOf("<leg") && 976 [ 1, "<fieldset>", "</fieldset>" ] || 977 978 tags.match(/^<(thead|tbody|tfoot|colg|cap)/) && 979 [ 1, "<table>", "</table>" ] || 980 981 !tags.indexOf("<tr") && 982 [ 2, "<table><tbody>", "</tbody></table>" ] || 983 984 // <thead> matched above 985 (!tags.indexOf("<td") || !tags.indexOf("<th")) && 986 [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] || 987 988 !tags.indexOf("<col") && 989 [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] || 990 991 // IE can't serialize <link> and <script> tags normally 992 jQuery.browser.msie && 993 [ 1, "div<div>", "</div>" ] || 994 995 [ 0, "", "" ]; 996 997 // Go to html and back, then peel off extra wrappers 998 div.innerHTML = wrap[1] + elem + wrap[2]; 999 1000 // Move to the right depth 1001 while ( wrap[0]-- ) 1002 div = div.lastChild; 1003 1004 // Remove IE's autoinserted <tbody> from table fragments 1005 if ( jQuery.browser.msie ) { 1006 1007 // String was a <table>, *may* have spurious <tbody> 1008 var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ? 1009 div.firstChild && div.firstChild.childNodes : 1010 1011 // String was a bare <thead> or <tfoot> 1012 wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ? 1013 div.childNodes : 1014 []; 1015 1016 for ( var j = tbody.length - 1; j >= 0 ; --j ) 1017 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) 1018 tbody[ j ].parentNode.removeChild( tbody[ j ] ); 1019 1020 // IE completely kills leading whitespace when innerHTML is used 1021 if ( /^\s/.test( elem ) ) 1022 div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild ); 1023 1024 } 1025 1026 elem = jQuery.makeArray( div.childNodes ); 1027 } 1028 1029 if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) ) 1030 return; 1031 1032 if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options ) 1033 ret.push( elem ); 1034 1035 else 1036 ret = jQuery.merge( ret, elem ); 1037 1038 }); 1039 1040 return ret; 1041 }, 1042 1043 attr: function( elem, name, value ) { 1044 // don't set attributes on text and comment nodes 1045 if (!elem || elem.nodeType == 3 || elem.nodeType == 8) 1046 return undefined; 1047 1048 var fix = jQuery.isXMLDoc( elem ) ? 1049 {} : 1050 jQuery.props; 1051 1052 // Safari mis-reports the default selected property of a hidden option 1053 // Accessing the parent's selectedIndex property fixes it 1054 if ( name == "selected" && jQuery.browser.safari ) 1055 elem.parentNode.selectedIndex; 1056 1057 // Certain attributes only work when accessed via the old DOM 0 way 1058 if ( fix[ name ] ) { 1059 if ( value != undefined ) 1060 elem[ fix[ name ] ] = value; 1061 1062 return elem[ fix[ name ] ]; 1063 1064 } else if ( jQuery.browser.msie && name == "style" ) 1065 return jQuery.attr( elem.style, "cssText", value ); 1066 1067 else if ( value == undefined && jQuery.browser.msie && jQuery.nodeName( elem, "form" ) && (name == "action" || name == "method") ) 1068 return elem.getAttributeNode( name ).nodeValue; 1069 1070 // IE elem.getAttribute passes even for style 1071 else if ( elem.tagName ) { 1072 1073 if ( value != undefined ) { 1074 // We can't allow the type property to be changed (since it causes problems in IE) 1075 if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode ) 1076 throw "type property can't be changed"; 1077 1078 // convert the value to a string (all browsers do this but IE) see #1070 1079 elem.setAttribute( name, "" + value ); 1080 } 1081 1082 if ( jQuery.browser.msie && /href|src/.test( name ) && !jQuery.isXMLDoc( elem ) ) 1083 return elem.getAttribute( name, 2 ); 1084 1085 return elem.getAttribute( name ); 1086 1087 // elem is actually elem.style ... set the style 1088 } else { 1089 // IE actually uses filters for opacity 1090 if ( name == "opacity" && jQuery.browser.msie ) { 1091 if ( value != undefined ) { 1092 // IE has trouble with opacity if it does not have layout 1093 // Force it by setting the zoom level 1094 elem.zoom = 1; 1095 1096 // Set the alpha filter to set the opacity 1097 elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) + 1098 (parseFloat( value ).toString() == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")"); 1099 } 1100 1101 return elem.filter && elem.filter.indexOf("opacity=") >= 0 ? 1102 (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100).toString() : 1103 ""; 1104 } 1105 1106 name = name.replace(/-([a-z])/ig, function(all, letter){ 1107 return letter.toUpperCase(); 1108 }); 1109 1110 if ( value != undefined ) 1111 elem[ name ] = value; 1112 1113 return elem[ name ]; 1114 } 1115 }, 1116 1117 trim: function( text ) { 1118 return (text || "").replace( /^\s+|\s+$/g, "" ); 1119 }, 1120 1121 makeArray: function( array ) { 1122 var ret = []; 1123 1124 // Need to use typeof to fight Safari childNodes crashes 1125 if ( typeof array != "array" ) 1126 for ( var i = 0, length = array.length; i < length; i++ ) 1127 ret.push( array[ i ] ); 1128 else 1129 ret = array.slice( 0 ); 1130 1131 return ret; 1132 }, 1133 1134 inArray: function( elem, array ) { 1135 for ( var i = 0, length = array.length; i < length; i++ ) 1136 if ( array[ i ] == elem ) 1137 return i; 1138 1139 return -1; 1140 }, 1141 1142 merge: function( first, second ) { 1143 // We have to loop this way because IE & Opera overwrite the length 1144 // expando of getElementsByTagName 1145 1146 // Also, we need to make sure that the correct elements are being returned 1147 // (IE returns comment nodes in a '*' query) 1148 if ( jQuery.browser.msie ) { 1149 for ( var i = 0; second[ i ]; i++ ) 1150 if ( second[ i ].nodeType != 8 ) 1151 first.push( second[ i ] ); 1152 1153 } else 1154 for ( var i = 0; second[ i ]; i++ ) 1155 first.push( second[ i ] ); 1156 1157 return first; 1158 }, 1159 1160 unique: function( array ) { 1161 var ret = [], done = {}; 1162 1163 try { 1164 1165 for ( var i = 0, length = array.length; i < length; i++ ) { 1166 var id = jQuery.data( array[ i ] ); 1167 1168 if ( !done[ id ] ) { 1169 done[ id ] = true; 1170 ret.push( array[ i ] ); 1171 } 1172 } 1173 1174 } catch( e ) { 1175 ret = array; 1176 } 1177 1178 return ret; 1179 }, 1180 1181 grep: function( elems, callback, inv ) { 1182 var ret = []; 1183 1184 // Go through the array, only saving the items 1185 // that pass the validator function 1186 for ( var i = 0, length = elems.length; i < length; i++ ) 1187 if ( !inv && callback( elems[ i ], i ) || inv && !callback( elems[ i ], i ) ) 1188 ret.push( elems[ i ] ); 1189 1190 return ret; 1191 }, 1192 1193 map: function( elems, callback ) { 1194 var ret = []; 1195 1196 // Go through the array, translating each of the items to their 1197 // new value (or values). 1198 for ( var i = 0, length = elems.length; i < length; i++ ) { 1199 var value = callback( elems[ i ], i ); 1200 1201 if ( value !== null && value != undefined ) { 1202 if ( value.constructor != Array ) 1203 value = [ value ]; 1204 1205 ret = ret.concat( value ); 1206 } 1207 } 1208 1209 return ret; 1210 } 1211 }); 1212 1213 var userAgent = navigator.userAgent.toLowerCase(); 1214 1215 // Figure out what browser is being used 1216 jQuery.browser = { 1217 version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1], 1218 safari: /webkit/.test( userAgent ), 1219 opera: /opera/.test( userAgent ), 1220 msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ), 1221 mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent ) 1222 }; 1223 1224 var styleFloat = jQuery.browser.msie ? 1225 "styleFloat" : 1226 "cssFloat"; 1227 1228 jQuery.extend({ 1229 // Check to see if the W3C box model is being used 1230 boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat", 1231 1232 props: { 1233 "for": "htmlFor", 1234 "class": "className", 1235 "float": styleFloat, 1236 cssFloat: styleFloat, 1237 styleFloat: styleFloat, 1238 innerHTML: "innerHTML", 1239 className: "className", 1240 value: "value", 1241 disabled: "disabled", 1242 checked: "checked", 1243 readonly: "readOnly", 1244 selected: "selected", 1245 maxlength: "maxLength", 1246 selectedIndex: "selectedIndex", 1247 defaultValue: "defaultValue", 1248 tagName: "tagName", 1249 nodeName: "nodeName" 1250 } 1251 }); 1252 1253 jQuery.each({ 1254 parent: function(elem){return elem.parentNode;}, 1255 parents: function(elem){return jQuery.dir(elem,"parentNode");}, 1256 next: function(elem){return jQuery.nth(elem,2,"nextSibling");}, 1257 prev: function(elem){return jQuery.nth(elem,2,"previousSibling");}, 1258 nextAll: function(elem){return jQuery.dir(elem,"nextSibling");}, 1259 prevAll: function(elem){return jQuery.dir(elem,"previousSibling");}, 1260 siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);}, 1261 children: function(elem){return jQuery.sibling(elem.firstChild);}, 1262 contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);} 1263 }, function(name, fn){ 1264 jQuery.fn[ name ] = function( selector ) { 1265 var ret = jQuery.map( this, fn ); 1266 1267 if ( selector && typeof selector == "string" ) 1268 ret = jQuery.multiFilter( selector, ret ); 1269 1270 return this.pushStack( jQuery.unique( ret ) ); 1271 }; 1272 }); 1273 1274 jQuery.each({ 1275 appendTo: "append", 1276 prependTo: "prepend", 1277 insertBefore: "before", 1278 insertAfter: "after", 1279 replaceAll: "replaceWith" 1280 }, function(name, original){ 1281 jQuery.fn[ name ] = function() { 1282 var args = arguments; 1283 1284 return this.each(function(){ 1285 for ( var i = 0, length = args.length; i < length; i++ ) 1286 jQuery( args[ i ] )[ original ]( this ); 1287 }); 1288 }; 1289 }); 1290 1291 jQuery.each({ 1292 removeAttr: function( name ) { 1293 jQuery.attr( this, name, "" ); 1294 if (this.nodeType == 1) 1295 this.removeAttribute( name ); 1296 }, 1297 1298 addClass: function( classNames ) { 1299 jQuery.className.add( this, classNames ); 1300 }, 1301 1302 removeClass: function( classNames ) { 1303 jQuery.className.remove( this, classNames ); 1304 }, 1305 1306 toggleClass: function( classNames ) { 1307 jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames ); 1308 }, 1309 1310 remove: function( selector ) { 1311 if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) { 1312 // Prevent memory leaks 1313 jQuery( "*", this ).add(this).each(function(){ 1314 jQuery.event.remove(this); 1315 jQuery.removeData(this); 1316 }); 1317 if (this.parentNode) 1318 this.parentNode.removeChild( this ); 1319 } 1320 }, 1321 1322 empty: function() { 1323 // Remove element nodes and prevent memory leaks 1324 jQuery( ">*", this ).remove(); 1325 1326 // Remove any remaining nodes 1327 while ( this.firstChild ) 1328 this.removeChild( this.firstChild ); 1329 } 1330 }, function(name, fn){ 1331 jQuery.fn[ name ] = function(){ 1332 return this.each( fn, arguments ); 1333 }; 1334 }); 1335 1336 jQuery.each([ "Height", "Width" ], function(i, name){ 1337 var type = name.toLowerCase(); 1338 1339 jQuery.fn[ type ] = function( size ) { 1340 // Get window width or height 1341 return this[0] == window ? 1342 // Opera reports document.body.client[Width/Height] properly in both quirks and standards 1343 jQuery.browser.opera && document.body[ "client" + name ] || 1344 1345 // Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths) 1346 jQuery.browser.safari && window[ "inner" + name ] || 1347 1348 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode 1349 document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] : 1350 1351 // Get document width or height 1352 this[0] == document ? 1353 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater 1354 Math.max( 1355 Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]), 1356 Math.max(document.body["offset" + name], document.documentElement["offset" + name]) 1357 ) : 1358 1359 // Get or set width or height on the element 1360 size == undefined ? 1361 // Get width or height on the element 1362 (this.length ? jQuery.css( this[0], type ) : null) : 1363 1364 // Set the width or height on the element (default to pixels if value is unitless) 1365 this.css( type, size.constructor == String ? size : size + "px" ); 1366 }; 1367 }); 1368 1369 var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ? 1370 "(?:[\\w*_-]|\\\\.)" : 1371 "(?:[\\w\u0128-\uFFFF*_-]|\\\\.)", 1372 quickChild = new RegExp("^>\\s*(" + chars + "+)"), 1373 quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"), 1374 quickClass = new RegExp("^([#.]?)(" + chars + "*)"); 1375 1376 jQuery.extend({ 1377 expr: { 1378 "": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);}, 1379 "#": function(a,i,m){return a.getAttribute("id")==m[2];}, 1380 ":": { 1381 // Position Checks 1382 lt: function(a,i,m){return i<m[3]-0;}, 1383 gt: function(a,i,m){return i>m[3]-0;}, 1384 nth: function(a,i,m){return m[3]-0==i;}, 1385 eq: function(a,i,m){return m[3]-0==i;}, 1386 first: function(a,i){return i==0;}, 1387 last: function(a,i,m,r){return i==r.length-1;}, 1388 even: function(a,i){return i%2==0;}, 1389 odd: function(a,i){return i%2;}, 1390 1391 // Child Checks 1392 "first-child": function(a){return a.parentNode.getElementsByTagName("*")[0]==a;}, 1393 "last-child": function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;}, 1394 "only-child": function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");}, 1395 1396 // Parent Checks 1397 parent: function(a){return a.firstChild;}, 1398 empty: function(a){return !a.firstChild;}, 1399 1400 // Text Check 1401 contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;}, 1402 1403 // Visibility 1404 visible: function(a){return "hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";}, 1405 hidden: function(a){return "hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";}, 1406 1407 // Form attributes 1408 enabled: function(a){return !a.disabled;}, 1409 disabled: function(a){return a.disabled;}, 1410 checked: function(a){return a.checked;}, 1411 selected: function(a){return a.selected||jQuery.attr(a,"selected");}, 1412 1413 // Form elements 1414 text: function(a){return "text"==a.type;}, 1415 radio: function(a){return "radio"==a.type;}, 1416 checkbox: function(a){return "checkbox"==a.type;}, 1417 file: function(a){return "file"==a.type;}, 1418 password: function(a){return "password"==a.type;}, 1419 submit: function(a){return "submit"==a.type;}, 1420 image: function(a){return "image"==a.type;}, 1421 reset: function(a){return "reset"==a.type;}, 1422 button: function(a){return "button"==a.type||jQuery.nodeName(a,"button");}, 1423 input: function(a){return /input|select|textarea|button/i.test(a.nodeName);}, 1424 1425 // :has() 1426 has: function(a,i,m){return jQuery.find(m[3],a).length;}, 1427 1428 // :header 1429 header: function(a){return /h\d/i.test(a.nodeName);}, 1430 1431 // :animated 1432 animated: function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;} 1433 } 1434 }, 1435 1436 // The regular expressions that power the parsing engine 1437 parse: [ 1438 // Match: [@value='test'], [@foo] 1439 /^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/, 1440 1441 // Match: :contains('foo') 1442 /^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/, 1443 1444 // Match: :even, :last-chlid, #id, .class 1445 new RegExp("^([:.#]*)(" + chars + "+)") 1446 ], 1447 1448 multiFilter: function( expr, elems, not ) { 1449 var old, cur = []; 1450 1451 while ( expr && expr != old ) { 1452 old = expr; 1453 var f = jQuery.filter( expr, elems, not ); 1454 expr = f.t.replace(/^\s*,\s*/, "" ); 1455 cur = not ? elems = f.r : jQuery.merge( cur, f.r ); 1456 } 1457 1458 return cur; 1459 }, 1460 1461 find: function( t, context ) { 1462 // Quickly handle non-string expressions 1463 if ( typeof t != "string" ) 1464 return [ t ]; 1465 1466 // check to make sure context is a DOM element or a document 1467 if ( context && context.nodeType != 1 && context.nodeType != 9) 1468 return [ ]; 1469 1470 // Set the correct context (if none is provided) 1471 context = context || document; 1472 1473 // Initialize the search 1474 var ret = [context], done = [], last, nodeName; 1475 1476 // Continue while a selector expression exists, and while 1477 // we're no longer looping upon ourselves 1478 while ( t && last != t ) { 1479 var r = []; 1480 last = t; 1481 1482 t = jQuery.trim(t); 1483 1484 var foundToken = false; 1485 1486 // An attempt at speeding up child selectors that 1487 // point to a specific element tag 1488 var re = quickChild; 1489 var m = re.exec(t); 1490 1491 if ( m ) { 1492 nodeName = m[1].toUpperCase(); 1493 1494 // Perform our own iteration and filter 1495 for ( var i = 0; ret[i]; i++ ) 1496 for ( var c = ret[i].firstChild; c; c = c.nextSibling ) 1497 if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) ) 1498 r.push( c ); 1499 1500 ret = r; 1501 t = t.replace( re, "" ); 1502 if ( t.indexOf(" ") == 0 ) continue; 1503 foundToken = true; 1504 } else { 1505 re = /^([>+~])\s*(\w*)/i; 1506 1507 if ( (m = re.exec(t)) != null ) { 1508 r = []; 1509 1510 var merge = {}; 1511 nodeName = m[2].toUpperCase(); 1512 m = m[1]; 1513 1514 for ( var j = 0, rl = ret.length; j < rl; j++ ) { 1515 var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild; 1516 for ( ; n; n = n.nextSibling ) 1517 if ( n.nodeType == 1 ) { 1518 var id = jQuery.data(n); 1519 1520 if ( m == "~" && merge[id] ) break; 1521 1522 if (!nodeName || n.nodeName.toUpperCase() == nodeName ) { 1523 if ( m == "~" ) merge[id] = true; 1524 r.push( n ); 1525 } 1526 1527 if ( m == "+" ) break; 1528 } 1529 } 1530 1531 ret = r; 1532 1533 // And remove the token 1534 t = jQuery.trim( t.replace( re, "" ) ); 1535 foundToken = true; 1536 } 1537 } 1538 1539 // See if there's still an expression, and that we haven't already 1540 // matched a token 1541 if ( t && !foundToken ) { 1542 // Handle multiple expressions 1543 if ( !t.indexOf(",") ) { 1544 // Clean the result set 1545 if ( context == ret[0] ) ret.shift(); 1546 1547 // Merge the result sets 1548 done = jQuery.merge( done, ret ); 1549 1550 // Reset the context 1551 r = ret = [context]; 1552 1553 // Touch up the selector string 1554 t = " " + t.substr(1,t.length); 1555 1556 } else { 1557 // Optimize for the case nodeName#idName 1558 var re2 = quickID; 1559 var m = re2.exec(t); 1560 1561 // Re-organize the results, so that they're consistent 1562 if ( m ) { 1563 m = [ 0, m[2], m[3], m[1] ]; 1564 1565 } else { 1566 // Otherwise, do a traditional filter check for 1567 // ID, class, and element selectors 1568 re2 = quickClass; 1569 m = re2.exec(t); 1570 } 1571 1572 m[2] = m[2].replace(/\\/g, ""); 1573 1574 var elem = ret[ret.length-1]; 1575 1576 // Try to do a global search by ID, where we can 1577 if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) { 1578 // Optimization for HTML document case 1579 var oid = elem.getElementById(m[2]); 1580 1581 // Do a quick check for the existence of the actual ID attribute 1582 // to avoid selecting by the name attribute in IE 1583 // also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form 1584 if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] ) 1585 oid = jQuery('[@id="'+m[2]+'"]', elem)[0]; 1586 1587 // Do a quick check for node name (where applicable) so 1588 // that div#foo searches will be really fast 1589 ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : []; 1590 } else { 1591 // We need to find all descendant elements 1592 for ( var i = 0; ret[i]; i++ ) { 1593 // Grab the tag name being searched for 1594 var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2]; 1595 1596 // Handle IE7 being really dumb about <object>s 1597 if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" ) 1598 tag = "param"; 1599 1600 r = jQuery.merge( r, ret[i].getElementsByTagName( tag )); 1601 } 1602 1603 // It's faster to filter by class and be done with it 1604 if ( m[1] == "." ) 1605 r = jQuery.classFilter( r, m[2] ); 1606 1607 // Same with ID filtering 1608 if ( m[1] == "#" ) { 1609 var tmp = []; 1610 1611 // Try to find the element with the ID 1612 for ( var i = 0; r[i]; i++ ) 1613 if ( r[i].getAttribute("id") == m[2] ) { 1614 tmp = [ r[i] ]; 1615 break; 1616 } 1617 1618 r = tmp; 1619 } 1620 1621 ret = r; 1622 } 1623 1624 t = t.replace( re2, "" ); 1625 } 1626 1627 } 1628 1629 // If a selector string still exists 1630 if ( t ) { 1631 // Attempt to filter it 1632 var val = jQuery.filter(t,r); 1633 ret = r = val.r; 1634 t = jQuery.trim(val.t); 1635 } 1636 } 1637 1638 // An error occurred with the selector; 1639 // just return an empty set instead 1640 if ( t ) 1641 ret = []; 1642 1643 // Remove the root context 1644 if ( ret && context == ret[0] ) 1645 ret.shift(); 1646 1647 // And combine the results 1648 done = jQuery.merge( done, ret ); 1649 1650 return done; 1651 }, 1652 1653 classFilter: function(r,m,not){ 1654 m = " " + m + " "; 1655 var tmp = []; 1656 for ( var i = 0; r[i]; i++ ) { 1657 var pass = (" " + r[i].className + " ").indexOf( m ) >= 0; 1658 if ( !not && pass || not && !pass ) 1659 tmp.push( r[i] ); 1660 } 1661 return tmp; 1662 }, 1663 1664 filter: function(t,r,not) { 1665 var last; 1666 1667 // Look for common filter expressions 1668 while ( t && t != last ) { 1669 last = t; 1670 1671 var p = jQuery.parse, m; 1672 1673 for ( var i = 0; p[i]; i++ ) { 1674 m = p[i].exec( t ); 1675 1676 if ( m ) { 1677 // Remove what we just matched 1678 t = t.substring( m[0].length ); 1679 1680 m[2] = m[2].replace(/\\/g, ""); 1681 break; 1682 } 1683 } 1684 1685 if ( !m ) 1686 break; 1687 1688 // :not() is a special case that can be optimized by 1689 // keeping it out of the expression list 1690 if ( m[1] == ":" && m[2] == "not" ) 1691 // optimize if only one selector found (most common case) 1692 r = isSimple.test( m[3] ) ? 1693 jQuery.filter(m[3], r, true).r : 1694 jQuery( r ).not( m[3] ); 1695 1696 // We can get a big speed boost by filtering by class here 1697 else if ( m[1] == "." ) 1698 r = jQuery.classFilter(r, m[2], not); 1699 1700 else if ( m[1] == "[" ) { 1701 var tmp = [], type = m[3]; 1702 1703 for ( var i = 0, rl = r.length; i < rl; i++ ) { 1704 var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ]; 1705 1706 if ( z == null || /href|src|selected/.test(m[2]) ) 1707 z = jQuery.attr(a,m[2]) || ''; 1708 1709 if ( (type == "" && !!z || 1710 type == "=" && z == m[5] || 1711 type == "!=" && z != m[5] || 1712 type == "^=" && z && !z.indexOf(m[5]) || 1713 type == "$=" && z.substr(z.length - m[5].length) == m[5] || 1714 (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not ) 1715 tmp.push( a ); 1716 } 1717 1718 r = tmp; 1719 1720 // We can get a speed boost by handling nth-child here 1721 } else if ( m[1] == ":" && m[2] == "nth-child" ) { 1722 var merge = {}, tmp = [], 1723 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' 1724 test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec( 1725 m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" || 1726 !/\D/.test(m[3]) && "0n+" + m[3] || m[3]), 1727 // calculate the numbers (first)n+(last) including if they are negative 1728 first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0; 1729 1730 // loop through all the elements left in the jQuery object 1731 for ( var i = 0, rl = r.length; i < rl; i++ ) { 1732 var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode); 1733 1734 if ( !merge[id] ) { 1735 var c = 1; 1736 1737 for ( var n = parentNode.firstChild; n; n = n.nextSibling ) 1738 if ( n.nodeType == 1 ) 1739 n.nodeIndex = c++; 1740 1741 merge[id] = true; 1742 } 1743 1744 var add = false; 1745 1746 if ( first == 0 ) { 1747 if ( node.nodeIndex == last ) 1748 add = true; 1749 } else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 ) 1750 add = true; 1751 1752 if ( add ^ not ) 1753 tmp.push( node ); 1754 } 1755 1756 r = tmp; 1757 1758 // Otherwise, find the expression to execute 1759 } else { 1760 var fn = jQuery.expr[ m[1] ]; 1761 if ( typeof fn == "object" ) 1762 fn = fn[ m[2] ]; 1763 1764 if ( typeof fn == "string" ) 1765 fn = eval("false||function(a,i){return " + fn + ";}"); 1766 1767 // Execute it against the current filter 1768 r = jQuery.grep( r, function(elem, i){ 1769 return fn(elem, i, m, r); 1770 }, not ); 1771 } 1772 } 1773 1774 // Return an array of filtered elements (r) 1775 // and the modified expression string (t) 1776 return { r: r, t: t }; 1777 }, 1778 1779 dir: function( elem, dir ){ 1780 var matched = []; 1781 var cur = elem[dir]; 1782 while ( cur && cur != document ) { 1783 if ( cur.nodeType == 1 ) 1784 matched.push( cur ); 1785 cur = cur[dir]; 1786 } 1787 return matched; 1788 }, 1789 1790 nth: function(cur,result,dir,elem){ 1791 result = result || 1; 1792 var num = 0; 1793 1794 for ( ; cur; cur = cur[dir] ) 1795 if ( cur.nodeType == 1 && ++num == result ) 1796 break; 1797 1798 return cur; 1799 }, 1800 1801 sibling: function( n, elem ) { 1802 var r = []; 1803 1804 for ( ; n; n = n.nextSibling ) { 1805 if ( n.nodeType == 1 && (!elem || n != elem) ) 1806 r.push( n ); 1807 } 1808 1809 return r; 1810 } 1811 }); 1812 1813 /* 1814 * A number of helper functions used for managing events. 1815 * Many of the ideas behind this code orignated from 1816 * Dean Edwards' addEvent library. 1817 */ 1818 jQuery.event = { 1819 1820 // Bind an event to an element 1821 // Original by Dean Edwards 1822 add: function(elem, types, handler, data) { 1823 if ( elem.nodeType == 3 || elem.nodeType == 8 ) 1824 return; 1825 1826 // For whatever reason, IE has trouble passing the window object 1827 // around, causing it to be cloned in the process 1828 if ( jQuery.browser.msie && elem.setInterval != undefined ) 1829 elem = window; 1830 1831 // Make sure that the function being executed has a unique ID 1832 if ( !handler.guid ) 1833 handler.guid = this.guid++; 1834 1835 // if data is passed, bind to handler 1836 if( data != undefined ) { 1837 // Create temporary function pointer to original handler 1838 var fn = handler; 1839 1840 // Create unique handler function, wrapped around original handler 1841 handler = function() { 1842 // Pass arguments and context to original handler 1843 return fn.apply(this, arguments); 1844 }; 1845 1846 // Store data in unique handler 1847 handler.data = data; 1848 1849 // Set the guid of unique handler to the same of original handler, so it can be removed 1850 handler.guid = fn.guid; 1851 } 1852 1853 // Init the element's event structure 1854 var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}), 1855 handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){ 1856 // returned undefined or false 1857 var val; 1858 1859 // Handle the second event of a trigger and when 1860 // an event is called after a page has unloaded 1861 if ( typeof jQuery == "undefined" || jQuery.event.triggered ) 1862 return val; 1863 1864 val = jQuery.event.handle.apply(arguments.callee.elem, arguments); 1865 1866 return val; 1867 }); 1868 // Add elem as a property of the handle function 1869 // This is to prevent a memory leak with non-native 1870 // event in IE. 1871 handle.elem = elem; 1872 1873 // Handle multiple events seperated by a space 1874 // jQuery(...).bind("mouseover mouseout", fn); 1875 jQuery.each(types.split(/\s+/), function(index, type) { 1876 // Namespaced event handlers 1877 var parts = type.split("."); 1878 type = parts[0]; 1879 handler.type = parts[1]; 1880 1881 // Get the current list of functions bound to this event 1882 var handlers = events[type]; 1883 1884 // Init the event handler queue 1885 if (!handlers) { 1886 handlers = events[type] = {}; 1887 1888 // Check for a special event handler 1889 // Only use addEventListener/attachEvent if the special 1890 // events handler returns false 1891 if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) { 1892 // Bind the global event handler to the element 1893 if (elem.addEventListener) 1894 elem.addEventListener(type, handle, false); 1895 else if (elem.attachEvent) 1896 elem.attachEvent("on" + type, handle); 1897 } 1898 } 1899 1900 // Add the function to the element's handler list 1901 handlers[handler.guid] = handler; 1902 1903 // Keep track of which events have been used, for global triggering 1904 jQuery.event.global[type] = true; 1905 }); 1906 1907 // Nullify elem to prevent memory leaks in IE 1908 elem = null; 1909 }, 1910 1911 guid: 1, 1912 global: {}, 1913 1914 // Detach an event or set of events from an element 1915 remove: function(elem, types, handler) { 1916 // don't do events on text and comment nodes 1917 if ( elem.nodeType == 3 || elem.nodeType == 8 ) 1918 return; 1919 1920 var events = jQuery.data(elem, "events"), ret, index; 1921 1922 if ( events ) { 1923 // Unbind all events for the element 1924 if ( types == undefined || (typeof types == "string" && types.charAt(0) == ".") ) 1925 for ( var type in events ) 1926 this.remove( elem, type + (types || "") ); 1927 else { 1928 // types is actually an event object here 1929 if ( types.type ) { 1930 handler = types.handler; 1931 types = types.type; 1932 } 1933 1934 // Handle multiple events seperated by a space 1935 // jQuery(...).unbind("mouseover mouseout", fn); 1936 jQuery.each(types.split(/\s+/), function(index, type){ 1937 // Namespaced event handlers 1938 var parts = type.split("."); 1939 type = parts[0]; 1940 1941 if ( events[type] ) { 1942 // remove the given handler for the given type 1943 if ( handler ) 1944 delete events[type][handler.guid]; 1945 1946 // remove all handlers for the given type 1947 else 1948 for ( handler in events[type] ) 1949 // Handle the removal of namespaced events 1950 if ( !parts[1] || events[type][handler].type == parts[1] ) 1951 delete events[type][handler]; 1952 1953 // remove generic event handler if no more handlers exist 1954 for ( ret in events[type] ) break; 1955 if ( !ret ) { 1956 if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) { 1957 if (elem.removeEventListener) 1958 elem.removeEventListener(type, jQuery.data(elem, "handle"), false); 1959 else if (elem.detachEvent) 1960 elem.detachEvent("on" + type, jQuery.data(elem, "handle")); 1961 } 1962 ret = null; 1963 delete events[type]; 1964 } 1965 } 1966 }); 1967 } 1968 1969 // Remove the expando if it's no longer used 1970 for ( ret in events ) break; 1971 if ( !ret ) { 1972 var handle = jQuery.data( elem, "handle" ); 1973 if ( handle ) handle.elem = null; 1974 jQuery.removeData( elem, "events" ); 1975 jQuery.removeData( elem, "handle" ); 1976 } 1977 } 1978 }, 1979 1980 trigger: function(type, data, elem, donative, extra) { 1981 // Clone the incoming data, if any 1982 data = jQuery.makeArray(data || []); 1983 1984 if ( type.indexOf("!") >= 0 ) { 1985 type = type.slice(0, -1); 1986 var exclusive = true; 1987 } 1988 1989 // Handle a global trigger 1990 if ( !elem ) { 1991 // Only trigger if we've ever bound an event for it 1992 if ( this.global[type] ) 1993 jQuery("*").add([window, document]).trigger(type, data); 1994 1995 // Handle triggering a single element 1996 } else { 1997 // don't do events on text and comment nodes 1998 if ( elem.nodeType == 3 || elem.nodeType == 8 ) 1999 return undefined; 2000 2001 var val, ret, fn = jQuery.isFunction( elem[ type ] || null ), 2002 // Check to see if we need to provide a fake event, or not 2003 event = !data[0] || !data[0].preventDefault; 2004 2005 // Pass along a fake event 2006 if ( event ) 2007 data.unshift( this.fix({ type: type, target: elem }) ); 2008 2009 // Enforce the right trigger type 2010 data[0].type = type; 2011 if ( exclusive ) 2012 data[0].exclusive = true; 2013 2014 // Trigger the event 2015 if ( jQuery.isFunction( jQuery.data(elem, "handle") ) ) 2016 val = jQuery.data(elem, "handle").apply( elem, data ); 2017 2018 // Handle triggering native .onfoo handlers 2019 if ( !fn && elem["on"+type] && elem["on"+type].apply( elem, data ) === false ) 2020 val = false; 2021 2022 // Extra functions don't get the custom event object 2023 if ( event ) 2024 data.shift(); 2025 2026 // Handle triggering of extra function 2027 if ( extra && jQuery.isFunction( extra ) ) { 2028 // call the extra function and tack the current return value on the end for possible inspection 2029 ret = extra.apply( elem, val == null ? data : data.concat( val ) ); 2030 // if anything is returned, give it precedence and have it overwrite the previous value 2031 if (ret !== undefined) 2032 val = ret; 2033 } 2034 2035 // Trigger the native events (except for clicks on links) 2036 if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) { 2037 this.triggered = true; 2038 try { 2039 elem[ type ](); 2040 // prevent IE from throwing an error for some hidden elements 2041 } catch (e) {} 2042 } 2043 2044 this.triggered = false; 2045 } 2046 2047 return val; 2048 }, 2049 2050 handle: function(event) { 2051 // returned undefined or false 2052 var val; 2053 2054 // Empty object is for triggered events with no data 2055 event = jQuery.event.fix( event || window.event || {} ); 2056 2057 // Namespaced event handlers 2058 var parts = event.type.split("."); 2059 event.type = parts[0]; 2060 2061 var handlers = jQuery.data(this, "events") && jQuery.data(this, "events")[event.type], args = Array.prototype.slice.call( arguments, 1 ); 2062 args.unshift( event ); 2063 2064 for ( var j in handlers ) { 2065 var handler = handlers[j]; 2066 // Pass in a reference to the handler function itself 2067 // So that we can later remove it 2068 args[0].handler = handler; 2069 args[0].data = handler.data; 2070 2071 // Filter the functions by class 2072 if ( !parts[1] && !event.exclusive || handler.type == parts[1] ) { 2073 var ret = handler.apply( this, args ); 2074 2075 if ( val !== false ) 2076 val = ret; 2077 2078 if ( ret === false ) { 2079 event.preventDefault(); 2080 event.stopPropagation(); 2081 } 2082 } 2083 } 2084 2085 // Clean up added properties in IE to prevent memory leak 2086 if (jQuery.browser.msie) 2087 event.target = event.preventDefault = event.stopPropagation = 2088 event.handler = event.data = null; 2089 2090 return val; 2091 }, 2092 2093 fix: function(event) { 2094 // store a copy of the original event object 2095 // and clone to set read-only properties 2096 var originalEvent = event; 2097 event = jQuery.extend({}, originalEvent); 2098 2099 // add preventDefault and stopPropagation since 2100 // they will not work on the clone 2101 event.preventDefault = function() { 2102 // if preventDefault exists run it on the original event 2103 if (originalEvent.preventDefault) 2104 originalEvent.preventDefault(); 2105 // otherwise set the returnValue property of the original event to false (IE) 2106 originalEvent.returnValue = false; 2107 }; 2108 event.stopPropagation = function() { 2109 // if stopPropagation exists run it on the original event 2110 if (originalEvent.stopPropagation) 2111 originalEvent.stopPropagation(); 2112 // otherwise set the cancelBubble property of the original event to true (IE) 2113 originalEvent.cancelBubble = true; 2114 }; 2115 2116 // Fix target property, if necessary 2117 if ( !event.target ) 2118 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either 2119 2120 // check if target is a textnode (safari) 2121 if ( event.target.nodeType == 3 ) 2122 event.target = originalEvent.target.parentNode; 2123 2124 // Add relatedTarget, if necessary 2125 if ( !event.relatedTarget && event.fromElement ) 2126 event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement; 2127 2128 // Calculate pageX/Y if missing and clientX/Y available 2129 if ( event.pageX == null && event.clientX != null ) { 2130 var doc = document.documentElement, body = document.body; 2131 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0); 2132 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0); 2133 } 2134 2135 // Add which for key events 2136 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) 2137 event.which = event.charCode || event.keyCode; 2138 2139 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) 2140 if ( !event.metaKey && event.ctrlKey ) 2141 event.metaKey = event.ctrlKey; 2142 2143 // Add which for click: 1 == left; 2 == middle; 3 == right 2144 // Note: button is not normalized, so don't use it 2145 if ( !event.which && event.button ) 2146 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) )); 2147 2148 return event; 2149 }, 2150 2151 special: { 2152 ready: { 2153 setup: function() { 2154 // Make sure the ready event is setup 2155 bindReady(); 2156 return; 2157 }, 2158 2159 teardown: function() { return; } 2160 }, 2161 2162 mouseenter: { 2163 setup: function() { 2164 if ( jQuery.browser.msie ) return false; 2165 jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler); 2166 return true; 2167 }, 2168 2169 teardown: function() { 2170 if ( jQuery.browser.msie ) return false; 2171 jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler); 2172 return true; 2173 }, 2174 2175 handler: function(event) { 2176 // If we actually just moused on to a sub-element, ignore it 2177 if ( withinElement(event, this) ) return true; 2178 // Execute the right handlers by setting the event type to mouseenter 2179 arguments[0].type = "mouseenter"; 2180 return jQuery.event.handle.apply(this, arguments); 2181 } 2182 }, 2183 2184 mouseleave: { 2185 setup: function() { 2186 if ( jQuery.browser.msie ) return false; 2187 jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler); 2188 return true; 2189 }, 2190 2191 teardown: function() { 2192 if ( jQuery.browser.msie ) return false; 2193 jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler); 2194 return true; 2195 }, 2196 2197 handler: function(event) { 2198 // If we actually just moused on to a sub-element, ignore it 2199 if ( withinElement(event, this) ) return true; 2200 // Execute the right handlers by setting the event type to mouseleave 2201 arguments[0].type = "mouseleave"; 2202 return jQuery.event.handle.apply(this, arguments); 2203 } 2204 } 2205 } 2206 }; 2207 2208 jQuery.fn.extend({ 2209 bind: function( type, data, fn ) { 2210 return type == "unload" ? this.one(type, data, fn) : this.each(function(){ 2211 jQuery.event.add( this, type, fn || data, fn && data ); 2212 }); 2213 }, 2214 2215 one: function( type, data, fn ) { 2216 return this.each(function(){ 2217 jQuery.event.add( this, type, function(event) { 2218 jQuery(this).unbind(event); 2219 return (fn || data).apply( this, arguments); 2220 }, fn && data); 2221 }); 2222 }, 2223 2224 unbind: function( type, fn ) { 2225 return this.each(function(){ 2226 jQuery.event.remove( this, type, fn ); 2227 }); 2228 }, 2229 2230 trigger: function( type, data, fn ) { 2231 return this.each(function(){ 2232 jQuery.event.trigger( type, data, this, true, fn ); 2233 }); 2234 }, 2235 2236 triggerHandler: function( type, data, fn ) { 2237 if ( this[0] ) 2238 return jQuery.event.trigger( type, data, this[0], false, fn ); 2239 return undefined; 2240 }, 2241 2242 toggle: function() { 2243 // Save reference to arguments for access in closure 2244 var args = arguments; 2245 2246 return this.click(function(event) { 2247 // Figure out which function to execute 2248 this.lastToggle = 0 == this.lastToggle ? 1 : 0; 2249 2250 // Make sure that clicks stop 2251 event.preventDefault(); 2252 2253 // and execute the function 2254 return args[this.lastToggle].apply( this, arguments ) || false; 2255 }); 2256 }, 2257 2258 hover: function(fnOver, fnOut) { 2259 return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut); 2260 }, 2261 2262 ready: function(fn) { 2263 // Attach the listeners 2264 bindReady(); 2265 2266 // If the DOM is already ready 2267 if ( jQuery.isReady ) 2268 // Execute the function immediately 2269 fn.call( document, jQuery ); 2270 2271 // Otherwise, remember the function for later 2272 else 2273 // Add the function to the wait list 2274 jQuery.readyList.push( function() { return fn.call(this, jQuery); } ); 2275 2276 return this; 2277 } 2278 }); 2279 2280 jQuery.extend({ 2281 isReady: false, 2282 readyList: [], 2283 // Handle when the DOM is ready 2284 ready: function() { 2285 // Make sure that the DOM is not already loaded 2286 if ( !jQuery.isReady ) { 2287 // Remember that the DOM is ready 2288 jQuery.isReady = true; 2289 2290 // If there are functions bound, to execute 2291 if ( jQuery.readyList ) { 2292 // Execute all of them 2293 jQuery.each( jQuery.readyList, function(){ 2294 this.apply( document ); 2295 }); 2296 2297 // Reset the list of functions 2298 jQuery.readyList = null; 2299 } 2300 2301 // Trigger any bound ready events 2302 jQuery(document).triggerHandler("ready"); 2303 } 2304 } 2305 }); 2306 2307 var readyBound = false; 2308 2309 function bindReady(){ 2310 if ( readyBound ) return; 2311 readyBound = true; 2312 2313 // Mozilla, Opera (see further below for it) and webkit nightlies currently support this event 2314 if ( document.addEventListener && !jQuery.browser.opera) 2315 // Use the handy event callback 2316 document.addEventListener( "DOMContentLoaded", jQuery.ready, false ); 2317 2318 // If IE is used and is not in a frame 2319 // Continually check to see if the document is ready 2320 if ( jQuery.browser.msie && window == top ) (function(){ 2321 if (jQuery.isReady) return; 2322 try { 2323 // If IE is used, use the trick by Diego Perini 2324 // http://javascript.nwbox.com/IEContentLoaded/ 2325 document.documentElement.doScroll("left"); 2326 } catch( error ) { 2327 setTimeout( arguments.callee, 0 ); 2328 return; 2329 } 2330 // and execute any waiting functions 2331 jQuery.ready(); 2332 })(); 2333 2334 if ( jQuery.browser.opera ) 2335 document.addEventListener( "DOMContentLoaded", function () { 2336 if (jQuery.isReady) return; 2337 for (var i = 0; i < document.styleSheets.length; i++) 2338 if (document.styleSheets[i].disabled) { 2339 setTimeout( arguments.callee, 0 ); 2340 return; 2341 } 2342 // and execute any waiting functions 2343 jQuery.ready(); 2344 }, false); 2345 2346 if ( jQuery.browser.safari ) { 2347 var numStyles; 2348 (function(){ 2349 if (jQuery.isReady) return; 2350 if ( document.readyState != "loaded" && document.readyState != "complete" ) { 2351 setTimeout( arguments.callee, 0 ); 2352 return; 2353 } 2354 if ( numStyles === undefined ) 2355 numStyles = jQuery("style, link[rel=stylesheet]").length; 2356 if ( document.styleSheets.length != numStyles ) { 2357 setTimeout( arguments.callee, 0 ); 2358 return; 2359 } 2360 // and execute any waiting functions 2361 jQuery.ready(); 2362 })(); 2363 } 2364 2365 // A fallback to window.onload, that will always work 2366 jQuery.event.add( window, "load", jQuery.ready ); 2367 } 2368 2369 jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," + 2370 "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," + 2371 "submit,keydown,keypress,keyup,error").split(","), function(i, name){ 2372 2373 // Handle event binding 2374 jQuery.fn[name] = function(fn){ 2375 return fn ? this.bind(name, fn) : this.trigger(name); 2376 }; 2377 }); 2378 2379 // Checks if an event happened on an element within another element 2380 // Used in jQuery.event.special.mouseenter and mouseleave handlers 2381 var withinElement = function(event, elem) { 2382 // Check if mouse(over|out) are still within the same parent element 2383 var parent = event.relatedTarget; 2384 // Traverse up the tree 2385 while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; } 2386 // Return true if we actually just moused on to a sub-element 2387 return parent == elem; 2388 }; 2389 2390 // Prevent memory leaks in IE 2391 // And prevent errors on refresh with events like mouseover in other browsers 2392 // Window isn't included so as not to unbind existing unload events 2393 jQuery(window).bind("unload", function() { 2394 jQuery("*").add(document).unbind(); 2395 }); 2396 jQuery.fn.extend({ 2397 load: function( url, params, callback ) { 2398 if ( jQuery.isFunction( url ) ) 2399 return this.bind("load", url); 2400 2401 var off = url.indexOf(" "); 2402 if ( off >= 0 ) { 2403 var selector = url.slice(off, url.length); 2404 url = url.slice(0, off); 2405 } 2406 2407 callback = callback || function(){}; 2408 2409 // Default to a GET request 2410 var type = "GET"; 2411 2412 // If the second parameter was provided 2413 if ( params ) 2414 // If it's a function 2415 if ( jQuery.isFunction( params ) ) { 2416 // We assume that it's the callback 2417 callback = params; 2418 params = null; 2419 2420 // Otherwise, build a param string 2421 } else { 2422 params = jQuery.param( params ); 2423 type = "POST"; 2424 } 2425 2426 var self = this; 2427 2428 // Request the remote document 2429 jQuery.ajax({ 2430 url: url, 2431 type: type, 2432 dataType: "html", 2433 data: params, 2434 complete: function(res, status){ 2435 // If successful, inject the HTML into all the matched elements 2436 if ( status == "success" || status == "notmodified" ) 2437 // See if a selector was specified 2438 self.html( selector ? 2439 // Create a dummy div to hold the results 2440 jQuery("<div/>") 2441 // inject the contents of the document in, removing the scripts 2442 // to avoid any 'Permission Denied' errors in IE 2443 .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, "")) 2444 2445 // Locate the specified elements 2446 .find(selector) : 2447 2448 // If not, just inject the full result 2449 res.responseText ); 2450 2451 self.each( callback, [res.responseText, status, res] ); 2452 } 2453 }); 2454 return this; 2455 }, 2456 2457 serialize: function() { 2458 return jQuery.param(this.serializeArray()); 2459 }, 2460 serializeArray: function() { 2461 return this.map(function(){ 2462 return jQuery.nodeName(this, "form") ? 2463 jQuery.makeArray(this.elements) : this; 2464 }) 2465 .filter(function(){ 2466 return this.name && !this.disabled && 2467 (this.checked || /select|textarea/i.test(this.nodeName) || 2468 /text|hidden|password/i.test(this.type)); 2469 }) 2470 .map(function(i, elem){ 2471 var val = jQuery(this).val(); 2472 return val == null ? null : 2473 val.constructor == Array ? 2474 jQuery.map( val, function(val, i){ 2475 return {name: elem.name, value: val}; 2476 }) : 2477 {name: elem.name, value: val}; 2478 }).get(); 2479 } 2480 }); 2481 2482 // Attach a bunch of functions for handling common AJAX events 2483 jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){ 2484 jQuery.fn[o] = function(f){ 2485 return this.bind(o, f); 2486 }; 2487 }); 2488 2489 var jsc = (new Date).getTime(); 2490 2491 jQuery.extend({ 2492 get: function( url, data, callback, type ) { 2493 // shift arguments if data argument was ommited 2494 if ( jQuery.isFunction( data ) ) { 2495 callback = data; 2496 data = null; 2497 } 2498 2499 return jQuery.ajax({ 2500 type: "GET", 2501 url: url, 2502 data: data, 2503 success: callback, 2504 dataType: type 2505 }); 2506 }, 2507 2508 getScript: function( url, callback ) { 2509 return jQuery.get(url, null, callback, "script"); 2510 }, 2511 2512 getJSON: function( url, data, callback ) { 2513 return jQuery.get(url, data, callback, "json"); 2514 }, 2515 2516 post: function( url, data, callback, type ) { 2517 if ( jQuery.isFunction( data ) ) { 2518 callback = data; 2519 data = {}; 2520 } 2521 2522 return jQuery.ajax({ 2523 type: "POST", 2524 url: url, 2525 data: data, 2526 success: callback, 2527 dataType: type 2528 }); 2529 }, 2530 2531 ajaxSetup: function( settings ) { 2532 jQuery.extend( jQuery.ajaxSettings, settings ); 2533 }, 2534 2535 ajaxSettings: { 2536 global: true, 2537 type: "GET", 2538 timeout: 0, 2539 contentType: "application/x-www-form-urlencoded", 2540 processData: true, 2541 async: true, 2542 data: null, 2543 username: null, 2544 password: null, 2545 accepts: { 2546 xml: "application/xml, text/xml", 2547 html: "text/html", 2548 script: "text/javascript, application/javascript", 2549 json: "application/json, text/javascript", 2550 text: "text/plain", 2551 _default: "*/*" 2552 } 2553 }, 2554 2555 // Last-Modified header cache for next request 2556 lastModified: {}, 2557 2558 ajax: function( s ) { 2559 var jsonp, jsre = /=\?(&|$)/g, status, data; 2560 2561 // Extend the settings, but re-extend 's' so that it can be 2562 // checked again later (in the test suite, specifically) 2563 s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s)); 2564 2565 // convert data if not already a string 2566 if ( s.data && s.processData && typeof s.data != "string" ) 2567 s.data = jQuery.param(s.data); 2568 2569 // Handle JSONP Parameter Callbacks 2570 if ( s.dataType == "jsonp" ) { 2571 if ( s.type.toLowerCase() == "get" ) { 2572 if ( !s.url.match(jsre) ) 2573 s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?"; 2574 } else if ( !s.data || !s.data.match(jsre) ) 2575 s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?"; 2576 s.dataType = "json"; 2577 } 2578 2579 // Build temporary JSONP function 2580 if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) { 2581 jsonp = "jsonp" + jsc++; 2582 2583 // Replace the =? sequence both in the query string and the data 2584 if ( s.data ) 2585 s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1"); 2586 s.url = s.url.replace(jsre, "=" + jsonp + "$1"); 2587 2588 // We need to make sure 2589 // that a JSONP style response is executed properly 2590 s.dataType = "script"; 2591 2592 // Handle JSONP-style loading 2593 window[ jsonp ] = function(tmp){ 2594 data = tmp; 2595 success(); 2596 complete(); 2597 // Garbage collect 2598 window[ jsonp ] = undefined; 2599 try{ delete window[ jsonp ]; } catch(e){} 2600 if ( head ) 2601 head.removeChild( script ); 2602 }; 2603 } 2604 2605 if ( s.dataType == "script" && s.cache == null ) 2606 s.cache = false; 2607 2608 if ( s.cache === false && s.type.toLowerCase() == "get" ) { 2609 var ts = (new Date()).getTime(); 2610 // try replacing _= if it is there 2611 var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2"); 2612 // if nothing was replaced, add timestamp to the end 2613 s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : ""); 2614 } 2615 2616 // If data is available, append data to url for get requests 2617 if ( s.data && s.type.toLowerCase() == "get" ) { 2618 s.url += (s.url.match(/\?/) ? "&" : "?") + s.data; 2619 2620 // IE likes to send both get and post data, prevent this 2621 s.data = null; 2622 } 2623 2624 // Watch for a new set of requests 2625 if ( s.global && ! jQuery.active++ ) 2626 jQuery.event.trigger( "ajaxStart" ); 2627 2628 // If we're requesting a remote document 2629 // and trying to load JSON or Script with a GET 2630 if ( (!s.url.indexOf("http") || !s.url.indexOf("//")) && s.dataType == "script" && s.type.toLowerCase() == "get" ) { 2631 var head = document.getElementsByTagName("head")[0]; 2632 var script = document.createElement("script"); 2633 script.src = s.url; 2634 if (s.scriptCharset) 2635 script.charset = s.scriptCharset; 2636 2637 // Handle Script loading 2638 if ( !jsonp ) { 2639 var done = false; 2640 2641 // Attach handlers for all browsers 2642 script.onload = script.onreadystatechange = function(){ 2643 if ( !done && (!this.readyState || 2644 this.readyState == "loaded" || this.readyState == "complete") ) { 2645 done = true; 2646 success(); 2647 complete(); 2648 head.removeChild( script ); 2649 } 2650 }; 2651 } 2652 2653 head.appendChild(script); 2654 2655 // We handle everything using the script element injection 2656 return undefined; 2657 } 2658 2659 var requestDone = false; 2660 2661 // Create the request object; Microsoft failed to properly 2662 // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available 2663 var xml = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest(); 2664 2665 // Open the socket 2666 xml.open(s.type, s.url, s.async, s.username, s.password); 2667 2668 // Need an extra try/catch for cross domain requests in Firefox 3 2669 try { 2670 // Set the correct header, if data is being sent 2671 if ( s.data ) 2672 xml.setRequestHeader("Content-Type", s.contentType); 2673 2674 // Set the If-Modified-Since header, if ifModified mode. 2675 if ( s.ifModified ) 2676 xml.setRequestHeader("If-Modified-Since", 2677 jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" ); 2678 2679 // Set header so the called script knows that it's an XMLHttpRequest 2680 xml.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 2681 2682 // Set the Accepts header for the server, depending on the dataType 2683 xml.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ? 2684 s.accepts[ s.dataType ] + ", */*" : 2685 s.accepts._default ); 2686 } catch(e){} 2687 2688 // Allow custom headers/mimetypes 2689 if ( s.beforeSend ) 2690 s.beforeSend(xml); 2691 2692 if ( s.global ) 2693 jQuery.event.trigger("ajaxSend", [xml, s]); 2694 2695 // Wait for a response to come back 2696 var onreadystatechange = function(isTimeout){ 2697 // The transfer is complete and the data is available, or the request timed out 2698 if ( !requestDone && xml && (xml.readyState == 4 || isTimeout == "timeout") ) { 2699 requestDone = true; 2700 2701 // clear poll interval 2702 if (ival) { 2703 clearInterval(ival); 2704 ival = null; 2705 } 2706 2707 status = isTimeout == "timeout" && "timeout" || 2708 !jQuery.httpSuccess( xml ) && "error" || 2709 s.ifModified && jQuery.httpNotModified( xml, s.url ) && "notmodified" || 2710 "success"; 2711 2712 if ( status == "success" ) { 2713 // Watch for, and catch, XML document parse errors 2714 try { 2715 // process the data (runs the xml through httpData regardless of callback) 2716 data = jQuery.httpData( xml, s.dataType ); 2717 } catch(e) { 2718 status = "parsererror"; 2719 } 2720 } 2721 2722 // Make sure that the request was successful or notmodified 2723 if ( status == "success" ) { 2724 // Cache Last-Modified header, if ifModified mode. 2725 var modRes; 2726 try { 2727 modRes = xml.getResponseHeader("Last-Modified"); 2728 } catch(e) {} // swallow exception thrown by FF if header is not available 2729 2730 if ( s.ifModified && modRes ) 2731 jQuery.lastModified[s.url] = modRes; 2732 2733 // JSONP handles its own success callback 2734 if ( !jsonp ) 2735 success(); 2736 } else 2737 jQuery.handleError(s, xml, status); 2738 2739 // Fire the complete handlers 2740 complete(); 2741 2742 // Stop memory leaks 2743 if ( s.async ) 2744 xml = null; 2745 } 2746 }; 2747 2748 if ( s.async ) { 2749 // don't attach the handler to the request, just poll it instead 2750 var ival = setInterval(onreadystatechange, 13); 2751 2752 // Timeout checker 2753 if ( s.timeout > 0 ) 2754 setTimeout(function(){ 2755 // Check to see if the request is still happening 2756 if ( xml ) { 2757 // Cancel the request 2758 xml.abort(); 2759 2760 if( !requestDone ) 2761 onreadystatechange( "timeout" ); 2762 } 2763 }, s.timeout); 2764 } 2765 2766 // Send the data 2767 try { 2768 xml.send(s.data); 2769 } catch(e) { 2770 jQuery.handleError(s, xml, null, e); 2771 } 2772 2773 // firefox 1.5 doesn't fire statechange for sync requests 2774 if ( !s.async ) 2775 onreadystatechange(); 2776 2777 function success(){ 2778 // If a local callback was specified, fire it and pass it the data 2779 if ( s.success ) 2780 s.success( data, status ); 2781 2782 // Fire the global callback 2783 if ( s.global ) 2784 jQuery.event.trigger( "ajaxSuccess", [xml, s] ); 2785 } 2786 2787 function complete(){ 2788 // Process result 2789 if ( s.complete ) 2790 s.complete(xml, status); 2791 2792 // The request was completed 2793 if ( s.global ) 2794 jQuery.event.trigger( "ajaxComplete", [xml, s] ); 2795 2796 // Handle the global AJAX counter 2797 if ( s.global && ! --jQuery.active ) 2798 jQuery.event.trigger( "ajaxStop" ); 2799 } 2800 2801 // return XMLHttpRequest to allow aborting the request etc. 2802 return xml; 2803 }, 2804 2805 handleError: function( s, xml, status, e ) { 2806 // If a local callback was specified, fire it 2807 if ( s.error ) s.error( xml, status, e ); 2808 2809 // Fire the global callback 2810 if ( s.global ) 2811 jQuery.event.trigger( "ajaxError", [xml, s, e] ); 2812 }, 2813 2814 // Counter for holding the number of active queries 2815 active: 0, 2816 2817 // Determines if an XMLHttpRequest was successful or not 2818 httpSuccess: function( r ) { 2819 try { 2820 // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450 2821 return !r.status && location.protocol == "file:" || 2822 ( r.status >= 200 && r.status < 300 ) || r.status == 304 || r.status == 1223 || 2823 jQuery.browser.safari && r.status == undefined; 2824 } catch(e){} 2825 return false; 2826 }, 2827 2828 // Determines if an XMLHttpRequest returns NotModified 2829 httpNotModified: function( xml, url ) { 2830 try { 2831 var xmlRes = xml.getResponseHeader("Last-Modified"); 2832 2833 // Firefox always returns 200. check Last-Modified date 2834 return xml.status == 304 || xmlRes == jQuery.lastModified[url] || 2835 jQuery.browser.safari && xml.status == undefined; 2836 } catch(e){} 2837 return false; 2838 }, 2839 2840 httpData: function( r, type ) { 2841 var ct = r.getResponseHeader("content-type"); 2842 var xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0; 2843 var data = xml ? r.responseXML : r.responseText; 2844 2845 if ( xml && data.documentElement.tagName == "parsererror" ) 2846 throw "parsererror"; 2847 2848 // If the type is "script", eval it in global context 2849 if ( type == "script" ) 2850 jQuery.globalEval( data ); 2851 2852 // Get the JavaScript object, if JSON is used. 2853 if ( type == "json" ) 2854 data = eval("(" + data + ")"); 2855 2856 return data; 2857 }, 2858 2859 // Serialize an array of form elements or a set of 2860 // key/values into a query string 2861 param: function( a ) { 2862 var s = []; 2863 2864 // If an array was passed in, assume that it is an array 2865 // of form elements 2866 if ( a.constructor == Array || a.jquery ) 2867 // Serialize the form elements 2868 jQuery.each( a, function(){ 2869 s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) ); 2870 }); 2871 2872 // Otherwise, assume that it's an object of key/value pairs 2873 else 2874 // Serialize the key/values 2875 for ( var j in a ) 2876 // If the value is an array then the key names need to be repeated 2877 if ( a[j] && a[j].constructor == Array ) 2878 jQuery.each( a[j], function(){ 2879 s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) ); 2880 }); 2881 else 2882 s.push( encodeURIComponent(j) + "=" + encodeURIComponent( a[j] ) ); 2883 2884 // Return the resulting serialization 2885 return s.join("&").replace(/%20/g, "+"); 2886 } 2887 2888 }); 2889 jQuery.fn.extend({ 2890 show: function(speed,callback){ 2891 return speed ? 2892 this.animate({ 2893 height: "show", width: "show", opacity: "show" 2894 }, speed, callback) : 2895 2896 this.filter(":hidden").each(function(){ 2897 this.style.display = this.oldblock || ""; 2898 if ( jQuery.css(this,"display") == "none" ) { 2899 var elem = jQuery("<" + this.tagName + " />").appendTo("body"); 2900 this.style.display = elem.css("display"); 2901 // handle an edge condition where css is - div { display:none; } or similar 2902 if (this.style.display == "none") 2903 this.style.display = "block"; 2904 elem.remove(); 2905 } 2906 }).end(); 2907 }, 2908 2909 hide: function(speed,callback){ 2910 return speed ? 2911 this.animate({ 2912 height: "hide", width: "hide", opacity: "hide" 2913 }, speed, callback) : 2914 2915 this.filter(":visible").each(function(){ 2916 this.oldblock = this.oldblock || jQuery.css(this,"display"); 2917 this.style.display = "none"; 2918 }).end(); 2919 }, 2920 2921 // Save the old toggle function 2922 _toggle: jQuery.fn.toggle, 2923 2924 toggle: function( fn, fn2 ){ 2925 return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ? 2926 this._toggle( fn, fn2 ) : 2927 fn ? 2928 this.animate({ 2929 height: "toggle", width: "toggle", opacity: "toggle" 2930 }, fn, fn2) : 2931 this.each(function(){ 2932 jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ](); 2933 }); 2934 }, 2935 2936 slideDown: function(speed,callback){ 2937 return this.animate({height: "show"}, speed, callback); 2938 }, 2939 2940 slideUp: function(speed,callback){ 2941 return this.animate({height: "hide"}, speed, callback); 2942 }, 2943 2944 slideToggle: function(speed, callback){ 2945 return this.animate({height: "toggle"}, speed, callback); 2946 }, 2947 2948 fadeIn: function(speed, callback){ 2949 return this.animate({opacity: "show"}, speed, callback); 2950 }, 2951 2952 fadeOut: function(speed, callback){ 2953 return this.animate({opacity: "hide"}, speed, callback); 2954 }, 2955 2956 fadeTo: function(speed,to,callback){ 2957 return this.animate({opacity: to}, speed, callback); 2958 }, 2959 2960 animate: function( prop, speed, easing, callback ) { 2961 var optall = jQuery.speed(speed, easing, callback); 2962 2963 return this[ optall.queue === false ? "each" : "queue" ](function(){ 2964 if ( this.nodeType != 1) 2965 return false; 2966 2967 var opt = jQuery.extend({}, optall); 2968 var hidden = jQuery(this).is(":hidden"), self = this; 2969 2970 for ( var p in prop ) { 2971 if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden ) 2972 return jQuery.isFunction(opt.complete) && opt.complete.apply(this); 2973 2974 if ( p == "height" || p == "width" ) { 2975 // Store display property 2976 opt.display = jQuery.css(this, "display"); 2977 2978 // Make sure that nothing sneaks out 2979 opt.overflow = this.style.overflow; 2980 } 2981 } 2982 2983 if ( opt.overflow != null ) 2984 this.style.overflow = "hidden"; 2985 2986 opt.curAnim = jQuery.extend({}, prop); 2987 2988 jQuery.each( prop, function(name, val){ 2989 var e = new jQuery.fx( self, opt, name ); 2990 2991 if ( /toggle|show|hide/.test(val) ) 2992 e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop ); 2993 else { 2994 var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/), 2995 start = e.cur(true) || 0; 2996 2997 if ( parts ) { 2998 var end = parseFloat(parts[2]), 2999 unit = parts[3] || "px"; 3000 3001 // We need to compute starting value 3002 if ( unit != "px" ) { 3003 self.style[ name ] = (end || 1) + unit; 3004 start = ((end || 1) / e.cur(true)) * start; 3005 self.style[ name ] = start + unit; 3006 } 3007 3008 // If a +=/-= token was provided, we're doing a relative animation 3009 if ( parts[1] ) 3010 end = ((parts[1] == "-=" ? -1 : 1) * end) + start; 3011 3012 e.custom( start, end, unit ); 3013 } else 3014 e.custom( start, val, "" ); 3015 } 3016 }); 3017 3018 // For JS strict compliance 3019 return true; 3020 }); 3021 }, 3022 3023 queue: function(type, fn){ 3024 if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) { 3025 fn = type; 3026 type = "fx"; 3027 } 3028 3029 if ( !type || (typeof type == "string" && !fn) ) 3030 return queue( this[0], type ); 3031 3032 return this.each(function(){ 3033 if ( fn.constructor == Array ) 3034 queue(this, type, fn); 3035 else { 3036 queue(this, type).push( fn ); 3037 3038 if ( queue(this, type).length == 1 ) 3039 fn.apply(this); 3040 } 3041 }); 3042 }, 3043 3044 stop: function(clearQueue, gotoEnd){ 3045 var timers = jQuery.timers; 3046 3047 if (clearQueue) 3048 this.queue([]); 3049 3050 this.each(function(){ 3051 // go in reverse order so anything added to the queue during the loop is ignored 3052 for ( var i = timers.length - 1; i >= 0; i-- ) 3053 if ( timers[i].elem == this ) { 3054 if (gotoEnd) 3055 // force the next step to be the last 3056 timers[i](true); 3057 timers.splice(i, 1); 3058 } 3059 }); 3060 3061 // start the next in the queue if the last step wasn't forced 3062 if (!gotoEnd) 3063 this.dequeue(); 3064 3065 return this; 3066 } 3067 3068 }); 3069 3070 var queue = function( elem, type, array ) { 3071 if ( !elem ) 3072 return undefined; 3073 3074 type = type || "fx"; 3075 3076 var q = jQuery.data( elem, type + "queue" ); 3077 3078 if ( !q || array ) 3079 q = jQuery.data( elem, type + "queue", 3080 array ? jQuery.makeArray(array) : [] ); 3081 3082 return q; 3083 }; 3084 3085 jQuery.fn.dequeue = function(type){ 3086 type = type || "fx"; 3087 3088 return this.each(function(){ 3089 var q = queue(this, type); 3090 3091 q.shift(); 3092 3093 if ( q.length ) 3094 q[0].apply( this ); 3095 }); 3096 }; 3097 3098 jQuery.extend({ 3099 3100 speed: function(speed, easing, fn) { 3101 var opt = speed && speed.constructor == Object ? speed : { 3102 complete: fn || !fn && easing || 3103 jQuery.isFunction( speed ) && speed, 3104 duration: speed, 3105 easing: fn && easing || easing && easing.constructor != Function && easing 3106 }; 3107 3108 opt.duration = (opt.duration && opt.duration.constructor == Number ? 3109 opt.duration : 3110 { slow: 600, fast: 200 }[opt.duration]) || 400; 3111 3112 // Queueing 3113 opt.old = opt.complete; 3114 opt.complete = function(){ 3115 if ( opt.queue !== false ) 3116 jQuery(this).dequeue(); 3117 if ( jQuery.isFunction( opt.old ) ) 3118 opt.old.apply( this ); 3119 }; 3120 3121 return opt; 3122 }, 3123 3124 easing: { 3125 linear: function( p, n, firstNum, diff ) { 3126 return firstNum + diff * p; 3127 }, 3128 swing: function( p, n, firstNum, diff ) { 3129 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum; 3130 } 3131 }, 3132 3133 timers: [], 3134 timerId: null, 3135 3136 fx: function( elem, options, prop ){ 3137 this.options = options; 3138 this.elem = elem; 3139 this.prop = prop; 3140 3141 if ( !options.orig ) 3142 options.orig = {}; 3143 } 3144 3145 }); 3146 3147 jQuery.fx.prototype = { 3148 3149 // Simple function for setting a style value 3150 update: function(){ 3151 if ( this.options.step ) 3152 this.options.step.apply( this.elem, [ this.now, this ] ); 3153 3154 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this ); 3155 3156 // Set display property to block for height/width animations 3157 if ( this.prop == "height" || this.prop == "width" ) 3158 this.elem.style.display = "block"; 3159 }, 3160 3161 // Get the current size 3162 cur: function(force){ 3163 if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null ) 3164 return this.elem[ this.prop ]; 3165 3166 var r = parseFloat(jQuery.css(this.elem, this.prop, force)); 3167 return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0; 3168 }, 3169 3170 // Start an animation from one number to another 3171 custom: function(from, to, unit){ 3172 this.startTime = (new Date()).getTime(); 3173 this.start = from; 3174 this.end = to; 3175 this.unit = unit || this.unit || "px"; 3176 this.now = this.start; 3177 this.pos = this.state = 0; 3178 this.update(); 3179 3180 var self = this; 3181 function t(gotoEnd){ 3182 return self.step(gotoEnd); 3183 } 3184 3185 t.elem = this.elem; 3186 3187 jQuery.timers.push(t); 3188 3189 if ( jQuery.timerId == null ) { 3190 jQuery.timerId = setInterval(function(){ 3191 var timers = jQuery.timers; 3192 3193 for ( var i = 0; i < timers.length; i++ ) 3194 if ( !timers[i]() ) 3195 timers.splice(i--, 1); 3196 3197 if ( !timers.length ) { 3198 clearInterval( jQuery.timerId ); 3199 jQuery.timerId = null; 3200 } 3201 }, 13); 3202 } 3203 }, 3204 3205 // Simple 'show' function 3206 show: function(){ 3207 // Remember where we started, so that we can go back to it later 3208 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop ); 3209 this.options.show = true; 3210 3211 // Begin the animation 3212 this.custom(0, this.cur()); 3213 3214 // Make sure that we start at a small width/height to avoid any 3215 // flash of content 3216 if ( this.prop == "width" || this.prop == "height" ) 3217 this.elem.style[this.prop] = "1px"; 3218 3219 // Start by showing the element 3220 jQuery(this.elem).show(); 3221 }, 3222 3223 // Simple 'hide' function 3224 hide: function(){ 3225 // Remember where we started, so that we can go back to it later 3226 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop ); 3227 this.options.hide = true; 3228 3229 // Begin the animation 3230 this.custom(this.cur(), 0); 3231 }, 3232 3233 // Each step of an animation 3234 step: function(gotoEnd){ 3235 var t = (new Date()).getTime(); 3236 3237 if ( gotoEnd || t > this.options.duration + this.startTime ) { 3238 this.now = this.end; 3239 this.pos = this.state = 1; 3240 this.update(); 3241 3242 this.options.curAnim[ this.prop ] = true; 3243 3244 var done = true; 3245 for ( var i in this.options.curAnim ) 3246 if ( this.options.curAnim[i] !== true ) 3247 done = false; 3248 3249 if ( done ) { 3250 if ( this.options.display != null ) { 3251 // Reset the overflow 3252 this.elem.style.overflow = this.options.overflow; 3253 3254 // Reset the display 3255 this.elem.style.display = this.options.display; 3256 if ( jQuery.css(this.elem, "display") == "none" ) 3257 this.elem.style.display = "block"; 3258 } 3259 3260 // Hide the element if the "hide" operation was done 3261 if ( this.options.hide ) 3262 this.elem.style.display = "none"; 3263 3264 // Reset the properties, if the item has been hidden or shown 3265 if ( this.options.hide || this.options.show ) 3266 for ( var p in this.options.curAnim ) 3267 jQuery.attr(this.elem.style, p, this.options.orig[p]); 3268 } 3269 3270 // If a callback was provided, execute it 3271 if ( done && jQuery.isFunction( this.options.complete ) ) 3272 // Execute the complete function 3273 this.options.complete.apply( this.elem ); 3274 3275 return false; 3276 } else { 3277 var n = t - this.startTime; 3278 this.state = n / this.options.duration; 3279 3280 // Perform the easing function, defaults to swing 3281 this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration); 3282 this.now = this.start + ((this.end - this.start) * this.pos); 3283 3284 // Perform the next step of the animation 3285 this.update(); 3286 } 3287 3288 return true; 3289 } 3290 3291 }; 3292 3293 jQuery.fx.step = { 3294 scrollLeft: function(fx){ 3295 fx.elem.scrollLeft = fx.now; 3296 }, 3297 3298 scrollTop: function(fx){ 3299 fx.elem.scrollTop = fx.now; 3300 }, 3301 3302 opacity: function(fx){ 3303 jQuery.attr(fx.elem.style, "opacity", fx.now); 3304 }, 3305 3306 _default: function(fx){ 3307 fx.elem.style[ fx.prop ] = fx.now + fx.unit; 3308 } 3309 }; 3310 // The Offset Method 3311 // Originally By Brandon Aaron, part of the Dimension Plugin 3312 // http://jquery.com/plugins/project/dimensions 3313 jQuery.fn.offset = function() { 3314 var left = 0, top = 0, elem = this[0], results; 3315 3316 if ( elem ) with ( jQuery.browser ) { 3317 var parent = elem.parentNode, 3318 offsetChild = elem, 3319 offsetParent = elem.offsetParent, 3320 doc = elem.ownerDocument, 3321 safari2 = safari && parseInt(version) < 522 && !/adobeair/i.test(userAgent), 3322 fixed = jQuery.css(elem, "position") == "fixed"; 3323 3324 // Use getBoundingClientRect if available 3325 if ( elem.getBoundingClientRect ) { 3326 var box = elem.getBoundingClientRect(); 3327 3328 // Add the document scroll offsets 3329 add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft), 3330 box.top + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop)); 3331 3332 // IE adds the HTML element's border, by default it is medium which is 2px 3333 // IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; } 3334 // IE 7 standards mode, the border is always 2px 3335 // This border/offset is typically represented by the clientLeft and clientTop properties 3336 // However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS 3337 // Therefore this method will be off by 2px in IE while in quirksmode 3338 add( -doc.documentElement.clientLeft, -doc.documentElement.clientTop ); 3339 3340 // Otherwise loop through the offsetParents and parentNodes 3341 } else { 3342 3343 // Initial element offsets 3344 add( elem.offsetLeft, elem.offsetTop ); 3345 3346 // Get parent offsets 3347 while ( offsetParent ) { 3348 // Add offsetParent offsets 3349 add( offsetParent.offsetLeft, offsetParent.offsetTop ); 3350 3351 // Mozilla and Safari > 2 does not include the border on offset parents 3352 // However Mozilla adds the border for table or table cells 3353 if ( mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2 ) 3354 border( offsetParent ); 3355 3356 // Add the document scroll offsets if position is fixed on any offsetParent 3357 if ( !fixed && jQuery.css(offsetParent, "position") == "fixed" ) 3358 fixed = true; 3359 3360 // Set offsetChild to previous offsetParent unless it is the body element 3361 offsetChild = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent; 3362 // Get next offsetParent 3363 offsetParent = offsetParent.offsetParent; 3364 } 3365 3366 // Get parent scroll offsets 3367 while ( parent && parent.tagName && !/^body|html$/i.test(parent.tagName) ) { 3368 // Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug 3369 if ( !/^inline|table.*$/i.test(jQuery.css(parent, "display")) ) 3370 // Subtract parent scroll offsets 3371 add( -parent.scrollLeft, -parent.scrollTop ); 3372 3373 // Mozilla does not add the border for a parent that has overflow != visible 3374 if ( mozilla && jQuery.css(parent, "overflow") != "visible" ) 3375 border( parent ); 3376 3377 // Get next parent 3378 parent = parent.parentNode; 3379 } 3380 3381 // Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild 3382 // Mozilla doubles body offsets with a non-absolutely positioned offsetChild 3383 if ( (safari2 && (fixed || jQuery.css(offsetChild, "position") == "absolute")) || 3384 (mozilla && jQuery.css(offsetChild, "position") != "absolute") ) 3385 add( -doc.body.offsetLeft, -doc.body.offsetTop ); 3386 3387 // Add the document scroll offsets if position is fixed 3388 if ( fixed ) 3389 add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft), 3390 Math.max(doc.documentElement.scrollTop, doc.body.scrollTop)); 3391 } 3392 3393 // Return an object with top and left properties 3394 results = { top: top, left: left }; 3395 } 3396 3397 function border(elem) { 3398 add( jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true) ); 3399 } 3400 3401 function add(l, t) { 3402 left += parseInt(l) || 0; 3403 top += parseInt(t) || 0; 3404 } 3405 3406 return results; 3407 }; 3408 })();

Contact Us
Can't read the article? Contact us for free answers! Free help for personal, small business sites!
Tel: 020-2206-9892
QQ咨询:1025174874
(iii) E-mail: info@361sale.com
Working hours: Monday to Friday, 9:30-18:30, holidays off
© Reprint statement
This article was written by Harry
THE END
If you like it, support it.
kudos0 share (joys, benefits, privileges etc) with others
commentaries sofa-buying

Please log in to post a comment

    No comments