root/trunk/Wierszowki/Wierszowki.Web/Scripts/jquery-1.2.6.js @ 926

Wersja 842, 102.3 KB (wprowadzona przez alina, 17 years temu)

fix #207, #193, #205

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