Add jQuery 1.3.1, needed by DropDownMultiple.
[matthijs/projects/xerxes.git] / media / base / js / jquery-1.3.1.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 = {};\r
1254 \r
1255 jQuery.extend({\r
1256         cache: {},\r
1257 \r
1258         data: function( elem, name, data ) {\r
1259                 elem = elem == window ?\r
1260                         windowData :\r
1261                         elem;\r
1262 \r
1263                 var id = elem[ expando ];\r
1264 \r
1265                 // Compute a unique ID for the element\r
1266                 if ( !id )\r
1267                         id = elem[ expando ] = ++uuid;\r
1268 \r
1269                 // Only generate the data cache if we're\r
1270                 // trying to access or manipulate it\r
1271                 if ( name && !jQuery.cache[ id ] )\r
1272                         jQuery.cache[ id ] = {};\r
1273 \r
1274                 // Prevent overriding the named cache with undefined values\r
1275                 if ( data !== undefined )\r
1276                         jQuery.cache[ id ][ name ] = data;\r
1277 \r
1278                 // Return the named cache data, or the ID for the element\r
1279                 return name ?\r
1280                         jQuery.cache[ id ][ name ] :\r
1281                         id;\r
1282         },\r
1283 \r
1284         removeData: function( elem, name ) {\r
1285                 elem = elem == window ?\r
1286                         windowData :\r
1287                         elem;\r
1288 \r
1289                 var id = elem[ expando ];\r
1290 \r
1291                 // If we want to remove a specific section of the element's data\r
1292                 if ( name ) {\r
1293                         if ( jQuery.cache[ id ] ) {\r
1294                                 // Remove the section of cache data\r
1295                                 delete jQuery.cache[ id ][ name ];\r
1296 \r
1297                                 // If we've removed all the data, remove the element's cache\r
1298                                 name = "";\r
1299 \r
1300                                 for ( name in jQuery.cache[ id ] )\r
1301                                         break;\r
1302 \r
1303                                 if ( !name )\r
1304                                         jQuery.removeData( elem );\r
1305                         }\r
1306 \r
1307                 // Otherwise, we want to remove all of the element's data\r
1308                 } else {\r
1309                         // Clean up the element expando\r
1310                         try {\r
1311                                 delete elem[ expando ];\r
1312                         } catch(e){\r
1313                                 // IE has trouble directly removing the expando\r
1314                                 // but it's ok with using removeAttribute\r
1315                                 if ( elem.removeAttribute )\r
1316                                         elem.removeAttribute( expando );\r
1317                         }\r
1318 \r
1319                         // Completely remove the data cache\r
1320                         delete jQuery.cache[ id ];\r
1321                 }\r
1322         },\r
1323         queue: function( elem, type, data ) {\r
1324                 if ( elem ){\r
1325         \r
1326                         type = (type || "fx") + "queue";\r
1327         \r
1328                         var q = jQuery.data( elem, type );\r
1329         \r
1330                         if ( !q || jQuery.isArray(data) )\r
1331                                 q = jQuery.data( elem, type, jQuery.makeArray(data) );\r
1332                         else if( data )\r
1333                                 q.push( data );\r
1334         \r
1335                 }\r
1336                 return q;\r
1337         },\r
1338 \r
1339         dequeue: function( elem, type ){\r
1340                 var queue = jQuery.queue( elem, type ),\r
1341                         fn = queue.shift();\r
1342                 \r
1343                 if( !type || type === "fx" )\r
1344                         fn = queue[0];\r
1345                         \r
1346                 if( fn !== undefined )\r
1347                         fn.call(elem);\r
1348         }\r
1349 });\r
1350 \r
1351 jQuery.fn.extend({\r
1352         data: function( key, value ){\r
1353                 var parts = key.split(".");\r
1354                 parts[1] = parts[1] ? "." + parts[1] : "";\r
1355 \r
1356                 if ( value === undefined ) {\r
1357                         var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);\r
1358 \r
1359                         if ( data === undefined && this.length )\r
1360                                 data = jQuery.data( this[0], key );\r
1361 \r
1362                         return data === undefined && parts[1] ?\r
1363                                 this.data( parts[0] ) :\r
1364                                 data;\r
1365                 } else\r
1366                         return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){\r
1367                                 jQuery.data( this, key, value );\r
1368                         });\r
1369         },\r
1370 \r
1371         removeData: function( key ){\r
1372                 return this.each(function(){\r
1373                         jQuery.removeData( this, key );\r
1374                 });\r
1375         },\r
1376         queue: function(type, data){\r
1377                 if ( typeof type !== "string" ) {\r
1378                         data = type;\r
1379                         type = "fx";\r
1380                 }\r
1381 \r
1382                 if ( data === undefined )\r
1383                         return jQuery.queue( this[0], type );\r
1384 \r
1385                 return this.each(function(){\r
1386                         var queue = jQuery.queue( this, type, data );\r
1387                         \r
1388                          if( type == "fx" && queue.length == 1 )\r
1389                                 queue[0].call(this);\r
1390                 });\r
1391         },\r
1392         dequeue: function(type){\r
1393                 return this.each(function(){\r
1394                         jQuery.dequeue( this, type );\r
1395                 });\r
1396         }\r
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 });})();