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