MOD upgrade to jQuery 1.3
[euphorik.git] / js / libs / jquery.js
1 /*!
2 * jQuery JavaScript Library v1.3
3 * http://jquery.com/
4 *
5 * Copyright (c) 2009 John Resig
6 * Dual licensed under the MIT and GPL licenses.
7 * http://docs.jquery.com/License
8 *
9 * Date: 2009-01-13 12:50:31 -0500 (Tue, 13 Jan 2009)
10 * Revision: 6104
11 */
12 (function(){
13
14 var
15 // Will speed up references to window, and allows munging its name.
16 window = this,
17 // Will speed up references to undefined, and allows munging its name.
18 undefined,
19 // Map over jQuery in case of overwrite
20 _jQuery = window.jQuery,
21 // Map over the $ in case of overwrite
22 _$ = window.$,
23
24 jQuery = window.jQuery = window.$ = function( selector, context ) {
25 // The jQuery object is actually just the init constructor 'enhanced'
26 return new jQuery.fn.init( selector, context );
27 },
28
29 // A simple way to check for HTML strings or ID strings
30 // (both of which we optimize for)
31 quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,
32 // Is it a simple selector
33 isSimple = /^.[^:#\[\.,]*$/;
34
35 jQuery.fn = jQuery.prototype = {
36 init: function( selector, context ) {
37 // Make sure that a selection was provided
38 selector = selector || document;
39
40 // Handle $(DOMElement)
41 if ( selector.nodeType ) {
42 this[0] = selector;
43 this.length = 1;
44 this.context = selector;
45 return this;
46 }
47 // Handle HTML strings
48 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 var ret = jQuery( elem );
72 ret.context = document;
73 ret.selector = selector;
74 return ret;
75 }
76 selector = [];
77 }
78
79 // HANDLE: $(expr, [context])
80 // (which is just equivalent to: $(content).find(expr)
81 } else
82 return jQuery( context ).find( selector );
83
84 // HANDLE: $(function)
85 // Shortcut for document ready
86 } else if ( jQuery.isFunction( selector ) )
87 return jQuery( document ).ready( selector );
88
89 // Make sure that old selector state is passed along
90 if ( selector.selector && selector.context ) {
91 this.selector = selector.selector;
92 this.context = selector.context;
93 }
94
95 return this.setArray(jQuery.makeArray(selector));
96 },
97
98 // Start with an empty selector
99 selector: "",
100
101 // The current version of jQuery being used
102 jquery: "1.3",
103
104 // The number of elements contained in the matched element set
105 size: function() {
106 return this.length;
107 },
108
109 // Get the Nth element in the matched element set OR
110 // Get the whole matched element set as a clean array
111 get: function( num ) {
112 return num === undefined ?
113
114 // Return a 'clean' array
115 jQuery.makeArray( this ) :
116
117 // Return just the object
118 this[ num ];
119 },
120
121 // Take an array of elements and push it onto the stack
122 // (returning the new matched element set)
123 pushStack: function( elems, name, selector ) {
124 // Build a new jQuery matched element set
125 var ret = jQuery( elems );
126
127 // Add the old object onto the stack (as a reference)
128 ret.prevObject = this;
129
130 ret.context = this.context;
131
132 if ( name === "find" )
133 ret.selector = this.selector + (this.selector ? " " : "") + selector;
134 else if ( name )
135 ret.selector = this.selector + "." + name + "(" + selector + ")";
136
137 // Return the newly-formed element set
138 return ret;
139 },
140
141 // Force the current matched set of elements to become
142 // the specified array of elements (destroying the stack in the process)
143 // You should use pushStack() in order to do this, but maintain the stack
144 setArray: function( elems ) {
145 // Resetting the length to 0, then using the native Array push
146 // is a super-fast way to populate an object with array-like properties
147 this.length = 0;
148 Array.prototype.push.apply( this, elems );
149
150 return this;
151 },
152
153 // Execute a callback for every element in the matched set.
154 // (You can seed the arguments with an array of args, but this is
155 // only used internally.)
156 each: function( callback, args ) {
157 return jQuery.each( this, callback, args );
158 },
159
160 // Determine the position of an element within
161 // the matched set of elements
162 index: function( elem ) {
163 // Locate the position of the desired element
164 return jQuery.inArray(
165 // If it receives a jQuery object, the first element is used
166 elem && elem.jquery ? elem[0] : elem
167 , this );
168 },
169
170 attr: function( name, value, type ) {
171 var options = name;
172
173 // Look for the case where we're accessing a style value
174 if ( typeof name === "string" )
175 if ( value === undefined )
176 return this[0] && jQuery[ type || "attr" ]( this[0], name );
177
178 else {
179 options = {};
180 options[ name ] = value;
181 }
182
183 // Check to see if we're setting style values
184 return this.each(function(i){
185 // Set all the styles
186 for ( name in options )
187 jQuery.attr(
188 type ?
189 this.style :
190 this,
191 name, jQuery.prop( this, options[ name ], type, i, name )
192 );
193 });
194 },
195
196 css: function( key, value ) {
197 // ignore negative width and height values
198 if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
199 value = undefined;
200 return this.attr( key, value, "curCSS" );
201 },
202
203 text: function( text ) {
204 if ( typeof text !== "object" && text != null )
205 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
206
207 var ret = "";
208
209 jQuery.each( text || this, function(){
210 jQuery.each( this.childNodes, function(){
211 if ( this.nodeType != 8 )
212 ret += this.nodeType != 1 ?
213 this.nodeValue :
214 jQuery.fn.text( [ this ] );
215 });
216 });
217
218 return ret;
219 },
220
221 wrapAll: function( html ) {
222 if ( this[0] ) {
223 // The elements to wrap the target around
224 var wrap = jQuery( html, this[0].ownerDocument ).clone();
225
226 if ( this[0].parentNode )
227 wrap.insertBefore( this[0] );
228
229 wrap.map(function(){
230 var elem = this;
231
232 while ( elem.firstChild )
233 elem = elem.firstChild;
234
235 return elem;
236 }).append(this);
237 }
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, function(elem){
256 if (this.nodeType == 1)
257 this.appendChild( elem );
258 });
259 },
260
261 prepend: function() {
262 return this.domManip(arguments, 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, function(elem){
270 this.parentNode.insertBefore( elem, this );
271 });
272 },
273
274 after: function() {
275 return this.domManip(arguments, false, function(elem){
276 this.parentNode.insertBefore( elem, this.nextSibling );
277 });
278 },
279
280 end: function() {
281 return this.prevObject || jQuery( [] );
282 },
283
284 // For internal use only.
285 // Behaves like an Array's .push method, not like a jQuery method.
286 push: [].push,
287
288 find: function( selector ) {
289 if ( this.length === 1 && !/,/.test(selector) ) {
290 var ret = this.pushStack( [], "find", selector );
291 ret.length = 0;
292 jQuery.find( selector, this[0], ret );
293 return ret;
294 } else {
295 var elems = jQuery.map(this, function(elem){
296 return jQuery.find( selector, elem );
297 });
298
299 return this.pushStack( /[^+>] [^+>]/.test( selector ) ?
300 jQuery.unique( elems ) :
301 elems, "find", selector );
302 }
303 },
304
305 clone: function( events ) {
306 // Do the clone
307 var ret = this.map(function(){
308 if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
309 // IE copies events bound via attachEvent when
310 // using cloneNode. Calling detachEvent on the
311 // clone will also remove the events from the orignal
312 // In order to get around this, we use innerHTML.
313 // Unfortunately, this means some modifications to
314 // attributes in IE that are actually only stored
315 // as properties will not be copied (such as the
316 // the name attribute on an input).
317 var clone = this.cloneNode(true),
318 container = document.createElement("div");
319 container.appendChild(clone);
320 return jQuery.clean([container.innerHTML])[0];
321 } else
322 return this.cloneNode(true);
323 });
324
325 // Need to set the expando to null on the cloned set if it exists
326 // removeData doesn't work here, IE removes it from the original as well
327 // this is primarily for IE but the data expando shouldn't be copied over in any browser
328 var clone = ret.find("*").andSelf().each(function(){
329 if ( this[ expando ] !== undefined )
330 this[ expando ] = null;
331 });
332
333 // Copy the events from the original to the clone
334 if ( events === true )
335 this.find("*").andSelf().each(function(i){
336 if (this.nodeType == 3)
337 return;
338 var events = jQuery.data( this, "events" );
339
340 for ( var type in events )
341 for ( var handler in events[ type ] )
342 jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );
343 });
344
345 // Return the cloned set
346 return ret;
347 },
348
349 filter: function( selector ) {
350 return this.pushStack(
351 jQuery.isFunction( selector ) &&
352 jQuery.grep(this, function(elem, i){
353 return selector.call( elem, i );
354 }) ||
355
356 jQuery.multiFilter( selector, jQuery.grep(this, function(elem){
357 return elem.nodeType === 1;
358 }) ), "filter", selector );
359 },
360
361 closest: function( selector ) {
362 var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null;
363
364 return this.map(function(){
365 var cur = this;
366 while ( cur && cur.ownerDocument ) {
367 if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) )
368 return cur;
369 cur = cur.parentNode;
370 }
371 });
372 },
373
374 not: function( selector ) {
375 if ( typeof selector === "string" )
376 // test special case where just one selector is passed in
377 if ( isSimple.test( selector ) )
378 return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector );
379 else
380 selector = jQuery.multiFilter( selector, this );
381
382 var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
383 return this.filter(function() {
384 return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
385 });
386 },
387
388 add: function( selector ) {
389 return this.pushStack( jQuery.unique( jQuery.merge(
390 this.get(),
391 typeof selector === "string" ?
392 jQuery( selector ) :
393 jQuery.makeArray( selector )
394 )));
395 },
396
397 is: function( selector ) {
398 return !!selector && jQuery.multiFilter( selector, this ).length > 0;
399 },
400
401 hasClass: function( selector ) {
402 return !!selector && this.is( "." + selector );
403 },
404
405 val: function( value ) {
406 if ( value === undefined ) {
407 var elem = this[0];
408
409 if ( elem ) {
410 if( jQuery.nodeName( elem, 'option' ) )
411 return (elem.attributes.value || {}).specified ? elem.value : elem.text;
412
413 // We need to handle select boxes special
414 if ( jQuery.nodeName( elem, "select" ) ) {
415 var index = elem.selectedIndex,
416 values = [],
417 options = elem.options,
418 one = elem.type == "select-one";
419
420 // Nothing was selected
421 if ( index < 0 )
422 return null;
423
424 // Loop through all the selected options
425 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
426 var option = options[ i ];
427
428 if ( option.selected ) {
429 // Get the specifc value for the option
430 value = jQuery(option).val();
431
432 // We don't need an array for one selects
433 if ( one )
434 return value;
435
436 // Multi-Selects return an array
437 values.push( value );
438 }
439 }
440
441 return values;
442 }
443
444 // Everything else, we just grab the value
445 return (elem.value || "").replace(/\r/g, "");
446
447 }
448
449 return undefined;
450 }
451
452 if ( typeof value === "number" )
453 value += '';
454
455 return this.each(function(){
456 if ( this.nodeType != 1 )
457 return;
458
459 if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) )
460 this.checked = (jQuery.inArray(this.value, value) >= 0 ||
461 jQuery.inArray(this.name, value) >= 0);
462
463 else if ( jQuery.nodeName( this, "select" ) ) {
464 var values = jQuery.makeArray(value);
465
466 jQuery( "option", this ).each(function(){
467 this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
468 jQuery.inArray( this.text, values ) >= 0);
469 });
470
471 if ( !values.length )
472 this.selectedIndex = -1;
473
474 } else
475 this.value = value;
476 });
477 },
478
479 html: function( value ) {
480 return value === undefined ?
481 (this[0] ?
482 this[0].innerHTML :
483 null) :
484 this.empty().append( value );
485 },
486
487 replaceWith: function( value ) {
488 return this.after( value ).remove();
489 },
490
491 eq: function( i ) {
492 return this.slice( i, +i + 1 );
493 },
494
495 slice: function() {
496 return this.pushStack( Array.prototype.slice.apply( this, arguments ),
497 "slice", Array.prototype.slice.call(arguments).join(",") );
498 },
499
500 map: function( callback ) {
501 return this.pushStack( jQuery.map(this, function(elem, i){
502 return callback.call( elem, i, elem );
503 }));
504 },
505
506 andSelf: function() {
507 return this.add( this.prevObject );
508 },
509
510 domManip: function( args, table, callback ) {
511 if ( this[0] ) {
512 var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
513 scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
514 first = fragment.firstChild,
515 extra = this.length > 1 ? fragment.cloneNode(true) : fragment;
516
517 if ( first )
518 for ( var i = 0, l = this.length; i < l; i++ )
519 callback.call( root(this[i], first), i > 0 ? extra.cloneNode(true) : fragment );
520
521 if ( scripts )
522 jQuery.each( scripts, evalScript );
523 }
524
525 return this;
526
527 function root( elem, cur ) {
528 return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
529 (elem.getElementsByTagName("tbody")[0] ||
530 elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
531 elem;
532 }
533 }
534 };
535
536 // Give the init function the jQuery prototype for later instantiation
537 jQuery.fn.init.prototype = jQuery.fn;
538
539 function evalScript( i, elem ) {
540 if ( elem.src )
541 jQuery.ajax({
542 url: elem.src,
543 async: false,
544 dataType: "script"
545 });
546
547 else
548 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
549
550 if ( elem.parentNode )
551 elem.parentNode.removeChild( elem );
552 }
553
554 function now(){
555 return +new Date;
556 }
557
558 jQuery.extend = jQuery.fn.extend = function() {
559 // copy reference to target object
560 var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
561
562 // Handle a deep copy situation
563 if ( typeof target === "boolean" ) {
564 deep = target;
565 target = arguments[1] || {};
566 // skip the boolean and the target
567 i = 2;
568 }
569
570 // Handle case when target is a string or something (possible in deep copy)
571 if ( typeof target !== "object" && !jQuery.isFunction(target) )
572 target = {};
573
574 // extend jQuery itself if only one argument is passed
575 if ( length == i ) {
576 target = this;
577 --i;
578 }
579
580 for ( ; i < length; i++ )
581 // Only deal with non-null/undefined values
582 if ( (options = arguments[ i ]) != null )
583 // Extend the base object
584 for ( var name in options ) {
585 var src = target[ name ], copy = options[ name ];
586
587 // Prevent never-ending loop
588 if ( target === copy )
589 continue;
590
591 // Recurse if we're merging object values
592 if ( deep && copy && typeof copy === "object" && !copy.nodeType )
593 target[ name ] = jQuery.extend( deep,
594 // Never move original objects, clone them
595 src || ( copy.length != null ? [ ] : { } )
596 , copy );
597
598 // Don't bring in undefined values
599 else if ( copy !== undefined )
600 target[ name ] = copy;
601
602 }
603
604 // Return the modified object
605 return target;
606 };
607
608 // exclude the following css properties to add px
609 var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
610 // cache defaultView
611 defaultView = document.defaultView || {},
612 toString = Object.prototype.toString;
613
614 jQuery.extend({
615 noConflict: function( deep ) {
616 window.$ = _$;
617
618 if ( deep )
619 window.jQuery = _jQuery;
620
621 return jQuery;
622 },
623
624 // See test/unit/core.js for details concerning isFunction.
625 // Since version 1.3, DOM methods and functions like alert
626 // aren't supported. They return false on IE (#2968).
627 isFunction: function( obj ) {
628 return toString.call(obj) === "[object Function]";
629 },
630
631 isArray: function( obj ) {
632 return toString.call(obj) === "[object Array]";
633 },
634
635 // check if an element is in a (or is an) XML document
636 isXMLDoc: function( elem ) {
637 return elem.documentElement && !elem.body ||
638 elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
639 },
640
641 // Evalulates a script in a global context
642 globalEval: function( data ) {
643 data = jQuery.trim( data );
644
645 if ( data ) {
646 // Inspired by code by Andrea Giammarchi
647 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
648 var head = document.getElementsByTagName("head")[0] || document.documentElement,
649 script = document.createElement("script");
650
651 script.type = "text/javascript";
652 if ( jQuery.support.scriptEval )
653 script.appendChild( document.createTextNode( data ) );
654 else
655 script.text = data;
656
657 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
658 // This arises when a base node is used (#2709).
659 head.insertBefore( script, head.firstChild );
660 head.removeChild( script );
661 }
662 },
663
664 nodeName: function( elem, name ) {
665 return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
666 },
667
668 // args is for internal usage only
669 each: function( object, callback, args ) {
670 var name, i = 0, length = object.length;
671
672 if ( args ) {
673 if ( length === undefined ) {
674 for ( name in object )
675 if ( callback.apply( object[ name ], args ) === false )
676 break;
677 } else
678 for ( ; i < length; )
679 if ( callback.apply( object[ i++ ], args ) === false )
680 break;
681
682 // A special, fast, case for the most common use of each
683 } else {
684 if ( length === undefined ) {
685 for ( name in object )
686 if ( callback.call( object[ name ], name, object[ name ] ) === false )
687 break;
688 } else
689 for ( var value = object[0];
690 i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
691 }
692
693 return object;
694 },
695
696 prop: function( elem, value, type, i, name ) {
697 // Handle executable functions
698 if ( jQuery.isFunction( value ) )
699 value = value.call( elem, i );
700
701 // Handle passing in a number to a CSS property
702 return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ?
703 value + "px" :
704 value;
705 },
706
707 className: {
708 // internal only, use addClass("class")
709 add: function( elem, classNames ) {
710 jQuery.each((classNames || "").split(/\s+/), function(i, className){
711 if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
712 elem.className += (elem.className ? " " : "") + className;
713 });
714 },
715
716 // internal only, use removeClass("class")
717 remove: function( elem, classNames ) {
718 if (elem.nodeType == 1)
719 elem.className = classNames !== undefined ?
720 jQuery.grep(elem.className.split(/\s+/), function(className){
721 return !jQuery.className.has( classNames, className );
722 }).join(" ") :
723 "";
724 },
725
726 // internal only, use hasClass("class")
727 has: function( elem, className ) {
728 return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
729 }
730 },
731
732 // A method for quickly swapping in/out CSS properties to get correct calculations
733 swap: function( elem, options, callback ) {
734 var old = {};
735 // Remember the old values, and insert the new ones
736 for ( var name in options ) {
737 old[ name ] = elem.style[ name ];
738 elem.style[ name ] = options[ name ];
739 }
740
741 callback.call( elem );
742
743 // Revert the old values
744 for ( var name in options )
745 elem.style[ name ] = old[ name ];
746 },
747
748 css: function( elem, name, force ) {
749 if ( name == "width" || name == "height" ) {
750 var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
751
752 function getWH() {
753 val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
754 var padding = 0, border = 0;
755 jQuery.each( which, function() {
756 padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
757 border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
758 });
759 val -= Math.round(padding + border);
760 }
761
762 if ( jQuery(elem).is(":visible") )
763 getWH();
764 else
765 jQuery.swap( elem, props, getWH );
766
767 return Math.max(0, val);
768 }
769
770 return jQuery.curCSS( elem, name, force );
771 },
772
773 curCSS: function( elem, name, force ) {
774 var ret, style = elem.style;
775
776 // We need to handle opacity special in IE
777 if ( name == "opacity" && !jQuery.support.opacity ) {
778 ret = jQuery.attr( style, "opacity" );
779
780 return ret == "" ?
781 "1" :
782 ret;
783 }
784
785 // Make sure we're using the right name for getting the float value
786 if ( name.match( /float/i ) )
787 name = styleFloat;
788
789 if ( !force && style && style[ name ] )
790 ret = style[ name ];
791
792 else if ( defaultView.getComputedStyle ) {
793
794 // Only "float" is needed here
795 if ( name.match( /float/i ) )
796 name = "float";
797
798 name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
799
800 var computedStyle = defaultView.getComputedStyle( elem, null );
801
802 if ( computedStyle )
803 ret = computedStyle.getPropertyValue( name );
804
805 // We should always get a number back from opacity
806 if ( name == "opacity" && ret == "" )
807 ret = "1";
808
809 } else if ( elem.currentStyle ) {
810 var camelCase = name.replace(/\-(\w)/g, function(all, letter){
811 return letter.toUpperCase();
812 });
813
814 ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
815
816 // From the awesome hack by Dean Edwards
817 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
818
819 // If we're not dealing with a regular pixel number
820 // but a number that has a weird ending, we need to convert it to pixels
821 if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
822 // Remember the original values
823 var left = style.left, rsLeft = elem.runtimeStyle.left;
824
825 // Put in the new values to get a computed value out
826 elem.runtimeStyle.left = elem.currentStyle.left;
827 style.left = ret || 0;
828 ret = style.pixelLeft + "px";
829
830 // Revert the changed values
831 style.left = left;
832 elem.runtimeStyle.left = rsLeft;
833 }
834 }
835
836 return ret;
837 },
838
839 clean: function( elems, context, fragment ) {
840 context = context || document;
841
842 // !context.createElement fails in IE with an error but returns typeof 'object'
843 if ( typeof context.createElement === "undefined" )
844 context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
845
846 // If a single string is passed in and it's a single tag
847 // just do a createElement and skip the rest
848 if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) {
849 var match = /^<(\w+)\s*\/?>$/.exec(elems[0]);
850 if ( match )
851 return [ context.createElement( match[1] ) ];
852 }
853
854 var ret = [], scripts = [], div = context.createElement("div");
855
856 jQuery.each(elems, function(i, elem){
857 if ( typeof elem === "number" )
858 elem += '';
859
860 if ( !elem )
861 return;
862
863 // Convert html string into DOM nodes
864 if ( typeof elem === "string" ) {
865 // Fix "XHTML"-style tags in all browsers
866 elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
867 return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
868 all :
869 front + "></" + tag + ">";
870 });
871
872 // Trim whitespace, otherwise indexOf won't work as expected
873 var tags = jQuery.trim( elem ).toLowerCase();
874
875 var wrap =
876 // option or optgroup
877 !tags.indexOf("<opt") &&
878 [ 1, "<select multiple='multiple'>", "</select>" ] ||
879
880 !tags.indexOf("<leg") &&
881 [ 1, "<fieldset>", "</fieldset>" ] ||
882
883 tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
884 [ 1, "<table>", "</table>" ] ||
885
886 !tags.indexOf("<tr") &&
887 [ 2, "<table><tbody>", "</tbody></table>" ] ||
888
889 // <thead> matched above
890 (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
891 [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
892
893 !tags.indexOf("<col") &&
894 [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
895
896 // IE can't serialize <link> and <script> tags normally
897 !jQuery.support.htmlSerialize &&
898 [ 1, "div<div>", "</div>" ] ||
899
900 [ 0, "", "" ];
901
902 // Go to html and back, then peel off extra wrappers
903 div.innerHTML = wrap[1] + elem + wrap[2];
904
905 // Move to the right depth
906 while ( wrap[0]-- )
907 div = div.lastChild;
908
909 // Remove IE's autoinserted <tbody> from table fragments
910 if ( !jQuery.support.tbody ) {
911
912 // String was a <table>, *may* have spurious <tbody>
913 var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ?
914 div.firstChild && div.firstChild.childNodes :
915
916 // String was a bare <thead> or <tfoot>
917 wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ?
918 div.childNodes :
919 [];
920
921 for ( var j = tbody.length - 1; j >= 0 ; --j )
922 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
923 tbody[ j ].parentNode.removeChild( tbody[ j ] );
924
925 }
926
927 // IE completely kills leading whitespace when innerHTML is used
928 if ( !jQuery.support.leadingWhitespace && /^\s/.test( elem ) )
929 div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
930
931 elem = jQuery.makeArray( div.childNodes );
932 }
933
934 if ( elem.nodeType )
935 ret.push( elem );
936 else
937 ret = jQuery.merge( ret, elem );
938
939 });
940
941 if ( fragment ) {
942 for ( var i = 0; ret[i]; i++ ) {
943 if ( jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
944 scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
945 } else {
946 if ( ret[i].nodeType === 1 )
947 ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
948 fragment.appendChild( ret[i] );
949 }
950 }
951
952 return scripts;
953 }
954
955 return ret;
956 },
957
958 attr: function( elem, name, value ) {
959 // don't set attributes on text and comment nodes
960 if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
961 return undefined;
962
963 var notxml = !jQuery.isXMLDoc( elem ),
964 // Whether we are setting (or getting)
965 set = value !== undefined;
966
967 // Try to normalize/fix the name
968 name = notxml && jQuery.props[ name ] || name;
969
970 // Only do all the following if this is a node (faster for style)
971 // IE elem.getAttribute passes even for style
972 if ( elem.tagName ) {
973
974 // These attributes require special treatment
975 var special = /href|src|style/.test( name );
976
977 // Safari mis-reports the default selected property of a hidden option
978 // Accessing the parent's selectedIndex property fixes it
979 if ( name == "selected" && elem.parentNode )
980 elem.parentNode.selectedIndex;
981
982 // If applicable, access the attribute via the DOM 0 way
983 if ( name in elem && notxml && !special ) {
984 if ( set ){
985 // We can't allow the type property to be changed (since it causes problems in IE)
986 if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
987 throw "type property can't be changed";
988
989 elem[ name ] = value;
990 }
991
992 // browsers index elements by id/name on forms, give priority to attributes.
993 if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
994 return elem.getAttributeNode( name ).nodeValue;
995
996 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
997 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
998 if ( name == "tabIndex" ) {
999 var attributeNode = elem.getAttributeNode( "tabIndex" );
1000 return attributeNode && attributeNode.specified
1001 ? attributeNode.value
1002 : elem.nodeName.match(/^(a|area|button|input|object|select|textarea)$/i)
1003 ? 0
1004 : undefined;
1005 }
1006
1007 return elem[ name ];
1008 }
1009
1010 if ( !jQuery.support.style && notxml && name == "style" )
1011 return jQuery.attr( elem.style, "cssText", value );
1012
1013 if ( set )
1014 // convert the value to a string (all browsers do this but IE) see #1070
1015 elem.setAttribute( name, "" + value );
1016
1017 var attr = !jQuery.support.hrefNormalized && notxml && special
1018 // Some attributes require a special call on IE
1019 ? elem.getAttribute( name, 2 )
1020 : elem.getAttribute( name );
1021
1022 // Non-existent attributes return null, we normalize to undefined
1023 return attr === null ? undefined : attr;
1024 }
1025
1026 // elem is actually elem.style ... set the style
1027
1028 // IE uses filters for opacity
1029 if ( !jQuery.support.opacity && name == "opacity" ) {
1030 if ( set ) {
1031 // IE has trouble with opacity if it does not have layout
1032 // Force it by setting the zoom level
1033 elem.zoom = 1;
1034
1035 // Set the alpha filter to set the opacity
1036 elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
1037 (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
1038 }
1039
1040 return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
1041 (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
1042 "";
1043 }
1044
1045 name = name.replace(/-([a-z])/ig, function(all, letter){
1046 return letter.toUpperCase();
1047 });
1048
1049 if ( set )
1050 elem[ name ] = value;
1051
1052 return elem[ name ];
1053 },
1054
1055 trim: function( text ) {
1056 return (text || "").replace( /^\s+|\s+$/g, "" );
1057 },
1058
1059 makeArray: function( array ) {
1060 var ret = [];
1061
1062 if( array != null ){
1063 var i = array.length;
1064 // The window, strings (and functions) also have 'length'
1065 if( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval )
1066 ret[0] = array;
1067 else
1068 while( i )
1069 ret[--i] = array[i];
1070 }
1071
1072 return ret;
1073 },
1074
1075 inArray: function( elem, array ) {
1076 for ( var i = 0, length = array.length; i < length; i++ )
1077 // Use === because on IE, window == document
1078 if ( array[ i ] === elem )
1079 return i;
1080
1081 return -1;
1082 },
1083
1084 merge: function( first, second ) {
1085 // We have to loop this way because IE & Opera overwrite the length
1086 // expando of getElementsByTagName
1087 var i = 0, elem, pos = first.length;
1088 // Also, we need to make sure that the correct elements are being returned
1089 // (IE returns comment nodes in a '*' query)
1090 if ( !jQuery.support.getAll ) {
1091 while ( (elem = second[ i++ ]) != null )
1092 if ( elem.nodeType != 8 )
1093 first[ pos++ ] = elem;
1094
1095 } else
1096 while ( (elem = second[ i++ ]) != null )
1097 first[ pos++ ] = elem;
1098
1099 return first;
1100 },
1101
1102 unique: function( array ) {
1103 var ret = [], done = {};
1104
1105 try {
1106
1107 for ( var i = 0, length = array.length; i < length; i++ ) {
1108 var id = jQuery.data( array[ i ] );
1109
1110 if ( !done[ id ] ) {
1111 done[ id ] = true;
1112 ret.push( array[ i ] );
1113 }
1114 }
1115
1116 } catch( e ) {
1117 ret = array;
1118 }
1119
1120 return ret;
1121 },
1122
1123 grep: function( elems, callback, inv ) {
1124 var ret = [];
1125
1126 // Go through the array, only saving the items
1127 // that pass the validator function
1128 for ( var i = 0, length = elems.length; i < length; i++ )
1129 if ( !inv != !callback( elems[ i ], i ) )
1130 ret.push( elems[ i ] );
1131
1132 return ret;
1133 },
1134
1135 map: function( elems, callback ) {
1136 var ret = [];
1137
1138 // Go through the array, translating each of the items to their
1139 // new value (or values).
1140 for ( var i = 0, length = elems.length; i < length; i++ ) {
1141 var value = callback( elems[ i ], i );
1142
1143 if ( value != null )
1144 ret[ ret.length ] = value;
1145 }
1146
1147 return ret.concat.apply( [], ret );
1148 }
1149 });
1150
1151 // Use of jQuery.browser is deprecated.
1152 // It's included for backwards compatibility and plugins,
1153 // although they should work to migrate away.
1154
1155 var userAgent = navigator.userAgent.toLowerCase();
1156
1157 // Figure out what browser is being used
1158 jQuery.browser = {
1159 version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
1160 safari: /webkit/.test( userAgent ),
1161 opera: /opera/.test( userAgent ),
1162 msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
1163 mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
1164 };
1165
1166 jQuery.each({
1167 parent: function(elem){return elem.parentNode;},
1168 parents: function(elem){return jQuery.dir(elem,"parentNode");},
1169 next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
1170 prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
1171 nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
1172 prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
1173 siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
1174 children: function(elem){return jQuery.sibling(elem.firstChild);},
1175 contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
1176 }, function(name, fn){
1177 jQuery.fn[ name ] = function( selector ) {
1178 var ret = jQuery.map( this, fn );
1179
1180 if ( selector && typeof selector == "string" )
1181 ret = jQuery.multiFilter( selector, ret );
1182
1183 return this.pushStack( jQuery.unique( ret ), name, selector );
1184 };
1185 });
1186
1187 jQuery.each({
1188 appendTo: "append",
1189 prependTo: "prepend",
1190 insertBefore: "before",
1191 insertAfter: "after",
1192 replaceAll: "replaceWith"
1193 }, function(name, original){
1194 jQuery.fn[ name ] = function() {
1195 var args = arguments;
1196
1197 return this.each(function(){
1198 for ( var i = 0, length = args.length; i < length; i++ )
1199 jQuery( args[ i ] )[ original ]( this );
1200 });
1201 };
1202 });
1203
1204 jQuery.each({
1205 removeAttr: function( name ) {
1206 jQuery.attr( this, name, "" );
1207 if (this.nodeType == 1)
1208 this.removeAttribute( name );
1209 },
1210
1211 addClass: function( classNames ) {
1212 jQuery.className.add( this, classNames );
1213 },
1214
1215 removeClass: function( classNames ) {
1216 jQuery.className.remove( this, classNames );
1217 },
1218
1219 toggleClass: function( classNames, state ) {
1220 if( typeof state !== "boolean" )
1221 state = !jQuery.className.has( this, classNames );
1222 jQuery.className[ state ? "add" : "remove" ]( this, classNames );
1223 },
1224
1225 remove: function( selector ) {
1226 if ( !selector || jQuery.filter( selector, [ this ] ).length ) {
1227 // Prevent memory leaks
1228 jQuery( "*", this ).add([this]).each(function(){
1229 jQuery.event.remove(this);
1230 jQuery.removeData(this);
1231 });
1232 if (this.parentNode)
1233 this.parentNode.removeChild( this );
1234 }
1235 },
1236
1237 empty: function() {
1238 // Remove element nodes and prevent memory leaks
1239 jQuery( ">*", this ).remove();
1240
1241 // Remove any remaining nodes
1242 while ( this.firstChild )
1243 this.removeChild( this.firstChild );
1244 }
1245 }, function(name, fn){
1246 jQuery.fn[ name ] = function(){
1247 return this.each( fn, arguments );
1248 };
1249 });
1250
1251 // Helper function used by the dimensions and offset modules
1252 function num(elem, prop) {
1253 return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
1254 }
1255 var expando = "jQuery" + now(), uuid = 0, windowData = {};
1256
1257 jQuery.extend({
1258 cache: {},
1259
1260 data: function( elem, name, data ) {
1261 elem = elem == window ?
1262 windowData :
1263 elem;
1264
1265 var id = elem[ expando ];
1266
1267 // Compute a unique ID for the element
1268 if ( !id )
1269 id = elem[ expando ] = ++uuid;
1270
1271 // Only generate the data cache if we're
1272 // trying to access or manipulate it
1273 if ( name && !jQuery.cache[ id ] )
1274 jQuery.cache[ id ] = {};
1275
1276 // Prevent overriding the named cache with undefined values
1277 if ( data !== undefined )
1278 jQuery.cache[ id ][ name ] = data;
1279
1280 // Return the named cache data, or the ID for the element
1281 return name ?
1282 jQuery.cache[ id ][ name ] :
1283 id;
1284 },
1285
1286 removeData: function( elem, name ) {
1287 elem = elem == window ?
1288 windowData :
1289 elem;
1290
1291 var id = elem[ expando ];
1292
1293 // If we want to remove a specific section of the element's data
1294 if ( name ) {
1295 if ( jQuery.cache[ id ] ) {
1296 // Remove the section of cache data
1297 delete jQuery.cache[ id ][ name ];
1298
1299 // If we've removed all the data, remove the element's cache
1300 name = "";
1301
1302 for ( name in jQuery.cache[ id ] )
1303 break;
1304
1305 if ( !name )
1306 jQuery.removeData( elem );
1307 }
1308
1309 // Otherwise, we want to remove all of the element's data
1310 } else {
1311 // Clean up the element expando
1312 try {
1313 delete elem[ expando ];
1314 } catch(e){
1315 // IE has trouble directly removing the expando
1316 // but it's ok with using removeAttribute
1317 if ( elem.removeAttribute )
1318 elem.removeAttribute( expando );
1319 }
1320
1321 // Completely remove the data cache
1322 delete jQuery.cache[ id ];
1323 }
1324 },
1325 queue: function( elem, type, data ) {
1326 if ( elem ){
1327
1328 type = (type || "fx") + "queue";
1329
1330 var q = jQuery.data( elem, type );
1331
1332 if ( !q || jQuery.isArray(data) )
1333 q = jQuery.data( elem, type, jQuery.makeArray(data) );
1334 else if( data )
1335 q.push( data );
1336
1337 }
1338 return q;
1339 },
1340
1341 dequeue: function( elem, type ){
1342 var queue = jQuery.queue( elem, type ),
1343 fn = queue.shift();
1344
1345 if( !type || type === "fx" )
1346 fn = queue[0];
1347
1348 if( fn !== undefined )
1349 fn.call(elem);
1350 }
1351 });
1352
1353 jQuery.fn.extend({
1354 data: function( key, value ){
1355 var parts = key.split(".");
1356 parts[1] = parts[1] ? "." + parts[1] : "";
1357
1358 if ( value === undefined ) {
1359 var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1360
1361 if ( data === undefined && this.length )
1362 data = jQuery.data( this[0], key );
1363
1364 return data === undefined && parts[1] ?
1365 this.data( parts[0] ) :
1366 data;
1367 } else
1368 return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
1369 jQuery.data( this, key, value );
1370 });
1371 },
1372
1373 removeData: function( key ){
1374 return this.each(function(){
1375 jQuery.removeData( this, key );
1376 });
1377 },
1378 queue: function(type, data){
1379 if ( typeof type !== "string" ) {
1380 data = type;
1381 type = "fx";
1382 }
1383
1384 if ( data === undefined )
1385 return jQuery.queue( this[0], type );
1386
1387 return this.each(function(){
1388 var queue = jQuery.queue( this, type, data );
1389
1390 if( type == "fx" && queue.length == 1 )
1391 queue[0].call(this);
1392 });
1393 },
1394 dequeue: function(type){
1395 return this.each(function(){
1396 jQuery.dequeue( this, type );
1397 });
1398 }
1399 });/*!
1400 * Sizzle CSS Selector Engine - v0.9.1
1401 * Copyright 2009, The Dojo Foundation
1402 * Released under the MIT, BSD, and GPL Licenses.
1403 * More information: http://sizzlejs.com/
1404 */
1405 (function(){
1406
1407 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|[^[\]]+)+\]|\\.|[^ >+~,(\[]+)+|[>+~])(\s*,\s*)?/g,
1408 done = 0,
1409 toString = Object.prototype.toString;
1410
1411 var Sizzle = function(selector, context, results, seed) {
1412 results = results || [];
1413 context = context || document;
1414
1415 if ( context.nodeType !== 1 && context.nodeType !== 9 )
1416 return [];
1417
1418 if ( !selector || typeof selector !== "string" ) {
1419 return results;
1420 }
1421
1422 var parts = [], m, set, checkSet, check, mode, extra, prune = true;
1423
1424 // Reset the position of the chunker regexp (start from head)
1425 chunker.lastIndex = 0;
1426
1427 while ( (m = chunker.exec(selector)) !== null ) {
1428 parts.push( m[1] );
1429
1430 if ( m[2] ) {
1431 extra = RegExp.rightContext;
1432 break;
1433 }
1434 }
1435
1436 if ( parts.length > 1 && Expr.match.POS.exec( selector ) ) {
1437 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
1438 var later = "", match;
1439
1440 // Position selectors must be done after the filter
1441 while ( (match = Expr.match.POS.exec( selector )) ) {
1442 later += match[0];
1443 selector = selector.replace( Expr.match.POS, "" );
1444 }
1445
1446 set = Sizzle.filter( later, Sizzle( /\s$/.test(selector) ? selector + "*" : selector, context ) );
1447 } else {
1448 set = Expr.relative[ parts[0] ] ?
1449 [ context ] :
1450 Sizzle( parts.shift(), context );
1451
1452 while ( parts.length ) {
1453 var tmpSet = [];
1454
1455 selector = parts.shift();
1456 if ( Expr.relative[ selector ] )
1457 selector += parts.shift();
1458
1459 for ( var i = 0, l = set.length; i < l; i++ ) {
1460 Sizzle( selector, set[i], tmpSet );
1461 }
1462
1463 set = tmpSet;
1464 }
1465 }
1466 } else {
1467 var ret = seed ?
1468 { expr: parts.pop(), set: makeArray(seed) } :
1469 Sizzle.find( parts.pop(), parts.length === 1 && context.parentNode ? context.parentNode : context );
1470 set = Sizzle.filter( ret.expr, ret.set );
1471
1472 if ( parts.length > 0 ) {
1473 checkSet = makeArray(set);
1474 } else {
1475 prune = false;
1476 }
1477
1478 while ( parts.length ) {
1479 var cur = parts.pop(), pop = cur;
1480
1481 if ( !Expr.relative[ cur ] ) {
1482 cur = "";
1483 } else {
1484 pop = parts.pop();
1485 }
1486
1487 if ( pop == null ) {
1488 pop = context;
1489 }
1490
1491 Expr.relative[ cur ]( checkSet, pop, isXML(context) );
1492 }
1493 }
1494
1495 if ( !checkSet ) {
1496 checkSet = set;
1497 }
1498
1499 if ( !checkSet ) {
1500 throw "Syntax error, unrecognized expression: " + (cur || selector);
1501 }
1502
1503 if ( toString.call(checkSet) === "[object Array]" ) {
1504 if ( !prune ) {
1505 results.push.apply( results, checkSet );
1506 } else if ( context.nodeType === 1 ) {
1507 for ( var i = 0; checkSet[i] != null; i++ ) {
1508 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
1509 results.push( set[i] );
1510 }
1511 }
1512 } else {
1513 for ( var i = 0; checkSet[i] != null; i++ ) {
1514 if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
1515 results.push( set[i] );
1516 }
1517 }
1518 }
1519 } else {
1520 makeArray( checkSet, results );
1521 }
1522
1523 if ( extra ) {
1524 Sizzle( extra, context, results, seed );
1525 }
1526
1527 return results;
1528 };
1529
1530 Sizzle.matches = function(expr, set){
1531 return Sizzle(expr, null, null, set);
1532 };
1533
1534 Sizzle.find = function(expr, context){
1535 var set, match;
1536
1537 if ( !expr ) {
1538 return [];
1539 }
1540
1541 for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
1542 var type = Expr.order[i], match;
1543
1544 if ( (match = Expr.match[ type ].exec( expr )) ) {
1545 var left = RegExp.leftContext;
1546
1547 if ( left.substr( left.length - 1 ) !== "\\" ) {
1548 match[1] = (match[1] || "").replace(/\\/g, "");
1549 set = Expr.find[ type ]( match, context );
1550 if ( set != null ) {
1551 expr = expr.replace( Expr.match[ type ], "" );
1552 break;
1553 }
1554 }
1555 }
1556 }
1557
1558 if ( !set ) {
1559 set = context.getElementsByTagName("*");
1560 }
1561
1562 return {set: set, expr: expr};
1563 };
1564
1565 Sizzle.filter = function(expr, set, inplace, not){
1566 var old = expr, result = [], curLoop = set, match, anyFound;
1567
1568 while ( expr && set.length ) {
1569 for ( var type in Expr.filter ) {
1570 if ( (match = Expr.match[ type ].exec( expr )) != null ) {
1571 var filter = Expr.filter[ type ], goodArray = null, goodPos = 0, found, item;
1572 anyFound = false;
1573
1574 if ( curLoop == result ) {
1575 result = [];
1576 }
1577
1578 if ( Expr.preFilter[ type ] ) {
1579 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not );
1580
1581 if ( !match ) {
1582 anyFound = found = true;
1583 } else if ( match === true ) {
1584 continue;
1585 } else if ( match[0] === true ) {
1586 goodArray = [];
1587 var last = null, elem;
1588 for ( var i = 0; (elem = curLoop[i]) !== undefined; i++ ) {
1589 if ( elem && last !== elem ) {
1590 goodArray.push( elem );
1591 last = elem;
1592 }
1593 }
1594 }
1595 }
1596
1597 if ( match ) {
1598 for ( var i = 0; (item = curLoop[i]) !== undefined; i++ ) {
1599 if ( item ) {
1600 if ( goodArray && item != goodArray[goodPos] ) {
1601 goodPos++;
1602 }
1603
1604 found = filter( item, match, goodPos, goodArray );
1605 var pass = not ^ !!found;
1606
1607 if ( inplace && found != null ) {
1608 if ( pass ) {
1609 anyFound = true;
1610 } else {
1611 curLoop[i] = false;
1612 }
1613 } else if ( pass ) {
1614 result.push( item );
1615 anyFound = true;
1616 }
1617 }
1618 }
1619 }
1620
1621 if ( found !== undefined ) {
1622 if ( !inplace ) {
1623 curLoop = result;
1624 }
1625
1626 expr = expr.replace( Expr.match[ type ], "" );
1627
1628 if ( !anyFound ) {
1629 return [];
1630 }
1631
1632 break;
1633 }
1634 }
1635 }
1636
1637 expr = expr.replace(/\s*,\s*/, "");
1638
1639 // Improper expression
1640 if ( expr == old ) {
1641 if ( anyFound == null ) {
1642 throw "Syntax error, unrecognized expression: " + expr;
1643 } else {
1644 break;
1645 }
1646 }
1647
1648 old = expr;
1649 }
1650
1651 return curLoop;
1652 };
1653
1654 var Expr = Sizzle.selectors = {
1655 order: [ "ID", "NAME", "TAG" ],
1656 match: {
1657 ID: /#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
1658 CLASS: /\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
1659 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,
1660 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
1661 TAG: /^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,
1662 CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
1663 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
1664 PSEUDO: /:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
1665 },
1666 attrMap: {
1667 "class": "className",
1668 "for": "htmlFor"
1669 },
1670 attrHandle: {
1671 href: function(elem){
1672 return elem.getAttribute("href");
1673 }
1674 },
1675 relative: {
1676 "+": function(checkSet, part){
1677 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
1678 var elem = checkSet[i];
1679 if ( elem ) {
1680 var cur = elem.previousSibling;
1681 while ( cur && cur.nodeType !== 1 ) {
1682 cur = cur.previousSibling;
1683 }
1684 checkSet[i] = typeof part === "string" ?
1685 cur || false :
1686 cur === part;
1687 }
1688 }
1689
1690 if ( typeof part === "string" ) {
1691 Sizzle.filter( part, checkSet, true );
1692 }
1693 },
1694 ">": function(checkSet, part, isXML){
1695 if ( typeof part === "string" && !/\W/.test(part) ) {
1696 part = isXML ? part : part.toUpperCase();
1697
1698 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
1699 var elem = checkSet[i];
1700 if ( elem ) {
1701 var parent = elem.parentNode;
1702 checkSet[i] = parent.nodeName === part ? parent : false;
1703 }
1704 }
1705 } else {
1706 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
1707 var elem = checkSet[i];
1708 if ( elem ) {
1709 checkSet[i] = typeof part === "string" ?
1710 elem.parentNode :
1711 elem.parentNode === part;
1712 }
1713 }
1714
1715 if ( typeof part === "string" ) {
1716 Sizzle.filter( part, checkSet, true );
1717 }
1718 }
1719 },
1720 "": function(checkSet, part, isXML){
1721 var doneName = "done" + (done++), checkFn = dirCheck;
1722
1723 if ( !part.match(/\W/) ) {
1724 var nodeCheck = part = isXML ? part : part.toUpperCase();
1725 checkFn = dirNodeCheck;
1726 }
1727
1728 checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
1729 },
1730 "~": function(checkSet, part, isXML){
1731 var doneName = "done" + (done++), checkFn = dirCheck;
1732
1733 if ( typeof part === "string" && !part.match(/\W/) ) {
1734 var nodeCheck = part = isXML ? part : part.toUpperCase();
1735 checkFn = dirNodeCheck;
1736 }
1737
1738 checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
1739 }
1740 },
1741 find: {
1742 ID: function(match, context){
1743 if ( context.getElementById ) {
1744 var m = context.getElementById(match[1]);
1745 return m ? [m] : [];
1746 }
1747 },
1748 NAME: function(match, context){
1749 return context.getElementsByName ? context.getElementsByName(match[1]) : null;
1750 },
1751 TAG: function(match, context){
1752 return context.getElementsByTagName(match[1]);
1753 }
1754 },
1755 preFilter: {
1756 CLASS: function(match, curLoop, inplace, result, not){
1757 match = " " + match[1].replace(/\\/g, "") + " ";
1758
1759 for ( var i = 0; curLoop[i]; i++ ) {
1760 if ( not ^ (" " + curLoop[i].className + " ").indexOf(match) >= 0 ) {
1761 if ( !inplace )
1762 result.push( curLoop[i] );
1763 } else if ( inplace ) {
1764 curLoop[i] = false;
1765 }
1766 }
1767
1768 return false;
1769 },
1770 ID: function(match){
1771 return match[1].replace(/\\/g, "");
1772 },
1773 TAG: function(match, curLoop){
1774 for ( var i = 0; !curLoop[i]; i++ ){}
1775 return isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
1776 },
1777 CHILD: function(match){
1778 if ( match[1] == "nth" ) {
1779 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
1780 var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
1781 match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
1782 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
1783
1784 // calculate the numbers (first)n+(last) including if they are negative
1785 match[2] = (test[1] + (test[2] || 1)) - 0;
1786 match[3] = test[3] - 0;
1787 }
1788
1789 // TODO: Move to normal caching system
1790 match[0] = "done" + (done++);
1791
1792 return match;
1793 },
1794 ATTR: function(match){
1795 var name = match[1];
1796
1797 if ( Expr.attrMap[name] ) {
1798 match[1] = Expr.attrMap[name];
1799 }
1800
1801 if ( match[2] === "~=" ) {
1802 match[4] = " " + match[4] + " ";
1803 }
1804
1805 return match;
1806 },
1807 PSEUDO: function(match, curLoop, inplace, result, not){
1808 if ( match[1] === "not" ) {
1809 // If we're dealing with a complex expression, or a simple one
1810 if ( match[3].match(chunker).length > 1 ) {
1811 match[3] = Sizzle(match[3], null, null, curLoop);
1812 } else {
1813 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
1814 if ( !inplace ) {
1815 result.push.apply( result, ret );
1816 }
1817 return false;
1818 }
1819 } else if ( Expr.match.POS.test( match[0] ) ) {
1820 return true;
1821 }
1822
1823 return match;
1824 },
1825 POS: function(match){
1826 match.unshift( true );
1827 return match;
1828 }
1829 },
1830 filters: {
1831 enabled: function(elem){
1832 return elem.disabled === false && elem.type !== "hidden";
1833 },
1834 disabled: function(elem){
1835 return elem.disabled === true;
1836 },
1837 checked: function(elem){
1838 return elem.checked === true;
1839 },
1840 selected: function(elem){
1841 // Accessing this property makes selected-by-default
1842 // options in Safari work properly
1843 elem.parentNode.selectedIndex;
1844 return elem.selected === true;
1845 },
1846 parent: function(elem){
1847 return !!elem.firstChild;
1848 },
1849 empty: function(elem){
1850 return !elem.firstChild;
1851 },
1852 has: function(elem, i, match){
1853 return !!Sizzle( match[3], elem ).length;
1854 },
1855 header: function(elem){
1856 return /h\d/i.test( elem.nodeName );
1857 },
1858 text: function(elem){
1859 return "text" === elem.type;
1860 },
1861 radio: function(elem){
1862 return "radio" === elem.type;
1863 },
1864 checkbox: function(elem){
1865 return "checkbox" === elem.type;
1866 },
1867 file: function(elem){
1868 return "file" === elem.type;
1869 },
1870 password: function(elem){
1871 return "password" === elem.type;
1872 },
1873 submit: function(elem){
1874 return "submit" === elem.type;
1875 },
1876 image: function(elem){
1877 return "image" === elem.type;
1878 },
1879 reset: function(elem){
1880 return "reset" === elem.type;
1881 },
1882 button: function(elem){
1883 return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
1884 },
1885 input: function(elem){
1886 return /input|select|textarea|button/i.test(elem.nodeName);
1887 }
1888 },
1889 setFilters: {
1890 first: function(elem, i){
1891 return i === 0;
1892 },
1893 last: function(elem, i, match, array){
1894 return i === array.length - 1;
1895 },
1896 even: function(elem, i){
1897 return i % 2 === 0;
1898 },
1899 odd: function(elem, i){
1900 return i % 2 === 1;
1901 },
1902 lt: function(elem, i, match){
1903 return i < match[3] - 0;
1904 },
1905 gt: function(elem, i, match){
1906 return i > match[3] - 0;
1907 },
1908 nth: function(elem, i, match){
1909 return match[3] - 0 == i;
1910 },
1911 eq: function(elem, i, match){
1912 return match[3] - 0 == i;
1913 }
1914 },
1915 filter: {
1916 CHILD: function(elem, match){
1917 var type = match[1], parent = elem.parentNode;
1918
1919 var doneName = "child" + parent.childNodes.length;
1920
1921 if ( parent && (!parent[ doneName ] || !elem.nodeIndex) ) {
1922 var count = 1;
1923
1924 for ( var node = parent.firstChild; node; node = node.nextSibling ) {
1925 if ( node.nodeType == 1 ) {
1926 node.nodeIndex = count++;
1927 }
1928 }
1929
1930 parent[ doneName ] = count - 1;
1931 }
1932
1933 if ( type == "first" ) {
1934 return elem.nodeIndex == 1;
1935 } else if ( type == "last" ) {
1936 return elem.nodeIndex == parent[ doneName ];
1937 } else if ( type == "only" ) {
1938 return parent[ doneName ] == 1;
1939 } else if ( type == "nth" ) {
1940 var add = false, first = match[2], last = match[3];
1941
1942 if ( first == 1 && last == 0 ) {
1943 return true;
1944 }
1945
1946 if ( first == 0 ) {
1947 if ( elem.nodeIndex == last ) {
1948 add = true;
1949 }
1950 } else if ( (elem.nodeIndex - last) % first == 0 && (elem.nodeIndex - last) / first >= 0 ) {
1951 add = true;
1952 }
1953
1954 return add;
1955 }
1956 },
1957 PSEUDO: function(elem, match, i, array){
1958 var name = match[1], filter = Expr.filters[ name ];
1959
1960 if ( filter ) {
1961 return filter( elem, i, match, array );
1962 } else if ( name === "contains" ) {
1963 return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
1964 } else if ( name === "not" ) {
1965 var not = match[3];
1966
1967 for ( var i = 0, l = not.length; i < l; i++ ) {
1968 if ( not[i] === elem ) {
1969 return false;
1970 }
1971 }
1972
1973 return true;
1974 }
1975 },
1976 ID: function(elem, match){
1977 return elem.nodeType === 1 && elem.getAttribute("id") === match;
1978 },
1979 TAG: function(elem, match){
1980 return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
1981 },
1982 CLASS: function(elem, match){
1983 return match.test( elem.className );
1984 },
1985 ATTR: function(elem, match){
1986 var result = Expr.attrHandle[ match[1] ] ? Expr.attrHandle[ match[1] ]( elem ) : elem[ match[1] ] || elem.getAttribute( match[1] ), value = result + "", type = match[2], check = match[4];
1987 return result == null ?
1988 false :
1989 type === "=" ?
1990 value === check :
1991 type === "*=" ?
1992 value.indexOf(check) >= 0 :
1993 type === "~=" ?
1994 (" " + value + " ").indexOf(check) >= 0 :
1995 !match[4] ?
1996 result :
1997 type === "!=" ?
1998 value != check :
1999 type === "^=" ?
2000 value.indexOf(check) === 0 :
2001 type === "$=" ?
2002 value.substr(value.length - check.length) === check :
2003 type === "|=" ?
2004 value === check || value.substr(0, check.length + 1) === check + "-" :
2005 false;
2006 },
2007 POS: function(elem, match, i, array){
2008 var name = match[2], filter = Expr.setFilters[ name ];
2009
2010 if ( filter ) {
2011 return filter( elem, i, match, array );
2012 }
2013 }
2014 }
2015 };
2016
2017 for ( var type in Expr.match ) {
2018 Expr.match[ type ] = RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
2019 }
2020
2021 var makeArray = function(array, results) {
2022 array = Array.prototype.slice.call( array );
2023
2024 if ( results ) {
2025 results.push.apply( results, array );
2026 return results;
2027 }
2028
2029 return array;
2030 };
2031
2032 // Perform a simple check to determine if the browser is capable of
2033 // converting a NodeList to an array using builtin methods.
2034 try {
2035 Array.prototype.slice.call( document.documentElement.childNodes );
2036
2037 // Provide a fallback method if it does not work
2038 } catch(e){
2039 makeArray = function(array, results) {
2040 var ret = results || [];
2041
2042 if ( toString.call(array) === "[object Array]" ) {
2043 Array.prototype.push.apply( ret, array );
2044 } else {
2045 if ( typeof array.length === "number" ) {
2046 for ( var i = 0, l = array.length; i < l; i++ ) {
2047 ret.push( array[i] );
2048 }
2049 } else {
2050 for ( var i = 0; array[i]; i++ ) {
2051 ret.push( array[i] );
2052 }
2053 }
2054 }
2055
2056 return ret;
2057 };
2058 }
2059
2060 // Check to see if the browser returns elements by name when
2061 // querying by getElementById (and provide a workaround)
2062 (function(){
2063 // We're going to inject a fake input element with a specified name
2064 var form = document.createElement("form"),
2065 id = "script" + (new Date).getTime();
2066 form.innerHTML = "<input name='" + id + "'/>";
2067
2068 // Inject it into the root element, check its status, and remove it quickly
2069 var root = document.documentElement;
2070 root.insertBefore( form, root.firstChild );
2071
2072 // The workaround has to do additional checks after a getElementById
2073 // Which slows things down for other browsers (hence the branching)
2074 if ( !!document.getElementById( id ) ) {
2075 Expr.find.ID = function(match, context){
2076 if ( context.getElementById ) {
2077 var m = context.getElementById(match[1]);
2078 return m ? m.id === match[1] || m.getAttributeNode && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
2079 }
2080 };
2081
2082 Expr.filter.ID = function(elem, match){
2083 var node = elem.getAttributeNode && elem.getAttributeNode("id");
2084 return elem.nodeType === 1 && node && node.nodeValue === match;
2085 };
2086 }
2087
2088 root.removeChild( form );
2089 })();
2090
2091 (function(){
2092 // Check to see if the browser returns only elements
2093 // when doing getElementsByTagName("*")
2094
2095 // Create a fake element
2096 var div = document.createElement("div");
2097 div.appendChild( document.createComment("") );
2098
2099 // Make sure no comments are found
2100 if ( div.getElementsByTagName("*").length > 0 ) {
2101 Expr.find.TAG = function(match, context){
2102 var results = context.getElementsByTagName(match[1]);
2103
2104 // Filter out possible comments
2105 if ( match[1] === "*" ) {
2106 var tmp = [];
2107
2108 for ( var i = 0; results[i]; i++ ) {
2109 if ( results[i].nodeType === 1 ) {
2110 tmp.push( results[i] );
2111 }
2112 }
2113
2114 results = tmp;
2115 }
2116
2117 return results;
2118 };
2119 }
2120
2121 // Check to see if an attribute returns normalized href attributes
2122 div.innerHTML = "<a href='#'></a>";
2123 if ( div.firstChild.getAttribute("href") !== "#" ) {
2124 Expr.attrHandle.href = function(elem){
2125 return elem.getAttribute("href", 2);
2126 };
2127 }
2128 })();
2129
2130 if ( document.querySelectorAll ) (function(){
2131 var oldSizzle = Sizzle;
2132
2133 Sizzle = function(query, context, extra, seed){
2134 context = context || document;
2135
2136 if ( !seed && context.nodeType === 9 ) {
2137 try {
2138 return makeArray( context.querySelectorAll(query), extra );
2139 } catch(e){}
2140 }
2141
2142 return oldSizzle(query, context, extra, seed);
2143 };
2144
2145 Sizzle.find = oldSizzle.find;
2146 Sizzle.filter = oldSizzle.filter;
2147 Sizzle.selectors = oldSizzle.selectors;
2148 Sizzle.matches = oldSizzle.matches;
2149 })();
2150
2151 if ( document.documentElement.getElementsByClassName ) {
2152 Expr.order.splice(1, 0, "CLASS");
2153 Expr.find.CLASS = function(match, context) {
2154 return context.getElementsByClassName(match[1]);
2155 };
2156 }
2157
2158 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
2159 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
2160 var elem = checkSet[i];
2161 if ( elem ) {
2162 elem = elem[dir];
2163 var match = false;
2164
2165 while ( elem && elem.nodeType ) {
2166 var done = elem[doneName];
2167 if ( done ) {
2168 match = checkSet[ done ];
2169 break;
2170 }
2171
2172 if ( elem.nodeType === 1 && !isXML )
2173 elem[doneName] = i;
2174
2175 if ( elem.nodeName === cur ) {
2176 match = elem;
2177 break;
2178 }
2179
2180 elem = elem[dir];
2181 }
2182
2183 checkSet[i] = match;
2184 }
2185 }
2186 }
2187
2188 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
2189 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
2190 var elem = checkSet[i];
2191 if ( elem ) {
2192 elem = elem[dir];
2193 var match = false;
2194
2195 while ( elem && elem.nodeType ) {
2196 if ( elem[doneName] ) {
2197 match = checkSet[ elem[doneName] ];
2198 break;
2199 }
2200
2201 if ( elem.nodeType === 1 ) {
2202 if ( !isXML )
2203 elem[doneName] = i;
2204
2205 if ( typeof cur !== "string" ) {
2206 if ( elem === cur ) {
2207 match = true;
2208 break;
2209 }
2210
2211 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
2212 match = elem;
2213 break;
2214 }
2215 }
2216
2217 elem = elem[dir];
2218 }
2219
2220 checkSet[i] = match;
2221 }
2222 }
2223 }
2224
2225 var contains = document.compareDocumentPosition ? function(a, b){
2226 return a.compareDocumentPosition(b) & 16;
2227 } : function(a, b){
2228 return a !== b && (a.contains ? a.contains(b) : true);
2229 };
2230
2231 var isXML = function(elem){
2232 return elem.documentElement && !elem.body ||
2233 elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
2234 };
2235
2236 // EXPOSE
2237 jQuery.find = Sizzle;
2238 jQuery.filter = Sizzle.filter;
2239 jQuery.expr = Sizzle.selectors;
2240 jQuery.expr[":"] = jQuery.expr.filters;
2241
2242 Sizzle.selectors.filters.hidden = function(elem){
2243 return "hidden" === elem.type ||
2244 jQuery.css(elem, "display") === "none" ||
2245 jQuery.css(elem, "visibility") === "hidden";
2246 };
2247
2248 Sizzle.selectors.filters.visible = function(elem){
2249 return "hidden" !== elem.type &&
2250 jQuery.css(elem, "display") !== "none" &&
2251 jQuery.css(elem, "visibility") !== "hidden";
2252 };
2253
2254 Sizzle.selectors.filters.animated = function(elem){
2255 return jQuery.grep(jQuery.timers, function(fn){
2256 return elem === fn.elem;
2257 }).length;
2258 };
2259
2260 jQuery.multiFilter = function( expr, elems, not ) {
2261 if ( not ) {
2262 expr = ":not(" + expr + ")";
2263 }
2264
2265 return Sizzle.matches(expr, elems);
2266 };
2267
2268 jQuery.dir = function( elem, dir ){
2269 var matched = [], cur = elem[dir];
2270 while ( cur && cur != document ) {
2271 if ( cur.nodeType == 1 )
2272 matched.push( cur );
2273 cur = cur[dir];
2274 }
2275 return matched;
2276 };
2277
2278 jQuery.nth = function(cur, result, dir, elem){
2279 result = result || 1;
2280 var num = 0;
2281
2282 for ( ; cur; cur = cur[dir] )
2283 if ( cur.nodeType == 1 && ++num == result )
2284 break;
2285
2286 return cur;
2287 };
2288
2289 jQuery.sibling = function(n, elem){
2290 var r = [];
2291
2292 for ( ; n; n = n.nextSibling ) {
2293 if ( n.nodeType == 1 && n != elem )
2294 r.push( n );
2295 }
2296
2297 return r;
2298 };
2299
2300 return;
2301
2302 window.Sizzle = Sizzle;
2303
2304 })();
2305 /*
2306 * A number of helper functions used for managing events.
2307 * Many of the ideas behind this code originated from
2308 * Dean Edwards' addEvent library.
2309 */
2310 jQuery.event = {
2311
2312 // Bind an event to an element
2313 // Original by Dean Edwards
2314 add: function(elem, types, handler, data) {
2315 if ( elem.nodeType == 3 || elem.nodeType == 8 )
2316 return;
2317
2318 // For whatever reason, IE has trouble passing the window object
2319 // around, causing it to be cloned in the process
2320 if ( elem.setInterval && elem != window )
2321 elem = window;
2322
2323 // Make sure that the function being executed has a unique ID
2324 if ( !handler.guid )
2325 handler.guid = this.guid++;
2326
2327 // if data is passed, bind to handler
2328 if ( data !== undefined ) {
2329 // Create temporary function pointer to original handler
2330 var fn = handler;
2331
2332 // Create unique handler function, wrapped around original handler
2333 handler = this.proxy( fn );
2334
2335 // Store data in unique handler
2336 handler.data = data;
2337 }
2338
2339 // Init the element's event structure
2340 var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
2341 handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
2342 // Handle the second event of a trigger and when
2343 // an event is called after a page has unloaded
2344 return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
2345 jQuery.event.handle.apply(arguments.callee.elem, arguments) :
2346 undefined;
2347 });
2348 // Add elem as a property of the handle function
2349 // This is to prevent a memory leak with non-native
2350 // event in IE.
2351 handle.elem = elem;
2352
2353 // Handle multiple events separated by a space
2354 // jQuery(...).bind("mouseover mouseout", fn);
2355 jQuery.each(types.split(/\s+/), function(index, type) {
2356 // Namespaced event handlers
2357 var namespaces = type.split(".");
2358 type = namespaces.shift();
2359 handler.type = namespaces.slice().sort().join(".");
2360
2361 // Get the current list of functions bound to this event
2362 var handlers = events[type];
2363
2364 if ( jQuery.event.specialAll[type] )
2365 jQuery.event.specialAll[type].setup.call(elem, data, namespaces);
2366
2367 // Init the event handler queue
2368 if (!handlers) {
2369 handlers = events[type] = {};
2370
2371 // Check for a special event handler
2372 // Only use addEventListener/attachEvent if the special
2373 // events handler returns false
2374 if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem, data, namespaces) === false ) {
2375 // Bind the global event handler to the element
2376 if (elem.addEventListener)
2377 elem.addEventListener(type, handle, false);
2378 else if (elem.attachEvent)
2379 elem.attachEvent("on" + type, handle);
2380 }
2381 }
2382
2383 // Add the function to the element's handler list
2384 handlers[handler.guid] = handler;
2385
2386 // Keep track of which events have been used, for global triggering
2387 jQuery.event.global[type] = true;
2388 });
2389
2390 // Nullify elem to prevent memory leaks in IE
2391 elem = null;
2392 },
2393
2394 guid: 1,
2395 global: {},
2396
2397 // Detach an event or set of events from an element
2398 remove: function(elem, types, handler) {
2399 // don't do events on text and comment nodes
2400 if ( elem.nodeType == 3 || elem.nodeType == 8 )
2401 return;
2402
2403 var events = jQuery.data(elem, "events"), ret, index;
2404
2405 if ( events ) {
2406 // Unbind all events for the element
2407 if ( types === undefined || (typeof types === "string" && types.charAt(0) == ".") )
2408 for ( var type in events )
2409 this.remove( elem, type + (types || "") );
2410 else {
2411 // types is actually an event object here
2412 if ( types.type ) {
2413 handler = types.handler;
2414 types = types.type;
2415 }
2416
2417 // Handle multiple events seperated by a space
2418 // jQuery(...).unbind("mouseover mouseout", fn);
2419 jQuery.each(types.split(/\s+/), function(index, type){
2420 // Namespaced event handlers
2421 var namespaces = type.split(".");
2422 type = namespaces.shift();
2423 var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
2424
2425 if ( events[type] ) {
2426 // remove the given handler for the given type
2427 if ( handler )
2428 delete events[type][handler.guid];
2429
2430 // remove all handlers for the given type
2431 else
2432 for ( var handle in events[type] )
2433 // Handle the removal of namespaced events
2434 if ( namespace.test(events[type][handle].type) )
2435 delete events[type][handle];
2436
2437 if ( jQuery.event.specialAll[type] )
2438 jQuery.event.specialAll[type].teardown.call(elem, namespaces);
2439
2440 // remove generic event handler if no more handlers exist
2441 for ( ret in events[type] ) break;
2442 if ( !ret ) {
2443 if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem, namespaces) === false ) {
2444 if (elem.removeEventListener)
2445 elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
2446 else if (elem.detachEvent)
2447 elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
2448 }
2449 ret = null;
2450 delete events[type];
2451 }
2452 }
2453 });
2454 }
2455
2456 // Remove the expando if it's no longer used
2457 for ( ret in events ) break;
2458 if ( !ret ) {
2459 var handle = jQuery.data( elem, "handle" );
2460 if ( handle ) handle.elem = null;
2461 jQuery.removeData( elem, "events" );
2462 jQuery.removeData( elem, "handle" );
2463 }
2464 }
2465 },
2466
2467 // bubbling is internal
2468 trigger: function( event, data, elem, bubbling ) {
2469 // Event object or event type
2470 var type = event.type || event;
2471
2472 if( !bubbling ){
2473 event = typeof event === "object" ?
2474 // jQuery.Event object
2475 event[expando] ? event :
2476 // Object literal
2477 jQuery.extend( jQuery.Event(type), event ) :
2478 // Just the event type (string)
2479 jQuery.Event(type);
2480
2481 if ( type.indexOf("!") >= 0 ) {
2482 event.type = type = type.slice(0, -1);
2483 event.exclusive = true;
2484 }
2485
2486 // Handle a global trigger
2487 if ( !elem ) {
2488 // Don't bubble custom events when global (to avoid too much overhead)
2489 event.stopPropagation();
2490 // Only trigger if we've ever bound an event for it
2491 if ( this.global[type] )
2492 jQuery.each( jQuery.cache, function(){
2493 if ( this.events && this.events[type] )
2494 jQuery.event.trigger( event, data, this.handle.elem );
2495 });
2496 }
2497
2498 // Handle triggering a single element
2499
2500 // don't do events on text and comment nodes
2501 if ( !elem || elem.nodeType == 3 || elem.nodeType == 8 )
2502 return undefined;
2503
2504 // Clean up in case it is reused
2505 event.result = undefined;
2506 event.target = elem;
2507
2508 // Clone the incoming data, if any
2509 data = jQuery.makeArray(data);
2510 data.unshift( event );
2511 }
2512
2513 event.currentTarget = elem;
2514
2515 // Trigger the event, it is assumed that "handle" is a function
2516 var handle = jQuery.data(elem, "handle");
2517 if ( handle )
2518 handle.apply( elem, data );
2519
2520 // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
2521 if ( (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
2522 event.result = false;
2523
2524 // Trigger the native events (except for clicks on links)
2525 if ( !bubbling && elem[type] && !event.isDefaultPrevented() && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
2526 this.triggered = true;
2527 try {
2528 elem[ type ]();
2529 // prevent IE from throwing an error for some hidden elements
2530 } catch (e) {}
2531 }
2532
2533 this.triggered = false;
2534
2535 if ( !event.isPropagationStopped() ) {
2536 var parent = elem.parentNode || elem.ownerDocument;
2537 if ( parent )
2538 jQuery.event.trigger(event, data, parent, true);
2539 }
2540 },
2541
2542 handle: function(event) {
2543 // returned undefined or false
2544 var all, handlers;
2545
2546 event = arguments[0] = jQuery.event.fix( event || window.event );
2547
2548 // Namespaced event handlers
2549 var namespaces = event.type.split(".");
2550 event.type = namespaces.shift();
2551
2552 // Cache this now, all = true means, any handler
2553 all = !namespaces.length && !event.exclusive;
2554
2555 var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
2556
2557 handlers = ( jQuery.data(this, "events") || {} )[event.type];
2558
2559 for ( var j in handlers ) {
2560 var handler = handlers[j];
2561
2562 // Filter the functions by class
2563 if ( all || namespace.test(handler.type) ) {
2564 // Pass in a reference to the handler function itself
2565 // So that we can later remove it
2566 event.handler = handler;
2567 event.data = handler.data;
2568
2569 var ret = handler.apply(this, arguments);
2570
2571 if( ret !== undefined ){
2572 event.result = ret;
2573 if ( ret === false ) {
2574 event.preventDefault();
2575 event.stopPropagation();
2576 }
2577 }
2578
2579 if( event.isImmediatePropagationStopped() )
2580 break;
2581
2582 }
2583 }
2584 },
2585
2586 props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
2587
2588 fix: function(event) {
2589 if ( event[expando] )
2590 return event;
2591
2592 // store a copy of the original event object
2593 // and "clone" to set read-only properties
2594 var originalEvent = event;
2595 event = jQuery.Event( originalEvent );
2596
2597 for ( var i = this.props.length, prop; i; ){
2598 prop = this.props[ --i ];
2599 event[ prop ] = originalEvent[ prop ];
2600 }
2601
2602 // Fix target property, if necessary
2603 if ( !event.target )
2604 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
2605
2606 // check if target is a textnode (safari)
2607 if ( event.target.nodeType == 3 )
2608 event.target = event.target.parentNode;
2609
2610 // Add relatedTarget, if necessary
2611 if ( !event.relatedTarget && event.fromElement )
2612 event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
2613
2614 // Calculate pageX/Y if missing and clientX/Y available
2615 if ( event.pageX == null && event.clientX != null ) {
2616 var doc = document.documentElement, body = document.body;
2617 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
2618 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
2619 }
2620
2621 // Add which for key events
2622 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
2623 event.which = event.charCode || event.keyCode;
2624
2625 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
2626 if ( !event.metaKey && event.ctrlKey )
2627 event.metaKey = event.ctrlKey;
2628
2629 // Add which for click: 1 == left; 2 == middle; 3 == right
2630 // Note: button is not normalized, so don't use it
2631 if ( !event.which && event.button )
2632 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
2633
2634 return event;
2635 },
2636
2637 proxy: function( fn, proxy ){
2638 proxy = proxy || function(){ return fn.apply(this, arguments); };
2639 // Set the guid of unique handler to the same of original handler, so it can be removed
2640 proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
2641 // So proxy can be declared as an argument
2642 return proxy;
2643 },
2644
2645 special: {
2646 ready: {
2647 // Make sure the ready event is setup
2648 setup: bindReady,
2649 teardown: function() {}
2650 }
2651 },
2652
2653 specialAll: {
2654 live: {
2655 setup: function( selector, namespaces ){
2656 jQuery.event.add( this, namespaces[0], liveHandler );
2657 },
2658 teardown: function( namespaces ){
2659 if ( namespaces.length ) {
2660 var remove = 0, name = RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)");
2661
2662 jQuery.each( (jQuery.data(this, "events").live || {}), function(){
2663 if ( name.test(this.type) )
2664 remove++;
2665 });
2666
2667 if ( remove < 1 )
2668 jQuery.event.remove( this, namespaces[0], liveHandler );
2669 }
2670 }
2671 }
2672 }
2673 };
2674
2675 jQuery.Event = function( src ){
2676 // Allow instantiation without the 'new' keyword
2677 if( !this.preventDefault )
2678 return new jQuery.Event(src);
2679
2680 // Event object
2681 if( src && src.type ){
2682 this.originalEvent = src;
2683 this.type = src.type;
2684 this.timeStamp = src.timeStamp;
2685 // Event type
2686 }else
2687 this.type = src;
2688
2689 if( !this.timeStamp )
2690 this.timeStamp = now();
2691
2692 // Mark it as fixed
2693 this[expando] = true;
2694 };
2695
2696 function returnFalse(){
2697 return false;
2698 }
2699 function returnTrue(){
2700 return true;
2701 }
2702
2703 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
2704 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
2705 jQuery.Event.prototype = {
2706 preventDefault: function() {
2707 this.isDefaultPrevented = returnTrue;
2708
2709 var e = this.originalEvent;
2710 if( !e )
2711 return;
2712 // if preventDefault exists run it on the original event
2713 if (e.preventDefault)
2714 e.preventDefault();
2715 // otherwise set the returnValue property of the original event to false (IE)
2716 e.returnValue = false;
2717 },
2718 stopPropagation: function() {
2719 this.isPropagationStopped = returnTrue;
2720
2721 var e = this.originalEvent;
2722 if( !e )
2723 return;
2724 // if stopPropagation exists run it on the original event
2725 if (e.stopPropagation)
2726 e.stopPropagation();
2727 // otherwise set the cancelBubble property of the original event to true (IE)
2728 e.cancelBubble = true;
2729 },
2730 stopImmediatePropagation:function(){
2731 this.isImmediatePropagationStopped = returnTrue;
2732 this.stopPropagation();
2733 },
2734 isDefaultPrevented: returnFalse,
2735 isPropagationStopped: returnFalse,
2736 isImmediatePropagationStopped: returnFalse
2737 };
2738 // Checks if an event happened on an element within another element
2739 // Used in jQuery.event.special.mouseenter and mouseleave handlers
2740 var withinElement = function(event) {
2741 // Check if mouse(over|out) are still within the same parent element
2742 var parent = event.relatedTarget;
2743 // Traverse up the tree
2744 while ( parent && parent != this )
2745 try { parent = parent.parentNode; }
2746 catch(e) { parent = this; }
2747
2748 if( parent != this ){
2749 // set the correct event type
2750 event.type = event.data;
2751 // handle event if we actually just moused on to a non sub-element
2752 jQuery.event.handle.apply( this, arguments );
2753 }
2754 };
2755
2756 jQuery.each({
2757 mouseover: 'mouseenter',
2758 mouseout: 'mouseleave'
2759 }, function( orig, fix ){
2760 jQuery.event.special[ fix ] = {
2761 setup: function(){
2762 jQuery.event.add( this, orig, withinElement, fix );
2763 },
2764 teardown: function(){
2765 jQuery.event.remove( this, orig, withinElement );
2766 }
2767 };
2768 });
2769
2770 jQuery.fn.extend({
2771 bind: function( type, data, fn ) {
2772 return type == "unload" ? this.one(type, data, fn) : this.each(function(){
2773 jQuery.event.add( this, type, fn || data, fn && data );
2774 });
2775 },
2776
2777 one: function( type, data, fn ) {
2778 var one = jQuery.event.proxy( fn || data, function(event) {
2779 jQuery(this).unbind(event, one);
2780 return (fn || data).apply( this, arguments );
2781 });
2782 return this.each(function(){
2783 jQuery.event.add( this, type, one, fn && data);
2784 });
2785 },
2786
2787 unbind: function( type, fn ) {
2788 return this.each(function(){
2789 jQuery.event.remove( this, type, fn );
2790 });
2791 },
2792
2793 trigger: function( type, data ) {
2794 return this.each(function(){
2795 jQuery.event.trigger( type, data, this );
2796 });
2797 },
2798
2799 triggerHandler: function( type, data ) {
2800 if( this[0] ){
2801 var event = jQuery.Event(type);
2802 event.preventDefault();
2803 event.stopPropagation();
2804 jQuery.event.trigger( event, data, this[0] );
2805 return event.result;
2806 }
2807 },
2808
2809 toggle: function( fn ) {
2810 // Save reference to arguments for access in closure
2811 var args = arguments, i = 1;
2812
2813 // link all the functions, so any of them can unbind this click handler
2814 while( i < args.length )
2815 jQuery.event.proxy( fn, args[i++] );
2816
2817 return this.click( jQuery.event.proxy( fn, function(event) {
2818 // Figure out which function to execute
2819 this.lastToggle = ( this.lastToggle || 0 ) % i;
2820
2821 // Make sure that clicks stop
2822 event.preventDefault();
2823
2824 // and execute the function
2825 return args[ this.lastToggle++ ].apply( this, arguments ) || false;
2826 }));
2827 },
2828
2829 hover: function(fnOver, fnOut) {
2830 return this.mouseenter(fnOver).mouseleave(fnOut);
2831 },
2832
2833 ready: function(fn) {
2834 // Attach the listeners
2835 bindReady();
2836
2837 // If the DOM is already ready
2838 if ( jQuery.isReady )
2839 // Execute the function immediately
2840 fn.call( document, jQuery );
2841
2842 // Otherwise, remember the function for later
2843 else
2844 // Add the function to the wait list
2845 jQuery.readyList.push( fn );
2846
2847 return this;
2848 },
2849
2850 live: function( type, fn ){
2851 var proxy = jQuery.event.proxy( fn );
2852 proxy.guid += this.selector + type;
2853
2854 jQuery(document).bind( liveConvert(type, this.selector), this.selector, proxy );
2855
2856 return this;
2857 },
2858
2859 die: function( type, fn ){
2860 jQuery(document).unbind( liveConvert(type, this.selector), fn ? { guid: fn.guid + this.selector + type } : null );
2861 return this;
2862 }
2863 });
2864
2865 function liveHandler( event ){
2866 var check = RegExp("(^|\\.)" + event.type + "(\\.|$)"),
2867 stop = true,
2868 elems = [];
2869
2870 jQuery.each(jQuery.data(this, "events").live || [], function(i, fn){
2871 if ( check.test(fn.type) ) {
2872 var elem = jQuery(event.target).closest(fn.data)[0];
2873 if ( elem )
2874 elems.push({ elem: elem, fn: fn });
2875 }
2876 });
2877
2878 jQuery.each(elems, function(){
2879 if ( !event.isImmediatePropagationStopped() &&
2880 this.fn.call(this.elem, event, this.fn.data) === false )
2881 stop = false;
2882 });
2883
2884 return stop;
2885 }
2886
2887 function liveConvert(type, selector){
2888 return ["live", type, selector.replace(/\./g, "`").replace(/ /g, "|")].join(".");
2889 }
2890
2891 jQuery.extend({
2892 isReady: false,
2893 readyList: [],
2894 // Handle when the DOM is ready
2895 ready: function() {
2896 // Make sure that the DOM is not already loaded
2897 if ( !jQuery.isReady ) {
2898 // Remember that the DOM is ready
2899 jQuery.isReady = true;
2900
2901 // If there are functions bound, to execute
2902 if ( jQuery.readyList ) {
2903 // Execute all of them
2904 jQuery.each( jQuery.readyList, function(){
2905 this.call( document, jQuery );
2906 });
2907
2908 // Reset the list of functions
2909 jQuery.readyList = null;
2910 }
2911
2912 // Trigger any bound ready events
2913 jQuery(document).triggerHandler("ready");
2914 }
2915 }
2916 });
2917
2918 var readyBound = false;
2919
2920 function bindReady(){
2921 if ( readyBound ) return;
2922 readyBound = true;
2923
2924 // Mozilla, Opera and webkit nightlies currently support this event
2925 if ( document.addEventListener ) {
2926 // Use the handy event callback
2927 document.addEventListener( "DOMContentLoaded", function(){
2928 document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
2929 jQuery.ready();
2930 }, false );
2931
2932 // If IE event model is used
2933 } else if ( document.attachEvent ) {
2934 // ensure firing before onload,
2935 // maybe late but safe also for iframes
2936 document.attachEvent("onreadystatechange", function(){
2937 if ( document.readyState === "complete" ) {
2938 document.detachEvent( "onreadystatechange", arguments.callee );
2939 jQuery.ready();
2940 }
2941 });
2942
2943 // If IE and not an iframe
2944 // continually check to see if the document is ready
2945 if ( document.documentElement.doScroll && !window.frameElement ) (function(){
2946 if ( jQuery.isReady ) return;
2947
2948 try {
2949 // If IE is used, use the trick by Diego Perini
2950 // http://javascript.nwbox.com/IEContentLoaded/
2951 document.documentElement.doScroll("left");
2952 } catch( error ) {
2953 setTimeout( arguments.callee, 0 );
2954 return;
2955 }
2956
2957 // and execute any waiting functions
2958 jQuery.ready();
2959 })();
2960 }
2961
2962 // A fallback to window.onload, that will always work
2963 jQuery.event.add( window, "load", jQuery.ready );
2964 }
2965
2966 jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
2967 "mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave," +
2968 "change,select,submit,keydown,keypress,keyup,error").split(","), function(i, name){
2969
2970 // Handle event binding
2971 jQuery.fn[name] = function(fn){
2972 return fn ? this.bind(name, fn) : this.trigger(name);
2973 };
2974 });
2975
2976 // Prevent memory leaks in IE
2977 // And prevent errors on refresh with events like mouseover in other browsers
2978 // Window isn't included so as not to unbind existing unload events
2979 jQuery( window ).bind( 'unload', function(){
2980 for ( var id in jQuery.cache )
2981 // Skip the window
2982 if ( id != 1 && jQuery.cache[ id ].handle )
2983 jQuery.event.remove( jQuery.cache[ id ].handle.elem );
2984 });
2985 (function(){
2986
2987 jQuery.support = {};
2988
2989 var root = document.documentElement,
2990 script = document.createElement("script"),
2991 div = document.createElement("div"),
2992 id = "script" + (new Date).getTime();
2993
2994 div.style.display = "none";
2995 div.innerHTML = ' <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';
2996
2997 var all = div.getElementsByTagName("*"),
2998 a = div.getElementsByTagName("a")[0];
2999
3000 // Can't get basic test support
3001 if ( !all || !all.length || !a ) {
3002 return;
3003 }
3004
3005 jQuery.support = {
3006 // IE strips leading whitespace when .innerHTML is used
3007 leadingWhitespace: div.firstChild.nodeType == 3,
3008
3009 // Make sure that tbody elements aren't automatically inserted
3010 // IE will insert them into empty tables
3011 tbody: !div.getElementsByTagName("tbody").length,
3012
3013 // Make sure that you can get all elements in an <object> element
3014 // IE 7 always returns no results
3015 objectAll: !!div.getElementsByTagName("object")[0]
3016 .getElementsByTagName("*").length,
3017
3018 // Make sure that link elements get serialized correctly by innerHTML
3019 // This requires a wrapper element in IE
3020 htmlSerialize: !!div.getElementsByTagName("link").length,
3021
3022 // Get the style information from getAttribute
3023 // (IE uses .cssText insted)
3024 style: /red/.test( a.getAttribute("style") ),
3025
3026 // Make sure that URLs aren't manipulated
3027 // (IE normalizes it by default)
3028 hrefNormalized: a.getAttribute("href") === "/a",
3029
3030 // Make sure that element opacity exists
3031 // (IE uses filter instead)
3032 opacity: a.style.opacity === "0.5",
3033
3034 // Verify style float existence
3035 // (IE uses styleFloat instead of cssFloat)
3036 cssFloat: !!a.style.cssFloat,
3037
3038 // Will be defined later
3039 scriptEval: false,
3040 noCloneEvent: true,
3041 boxModel: null
3042 };
3043
3044 script.type = "text/javascript";
3045 try {
3046 script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
3047 } catch(e){}
3048
3049 root.insertBefore( script, root.firstChild );
3050
3051 // Make sure that the execution of code works by injecting a script
3052 // tag with appendChild/createTextNode
3053 // (IE doesn't support this, fails, and uses .text instead)
3054 if ( window[ id ] ) {
3055 jQuery.support.scriptEval = true;
3056 delete window[ id ];
3057 }
3058
3059 root.removeChild( script );
3060
3061 if ( div.attachEvent && div.fireEvent ) {
3062 div.attachEvent("onclick", function(){
3063 // Cloning a node shouldn't copy over any
3064 // bound event handlers (IE does this)
3065 jQuery.support.noCloneEvent = false;
3066 div.detachEvent("onclick", arguments.callee);
3067 });
3068 div.cloneNode(true).fireEvent("onclick");
3069 }
3070
3071 // Figure out if the W3C box model works as expected
3072 // document.body must exist before we can do this
3073 jQuery(function(){
3074 var div = document.createElement("div");
3075 div.style.width = "1px";
3076 div.style.paddingLeft = "1px";
3077
3078 document.body.appendChild( div );
3079 jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
3080 document.body.removeChild( div );
3081 });
3082 })();
3083
3084 var styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat";
3085
3086 jQuery.props = {
3087 "for": "htmlFor",
3088 "class": "className",
3089 "float": styleFloat,
3090 cssFloat: styleFloat,
3091 styleFloat: styleFloat,
3092 readonly: "readOnly",
3093 maxlength: "maxLength",
3094 cellspacing: "cellSpacing",
3095 rowspan: "rowSpan",
3096 tabindex: "tabIndex"
3097 };
3098 jQuery.fn.extend({
3099 // Keep a copy of the old load
3100 _load: jQuery.fn.load,
3101
3102 load: function( url, params, callback ) {
3103 if ( typeof url !== "string" )
3104 return this._load( url );
3105
3106 var off = url.indexOf(" ");
3107 if ( off >= 0 ) {
3108 var selector = url.slice(off, url.length);
3109 url = url.slice(0, off);
3110 }
3111
3112 // Default to a GET request
3113 var type = "GET";
3114
3115 // If the second parameter was provided
3116 if ( params )
3117 // If it's a function
3118 if ( jQuery.isFunction( params ) ) {
3119 // We assume that it's the callback
3120 callback = params;
3121 params = null;
3122
3123 // Otherwise, build a param string
3124 } else if( typeof params === "object" ) {
3125 params = jQuery.param( params );
3126 type = "POST";
3127 }
3128
3129 var self = this;
3130
3131 // Request the remote document
3132 jQuery.ajax({
3133 url: url,
3134 type: type,
3135 dataType: "html",
3136 data: params,
3137 complete: function(res, status){
3138 // If successful, inject the HTML into all the matched elements
3139 if ( status == "success" || status == "notmodified" )
3140 // See if a selector was specified
3141 self.html( selector ?
3142 // Create a dummy div to hold the results
3143 jQuery("<div/>")
3144 // inject the contents of the document in, removing the scripts
3145 // to avoid any 'Permission Denied' errors in IE
3146 .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
3147
3148 // Locate the specified elements
3149 .find(selector) :
3150
3151 // If not, just inject the full result
3152 res.responseText );
3153
3154 if( callback )
3155 self.each( callback, [res.responseText, status, res] );
3156 }
3157 });
3158 return this;
3159 },
3160
3161 serialize: function() {
3162 return jQuery.param(this.serializeArray());
3163 },
3164 serializeArray: function() {
3165 return this.map(function(){
3166 return this.elements ? jQuery.makeArray(this.elements) : this;
3167 })
3168 .filter(function(){
3169 return this.name && !this.disabled &&
3170 (this.checked || /select|textarea/i.test(this.nodeName) ||
3171 /text|hidden|password/i.test(this.type));
3172 })
3173 .map(function(i, elem){
3174 var val = jQuery(this).val();
3175 return val == null ? null :
3176 jQuery.isArray(val) ?
3177 jQuery.map( val, function(val, i){
3178 return {name: elem.name, value: val};
3179 }) :
3180 {name: elem.name, value: val};
3181 }).get();
3182 }
3183 });
3184
3185 // Attach a bunch of functions for handling common AJAX events
3186 jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
3187 jQuery.fn[o] = function(f){
3188 return this.bind(o, f);
3189 };
3190 });
3191
3192 var jsc = now();
3193
3194 jQuery.extend({
3195
3196 get: function( url, data, callback, type ) {
3197 // shift arguments if data argument was ommited
3198 if ( jQuery.isFunction( data ) ) {
3199 callback = data;
3200 data = null;
3201 }
3202
3203 return jQuery.ajax({
3204 type: "GET",
3205 url: url,
3206 data: data,
3207 success: callback,
3208 dataType: type
3209 });
3210 },
3211
3212 getScript: function( url, callback ) {
3213 return jQuery.get(url, null, callback, "script");
3214 },
3215
3216 getJSON: function( url, data, callback ) {
3217 return jQuery.get(url, data, callback, "json");
3218 },
3219
3220 post: function( url, data, callback, type ) {
3221 if ( jQuery.isFunction( data ) ) {
3222 callback = data;
3223 data = {};
3224 }
3225
3226 return jQuery.ajax({
3227 type: "POST",
3228 url: url,
3229 data: data,
3230 success: callback,
3231 dataType: type
3232 });
3233 },
3234
3235 ajaxSetup: function( settings ) {
3236 jQuery.extend( jQuery.ajaxSettings, settings );
3237 },
3238
3239 ajaxSettings: {
3240 url: location.href,
3241 global: true,
3242 type: "GET",
3243 contentType: "application/x-www-form-urlencoded",
3244 processData: true,
3245 async: true,
3246 /*
3247 timeout: 0,
3248 data: null,
3249 username: null,
3250 password: null,
3251 */
3252 // Create the request object; Microsoft failed to properly
3253 // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
3254 // This function can be overriden by calling jQuery.ajaxSetup
3255 xhr:function(){
3256 return window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
3257 },
3258 accepts: {
3259 xml: "application/xml, text/xml",
3260 html: "text/html",
3261 script: "text/javascript, application/javascript",
3262 json: "application/json, text/javascript",
3263 text: "text/plain",
3264 _default: "*/*"
3265 }
3266 },
3267
3268 // Last-Modified header cache for next request
3269 lastModified: {},
3270
3271 ajax: function( s ) {
3272 // Extend the settings, but re-extend 's' so that it can be
3273 // checked again later (in the test suite, specifically)
3274 s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
3275
3276 var jsonp, jsre = /=\?(&|$)/g, status, data,
3277 type = s.type.toUpperCase();
3278
3279 // convert data if not already a string
3280 if ( s.data && s.processData && typeof s.data !== "string" )
3281 s.data = jQuery.param(s.data);
3282
3283 // Handle JSONP Parameter Callbacks
3284 if ( s.dataType == "jsonp" ) {
3285 if ( type == "GET" ) {
3286 if ( !s.url.match(jsre) )
3287 s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
3288 } else if ( !s.data || !s.data.match(jsre) )
3289 s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
3290 s.dataType = "json";
3291 }
3292
3293 // Build temporary JSONP function
3294 if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
3295 jsonp = "jsonp" + jsc++;
3296
3297 // Replace the =? sequence both in the query string and the data
3298 if ( s.data )
3299 s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
3300 s.url = s.url.replace(jsre, "=" + jsonp + "$1");
3301
3302 // We need to make sure
3303 // that a JSONP style response is executed properly
3304 s.dataType = "script";
3305
3306 // Handle JSONP-style loading
3307 window[ jsonp ] = function(tmp){
3308 data = tmp;
3309 success();
3310 complete();
3311 // Garbage collect
3312 window[ jsonp ] = undefined;
3313 try{ delete window[ jsonp ]; } catch(e){}
3314 if ( head )
3315 head.removeChild( script );
3316 };
3317 }
3318
3319 if ( s.dataType == "script" && s.cache == null )
3320 s.cache = false;
3321
3322 if ( s.cache === false && type == "GET" ) {
3323 var ts = now();
3324 // try replacing _= if it is there
3325 var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
3326 // if nothing was replaced, add timestamp to the end
3327 s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
3328 }
3329
3330 // If data is available, append data to url for get requests
3331 if ( s.data && type == "GET" ) {
3332 s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
3333
3334 // IE likes to send both get and post data, prevent this
3335 s.data = null;
3336 }
3337
3338 // Watch for a new set of requests
3339 if ( s.global && ! jQuery.active++ )
3340 jQuery.event.trigger( "ajaxStart" );
3341
3342 // Matches an absolute URL, and saves the domain
3343 var parts = /^(\w+:)?\/\/([^\/?#]+)/.exec( s.url );
3344
3345 // If we're requesting a remote document
3346 // and trying to load JSON or Script with a GET
3347 if ( s.dataType == "script" && type == "GET" && parts
3348 && ( parts[1] && parts[1] != location.protocol || parts[2] != location.host )){
3349
3350 var head = document.getElementsByTagName("head")[0];
3351 var script = document.createElement("script");
3352 script.src = s.url;
3353 if (s.scriptCharset)
3354 script.charset = s.scriptCharset;
3355
3356 // Handle Script loading
3357 if ( !jsonp ) {
3358 var done = false;
3359
3360 // Attach handlers for all browsers
3361 script.onload = script.onreadystatechange = function(){
3362 if ( !done && (!this.readyState ||
3363 this.readyState == "loaded" || this.readyState == "complete") ) {
3364 done = true;
3365 success();
3366 complete();
3367 head.removeChild( script );
3368 }
3369 };
3370 }
3371
3372 head.appendChild(script);
3373
3374 // We handle everything using the script element injection
3375 return undefined;
3376 }
3377
3378 var requestDone = false;
3379
3380 // Create the request object
3381 var xhr = s.xhr();
3382
3383 // Open the socket
3384 // Passing null username, generates a login popup on Opera (#2865)
3385 if( s.username )
3386 xhr.open(type, s.url, s.async, s.username, s.password);
3387 else
3388 xhr.open(type, s.url, s.async);
3389
3390 // Need an extra try/catch for cross domain requests in Firefox 3
3391 try {
3392 // Set the correct header, if data is being sent
3393 if ( s.data )
3394 xhr.setRequestHeader("Content-Type", s.contentType);
3395
3396 // Set the If-Modified-Since header, if ifModified mode.
3397 if ( s.ifModified )
3398 xhr.setRequestHeader("If-Modified-Since",
3399 jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
3400
3401 // Set header so the called script knows that it's an XMLHttpRequest
3402 xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
3403
3404 // Set the Accepts header for the server, depending on the dataType
3405 xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
3406 s.accepts[ s.dataType ] + ", */*" :
3407 s.accepts._default );
3408 } catch(e){}
3409
3410 // Allow custom headers/mimetypes and early abort
3411 if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {
3412 // Handle the global AJAX counter
3413 if ( s.global && ! --jQuery.active )
3414 jQuery.event.trigger( "ajaxStop" );
3415 // close opended socket
3416 xhr.abort();
3417 return false;
3418 }
3419
3420 if ( s.global )
3421 jQuery.event.trigger("ajaxSend", [xhr, s]);
3422
3423 // Wait for a response to come back
3424 var onreadystatechange = function(isTimeout){
3425 // The request was aborted, clear the interval and decrement jQuery.active
3426 if (xhr.readyState == 0) {
3427 if (ival) {
3428 // clear poll interval
3429 clearInterval(ival);
3430 ival = null;
3431 // Handle the global AJAX counter
3432 if ( s.global && ! --jQuery.active )
3433 jQuery.event.trigger( "ajaxStop" );
3434 }
3435 // The transfer is complete and the data is available, or the request timed out
3436 } else if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {
3437 requestDone = true;
3438
3439 // clear poll interval
3440 if (ival) {
3441 clearInterval(ival);
3442 ival = null;
3443 }
3444
3445 status = isTimeout == "timeout" ? "timeout" :
3446 !jQuery.httpSuccess( xhr ) ? "error" :
3447 s.ifModified && jQuery.httpNotModified( xhr, s.url ) ? "notmodified" :
3448 "success";
3449
3450 if ( status == "success" ) {
3451 // Watch for, and catch, XML document parse errors
3452 try {
3453 // process the data (runs the xml through httpData regardless of callback)
3454 data = jQuery.httpData( xhr, s.dataType, s );
3455 } catch(e) {
3456 status = "parsererror";
3457 }
3458 }
3459
3460 // Make sure that the request was successful or notmodified
3461 if ( status == "success" ) {
3462 // Cache Last-Modified header, if ifModified mode.
3463 var modRes;
3464 try {
3465 modRes = xhr.getResponseHeader("Last-Modified");
3466 } catch(e) {} // swallow exception thrown by FF if header is not available
3467
3468 if ( s.ifModified && modRes )
3469 jQuery.lastModified[s.url] = modRes;
3470
3471 // JSONP handles its own success callback
3472 if ( !jsonp )
3473 success();
3474 } else
3475 jQuery.handleError(s, xhr, status);
3476
3477 // Fire the complete handlers
3478 complete();
3479
3480 // Stop memory leaks
3481 if ( s.async )
3482 xhr = null;
3483 }
3484 };
3485
3486 if ( s.async ) {
3487 // don't attach the handler to the request, just poll it instead
3488 var ival = setInterval(onreadystatechange, 13);
3489
3490 // Timeout checker
3491 if ( s.timeout > 0 )
3492 setTimeout(function(){
3493 // Check to see if the request is still happening
3494 if ( xhr ) {
3495 if( !requestDone )
3496 onreadystatechange( "timeout" );
3497
3498 // Cancel the request
3499 if ( xhr )
3500 xhr.abort();
3501 }
3502 }, s.timeout);
3503 }
3504
3505 // Send the data
3506 try {
3507 xhr.send(s.data);
3508 } catch(e) {
3509 jQuery.handleError(s, xhr, null, e);
3510 }
3511
3512 // firefox 1.5 doesn't fire statechange for sync requests
3513 if ( !s.async )
3514 onreadystatechange();
3515
3516 function success(){
3517 // If a local callback was specified, fire it and pass it the data
3518 if ( s.success )
3519 s.success( data, status );
3520
3521 // Fire the global callback
3522 if ( s.global )
3523 jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
3524 }
3525
3526 function complete(){
3527 // Process result
3528 if ( s.complete )
3529 s.complete(xhr, status);
3530
3531 // The request was completed
3532 if ( s.global )
3533 jQuery.event.trigger( "ajaxComplete", [xhr, s] );
3534
3535 // Handle the global AJAX counter
3536 if ( s.global && ! --jQuery.active )
3537 jQuery.event.trigger( "ajaxStop" );
3538 }
3539
3540 // return XMLHttpRequest to allow aborting the request etc.
3541 return xhr;
3542 },
3543
3544 handleError: function( s, xhr, status, e ) {
3545 // If a local callback was specified, fire it
3546 if ( s.error ) s.error( xhr, status, e );
3547
3548 // Fire the global callback
3549 if ( s.global )
3550 jQuery.event.trigger( "ajaxError", [xhr, s, e] );
3551 },
3552
3553 // Counter for holding the number of active queries
3554 active: 0,
3555
3556 // Determines if an XMLHttpRequest was successful or not
3557 httpSuccess: function( xhr ) {
3558 try {
3559 // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
3560 return !xhr.status && location.protocol == "file:" ||
3561 ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223;
3562 } catch(e){}
3563 return false;
3564 },
3565
3566 // Determines if an XMLHttpRequest returns NotModified
3567 httpNotModified: function( xhr, url ) {
3568 try {
3569 var xhrRes = xhr.getResponseHeader("Last-Modified");
3570
3571 // Firefox always returns 200. check Last-Modified date
3572 return xhr.status == 304 || xhrRes == jQuery.lastModified[url];
3573 } catch(e){}
3574 return false;
3575 },
3576
3577 httpData: function( xhr, type, s ) {
3578 var ct = xhr.getResponseHeader("content-type"),
3579 xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,
3580 data = xml ? xhr.responseXML : xhr.responseText;
3581
3582 if ( xml && data.documentElement.tagName == "parsererror" )
3583 throw "parsererror";
3584
3585 // Allow a pre-filtering function to sanitize the response
3586 // s != null is checked to keep backwards compatibility
3587 if( s && s.dataFilter )
3588 data = s.dataFilter( data, type );
3589
3590 // The filter can actually parse the response
3591 if( typeof data === "string" ){
3592
3593 // If the type is "script", eval it in global context
3594 if ( type == "script" )
3595 jQuery.globalEval( data );
3596
3597 // Get the JavaScript object, if JSON is used.
3598 if ( type == "json" )
3599 data = window["eval"]("(" + data + ")");
3600 }
3601
3602 return data;
3603 },
3604
3605 // Serialize an array of form elements or a set of
3606 // key/values into a query string
3607 param: function( a ) {
3608 var s = [ ];
3609
3610 function add( key, value ){
3611 s[ s.length ] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
3612 };
3613
3614 // If an array was passed in, assume that it is an array
3615 // of form elements
3616 if ( jQuery.isArray(a) || a.jquery )
3617 // Serialize the form elements
3618 jQuery.each( a, function(){
3619 add( this.name, this.value );
3620 });
3621
3622 // Otherwise, assume that it's an object of key/value pairs
3623 else
3624 // Serialize the key/values
3625 for ( var j in a )
3626 // If the value is an array then the key names need to be repeated
3627 if ( jQuery.isArray(a[j]) )
3628 jQuery.each( a[j], function(){
3629 add( j, this );
3630 });
3631 else
3632 add( j, jQuery.isFunction(a[j]) ? a[j]() : a[j] );
3633
3634 // Return the resulting serialization
3635 return s.join("&").replace(/%20/g, "+");
3636 }
3637
3638 });
3639 var elemdisplay = {},
3640 fxAttrs = [
3641 // height animations
3642 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
3643 // width animations
3644 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
3645 // opacity animations
3646 [ "opacity" ]
3647 ];
3648
3649 function genFx( type, num ){
3650 var obj = {};
3651 jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function(){
3652 obj[ this ] = type;
3653 });
3654 return obj;
3655 }
3656
3657 jQuery.fn.extend({
3658 show: function(speed,callback){
3659 if ( speed ) {
3660 return this.animate( genFx("show", 3), speed, callback);
3661 } else {
3662 for ( var i = 0, l = this.length; i < l; i++ ){
3663 var old = jQuery.data(this[i], "olddisplay");
3664
3665 this[i].style.display = old || "";
3666
3667 if ( jQuery.css(this[i], "display") === "none" ) {
3668 var tagName = this[i].tagName, display;
3669
3670 if ( elemdisplay[ tagName ] ) {
3671 display = elemdisplay[ tagName ];
3672 } else {
3673 var elem = jQuery("<" + tagName + " />").appendTo("body");
3674
3675 display = elem.css("display");
3676 if ( display === "none" )
3677 display = "block";
3678
3679 elem.remove();
3680
3681 elemdisplay[ tagName ] = display;
3682 }
3683
3684 this[i].style.display = jQuery.data(this[i], "olddisplay", display);
3685 }
3686 }
3687
3688 return this;
3689 }
3690 },
3691
3692 hide: function(speed,callback){
3693 if ( speed ) {
3694 return this.animate( genFx("hide", 3), speed, callback);
3695 } else {
3696 for ( var i = 0, l = this.length; i < l; i++ ){
3697 var old = jQuery.data(this[i], "olddisplay");
3698 if ( !old && old !== "none" )
3699 jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
3700 this[i].style.display = "none";
3701 }
3702 return this;
3703 }
3704 },
3705
3706 // Save the old toggle function
3707 _toggle: jQuery.fn.toggle,
3708
3709 toggle: function( fn, fn2 ){
3710 var bool = typeof fn === "boolean";
3711
3712 return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
3713 this._toggle.apply( this, arguments ) :
3714 fn == null || bool ?
3715 this.each(function(){
3716 var state = bool ? fn : jQuery(this).is(":hidden");
3717 jQuery(this)[ state ? "show" : "hide" ]();
3718 }) :
3719 this.animate(genFx("toggle", 3), fn, fn2);
3720 },
3721
3722 fadeTo: function(speed,to,callback){
3723 return this.animate({opacity: to}, speed, callback);
3724 },
3725
3726 animate: function( prop, speed, easing, callback ) {
3727 var optall = jQuery.speed(speed, easing, callback);
3728
3729 return this[ optall.queue === false ? "each" : "queue" ](function(){
3730
3731 var opt = jQuery.extend({}, optall), p,
3732 hidden = this.nodeType == 1 && jQuery(this).is(":hidden"),
3733 self = this;
3734
3735 for ( p in prop ) {
3736 if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
3737 return opt.complete.call(this);
3738
3739 if ( ( p == "height" || p == "width" ) && this.style ) {
3740 // Store display property
3741 opt.display = jQuery.css(this, "display");
3742
3743 // Make sure that nothing sneaks out
3744 opt.overflow = this.style.overflow;
3745 }
3746 }
3747
3748 if ( opt.overflow != null )
3749 this.style.overflow = "hidden";
3750
3751 opt.curAnim = jQuery.extend({}, prop);
3752
3753 jQuery.each( prop, function(name, val){
3754 var e = new jQuery.fx( self, opt, name );
3755
3756 if ( /toggle|show|hide/.test(val) )
3757 e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
3758 else {
3759 var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
3760 start = e.cur(true) || 0;
3761
3762 if ( parts ) {
3763 var end = parseFloat(parts[2]),
3764 unit = parts[3] || "px";
3765
3766 // We need to compute starting value
3767 if ( unit != "px" ) {
3768 self.style[ name ] = (end || 1) + unit;
3769 start = ((end || 1) / e.cur(true)) * start;
3770 self.style[ name ] = start + unit;
3771 }
3772
3773 // If a +=/-= token was provided, we're doing a relative animation
3774 if ( parts[1] )
3775 end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
3776
3777 e.custom( start, end, unit );
3778 } else
3779 e.custom( start, val, "" );
3780 }
3781 });
3782
3783 // For JS strict compliance
3784 return true;
3785 });
3786 },
3787
3788 stop: function(clearQueue, gotoEnd){
3789 var timers = jQuery.timers;
3790
3791 if (clearQueue)
3792 this.queue([]);
3793
3794 this.each(function(){
3795 // go in reverse order so anything added to the queue during the loop is ignored
3796 for ( var i = timers.length - 1; i >= 0; i-- )
3797 if ( timers[i].elem == this ) {
3798 if (gotoEnd)
3799 // force the next step to be the last
3800 timers[i](true);
3801 timers.splice(i, 1);
3802 }
3803 });
3804
3805 // start the next in the queue if the last step wasn't forced
3806 if (!gotoEnd)
3807 this.dequeue();
3808
3809 return this;
3810 }
3811
3812 });
3813
3814 // Generate shortcuts for custom animations
3815 jQuery.each({
3816 slideDown: genFx("show", 1),
3817 slideUp: genFx("hide", 1),
3818 slideToggle: genFx("toggle", 1),
3819 fadeIn: { opacity: "show" },
3820 fadeOut: { opacity: "hide" }
3821 }, function( name, props ){
3822 jQuery.fn[ name ] = function( speed, callback ){
3823 return this.animate( props, speed, callback );
3824 };
3825 });
3826
3827 jQuery.extend({
3828
3829 speed: function(speed, easing, fn) {
3830 var opt = typeof speed === "object" ? speed : {
3831 complete: fn || !fn && easing ||
3832 jQuery.isFunction( speed ) && speed,
3833 duration: speed,
3834 easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
3835 };
3836
3837 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
3838 jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;
3839
3840 // Queueing
3841 opt.old = opt.complete;
3842 opt.complete = function(){
3843 if ( opt.queue !== false )
3844 jQuery(this).dequeue();
3845 if ( jQuery.isFunction( opt.old ) )
3846 opt.old.call( this );
3847 };
3848
3849 return opt;
3850 },
3851
3852 easing: {
3853 linear: function( p, n, firstNum, diff ) {
3854 return firstNum + diff * p;
3855 },
3856 swing: function( p, n, firstNum, diff ) {
3857 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
3858 }
3859 },
3860
3861 timers: [],
3862 timerId: null,
3863
3864 fx: function( elem, options, prop ){
3865 this.options = options;
3866 this.elem = elem;
3867 this.prop = prop;
3868
3869 if ( !options.orig )
3870 options.orig = {};
3871 }
3872
3873 });
3874
3875 jQuery.fx.prototype = {
3876
3877 // Simple function for setting a style value
3878 update: function(){
3879 if ( this.options.step )
3880 this.options.step.call( this.elem, this.now, this );
3881
3882 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
3883
3884 // Set display property to block for height/width animations
3885 if ( ( this.prop == "height" || this.prop == "width" ) && this.elem.style )
3886 this.elem.style.display = "block";
3887 },
3888
3889 // Get the current size
3890 cur: function(force){
3891 if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) )
3892 return this.elem[ this.prop ];
3893
3894 var r = parseFloat(jQuery.css(this.elem, this.prop, force));
3895 return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
3896 },
3897
3898 // Start an animation from one number to another
3899 custom: function(from, to, unit){
3900 this.startTime = now();
3901 this.start = from;
3902 this.end = to;
3903 this.unit = unit || this.unit || "px";
3904 this.now = this.start;
3905 this.pos = this.state = 0;
3906
3907 var self = this;
3908 function t(gotoEnd){
3909 return self.step(gotoEnd);
3910 }
3911
3912 t.elem = this.elem;
3913
3914 jQuery.timers.push(t);
3915
3916 if ( t() && jQuery.timerId == null ) {
3917 jQuery.timerId = setInterval(function(){
3918 var timers = jQuery.timers;
3919
3920 for ( var i = 0; i < timers.length; i++ )
3921 if ( !timers[i]() )
3922 timers.splice(i--, 1);
3923
3924 if ( !timers.length ) {
3925 clearInterval( jQuery.timerId );
3926 jQuery.timerId = null;
3927 }
3928 }, 13);
3929 }
3930 },
3931
3932 // Simple 'show' function
3933 show: function(){
3934 // Remember where we started, so that we can go back to it later
3935 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
3936 this.options.show = true;
3937
3938 // Begin the animation
3939 // Make sure that we start at a small width/height to avoid any
3940 // flash of content
3941 this.custom(this.prop == "width" || this.prop == "height" ? 1 : 0, this.cur());
3942
3943 // Start by showing the element
3944 jQuery(this.elem).show();
3945 },
3946
3947 // Simple 'hide' function
3948 hide: function(){
3949 // Remember where we started, so that we can go back to it later
3950 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
3951 this.options.hide = true;
3952
3953 // Begin the animation
3954 this.custom(this.cur(), 0);
3955 },
3956
3957 // Each step of an animation
3958 step: function(gotoEnd){
3959 var t = now();
3960
3961 if ( gotoEnd || t >= this.options.duration + this.startTime ) {
3962 this.now = this.end;
3963 this.pos = this.state = 1;
3964 this.update();
3965
3966 this.options.curAnim[ this.prop ] = true;
3967
3968 var done = true;
3969 for ( var i in this.options.curAnim )
3970 if ( this.options.curAnim[i] !== true )
3971 done = false;
3972
3973 if ( done ) {
3974 if ( this.options.display != null ) {
3975 // Reset the overflow
3976 this.elem.style.overflow = this.options.overflow;
3977
3978 // Reset the display
3979 this.elem.style.display = this.options.display;
3980 if ( jQuery.css(this.elem, "display") == "none" )
3981 this.elem.style.display = "block";
3982 }
3983
3984 // Hide the element if the "hide" operation was done
3985 if ( this.options.hide )
3986 jQuery(this.elem).hide();
3987
3988 // Reset the properties, if the item has been hidden or shown
3989 if ( this.options.hide || this.options.show )
3990 for ( var p in this.options.curAnim )
3991 jQuery.attr(this.elem.style, p, this.options.orig[p]);
3992 }
3993
3994 if ( done )
3995 // Execute the complete function
3996 this.options.complete.call( this.elem );
3997
3998 return false;
3999 } else {
4000 var n = t - this.startTime;
4001 this.state = n / this.options.duration;
4002
4003 // Perform the easing function, defaults to swing
4004 this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
4005 this.now = this.start + ((this.end - this.start) * this.pos);
4006
4007 // Perform the next step of the animation
4008 this.update();
4009 }
4010
4011 return true;
4012 }
4013
4014 };
4015
4016 jQuery.extend( jQuery.fx, {
4017 speeds:{
4018 slow: 600,
4019 fast: 200,
4020 // Default speed
4021 _default: 400
4022 },
4023 step: {
4024
4025 opacity: function(fx){
4026 jQuery.attr(fx.elem.style, "opacity", fx.now);
4027 },
4028
4029 _default: function(fx){
4030 if ( fx.elem.style && fx.elem.style[ fx.prop ] != null )
4031 fx.elem.style[ fx.prop ] = fx.now + fx.unit;
4032 else
4033 fx.elem[ fx.prop ] = fx.now;
4034 }
4035 }
4036 });
4037 if ( document.documentElement["getBoundingClientRect"] )
4038 jQuery.fn.offset = function() {
4039 if ( !this[0] ) return { top: 0, left: 0 };
4040 if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] );
4041 var box = this[0].getBoundingClientRect(), doc = this[0].ownerDocument, body = doc.body, docElem = doc.documentElement,
4042 clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
4043 top = box.top + (self.pageYOffset || jQuery.boxModel && docElem.scrollTop || body.scrollTop ) - clientTop,
4044 left = box.left + (self.pageXOffset || jQuery.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
4045 return { top: top, left: left };
4046 };
4047 else
4048 jQuery.fn.offset = function() {
4049 if ( !this[0] ) return { top: 0, left: 0 };
4050 if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] );
4051 jQuery.offset.initialized || jQuery.offset.initialize();
4052
4053 var elem = this[0], offsetParent = elem.offsetParent, prevOffsetParent = elem,
4054 doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
4055 body = doc.body, defaultView = doc.defaultView,
4056 prevComputedStyle = defaultView.getComputedStyle(elem, null),
4057 top = elem.offsetTop, left = elem.offsetLeft;
4058
4059 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
4060 computedStyle = defaultView.getComputedStyle(elem, null);
4061 top -= elem.scrollTop, left -= elem.scrollLeft;
4062 if ( elem === offsetParent ) {
4063 top += elem.offsetTop, left += elem.offsetLeft;
4064 if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.tagName)) )
4065 top += parseInt( computedStyle.borderTopWidth, 10) || 0,
4066 left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
4067 prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;
4068 }
4069 if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" )
4070 top += parseInt( computedStyle.borderTopWidth, 10) || 0,
4071 left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
4072 prevComputedStyle = computedStyle;
4073 }
4074
4075 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" )
4076 top += body.offsetTop,
4077 left += body.offsetLeft;
4078
4079 if ( prevComputedStyle.position === "fixed" )
4080 top += Math.max(docElem.scrollTop, body.scrollTop),
4081 left += Math.max(docElem.scrollLeft, body.scrollLeft);
4082
4083 return { top: top, left: left };
4084 };
4085
4086 jQuery.offset = {
4087 initialize: function() {
4088 if ( this.initialized ) return;
4089 var body = document.body, container = document.createElement('div'), innerDiv, checkDiv, table, td, rules, prop, bodyMarginTop = body.style.marginTop,
4090 html = '<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"cellpadding="0"cellspacing="0"><tr><td></td></tr></table>';
4091
4092 rules = { position: 'absolute', top: 0, left: 0, margin: 0, border: 0, width: '1px', height: '1px', visibility: 'hidden' };
4093 for ( prop in rules ) container.style[prop] = rules[prop];
4094
4095 container.innerHTML = html;
4096 body.insertBefore(container, body.firstChild);
4097 innerDiv = container.firstChild, checkDiv = innerDiv.firstChild, td = innerDiv.nextSibling.firstChild.firstChild;
4098
4099 this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
4100 this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
4101
4102 innerDiv.style.overflow = 'hidden', innerDiv.style.position = 'relative';
4103 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
4104
4105 body.style.marginTop = '1px';
4106 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop === 0);
4107 body.style.marginTop = bodyMarginTop;
4108
4109 body.removeChild(container);
4110 this.initialized = true;
4111 },
4112
4113 bodyOffset: function(body) {
4114 jQuery.offset.initialized || jQuery.offset.initialize();
4115 var top = body.offsetTop, left = body.offsetLeft;
4116 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset )
4117 top += parseInt( jQuery.curCSS(body, 'marginTop', true), 10 ) || 0,
4118 left += parseInt( jQuery.curCSS(body, 'marginLeft', true), 10 ) || 0;
4119 return { top: top, left: left };
4120 }
4121 };
4122
4123
4124 jQuery.fn.extend({
4125 position: function() {
4126 var left = 0, top = 0, results;
4127
4128 if ( this[0] ) {
4129 // Get *real* offsetParent
4130 var offsetParent = this.offsetParent(),
4131
4132 // Get correct offsets
4133 offset = this.offset(),
4134 parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();
4135
4136 // Subtract element margins
4137 // note: when an element has margin: auto the offsetLeft and marginLeft
4138 // are the same in Safari causing offset.left to incorrectly be 0
4139 offset.top -= num( this, 'marginTop' );
4140 offset.left -= num( this, 'marginLeft' );
4141
4142 // Add offsetParent borders
4143 parentOffset.top += num( offsetParent, 'borderTopWidth' );
4144 parentOffset.left += num( offsetParent, 'borderLeftWidth' );
4145
4146 // Subtract the two offsets
4147 results = {
4148 top: offset.top - parentOffset.top,
4149 left: offset.left - parentOffset.left
4150 };
4151 }
4152
4153 return results;
4154 },
4155
4156 offsetParent: function() {
4157 var offsetParent = this[0].offsetParent || document.body;
4158 while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') )
4159 offsetParent = offsetParent.offsetParent;
4160 return jQuery(offsetParent);
4161 }
4162 });
4163
4164
4165 // Create scrollLeft and scrollTop methods
4166 jQuery.each( ['Left', 'Top'], function(i, name) {
4167 var method = 'scroll' + name;
4168
4169 jQuery.fn[ method ] = function(val) {
4170 if (!this[0]) return null;
4171
4172 return val !== undefined ?
4173
4174 // Set the scroll offset
4175 this.each(function() {
4176 this == window || this == document ?
4177 window.scrollTo(
4178 !i ? val : jQuery(window).scrollLeft(),
4179 i ? val : jQuery(window).scrollTop()
4180 ) :
4181 this[ method ] = val;
4182 }) :
4183
4184 // Return the scroll offset
4185 this[0] == window || this[0] == document ?
4186 self[ i ? 'pageYOffset' : 'pageXOffset' ] ||
4187 jQuery.boxModel && document.documentElement[ method ] ||
4188 document.body[ method ] :
4189 this[0][ method ];
4190 };
4191 });
4192 // Create innerHeight, innerWidth, outerHeight and outerWidth methods
4193 jQuery.each([ "Height", "Width" ], function(i, name){
4194
4195 var tl = i ? "Left" : "Top", // top or left
4196 br = i ? "Right" : "Bottom"; // bottom or right
4197
4198 // innerHeight and innerWidth
4199 jQuery.fn["inner" + name] = function(){
4200 return this[ name.toLowerCase() ]() +
4201 num(this, "padding" + tl) +
4202 num(this, "padding" + br);
4203 };
4204
4205 // outerHeight and outerWidth
4206 jQuery.fn["outer" + name] = function(margin) {
4207 return this["inner" + name]() +
4208 num(this, "border" + tl + "Width") +
4209 num(this, "border" + br + "Width") +
4210 (margin ?
4211 num(this, "margin" + tl) + num(this, "margin" + br) : 0);
4212 };
4213
4214 var type = name.toLowerCase();
4215
4216 jQuery.fn[ type ] = function( size ) {
4217 // Get window width or height
4218 return this[0] == window ?
4219 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
4220 document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] ||
4221 document.body[ "client" + name ] :
4222
4223 // Get document width or height
4224 this[0] == document ?
4225 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
4226 Math.max(
4227 document.documentElement["client" + name],
4228 document.body["scroll" + name], document.documentElement["scroll" + name],
4229 document.body["offset" + name], document.documentElement["offset" + name]
4230 ) :
4231
4232 // Get or set width or height on the element
4233 size === undefined ?
4234 // Get width or height on the element
4235 (this.length ? jQuery.css( this[0], type ) : null) :
4236
4237 // Set the width or height on the element (default to pixels if value is unitless)
4238 this.css( type, typeof size === "string" ? size : size + "px" );
4239 };
4240
4241 });})();