Ignore:
Timestamp:
Feb 20, 2010, 8:56:36 PM (14 years ago)
Author:
nikrou
Message:

Feature 1442 : update jquery

  • update jquery to 1.4.1
  • update jquery ui to 1.7.2
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/template-common/lib/jquery.js

    r3282 r4918  
    1 (function(){
    2 /*
    3  * jQuery 1.2.6 - New Wave Javascript
     1/*!
     2 * jQuery JavaScript Library v1.4.1
     3 * http://jquery.com/
    44 *
    5  * Copyright (c) 2008 John Resig (jquery.com)
    6  * Dual licensed under the MIT (MIT-LICENSE.txt)
    7  * and GPL (GPL-LICENSE.txt) licenses.
     5 * Copyright 2010, John Resig
     6 * Dual licensed under the MIT or GPL Version 2 licenses.
     7 * http://jquery.org/license
    88 *
    9  * $Date: 2008-08-28T01:26:26.034575Z $
    10  * $Rev: 6329 $
     9 * Includes Sizzle.js
     10 * http://sizzlejs.com/
     11 * Copyright 2010, The Dojo Foundation
     12 * Released under the MIT, BSD, and GPL Licenses.
     13 *
     14 * Date: Mon Jan 25 19:43:33 2010 -0500
    1115 */
    12 
    13 // Map over jQuery in case of overwrite
    14 var _jQuery = window.jQuery,
    15 // Map over the $ in case of overwrite
    16         _$ = window.$;
    17 
    18 var jQuery = window.jQuery = window.$ = function( selector, context ) {
    19         // The jQuery object is actually just the init constructor 'enhanced'
    20         return new jQuery.fn.init( selector, context );
    21 };
    22 
    23 // A simple way to check for HTML strings or ID strings
    24 // (both of which we optimize for)
    25 var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,
    26 
    27 // Is it a simple selector
    28         isSimple = /^.[^:#\[\.]*$/,
    29 
    30 // Will speed up references to undefined, and allows munging its name.
    31         undefined;
     16(function( window, undefined ) {
     17
     18// Define a local copy of jQuery
     19var jQuery = function( selector, context ) {
     20                // The jQuery object is actually just the init constructor 'enhanced'
     21                return new jQuery.fn.init( selector, context );
     22        },
     23
     24        // Map over jQuery in case of overwrite
     25        _jQuery = window.jQuery,
     26
     27        // Map over the $ in case of overwrite
     28        _$ = window.$,
     29
     30        // Use the correct document accordingly with window argument (sandbox)
     31        document = window.document,
     32
     33        // A central reference to the root jQuery(document)
     34        rootjQuery,
     35
     36        // A simple way to check for HTML strings or ID strings
     37        // (both of which we optimize for)
     38        quickExpr = /^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,
     39
     40        // Is it a simple selector
     41        isSimple = /^.[^:#\[\.,]*$/,
     42
     43        // Check if a string has a non-whitespace character in it
     44        rnotwhite = /\S/,
     45
     46        // Used for trimming whitespace
     47        rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g,
     48
     49        // Match a standalone tag
     50        rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
     51
     52        // Keep a UserAgent string for use with jQuery.browser
     53        userAgent = navigator.userAgent,
     54
     55        // For matching the engine and version of the browser
     56        browserMatch,
     57       
     58        // Has the ready events already been bound?
     59        readyBound = false,
     60       
     61        // The functions to execute on DOM ready
     62        readyList = [],
     63
     64        // The ready event handler
     65        DOMContentLoaded,
     66
     67        // Save a reference to some core methods
     68        toString = Object.prototype.toString,
     69        hasOwnProperty = Object.prototype.hasOwnProperty,
     70        push = Array.prototype.push,
     71        slice = Array.prototype.slice,
     72        indexOf = Array.prototype.indexOf;
    3273
    3374jQuery.fn = jQuery.prototype = {
    3475        init: function( selector, context ) {
    35                 // Make sure that a selection was provided
    36                 selector = selector || document;
     76                var match, elem, ret, doc;
     77
     78                // Handle $(""), $(null), or $(undefined)
     79                if ( !selector ) {
     80                        return this;
     81                }
    3782
    3883                // Handle $(DOMElement)
    3984                if ( selector.nodeType ) {
    40                         this[0] = selector;
     85                        this.context = this[0] = selector;
    4186                        this.length = 1;
    4287                        return this;
    4388                }
     89
    4490                // Handle HTML strings
    45                 if ( typeof selector == "string" ) {
     91                if ( typeof selector === "string" ) {
    4692                        // Are we dealing with HTML string or an ID?
    47                         var match = quickExpr.exec( selector );
     93                        match = quickExpr.exec( selector );
    4894
    4995                        // Verify a match, and that no context was specified for #id
     
    5197
    5298                                // HANDLE: $(html) -> $(array)
    53                                 if ( match[1] )
    54                                         selector = jQuery.clean( [ match[1] ], context );
     99                                if ( match[1] ) {
     100                                        doc = (context ? context.ownerDocument || context : document);
     101
     102                                        // If a single string is passed in and it's a single tag
     103                                        // just do a createElement and skip the rest
     104                                        ret = rsingleTag.exec( selector );
     105
     106                                        if ( ret ) {
     107                                                if ( jQuery.isPlainObject( context ) ) {
     108                                                        selector = [ document.createElement( ret[1] ) ];
     109                                                        jQuery.fn.attr.call( selector, context, true );
     110
     111                                                } else {
     112                                                        selector = [ doc.createElement( ret[1] ) ];
     113                                                }
     114
     115                                        } else {
     116                                                ret = buildFragment( [ match[1] ], [ doc ] );
     117                                                selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
     118                                        }
    55119
    56120                                // HANDLE: $("#id")
    57                                 else {
    58                                         var elem = document.getElementById( match[3] );
    59 
    60                                         // Make sure an element was located
    61                                         if ( elem ){
     121                                } else {
     122                                        elem = document.getElementById( match[2] );
     123
     124                                        if ( elem ) {
    62125                                                // Handle the case where IE and Opera return items
    63126                                                // by name instead of ID
    64                                                 if ( elem.id != match[3] )
    65                                                         return jQuery().find( selector );
     127                                                if ( elem.id !== match[2] ) {
     128                                                        return rootjQuery.find( selector );
     129                                                }
    66130
    67131                                                // Otherwise, we inject the element directly into the jQuery object
    68                                                 return jQuery( elem );
     132                                                this.length = 1;
     133                                                this[0] = elem;
    69134                                        }
    70                                         selector = [];
    71                                 }
    72 
    73                         // HANDLE: $(expr, [context])
    74                         // (which is just equivalent to: $(content).find(expr)
    75                         } else
     135
     136                                        this.context = document;
     137                                        this.selector = selector;
     138                                        return this;
     139                                }
     140
     141                        // HANDLE: $("TAG")
     142                        } else if ( !context && /^\w+$/.test( selector ) ) {
     143                                this.selector = selector;
     144                                this.context = document;
     145                                selector = document.getElementsByTagName( selector );
     146
     147                        // HANDLE: $(expr, $(...))
     148                        } else if ( !context || context.jquery ) {
     149                                return (context || rootjQuery).find( selector );
     150
     151                        // HANDLE: $(expr, context)
     152                        // (which is just equivalent to: $(context).find(expr)
     153                        } else {
    76154                                return jQuery( context ).find( selector );
     155                        }
    77156
    78157                // HANDLE: $(function)
    79158                // Shortcut for document ready
    80                 } else if ( jQuery.isFunction( selector ) )
    81                         return jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector );
    82 
    83                 return this.setArray(jQuery.makeArray(selector));
    84         },
     159                } else if ( jQuery.isFunction( selector ) ) {
     160                        return rootjQuery.ready( selector );
     161                }
     162
     163                if (selector.selector !== undefined) {
     164                        this.selector = selector.selector;
     165                        this.context = selector.context;
     166                }
     167
     168                return jQuery.isArray( selector ) ?
     169                        this.setArray( selector ) :
     170                        jQuery.makeArray( selector, this );
     171        },
     172
     173        // Start with an empty selector
     174        selector: "",
    85175
    86176        // The current version of jQuery being used
    87         jquery: "1.2.6",
     177        jquery: "1.4.1",
     178
     179        // The default length of a jQuery object is 0
     180        length: 0,
    88181
    89182        // The number of elements contained in the matched element set
     
    92185        },
    93186
    94         // The number of elements contained in the matched element set
    95         length: 0,
     187        toArray: function() {
     188                return slice.call( this, 0 );
     189        },
    96190
    97191        // Get the Nth element in the matched element set OR
    98192        // Get the whole matched element set as a clean array
    99193        get: function( num ) {
    100                 return num == undefined ?
     194                return num == null ?
    101195
    102196                        // Return a 'clean' array
    103                         jQuery.makeArray( this ) :
     197                        this.toArray() :
    104198
    105199                        // Return just the object
    106                         this[ num ];
     200                        ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
    107201        },
    108202
    109203        // Take an array of elements and push it onto the stack
    110204        // (returning the new matched element set)
    111         pushStack: function( elems ) {
     205        pushStack: function( elems, name, selector ) {
    112206                // Build a new jQuery matched element set
    113                 var ret = jQuery( elems );
     207                var ret = jQuery( elems || null );
    114208
    115209                // Add the old object onto the stack (as a reference)
    116210                ret.prevObject = this;
     211
     212                ret.context = this.context;
     213
     214                if ( name === "find" ) {
     215                        ret.selector = this.selector + (this.selector ? " " : "") + selector;
     216                } else if ( name ) {
     217                        ret.selector = this.selector + "." + name + "(" + selector + ")";
     218                }
    117219
    118220                // Return the newly-formed element set
     
    127229                // is a super-fast way to populate an object with array-like properties
    128230                this.length = 0;
    129                 Array.prototype.push.apply( this, elems );
     231                push.apply( this, elems );
    130232
    131233                return this;
     
    138240                return jQuery.each( this, callback, args );
    139241        },
    140 
     242       
     243        ready: function( fn ) {
     244                // Attach the listeners
     245                jQuery.bindReady();
     246
     247                // If the DOM is already ready
     248                if ( jQuery.isReady ) {
     249                        // Execute the function immediately
     250                        fn.call( document, jQuery );
     251
     252                // Otherwise, remember the function for later
     253                } else if ( readyList ) {
     254                        // Add the function to the wait list
     255                        readyList.push( fn );
     256                }
     257
     258                return this;
     259        },
     260       
     261        eq: function( i ) {
     262                return i === -1 ?
     263                        this.slice( i ) :
     264                        this.slice( i, +i + 1 );
     265        },
     266
     267        first: function() {
     268                return this.eq( 0 );
     269        },
     270
     271        last: function() {
     272                return this.eq( -1 );
     273        },
     274
     275        slice: function() {
     276                return this.pushStack( slice.apply( this, arguments ),
     277                        "slice", slice.call(arguments).join(",") );
     278        },
     279
     280        map: function( callback ) {
     281                return this.pushStack( jQuery.map(this, function( elem, i ) {
     282                        return callback.call( elem, i, elem );
     283                }));
     284        },
     285       
     286        end: function() {
     287                return this.prevObject || jQuery(null);
     288        },
     289
     290        // For internal use only.
     291        // Behaves like an Array's method, not like a jQuery method.
     292        push: push,
     293        sort: [].sort,
     294        splice: [].splice
     295};
     296
     297// Give the init function the jQuery prototype for later instantiation
     298jQuery.fn.init.prototype = jQuery.fn;
     299
     300jQuery.extend = jQuery.fn.extend = function() {
     301        // copy reference to target object
     302        var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy;
     303
     304        // Handle a deep copy situation
     305        if ( typeof target === "boolean" ) {
     306                deep = target;
     307                target = arguments[1] || {};
     308                // skip the boolean and the target
     309                i = 2;
     310        }
     311
     312        // Handle case when target is a string or something (possible in deep copy)
     313        if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
     314                target = {};
     315        }
     316
     317        // extend jQuery itself if only one argument is passed
     318        if ( length === i ) {
     319                target = this;
     320                --i;
     321        }
     322
     323        for ( ; i < length; i++ ) {
     324                // Only deal with non-null/undefined values
     325                if ( (options = arguments[ i ]) != null ) {
     326                        // Extend the base object
     327                        for ( name in options ) {
     328                                src = target[ name ];
     329                                copy = options[ name ];
     330
     331                                // Prevent never-ending loop
     332                                if ( target === copy ) {
     333                                        continue;
     334                                }
     335
     336                                // Recurse if we're merging object literal values or arrays
     337                                if ( deep && copy && ( jQuery.isPlainObject(copy) || jQuery.isArray(copy) ) ) {
     338                                        var clone = src && ( jQuery.isPlainObject(src) || jQuery.isArray(src) ) ? src
     339                                                : jQuery.isArray(copy) ? [] : {};
     340
     341                                        // Never move original objects, clone them
     342                                        target[ name ] = jQuery.extend( deep, clone, copy );
     343
     344                                // Don't bring in undefined values
     345                                } else if ( copy !== undefined ) {
     346                                        target[ name ] = copy;
     347                                }
     348                        }
     349                }
     350        }
     351
     352        // Return the modified object
     353        return target;
     354};
     355
     356jQuery.extend({
     357        noConflict: function( deep ) {
     358                window.$ = _$;
     359
     360                if ( deep ) {
     361                        window.jQuery = _jQuery;
     362                }
     363
     364                return jQuery;
     365        },
     366       
     367        // Is the DOM ready to be used? Set to true once it occurs.
     368        isReady: false,
     369       
     370        // Handle when the DOM is ready
     371        ready: function() {
     372                // Make sure that the DOM is not already loaded
     373                if ( !jQuery.isReady ) {
     374                        // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
     375                        if ( !document.body ) {
     376                                return setTimeout( jQuery.ready, 13 );
     377                        }
     378
     379                        // Remember that the DOM is ready
     380                        jQuery.isReady = true;
     381
     382                        // If there are functions bound, to execute
     383                        if ( readyList ) {
     384                                // Execute all of them
     385                                var fn, i = 0;
     386                                while ( (fn = readyList[ i++ ]) ) {
     387                                        fn.call( document, jQuery );
     388                                }
     389
     390                                // Reset the list of functions
     391                                readyList = null;
     392                        }
     393
     394                        // Trigger any bound ready events
     395                        if ( jQuery.fn.triggerHandler ) {
     396                                jQuery( document ).triggerHandler( "ready" );
     397                        }
     398                }
     399        },
     400       
     401        bindReady: function() {
     402                if ( readyBound ) {
     403                        return;
     404                }
     405
     406                readyBound = true;
     407
     408                // Catch cases where $(document).ready() is called after the
     409                // browser event has already occurred.
     410                if ( document.readyState === "complete" ) {
     411                        return jQuery.ready();
     412                }
     413
     414                // Mozilla, Opera and webkit nightlies currently support this event
     415                if ( document.addEventListener ) {
     416                        // Use the handy event callback
     417                        document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
     418                       
     419                        // A fallback to window.onload, that will always work
     420                        window.addEventListener( "load", jQuery.ready, false );
     421
     422                // If IE event model is used
     423                } else if ( document.attachEvent ) {
     424                        // ensure firing before onload,
     425                        // maybe late but safe also for iframes
     426                        document.attachEvent("onreadystatechange", DOMContentLoaded);
     427                       
     428                        // A fallback to window.onload, that will always work
     429                        window.attachEvent( "onload", jQuery.ready );
     430
     431                        // If IE and not a frame
     432                        // continually check to see if the document is ready
     433                        var toplevel = false;
     434
     435                        try {
     436                                toplevel = window.frameElement == null;
     437                        } catch(e) {}
     438
     439                        if ( document.documentElement.doScroll && toplevel ) {
     440                                doScrollCheck();
     441                        }
     442                }
     443        },
     444
     445        // See test/unit/core.js for details concerning isFunction.
     446        // Since version 1.3, DOM methods and functions like alert
     447        // aren't supported. They return false on IE (#2968).
     448        isFunction: function( obj ) {
     449                return toString.call(obj) === "[object Function]";
     450        },
     451
     452        isArray: function( obj ) {
     453                return toString.call(obj) === "[object Array]";
     454        },
     455
     456        isPlainObject: function( obj ) {
     457                // Must be an Object.
     458                // Because of IE, we also have to check the presence of the constructor property.
     459                // Make sure that DOM nodes and window objects don't pass through, as well
     460                if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) {
     461                        return false;
     462                }
     463               
     464                // Not own constructor property must be Object
     465                if ( obj.constructor
     466                        && !hasOwnProperty.call(obj, "constructor")
     467                        && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) {
     468                        return false;
     469                }
     470               
     471                // Own properties are enumerated firstly, so to speed up,
     472                // if last one is own, then all properties are own.
     473       
     474                var key;
     475                for ( key in obj ) {}
     476               
     477                return key === undefined || hasOwnProperty.call( obj, key );
     478        },
     479
     480        isEmptyObject: function( obj ) {
     481                for ( var name in obj ) {
     482                        return false;
     483                }
     484                return true;
     485        },
     486       
     487        error: function( msg ) {
     488                throw msg;
     489        },
     490       
     491        parseJSON: function( data ) {
     492                if ( typeof data !== "string" || !data ) {
     493                        return null;
     494                }
     495               
     496                // Make sure the incoming data is actual JSON
     497                // Logic borrowed from http://json.org/json2.js
     498                if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
     499                        .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
     500                        .replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {
     501
     502                        // Try to use the native JSON parser first
     503                        return window.JSON && window.JSON.parse ?
     504                                window.JSON.parse( data ) :
     505                                (new Function("return " + data))();
     506
     507                } else {
     508                        jQuery.error( "Invalid JSON: " + data );
     509                }
     510        },
     511
     512        noop: function() {},
     513
     514        // Evalulates a script in a global context
     515        globalEval: function( data ) {
     516                if ( data && rnotwhite.test(data) ) {
     517                        // Inspired by code by Andrea Giammarchi
     518                        // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
     519                        var head = document.getElementsByTagName("head")[0] || document.documentElement,
     520                                script = document.createElement("script");
     521
     522                        script.type = "text/javascript";
     523
     524                        if ( jQuery.support.scriptEval ) {
     525                                script.appendChild( document.createTextNode( data ) );
     526                        } else {
     527                                script.text = data;
     528                        }
     529
     530                        // Use insertBefore instead of appendChild to circumvent an IE6 bug.
     531                        // This arises when a base node is used (#2709).
     532                        head.insertBefore( script, head.firstChild );
     533                        head.removeChild( script );
     534                }
     535        },
     536
     537        nodeName: function( elem, name ) {
     538                return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
     539        },
     540
     541        // args is for internal usage only
     542        each: function( object, callback, args ) {
     543                var name, i = 0,
     544                        length = object.length,
     545                        isObj = length === undefined || jQuery.isFunction(object);
     546
     547                if ( args ) {
     548                        if ( isObj ) {
     549                                for ( name in object ) {
     550                                        if ( callback.apply( object[ name ], args ) === false ) {
     551                                                break;
     552                                        }
     553                                }
     554                        } else {
     555                                for ( ; i < length; ) {
     556                                        if ( callback.apply( object[ i++ ], args ) === false ) {
     557                                                break;
     558                                        }
     559                                }
     560                        }
     561
     562                // A special, fast, case for the most common use of each
     563                } else {
     564                        if ( isObj ) {
     565                                for ( name in object ) {
     566                                        if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
     567                                                break;
     568                                        }
     569                                }
     570                        } else {
     571                                for ( var value = object[0];
     572                                        i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
     573                        }
     574                }
     575
     576                return object;
     577        },
     578
     579        trim: function( text ) {
     580                return (text || "").replace( rtrim, "" );
     581        },
     582
     583        // results is for internal usage only
     584        makeArray: function( array, results ) {
     585                var ret = results || [];
     586
     587                if ( array != null ) {
     588                        // The window, strings (and functions) also have 'length'
     589                        // The extra typeof function check is to prevent crashes
     590                        // in Safari 2 (See: #3039)
     591                        if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) {
     592                                push.call( ret, array );
     593                        } else {
     594                                jQuery.merge( ret, array );
     595                        }
     596                }
     597
     598                return ret;
     599        },
     600
     601        inArray: function( elem, array ) {
     602                if ( array.indexOf ) {
     603                        return array.indexOf( elem );
     604                }
     605
     606                for ( var i = 0, length = array.length; i < length; i++ ) {
     607                        if ( array[ i ] === elem ) {
     608                                return i;
     609                        }
     610                }
     611
     612                return -1;
     613        },
     614
     615        merge: function( first, second ) {
     616                var i = first.length, j = 0;
     617
     618                if ( typeof second.length === "number" ) {
     619                        for ( var l = second.length; j < l; j++ ) {
     620                                first[ i++ ] = second[ j ];
     621                        }
     622                } else {
     623                        while ( second[j] !== undefined ) {
     624                                first[ i++ ] = second[ j++ ];
     625                        }
     626                }
     627
     628                first.length = i;
     629
     630                return first;
     631        },
     632
     633        grep: function( elems, callback, inv ) {
     634                var ret = [];
     635
     636                // Go through the array, only saving the items
     637                // that pass the validator function
     638                for ( var i = 0, length = elems.length; i < length; i++ ) {
     639                        if ( !inv !== !callback( elems[ i ], i ) ) {
     640                                ret.push( elems[ i ] );
     641                        }
     642                }
     643
     644                return ret;
     645        },
     646
     647        // arg is for internal usage only
     648        map: function( elems, callback, arg ) {
     649                var ret = [], value;
     650
     651                // Go through the array, translating each of the items to their
     652                // new value (or values).
     653                for ( var i = 0, length = elems.length; i < length; i++ ) {
     654                        value = callback( elems[ i ], i, arg );
     655
     656                        if ( value != null ) {
     657                                ret[ ret.length ] = value;
     658                        }
     659                }
     660
     661                return ret.concat.apply( [], ret );
     662        },
     663
     664        // A global GUID counter for objects
     665        guid: 1,
     666
     667        proxy: function( fn, proxy, thisObject ) {
     668                if ( arguments.length === 2 ) {
     669                        if ( typeof proxy === "string" ) {
     670                                thisObject = fn;
     671                                fn = thisObject[ proxy ];
     672                                proxy = undefined;
     673
     674                        } else if ( proxy && !jQuery.isFunction( proxy ) ) {
     675                                thisObject = proxy;
     676                                proxy = undefined;
     677                        }
     678                }
     679
     680                if ( !proxy && fn ) {
     681                        proxy = function() {
     682                                return fn.apply( thisObject || this, arguments );
     683                        };
     684                }
     685
     686                // Set the guid of unique handler to the same of original handler, so it can be removed
     687                if ( fn ) {
     688                        proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
     689                }
     690
     691                // So proxy can be declared as an argument
     692                return proxy;
     693        },
     694
     695        // Use of jQuery.browser is frowned upon.
     696        // More details: http://docs.jquery.com/Utilities/jQuery.browser
     697        uaMatch: function( ua ) {
     698                ua = ua.toLowerCase();
     699
     700                var match = /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
     701                        /(opera)(?:.*version)?[ \/]([\w.]+)/.exec( ua ) ||
     702                        /(msie) ([\w.]+)/.exec( ua ) ||
     703                        !/compatible/.test( ua ) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec( ua ) ||
     704                        [];
     705
     706                return { browser: match[1] || "", version: match[2] || "0" };
     707        },
     708
     709        browser: {}
     710});
     711
     712browserMatch = jQuery.uaMatch( userAgent );
     713if ( browserMatch.browser ) {
     714        jQuery.browser[ browserMatch.browser ] = true;
     715        jQuery.browser.version = browserMatch.version;
     716}
     717
     718// Deprecated, use jQuery.browser.webkit instead
     719if ( jQuery.browser.webkit ) {
     720        jQuery.browser.safari = true;
     721}
     722
     723if ( indexOf ) {
     724        jQuery.inArray = function( elem, array ) {
     725                return indexOf.call( array, elem );
     726        };
     727}
     728
     729// All jQuery objects should point back to these
     730rootjQuery = jQuery(document);
     731
     732// Cleanup functions for the document ready method
     733if ( document.addEventListener ) {
     734        DOMContentLoaded = function() {
     735                document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
     736                jQuery.ready();
     737        };
     738
     739} else if ( document.attachEvent ) {
     740        DOMContentLoaded = function() {
     741                // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
     742                if ( document.readyState === "complete" ) {
     743                        document.detachEvent( "onreadystatechange", DOMContentLoaded );
     744                        jQuery.ready();
     745                }
     746        };
     747}
     748
     749// The DOM ready check for Internet Explorer
     750function doScrollCheck() {
     751        if ( jQuery.isReady ) {
     752                return;
     753        }
     754
     755        try {
     756                // If IE is used, use the trick by Diego Perini
     757                // http://javascript.nwbox.com/IEContentLoaded/
     758                document.documentElement.doScroll("left");
     759        } catch( error ) {
     760                setTimeout( doScrollCheck, 1 );
     761                return;
     762        }
     763
     764        // and execute any waiting functions
     765        jQuery.ready();
     766}
     767
     768function evalScript( i, elem ) {
     769        if ( elem.src ) {
     770                jQuery.ajax({
     771                        url: elem.src,
     772                        async: false,
     773                        dataType: "script"
     774                });
     775        } else {
     776                jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
     777        }
     778
     779        if ( elem.parentNode ) {
     780                elem.parentNode.removeChild( elem );
     781        }
     782}
     783
     784// Mutifunctional method to get and set values to a collection
     785// The value/s can be optionally by executed if its a function
     786function access( elems, key, value, exec, fn, pass ) {
     787        var length = elems.length;
     788       
     789        // Setting many attributes
     790        if ( typeof key === "object" ) {
     791                for ( var k in key ) {
     792                        access( elems, k, key[k], exec, fn, value );
     793                }
     794                return elems;
     795        }
     796       
     797        // Setting one attribute
     798        if ( value !== undefined ) {
     799                // Optionally, function values get executed if exec is true
     800                exec = !pass && exec && jQuery.isFunction(value);
     801               
     802                for ( var i = 0; i < length; i++ ) {
     803                        fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
     804                }
     805               
     806                return elems;
     807        }
     808       
     809        // Getting an attribute
     810        return length ? fn( elems[0], key ) : null;
     811}
     812
     813function now() {
     814        return (new Date).getTime();
     815}
     816(function() {
     817
     818        jQuery.support = {};
     819
     820        var root = document.documentElement,
     821                script = document.createElement("script"),
     822                div = document.createElement("div"),
     823                id = "script" + now();
     824
     825        div.style.display = "none";
     826        div.innerHTML = "   <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
     827
     828        var all = div.getElementsByTagName("*"),
     829                a = div.getElementsByTagName("a")[0];
     830
     831        // Can't get basic test support
     832        if ( !all || !all.length || !a ) {
     833                return;
     834        }
     835
     836        jQuery.support = {
     837                // IE strips leading whitespace when .innerHTML is used
     838                leadingWhitespace: div.firstChild.nodeType === 3,
     839
     840                // Make sure that tbody elements aren't automatically inserted
     841                // IE will insert them into empty tables
     842                tbody: !div.getElementsByTagName("tbody").length,
     843
     844                // Make sure that link elements get serialized correctly by innerHTML
     845                // This requires a wrapper element in IE
     846                htmlSerialize: !!div.getElementsByTagName("link").length,
     847
     848                // Get the style information from getAttribute
     849                // (IE uses .cssText insted)
     850                style: /red/.test( a.getAttribute("style") ),
     851
     852                // Make sure that URLs aren't manipulated
     853                // (IE normalizes it by default)
     854                hrefNormalized: a.getAttribute("href") === "/a",
     855
     856                // Make sure that element opacity exists
     857                // (IE uses filter instead)
     858                // Use a regex to work around a WebKit issue. See #5145
     859                opacity: /^0.55$/.test( a.style.opacity ),
     860
     861                // Verify style float existence
     862                // (IE uses styleFloat instead of cssFloat)
     863                cssFloat: !!a.style.cssFloat,
     864
     865                // Make sure that if no value is specified for a checkbox
     866                // that it defaults to "on".
     867                // (WebKit defaults to "" instead)
     868                checkOn: div.getElementsByTagName("input")[0].value === "on",
     869
     870                // Make sure that a selected-by-default option has a working selected property.
     871                // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
     872                optSelected: document.createElement("select").appendChild( document.createElement("option") ).selected,
     873
     874                // Will be defined later
     875                checkClone: false,
     876                scriptEval: false,
     877                noCloneEvent: true,
     878                boxModel: null
     879        };
     880
     881        script.type = "text/javascript";
     882        try {
     883                script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
     884        } catch(e) {}
     885
     886        root.insertBefore( script, root.firstChild );
     887
     888        // Make sure that the execution of code works by injecting a script
     889        // tag with appendChild/createTextNode
     890        // (IE doesn't support this, fails, and uses .text instead)
     891        if ( window[ id ] ) {
     892                jQuery.support.scriptEval = true;
     893                delete window[ id ];
     894        }
     895
     896        root.removeChild( script );
     897
     898        if ( div.attachEvent && div.fireEvent ) {
     899                div.attachEvent("onclick", function click() {
     900                        // Cloning a node shouldn't copy over any
     901                        // bound event handlers (IE does this)
     902                        jQuery.support.noCloneEvent = false;
     903                        div.detachEvent("onclick", click);
     904                });
     905                div.cloneNode(true).fireEvent("onclick");
     906        }
     907
     908        div = document.createElement("div");
     909        div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
     910
     911        var fragment = document.createDocumentFragment();
     912        fragment.appendChild( div.firstChild );
     913
     914        // WebKit doesn't clone checked state correctly in fragments
     915        jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
     916
     917        // Figure out if the W3C box model works as expected
     918        // document.body must exist before we can do this
     919        jQuery(function() {
     920                var div = document.createElement("div");
     921                div.style.width = div.style.paddingLeft = "1px";
     922
     923                document.body.appendChild( div );
     924                jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
     925                document.body.removeChild( div ).style.display = 'none';
     926                div = null;
     927        });
     928
     929        // Technique from Juriy Zaytsev
     930        // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
     931        var eventSupported = function( eventName ) {
     932                var el = document.createElement("div");
     933                eventName = "on" + eventName;
     934
     935                var isSupported = (eventName in el);
     936                if ( !isSupported ) {
     937                        el.setAttribute(eventName, "return;");
     938                        isSupported = typeof el[eventName] === "function";
     939                }
     940                el = null;
     941
     942                return isSupported;
     943        };
     944       
     945        jQuery.support.submitBubbles = eventSupported("submit");
     946        jQuery.support.changeBubbles = eventSupported("change");
     947
     948        // release memory in IE
     949        root = script = div = all = a = null;
     950})();
     951
     952jQuery.props = {
     953        "for": "htmlFor",
     954        "class": "className",
     955        readonly: "readOnly",
     956        maxlength: "maxLength",
     957        cellspacing: "cellSpacing",
     958        rowspan: "rowSpan",
     959        colspan: "colSpan",
     960        tabindex: "tabIndex",
     961        usemap: "useMap",
     962        frameborder: "frameBorder"
     963};
     964var expando = "jQuery" + now(), uuid = 0, windowData = {};
     965var emptyObject = {};
     966
     967jQuery.extend({
     968        cache: {},
     969       
     970        expando:expando,
     971
     972        // The following elements throw uncatchable exceptions if you
     973        // attempt to add expando properties to them.
     974        noData: {
     975                "embed": true,
     976                "object": true,
     977                "applet": true
     978        },
     979
     980        data: function( elem, name, data ) {
     981                if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
     982                        return;
     983                }
     984
     985                elem = elem == window ?
     986                        windowData :
     987                        elem;
     988
     989                var id = elem[ expando ], cache = jQuery.cache, thisCache;
     990
     991                // Handle the case where there's no name immediately
     992                if ( !name && !id ) {
     993                        return null;
     994                }
     995
     996                // Compute a unique ID for the element
     997                if ( !id ) {
     998                        id = ++uuid;
     999                }
     1000
     1001                // Avoid generating a new cache unless none exists and we
     1002                // want to manipulate it.
     1003                if ( typeof name === "object" ) {
     1004                        elem[ expando ] = id;
     1005                        thisCache = cache[ id ] = jQuery.extend(true, {}, name);
     1006                } else if ( cache[ id ] ) {
     1007                        thisCache = cache[ id ];
     1008                } else if ( typeof data === "undefined" ) {
     1009                        thisCache = emptyObject;
     1010                } else {
     1011                        thisCache = cache[ id ] = {};
     1012                }
     1013
     1014                // Prevent overriding the named cache with undefined values
     1015                if ( data !== undefined ) {
     1016                        elem[ expando ] = id;
     1017                        thisCache[ name ] = data;
     1018                }
     1019
     1020                return typeof name === "string" ? thisCache[ name ] : thisCache;
     1021        },
     1022
     1023        removeData: function( elem, name ) {
     1024                if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
     1025                        return;
     1026                }
     1027
     1028                elem = elem == window ?
     1029                        windowData :
     1030                        elem;
     1031
     1032                var id = elem[ expando ], cache = jQuery.cache, thisCache = cache[ id ];
     1033
     1034                // If we want to remove a specific section of the element's data
     1035                if ( name ) {
     1036                        if ( thisCache ) {
     1037                                // Remove the section of cache data
     1038                                delete thisCache[ name ];
     1039
     1040                                // If we've removed all the data, remove the element's cache
     1041                                if ( jQuery.isEmptyObject(thisCache) ) {
     1042                                        jQuery.removeData( elem );
     1043                                }
     1044                        }
     1045
     1046                // Otherwise, we want to remove all of the element's data
     1047                } else {
     1048                        // Clean up the element expando
     1049                        try {
     1050                                delete elem[ expando ];
     1051                        } catch( e ) {
     1052                                // IE has trouble directly removing the expando
     1053                                // but it's ok with using removeAttribute
     1054                                if ( elem.removeAttribute ) {
     1055                                        elem.removeAttribute( expando );
     1056                                }
     1057                        }
     1058
     1059                        // Completely remove the data cache
     1060                        delete cache[ id ];
     1061                }
     1062        }
     1063});
     1064
     1065jQuery.fn.extend({
     1066        data: function( key, value ) {
     1067                if ( typeof key === "undefined" && this.length ) {
     1068                        return jQuery.data( this[0] );
     1069
     1070                } else if ( typeof key === "object" ) {
     1071                        return this.each(function() {
     1072                                jQuery.data( this, key );
     1073                        });
     1074                }
     1075
     1076                var parts = key.split(".");
     1077                parts[1] = parts[1] ? "." + parts[1] : "";
     1078
     1079                if ( value === undefined ) {
     1080                        var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
     1081
     1082                        if ( data === undefined && this.length ) {
     1083                                data = jQuery.data( this[0], key );
     1084                        }
     1085                        return data === undefined && parts[1] ?
     1086                                this.data( parts[0] ) :
     1087                                data;
     1088                } else {
     1089                        return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function() {
     1090                                jQuery.data( this, key, value );
     1091                        });
     1092                }
     1093        },
     1094
     1095        removeData: function( key ) {
     1096                return this.each(function() {
     1097                        jQuery.removeData( this, key );
     1098                });
     1099        }
     1100});
     1101jQuery.extend({
     1102        queue: function( elem, type, data ) {
     1103                if ( !elem ) {
     1104                        return;
     1105                }
     1106
     1107                type = (type || "fx") + "queue";
     1108                var q = jQuery.data( elem, type );
     1109
     1110                // Speed up dequeue by getting out quickly if this is just a lookup
     1111                if ( !data ) {
     1112                        return q || [];
     1113                }
     1114
     1115                if ( !q || jQuery.isArray(data) ) {
     1116                        q = jQuery.data( elem, type, jQuery.makeArray(data) );
     1117
     1118                } else {
     1119                        q.push( data );
     1120                }
     1121
     1122                return q;
     1123        },
     1124
     1125        dequeue: function( elem, type ) {
     1126                type = type || "fx";
     1127
     1128                var queue = jQuery.queue( elem, type ), fn = queue.shift();
     1129
     1130                // If the fx queue is dequeued, always remove the progress sentinel
     1131                if ( fn === "inprogress" ) {
     1132                        fn = queue.shift();
     1133                }
     1134
     1135                if ( fn ) {
     1136                        // Add a progress sentinel to prevent the fx queue from being
     1137                        // automatically dequeued
     1138                        if ( type === "fx" ) {
     1139                                queue.unshift("inprogress");
     1140                        }
     1141
     1142                        fn.call(elem, function() {
     1143                                jQuery.dequeue(elem, type);
     1144                        });
     1145                }
     1146        }
     1147});
     1148
     1149jQuery.fn.extend({
     1150        queue: function( type, data ) {
     1151                if ( typeof type !== "string" ) {
     1152                        data = type;
     1153                        type = "fx";
     1154                }
     1155
     1156                if ( data === undefined ) {
     1157                        return jQuery.queue( this[0], type );
     1158                }
     1159                return this.each(function( i, elem ) {
     1160                        var queue = jQuery.queue( this, type, data );
     1161
     1162                        if ( type === "fx" && queue[0] !== "inprogress" ) {
     1163                                jQuery.dequeue( this, type );
     1164                        }
     1165                });
     1166        },
     1167        dequeue: function( type ) {
     1168                return this.each(function() {
     1169                        jQuery.dequeue( this, type );
     1170                });
     1171        },
     1172
     1173        // Based off of the plugin by Clint Helfers, with permission.
     1174        // http://blindsignals.com/index.php/2009/07/jquery-delay/
     1175        delay: function( time, type ) {
     1176                time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
     1177                type = type || "fx";
     1178
     1179                return this.queue( type, function() {
     1180                        var elem = this;
     1181                        setTimeout(function() {
     1182                                jQuery.dequeue( elem, type );
     1183                        }, time );
     1184                });
     1185        },
     1186
     1187        clearQueue: function( type ) {
     1188                return this.queue( type || "fx", [] );
     1189        }
     1190});
     1191var rclass = /[\n\t]/g,
     1192        rspace = /\s+/,
     1193        rreturn = /\r/g,
     1194        rspecialurl = /href|src|style/,
     1195        rtype = /(button|input)/i,
     1196        rfocusable = /(button|input|object|select|textarea)/i,
     1197        rclickable = /^(a|area)$/i,
     1198        rradiocheck = /radio|checkbox/;
     1199
     1200jQuery.fn.extend({
     1201        attr: function( name, value ) {
     1202                return access( this, name, value, true, jQuery.attr );
     1203        },
     1204
     1205        removeAttr: function( name, fn ) {
     1206                return this.each(function(){
     1207                        jQuery.attr( this, name, "" );
     1208                        if ( this.nodeType === 1 ) {
     1209                                this.removeAttribute( name );
     1210                        }
     1211                });
     1212        },
     1213
     1214        addClass: function( value ) {
     1215                if ( jQuery.isFunction(value) ) {
     1216                        return this.each(function(i) {
     1217                                var self = jQuery(this);
     1218                                self.addClass( value.call(this, i, self.attr("class")) );
     1219                        });
     1220                }
     1221
     1222                if ( value && typeof value === "string" ) {
     1223                        var classNames = (value || "").split( rspace );
     1224
     1225                        for ( var i = 0, l = this.length; i < l; i++ ) {
     1226                                var elem = this[i];
     1227
     1228                                if ( elem.nodeType === 1 ) {
     1229                                        if ( !elem.className ) {
     1230                                                elem.className = value;
     1231
     1232                                        } else {
     1233                                                var className = " " + elem.className + " ";
     1234                                                for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
     1235                                                        if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
     1236                                                                elem.className += " " + classNames[c];
     1237                                                        }
     1238                                                }
     1239                                        }
     1240                                }
     1241                        }
     1242                }
     1243
     1244                return this;
     1245        },
     1246
     1247        removeClass: function( value ) {
     1248                if ( jQuery.isFunction(value) ) {
     1249                        return this.each(function(i) {
     1250                                var self = jQuery(this);
     1251                                self.removeClass( value.call(this, i, self.attr("class")) );
     1252                        });
     1253                }
     1254
     1255                if ( (value && typeof value === "string") || value === undefined ) {
     1256                        var classNames = (value || "").split(rspace);
     1257
     1258                        for ( var i = 0, l = this.length; i < l; i++ ) {
     1259                                var elem = this[i];
     1260
     1261                                if ( elem.nodeType === 1 && elem.className ) {
     1262                                        if ( value ) {
     1263                                                var className = (" " + elem.className + " ").replace(rclass, " ");
     1264                                                for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
     1265                                                        className = className.replace(" " + classNames[c] + " ", " ");
     1266                                                }
     1267                                                elem.className = className.substring(1, className.length - 1);
     1268
     1269                                        } else {
     1270                                                elem.className = "";
     1271                                        }
     1272                                }
     1273                        }
     1274                }
     1275
     1276                return this;
     1277        },
     1278
     1279        toggleClass: function( value, stateVal ) {
     1280                var type = typeof value, isBool = typeof stateVal === "boolean";
     1281
     1282                if ( jQuery.isFunction( value ) ) {
     1283                        return this.each(function(i) {
     1284                                var self = jQuery(this);
     1285                                self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
     1286                        });
     1287                }
     1288
     1289                return this.each(function() {
     1290                        if ( type === "string" ) {
     1291                                // toggle individual class names
     1292                                var className, i = 0, self = jQuery(this),
     1293                                        state = stateVal,
     1294                                        classNames = value.split( rspace );
     1295
     1296                                while ( (className = classNames[ i++ ]) ) {
     1297                                        // check each className given, space seperated list
     1298                                        state = isBool ? state : !self.hasClass( className );
     1299                                        self[ state ? "addClass" : "removeClass" ]( className );
     1300                                }
     1301
     1302                        } else if ( type === "undefined" || type === "boolean" ) {
     1303                                if ( this.className ) {
     1304                                        // store className if set
     1305                                        jQuery.data( this, "__className__", this.className );
     1306                                }
     1307
     1308                                // toggle whole className
     1309                                this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
     1310                        }
     1311                });
     1312        },
     1313
     1314        hasClass: function( selector ) {
     1315                var className = " " + selector + " ";
     1316                for ( var i = 0, l = this.length; i < l; i++ ) {
     1317                        if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
     1318                                return true;
     1319                        }
     1320                }
     1321
     1322                return false;
     1323        },
     1324
     1325        val: function( value ) {
     1326                if ( value === undefined ) {
     1327                        var elem = this[0];
     1328
     1329                        if ( elem ) {
     1330                                if ( jQuery.nodeName( elem, "option" ) ) {
     1331                                        return (elem.attributes.value || {}).specified ? elem.value : elem.text;
     1332                                }
     1333
     1334                                // We need to handle select boxes special
     1335                                if ( jQuery.nodeName( elem, "select" ) ) {
     1336                                        var index = elem.selectedIndex,
     1337                                                values = [],
     1338                                                options = elem.options,
     1339                                                one = elem.type === "select-one";
     1340
     1341                                        // Nothing was selected
     1342                                        if ( index < 0 ) {
     1343                                                return null;
     1344                                        }
     1345
     1346                                        // Loop through all the selected options
     1347                                        for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
     1348                                                var option = options[ i ];
     1349
     1350                                                if ( option.selected ) {
     1351                                                        // Get the specifc value for the option
     1352                                                        value = jQuery(option).val();
     1353
     1354                                                        // We don't need an array for one selects
     1355                                                        if ( one ) {
     1356                                                                return value;
     1357                                                        }
     1358
     1359                                                        // Multi-Selects return an array
     1360                                                        values.push( value );
     1361                                                }
     1362                                        }
     1363
     1364                                        return values;
     1365                                }
     1366
     1367                                // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
     1368                                if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
     1369                                        return elem.getAttribute("value") === null ? "on" : elem.value;
     1370                                }
     1371                               
     1372
     1373                                // Everything else, we just grab the value
     1374                                return (elem.value || "").replace(rreturn, "");
     1375
     1376                        }
     1377
     1378                        return undefined;
     1379                }
     1380
     1381                var isFunction = jQuery.isFunction(value);
     1382
     1383                return this.each(function(i) {
     1384                        var self = jQuery(this), val = value;
     1385
     1386                        if ( this.nodeType !== 1 ) {
     1387                                return;
     1388                        }
     1389
     1390                        if ( isFunction ) {
     1391                                val = value.call(this, i, self.val());
     1392                        }
     1393
     1394                        // Typecast each time if the value is a Function and the appended
     1395                        // value is therefore different each time.
     1396                        if ( typeof val === "number" ) {
     1397                                val += "";
     1398                        }
     1399
     1400                        if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
     1401                                this.checked = jQuery.inArray( self.val(), val ) >= 0;
     1402
     1403                        } else if ( jQuery.nodeName( this, "select" ) ) {
     1404                                var values = jQuery.makeArray(val);
     1405
     1406                                jQuery( "option", this ).each(function() {
     1407                                        this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
     1408                                });
     1409
     1410                                if ( !values.length ) {
     1411                                        this.selectedIndex = -1;
     1412                                }
     1413
     1414                        } else {
     1415                                this.value = val;
     1416                        }
     1417                });
     1418        }
     1419});
     1420
     1421jQuery.extend({
     1422        attrFn: {
     1423                val: true,
     1424                css: true,
     1425                html: true,
     1426                text: true,
     1427                data: true,
     1428                width: true,
     1429                height: true,
     1430                offset: true
     1431        },
     1432               
     1433        attr: function( elem, name, value, pass ) {
     1434                // don't set attributes on text and comment nodes
     1435                if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
     1436                        return undefined;
     1437                }
     1438
     1439                if ( pass && name in jQuery.attrFn ) {
     1440                        return jQuery(elem)[name](value);
     1441                }
     1442
     1443                var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
     1444                        // Whether we are setting (or getting)
     1445                        set = value !== undefined;
     1446
     1447                // Try to normalize/fix the name
     1448                name = notxml && jQuery.props[ name ] || name;
     1449
     1450                // Only do all the following if this is a node (faster for style)
     1451                if ( elem.nodeType === 1 ) {
     1452                        // These attributes require special treatment
     1453                        var special = rspecialurl.test( name );
     1454
     1455                        // Safari mis-reports the default selected property of an option
     1456                        // Accessing the parent's selectedIndex property fixes it
     1457                        if ( name === "selected" && !jQuery.support.optSelected ) {
     1458                                var parent = elem.parentNode;
     1459                                if ( parent ) {
     1460                                        parent.selectedIndex;
     1461       
     1462                                        // Make sure that it also works with optgroups, see #5701
     1463                                        if ( parent.parentNode ) {
     1464                                                parent.parentNode.selectedIndex;
     1465                                        }
     1466                                }
     1467                        }
     1468
     1469                        // If applicable, access the attribute via the DOM 0 way
     1470                        if ( name in elem && notxml && !special ) {
     1471                                if ( set ) {
     1472                                        // We can't allow the type property to be changed (since it causes problems in IE)
     1473                                        if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
     1474                                                jQuery.error( "type property can't be changed" );
     1475                                        }
     1476
     1477                                        elem[ name ] = value;
     1478                                }
     1479
     1480                                // browsers index elements by id/name on forms, give priority to attributes.
     1481                                if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
     1482                                        return elem.getAttributeNode( name ).nodeValue;
     1483                                }
     1484
     1485                                // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
     1486                                // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
     1487                                if ( name === "tabIndex" ) {
     1488                                        var attributeNode = elem.getAttributeNode( "tabIndex" );
     1489
     1490                                        return attributeNode && attributeNode.specified ?
     1491                                                attributeNode.value :
     1492                                                rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
     1493                                                        0 :
     1494                                                        undefined;
     1495                                }
     1496
     1497                                return elem[ name ];
     1498                        }
     1499
     1500                        if ( !jQuery.support.style && notxml && name === "style" ) {
     1501                                if ( set ) {
     1502                                        elem.style.cssText = "" + value;
     1503                                }
     1504
     1505                                return elem.style.cssText;
     1506                        }
     1507
     1508                        if ( set ) {
     1509                                // convert the value to a string (all browsers do this but IE) see #1070
     1510                                elem.setAttribute( name, "" + value );
     1511                        }
     1512
     1513                        var attr = !jQuery.support.hrefNormalized && notxml && special ?
     1514                                        // Some attributes require a special call on IE
     1515                                        elem.getAttribute( name, 2 ) :
     1516                                        elem.getAttribute( name );
     1517
     1518                        // Non-existent attributes return null, we normalize to undefined
     1519                        return attr === null ? undefined : attr;
     1520                }
     1521
     1522                // elem is actually elem.style ... set the style
     1523                // Using attr for specific style information is now deprecated. Use style insead.
     1524                return jQuery.style( elem, name, value );
     1525        }
     1526});
     1527var fcleanup = function( nm ) {
     1528        return nm.replace(/[^\w\s\.\|`]/g, function( ch ) {
     1529                return "\\" + ch;
     1530        });
     1531};
     1532
     1533/*
     1534 * A number of helper functions used for managing events.
     1535 * Many of the ideas behind this code originated from
     1536 * Dean Edwards' addEvent library.
     1537 */
     1538jQuery.event = {
     1539
     1540        // Bind an event to an element
     1541        // Original by Dean Edwards
     1542        add: function( elem, types, handler, data ) {
     1543                if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
     1544                        return;
     1545                }
     1546
     1547                // For whatever reason, IE has trouble passing the window object
     1548                // around, causing it to be cloned in the process
     1549                if ( elem.setInterval && ( elem !== window && !elem.frameElement ) ) {
     1550                        elem = window;
     1551                }
     1552
     1553                // Make sure that the function being executed has a unique ID
     1554                if ( !handler.guid ) {
     1555                        handler.guid = jQuery.guid++;
     1556                }
     1557
     1558                // if data is passed, bind to handler
     1559                if ( data !== undefined ) {
     1560                        // Create temporary function pointer to original handler
     1561                        var fn = handler;
     1562
     1563                        // Create unique handler function, wrapped around original handler
     1564                        handler = jQuery.proxy( fn );
     1565
     1566                        // Store data in unique handler
     1567                        handler.data = data;
     1568                }
     1569
     1570                // Init the element's event structure
     1571                var events = jQuery.data( elem, "events" ) || jQuery.data( elem, "events", {} ),
     1572                        handle = jQuery.data( elem, "handle" ), eventHandle;
     1573
     1574                if ( !handle ) {
     1575                        eventHandle = function() {
     1576                                // Handle the second event of a trigger and when
     1577                                // an event is called after a page has unloaded
     1578                                return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
     1579                                        jQuery.event.handle.apply( eventHandle.elem, arguments ) :
     1580                                        undefined;
     1581                        };
     1582
     1583                        handle = jQuery.data( elem, "handle", eventHandle );
     1584                }
     1585
     1586                // If no handle is found then we must be trying to bind to one of the
     1587                // banned noData elements
     1588                if ( !handle ) {
     1589                        return;
     1590                }
     1591
     1592                // Add elem as a property of the handle function
     1593                // This is to prevent a memory leak with non-native
     1594                // event in IE.
     1595                handle.elem = elem;
     1596
     1597                // Handle multiple events separated by a space
     1598                // jQuery(...).bind("mouseover mouseout", fn);
     1599                types = types.split( /\s+/ );
     1600
     1601                var type, i = 0;
     1602
     1603                while ( (type = types[ i++ ]) ) {
     1604                        // Namespaced event handlers
     1605                        var namespaces = type.split(".");
     1606                        type = namespaces.shift();
     1607
     1608                        if ( i > 1 ) {
     1609                                handler = jQuery.proxy( handler );
     1610
     1611                                if ( data !== undefined ) {
     1612                                        handler.data = data;
     1613                                }
     1614                        }
     1615
     1616                        handler.type = namespaces.slice(0).sort().join(".");
     1617
     1618                        // Get the current list of functions bound to this event
     1619                        var handlers = events[ type ],
     1620                                special = this.special[ type ] || {};
     1621
     1622                        // Init the event handler queue
     1623                        if ( !handlers ) {
     1624                                handlers = events[ type ] = {};
     1625
     1626                                // Check for a special event handler
     1627                                // Only use addEventListener/attachEvent if the special
     1628                                // events handler returns false
     1629                                if ( !special.setup || special.setup.call( elem, data, namespaces, handler) === false ) {
     1630                                        // Bind the global event handler to the element
     1631                                        if ( elem.addEventListener ) {
     1632                                                elem.addEventListener( type, handle, false );
     1633                                        } else if ( elem.attachEvent ) {
     1634                                                elem.attachEvent( "on" + type, handle );
     1635                                        }
     1636                                }
     1637                        }
     1638                       
     1639                        if ( special.add ) {
     1640                                var modifiedHandler = special.add.call( elem, handler, data, namespaces, handlers );
     1641                                if ( modifiedHandler && jQuery.isFunction( modifiedHandler ) ) {
     1642                                        modifiedHandler.guid = modifiedHandler.guid || handler.guid;
     1643                                        modifiedHandler.data = modifiedHandler.data || handler.data;
     1644                                        modifiedHandler.type = modifiedHandler.type || handler.type;
     1645                                        handler = modifiedHandler;
     1646                                }
     1647                        }
     1648                       
     1649                        // Add the function to the element's handler list
     1650                        handlers[ handler.guid ] = handler;
     1651
     1652                        // Keep track of which events have been used, for global triggering
     1653                        this.global[ type ] = true;
     1654                }
     1655
     1656                // Nullify elem to prevent memory leaks in IE
     1657                elem = null;
     1658        },
     1659
     1660        global: {},
     1661
     1662        // Detach an event or set of events from an element
     1663        remove: function( elem, types, handler ) {
     1664                // don't do events on text and comment nodes
     1665                if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
     1666                        return;
     1667                }
     1668
     1669                var events = jQuery.data( elem, "events" ), ret, type, fn;
     1670
     1671                if ( events ) {
     1672                        // Unbind all events for the element
     1673                        if ( types === undefined || (typeof types === "string" && types.charAt(0) === ".") ) {
     1674                                for ( type in events ) {
     1675                                        this.remove( elem, type + (types || "") );
     1676                                }
     1677                        } else {
     1678                                // types is actually an event object here
     1679                                if ( types.type ) {
     1680                                        handler = types.handler;
     1681                                        types = types.type;
     1682                                }
     1683
     1684                                // Handle multiple events separated by a space
     1685                                // jQuery(...).unbind("mouseover mouseout", fn);
     1686                                types = types.split(/\s+/);
     1687                                var i = 0;
     1688                                while ( (type = types[ i++ ]) ) {
     1689                                        // Namespaced event handlers
     1690                                        var namespaces = type.split(".");
     1691                                        type = namespaces.shift();
     1692                                        var all = !namespaces.length,
     1693                                                cleaned = jQuery.map( namespaces.slice(0).sort(), fcleanup ),
     1694                                                namespace = new RegExp("(^|\\.)" + cleaned.join("\\.(?:.*\\.)?") + "(\\.|$)"),
     1695                                                special = this.special[ type ] || {};
     1696
     1697                                        if ( events[ type ] ) {
     1698                                                // remove the given handler for the given type
     1699                                                if ( handler ) {
     1700                                                        fn = events[ type ][ handler.guid ];
     1701                                                        delete events[ type ][ handler.guid ];
     1702
     1703                                                // remove all handlers for the given type
     1704                                                } else {
     1705                                                        for ( var handle in events[ type ] ) {
     1706                                                                // Handle the removal of namespaced events
     1707                                                                if ( all || namespace.test( events[ type ][ handle ].type ) ) {
     1708                                                                        delete events[ type ][ handle ];
     1709                                                                }
     1710                                                        }
     1711                                                }
     1712
     1713                                                if ( special.remove ) {
     1714                                                        special.remove.call( elem, namespaces, fn);
     1715                                                }
     1716
     1717                                                // remove generic event handler if no more handlers exist
     1718                                                for ( ret in events[ type ] ) {
     1719                                                        break;
     1720                                                }
     1721                                                if ( !ret ) {
     1722                                                        if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
     1723                                                                if ( elem.removeEventListener ) {
     1724                                                                        elem.removeEventListener( type, jQuery.data( elem, "handle" ), false );
     1725                                                                } else if ( elem.detachEvent ) {
     1726                                                                        elem.detachEvent( "on" + type, jQuery.data( elem, "handle" ) );
     1727                                                                }
     1728                                                        }
     1729                                                        ret = null;
     1730                                                        delete events[ type ];
     1731                                                }
     1732                                        }
     1733                                }
     1734                        }
     1735
     1736                        // Remove the expando if it's no longer used
     1737                        for ( ret in events ) {
     1738                                break;
     1739                        }
     1740                        if ( !ret ) {
     1741                                var handle = jQuery.data( elem, "handle" );
     1742                                if ( handle ) {
     1743                                        handle.elem = null;
     1744                                }
     1745                                jQuery.removeData( elem, "events" );
     1746                                jQuery.removeData( elem, "handle" );
     1747                        }
     1748                }
     1749        },
     1750
     1751        // bubbling is internal
     1752        trigger: function( event, data, elem /*, bubbling */ ) {
     1753                // Event object or event type
     1754                var type = event.type || event,
     1755                        bubbling = arguments[3];
     1756
     1757                if ( !bubbling ) {
     1758                        event = typeof event === "object" ?
     1759                                // jQuery.Event object
     1760                                event[expando] ? event :
     1761                                // Object literal
     1762                                jQuery.extend( jQuery.Event(type), event ) :
     1763                                // Just the event type (string)
     1764                                jQuery.Event(type);
     1765
     1766                        if ( type.indexOf("!") >= 0 ) {
     1767                                event.type = type = type.slice(0, -1);
     1768                                event.exclusive = true;
     1769                        }
     1770
     1771                        // Handle a global trigger
     1772                        if ( !elem ) {
     1773                                // Don't bubble custom events when global (to avoid too much overhead)
     1774                                event.stopPropagation();
     1775
     1776                                // Only trigger if we've ever bound an event for it
     1777                                if ( this.global[ type ] ) {
     1778                                        jQuery.each( jQuery.cache, function() {
     1779                                                if ( this.events && this.events[type] ) {
     1780                                                        jQuery.event.trigger( event, data, this.handle.elem );
     1781                                                }
     1782                                        });
     1783                                }
     1784                        }
     1785
     1786                        // Handle triggering a single element
     1787
     1788                        // don't do events on text and comment nodes
     1789                        if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
     1790                                return undefined;
     1791                        }
     1792
     1793                        // Clean up in case it is reused
     1794                        event.result = undefined;
     1795                        event.target = elem;
     1796
     1797                        // Clone the incoming data, if any
     1798                        data = jQuery.makeArray( data );
     1799                        data.unshift( event );
     1800                }
     1801
     1802                event.currentTarget = elem;
     1803
     1804                // Trigger the event, it is assumed that "handle" is a function
     1805                var handle = jQuery.data( elem, "handle" );
     1806                if ( handle ) {
     1807                        handle.apply( elem, data );
     1808                }
     1809
     1810                var parent = elem.parentNode || elem.ownerDocument;
     1811
     1812                // Trigger an inline bound script
     1813                try {
     1814                        if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
     1815                                if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
     1816                                        event.result = false;
     1817                                }
     1818                        }
     1819
     1820                // prevent IE from throwing an error for some elements with some event types, see #3533
     1821                } catch (e) {}
     1822
     1823                if ( !event.isPropagationStopped() && parent ) {
     1824                        jQuery.event.trigger( event, data, parent, true );
     1825
     1826                } else if ( !event.isDefaultPrevented() ) {
     1827                        var target = event.target, old,
     1828                                isClick = jQuery.nodeName(target, "a") && type === "click";
     1829
     1830                        if ( !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
     1831                                try {
     1832                                        if ( target[ type ] ) {
     1833                                                // Make sure that we don't accidentally re-trigger the onFOO events
     1834                                                old = target[ "on" + type ];
     1835
     1836                                                if ( old ) {
     1837                                                        target[ "on" + type ] = null;
     1838                                                }
     1839
     1840                                                this.triggered = true;
     1841                                                target[ type ]();
     1842                                        }
     1843
     1844                                // prevent IE from throwing an error for some elements with some event types, see #3533
     1845                                } catch (e) {}
     1846
     1847                                if ( old ) {
     1848                                        target[ "on" + type ] = old;
     1849                                }
     1850
     1851                                this.triggered = false;
     1852                        }
     1853                }
     1854        },
     1855
     1856        handle: function( event ) {
     1857                // returned undefined or false
     1858                var all, handlers;
     1859
     1860                event = arguments[0] = jQuery.event.fix( event || window.event );
     1861                event.currentTarget = this;
     1862
     1863                // Namespaced event handlers
     1864                var namespaces = event.type.split(".");
     1865                event.type = namespaces.shift();
     1866
     1867                // Cache this now, all = true means, any handler
     1868                all = !namespaces.length && !event.exclusive;
     1869
     1870                var namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)");
     1871
     1872                handlers = ( jQuery.data(this, "events") || {} )[ event.type ];
     1873
     1874                for ( var j in handlers ) {
     1875                        var handler = handlers[ j ];
     1876
     1877                        // Filter the functions by class
     1878                        if ( all || namespace.test(handler.type) ) {
     1879                                // Pass in a reference to the handler function itself
     1880                                // So that we can later remove it
     1881                                event.handler = handler;
     1882                                event.data = handler.data;
     1883
     1884                                var ret = handler.apply( this, arguments );
     1885
     1886                                if ( ret !== undefined ) {
     1887                                        event.result = ret;
     1888                                        if ( ret === false ) {
     1889                                                event.preventDefault();
     1890                                                event.stopPropagation();
     1891                                        }
     1892                                }
     1893
     1894                                if ( event.isImmediatePropagationStopped() ) {
     1895                                        break;
     1896                                }
     1897
     1898                        }
     1899                }
     1900
     1901                return event.result;
     1902        },
     1903
     1904        props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
     1905
     1906        fix: function( event ) {
     1907                if ( event[ expando ] ) {
     1908                        return event;
     1909                }
     1910
     1911                // store a copy of the original event object
     1912                // and "clone" to set read-only properties
     1913                var originalEvent = event;
     1914                event = jQuery.Event( originalEvent );
     1915
     1916                for ( var i = this.props.length, prop; i; ) {
     1917                        prop = this.props[ --i ];
     1918                        event[ prop ] = originalEvent[ prop ];
     1919                }
     1920
     1921                // Fix target property, if necessary
     1922                if ( !event.target ) {
     1923                        event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
     1924                }
     1925
     1926                // check if target is a textnode (safari)
     1927                if ( event.target.nodeType === 3 ) {
     1928                        event.target = event.target.parentNode;
     1929                }
     1930
     1931                // Add relatedTarget, if necessary
     1932                if ( !event.relatedTarget && event.fromElement ) {
     1933                        event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
     1934                }
     1935
     1936                // Calculate pageX/Y if missing and clientX/Y available
     1937                if ( event.pageX == null && event.clientX != null ) {
     1938                        var doc = document.documentElement, body = document.body;
     1939                        event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
     1940                        event.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);
     1941                }
     1942
     1943                // Add which for key events
     1944                if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) {
     1945                        event.which = event.charCode || event.keyCode;
     1946                }
     1947
     1948                // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
     1949                if ( !event.metaKey && event.ctrlKey ) {
     1950                        event.metaKey = event.ctrlKey;
     1951                }
     1952
     1953                // Add which for click: 1 === left; 2 === middle; 3 === right
     1954                // Note: button is not normalized, so don't use it
     1955                if ( !event.which && event.button !== undefined ) {
     1956                        event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
     1957                }
     1958
     1959                return event;
     1960        },
     1961
     1962        // Deprecated, use jQuery.guid instead
     1963        guid: 1E8,
     1964
     1965        // Deprecated, use jQuery.proxy instead
     1966        proxy: jQuery.proxy,
     1967
     1968        special: {
     1969                ready: {
     1970                        // Make sure the ready event is setup
     1971                        setup: jQuery.bindReady,
     1972                        teardown: jQuery.noop
     1973                },
     1974
     1975                live: {
     1976                        add: function( proxy, data, namespaces, live ) {
     1977                                jQuery.extend( proxy, data || {} );
     1978
     1979                                proxy.guid += data.selector + data.live;
     1980                                data.liveProxy = proxy;
     1981
     1982                                jQuery.event.add( this, data.live, liveHandler, data );
     1983                               
     1984                        },
     1985
     1986                        remove: function( namespaces ) {
     1987                                if ( namespaces.length ) {
     1988                                        var remove = 0, name = new RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)");
     1989
     1990                                        jQuery.each( (jQuery.data(this, "events").live || {}), function() {
     1991                                                if ( name.test(this.type) ) {
     1992                                                        remove++;
     1993                                                }
     1994                                        });
     1995
     1996                                        if ( remove < 1 ) {
     1997                                                jQuery.event.remove( this, namespaces[0], liveHandler );
     1998                                        }
     1999                                }
     2000                        },
     2001                        special: {}
     2002                },
     2003                beforeunload: {
     2004                        setup: function( data, namespaces, fn ) {
     2005                                // We only want to do this special case on windows
     2006                                if ( this.setInterval ) {
     2007                                        this.onbeforeunload = fn;
     2008                                }
     2009
     2010                                return false;
     2011                        },
     2012                        teardown: function( namespaces, fn ) {
     2013                                if ( this.onbeforeunload === fn ) {
     2014                                        this.onbeforeunload = null;
     2015                                }
     2016                        }
     2017                }
     2018        }
     2019};
     2020
     2021jQuery.Event = function( src ) {
     2022        // Allow instantiation without the 'new' keyword
     2023        if ( !this.preventDefault ) {
     2024                return new jQuery.Event( src );
     2025        }
     2026
     2027        // Event object
     2028        if ( src && src.type ) {
     2029                this.originalEvent = src;
     2030                this.type = src.type;
     2031        // Event type
     2032        } else {
     2033                this.type = src;
     2034        }
     2035
     2036        // timeStamp is buggy for some events on Firefox(#3843)
     2037        // So we won't rely on the native value
     2038        this.timeStamp = now();
     2039
     2040        // Mark it as fixed
     2041        this[ expando ] = true;
     2042};
     2043
     2044function returnFalse() {
     2045        return false;
     2046}
     2047function returnTrue() {
     2048        return true;
     2049}
     2050
     2051// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
     2052// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
     2053jQuery.Event.prototype = {
     2054        preventDefault: function() {
     2055                this.isDefaultPrevented = returnTrue;
     2056
     2057                var e = this.originalEvent;
     2058                if ( !e ) {
     2059                        return;
     2060                }
     2061               
     2062                // if preventDefault exists run it on the original event
     2063                if ( e.preventDefault ) {
     2064                        e.preventDefault();
     2065                }
     2066                // otherwise set the returnValue property of the original event to false (IE)
     2067                e.returnValue = false;
     2068        },
     2069        stopPropagation: function() {
     2070                this.isPropagationStopped = returnTrue;
     2071
     2072                var e = this.originalEvent;
     2073                if ( !e ) {
     2074                        return;
     2075                }
     2076                // if stopPropagation exists run it on the original event
     2077                if ( e.stopPropagation ) {
     2078                        e.stopPropagation();
     2079                }
     2080                // otherwise set the cancelBubble property of the original event to true (IE)
     2081                e.cancelBubble = true;
     2082        },
     2083        stopImmediatePropagation: function() {
     2084                this.isImmediatePropagationStopped = returnTrue;
     2085                this.stopPropagation();
     2086        },
     2087        isDefaultPrevented: returnFalse,
     2088        isPropagationStopped: returnFalse,
     2089        isImmediatePropagationStopped: returnFalse
     2090};
     2091
     2092// Checks if an event happened on an element within another element
     2093// Used in jQuery.event.special.mouseenter and mouseleave handlers
     2094var withinElement = function( event ) {
     2095        // Check if mouse(over|out) are still within the same parent element
     2096        var parent = event.relatedTarget;
     2097
     2098        // Traverse up the tree
     2099        while ( parent && parent !== this ) {
     2100                // Firefox sometimes assigns relatedTarget a XUL element
     2101                // which we cannot access the parentNode property of
     2102                try {
     2103                        parent = parent.parentNode;
     2104
     2105                // assuming we've left the element since we most likely mousedover a xul element
     2106                } catch(e) {
     2107                        break;
     2108                }
     2109        }
     2110
     2111        if ( parent !== this ) {
     2112                // set the correct event type
     2113                event.type = event.data;
     2114
     2115                // handle event if we actually just moused on to a non sub-element
     2116                jQuery.event.handle.apply( this, arguments );
     2117        }
     2118
     2119},
     2120
     2121// In case of event delegation, we only need to rename the event.type,
     2122// liveHandler will take care of the rest.
     2123delegate = function( event ) {
     2124        event.type = event.data;
     2125        jQuery.event.handle.apply( this, arguments );
     2126};
     2127
     2128// Create mouseenter and mouseleave events
     2129jQuery.each({
     2130        mouseenter: "mouseover",
     2131        mouseleave: "mouseout"
     2132}, function( orig, fix ) {
     2133        jQuery.event.special[ orig ] = {
     2134                setup: function( data ) {
     2135                        jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
     2136                },
     2137                teardown: function( data ) {
     2138                        jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
     2139                }
     2140        };
     2141});
     2142
     2143// submit delegation
     2144if ( !jQuery.support.submitBubbles ) {
     2145
     2146jQuery.event.special.submit = {
     2147        setup: function( data, namespaces, fn ) {
     2148                if ( this.nodeName.toLowerCase() !== "form" ) {
     2149                        jQuery.event.add(this, "click.specialSubmit." + fn.guid, function( e ) {
     2150                                var elem = e.target, type = elem.type;
     2151
     2152                                if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
     2153                                        return trigger( "submit", this, arguments );
     2154                                }
     2155                        });
     2156         
     2157                        jQuery.event.add(this, "keypress.specialSubmit." + fn.guid, function( e ) {
     2158                                var elem = e.target, type = elem.type;
     2159
     2160                                if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
     2161                                        return trigger( "submit", this, arguments );
     2162                                }
     2163                        });
     2164
     2165                } else {
     2166                        return false;
     2167                }
     2168        },
     2169
     2170        remove: function( namespaces, fn ) {
     2171                jQuery.event.remove( this, "click.specialSubmit" + (fn ? "."+fn.guid : "") );
     2172                jQuery.event.remove( this, "keypress.specialSubmit" + (fn ? "."+fn.guid : "") );
     2173        }
     2174};
     2175
     2176}
     2177
     2178// change delegation, happens here so we have bind.
     2179if ( !jQuery.support.changeBubbles ) {
     2180
     2181var formElems = /textarea|input|select/i;
     2182
     2183function getVal( elem ) {
     2184        var type = elem.type, val = elem.value;
     2185
     2186        if ( type === "radio" || type === "checkbox" ) {
     2187                val = elem.checked;
     2188
     2189        } else if ( type === "select-multiple" ) {
     2190                val = elem.selectedIndex > -1 ?
     2191                        jQuery.map( elem.options, function( elem ) {
     2192                                return elem.selected;
     2193                        }).join("-") :
     2194                        "";
     2195
     2196        } else if ( elem.nodeName.toLowerCase() === "select" ) {
     2197                val = elem.selectedIndex;
     2198        }
     2199
     2200        return val;
     2201}
     2202
     2203function testChange( e ) {
     2204                var elem = e.target, data, val;
     2205
     2206                if ( !formElems.test( elem.nodeName ) || elem.readOnly ) {
     2207                        return;
     2208                }
     2209
     2210                data = jQuery.data( elem, "_change_data" );
     2211                val = getVal(elem);
     2212
     2213                // the current data will be also retrieved by beforeactivate
     2214                if ( e.type !== "focusout" || elem.type !== "radio" ) {
     2215                        jQuery.data( elem, "_change_data", val );
     2216                }
     2217               
     2218                if ( data === undefined || val === data ) {
     2219                        return;
     2220                }
     2221
     2222                if ( data != null || val ) {
     2223                        e.type = "change";
     2224                        return jQuery.event.trigger( e, arguments[1], elem );
     2225                }
     2226}
     2227
     2228jQuery.event.special.change = {
     2229        filters: {
     2230                focusout: testChange,
     2231
     2232                click: function( e ) {
     2233                        var elem = e.target, type = elem.type;
     2234
     2235                        if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
     2236                                return testChange.call( this, e );
     2237                        }
     2238                },
     2239
     2240                // Change has to be called before submit
     2241                // Keydown will be called before keypress, which is used in submit-event delegation
     2242                keydown: function( e ) {
     2243                        var elem = e.target, type = elem.type;
     2244
     2245                        if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
     2246                                (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
     2247                                type === "select-multiple" ) {
     2248                                return testChange.call( this, e );
     2249                        }
     2250                },
     2251
     2252                // Beforeactivate happens also before the previous element is blurred
     2253                // with this event you can't trigger a change event, but you can store
     2254                // information/focus[in] is not needed anymore
     2255                beforeactivate: function( e ) {
     2256                        var elem = e.target;
     2257
     2258                        if ( elem.nodeName.toLowerCase() === "input" && elem.type === "radio" ) {
     2259                                jQuery.data( elem, "_change_data", getVal(elem) );
     2260                        }
     2261                }
     2262        },
     2263        setup: function( data, namespaces, fn ) {
     2264                for ( var type in changeFilters ) {
     2265                        jQuery.event.add( this, type + ".specialChange." + fn.guid, changeFilters[type] );
     2266                }
     2267
     2268                return formElems.test( this.nodeName );
     2269        },
     2270        remove: function( namespaces, fn ) {
     2271                for ( var type in changeFilters ) {
     2272                        jQuery.event.remove( this, type + ".specialChange" + (fn ? "."+fn.guid : ""), changeFilters[type] );
     2273                }
     2274
     2275                return formElems.test( this.nodeName );
     2276        }
     2277};
     2278
     2279var changeFilters = jQuery.event.special.change.filters;
     2280
     2281}
     2282
     2283function trigger( type, elem, args ) {
     2284        args[0].type = type;
     2285        return jQuery.event.handle.apply( elem, args );
     2286}
     2287
     2288// Create "bubbling" focus and blur events
     2289if ( document.addEventListener ) {
     2290        jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
     2291                jQuery.event.special[ fix ] = {
     2292                        setup: function() {
     2293                                this.addEventListener( orig, handler, true );
     2294                        },
     2295                        teardown: function() {
     2296                                this.removeEventListener( orig, handler, true );
     2297                        }
     2298                };
     2299
     2300                function handler( e ) {
     2301                        e = jQuery.event.fix( e );
     2302                        e.type = fix;
     2303                        return jQuery.event.handle.call( this, e );
     2304                }
     2305        });
     2306}
     2307
     2308jQuery.each(["bind", "one"], function( i, name ) {
     2309        jQuery.fn[ name ] = function( type, data, fn ) {
     2310                // Handle object literals
     2311                if ( typeof type === "object" ) {
     2312                        for ( var key in type ) {
     2313                                this[ name ](key, data, type[key], fn);
     2314                        }
     2315                        return this;
     2316                }
     2317               
     2318                if ( jQuery.isFunction( data ) ) {
     2319                        fn = data;
     2320                        data = undefined;
     2321                }
     2322
     2323                var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
     2324                        jQuery( this ).unbind( event, handler );
     2325                        return fn.apply( this, arguments );
     2326                }) : fn;
     2327
     2328                return type === "unload" && name !== "one" ?
     2329                        this.one( type, data, fn ) :
     2330                        this.each(function() {
     2331                                jQuery.event.add( this, type, handler, data );
     2332                        });
     2333        };
     2334});
     2335
     2336jQuery.fn.extend({
     2337        unbind: function( type, fn ) {
     2338                // Handle object literals
     2339                if ( typeof type === "object" && !type.preventDefault ) {
     2340                        for ( var key in type ) {
     2341                                this.unbind(key, type[key]);
     2342                        }
     2343                        return this;
     2344                }
     2345
     2346                return this.each(function() {
     2347                        jQuery.event.remove( this, type, fn );
     2348                });
     2349        },
     2350        trigger: function( type, data ) {
     2351                return this.each(function() {
     2352                        jQuery.event.trigger( type, data, this );
     2353                });
     2354        },
     2355
     2356        triggerHandler: function( type, data ) {
     2357                if ( this[0] ) {
     2358                        var event = jQuery.Event( type );
     2359                        event.preventDefault();
     2360                        event.stopPropagation();
     2361                        jQuery.event.trigger( event, data, this[0] );
     2362                        return event.result;
     2363                }
     2364        },
     2365
     2366        toggle: function( fn ) {
     2367                // Save reference to arguments for access in closure
     2368                var args = arguments, i = 1;
     2369
     2370                // link all the functions, so any of them can unbind this click handler
     2371                while ( i < args.length ) {
     2372                        jQuery.proxy( fn, args[ i++ ] );
     2373                }
     2374
     2375                return this.click( jQuery.proxy( fn, function( event ) {
     2376                        // Figure out which function to execute
     2377                        var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
     2378                        jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
     2379
     2380                        // Make sure that clicks stop
     2381                        event.preventDefault();
     2382
     2383                        // and execute the function
     2384                        return args[ lastToggle ].apply( this, arguments ) || false;
     2385                }));
     2386        },
     2387
     2388        hover: function( fnOver, fnOut ) {
     2389                return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
     2390        }
     2391});
     2392
     2393jQuery.each(["live", "die"], function( i, name ) {
     2394        jQuery.fn[ name ] = function( types, data, fn ) {
     2395                var type, i = 0;
     2396
     2397                if ( jQuery.isFunction( data ) ) {
     2398                        fn = data;
     2399                        data = undefined;
     2400                }
     2401
     2402                types = (types || "").split( /\s+/ );
     2403
     2404                while ( (type = types[ i++ ]) != null ) {
     2405                        type = type === "focus" ? "focusin" : // focus --> focusin
     2406                                        type === "blur" ? "focusout" : // blur --> focusout
     2407                                        type === "hover" ? types.push("mouseleave") && "mouseenter" : // hover support
     2408                                        type;
     2409                       
     2410                        if ( name === "live" ) {
     2411                                // bind live handler
     2412                                jQuery( this.context ).bind( liveConvert( type, this.selector ), {
     2413                                        data: data, selector: this.selector, live: type
     2414                                }, fn );
     2415
     2416                        } else {
     2417                                // unbind live handler
     2418                                jQuery( this.context ).unbind( liveConvert( type, this.selector ), fn ? { guid: fn.guid + this.selector + type } : null );
     2419                        }
     2420                }
     2421               
     2422                return this;
     2423        }
     2424});
     2425
     2426function liveHandler( event ) {
     2427        var stop, elems = [], selectors = [], args = arguments,
     2428                related, match, fn, elem, j, i, l, data,
     2429                live = jQuery.extend({}, jQuery.data( this, "events" ).live);
     2430
     2431        // Make sure we avoid non-left-click bubbling in Firefox (#3861)
     2432        if ( event.button && event.type === "click" ) {
     2433                return;
     2434        }
     2435
     2436        for ( j in live ) {
     2437                fn = live[j];
     2438                if ( fn.live === event.type ||
     2439                                fn.altLive && jQuery.inArray(event.type, fn.altLive) > -1 ) {
     2440
     2441                        data = fn.data;
     2442                        if ( !(data.beforeFilter && data.beforeFilter[event.type] &&
     2443                                        !data.beforeFilter[event.type](event)) ) {
     2444                                selectors.push( fn.selector );
     2445                        }
     2446                } else {
     2447                        delete live[j];
     2448                }
     2449        }
     2450
     2451        match = jQuery( event.target ).closest( selectors, event.currentTarget );
     2452
     2453        for ( i = 0, l = match.length; i < l; i++ ) {
     2454                for ( j in live ) {
     2455                        fn = live[j];
     2456                        elem = match[i].elem;
     2457                        related = null;
     2458
     2459                        if ( match[i].selector === fn.selector ) {
     2460                                // Those two events require additional checking
     2461                                if ( fn.live === "mouseenter" || fn.live === "mouseleave" ) {
     2462                                        related = jQuery( event.relatedTarget ).closest( fn.selector )[0];
     2463                                }
     2464
     2465                                if ( !related || related !== elem ) {
     2466                                        elems.push({ elem: elem, fn: fn });
     2467                                }
     2468                        }
     2469                }
     2470        }
     2471
     2472        for ( i = 0, l = elems.length; i < l; i++ ) {
     2473                match = elems[i];
     2474                event.currentTarget = match.elem;
     2475                event.data = match.fn.data;
     2476                if ( match.fn.apply( match.elem, args ) === false ) {
     2477                        stop = false;
     2478                        break;
     2479                }
     2480        }
     2481
     2482        return stop;
     2483}
     2484
     2485function liveConvert( type, selector ) {
     2486        return "live." + (type ? type + "." : "") + selector.replace(/\./g, "`").replace(/ /g, "&");
     2487}
     2488
     2489jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
     2490        "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
     2491        "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
     2492
     2493        // Handle event binding
     2494        jQuery.fn[ name ] = function( fn ) {
     2495                return fn ? this.bind( name, fn ) : this.trigger( name );
     2496        };
     2497
     2498        if ( jQuery.attrFn ) {
     2499                jQuery.attrFn[ name ] = true;
     2500        }
     2501});
     2502
     2503// Prevent memory leaks in IE
     2504// Window isn't included so as not to unbind existing unload events
     2505// More info:
     2506//  - http://isaacschlueter.com/2006/10/msie-memory-leaks/
     2507if ( window.attachEvent && !window.addEventListener ) {
     2508        window.attachEvent("onunload", function() {
     2509                for ( var id in jQuery.cache ) {
     2510                        if ( jQuery.cache[ id ].handle ) {
     2511                                // Try/Catch is to handle iframes being unloaded, see #4280
     2512                                try {
     2513                                        jQuery.event.remove( jQuery.cache[ id ].handle.elem );
     2514                                } catch(e) {}
     2515                        }
     2516                }
     2517        });
     2518}
     2519/*!
     2520 * Sizzle CSS Selector Engine - v1.0
     2521 *  Copyright 2009, The Dojo Foundation
     2522 *  Released under the MIT, BSD, and GPL Licenses.
     2523 *  More information: http://sizzlejs.com/
     2524 */
     2525(function(){
     2526
     2527var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
     2528        done = 0,
     2529        toString = Object.prototype.toString,
     2530        hasDuplicate = false,
     2531        baseHasDuplicate = true;
     2532
     2533// Here we check if the JavaScript engine is using some sort of
     2534// optimization where it does not always call our comparision
     2535// function. If that is the case, discard the hasDuplicate value.
     2536//   Thus far that includes Google Chrome.
     2537[0, 0].sort(function(){
     2538        baseHasDuplicate = false;
     2539        return 0;
     2540});
     2541
     2542var Sizzle = function(selector, context, results, seed) {
     2543        results = results || [];
     2544        var origContext = context = context || document;
     2545
     2546        if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
     2547                return [];
     2548        }
     2549       
     2550        if ( !selector || typeof selector !== "string" ) {
     2551                return results;
     2552        }
     2553
     2554        var parts = [], m, set, checkSet, extra, prune = true, contextXML = isXML(context),
     2555                soFar = selector;
     2556       
     2557        // Reset the position of the chunker regexp (start from head)
     2558        while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
     2559                soFar = m[3];
     2560               
     2561                parts.push( m[1] );
     2562               
     2563                if ( m[2] ) {
     2564                        extra = m[3];
     2565                        break;
     2566                }
     2567        }
     2568
     2569        if ( parts.length > 1 && origPOS.exec( selector ) ) {
     2570                if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
     2571                        set = posProcess( parts[0] + parts[1], context );
     2572                } else {
     2573                        set = Expr.relative[ parts[0] ] ?
     2574                                [ context ] :
     2575                                Sizzle( parts.shift(), context );
     2576
     2577                        while ( parts.length ) {
     2578                                selector = parts.shift();
     2579
     2580                                if ( Expr.relative[ selector ] ) {
     2581                                        selector += parts.shift();
     2582                                }
     2583                               
     2584                                set = posProcess( selector, set );
     2585                        }
     2586                }
     2587        } else {
     2588                // Take a shortcut and set the context if the root selector is an ID
     2589                // (but not if it'll be faster if the inner selector is an ID)
     2590                if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
     2591                                Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
     2592                        var ret = Sizzle.find( parts.shift(), context, contextXML );
     2593                        context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
     2594                }
     2595
     2596                if ( context ) {
     2597                        var ret = seed ?
     2598                                { expr: parts.pop(), set: makeArray(seed) } :
     2599                                Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
     2600                        set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
     2601
     2602                        if ( parts.length > 0 ) {
     2603                                checkSet = makeArray(set);
     2604                        } else {
     2605                                prune = false;
     2606                        }
     2607
     2608                        while ( parts.length ) {
     2609                                var cur = parts.pop(), pop = cur;
     2610
     2611                                if ( !Expr.relative[ cur ] ) {
     2612                                        cur = "";
     2613                                } else {
     2614                                        pop = parts.pop();
     2615                                }
     2616
     2617                                if ( pop == null ) {
     2618                                        pop = context;
     2619                                }
     2620
     2621                                Expr.relative[ cur ]( checkSet, pop, contextXML );
     2622                        }
     2623                } else {
     2624                        checkSet = parts = [];
     2625                }
     2626        }
     2627
     2628        if ( !checkSet ) {
     2629                checkSet = set;
     2630        }
     2631
     2632        if ( !checkSet ) {
     2633                Sizzle.error( cur || selector );
     2634        }
     2635
     2636        if ( toString.call(checkSet) === "[object Array]" ) {
     2637                if ( !prune ) {
     2638                        results.push.apply( results, checkSet );
     2639                } else if ( context && context.nodeType === 1 ) {
     2640                        for ( var i = 0; checkSet[i] != null; i++ ) {
     2641                                if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
     2642                                        results.push( set[i] );
     2643                                }
     2644                        }
     2645                } else {
     2646                        for ( var i = 0; checkSet[i] != null; i++ ) {
     2647                                if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
     2648                                        results.push( set[i] );
     2649                                }
     2650                        }
     2651                }
     2652        } else {
     2653                makeArray( checkSet, results );
     2654        }
     2655
     2656        if ( extra ) {
     2657                Sizzle( extra, origContext, results, seed );
     2658                Sizzle.uniqueSort( results );
     2659        }
     2660
     2661        return results;
     2662};
     2663
     2664Sizzle.uniqueSort = function(results){
     2665        if ( sortOrder ) {
     2666                hasDuplicate = baseHasDuplicate;
     2667                results.sort(sortOrder);
     2668
     2669                if ( hasDuplicate ) {
     2670                        for ( var i = 1; i < results.length; i++ ) {
     2671                                if ( results[i] === results[i-1] ) {
     2672                                        results.splice(i--, 1);
     2673                                }
     2674                        }
     2675                }
     2676        }
     2677
     2678        return results;
     2679};
     2680
     2681Sizzle.matches = function(expr, set){
     2682        return Sizzle(expr, null, null, set);
     2683};
     2684
     2685Sizzle.find = function(expr, context, isXML){
     2686        var set, match;
     2687
     2688        if ( !expr ) {
     2689                return [];
     2690        }
     2691
     2692        for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
     2693                var type = Expr.order[i], match;
     2694               
     2695                if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
     2696                        var left = match[1];
     2697                        match.splice(1,1);
     2698
     2699                        if ( left.substr( left.length - 1 ) !== "\\" ) {
     2700                                match[1] = (match[1] || "").replace(/\\/g, "");
     2701                                set = Expr.find[ type ]( match, context, isXML );
     2702                                if ( set != null ) {
     2703                                        expr = expr.replace( Expr.match[ type ], "" );
     2704                                        break;
     2705                                }
     2706                        }
     2707                }
     2708        }
     2709
     2710        if ( !set ) {
     2711                set = context.getElementsByTagName("*");
     2712        }
     2713
     2714        return {set: set, expr: expr};
     2715};
     2716
     2717Sizzle.filter = function(expr, set, inplace, not){
     2718        var old = expr, result = [], curLoop = set, match, anyFound,
     2719                isXMLFilter = set && set[0] && isXML(set[0]);
     2720
     2721        while ( expr && set.length ) {
     2722                for ( var type in Expr.filter ) {
     2723                        if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
     2724                                var filter = Expr.filter[ type ], found, item, left = match[1];
     2725                                anyFound = false;
     2726
     2727                                match.splice(1,1);
     2728
     2729                                if ( left.substr( left.length - 1 ) === "\\" ) {
     2730                                        continue;
     2731                                }
     2732
     2733                                if ( curLoop === result ) {
     2734                                        result = [];
     2735                                }
     2736
     2737                                if ( Expr.preFilter[ type ] ) {
     2738                                        match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
     2739
     2740                                        if ( !match ) {
     2741                                                anyFound = found = true;
     2742                                        } else if ( match === true ) {
     2743                                                continue;
     2744                                        }
     2745                                }
     2746
     2747                                if ( match ) {
     2748                                        for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
     2749                                                if ( item ) {
     2750                                                        found = filter( item, match, i, curLoop );
     2751                                                        var pass = not ^ !!found;
     2752
     2753                                                        if ( inplace && found != null ) {
     2754                                                                if ( pass ) {
     2755                                                                        anyFound = true;
     2756                                                                } else {
     2757                                                                        curLoop[i] = false;
     2758                                                                }
     2759                                                        } else if ( pass ) {
     2760                                                                result.push( item );
     2761                                                                anyFound = true;
     2762                                                        }
     2763                                                }
     2764                                        }
     2765                                }
     2766
     2767                                if ( found !== undefined ) {
     2768                                        if ( !inplace ) {
     2769                                                curLoop = result;
     2770                                        }
     2771
     2772                                        expr = expr.replace( Expr.match[ type ], "" );
     2773
     2774                                        if ( !anyFound ) {
     2775                                                return [];
     2776                                        }
     2777
     2778                                        break;
     2779                                }
     2780                        }
     2781                }
     2782
     2783                // Improper expression
     2784                if ( expr === old ) {
     2785                        if ( anyFound == null ) {
     2786                                Sizzle.error( expr );
     2787                        } else {
     2788                                break;
     2789                        }
     2790                }
     2791
     2792                old = expr;
     2793        }
     2794
     2795        return curLoop;
     2796};
     2797
     2798Sizzle.error = function( msg ) {
     2799        throw "Syntax error, unrecognized expression: " + msg;
     2800};
     2801
     2802var Expr = Sizzle.selectors = {
     2803        order: [ "ID", "NAME", "TAG" ],
     2804        match: {
     2805                ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
     2806                CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
     2807                NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
     2808                ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
     2809                TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
     2810                CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
     2811                POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
     2812                PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
     2813        },
     2814        leftMatch: {},
     2815        attrMap: {
     2816                "class": "className",
     2817                "for": "htmlFor"
     2818        },
     2819        attrHandle: {
     2820                href: function(elem){
     2821                        return elem.getAttribute("href");
     2822                }
     2823        },
     2824        relative: {
     2825                "+": function(checkSet, part){
     2826                        var isPartStr = typeof part === "string",
     2827                                isTag = isPartStr && !/\W/.test(part),
     2828                                isPartStrNotTag = isPartStr && !isTag;
     2829
     2830                        if ( isTag ) {
     2831                                part = part.toLowerCase();
     2832                        }
     2833
     2834                        for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
     2835                                if ( (elem = checkSet[i]) ) {
     2836                                        while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
     2837
     2838                                        checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
     2839                                                elem || false :
     2840                                                elem === part;
     2841                                }
     2842                        }
     2843
     2844                        if ( isPartStrNotTag ) {
     2845                                Sizzle.filter( part, checkSet, true );
     2846                        }
     2847                },
     2848                ">": function(checkSet, part){
     2849                        var isPartStr = typeof part === "string";
     2850
     2851                        if ( isPartStr && !/\W/.test(part) ) {
     2852                                part = part.toLowerCase();
     2853
     2854                                for ( var i = 0, l = checkSet.length; i < l; i++ ) {
     2855                                        var elem = checkSet[i];
     2856                                        if ( elem ) {
     2857                                                var parent = elem.parentNode;
     2858                                                checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
     2859                                        }
     2860                                }
     2861                        } else {
     2862                                for ( var i = 0, l = checkSet.length; i < l; i++ ) {
     2863                                        var elem = checkSet[i];
     2864                                        if ( elem ) {
     2865                                                checkSet[i] = isPartStr ?
     2866                                                        elem.parentNode :
     2867                                                        elem.parentNode === part;
     2868                                        }
     2869                                }
     2870
     2871                                if ( isPartStr ) {
     2872                                        Sizzle.filter( part, checkSet, true );
     2873                                }
     2874                        }
     2875                },
     2876                "": function(checkSet, part, isXML){
     2877                        var doneName = done++, checkFn = dirCheck;
     2878
     2879                        if ( typeof part === "string" && !/\W/.test(part) ) {
     2880                                var nodeCheck = part = part.toLowerCase();
     2881                                checkFn = dirNodeCheck;
     2882                        }
     2883
     2884                        checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
     2885                },
     2886                "~": function(checkSet, part, isXML){
     2887                        var doneName = done++, checkFn = dirCheck;
     2888
     2889                        if ( typeof part === "string" && !/\W/.test(part) ) {
     2890                                var nodeCheck = part = part.toLowerCase();
     2891                                checkFn = dirNodeCheck;
     2892                        }
     2893
     2894                        checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
     2895                }
     2896        },
     2897        find: {
     2898                ID: function(match, context, isXML){
     2899                        if ( typeof context.getElementById !== "undefined" && !isXML ) {
     2900                                var m = context.getElementById(match[1]);
     2901                                return m ? [m] : [];
     2902                        }
     2903                },
     2904                NAME: function(match, context){
     2905                        if ( typeof context.getElementsByName !== "undefined" ) {
     2906                                var ret = [], results = context.getElementsByName(match[1]);
     2907
     2908                                for ( var i = 0, l = results.length; i < l; i++ ) {
     2909                                        if ( results[i].getAttribute("name") === match[1] ) {
     2910                                                ret.push( results[i] );
     2911                                        }
     2912                                }
     2913
     2914                                return ret.length === 0 ? null : ret;
     2915                        }
     2916                },
     2917                TAG: function(match, context){
     2918                        return context.getElementsByTagName(match[1]);
     2919                }
     2920        },
     2921        preFilter: {
     2922                CLASS: function(match, curLoop, inplace, result, not, isXML){
     2923                        match = " " + match[1].replace(/\\/g, "") + " ";
     2924
     2925                        if ( isXML ) {
     2926                                return match;
     2927                        }
     2928
     2929                        for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
     2930                                if ( elem ) {
     2931                                        if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
     2932                                                if ( !inplace ) {
     2933                                                        result.push( elem );
     2934                                                }
     2935                                        } else if ( inplace ) {
     2936                                                curLoop[i] = false;
     2937                                        }
     2938                                }
     2939                        }
     2940
     2941                        return false;
     2942                },
     2943                ID: function(match){
     2944                        return match[1].replace(/\\/g, "");
     2945                },
     2946                TAG: function(match, curLoop){
     2947                        return match[1].toLowerCase();
     2948                },
     2949                CHILD: function(match){
     2950                        if ( match[1] === "nth" ) {
     2951                                // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
     2952                                var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
     2953                                        match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
     2954                                        !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
     2955
     2956                                // calculate the numbers (first)n+(last) including if they are negative
     2957                                match[2] = (test[1] + (test[2] || 1)) - 0;
     2958                                match[3] = test[3] - 0;
     2959                        }
     2960
     2961                        // TODO: Move to normal caching system
     2962                        match[0] = done++;
     2963
     2964                        return match;
     2965                },
     2966                ATTR: function(match, curLoop, inplace, result, not, isXML){
     2967                        var name = match[1].replace(/\\/g, "");
     2968                       
     2969                        if ( !isXML && Expr.attrMap[name] ) {
     2970                                match[1] = Expr.attrMap[name];
     2971                        }
     2972
     2973                        if ( match[2] === "~=" ) {
     2974                                match[4] = " " + match[4] + " ";
     2975                        }
     2976
     2977                        return match;
     2978                },
     2979                PSEUDO: function(match, curLoop, inplace, result, not){
     2980                        if ( match[1] === "not" ) {
     2981                                // If we're dealing with a complex expression, or a simple one
     2982                                if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
     2983                                        match[3] = Sizzle(match[3], null, null, curLoop);
     2984                                } else {
     2985                                        var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
     2986                                        if ( !inplace ) {
     2987                                                result.push.apply( result, ret );
     2988                                        }
     2989                                        return false;
     2990                                }
     2991                        } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
     2992                                return true;
     2993                        }
     2994                       
     2995                        return match;
     2996                },
     2997                POS: function(match){
     2998                        match.unshift( true );
     2999                        return match;
     3000                }
     3001        },
     3002        filters: {
     3003                enabled: function(elem){
     3004                        return elem.disabled === false && elem.type !== "hidden";
     3005                },
     3006                disabled: function(elem){
     3007                        return elem.disabled === true;
     3008                },
     3009                checked: function(elem){
     3010                        return elem.checked === true;
     3011                },
     3012                selected: function(elem){
     3013                        // Accessing this property makes selected-by-default
     3014                        // options in Safari work properly
     3015                        elem.parentNode.selectedIndex;
     3016                        return elem.selected === true;
     3017                },
     3018                parent: function(elem){
     3019                        return !!elem.firstChild;
     3020                },
     3021                empty: function(elem){
     3022                        return !elem.firstChild;
     3023                },
     3024                has: function(elem, i, match){
     3025                        return !!Sizzle( match[3], elem ).length;
     3026                },
     3027                header: function(elem){
     3028                        return /h\d/i.test( elem.nodeName );
     3029                },
     3030                text: function(elem){
     3031                        return "text" === elem.type;
     3032                },
     3033                radio: function(elem){
     3034                        return "radio" === elem.type;
     3035                },
     3036                checkbox: function(elem){
     3037                        return "checkbox" === elem.type;
     3038                },
     3039                file: function(elem){
     3040                        return "file" === elem.type;
     3041                },
     3042                password: function(elem){
     3043                        return "password" === elem.type;
     3044                },
     3045                submit: function(elem){
     3046                        return "submit" === elem.type;
     3047                },
     3048                image: function(elem){
     3049                        return "image" === elem.type;
     3050                },
     3051                reset: function(elem){
     3052                        return "reset" === elem.type;
     3053                },
     3054                button: function(elem){
     3055                        return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
     3056                },
     3057                input: function(elem){
     3058                        return /input|select|textarea|button/i.test(elem.nodeName);
     3059                }
     3060        },
     3061        setFilters: {
     3062                first: function(elem, i){
     3063                        return i === 0;
     3064                },
     3065                last: function(elem, i, match, array){
     3066                        return i === array.length - 1;
     3067                },
     3068                even: function(elem, i){
     3069                        return i % 2 === 0;
     3070                },
     3071                odd: function(elem, i){
     3072                        return i % 2 === 1;
     3073                },
     3074                lt: function(elem, i, match){
     3075                        return i < match[3] - 0;
     3076                },
     3077                gt: function(elem, i, match){
     3078                        return i > match[3] - 0;
     3079                },
     3080                nth: function(elem, i, match){
     3081                        return match[3] - 0 === i;
     3082                },
     3083                eq: function(elem, i, match){
     3084                        return match[3] - 0 === i;
     3085                }
     3086        },
     3087        filter: {
     3088                PSEUDO: function(elem, match, i, array){
     3089                        var name = match[1], filter = Expr.filters[ name ];
     3090
     3091                        if ( filter ) {
     3092                                return filter( elem, i, match, array );
     3093                        } else if ( name === "contains" ) {
     3094                                return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;
     3095                        } else if ( name === "not" ) {
     3096                                var not = match[3];
     3097
     3098                                for ( var i = 0, l = not.length; i < l; i++ ) {
     3099                                        if ( not[i] === elem ) {
     3100                                                return false;
     3101                                        }
     3102                                }
     3103
     3104                                return true;
     3105                        } else {
     3106                                Sizzle.error( "Syntax error, unrecognized expression: " + name );
     3107                        }
     3108                },
     3109                CHILD: function(elem, match){
     3110                        var type = match[1], node = elem;
     3111                        switch (type) {
     3112                                case 'only':
     3113                                case 'first':
     3114                                        while ( (node = node.previousSibling) )  {
     3115                                                if ( node.nodeType === 1 ) {
     3116                                                        return false;
     3117                                                }
     3118                                        }
     3119                                        if ( type === "first" ) {
     3120                                                return true;
     3121                                        }
     3122                                        node = elem;
     3123                                case 'last':
     3124                                        while ( (node = node.nextSibling) )      {
     3125                                                if ( node.nodeType === 1 ) {
     3126                                                        return false;
     3127                                                }
     3128                                        }
     3129                                        return true;
     3130                                case 'nth':
     3131                                        var first = match[2], last = match[3];
     3132
     3133                                        if ( first === 1 && last === 0 ) {
     3134                                                return true;
     3135                                        }
     3136                                       
     3137                                        var doneName = match[0],
     3138                                                parent = elem.parentNode;
     3139       
     3140                                        if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
     3141                                                var count = 0;
     3142                                                for ( node = parent.firstChild; node; node = node.nextSibling ) {
     3143                                                        if ( node.nodeType === 1 ) {
     3144                                                                node.nodeIndex = ++count;
     3145                                                        }
     3146                                                }
     3147                                                parent.sizcache = doneName;
     3148                                        }
     3149                                       
     3150                                        var diff = elem.nodeIndex - last;
     3151                                        if ( first === 0 ) {
     3152                                                return diff === 0;
     3153                                        } else {
     3154                                                return ( diff % first === 0 && diff / first >= 0 );
     3155                                        }
     3156                        }
     3157                },
     3158                ID: function(elem, match){
     3159                        return elem.nodeType === 1 && elem.getAttribute("id") === match;
     3160                },
     3161                TAG: function(elem, match){
     3162                        return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
     3163                },
     3164                CLASS: function(elem, match){
     3165                        return (" " + (elem.className || elem.getAttribute("class")) + " ")
     3166                                .indexOf( match ) > -1;
     3167                },
     3168                ATTR: function(elem, match){
     3169                        var name = match[1],
     3170                                result = Expr.attrHandle[ name ] ?
     3171                                        Expr.attrHandle[ name ]( elem ) :
     3172                                        elem[ name ] != null ?
     3173                                                elem[ name ] :
     3174                                                elem.getAttribute( name ),
     3175                                value = result + "",
     3176                                type = match[2],
     3177                                check = match[4];
     3178
     3179                        return result == null ?
     3180                                type === "!=" :
     3181                                type === "=" ?
     3182                                value === check :
     3183                                type === "*=" ?
     3184                                value.indexOf(check) >= 0 :
     3185                                type === "~=" ?
     3186                                (" " + value + " ").indexOf(check) >= 0 :
     3187                                !check ?
     3188                                value && result !== false :
     3189                                type === "!=" ?
     3190                                value !== check :
     3191                                type === "^=" ?
     3192                                value.indexOf(check) === 0 :
     3193                                type === "$=" ?
     3194                                value.substr(value.length - check.length) === check :
     3195                                type === "|=" ?
     3196                                value === check || value.substr(0, check.length + 1) === check + "-" :
     3197                                false;
     3198                },
     3199                POS: function(elem, match, i, array){
     3200                        var name = match[2], filter = Expr.setFilters[ name ];
     3201
     3202                        if ( filter ) {
     3203                                return filter( elem, i, match, array );
     3204                        }
     3205                }
     3206        }
     3207};
     3208
     3209var origPOS = Expr.match.POS;
     3210
     3211for ( var type in Expr.match ) {
     3212        Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
     3213        Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, function(all, num){
     3214                return "\\" + (num - 0 + 1);
     3215        }));
     3216}
     3217
     3218var makeArray = function(array, results) {
     3219        array = Array.prototype.slice.call( array, 0 );
     3220
     3221        if ( results ) {
     3222                results.push.apply( results, array );
     3223                return results;
     3224        }
     3225       
     3226        return array;
     3227};
     3228
     3229// Perform a simple check to determine if the browser is capable of
     3230// converting a NodeList to an array using builtin methods.
     3231try {
     3232        Array.prototype.slice.call( document.documentElement.childNodes, 0 );
     3233
     3234// Provide a fallback method if it does not work
     3235} catch(e){
     3236        makeArray = function(array, results) {
     3237                var ret = results || [];
     3238
     3239                if ( toString.call(array) === "[object Array]" ) {
     3240                        Array.prototype.push.apply( ret, array );
     3241                } else {
     3242                        if ( typeof array.length === "number" ) {
     3243                                for ( var i = 0, l = array.length; i < l; i++ ) {
     3244                                        ret.push( array[i] );
     3245                                }
     3246                        } else {
     3247                                for ( var i = 0; array[i]; i++ ) {
     3248                                        ret.push( array[i] );
     3249                                }
     3250                        }
     3251                }
     3252
     3253                return ret;
     3254        };
     3255}
     3256
     3257var sortOrder;
     3258
     3259if ( document.documentElement.compareDocumentPosition ) {
     3260        sortOrder = function( a, b ) {
     3261                if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
     3262                        if ( a == b ) {
     3263                                hasDuplicate = true;
     3264                        }
     3265                        return a.compareDocumentPosition ? -1 : 1;
     3266                }
     3267
     3268                var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
     3269                if ( ret === 0 ) {
     3270                        hasDuplicate = true;
     3271                }
     3272                return ret;
     3273        };
     3274} else if ( "sourceIndex" in document.documentElement ) {
     3275        sortOrder = function( a, b ) {
     3276                if ( !a.sourceIndex || !b.sourceIndex ) {
     3277                        if ( a == b ) {
     3278                                hasDuplicate = true;
     3279                        }
     3280                        return a.sourceIndex ? -1 : 1;
     3281                }
     3282
     3283                var ret = a.sourceIndex - b.sourceIndex;
     3284                if ( ret === 0 ) {
     3285                        hasDuplicate = true;
     3286                }
     3287                return ret;
     3288        };
     3289} else if ( document.createRange ) {
     3290        sortOrder = function( a, b ) {
     3291                if ( !a.ownerDocument || !b.ownerDocument ) {
     3292                        if ( a == b ) {
     3293                                hasDuplicate = true;
     3294                        }
     3295                        return a.ownerDocument ? -1 : 1;
     3296                }
     3297
     3298                var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
     3299                aRange.setStart(a, 0);
     3300                aRange.setEnd(a, 0);
     3301                bRange.setStart(b, 0);
     3302                bRange.setEnd(b, 0);
     3303                var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
     3304                if ( ret === 0 ) {
     3305                        hasDuplicate = true;
     3306                }
     3307                return ret;
     3308        };
     3309}
     3310
     3311// Utility function for retreiving the text value of an array of DOM nodes
     3312function getText( elems ) {
     3313        var ret = "", elem;
     3314
     3315        for ( var i = 0; elems[i]; i++ ) {
     3316                elem = elems[i];
     3317
     3318                // Get the text from text nodes and CDATA nodes
     3319                if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
     3320                        ret += elem.nodeValue;
     3321
     3322                // Traverse everything else, except comment nodes
     3323                } else if ( elem.nodeType !== 8 ) {
     3324                        ret += getText( elem.childNodes );
     3325                }
     3326        }
     3327
     3328        return ret;
     3329}
     3330
     3331// Check to see if the browser returns elements by name when
     3332// querying by getElementById (and provide a workaround)
     3333(function(){
     3334        // We're going to inject a fake input element with a specified name
     3335        var form = document.createElement("div"),
     3336                id = "script" + (new Date).getTime();
     3337        form.innerHTML = "<a name='" + id + "'/>";
     3338
     3339        // Inject it into the root element, check its status, and remove it quickly
     3340        var root = document.documentElement;
     3341        root.insertBefore( form, root.firstChild );
     3342
     3343        // The workaround has to do additional checks after a getElementById
     3344        // Which slows things down for other browsers (hence the branching)
     3345        if ( document.getElementById( id ) ) {
     3346                Expr.find.ID = function(match, context, isXML){
     3347                        if ( typeof context.getElementById !== "undefined" && !isXML ) {
     3348                                var m = context.getElementById(match[1]);
     3349                                return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
     3350                        }
     3351                };
     3352
     3353                Expr.filter.ID = function(elem, match){
     3354                        var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
     3355                        return elem.nodeType === 1 && node && node.nodeValue === match;
     3356                };
     3357        }
     3358
     3359        root.removeChild( form );
     3360        root = form = null; // release memory in IE
     3361})();
     3362
     3363(function(){
     3364        // Check to see if the browser returns only elements
     3365        // when doing getElementsByTagName("*")
     3366
     3367        // Create a fake element
     3368        var div = document.createElement("div");
     3369        div.appendChild( document.createComment("") );
     3370
     3371        // Make sure no comments are found
     3372        if ( div.getElementsByTagName("*").length > 0 ) {
     3373                Expr.find.TAG = function(match, context){
     3374                        var results = context.getElementsByTagName(match[1]);
     3375
     3376                        // Filter out possible comments
     3377                        if ( match[1] === "*" ) {
     3378                                var tmp = [];
     3379
     3380                                for ( var i = 0; results[i]; i++ ) {
     3381                                        if ( results[i].nodeType === 1 ) {
     3382                                                tmp.push( results[i] );
     3383                                        }
     3384                                }
     3385
     3386                                results = tmp;
     3387                        }
     3388
     3389                        return results;
     3390                };
     3391        }
     3392
     3393        // Check to see if an attribute returns normalized href attributes
     3394        div.innerHTML = "<a href='#'></a>";
     3395        if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
     3396                        div.firstChild.getAttribute("href") !== "#" ) {
     3397                Expr.attrHandle.href = function(elem){
     3398                        return elem.getAttribute("href", 2);
     3399                };
     3400        }
     3401
     3402        div = null; // release memory in IE
     3403})();
     3404
     3405if ( document.querySelectorAll ) {
     3406        (function(){
     3407                var oldSizzle = Sizzle, div = document.createElement("div");
     3408                div.innerHTML = "<p class='TEST'></p>";
     3409
     3410                // Safari can't handle uppercase or unicode characters when
     3411                // in quirks mode.
     3412                if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
     3413                        return;
     3414                }
     3415       
     3416                Sizzle = function(query, context, extra, seed){
     3417                        context = context || document;
     3418
     3419                        // Only use querySelectorAll on non-XML documents
     3420                        // (ID selectors don't work in non-HTML documents)
     3421                        if ( !seed && context.nodeType === 9 && !isXML(context) ) {
     3422                                try {
     3423                                        return makeArray( context.querySelectorAll(query), extra );
     3424                                } catch(e){}
     3425                        }
     3426               
     3427                        return oldSizzle(query, context, extra, seed);
     3428                };
     3429
     3430                for ( var prop in oldSizzle ) {
     3431                        Sizzle[ prop ] = oldSizzle[ prop ];
     3432                }
     3433
     3434                div = null; // release memory in IE
     3435        })();
     3436}
     3437
     3438(function(){
     3439        var div = document.createElement("div");
     3440
     3441        div.innerHTML = "<div class='test e'></div><div class='test'></div>";
     3442
     3443        // Opera can't find a second classname (in 9.6)
     3444        // Also, make sure that getElementsByClassName actually exists
     3445        if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
     3446                return;
     3447        }
     3448
     3449        // Safari caches class attributes, doesn't catch changes (in 3.2)
     3450        div.lastChild.className = "e";
     3451
     3452        if ( div.getElementsByClassName("e").length === 1 ) {
     3453                return;
     3454        }
     3455       
     3456        Expr.order.splice(1, 0, "CLASS");
     3457        Expr.find.CLASS = function(match, context, isXML) {
     3458                if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
     3459                        return context.getElementsByClassName(match[1]);
     3460                }
     3461        };
     3462
     3463        div = null; // release memory in IE
     3464})();
     3465
     3466function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
     3467        for ( var i = 0, l = checkSet.length; i < l; i++ ) {
     3468                var elem = checkSet[i];
     3469                if ( elem ) {
     3470                        elem = elem[dir];
     3471                        var match = false;
     3472
     3473                        while ( elem ) {
     3474                                if ( elem.sizcache === doneName ) {
     3475                                        match = checkSet[elem.sizset];
     3476                                        break;
     3477                                }
     3478
     3479                                if ( elem.nodeType === 1 && !isXML ){
     3480                                        elem.sizcache = doneName;
     3481                                        elem.sizset = i;
     3482                                }
     3483
     3484                                if ( elem.nodeName.toLowerCase() === cur ) {
     3485                                        match = elem;
     3486                                        break;
     3487                                }
     3488
     3489                                elem = elem[dir];
     3490                        }
     3491
     3492                        checkSet[i] = match;
     3493                }
     3494        }
     3495}
     3496
     3497function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
     3498        for ( var i = 0, l = checkSet.length; i < l; i++ ) {
     3499                var elem = checkSet[i];
     3500                if ( elem ) {
     3501                        elem = elem[dir];
     3502                        var match = false;
     3503
     3504                        while ( elem ) {
     3505                                if ( elem.sizcache === doneName ) {
     3506                                        match = checkSet[elem.sizset];
     3507                                        break;
     3508                                }
     3509
     3510                                if ( elem.nodeType === 1 ) {
     3511                                        if ( !isXML ) {
     3512                                                elem.sizcache = doneName;
     3513                                                elem.sizset = i;
     3514                                        }
     3515                                        if ( typeof cur !== "string" ) {
     3516                                                if ( elem === cur ) {
     3517                                                        match = true;
     3518                                                        break;
     3519                                                }
     3520
     3521                                        } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
     3522                                                match = elem;
     3523                                                break;
     3524                                        }
     3525                                }
     3526
     3527                                elem = elem[dir];
     3528                        }
     3529
     3530                        checkSet[i] = match;
     3531                }
     3532        }
     3533}
     3534
     3535var contains = document.compareDocumentPosition ? function(a, b){
     3536        return a.compareDocumentPosition(b) & 16;
     3537} : function(a, b){
     3538        return a !== b && (a.contains ? a.contains(b) : true);
     3539};
     3540
     3541var isXML = function(elem){
     3542        // documentElement is verified for cases where it doesn't yet exist
     3543        // (such as loading iframes in IE - #4833)
     3544        var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
     3545        return documentElement ? documentElement.nodeName !== "HTML" : false;
     3546};
     3547
     3548var posProcess = function(selector, context){
     3549        var tmpSet = [], later = "", match,
     3550                root = context.nodeType ? [context] : context;
     3551
     3552        // Position selectors must be done after the filter
     3553        // And so must :not(positional) so we move all PSEUDOs to the end
     3554        while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
     3555                later += match[0];
     3556                selector = selector.replace( Expr.match.PSEUDO, "" );
     3557        }
     3558
     3559        selector = Expr.relative[selector] ? selector + "*" : selector;
     3560
     3561        for ( var i = 0, l = root.length; i < l; i++ ) {
     3562                Sizzle( selector, root[i], tmpSet );
     3563        }
     3564
     3565        return Sizzle.filter( later, tmpSet );
     3566};
     3567
     3568// EXPOSE
     3569jQuery.find = Sizzle;
     3570jQuery.expr = Sizzle.selectors;
     3571jQuery.expr[":"] = jQuery.expr.filters;
     3572jQuery.unique = Sizzle.uniqueSort;
     3573jQuery.getText = getText;
     3574jQuery.isXMLDoc = isXML;
     3575jQuery.contains = contains;
     3576
     3577return;
     3578
     3579window.Sizzle = Sizzle;
     3580
     3581})();
     3582var runtil = /Until$/,
     3583        rparentsprev = /^(?:parents|prevUntil|prevAll)/,
     3584        // Note: This RegExp should be improved, or likely pulled from Sizzle
     3585        rmultiselector = /,/,
     3586        slice = Array.prototype.slice;
     3587
     3588// Implement the identical functionality for filter and not
     3589var winnow = function( elements, qualifier, keep ) {
     3590        if ( jQuery.isFunction( qualifier ) ) {
     3591                return jQuery.grep(elements, function( elem, i ) {
     3592                        return !!qualifier.call( elem, i, elem ) === keep;
     3593                });
     3594
     3595        } else if ( qualifier.nodeType ) {
     3596                return jQuery.grep(elements, function( elem, i ) {
     3597                        return (elem === qualifier) === keep;
     3598                });
     3599
     3600        } else if ( typeof qualifier === "string" ) {
     3601                var filtered = jQuery.grep(elements, function( elem ) {
     3602                        return elem.nodeType === 1;
     3603                });
     3604
     3605                if ( isSimple.test( qualifier ) ) {
     3606                        return jQuery.filter(qualifier, filtered, !keep);
     3607                } else {
     3608                        qualifier = jQuery.filter( qualifier, filtered );
     3609                }
     3610        }
     3611
     3612        return jQuery.grep(elements, function( elem, i ) {
     3613                return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
     3614        });
     3615};
     3616
     3617jQuery.fn.extend({
     3618        find: function( selector ) {
     3619                var ret = this.pushStack( "", "find", selector ), length = 0;
     3620
     3621                for ( var i = 0, l = this.length; i < l; i++ ) {
     3622                        length = ret.length;
     3623                        jQuery.find( selector, this[i], ret );
     3624
     3625                        if ( i > 0 ) {
     3626                                // Make sure that the results are unique
     3627                                for ( var n = length; n < ret.length; n++ ) {
     3628                                        for ( var r = 0; r < length; r++ ) {
     3629                                                if ( ret[r] === ret[n] ) {
     3630                                                        ret.splice(n--, 1);
     3631                                                        break;
     3632                                                }
     3633                                        }
     3634                                }
     3635                        }
     3636                }
     3637
     3638                return ret;
     3639        },
     3640
     3641        has: function( target ) {
     3642                var targets = jQuery( target );
     3643                return this.filter(function() {
     3644                        for ( var i = 0, l = targets.length; i < l; i++ ) {
     3645                                if ( jQuery.contains( this, targets[i] ) ) {
     3646                                        return true;
     3647                                }
     3648                        }
     3649                });
     3650        },
     3651
     3652        not: function( selector ) {
     3653                return this.pushStack( winnow(this, selector, false), "not", selector);
     3654        },
     3655
     3656        filter: function( selector ) {
     3657                return this.pushStack( winnow(this, selector, true), "filter", selector );
     3658        },
     3659       
     3660        is: function( selector ) {
     3661                return !!selector && jQuery.filter( selector, this ).length > 0;
     3662        },
     3663
     3664        closest: function( selectors, context ) {
     3665                if ( jQuery.isArray( selectors ) ) {
     3666                        var ret = [], cur = this[0], match, matches = {}, selector;
     3667
     3668                        if ( cur && selectors.length ) {
     3669                                for ( var i = 0, l = selectors.length; i < l; i++ ) {
     3670                                        selector = selectors[i];
     3671
     3672                                        if ( !matches[selector] ) {
     3673                                                matches[selector] = jQuery.expr.match.POS.test( selector ) ?
     3674                                                        jQuery( selector, context || this.context ) :
     3675                                                        selector;
     3676                                        }
     3677                                }
     3678
     3679                                while ( cur && cur.ownerDocument && cur !== context ) {
     3680                                        for ( selector in matches ) {
     3681                                                match = matches[selector];
     3682
     3683                                                if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
     3684                                                        ret.push({ selector: selector, elem: cur });
     3685                                                        delete matches[selector];
     3686                                                }
     3687                                        }
     3688                                        cur = cur.parentNode;
     3689                                }
     3690                        }
     3691
     3692                        return ret;
     3693                }
     3694
     3695                var pos = jQuery.expr.match.POS.test( selectors ) ?
     3696                        jQuery( selectors, context || this.context ) : null;
     3697
     3698                return this.map(function( i, cur ) {
     3699                        while ( cur && cur.ownerDocument && cur !== context ) {
     3700                                if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selectors) ) {
     3701                                        return cur;
     3702                                }
     3703                                cur = cur.parentNode;
     3704                        }
     3705                        return null;
     3706                });
     3707        },
     3708       
    1413709        // Determine the position of an element within
    1423710        // the matched set of elements
    1433711        index: function( elem ) {
    144                 var ret = -1;
    145 
     3712                if ( !elem || typeof elem === "string" ) {
     3713                        return jQuery.inArray( this[0],
     3714                                // If it receives a string, the selector is used
     3715                                // If it receives nothing, the siblings are used
     3716                                elem ? jQuery( elem ) : this.parent().children() );
     3717                }
    1463718                // Locate the position of the desired element
    1473719                return jQuery.inArray(
    1483720                        // If it receives a jQuery object, the first element is used
    149                         elem && elem.jquery ? elem[0] : elem
    150                 , this );
    151         },
    152 
    153         attr: function( name, value, type ) {
    154                 var options = name;
    155 
    156                 // Look for the case where we're accessing a style value
    157                 if ( name.constructor == String )
    158                         if ( value === undefined )
    159                                 return this[0] && jQuery[ type || "attr" ]( this[0], name );
    160 
    161                         else {
    162                                 options = {};
    163                                 options[ name ] = value;
    164                         }
    165 
    166                 // Check to see if we're setting style values
    167                 return this.each(function(i){
    168                         // Set all the styles
    169                         for ( name in options )
    170                                 jQuery.attr(
    171                                         type ?
    172                                                 this.style :
    173                                                 this,
    174                                         name, jQuery.prop( this, options[ name ], type, i, name )
    175                                 );
     3721                        elem.jquery ? elem[0] : elem, this );
     3722        },
     3723
     3724        add: function( selector, context ) {
     3725                var set = typeof selector === "string" ?
     3726                                jQuery( selector, context || this.context ) :
     3727                                jQuery.makeArray( selector ),
     3728                        all = jQuery.merge( this.get(), set );
     3729
     3730                return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
     3731                        all :
     3732                        jQuery.unique( all ) );
     3733        },
     3734
     3735        andSelf: function() {
     3736                return this.add( this.prevObject );
     3737        }
     3738});
     3739
     3740// A painfully simple check to see if an element is disconnected
     3741// from a document (should be improved, where feasible).
     3742function isDisconnected( node ) {
     3743        return !node || !node.parentNode || node.parentNode.nodeType === 11;
     3744}
     3745
     3746jQuery.each({
     3747        parent: function( elem ) {
     3748                var parent = elem.parentNode;
     3749                return parent && parent.nodeType !== 11 ? parent : null;
     3750        },
     3751        parents: function( elem ) {
     3752                return jQuery.dir( elem, "parentNode" );
     3753        },
     3754        parentsUntil: function( elem, i, until ) {
     3755                return jQuery.dir( elem, "parentNode", until );
     3756        },
     3757        next: function( elem ) {
     3758                return jQuery.nth( elem, 2, "nextSibling" );
     3759        },
     3760        prev: function( elem ) {
     3761                return jQuery.nth( elem, 2, "previousSibling" );
     3762        },
     3763        nextAll: function( elem ) {
     3764                return jQuery.dir( elem, "nextSibling" );
     3765        },
     3766        prevAll: function( elem ) {
     3767                return jQuery.dir( elem, "previousSibling" );
     3768        },
     3769        nextUntil: function( elem, i, until ) {
     3770                return jQuery.dir( elem, "nextSibling", until );
     3771        },
     3772        prevUntil: function( elem, i, until ) {
     3773                return jQuery.dir( elem, "previousSibling", until );
     3774        },
     3775        siblings: function( elem ) {
     3776                return jQuery.sibling( elem.parentNode.firstChild, elem );
     3777        },
     3778        children: function( elem ) {
     3779                return jQuery.sibling( elem.firstChild );
     3780        },
     3781        contents: function( elem ) {
     3782                return jQuery.nodeName( elem, "iframe" ) ?
     3783                        elem.contentDocument || elem.contentWindow.document :
     3784                        jQuery.makeArray( elem.childNodes );
     3785        }
     3786}, function( name, fn ) {
     3787        jQuery.fn[ name ] = function( until, selector ) {
     3788                var ret = jQuery.map( this, fn, until );
     3789               
     3790                if ( !runtil.test( name ) ) {
     3791                        selector = until;
     3792                }
     3793
     3794                if ( selector && typeof selector === "string" ) {
     3795                        ret = jQuery.filter( selector, ret );
     3796                }
     3797
     3798                ret = this.length > 1 ? jQuery.unique( ret ) : ret;
     3799
     3800                if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
     3801                        ret = ret.reverse();
     3802                }
     3803
     3804                return this.pushStack( ret, name, slice.call(arguments).join(",") );
     3805        };
     3806});
     3807
     3808jQuery.extend({
     3809        filter: function( expr, elems, not ) {
     3810                if ( not ) {
     3811                        expr = ":not(" + expr + ")";
     3812                }
     3813
     3814                return jQuery.find.matches(expr, elems);
     3815        },
     3816       
     3817        dir: function( elem, dir, until ) {
     3818                var matched = [], cur = elem[dir];
     3819                while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
     3820                        if ( cur.nodeType === 1 ) {
     3821                                matched.push( cur );
     3822                        }
     3823                        cur = cur[dir];
     3824                }
     3825                return matched;
     3826        },
     3827
     3828        nth: function( cur, result, dir, elem ) {
     3829                result = result || 1;
     3830                var num = 0;
     3831
     3832                for ( ; cur; cur = cur[dir] ) {
     3833                        if ( cur.nodeType === 1 && ++num === result ) {
     3834                                break;
     3835                        }
     3836                }
     3837
     3838                return cur;
     3839        },
     3840
     3841        sibling: function( n, elem ) {
     3842                var r = [];
     3843
     3844                for ( ; n; n = n.nextSibling ) {
     3845                        if ( n.nodeType === 1 && n !== elem ) {
     3846                                r.push( n );
     3847                        }
     3848                }
     3849
     3850                return r;
     3851        }
     3852});
     3853var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
     3854        rleadingWhitespace = /^\s+/,
     3855        rxhtmlTag = /(<([\w:]+)[^>]*?)\/>/g,
     3856        rselfClosing = /^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,
     3857        rtagName = /<([\w:]+)/,
     3858        rtbody = /<tbody/i,
     3859        rhtml = /<|&\w+;/,
     3860        rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,  // checked="checked" or checked (html5)
     3861        fcloseTag = function( all, front, tag ) {
     3862                return rselfClosing.test( tag ) ?
     3863                        all :
     3864                        front + "></" + tag + ">";
     3865        },
     3866        wrapMap = {
     3867                option: [ 1, "<select multiple='multiple'>", "</select>" ],
     3868                legend: [ 1, "<fieldset>", "</fieldset>" ],
     3869                thead: [ 1, "<table>", "</table>" ],
     3870                tr: [ 2, "<table><tbody>", "</tbody></table>" ],
     3871                td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
     3872                col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
     3873                area: [ 1, "<map>", "</map>" ],
     3874                _default: [ 0, "", "" ]
     3875        };
     3876
     3877wrapMap.optgroup = wrapMap.option;
     3878wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
     3879wrapMap.th = wrapMap.td;
     3880
     3881// IE can't serialize <link> and <script> tags normally
     3882if ( !jQuery.support.htmlSerialize ) {
     3883        wrapMap._default = [ 1, "div<div>", "</div>" ];
     3884}
     3885
     3886jQuery.fn.extend({
     3887        text: function( text ) {
     3888                if ( jQuery.isFunction(text) ) {
     3889                        return this.each(function(i) {
     3890                                var self = jQuery(this);
     3891                                self.text( text.call(this, i, self.text()) );
     3892                        });
     3893                }
     3894
     3895                if ( typeof text !== "object" && text !== undefined ) {
     3896                        return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
     3897                }
     3898
     3899                return jQuery.getText( this );
     3900        },
     3901
     3902        wrapAll: function( html ) {
     3903                if ( jQuery.isFunction( html ) ) {
     3904                        return this.each(function(i) {
     3905                                jQuery(this).wrapAll( html.call(this, i) );
     3906                        });
     3907                }
     3908
     3909                if ( this[0] ) {
     3910                        // The elements to wrap the target around
     3911                        var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
     3912
     3913                        if ( this[0].parentNode ) {
     3914                                wrap.insertBefore( this[0] );
     3915                        }
     3916
     3917                        wrap.map(function() {
     3918                                var elem = this;
     3919
     3920                                while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
     3921                                        elem = elem.firstChild;
     3922                                }
     3923
     3924                                return elem;
     3925                        }).append(this);
     3926                }
     3927
     3928                return this;
     3929        },
     3930
     3931        wrapInner: function( html ) {
     3932                if ( jQuery.isFunction( html ) ) {
     3933                        return this.each(function(i) {
     3934                                jQuery(this).wrapInner( html.call(this, i) );
     3935                        });
     3936                }
     3937
     3938                return this.each(function() {
     3939                        var self = jQuery( this ), contents = self.contents();
     3940
     3941                        if ( contents.length ) {
     3942                                contents.wrapAll( html );
     3943
     3944                        } else {
     3945                                self.append( html );
     3946                        }
    1763947                });
    1773948        },
    1783949
    179         css: function( key, value ) {
    180                 // ignore negative width and height values
    181                 if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
    182                         value = undefined;
    183                 return this.attr( key, value, "curCSS" );
    184         },
    185 
    186         text: function( text ) {
    187                 if ( typeof text != "object" && text != null )
    188                         return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
    189 
    190                 var ret = "";
    191 
    192                 jQuery.each( text || this, function(){
    193                         jQuery.each( this.childNodes, function(){
    194                                 if ( this.nodeType != 8 )
    195                                         ret += this.nodeType != 1 ?
    196                                                 this.nodeValue :
    197                                                 jQuery.fn.text( [ this ] );
    198                         });
    199                 });
    200 
    201                 return ret;
    202         },
    203 
    204         wrapAll: function( html ) {
    205                 if ( this[0] )
    206                         // The elements to wrap the target around
    207                         jQuery( html, this[0].ownerDocument )
    208                                 .clone()
    209                                 .insertBefore( this[0] )
    210                                 .map(function(){
    211                                         var elem = this;
    212 
    213                                         while ( elem.firstChild )
    214                                                 elem = elem.firstChild;
    215 
    216                                         return elem;
    217                                 })
    218                                 .append(this);
    219 
    220                 return this;
    221         },
    222 
    223         wrapInner: function( html ) {
    224                 return this.each(function(){
    225                         jQuery( this ).contents().wrapAll( html );
    226                 });
    227         },
    228 
    2293950        wrap: function( html ) {
    230                 return this.each(function(){
     3951                return this.each(function() {
    2313952                        jQuery( this ).wrapAll( html );
    2323953                });
    2333954        },
    2343955
     3956        unwrap: function() {
     3957                return this.parent().each(function() {
     3958                        if ( !jQuery.nodeName( this, "body" ) ) {
     3959                                jQuery( this ).replaceWith( this.childNodes );
     3960                        }
     3961                }).end();
     3962        },
     3963
    2353964        append: function() {
    236                 return this.domManip(arguments, true, false, function(elem){
    237                         if (this.nodeType == 1)
     3965                return this.domManip(arguments, true, function( elem ) {
     3966                        if ( this.nodeType === 1 ) {
    2383967                                this.appendChild( elem );
     3968                        }
    2393969                });
    2403970        },
    2413971
    2423972        prepend: function() {
    243                 return this.domManip(arguments, true, true, function(elem){
    244                         if (this.nodeType == 1)
     3973                return this.domManip(arguments, true, function( elem ) {
     3974                        if ( this.nodeType === 1 ) {
    2453975                                this.insertBefore( elem, this.firstChild );
     3976                        }
    2463977                });
    2473978        },
    2483979
    2493980        before: function() {
    250                 return this.domManip(arguments, false, false, function(elem){
    251                         this.parentNode.insertBefore( elem, this );
    252                 });
     3981                if ( this[0] && this[0].parentNode ) {
     3982                        return this.domManip(arguments, false, function( elem ) {
     3983                                this.parentNode.insertBefore( elem, this );
     3984                        });
     3985                } else if ( arguments.length ) {
     3986                        var set = jQuery(arguments[0]);
     3987                        set.push.apply( set, this.toArray() );
     3988                        return this.pushStack( set, "before", arguments );
     3989                }
    2533990        },
    2543991
    2553992        after: function() {
    256                 return this.domManip(arguments, false, true, function(elem){
    257                         this.parentNode.insertBefore( elem, this.nextSibling );
    258                 });
    259         },
    260 
    261         end: function() {
    262                 return this.prevObject || jQuery( [] );
    263         },
    264 
    265         find: function( selector ) {
    266                 var elems = jQuery.map(this, function(elem){
    267                         return jQuery.find( selector, elem );
    268                 });
    269 
    270                 return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ?
    271                         jQuery.unique( elems ) :
    272                         elems );
     3993                if ( this[0] && this[0].parentNode ) {
     3994                        return this.domManip(arguments, false, function( elem ) {
     3995                                this.parentNode.insertBefore( elem, this.nextSibling );
     3996                        });
     3997                } else if ( arguments.length ) {
     3998                        var set = this.pushStack( this, "after", arguments );
     3999                        set.push.apply( set, jQuery(arguments[0]).toArray() );
     4000                        return set;
     4001                }
    2734002        },
    2744003
    2754004        clone: function( events ) {
    2764005                // Do the clone
    277                 var ret = this.map(function(){
    278                         if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) {
     4006                var ret = this.map(function() {
     4007                        if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
    2794008                                // IE copies events bound via attachEvent when
    2804009                                // using cloneNode. Calling detachEvent on the
     
    2854014                                // as properties will not be copied (such as the
    2864015                                // the name attribute on an input).
    287                                 var clone = this.cloneNode(true),
    288                                         container = document.createElement("div");
    289                                 container.appendChild(clone);
    290                                 return jQuery.clean([container.innerHTML])[0];
    291                         } else
     4016                                var html = this.outerHTML, ownerDocument = this.ownerDocument;
     4017                                if ( !html ) {
     4018                                        var div = ownerDocument.createElement("div");
     4019                                        div.appendChild( this.cloneNode(true) );
     4020                                        html = div.innerHTML;
     4021                                }
     4022
     4023                                return jQuery.clean([html.replace(rinlinejQuery, "")
     4024                                        .replace(rleadingWhitespace, "")], ownerDocument)[0];
     4025                        } else {
    2924026                                return this.cloneNode(true);
     4027                        }
    2934028                });
    2944029
    295                 // Need to set the expando to null on the cloned set if it exists
    296                 // removeData doesn't work here, IE removes it from the original as well
    297                 // this is primarily for IE but the data expando shouldn't be copied over in any browser
    298                 var clone = ret.find("*").andSelf().each(function(){
    299                         if ( this[ expando ] != undefined )
    300                                 this[ expando ] = null;
    301                 });
    302 
    3034030                // Copy the events from the original to the clone
    304                 if ( events === true )
    305                         this.find("*").andSelf().each(function(i){
    306                                 if (this.nodeType == 3)
    307                                         return;
    308                                 var events = jQuery.data( this, "events" );
    309 
    310                                 for ( var type in events )
    311                                         for ( var handler in events[ type ] )
    312                                                 jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );
    313                         });
     4031                if ( events === true ) {
     4032                        cloneCopyEvent( this, ret );
     4033                        cloneCopyEvent( this.find("*"), ret.find("*") );
     4034                }
    3144035
    3154036                // Return the cloned set
     
    3174038        },
    3184039
    319         filter: function( selector ) {
    320                 return this.pushStack(
    321                         jQuery.isFunction( selector ) &&
    322                         jQuery.grep(this, function(elem, i){
    323                                 return selector.call( elem, i );
    324                         }) ||
    325 
    326                         jQuery.multiFilter( selector, this ) );
    327         },
    328 
    329         not: function( selector ) {
    330                 if ( selector.constructor == String )
    331                         // test special case where just one selector is passed in
    332                         if ( isSimple.test( selector ) )
    333                                 return this.pushStack( jQuery.multiFilter( selector, this, true ) );
    334                         else
    335                                 selector = jQuery.multiFilter( selector, this );
    336 
    337                 var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
    338                 return this.filter(function() {
    339                         return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
    340                 });
    341         },
    342 
    343         add: function( selector ) {
    344                 return this.pushStack( jQuery.unique( jQuery.merge(
    345                         this.get(),
    346                         typeof selector == 'string' ?
    347                                 jQuery( selector ) :
    348                                 jQuery.makeArray( selector )
    349                 )));
    350         },
    351 
    352         is: function( selector ) {
    353                 return !!selector && jQuery.multiFilter( selector, this ).length > 0;
    354         },
    355 
    356         hasClass: function( selector ) {
    357                 return this.is( "." + selector );
    358         },
    359 
    360         val: function( value ) {
    361                 if ( value == undefined ) {
    362 
    363                         if ( this.length ) {
    364                                 var elem = this[0];
    365 
    366                                 // We need to handle select boxes special
    367                                 if ( jQuery.nodeName( elem, "select" ) ) {
    368                                         var index = elem.selectedIndex,
    369                                                 values = [],
    370                                                 options = elem.options,
    371                                                 one = elem.type == "select-one";
    372 
    373                                         // Nothing was selected
    374                                         if ( index < 0 )
    375                                                 return null;
    376 
    377                                         // Loop through all the selected options
    378                                         for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
    379                                                 var option = options[ i ];
    380 
    381                                                 if ( option.selected ) {
    382                                                         // Get the specifc value for the option
    383                                                         value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value;
    384 
    385                                                         // We don't need an array for one selects
    386                                                         if ( one )
    387                                                                 return value;
    388 
    389                                                         // Multi-Selects return an array
    390                                                         values.push( value );
    391                                                 }
     4040        html: function( value ) {
     4041                if ( value === undefined ) {
     4042                        return this[0] && this[0].nodeType === 1 ?
     4043                                this[0].innerHTML.replace(rinlinejQuery, "") :
     4044                                null;
     4045
     4046                // See if we can take a shortcut and just use innerHTML
     4047                } else if ( typeof value === "string" && !/<script/i.test( value ) &&
     4048                        (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
     4049                        !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
     4050
     4051                        value = value.replace(rxhtmlTag, fcloseTag);
     4052
     4053                        try {
     4054                                for ( var i = 0, l = this.length; i < l; i++ ) {
     4055                                        // Remove element nodes and prevent memory leaks
     4056                                        if ( this[i].nodeType === 1 ) {
     4057                                                jQuery.cleanData( this[i].getElementsByTagName("*") );
     4058                                                this[i].innerHTML = value;
    3924059                                        }
    393 
    394                                         return values;
    395 
    396                                 // Everything else, we just grab the value
    397                                 } else
    398                                         return (this[0].value || "").replace(/\r/g, "");
    399 
    400                         }
    401 
    402                         return undefined;
    403                 }
    404 
    405                 if( value.constructor == Number )
    406                         value += '';
    407 
    408                 return this.each(function(){
    409                         if ( this.nodeType != 1 )
    410                                 return;
    411 
    412                         if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )
    413                                 this.checked = (jQuery.inArray(this.value, value) >= 0 ||
    414                                         jQuery.inArray(this.name, value) >= 0);
    415 
    416                         else if ( jQuery.nodeName( this, "select" ) ) {
    417                                 var values = jQuery.makeArray(value);
    418 
    419                                 jQuery( "option", this ).each(function(){
    420                                         this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
    421                                                 jQuery.inArray( this.text, values ) >= 0);
     4060                                }
     4061
     4062                        // If using innerHTML throws an exception, use the fallback method
     4063                        } catch(e) {
     4064                                this.empty().append( value );
     4065                        }
     4066
     4067                } else if ( jQuery.isFunction( value ) ) {
     4068                        this.each(function(i){
     4069                                var self = jQuery(this), old = self.html();
     4070                                self.empty().append(function(){
     4071                                        return value.call( this, i, old );
    4224072                                });
    423 
    424                                 if ( !values.length )
    425                                         this.selectedIndex = -1;
    426 
    427                         } else
    428                                 this.value = value;
    429                 });
    430         },
    431 
    432         html: function( value ) {
    433                 return value == undefined ?
    434                         (this[0] ?
    435                                 this[0].innerHTML :
    436                                 null) :
     4073                        });
     4074
     4075                } else {
    4374076                        this.empty().append( value );
     4077                }
     4078
     4079                return this;
    4384080        },
    4394081
    4404082        replaceWith: function( value ) {
    441                 return this.after( value ).remove();
    442         },
    443 
    444         eq: function( i ) {
    445                 return this.slice( i, i + 1 );
    446         },
    447 
    448         slice: function() {
    449                 return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
    450         },
    451 
    452         map: function( callback ) {
    453                 return this.pushStack( jQuery.map(this, function(elem, i){
    454                         return callback.call( elem, i, elem );
    455                 }));
    456         },
    457 
    458         andSelf: function() {
    459                 return this.add( this.prevObject );
    460         },
    461 
    462         data: function( key, value ){
    463                 var parts = key.split(".");
    464                 parts[1] = parts[1] ? "." + parts[1] : "";
    465 
    466                 if ( value === undefined ) {
    467                         var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
    468 
    469                         if ( data === undefined && this.length )
    470                                 data = jQuery.data( this[0], key );
    471 
    472                         return data === undefined && parts[1] ?
    473                                 this.data( parts[0] ) :
    474                                 data;
    475                 } else
    476                         return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
    477                                 jQuery.data( this, key, value );
     4083                if ( this[0] && this[0].parentNode ) {
     4084                        // Make sure that the elements are removed from the DOM before they are inserted
     4085                        // this can help fix replacing a parent with child elements
     4086                        if ( !jQuery.isFunction( value ) ) {
     4087                                value = jQuery( value ).detach();
     4088
     4089                        } else {
     4090                                return this.each(function(i) {
     4091                                        var self = jQuery(this), old = self.html();
     4092                                        self.replaceWith( value.call( this, i, old ) );
     4093                                });
     4094                        }
     4095
     4096                        return this.each(function() {
     4097                                var next = this.nextSibling, parent = this.parentNode;
     4098
     4099                                jQuery(this).remove();
     4100
     4101                                if ( next ) {
     4102                                        jQuery(next).before( value );
     4103                                } else {
     4104                                        jQuery(parent).append( value );
     4105                                }
    4784106                        });
    479         },
    480 
    481         removeData: function( key ){
    482                 return this.each(function(){
    483                         jQuery.removeData( this, key );
    484                 });
    485         },
    486 
    487         domManip: function( args, table, reverse, callback ) {
    488                 var clone = this.length > 1, elems;
    489 
    490                 return this.each(function(){
    491                         if ( !elems ) {
    492                                 elems = jQuery.clean( args, this.ownerDocument );
    493 
    494                                 if ( reverse )
    495                                         elems.reverse();
    496                         }
    497 
    498                         var obj = this;
    499 
    500                         if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) )
    501                                 obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") );
    502 
    503                         var scripts = jQuery( [] );
    504 
    505                         jQuery.each(elems, function(){
    506                                 var elem = clone ?
    507                                         jQuery( this ).clone( true )[0] :
    508                                         this;
    509 
    510                                 // execute all scripts after the elements have been injected
    511                                 if ( jQuery.nodeName( elem, "script" ) )
    512                                         scripts = scripts.add( elem );
    513                                 else {
    514                                         // Remove any inner scripts for later evaluation
    515                                         if ( elem.nodeType == 1 )
    516                                                 scripts = scripts.add( jQuery( "script", elem ).remove() );
    517 
    518                                         // Inject the elements into the document
    519                                         callback.call( obj, elem );
    520                                 }
     4107                } else {
     4108                        return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value );
     4109                }
     4110        },
     4111
     4112        detach: function( selector ) {
     4113                return this.remove( selector, true );
     4114        },
     4115
     4116        domManip: function( args, table, callback ) {
     4117                var results, first, value = args[0], scripts = [];
     4118
     4119                // We can't cloneNode fragments that contain checked, in WebKit
     4120                if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
     4121                        return this.each(function() {
     4122                                jQuery(this).domManip( args, table, callback, true );
    5214123                        });
    522 
    523                         scripts.each( evalScript );
    524                 });
    525         }
    526 };
    527 
    528 // Give the init function the jQuery prototype for later instantiation
    529 jQuery.fn.init.prototype = jQuery.fn;
    530 
    531 function evalScript( i, elem ) {
    532         if ( elem.src )
    533                 jQuery.ajax({
    534                         url: elem.src,
    535                         async: false,
    536                         dataType: "script"
    537                 });
    538 
    539         else
    540                 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
    541 
    542         if ( elem.parentNode )
    543                 elem.parentNode.removeChild( elem );
     4124                }
     4125
     4126                if ( jQuery.isFunction(value) ) {
     4127                        return this.each(function(i) {
     4128                                var self = jQuery(this);
     4129                                args[0] = value.call(this, i, table ? self.html() : undefined);
     4130                                self.domManip( args, table, callback );
     4131                        });
     4132                }
     4133
     4134                if ( this[0] ) {
     4135                        // If we're in a fragment, just use that instead of building a new one
     4136                        if ( args[0] && args[0].parentNode && args[0].parentNode.nodeType === 11 ) {
     4137                                results = { fragment: args[0].parentNode };
     4138                        } else {
     4139                                results = buildFragment( args, this, scripts );
     4140                        }
     4141
     4142                        first = results.fragment.firstChild;
     4143
     4144                        if ( first ) {
     4145                                table = table && jQuery.nodeName( first, "tr" );
     4146
     4147                                for ( var i = 0, l = this.length; i < l; i++ ) {
     4148                                        callback.call(
     4149                                                table ?
     4150                                                        root(this[i], first) :
     4151                                                        this[i],
     4152                                                results.cacheable || this.length > 1 || i > 0 ?
     4153                                                        results.fragment.cloneNode(true) :
     4154                                                        results.fragment
     4155                                        );
     4156                                }
     4157                        }
     4158
     4159                        if ( scripts ) {
     4160                                jQuery.each( scripts, evalScript );
     4161                        }
     4162                }
     4163
     4164                return this;
     4165
     4166                function root( elem, cur ) {
     4167                        return jQuery.nodeName(elem, "table") ?
     4168                                (elem.getElementsByTagName("tbody")[0] ||
     4169                                elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
     4170                                elem;
     4171                }
     4172        }
     4173});
     4174
     4175function cloneCopyEvent(orig, ret) {
     4176        var i = 0;
     4177
     4178        ret.each(function() {
     4179                if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) {
     4180                        return;
     4181                }
     4182
     4183                var oldData = jQuery.data( orig[i++] ), curData = jQuery.data( this, oldData ), events = oldData && oldData.events;
     4184
     4185                if ( events ) {
     4186                        delete curData.handle;
     4187                        curData.events = {};
     4188
     4189                        for ( var type in events ) {
     4190                                for ( var handler in events[ type ] ) {
     4191                                        jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
     4192                                }
     4193                        }
     4194                }
     4195        });
    5444196}
    5454197
    546 function now(){
    547         return +new Date;
     4198function buildFragment( args, nodes, scripts ) {
     4199        var fragment, cacheable, cacheresults, doc;
     4200
     4201        // webkit does not clone 'checked' attribute of radio inputs on cloneNode, so don't cache if string has a checked
     4202        if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && args[0].indexOf("<option") < 0 && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
     4203                cacheable = true;
     4204                cacheresults = jQuery.fragments[ args[0] ];
     4205                if ( cacheresults ) {
     4206                        if ( cacheresults !== 1 ) {
     4207                                fragment = cacheresults;
     4208                        }
     4209                }
     4210        }
     4211
     4212        if ( !fragment ) {
     4213                doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
     4214                fragment = doc.createDocumentFragment();
     4215                jQuery.clean( args, doc, fragment, scripts );
     4216        }
     4217
     4218        if ( cacheable ) {
     4219                jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
     4220        }
     4221
     4222        return { fragment: fragment, cacheable: cacheable };
    5484223}
    5494224
    550 jQuery.extend = jQuery.fn.extend = function() {
    551         // copy reference to target object
    552         var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
    553 
    554         // Handle a deep copy situation
    555         if ( target.constructor == Boolean ) {
    556                 deep = target;
    557                 target = arguments[1] || {};
    558                 // skip the boolean and the target
    559                 i = 2;
    560         }
    561 
    562         // Handle case when target is a string or something (possible in deep copy)
    563         if ( typeof target != "object" && typeof target != "function" )
    564                 target = {};
    565 
    566         // extend jQuery itself if only one argument is passed
    567         if ( length == i ) {
    568                 target = this;
    569                 --i;
    570         }
    571 
    572         for ( ; i < length; i++ )
    573                 // Only deal with non-null/undefined values
    574                 if ( (options = arguments[ i ]) != null )
    575                         // Extend the base object
    576                         for ( var name in options ) {
    577                                 var src = target[ name ], copy = options[ name ];
    578 
    579                                 // Prevent never-ending loop
    580                                 if ( target === copy )
    581                                         continue;
    582 
    583                                 // Recurse if we're merging object values
    584                                 if ( deep && copy && typeof copy == "object" && !copy.nodeType )
    585                                         target[ name ] = jQuery.extend( deep,
    586                                                 // Never move original objects, clone them
    587                                                 src || ( copy.length != null ? [ ] : { } )
    588                                         , copy );
    589 
    590                                 // Don't bring in undefined values
    591                                 else if ( copy !== undefined )
    592                                         target[ name ] = copy;
    593 
    594                         }
    595 
    596         // Return the modified object
    597         return target;
    598 };
    599 
    600 var expando = "jQuery" + now(), uuid = 0, windowData = {},
    601         // exclude the following css properties to add px
    602         exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
    603         // cache defaultView
    604         defaultView = document.defaultView || {};
    605 
    606 jQuery.extend({
    607         noConflict: function( deep ) {
    608                 window.$ = _$;
    609 
    610                 if ( deep )
    611                         window.jQuery = _jQuery;
    612 
    613                 return jQuery;
    614         },
    615 
    616         // See test/unit/core.js for details concerning this function.
    617         isFunction: function( fn ) {
    618                 return !!fn && typeof fn != "string" && !fn.nodeName &&
    619                         fn.constructor != Array && /^[\s[]?function/.test( fn + "" );
    620         },
    621 
    622         // check if an element is in a (or is an) XML document
    623         isXMLDoc: function( elem ) {
    624                 return elem.documentElement && !elem.body ||
    625                         elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
    626         },
    627 
    628         // Evalulates a script in a global context
    629         globalEval: function( data ) {
    630                 data = jQuery.trim( data );
    631 
    632                 if ( data ) {
    633                         // Inspired by code by Andrea Giammarchi
    634                         // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
    635                         var head = document.getElementsByTagName("head")[0] || document.documentElement,
    636                                 script = document.createElement("script");
    637 
    638                         script.type = "text/javascript";
    639                         if ( jQuery.browser.msie )
    640                                 script.text = data;
    641                         else
    642                                 script.appendChild( document.createTextNode( data ) );
    643 
    644                         // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
    645                         // This arises when a base node is used (#2709).
    646                         head.insertBefore( script, head.firstChild );
    647                         head.removeChild( script );
    648                 }
    649         },
    650 
    651         nodeName: function( elem, name ) {
    652                 return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
    653         },
    654 
    655         cache: {},
    656 
    657         data: function( elem, name, data ) {
    658                 elem = elem == window ?
    659                         windowData :
    660                         elem;
    661 
    662                 var id = elem[ expando ];
    663 
    664                 // Compute a unique ID for the element
    665                 if ( !id )
    666                         id = elem[ expando ] = ++uuid;
    667 
    668                 // Only generate the data cache if we're
    669                 // trying to access or manipulate it
    670                 if ( name && !jQuery.cache[ id ] )
    671                         jQuery.cache[ id ] = {};
    672 
    673                 // Prevent overriding the named cache with undefined values
    674                 if ( data !== undefined )
    675                         jQuery.cache[ id ][ name ] = data;
    676 
    677                 // Return the named cache data, or the ID for the element
    678                 return name ?
    679                         jQuery.cache[ id ][ name ] :
    680                         id;
    681         },
    682 
    683         removeData: function( elem, name ) {
    684                 elem = elem == window ?
    685                         windowData :
    686                         elem;
    687 
    688                 var id = elem[ expando ];
    689 
    690                 // If we want to remove a specific section of the element's data
    691                 if ( name ) {
    692                         if ( jQuery.cache[ id ] ) {
    693                                 // Remove the section of cache data
    694                                 delete jQuery.cache[ id ][ name ];
    695 
    696                                 // If we've removed all the data, remove the element's cache
    697                                 name = "";
    698 
    699                                 for ( name in jQuery.cache[ id ] )
    700                                         break;
    701 
    702                                 if ( !name )
    703                                         jQuery.removeData( elem );
    704                         }
    705 
    706                 // Otherwise, we want to remove all of the element's data
    707                 } else {
    708                         // Clean up the element expando
    709                         try {
    710                                 delete elem[ expando ];
    711                         } catch(e){
    712                                 // IE has trouble directly removing the expando
    713                                 // but it's ok with using removeAttribute
    714                                 if ( elem.removeAttribute )
    715                                         elem.removeAttribute( expando );
    716                         }
    717 
    718                         // Completely remove the data cache
    719                         delete jQuery.cache[ id ];
    720                 }
    721         },
    722 
    723         // args is for internal usage only
    724         each: function( object, callback, args ) {
    725                 var name, i = 0, length = object.length;
    726 
    727                 if ( args ) {
    728                         if ( length == undefined ) {
    729                                 for ( name in object )
    730                                         if ( callback.apply( object[ name ], args ) === false )
    731                                                 break;
    732                         } else
    733                                 for ( ; i < length; )
    734                                         if ( callback.apply( object[ i++ ], args ) === false )
    735                                                 break;
    736 
    737                 // A special, fast, case for the most common use of each
    738                 } else {
    739                         if ( length == undefined ) {
    740                                 for ( name in object )
    741                                         if ( callback.call( object[ name ], name, object[ name ] ) === false )
    742                                                 break;
    743                         } else
    744                                 for ( var value = object[0];
    745                                         i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
    746                 }
    747 
    748                 return object;
    749         },
    750 
    751         prop: function( elem, value, type, i, name ) {
    752                 // Handle executable functions
    753                 if ( jQuery.isFunction( value ) )
    754                         value = value.call( elem, i );
    755 
    756                 // Handle passing in a number to a CSS property
    757                 return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ?
    758                         value + "px" :
    759                         value;
    760         },
    761 
    762         className: {
    763                 // internal only, use addClass("class")
    764                 add: function( elem, classNames ) {
    765                         jQuery.each((classNames || "").split(/\s+/), function(i, className){
    766                                 if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
    767                                         elem.className += (elem.className ? " " : "") + className;
    768                         });
    769                 },
    770 
    771                 // internal only, use removeClass("class")
    772                 remove: function( elem, classNames ) {
    773                         if (elem.nodeType == 1)
    774                                 elem.className = classNames != undefined ?
    775                                         jQuery.grep(elem.className.split(/\s+/), function(className){
    776                                                 return !jQuery.className.has( classNames, className );
    777                                         }).join(" ") :
    778                                         "";
    779                 },
    780 
    781                 // internal only, use hasClass("class")
    782                 has: function( elem, className ) {
    783                         return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
    784                 }
    785         },
    786 
    787         // A method for quickly swapping in/out CSS properties to get correct calculations
    788         swap: function( elem, options, callback ) {
    789                 var old = {};
    790                 // Remember the old values, and insert the new ones
    791                 for ( var name in options ) {
    792                         old[ name ] = elem.style[ name ];
    793                         elem.style[ name ] = options[ name ];
    794                 }
    795 
    796                 callback.call( elem );
    797 
    798                 // Revert the old values
    799                 for ( var name in options )
    800                         elem.style[ name ] = old[ name ];
    801         },
    802 
    803         css: function( elem, name, force ) {
    804                 if ( name == "width" || name == "height" ) {
    805                         var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
    806 
    807                         function getWH() {
    808                                 val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
    809                                 var padding = 0, border = 0;
    810                                 jQuery.each( which, function() {
    811                                         padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
    812                                         border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
    813                                 });
    814                                 val -= Math.round(padding + border);
    815                         }
    816 
    817                         if ( jQuery(elem).is(":visible") )
    818                                 getWH();
    819                         else
    820                                 jQuery.swap( elem, props, getWH );
    821 
    822                         return Math.max(0, val);
    823                 }
    824 
    825                 return jQuery.curCSS( elem, name, force );
    826         },
    827 
    828         curCSS: function( elem, name, force ) {
    829                 var ret, style = elem.style;
    830 
    831                 // A helper method for determining if an element's values are broken
    832                 function color( elem ) {
    833                         if ( !jQuery.browser.safari )
    834                                 return false;
    835 
    836                         // defaultView is cached
    837                         var ret = defaultView.getComputedStyle( elem, null );
    838                         return !ret || ret.getPropertyValue("color") == "";
    839                 }
    840 
    841                 // We need to handle opacity special in IE
    842                 if ( name == "opacity" && jQuery.browser.msie ) {
    843                         ret = jQuery.attr( style, "opacity" );
    844 
    845                         return ret == "" ?
    846                                 "1" :
    847                                 ret;
    848                 }
    849                 // Opera sometimes will give the wrong display answer, this fixes it, see #2037
    850                 if ( jQuery.browser.opera && name == "display" ) {
    851                         var save = style.outline;
    852                         style.outline = "0 solid black";
    853                         style.outline = save;
    854                 }
    855 
    856                 // Make sure we're using the right name for getting the float value
    857                 if ( name.match( /float/i ) )
    858                         name = styleFloat;
    859 
    860                 if ( !force && style && style[ name ] )
    861                         ret = style[ name ];
    862 
    863                 else if ( defaultView.getComputedStyle ) {
    864 
    865                         // Only "float" is needed here
    866                         if ( name.match( /float/i ) )
    867                                 name = "float";
    868 
    869                         name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
    870 
    871                         var computedStyle = defaultView.getComputedStyle( elem, null );
    872 
    873                         if ( computedStyle && !color( elem ) )
    874                                 ret = computedStyle.getPropertyValue( name );
    875 
    876                         // If the element isn't reporting its values properly in Safari
    877                         // then some display: none elements are involved
    878                         else {
    879                                 var swap = [], stack = [], a = elem, i = 0;
    880 
    881                                 // Locate all of the parent display: none elements
    882                                 for ( ; a && color(a); a = a.parentNode )
    883                                         stack.unshift(a);
    884 
    885                                 // Go through and make them visible, but in reverse
    886                                 // (It would be better if we knew the exact display type that they had)
    887                                 for ( ; i < stack.length; i++ )
    888                                         if ( color( stack[ i ] ) ) {
    889                                                 swap[ i ] = stack[ i ].style.display;
    890                                                 stack[ i ].style.display = "block";
    891                                         }
    892 
    893                                 // Since we flip the display style, we have to handle that
    894                                 // one special, otherwise get the value
    895                                 ret = name == "display" && swap[ stack.length - 1 ] != null ?
    896                                         "none" :
    897                                         ( computedStyle && computedStyle.getPropertyValue( name ) ) || "";
    898 
    899                                 // Finally, revert the display styles back
    900                                 for ( i = 0; i < swap.length; i++ )
    901                                         if ( swap[ i ] != null )
    902                                                 stack[ i ].style.display = swap[ i ];
    903                         }
    904 
    905                         // We should always get a number back from opacity
    906                         if ( name == "opacity" && ret == "" )
    907                                 ret = "1";
    908 
    909                 } else if ( elem.currentStyle ) {
    910                         var camelCase = name.replace(/\-(\w)/g, function(all, letter){
    911                                 return letter.toUpperCase();
    912                         });
    913 
    914                         ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
    915 
    916                         // From the awesome hack by Dean Edwards
    917                         // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
    918 
    919                         // If we're not dealing with a regular pixel number
    920                         // but a number that has a weird ending, we need to convert it to pixels
    921                         if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
    922                                 // Remember the original values
    923                                 var left = style.left, rsLeft = elem.runtimeStyle.left;
    924 
    925                                 // Put in the new values to get a computed value out
    926                                 elem.runtimeStyle.left = elem.currentStyle.left;
    927                                 style.left = ret || 0;
    928                                 ret = style.pixelLeft + "px";
    929 
    930                                 // Revert the changed values
    931                                 style.left = left;
    932                                 elem.runtimeStyle.left = rsLeft;
    933                         }
    934                 }
    935 
    936                 return ret;
    937         },
    938 
    939         clean: function( elems, context ) {
    940                 var ret = [];
    941                 context = context || document;
    942                 // !context.createElement fails in IE with an error but returns typeof 'object'
    943                 if (typeof context.createElement == 'undefined')
    944                         context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
    945 
    946                 jQuery.each(elems, function(i, elem){
    947                         if ( !elem )
    948                                 return;
    949 
    950                         if ( elem.constructor == Number )
    951                                 elem += '';
    952 
    953                         // Convert html string into DOM nodes
    954                         if ( typeof elem == "string" ) {
    955                                 // Fix "XHTML"-style tags in all browsers
    956                                 elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
    957                                         return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
    958                                                 all :
    959                                                 front + "></" + tag + ">";
    960                                 });
    961 
    962                                 // Trim whitespace, otherwise indexOf won't work as expected
    963                                 var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div");
    964 
    965                                 var wrap =
    966                                         // option or optgroup
    967                                         !tags.indexOf("<opt") &&
    968                                         [ 1, "<select multiple='multiple'>", "</select>" ] ||
    969 
    970                                         !tags.indexOf("<leg") &&
    971                                         [ 1, "<fieldset>", "</fieldset>" ] ||
    972 
    973                                         tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
    974                                         [ 1, "<table>", "</table>" ] ||
    975 
    976                                         !tags.indexOf("<tr") &&
    977                                         [ 2, "<table><tbody>", "</tbody></table>" ] ||
    978 
    979                                         // <thead> matched above
    980                                         (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
    981                                         [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
    982 
    983                                         !tags.indexOf("<col") &&
    984                                         [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
    985 
    986                                         // IE can't serialize <link> and <script> tags normally
    987                                         jQuery.browser.msie &&
    988                                         [ 1, "div<div>", "</div>" ] ||
    989 
    990                                         [ 0, "", "" ];
    991 
    992                                 // Go to html and back, then peel off extra wrappers
    993                                 div.innerHTML = wrap[1] + elem + wrap[2];
    994 
    995                                 // Move to the right depth
    996                                 while ( wrap[0]-- )
    997                                         div = div.lastChild;
    998 
    999                                 // Remove IE's autoinserted <tbody> from table fragments
    1000                                 if ( jQuery.browser.msie ) {
    1001 
    1002                                         // String was a <table>, *may* have spurious <tbody>
    1003                                         var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ?
    1004                                                 div.firstChild && div.firstChild.childNodes :
    1005 
    1006                                                 // String was a bare <thead> or <tfoot>
    1007                                                 wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ?
    1008                                                         div.childNodes :
    1009                                                         [];
    1010 
    1011                                         for ( var j = tbody.length - 1; j >= 0 ; --j )
    1012                                                 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
    1013                                                         tbody[ j ].parentNode.removeChild( tbody[ j ] );
    1014 
    1015                                         // IE completely kills leading whitespace when innerHTML is used
    1016                                         if ( /^\s/.test( elem ) )
    1017                                                 div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
    1018 
    1019                                 }
    1020 
    1021                                 elem = jQuery.makeArray( div.childNodes );
    1022                         }
    1023 
    1024                         if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) )
    1025                                 return;
    1026 
    1027                         if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options )
    1028                                 ret.push( elem );
    1029 
    1030                         else
    1031                                 ret = jQuery.merge( ret, elem );
    1032 
    1033                 });
    1034 
    1035                 return ret;
    1036         },
    1037 
    1038         attr: function( elem, name, value ) {
    1039                 // don't set attributes on text and comment nodes
    1040                 if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
    1041                         return undefined;
    1042 
    1043                 var notxml = !jQuery.isXMLDoc( elem ),
    1044                         // Whether we are setting (or getting)
    1045                         set = value !== undefined,
    1046                         msie = jQuery.browser.msie;
    1047 
    1048                 // Try to normalize/fix the name
    1049                 name = notxml && jQuery.props[ name ] || name;
    1050 
    1051                 // Only do all the following if this is a node (faster for style)
    1052                 // IE elem.getAttribute passes even for style
    1053                 if ( elem.tagName ) {
    1054 
    1055                         // These attributes require special treatment
    1056                         var special = /href|src|style/.test( name );
    1057 
    1058                         // Safari mis-reports the default selected property of a hidden option
    1059                         // Accessing the parent's selectedIndex property fixes it
    1060                         if ( name == "selected" && jQuery.browser.safari )
    1061                                 elem.parentNode.selectedIndex;
    1062 
    1063                         // If applicable, access the attribute via the DOM 0 way
    1064                         if ( name in elem && notxml && !special ) {
    1065                                 if ( set ){
    1066                                         // We can't allow the type property to be changed (since it causes problems in IE)
    1067                                         if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
    1068                                                 throw "type property can't be changed";
    1069 
    1070                                         elem[ name ] = value;
    1071                                 }
    1072 
    1073                                 // browsers index elements by id/name on forms, give priority to attributes.
    1074                                 if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
    1075                                         return elem.getAttributeNode( name ).nodeValue;
    1076 
    1077                                 return elem[ name ];
    1078                         }
    1079 
    1080                         if ( msie && notxml &&  name == "style" )
    1081                                 return jQuery.attr( elem.style, "cssText", value );
    1082 
    1083                         if ( set )
    1084                                 // convert the value to a string (all browsers do this but IE) see #1070
    1085                                 elem.setAttribute( name, "" + value );
    1086 
    1087                         var attr = msie && notxml && special
    1088                                         // Some attributes require a special call on IE
    1089                                         ? elem.getAttribute( name, 2 )
    1090                                         : elem.getAttribute( name );
    1091 
    1092                         // Non-existent attributes return null, we normalize to undefined
    1093                         return attr === null ? undefined : attr;
    1094                 }
    1095 
    1096                 // elem is actually elem.style ... set the style
    1097 
    1098                 // IE uses filters for opacity
    1099                 if ( msie && name == "opacity" ) {
    1100                         if ( set ) {
    1101                                 // IE has trouble with opacity if it does not have layout
    1102                                 // Force it by setting the zoom level
    1103                                 elem.zoom = 1;
    1104 
    1105                                 // Set the alpha filter to set the opacity
    1106                                 elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
    1107                                         (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
    1108                         }
    1109 
    1110                         return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
    1111                                 (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
    1112                                 "";
    1113                 }
    1114 
    1115                 name = name.replace(/-([a-z])/ig, function(all, letter){
    1116                         return letter.toUpperCase();
    1117                 });
    1118 
    1119                 if ( set )
    1120                         elem[ name ] = value;
    1121 
    1122                 return elem[ name ];
    1123         },
    1124 
    1125         trim: function( text ) {
    1126                 return (text || "").replace( /^\s+|\s+$/g, "" );
    1127         },
    1128 
    1129         makeArray: function( array ) {
    1130                 var ret = [];
    1131 
    1132                 if( array != null ){
    1133                         var i = array.length;
    1134                         //the window, strings and functions also have 'length'
    1135                         if( i == null || array.split || array.setInterval || array.call )
    1136                                 ret[0] = array;
    1137                         else
    1138                                 while( i )
    1139                                         ret[--i] = array[i];
    1140                 }
    1141 
    1142                 return ret;
    1143         },
    1144 
    1145         inArray: function( elem, array ) {
    1146                 for ( var i = 0, length = array.length; i < length; i++ )
    1147                 // Use === because on IE, window == document
    1148                         if ( array[ i ] === elem )
    1149                                 return i;
    1150 
    1151                 return -1;
    1152         },
    1153 
    1154         merge: function( first, second ) {
    1155                 // We have to loop this way because IE & Opera overwrite the length
    1156                 // expando of getElementsByTagName
    1157                 var i = 0, elem, pos = first.length;
    1158                 // Also, we need to make sure that the correct elements are being returned
    1159                 // (IE returns comment nodes in a '*' query)
    1160                 if ( jQuery.browser.msie ) {
    1161                         while ( elem = second[ i++ ] )
    1162                                 if ( elem.nodeType != 8 )
    1163                                         first[ pos++ ] = elem;
    1164 
    1165                 } else
    1166                         while ( elem = second[ i++ ] )
    1167                                 first[ pos++ ] = elem;
    1168 
    1169                 return first;
    1170         },
    1171 
    1172         unique: function( array ) {
    1173                 var ret = [], done = {};
    1174 
    1175                 try {
    1176 
    1177                         for ( var i = 0, length = array.length; i < length; i++ ) {
    1178                                 var id = jQuery.data( array[ i ] );
    1179 
    1180                                 if ( !done[ id ] ) {
    1181                                         done[ id ] = true;
    1182                                         ret.push( array[ i ] );
    1183                                 }
    1184                         }
    1185 
    1186                 } catch( e ) {
    1187                         ret = array;
    1188                 }
    1189 
    1190                 return ret;
    1191         },
    1192 
    1193         grep: function( elems, callback, inv ) {
    1194                 var ret = [];
    1195 
    1196                 // Go through the array, only saving the items
    1197                 // that pass the validator function
    1198                 for ( var i = 0, length = elems.length; i < length; i++ )
    1199                         if ( !inv != !callback( elems[ i ], i ) )
    1200                                 ret.push( elems[ i ] );
    1201 
    1202                 return ret;
    1203         },
    1204 
    1205         map: function( elems, callback ) {
    1206                 var ret = [];
    1207 
    1208                 // Go through the array, translating each of the items to their
    1209                 // new value (or values).
    1210                 for ( var i = 0, length = elems.length; i < length; i++ ) {
    1211                         var value = callback( elems[ i ], i );
    1212 
    1213                         if ( value != null )
    1214                                 ret[ ret.length ] = value;
    1215                 }
    1216 
    1217                 return ret.concat.apply( [], ret );
    1218         }
    1219 });
    1220 
    1221 var userAgent = navigator.userAgent.toLowerCase();
    1222 
    1223 // Figure out what browser is being used
    1224 jQuery.browser = {
    1225         version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],
    1226         safari: /webkit/.test( userAgent ),
    1227         opera: /opera/.test( userAgent ),
    1228         msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
    1229         mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
    1230 };
    1231 
    1232 var styleFloat = jQuery.browser.msie ?
    1233         "styleFloat" :
    1234         "cssFloat";
    1235 
    1236 jQuery.extend({
    1237         // Check to see if the W3C box model is being used
    1238         boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
    1239 
    1240         props: {
    1241                 "for": "htmlFor",
    1242                 "class": "className",
    1243                 "float": styleFloat,
    1244                 cssFloat: styleFloat,
    1245                 styleFloat: styleFloat,
    1246                 readonly: "readOnly",
    1247                 maxlength: "maxLength",
    1248                 cellspacing: "cellSpacing"
    1249         }
    1250 });
    1251 
    1252 jQuery.each({
    1253         parent: function(elem){return elem.parentNode;},
    1254         parents: function(elem){return jQuery.dir(elem,"parentNode");},
    1255         next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
    1256         prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
    1257         nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
    1258         prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
    1259         siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
    1260         children: function(elem){return jQuery.sibling(elem.firstChild);},
    1261         contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
    1262 }, function(name, fn){
    1263         jQuery.fn[ name ] = function( selector ) {
    1264                 var ret = jQuery.map( this, fn );
    1265 
    1266                 if ( selector && typeof selector == "string" )
    1267                         ret = jQuery.multiFilter( selector, ret );
    1268 
    1269                 return this.pushStack( jQuery.unique( ret ) );
    1270         };
    1271 });
     4225jQuery.fragments = {};
    12724226
    12734227jQuery.each({
     
    12774231        insertAfter: "after",
    12784232        replaceAll: "replaceWith"
    1279 }, function(name, original){
    1280         jQuery.fn[ name ] = function() {
    1281                 var args = arguments;
    1282 
    1283                 return this.each(function(){
    1284                         for ( var i = 0, length = args.length; i < length; i++ )
    1285                                 jQuery( args[ i ] )[ original ]( this );
    1286                 });
     4233}, function( name, original ) {
     4234        jQuery.fn[ name ] = function( selector ) {
     4235                var ret = [], insert = jQuery( selector );
     4236
     4237                for ( var i = 0, l = insert.length; i < l; i++ ) {
     4238                        var elems = (i > 0 ? this.clone(true) : this).get();
     4239                        jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
     4240                        ret = ret.concat( elems );
     4241                }
     4242                return this.pushStack( ret, name, insert.selector );
    12874243        };
    12884244});
    12894245
    12904246jQuery.each({
    1291         removeAttr: function( name ) {
    1292                 jQuery.attr( this, name, "" );
    1293                 if (this.nodeType == 1)
    1294                         this.removeAttribute( name );
    1295         },
    1296 
    1297         addClass: function( classNames ) {
    1298                 jQuery.className.add( this, classNames );
    1299         },
    1300 
    1301         removeClass: function( classNames ) {
    1302                 jQuery.className.remove( this, classNames );
    1303         },
    1304 
    1305         toggleClass: function( classNames ) {
    1306                 jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames );
    1307         },
    1308 
    1309         remove: function( selector ) {
    1310                 if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) {
    1311                         // Prevent memory leaks
    1312                         jQuery( "*", this ).add(this).each(function(){
    1313                                 jQuery.event.remove(this);
    1314                                 jQuery.removeData(this);
    1315                         });
    1316                         if (this.parentNode)
    1317                                 this.parentNode.removeChild( this );
     4247        // keepData is for internal use only--do not document
     4248        remove: function( selector, keepData ) {
     4249                if ( !selector || jQuery.filter( selector, [ this ] ).length ) {
     4250                        if ( !keepData && this.nodeType === 1 ) {
     4251                                jQuery.cleanData( this.getElementsByTagName("*") );
     4252                                jQuery.cleanData( [ this ] );
     4253                        }
     4254
     4255                        if ( this.parentNode ) {
     4256                                 this.parentNode.removeChild( this );
     4257                        }
    13184258                }
    13194259        },
     
    13214261        empty: function() {
    13224262                // Remove element nodes and prevent memory leaks
    1323                 jQuery( ">*", this ).remove();
     4263                if ( this.nodeType === 1 ) {
     4264                        jQuery.cleanData( this.getElementsByTagName("*") );
     4265                }
    13244266
    13254267                // Remove any remaining nodes
    1326                 while ( this.firstChild )
     4268                while ( this.firstChild ) {
    13274269                        this.removeChild( this.firstChild );
    1328         }
    1329 }, function(name, fn){
    1330         jQuery.fn[ name ] = function(){
     4270                }
     4271        }
     4272}, function( name, fn ) {
     4273        jQuery.fn[ name ] = function() {
    13314274                return this.each( fn, arguments );
    13324275        };
    13334276});
    13344277
    1335 jQuery.each([ "Height", "Width" ], function(i, name){
    1336         var type = name.toLowerCase();
    1337 
    1338         jQuery.fn[ type ] = function( size ) {
    1339                 // Get window width or height
    1340                 return this[0] == window ?
    1341                         // Opera reports document.body.client[Width/Height] properly in both quirks and standards
    1342                         jQuery.browser.opera && document.body[ "client" + name ] ||
    1343 
    1344                         // Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths)
    1345                         jQuery.browser.safari && window[ "inner" + name ] ||
    1346 
    1347                         // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
    1348                         document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] :
    1349 
    1350                         // Get document width or height
    1351                         this[0] == document ?
    1352                                 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
    1353                                 Math.max(
    1354                                         Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]),
    1355                                         Math.max(document.body["offset" + name], document.documentElement["offset" + name])
    1356                                 ) :
    1357 
    1358                                 // Get or set width or height on the element
    1359                                 size == undefined ?
    1360                                         // Get width or height on the element
    1361                                         (this.length ? jQuery.css( this[0], type ) : null) :
    1362 
    1363                                         // Set the width or height on the element (default to pixels if value is unitless)
    1364                                         this.css( type, size.constructor == String ? size : size + "px" );
    1365         };
    1366 });
    1367 
    1368 // Helper function used by the dimensions and offset modules
    1369 function num(elem, prop) {
    1370         return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
    1371 }var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ?
    1372                 "(?:[\\w*_-]|\\\\.)" :
    1373                 "(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",
    1374         quickChild = new RegExp("^>\\s*(" + chars + "+)"),
    1375         quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"),
    1376         quickClass = new RegExp("^([#.]?)(" + chars + "*)");
    1377 
    13784278jQuery.extend({
    1379         expr: {
    1380                 "": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},
    1381                 "#": function(a,i,m){return a.getAttribute("id")==m[2];},
    1382                 ":": {
    1383                         // Position Checks
    1384                         lt: function(a,i,m){return i<m[3]-0;},
    1385                         gt: function(a,i,m){return i>m[3]-0;},
    1386                         nth: function(a,i,m){return m[3]-0==i;},
    1387                         eq: function(a,i,m){return m[3]-0==i;},
    1388                         first: function(a,i){return i==0;},
    1389                         last: function(a,i,m,r){return i==r.length-1;},
    1390                         even: function(a,i){return i%2==0;},
    1391                         odd: function(a,i){return i%2;},
    1392 
    1393                         // Child Checks
    1394                         "first-child": function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},
    1395                         "last-child": function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},
    1396                         "only-child": function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},
    1397 
    1398                         // Parent Checks
    1399                         parent: function(a){return a.firstChild;},
    1400                         empty: function(a){return !a.firstChild;},
    1401 
    1402                         // Text Check
    1403                         contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},
    1404 
    1405                         // Visibility
    1406                         visible: function(a){return "hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},
    1407                         hidden: function(a){return "hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},
    1408 
    1409                         // Form attributes
    1410                         enabled: function(a){return !a.disabled;},
    1411                         disabled: function(a){return a.disabled;},
    1412                         checked: function(a){return a.checked;},
    1413                         selected: function(a){return a.selected||jQuery.attr(a,"selected");},
    1414 
    1415                         // Form elements
    1416                         text: function(a){return "text"==a.type;},
    1417                         radio: function(a){return "radio"==a.type;},
    1418                         checkbox: function(a){return "checkbox"==a.type;},
    1419                         file: function(a){return "file"==a.type;},
    1420                         password: function(a){return "password"==a.type;},
    1421                         submit: function(a){return "submit"==a.type;},
    1422                         image: function(a){return "image"==a.type;},
    1423                         reset: function(a){return "reset"==a.type;},
    1424                         button: function(a){return "button"==a.type||jQuery.nodeName(a,"button");},
    1425                         input: function(a){return /input|select|textarea|button/i.test(a.nodeName);},
    1426 
    1427                         // :has()
    1428                         has: function(a,i,m){return jQuery.find(m[3],a).length;},
    1429 
    1430                         // :header
    1431                         header: function(a){return /h\d/i.test(a.nodeName);},
    1432 
    1433                         // :animated
    1434                         animated: function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}
    1435                 }
    1436         },
    1437 
    1438         // The regular expressions that power the parsing engine
    1439         parse: [
    1440                 // Match: [@value='test'], [@foo]
    1441                 /^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,
    1442 
    1443                 // Match: :contains('foo')
    1444                 /^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,
    1445 
    1446                 // Match: :even, :last-child, #id, .class
    1447                 new RegExp("^([:.#]*)(" + chars + "+)")
    1448         ],
    1449 
    1450         multiFilter: function( expr, elems, not ) {
    1451                 var old, cur = [];
    1452 
    1453                 while ( expr && expr != old ) {
    1454                         old = expr;
    1455                         var f = jQuery.filter( expr, elems, not );
    1456                         expr = f.t.replace(/^\s*,\s*/, "" );
    1457                         cur = not ? elems = f.r : jQuery.merge( cur, f.r );
    1458                 }
    1459 
    1460                 return cur;
    1461         },
    1462 
    1463         find: function( t, context ) {
    1464                 // Quickly handle non-string expressions
    1465                 if ( typeof t != "string" )
    1466                         return [ t ];
    1467 
    1468                 // check to make sure context is a DOM element or a document
    1469                 if ( context && context.nodeType != 1 && context.nodeType != 9)
    1470                         return [ ];
    1471 
    1472                 // Set the correct context (if none is provided)
     4279        clean: function( elems, context, fragment, scripts ) {
    14734280                context = context || document;
    14744281
    1475                 // Initialize the search
    1476                 var ret = [context], done = [], last, nodeName;
    1477 
    1478                 // Continue while a selector expression exists, and while
    1479                 // we're no longer looping upon ourselves
    1480                 while ( t && last != t ) {
    1481                         var r = [];
    1482                         last = t;
    1483 
    1484                         t = jQuery.trim(t);
    1485 
    1486                         var foundToken = false,
    1487 
    1488                         // An attempt at speeding up child selectors that
    1489                         // point to a specific element tag
    1490                                 re = quickChild,
    1491 
    1492                                 m = re.exec(t);
    1493 
    1494                         if ( m ) {
    1495                                 nodeName = m[1].toUpperCase();
    1496 
    1497                                 // Perform our own iteration and filter
    1498                                 for ( var i = 0; ret[i]; i++ )
    1499                                         for ( var c = ret[i].firstChild; c; c = c.nextSibling )
    1500                                                 if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) )
    1501                                                         r.push( c );
    1502 
    1503                                 ret = r;
    1504                                 t = t.replace( re, "" );
    1505                                 if ( t.indexOf(" ") == 0 ) continue;
    1506                                 foundToken = true;
    1507                         } else {
    1508                                 re = /^([>+~])\s*(\w*)/i;
    1509 
    1510                                 if ( (m = re.exec(t)) != null ) {
    1511                                         r = [];
    1512 
    1513                                         var merge = {};
    1514                                         nodeName = m[2].toUpperCase();
    1515                                         m = m[1];
    1516 
    1517                                         for ( var j = 0, rl = ret.length; j < rl; j++ ) {
    1518                                                 var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild;
    1519                                                 for ( ; n; n = n.nextSibling )
    1520                                                         if ( n.nodeType == 1 ) {
    1521                                                                 var id = jQuery.data(n);
    1522 
    1523                                                                 if ( m == "~" && merge[id] ) break;
    1524 
    1525                                                                 if (!nodeName || n.nodeName.toUpperCase() == nodeName ) {
    1526                                                                         if ( m == "~" ) merge[id] = true;
    1527                                                                         r.push( n );
    1528                                                                 }
    1529 
    1530                                                                 if ( m == "+" ) break;
    1531                                                         }
    1532                                         }
    1533 
    1534                                         ret = r;
    1535 
    1536                                         // And remove the token
    1537                                         t = jQuery.trim( t.replace( re, "" ) );
    1538                                         foundToken = true;
    1539                                 }
    1540                         }
    1541 
    1542                         // See if there's still an expression, and that we haven't already
    1543                         // matched a token
    1544                         if ( t && !foundToken ) {
    1545                                 // Handle multiple expressions
    1546                                 if ( !t.indexOf(",") ) {
    1547                                         // Clean the result set
    1548                                         if ( context == ret[0] ) ret.shift();
    1549 
    1550                                         // Merge the result sets
    1551                                         done = jQuery.merge( done, ret );
    1552 
    1553                                         // Reset the context
    1554                                         r = ret = [context];
    1555 
    1556                                         // Touch up the selector string
    1557                                         t = " " + t.substr(1,t.length);
    1558 
    1559                                 } else {
    1560                                         // Optimize for the case nodeName#idName
    1561                                         var re2 = quickID;
    1562                                         var m = re2.exec(t);
    1563 
    1564                                         // Re-organize the results, so that they're consistent
    1565                                         if ( m ) {
    1566                                                 m = [ 0, m[2], m[3], m[1] ];
    1567 
    1568                                         } else {
    1569                                                 // Otherwise, do a traditional filter check for
    1570                                                 // ID, class, and element selectors
    1571                                                 re2 = quickClass;
    1572                                                 m = re2.exec(t);
    1573                                         }
    1574 
    1575                                         m[2] = m[2].replace(/\\/g, "");
    1576 
    1577                                         var elem = ret[ret.length-1];
    1578 
    1579                                         // Try to do a global search by ID, where we can
    1580                                         if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) {
    1581                                                 // Optimization for HTML document case
    1582                                                 var oid = elem.getElementById(m[2]);
    1583 
    1584                                                 // Do a quick check for the existence of the actual ID attribute
    1585                                                 // to avoid selecting by the name attribute in IE
    1586                                                 // also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form
    1587                                                 if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] )
    1588                                                         oid = jQuery('[@id="'+m[2]+'"]', elem)[0];
    1589 
    1590                                                 // Do a quick check for node name (where applicable) so
    1591                                                 // that div#foo searches will be really fast
    1592                                                 ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : [];
    1593                                         } else {
    1594                                                 // We need to find all descendant elements
    1595                                                 for ( var i = 0; ret[i]; i++ ) {
    1596                                                         // Grab the tag name being searched for
    1597                                                         var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2];
    1598 
    1599                                                         // Handle IE7 being really dumb about <object>s
    1600                                                         if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" )
    1601                                                                 tag = "param";
    1602 
    1603                                                         r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));
    1604                                                 }
    1605 
    1606                                                 // It's faster to filter by class and be done with it
    1607                                                 if ( m[1] == "." )
    1608                                                         r = jQuery.classFilter( r, m[2] );
    1609 
    1610                                                 // Same with ID filtering
    1611                                                 if ( m[1] == "#" ) {
    1612                                                         var tmp = [];
    1613 
    1614                                                         // Try to find the element with the ID
    1615                                                         for ( var i = 0; r[i]; i++ )
    1616                                                                 if ( r[i].getAttribute("id") == m[2] ) {
    1617                                                                         tmp = [ r[i] ];
    1618                                                                         break;
    1619                                                                 }
    1620 
    1621                                                         r = tmp;
    1622                                                 }
    1623 
    1624                                                 ret = r;
    1625                                         }
    1626 
    1627                                         t = t.replace( re2, "" );
    1628                                 }
    1629 
    1630                         }
    1631 
    1632                         // If a selector string still exists
    1633                         if ( t ) {
    1634                                 // Attempt to filter it
    1635                                 var val = jQuery.filter(t,r);
    1636                                 ret = r = val.r;
    1637                                 t = jQuery.trim(val.t);
    1638                         }
    1639                 }
    1640 
    1641                 // An error occurred with the selector;
    1642                 // just return an empty set instead
    1643                 if ( t )
    1644                         ret = [];
    1645 
    1646                 // Remove the root context
    1647                 if ( ret && context == ret[0] )
    1648                         ret.shift();
    1649 
    1650                 // And combine the results
    1651                 done = jQuery.merge( done, ret );
    1652 
    1653                 return done;
    1654         },
    1655 
    1656         classFilter: function(r,m,not){
    1657                 m = " " + m + " ";
    1658                 var tmp = [];
    1659                 for ( var i = 0; r[i]; i++ ) {
    1660                         var pass = (" " + r[i].className + " ").indexOf( m ) >= 0;
    1661                         if ( !not && pass || not && !pass )
    1662                                 tmp.push( r[i] );
    1663                 }
    1664                 return tmp;
    1665         },
    1666 
    1667         filter: function(t,r,not) {
    1668                 var last;
    1669 
    1670                 // Look for common filter expressions
    1671                 while ( t && t != last ) {
    1672                         last = t;
    1673 
    1674                         var p = jQuery.parse, m;
    1675 
    1676                         for ( var i = 0; p[i]; i++ ) {
    1677                                 m = p[i].exec( t );
    1678 
    1679                                 if ( m ) {
    1680                                         // Remove what we just matched
    1681                                         t = t.substring( m[0].length );
    1682 
    1683                                         m[2] = m[2].replace(/\\/g, "");
    1684                                         break;
    1685                                 }
    1686                         }
    1687 
    1688                         if ( !m )
    1689                                 break;
    1690 
    1691                         // :not() is a special case that can be optimized by
    1692                         // keeping it out of the expression list
    1693                         if ( m[1] == ":" && m[2] == "not" )
    1694                                 // optimize if only one selector found (most common case)
    1695                                 r = isSimple.test( m[3] ) ?
    1696                                         jQuery.filter(m[3], r, true).r :
    1697                                         jQuery( r ).not( m[3] );
    1698 
    1699                         // We can get a big speed boost by filtering by class here
    1700                         else if ( m[1] == "." )
    1701                                 r = jQuery.classFilter(r, m[2], not);
    1702 
    1703                         else if ( m[1] == "[" ) {
    1704                                 var tmp = [], type = m[3];
    1705 
    1706                                 for ( var i = 0, rl = r.length; i < rl; i++ ) {
    1707                                         var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ];
    1708 
    1709                                         if ( z == null || /href|src|selected/.test(m[2]) )
    1710                                                 z = jQuery.attr(a,m[2]) || '';
    1711 
    1712                                         if ( (type == "" && !!z ||
    1713                                                  type == "=" && z == m[5] ||
    1714                                                  type == "!=" && z != m[5] ||
    1715                                                  type == "^=" && z && !z.indexOf(m[5]) ||
    1716                                                  type == "$=" && z.substr(z.length - m[5].length) == m[5] ||
    1717                                                  (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not )
    1718                                                         tmp.push( a );
    1719                                 }
    1720 
    1721                                 r = tmp;
    1722 
    1723                         // We can get a speed boost by handling nth-child here
    1724                         } else if ( m[1] == ":" && m[2] == "nth-child" ) {
    1725                                 var merge = {}, tmp = [],
    1726                                         // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
    1727                                         test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
    1728                                                 m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||
    1729                                                 !/\D/.test(m[3]) && "0n+" + m[3] || m[3]),
    1730                                         // calculate the numbers (first)n+(last) including if they are negative
    1731                                         first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0;
    1732 
    1733                                 // loop through all the elements left in the jQuery object
    1734                                 for ( var i = 0, rl = r.length; i < rl; i++ ) {
    1735                                         var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode);
    1736 
    1737                                         if ( !merge[id] ) {
    1738                                                 var c = 1;
    1739 
    1740                                                 for ( var n = parentNode.firstChild; n; n = n.nextSibling )
    1741                                                         if ( n.nodeType == 1 )
    1742                                                                 n.nodeIndex = c++;
    1743 
    1744                                                 merge[id] = true;
    1745                                         }
    1746 
    1747                                         var add = false;
    1748 
    1749                                         if ( first == 0 ) {
    1750                                                 if ( node.nodeIndex == last )
    1751                                                         add = true;
    1752                                         } else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 )
    1753                                                 add = true;
    1754 
    1755                                         if ( add ^ not )
    1756                                                 tmp.push( node );
    1757                                 }
    1758 
    1759                                 r = tmp;
    1760 
    1761                         // Otherwise, find the expression to execute
    1762                         } else {
    1763                                 var fn = jQuery.expr[ m[1] ];
    1764                                 if ( typeof fn == "object" )
    1765                                         fn = fn[ m[2] ];
    1766 
    1767                                 if ( typeof fn == "string" )
    1768                                         fn = eval("false||function(a,i){return " + fn + ";}");
    1769 
    1770                                 // Execute it against the current filter
    1771                                 r = jQuery.grep( r, function(elem, i){
    1772                                         return fn(elem, i, m, r);
    1773                                 }, not );
    1774                         }
    1775                 }
    1776 
    1777                 // Return an array of filtered elements (r)
    1778                 // and the modified expression string (t)
    1779                 return { r: r, t: t };
    1780         },
    1781 
    1782         dir: function( elem, dir ){
    1783                 var matched = [],
    1784                         cur = elem[dir];
    1785                 while ( cur && cur != document ) {
    1786                         if ( cur.nodeType == 1 )
    1787                                 matched.push( cur );
    1788                         cur = cur[dir];
    1789                 }
    1790                 return matched;
    1791         },
    1792 
    1793         nth: function(cur,result,dir,elem){
    1794                 result = result || 1;
    1795                 var num = 0;
    1796 
    1797                 for ( ; cur; cur = cur[dir] )
    1798                         if ( cur.nodeType == 1 && ++num == result )
    1799                                 break;
    1800 
    1801                 return cur;
    1802         },
    1803 
    1804         sibling: function( n, elem ) {
    1805                 var r = [];
    1806 
    1807                 for ( ; n; n = n.nextSibling ) {
    1808                         if ( n.nodeType == 1 && n != elem )
    1809                                 r.push( n );
    1810                 }
    1811 
    1812                 return r;
    1813         }
    1814 });
    1815 /*
    1816  * A number of helper functions used for managing events.
    1817  * Many of the ideas behind this code orignated from
    1818  * Dean Edwards' addEvent library.
    1819  */
    1820 jQuery.event = {
    1821 
    1822         // Bind an event to an element
    1823         // Original by Dean Edwards
    1824         add: function(elem, types, handler, data) {
    1825                 if ( elem.nodeType == 3 || elem.nodeType == 8 )
    1826                         return;
    1827 
    1828                 // For whatever reason, IE has trouble passing the window object
    1829                 // around, causing it to be cloned in the process
    1830                 if ( jQuery.browser.msie && elem.setInterval )
    1831                         elem = window;
    1832 
    1833                 // Make sure that the function being executed has a unique ID
    1834                 if ( !handler.guid )
    1835                         handler.guid = this.guid++;
    1836 
    1837                 // if data is passed, bind to handler
    1838                 if( data != undefined ) {
    1839                         // Create temporary function pointer to original handler
    1840                         var fn = handler;
    1841 
    1842                         // Create unique handler function, wrapped around original handler
    1843                         handler = this.proxy( fn, function() {
    1844                                 // Pass arguments and context to original handler
    1845                                 return fn.apply(this, arguments);
    1846                         });
    1847 
    1848                         // Store data in unique handler
    1849                         handler.data = data;
    1850                 }
    1851 
    1852                 // Init the element's event structure
    1853                 var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
    1854                         handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
    1855                                 // Handle the second event of a trigger and when
    1856                                 // an event is called after a page has unloaded
    1857                                 if ( typeof jQuery != "undefined" && !jQuery.event.triggered )
    1858                                         return jQuery.event.handle.apply(arguments.callee.elem, arguments);
    1859                         });
    1860                 // Add elem as a property of the handle function
    1861                 // This is to prevent a memory leak with non-native
    1862                 // event in IE.
    1863                 handle.elem = elem;
    1864 
    1865                 // Handle multiple events separated by a space
    1866                 // jQuery(...).bind("mouseover mouseout", fn);
    1867                 jQuery.each(types.split(/\s+/), function(index, type) {
    1868                         // Namespaced event handlers
    1869                         var parts = type.split(".");
    1870                         type = parts[0];
    1871                         handler.type = parts[1];
    1872 
    1873                         // Get the current list of functions bound to this event
    1874                         var handlers = events[type];
    1875 
    1876                         // Init the event handler queue
    1877                         if (!handlers) {
    1878                                 handlers = events[type] = {};
    1879 
    1880                                 // Check for a special event handler
    1881                                 // Only use addEventListener/attachEvent if the special
    1882                                 // events handler returns false
    1883                                 if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) {
    1884                                         // Bind the global event handler to the element
    1885                                         if (elem.addEventListener)
    1886                                                 elem.addEventListener(type, handle, false);
    1887                                         else if (elem.attachEvent)
    1888                                                 elem.attachEvent("on" + type, handle);
    1889                                 }
    1890                         }
    1891 
    1892                         // Add the function to the element's handler list
    1893                         handlers[handler.guid] = handler;
    1894 
    1895                         // Keep track of which events have been used, for global triggering
    1896                         jQuery.event.global[type] = true;
    1897                 });
    1898 
    1899                 // Nullify elem to prevent memory leaks in IE
    1900                 elem = null;
    1901         },
    1902 
    1903         guid: 1,
    1904         global: {},
    1905 
    1906         // Detach an event or set of events from an element
    1907         remove: function(elem, types, handler) {
    1908                 // don't do events on text and comment nodes
    1909                 if ( elem.nodeType == 3 || elem.nodeType == 8 )
    1910                         return;
    1911 
    1912                 var events = jQuery.data(elem, "events"), ret, index;
    1913 
    1914                 if ( events ) {
    1915                         // Unbind all events for the element
    1916                         if ( types == undefined || (typeof types == "string" && types.charAt(0) == ".") )
    1917                                 for ( var type in events )
    1918                                         this.remove( elem, type + (types || "") );
    1919                         else {
    1920                                 // types is actually an event object here
    1921                                 if ( types.type ) {
    1922                                         handler = types.handler;
    1923                                         types = types.type;
    1924                                 }
    1925 
    1926                                 // Handle multiple events seperated by a space
    1927                                 // jQuery(...).unbind("mouseover mouseout", fn);
    1928                                 jQuery.each(types.split(/\s+/), function(index, type){
    1929                                         // Namespaced event handlers
    1930                                         var parts = type.split(".");
    1931                                         type = parts[0];
    1932 
    1933                                         if ( events[type] ) {
    1934                                                 // remove the given handler for the given type
    1935                                                 if ( handler )
    1936                                                         delete events[type][handler.guid];
    1937 
    1938                                                 // remove all handlers for the given type
    1939                                                 else
    1940                                                         for ( handler in events[type] )
    1941                                                                 // Handle the removal of namespaced events
    1942                                                                 if ( !parts[1] || events[type][handler].type == parts[1] )
    1943                                                                         delete events[type][handler];
    1944 
    1945                                                 // remove generic event handler if no more handlers exist
    1946                                                 for ( ret in events[type] ) break;
    1947                                                 if ( !ret ) {
    1948                                                         if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) {
    1949                                                                 if (elem.removeEventListener)
    1950                                                                         elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
    1951                                                                 else if (elem.detachEvent)
    1952                                                                         elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
    1953                                                         }
    1954                                                         ret = null;
    1955                                                         delete events[type];
     4282                // !context.createElement fails in IE with an error but returns typeof 'object'
     4283                if ( typeof context.createElement === "undefined" ) {
     4284                        context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
     4285                }
     4286
     4287                var ret = [];
     4288
     4289                jQuery.each(elems, function( i, elem ) {
     4290                        if ( typeof elem === "number" ) {
     4291                                elem += "";
     4292                        }
     4293
     4294                        if ( !elem ) {
     4295                                return;
     4296                        }
     4297
     4298                        // Convert html string into DOM nodes
     4299                        if ( typeof elem === "string" && !rhtml.test( elem ) ) {
     4300                                elem = context.createTextNode( elem );
     4301
     4302                        } else if ( typeof elem === "string" ) {
     4303                                // Fix "XHTML"-style tags in all browsers
     4304                                elem = elem.replace(rxhtmlTag, fcloseTag);
     4305
     4306                                // Trim whitespace, otherwise indexOf won't work as expected
     4307                                var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
     4308                                        wrap = wrapMap[ tag ] || wrapMap._default,
     4309                                        depth = wrap[0],
     4310                                        div = context.createElement("div");
     4311
     4312                                // Go to html and back, then peel off extra wrappers
     4313                                div.innerHTML = wrap[1] + elem + wrap[2];
     4314
     4315                                // Move to the right depth
     4316                                while ( depth-- ) {
     4317                                        div = div.lastChild;
     4318                                }
     4319
     4320                                // Remove IE's autoinserted <tbody> from table fragments
     4321                                if ( !jQuery.support.tbody ) {
     4322
     4323                                        // String was a <table>, *may* have spurious <tbody>
     4324                                        var hasBody = rtbody.test(elem),
     4325                                                tbody = tag === "table" && !hasBody ?
     4326                                                        div.firstChild && div.firstChild.childNodes :
     4327
     4328                                                        // String was a bare <thead> or <tfoot>
     4329                                                        wrap[1] === "<table>" && !hasBody ?
     4330                                                                div.childNodes :
     4331                                                                [];
     4332
     4333                                        for ( var j = tbody.length - 1; j >= 0 ; --j ) {
     4334                                                if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
     4335                                                        tbody[ j ].parentNode.removeChild( tbody[ j ] );
    19564336                                                }
    19574337                                        }
     4338
     4339                                }
     4340
     4341                                // IE completely kills leading whitespace when innerHTML is used
     4342                                if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
     4343                                        div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
     4344                                }
     4345
     4346                                elem = jQuery.makeArray( div.childNodes );
     4347                        }
     4348
     4349                        if ( elem.nodeType ) {
     4350                                ret.push( elem );
     4351                        } else {
     4352                                ret = jQuery.merge( ret, elem );
     4353                        }
     4354
     4355                });
     4356
     4357                if ( fragment ) {
     4358                        for ( var i = 0; ret[i]; i++ ) {
     4359                                if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
     4360                                        scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
     4361                                } else {
     4362                                        if ( ret[i].nodeType === 1 ) {
     4363                                                ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
     4364                                        }
     4365                                        fragment.appendChild( ret[i] );
     4366                                }
     4367                        }
     4368                }
     4369
     4370                return ret;
     4371        },
     4372       
     4373        cleanData: function( elems ) {
     4374                for ( var i = 0, elem, id; (elem = elems[i]) != null; i++ ) {
     4375                        jQuery.event.remove( elem );
     4376                        jQuery.removeData( elem );
     4377                }
     4378        }
     4379});
     4380// exclude the following css properties to add px
     4381var rexclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
     4382        ralpha = /alpha\([^)]*\)/,
     4383        ropacity = /opacity=([^)]*)/,
     4384        rfloat = /float/i,
     4385        rdashAlpha = /-([a-z])/ig,
     4386        rupper = /([A-Z])/g,
     4387        rnumpx = /^-?\d+(?:px)?$/i,
     4388        rnum = /^-?\d/,
     4389
     4390        cssShow = { position: "absolute", visibility: "hidden", display:"block" },
     4391        cssWidth = [ "Left", "Right" ],
     4392        cssHeight = [ "Top", "Bottom" ],
     4393
     4394        // cache check for defaultView.getComputedStyle
     4395        getComputedStyle = document.defaultView && document.defaultView.getComputedStyle,
     4396        // normalize float css property
     4397        styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat",
     4398        fcamelCase = function( all, letter ) {
     4399                return letter.toUpperCase();
     4400        };
     4401
     4402jQuery.fn.css = function( name, value ) {
     4403        return access( this, name, value, true, function( elem, name, value ) {
     4404                if ( value === undefined ) {
     4405                        return jQuery.curCSS( elem, name );
     4406                }
     4407               
     4408                if ( typeof value === "number" && !rexclude.test(name) ) {
     4409                        value += "px";
     4410                }
     4411
     4412                jQuery.style( elem, name, value );
     4413        });
     4414};
     4415
     4416jQuery.extend({
     4417        style: function( elem, name, value ) {
     4418                // don't set styles on text and comment nodes
     4419                if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
     4420                        return undefined;
     4421                }
     4422
     4423                // ignore negative width and height values #1599
     4424                if ( (name === "width" || name === "height") && parseFloat(value) < 0 ) {
     4425                        value = undefined;
     4426                }
     4427
     4428                var style = elem.style || elem, set = value !== undefined;
     4429
     4430                // IE uses filters for opacity
     4431                if ( !jQuery.support.opacity && name === "opacity" ) {
     4432                        if ( set ) {
     4433                                // IE has trouble with opacity if it does not have layout
     4434                                // Force it by setting the zoom level
     4435                                style.zoom = 1;
     4436
     4437                                // Set the alpha filter to set the opacity
     4438                                var opacity = parseInt( value, 10 ) + "" === "NaN" ? "" : "alpha(opacity=" + value * 100 + ")";
     4439                                var filter = style.filter || jQuery.curCSS( elem, "filter" ) || "";
     4440                                style.filter = ralpha.test(filter) ? filter.replace(ralpha, opacity) : opacity;
     4441                        }
     4442
     4443                        return style.filter && style.filter.indexOf("opacity=") >= 0 ?
     4444                                (parseFloat( ropacity.exec(style.filter)[1] ) / 100) + "":
     4445                                "";
     4446                }
     4447
     4448                // Make sure we're using the right name for getting the float value
     4449                if ( rfloat.test( name ) ) {
     4450                        name = styleFloat;
     4451                }
     4452
     4453                name = name.replace(rdashAlpha, fcamelCase);
     4454
     4455                if ( set ) {
     4456                        style[ name ] = value;
     4457                }
     4458
     4459                return style[ name ];
     4460        },
     4461
     4462        css: function( elem, name, force, extra ) {
     4463                if ( name === "width" || name === "height" ) {
     4464                        var val, props = cssShow, which = name === "width" ? cssWidth : cssHeight;
     4465
     4466                        function getWH() {
     4467                                val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
     4468
     4469                                if ( extra === "border" ) {
     4470                                        return;
     4471                                }
     4472
     4473                                jQuery.each( which, function() {
     4474                                        if ( !extra ) {
     4475                                                val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
     4476                                        }
     4477
     4478                                        if ( extra === "margin" ) {
     4479                                                val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
     4480                                        } else {
     4481                                                val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
     4482                                        }
    19584483                                });
    19594484                        }
    19604485
    1961                         // Remove the expando if it's no longer used
    1962                         for ( ret in events ) break;
    1963                         if ( !ret ) {
    1964                                 var handle = jQuery.data( elem, "handle" );
    1965                                 if ( handle ) handle.elem = null;
    1966                                 jQuery.removeData( elem, "events" );
    1967                                 jQuery.removeData( elem, "handle" );
    1968                         }
    1969                 }
    1970         },
    1971 
    1972         trigger: function(type, data, elem, donative, extra) {
    1973                 // Clone the incoming data, if any
    1974                 data = jQuery.makeArray(data);
    1975 
    1976                 if ( type.indexOf("!") >= 0 ) {
    1977                         type = type.slice(0, -1);
    1978                         var exclusive = true;
    1979                 }
    1980 
    1981                 // Handle a global trigger
    1982                 if ( !elem ) {
    1983                         // Only trigger if we've ever bound an event for it
    1984                         if ( this.global[type] )
    1985                                 jQuery("*").add([window, document]).trigger(type, data);
    1986 
    1987                 // Handle triggering a single element
    1988                 } else {
    1989                         // don't do events on text and comment nodes
    1990                         if ( elem.nodeType == 3 || elem.nodeType == 8 )
    1991                                 return undefined;
    1992 
    1993                         var val, ret, fn = jQuery.isFunction( elem[ type ] || null ),
    1994                                 // Check to see if we need to provide a fake event, or not
    1995                                 event = !data[0] || !data[0].preventDefault;
    1996 
    1997                         // Pass along a fake event
    1998                         if ( event ) {
    1999                                 data.unshift({
    2000                                         type: type,
    2001                                         target: elem,
    2002                                         preventDefault: function(){},
    2003                                         stopPropagation: function(){},
    2004                                         timeStamp: now()
    2005                                 });
    2006                                 data[0][expando] = true; // no need to fix fake event
    2007                         }
    2008 
    2009                         // Enforce the right trigger type
    2010                         data[0].type = type;
    2011                         if ( exclusive )
    2012                                 data[0].exclusive = true;
    2013 
    2014                         // Trigger the event, it is assumed that "handle" is a function
    2015                         var handle = jQuery.data(elem, "handle");
    2016                         if ( handle )
    2017                                 val = handle.apply( elem, data );
    2018 
    2019                         // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
    2020                         if ( (!fn || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
    2021                                 val = false;
    2022 
    2023                         // Extra functions don't get the custom event object
    2024                         if ( event )
    2025                                 data.shift();
    2026 
    2027                         // Handle triggering of extra function
    2028                         if ( extra && jQuery.isFunction( extra ) ) {
    2029                                 // call the extra function and tack the current return value on the end for possible inspection
    2030                                 ret = extra.apply( elem, val == null ? data : data.concat( val ) );
    2031                                 // if anything is returned, give it precedence and have it overwrite the previous value
    2032                                 if (ret !== undefined)
    2033                                         val = ret;
    2034                         }
    2035 
    2036                         // Trigger the native events (except for clicks on links)
    2037                         if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
    2038                                 this.triggered = true;
    2039                                 try {
    2040                                         elem[ type ]();
    2041                                 // prevent IE from throwing an error for some hidden elements
    2042                                 } catch (e) {}
    2043                         }
    2044 
    2045                         this.triggered = false;
    2046                 }
    2047 
    2048                 return val;
    2049         },
    2050 
    2051         handle: function(event) {
    2052                 // returned undefined or false
    2053                 var val, ret, namespace, all, handlers;
    2054 
    2055                 event = arguments[0] = jQuery.event.fix( event || window.event );
    2056 
    2057                 // Namespaced event handlers
    2058                 namespace = event.type.split(".");
    2059                 event.type = namespace[0];
    2060                 namespace = namespace[1];
    2061                 // Cache this now, all = true means, any handler
    2062                 all = !namespace && !event.exclusive;
    2063 
    2064                 handlers = ( jQuery.data(this, "events") || {} )[event.type];
    2065 
    2066                 for ( var j in handlers ) {
    2067                         var handler = handlers[j];
    2068 
    2069                         // Filter the functions by class
    2070                         if ( all || handler.type == namespace ) {
    2071                                 // Pass in a reference to the handler function itself
    2072                                 // So that we can later remove it
    2073                                 event.handler = handler;
    2074                                 event.data = handler.data;
    2075 
    2076                                 ret = handler.apply( this, arguments );
    2077 
    2078                                 if ( val !== false )
    2079                                         val = ret;
    2080 
    2081                                 if ( ret === false ) {
    2082                                         event.preventDefault();
    2083                                         event.stopPropagation();
    2084                                 }
    2085                         }
    2086                 }
    2087 
    2088                 return val;
    2089         },
    2090 
    2091         fix: function(event) {
    2092                 if ( event[expando] == true )
    2093                         return event;
    2094 
    2095                 // store a copy of the original event object
    2096                 // and "clone" to set read-only properties
    2097                 var originalEvent = event;
    2098                 event = { originalEvent: originalEvent };
    2099                 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(" ");
    2100                 for ( var i=props.length; i; i-- )
    2101                         event[ props[i] ] = originalEvent[ props[i] ];
    2102 
    2103                 // Mark it as fixed
    2104                 event[expando] = true;
    2105 
    2106                 // add preventDefault and stopPropagation since
    2107                 // they will not work on the clone
    2108                 event.preventDefault = function() {
    2109                         // if preventDefault exists run it on the original event
    2110                         if (originalEvent.preventDefault)
    2111                                 originalEvent.preventDefault();
    2112                         // otherwise set the returnValue property of the original event to false (IE)
    2113                         originalEvent.returnValue = false;
    2114                 };
    2115                 event.stopPropagation = function() {
    2116                         // if stopPropagation exists run it on the original event
    2117                         if (originalEvent.stopPropagation)
    2118                                 originalEvent.stopPropagation();
    2119                         // otherwise set the cancelBubble property of the original event to true (IE)
    2120                         originalEvent.cancelBubble = true;
    2121                 };
    2122 
    2123                 // Fix timeStamp
    2124                 event.timeStamp = event.timeStamp || now();
    2125 
    2126                 // Fix target property, if necessary
    2127                 if ( !event.target )
    2128                         event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
    2129 
    2130                 // check if target is a textnode (safari)
    2131                 if ( event.target.nodeType == 3 )
    2132                         event.target = event.target.parentNode;
    2133 
    2134                 // Add relatedTarget, if necessary
    2135                 if ( !event.relatedTarget && event.fromElement )
    2136                         event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
    2137 
    2138                 // Calculate pageX/Y if missing and clientX/Y available
    2139                 if ( event.pageX == null && event.clientX != null ) {
    2140                         var doc = document.documentElement, body = document.body;
    2141                         event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
    2142                         event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
    2143                 }
    2144 
    2145                 // Add which for key events
    2146                 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
    2147                         event.which = event.charCode || event.keyCode;
    2148 
    2149                 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
    2150                 if ( !event.metaKey && event.ctrlKey )
    2151                         event.metaKey = event.ctrlKey;
    2152 
    2153                 // Add which for click: 1 == left; 2 == middle; 3 == right
    2154                 // Note: button is not normalized, so don't use it
    2155                 if ( !event.which && event.button )
    2156                         event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
    2157 
    2158                 return event;
    2159         },
    2160 
    2161         proxy: function( fn, proxy ){
    2162                 // Set the guid of unique handler to the same of original handler, so it can be removed
    2163                 proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
    2164                 // So proxy can be declared as an argument
    2165                 return proxy;
    2166         },
    2167 
    2168         special: {
    2169                 ready: {
    2170                         setup: function() {
    2171                                 // Make sure the ready event is setup
    2172                                 bindReady();
    2173                                 return;
    2174                         },
    2175 
    2176                         teardown: function() { return; }
    2177                 },
    2178 
    2179                 mouseenter: {
    2180                         setup: function() {
    2181                                 if ( jQuery.browser.msie ) return false;
    2182                                 jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler);
    2183                                 return true;
    2184                         },
    2185 
    2186                         teardown: function() {
    2187                                 if ( jQuery.browser.msie ) return false;
    2188                                 jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler);
    2189                                 return true;
    2190                         },
    2191 
    2192                         handler: function(event) {
    2193                                 // If we actually just moused on to a sub-element, ignore it
    2194                                 if ( withinElement(event, this) ) return true;
    2195                                 // Execute the right handlers by setting the event type to mouseenter
    2196                                 event.type = "mouseenter";
    2197                                 return jQuery.event.handle.apply(this, arguments);
    2198                         }
    2199                 },
    2200 
    2201                 mouseleave: {
    2202                         setup: function() {
    2203                                 if ( jQuery.browser.msie ) return false;
    2204                                 jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler);
    2205                                 return true;
    2206                         },
    2207 
    2208                         teardown: function() {
    2209                                 if ( jQuery.browser.msie ) return false;
    2210                                 jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler);
    2211                                 return true;
    2212                         },
    2213 
    2214                         handler: function(event) {
    2215                                 // If we actually just moused on to a sub-element, ignore it
    2216                                 if ( withinElement(event, this) ) return true;
    2217                                 // Execute the right handlers by setting the event type to mouseleave
    2218                                 event.type = "mouseleave";
    2219                                 return jQuery.event.handle.apply(this, arguments);
    2220                         }
    2221                 }
    2222         }
    2223 };
    2224 
    2225 jQuery.fn.extend({
    2226         bind: function( type, data, fn ) {
    2227                 return type == "unload" ? this.one(type, data, fn) : this.each(function(){
    2228                         jQuery.event.add( this, type, fn || data, fn && data );
    2229                 });
    2230         },
    2231 
    2232         one: function( type, data, fn ) {
    2233                 var one = jQuery.event.proxy( fn || data, function(event) {
    2234                         jQuery(this).unbind(event, one);
    2235                         return (fn || data).apply( this, arguments );
    2236                 });
    2237                 return this.each(function(){
    2238                         jQuery.event.add( this, type, one, fn && data);
    2239                 });
    2240         },
    2241 
    2242         unbind: function( type, fn ) {
    2243                 return this.each(function(){
    2244                         jQuery.event.remove( this, type, fn );
    2245                 });
    2246         },
    2247 
    2248         trigger: function( type, data, fn ) {
    2249                 return this.each(function(){
    2250                         jQuery.event.trigger( type, data, this, true, fn );
    2251                 });
    2252         },
    2253 
    2254         triggerHandler: function( type, data, fn ) {
    2255                 return this[0] && jQuery.event.trigger( type, data, this[0], false, fn );
    2256         },
    2257 
    2258         toggle: function( fn ) {
    2259                 // Save reference to arguments for access in closure
    2260                 var args = arguments, i = 1;
    2261 
    2262                 // link all the functions, so any of them can unbind this click handler
    2263                 while( i < args.length )
    2264                         jQuery.event.proxy( fn, args[i++] );
    2265 
    2266                 return this.click( jQuery.event.proxy( fn, function(event) {
    2267                         // Figure out which function to execute
    2268                         this.lastToggle = ( this.lastToggle || 0 ) % i;
    2269 
    2270                         // Make sure that clicks stop
    2271                         event.preventDefault();
    2272 
    2273                         // and execute the function
    2274                         return args[ this.lastToggle++ ].apply( this, arguments ) || false;
    2275                 }));
    2276         },
    2277 
    2278         hover: function(fnOver, fnOut) {
    2279                 return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut);
    2280         },
    2281 
    2282         ready: function(fn) {
    2283                 // Attach the listeners
    2284                 bindReady();
    2285 
    2286                 // If the DOM is already ready
    2287                 if ( jQuery.isReady )
    2288                         // Execute the function immediately
    2289                         fn.call( document, jQuery );
    2290 
    2291                 // Otherwise, remember the function for later
    2292                 else
    2293                         // Add the function to the wait list
    2294                         jQuery.readyList.push( function() { return fn.call(this, jQuery); } );
    2295 
    2296                 return this;
     4486                        if ( elem.offsetWidth !== 0 ) {
     4487                                getWH();
     4488                        } else {
     4489                                jQuery.swap( elem, props, getWH );
     4490                        }
     4491
     4492                        return Math.max(0, Math.round(val));
     4493                }
     4494
     4495                return jQuery.curCSS( elem, name, force );
     4496        },
     4497
     4498        curCSS: function( elem, name, force ) {
     4499                var ret, style = elem.style, filter;
     4500
     4501                // IE uses filters for opacity
     4502                if ( !jQuery.support.opacity && name === "opacity" && elem.currentStyle ) {
     4503                        ret = ropacity.test(elem.currentStyle.filter || "") ?
     4504                                (parseFloat(RegExp.$1) / 100) + "" :
     4505                                "";
     4506
     4507                        return ret === "" ?
     4508                                "1" :
     4509                                ret;
     4510                }
     4511
     4512                // Make sure we're using the right name for getting the float value
     4513                if ( rfloat.test( name ) ) {
     4514                        name = styleFloat;
     4515                }
     4516
     4517                if ( !force && style && style[ name ] ) {
     4518                        ret = style[ name ];
     4519
     4520                } else if ( getComputedStyle ) {
     4521
     4522                        // Only "float" is needed here
     4523                        if ( rfloat.test( name ) ) {
     4524                                name = "float";
     4525                        }
     4526
     4527                        name = name.replace( rupper, "-$1" ).toLowerCase();
     4528
     4529                        var defaultView = elem.ownerDocument.defaultView;
     4530
     4531                        if ( !defaultView ) {
     4532                                return null;
     4533                        }
     4534
     4535                        var computedStyle = defaultView.getComputedStyle( elem, null );
     4536
     4537                        if ( computedStyle ) {
     4538                                ret = computedStyle.getPropertyValue( name );
     4539                        }
     4540
     4541                        // We should always get a number back from opacity
     4542                        if ( name === "opacity" && ret === "" ) {
     4543                                ret = "1";
     4544                        }
     4545
     4546                } else if ( elem.currentStyle ) {
     4547                        var camelCase = name.replace(rdashAlpha, fcamelCase);
     4548
     4549                        ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
     4550
     4551                        // From the awesome hack by Dean Edwards
     4552                        // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
     4553
     4554                        // If we're not dealing with a regular pixel number
     4555                        // but a number that has a weird ending, we need to convert it to pixels
     4556                        if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
     4557                                // Remember the original values
     4558                                var left = style.left, rsLeft = elem.runtimeStyle.left;
     4559
     4560                                // Put in the new values to get a computed value out
     4561                                elem.runtimeStyle.left = elem.currentStyle.left;
     4562                                style.left = camelCase === "fontSize" ? "1em" : (ret || 0);
     4563                                ret = style.pixelLeft + "px";
     4564
     4565                                // Revert the changed values
     4566                                style.left = left;
     4567                                elem.runtimeStyle.left = rsLeft;
     4568                        }
     4569                }
     4570
     4571                return ret;
     4572        },
     4573
     4574        // A method for quickly swapping in/out CSS properties to get correct calculations
     4575        swap: function( elem, options, callback ) {
     4576                var old = {};
     4577
     4578                // Remember the old values, and insert the new ones
     4579                for ( var name in options ) {
     4580                        old[ name ] = elem.style[ name ];
     4581                        elem.style[ name ] = options[ name ];
     4582                }
     4583
     4584                callback.call( elem );
     4585
     4586                // Revert the old values
     4587                for ( var name in options ) {
     4588                        elem.style[ name ] = old[ name ];
     4589                }
    22974590        }
    22984591});
    22994592
    2300 jQuery.extend({
    2301         isReady: false,
    2302         readyList: [],
    2303         // Handle when the DOM is ready
    2304         ready: function() {
    2305                 // Make sure that the DOM is not already loaded
    2306                 if ( !jQuery.isReady ) {
    2307                         // Remember that the DOM is ready
    2308                         jQuery.isReady = true;
    2309 
    2310                         // If there are functions bound, to execute
    2311                         if ( jQuery.readyList ) {
    2312                                 // Execute all of them
    2313                                 jQuery.each( jQuery.readyList, function(){
    2314                                         this.call( document );
    2315                                 });
    2316 
    2317                                 // Reset the list of functions
    2318                                 jQuery.readyList = null;
    2319                         }
    2320 
    2321                         // Trigger any bound ready events
    2322                         jQuery(document).triggerHandler("ready");
    2323                 }
    2324         }
    2325 });
    2326 
    2327 var readyBound = false;
    2328 
    2329 function bindReady(){
    2330         if ( readyBound ) return;
    2331         readyBound = true;
    2332 
    2333         // Mozilla, Opera (see further below for it) and webkit nightlies currently support this event
    2334         if ( document.addEventListener && !jQuery.browser.opera)
    2335                 // Use the handy event callback
    2336                 document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
    2337 
    2338         // If IE is used and is not in a frame
    2339         // Continually check to see if the document is ready
    2340         if ( jQuery.browser.msie && window == top ) (function(){
    2341                 if (jQuery.isReady) return;
    2342                 try {
    2343                         // If IE is used, use the trick by Diego Perini
    2344                         // http://javascript.nwbox.com/IEContentLoaded/
    2345                         document.documentElement.doScroll("left");
    2346                 } catch( error ) {
    2347                         setTimeout( arguments.callee, 0 );
    2348                         return;
    2349                 }
    2350                 // and execute any waiting functions
    2351                 jQuery.ready();
    2352         })();
    2353 
    2354         if ( jQuery.browser.opera )
    2355                 document.addEventListener( "DOMContentLoaded", function () {
    2356                         if (jQuery.isReady) return;
    2357                         for (var i = 0; i < document.styleSheets.length; i++)
    2358                                 if (document.styleSheets[i].disabled) {
    2359                                         setTimeout( arguments.callee, 0 );
    2360                                         return;
    2361                                 }
    2362                         // and execute any waiting functions
    2363                         jQuery.ready();
    2364                 }, false);
    2365 
    2366         if ( jQuery.browser.safari ) {
    2367                 var numStyles;
    2368                 (function(){
    2369                         if (jQuery.isReady) return;
    2370                         if ( document.readyState != "loaded" && document.readyState != "complete" ) {
    2371                                 setTimeout( arguments.callee, 0 );
    2372                                 return;
    2373                         }
    2374                         if ( numStyles === undefined )
    2375                                 numStyles = jQuery("style, link[rel=stylesheet]").length;
    2376                         if ( document.styleSheets.length != numStyles ) {
    2377                                 setTimeout( arguments.callee, 0 );
    2378                                 return;
    2379                         }
    2380                         // and execute any waiting functions
    2381                         jQuery.ready();
    2382                 })();
    2383         }
    2384 
    2385         // A fallback to window.onload, that will always work
    2386         jQuery.event.add( window, "load", jQuery.ready );
     4593if ( jQuery.expr && jQuery.expr.filters ) {
     4594        jQuery.expr.filters.hidden = function( elem ) {
     4595                var width = elem.offsetWidth, height = elem.offsetHeight,
     4596                        skip = elem.nodeName.toLowerCase() === "tr";
     4597
     4598                return width === 0 && height === 0 && !skip ?
     4599                        true :
     4600                        width > 0 && height > 0 && !skip ?
     4601                                false :
     4602                                jQuery.curCSS(elem, "display") === "none";
     4603        };
     4604
     4605        jQuery.expr.filters.visible = function( elem ) {
     4606                return !jQuery.expr.filters.hidden( elem );
     4607        };
    23874608}
    2388 
    2389 jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
    2390         "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
    2391         "submit,keydown,keypress,keyup,error").split(","), function(i, name){
    2392 
    2393         // Handle event binding
    2394         jQuery.fn[name] = function(fn){
    2395                 return fn ? this.bind(name, fn) : this.trigger(name);
    2396         };
    2397 });
    2398 
    2399 // Checks if an event happened on an element within another element
    2400 // Used in jQuery.event.special.mouseenter and mouseleave handlers
    2401 var withinElement = function(event, elem) {
    2402         // Check if mouse(over|out) are still within the same parent element
    2403         var parent = event.relatedTarget;
    2404         // Traverse up the tree
    2405         while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; }
    2406         // Return true if we actually just moused on to a sub-element
    2407         return parent == elem;
    2408 };
    2409 
    2410 // Prevent memory leaks in IE
    2411 // And prevent errors on refresh with events like mouseover in other browsers
    2412 // Window isn't included so as not to unbind existing unload events
    2413 jQuery(window).bind("unload", function() {
    2414         jQuery("*").add(document).unbind();
    2415 });
     4609var jsc = now(),
     4610        rscript = /<script(.|\s)*?\/script>/gi,
     4611        rselectTextarea = /select|textarea/i,
     4612        rinput = /color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,
     4613        jsre = /=\?(&|$)/,
     4614        rquery = /\?/,
     4615        rts = /(\?|&)_=.*?(&|$)/,
     4616        rurl = /^(\w+:)?\/\/([^\/?#]+)/,
     4617        r20 = /%20/g;
     4618
    24164619jQuery.fn.extend({
    24174620        // Keep a copy of the old load
     
    24194622
    24204623        load: function( url, params, callback ) {
    2421                 if ( typeof url != 'string' )
     4624                if ( typeof url !== "string" ) {
    24224625                        return this._load( url );
     4626
     4627                // Don't do a request if no elements are being requested
     4628                } else if ( !this.length ) {
     4629                        return this;
     4630                }
    24234631
    24244632                var off = url.indexOf(" ");
     
    24284636                }
    24294637
    2430                 callback = callback || function(){};
    2431 
    24324638                // Default to a GET request
    24334639                var type = "GET";
    24344640
    24354641                // If the second parameter was provided
    2436                 if ( params )
     4642                if ( params ) {
    24374643                        // If it's a function
    24384644                        if ( jQuery.isFunction( params ) ) {
     
    24424648
    24434649                        // Otherwise, build a param string
    2444                         } else {
    2445                                 params = jQuery.param( params );
     4650                        } else if ( typeof params === "object" ) {
     4651                                params = jQuery.param( params, jQuery.ajaxSettings.traditional );
    24464652                                type = "POST";
    24474653                        }
     4654                }
    24484655
    24494656                var self = this;
     
    24554662                        dataType: "html",
    24564663                        data: params,
    2457                         complete: function(res, status){
     4664                        complete: function( res, status ) {
    24584665                                // If successful, inject the HTML into all the matched elements
    2459                                 if ( status == "success" || status == "notmodified" )
     4666                                if ( status === "success" || status === "notmodified" ) {
    24604667                                        // See if a selector was specified
    24614668                                        self.html( selector ?
    24624669                                                // Create a dummy div to hold the results
    2463                                                 jQuery("<div/>")
     4670                                                jQuery("<div />")
    24644671                                                        // inject the contents of the document in, removing the scripts
    24654672                                                        // to avoid any 'Permission Denied' errors in IE
    2466                                                         .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
     4673                                                        .append(res.responseText.replace(rscript, ""))
    24674674
    24684675                                                        // Locate the specified elements
     
    24714678                                                // If not, just inject the full result
    24724679                                                res.responseText );
    2473 
    2474                                 self.each( callback, [res.responseText, status, res] );
     4680                                }
     4681
     4682                                if ( callback ) {
     4683                                        self.each( callback, [res.responseText, status, res] );
     4684                                }
    24754685                        }
    24764686                });
     4687
    24774688                return this;
    24784689        },
     
    24824693        },
    24834694        serializeArray: function() {
    2484                 return this.map(function(){
    2485                         return jQuery.nodeName(this, "form") ?
    2486                                 jQuery.makeArray(this.elements) : this;
     4695                return this.map(function() {
     4696                        return this.elements ? jQuery.makeArray(this.elements) : this;
    24874697                })
    2488                 .filter(function(){
     4698                .filter(function() {
    24894699                        return this.name && !this.disabled &&
    2490                                 (this.checked || /select|textarea/i.test(this.nodeName) ||
    2491                                         /text|hidden|password/i.test(this.type));
     4700                                (this.checked || rselectTextarea.test(this.nodeName) ||
     4701                                        rinput.test(this.type));
    24924702                })
    2493                 .map(function(i, elem){
     4703                .map(function( i, elem ) {
    24944704                        var val = jQuery(this).val();
    2495                         return val == null ? null :
    2496                                 val.constructor == Array ?
    2497                                         jQuery.map( val, function(val, i){
    2498                                                 return {name: elem.name, value: val};
     4705
     4706                        return val == null ?
     4707                                null :
     4708                                jQuery.isArray(val) ?
     4709                                        jQuery.map( val, function( val, i ) {
     4710                                                return { name: elem.name, value: val };
    24994711                                        }) :
    2500                                         {name: elem.name, value: val};
     4712                                        { name: elem.name, value: val };
    25014713                }).get();
    25024714        }
     
    25044716
    25054717// Attach a bunch of functions for handling common AJAX events
    2506 jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
    2507         jQuery.fn[o] = function(f){
     4718jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) {
     4719        jQuery.fn[o] = function( f ) {
    25084720                return this.bind(o, f);
    25094721        };
    25104722});
    25114723
    2512 var jsc = now();
    2513 
    25144724jQuery.extend({
     4725
    25154726        get: function( url, data, callback, type ) {
    2516                 // shift arguments if data argument was ommited
     4727                // shift arguments if data argument was omited
    25174728                if ( jQuery.isFunction( data ) ) {
     4729                        type = type || callback;
    25184730                        callback = data;
    25194731                        data = null;
     
    25384750
    25394751        post: function( url, data, callback, type ) {
     4752                // shift arguments if data argument was omited
    25404753                if ( jQuery.isFunction( data ) ) {
     4754                        type = type || callback;
    25414755                        callback = data;
    25424756                        data = {};
     
    25604774                global: true,
    25614775                type: "GET",
    2562                 timeout: 0,
    25634776                contentType: "application/x-www-form-urlencoded",
    25644777                processData: true,
    25654778                async: true,
     4779                /*
     4780                timeout: 0,
    25664781                data: null,
    25674782                username: null,
    25684783                password: null,
     4784                traditional: false,
     4785                */
     4786                // Create the request object; Microsoft failed to properly
     4787                // implement the XMLHttpRequest in IE7 (can't request local files),
     4788                // so we use the ActiveXObject when it is available
     4789                // This function can be overriden by calling jQuery.ajaxSetup
     4790                xhr: window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject) ?
     4791                        function() {
     4792                                return new window.XMLHttpRequest();
     4793                        } :
     4794                        function() {
     4795                                try {
     4796                                        return new window.ActiveXObject("Microsoft.XMLHTTP");
     4797                                } catch(e) {}
     4798                        },
    25694799                accepts: {
    25704800                        xml: "application/xml, text/xml",
     
    25794809        // Last-Modified header cache for next request
    25804810        lastModified: {},
    2581 
    2582         ajax: function( s ) {
    2583                 // Extend the settings, but re-extend 's' so that it can be
    2584                 // checked again later (in the test suite, specifically)
    2585                 s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
    2586 
    2587                 var jsonp, jsre = /=\?(&|$)/g, status, data,
     4811        etag: {},
     4812
     4813        ajax: function( origSettings ) {
     4814                var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings);
     4815               
     4816                var jsonp, status, data,
     4817                        callbackContext = origSettings && origSettings.context || s,
    25884818                        type = s.type.toUpperCase();
    25894819
    25904820                // convert data if not already a string
    2591                 if ( s.data && s.processData && typeof s.data != "string" )
    2592                         s.data = jQuery.param(s.data);
     4821                if ( s.data && s.processData && typeof s.data !== "string" ) {
     4822                        s.data = jQuery.param( s.data, s.traditional );
     4823                }
    25934824
    25944825                // Handle JSONP Parameter Callbacks
    2595                 if ( s.dataType == "jsonp" ) {
    2596                         if ( type == "GET" ) {
    2597                                 if ( !s.url.match(jsre) )
    2598                                         s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
    2599                         } else if ( !s.data || !s.data.match(jsre) )
     4826                if ( s.dataType === "jsonp" ) {
     4827                        if ( type === "GET" ) {
     4828                                if ( !jsre.test( s.url ) ) {
     4829                                        s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";
     4830                                }
     4831                        } else if ( !s.data || !jsre.test(s.data) ) {
    26004832                                s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
     4833                        }
    26014834                        s.dataType = "json";
    26024835                }
    26034836
    26044837                // Build temporary JSONP function
    2605                 if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
    2606                         jsonp = "jsonp" + jsc++;
     4838                if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
     4839                        jsonp = s.jsonpCallback || ("jsonp" + jsc++);
    26074840
    26084841                        // Replace the =? sequence both in the query string and the data
    2609                         if ( s.data )
     4842                        if ( s.data ) {
    26104843                                s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
     4844                        }
     4845
    26114846                        s.url = s.url.replace(jsre, "=" + jsonp + "$1");
    26124847
     
    26164851
    26174852                        // Handle JSONP-style loading
    2618                         window[ jsonp ] = function(tmp){
     4853                        window[ jsonp ] = window[ jsonp ] || function( tmp ) {
    26194854                                data = tmp;
    26204855                                success();
     
    26224857                                // Garbage collect
    26234858                                window[ jsonp ] = undefined;
    2624                                 try{ delete window[ jsonp ]; } catch(e){}
    2625                                 if ( head )
     4859
     4860                                try {
     4861                                        delete window[ jsonp ];
     4862                                } catch(e) {}
     4863
     4864                                if ( head ) {
    26264865                                        head.removeChild( script );
     4866                                }
    26274867                        };
    26284868                }
    26294869
    2630                 if ( s.dataType == "script" && s.cache == null )
     4870                if ( s.dataType === "script" && s.cache === null ) {
    26314871                        s.cache = false;
    2632 
    2633                 if ( s.cache === false && type == "GET" ) {
     4872                }
     4873
     4874                if ( s.cache === false && type === "GET" ) {
    26344875                        var ts = now();
     4876
    26354877                        // try replacing _= if it is there
    2636                         var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
     4878                        var ret = s.url.replace(rts, "$1_=" + ts + "$2");
     4879
    26374880                        // if nothing was replaced, add timestamp to the end
    2638                         s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
     4881                        s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
    26394882                }
    26404883
    26414884                // If data is available, append data to url for get requests
    2642                 if ( s.data && type == "GET" ) {
    2643                         s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
    2644 
    2645                         // IE likes to send both get and post data, prevent this
    2646                         s.data = null;
     4885                if ( s.data && type === "GET" ) {
     4886                        s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
    26474887                }
    26484888
    26494889                // Watch for a new set of requests
    2650                 if ( s.global && ! jQuery.active++ )
     4890                if ( s.global && ! jQuery.active++ ) {
    26514891                        jQuery.event.trigger( "ajaxStart" );
     4892                }
    26524893
    26534894                // Matches an absolute URL, and saves the domain
    2654                 var remote = /^(?:\w+:)?\/\/([^\/?#]+)/;
     4895                var parts = rurl.exec( s.url ),
     4896                        remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host);
    26554897
    26564898                // If we're requesting a remote document
    26574899                // and trying to load JSON or Script with a GET
    2658                 if ( s.dataType == "script" && type == "GET"
    2659                                 && remote.test(s.url) && remote.exec(s.url)[1] != location.host ){
    2660                         var head = document.getElementsByTagName("head")[0];
     4900                if ( s.dataType === "script" && type === "GET" && remote ) {
     4901                        var head = document.getElementsByTagName("head")[0] || document.documentElement;
    26614902                        var script = document.createElement("script");
    26624903                        script.src = s.url;
    2663                         if (s.scriptCharset)
     4904                        if ( s.scriptCharset ) {
    26644905                                script.charset = s.scriptCharset;
     4906                        }
    26654907
    26664908                        // Handle Script loading
     
    26694911
    26704912                                // Attach handlers for all browsers
    2671                                 script.onload = script.onreadystatechange = function(){
     4913                                script.onload = script.onreadystatechange = function() {
    26724914                                        if ( !done && (!this.readyState ||
    2673                                                         this.readyState == "loaded" || this.readyState == "complete") ) {
     4915                                                        this.readyState === "loaded" || this.readyState === "complete") ) {
    26744916                                                done = true;
    26754917                                                success();
    26764918                                                complete();
    2677                                                 head.removeChild( script );
     4919
     4920                                                // Handle memory leak in IE
     4921                                                script.onload = script.onreadystatechange = null;
     4922                                                if ( head && script.parentNode ) {
     4923                                                        head.removeChild( script );
     4924                                                }
    26784925                                        }
    26794926                                };
    26804927                        }
    26814928
    2682                         head.appendChild(script);
     4929                        // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
     4930                        // This arises when a base node is used (#2709 and #4378).
     4931                        head.insertBefore( script, head.firstChild );
    26834932
    26844933                        // We handle everything using the script element injection
     
    26884937                var requestDone = false;
    26894938
    2690                 // Create the request object; Microsoft failed to properly
    2691                 // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
    2692                 var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
     4939                // Create the request object
     4940                var xhr = s.xhr();
     4941
     4942                if ( !xhr ) {
     4943                        return;
     4944                }
    26934945
    26944946                // Open the socket
    26954947                // Passing null username, generates a login popup on Opera (#2865)
    2696                 if( s.username )
     4948                if ( s.username ) {
    26974949                        xhr.open(type, s.url, s.async, s.username, s.password);
    2698                 else
     4950                } else {
    26994951                        xhr.open(type, s.url, s.async);
     4952                }
    27004953
    27014954                // Need an extra try/catch for cross domain requests in Firefox 3
    27024955                try {
    27034956                        // Set the correct header, if data is being sent
    2704                         if ( s.data )
     4957                        if ( s.data || origSettings && origSettings.contentType ) {
    27054958                                xhr.setRequestHeader("Content-Type", s.contentType);
    2706 
    2707                         // Set the If-Modified-Since header, if ifModified mode.
    2708                         if ( s.ifModified )
    2709                                 xhr.setRequestHeader("If-Modified-Since",
    2710                                         jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
     4959                        }
     4960
     4961                        // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
     4962                        if ( s.ifModified ) {
     4963                                if ( jQuery.lastModified[s.url] ) {
     4964                                        xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);
     4965                                }
     4966
     4967                                if ( jQuery.etag[s.url] ) {
     4968                                        xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]);
     4969                                }
     4970                        }
    27114971
    27124972                        // Set header so the called script knows that it's an XMLHttpRequest
    2713                         xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
     4973                        // Only send the header if it's not a remote XHR
     4974                        if ( !remote ) {
     4975                                xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
     4976                        }
    27144977
    27154978                        // Set the Accepts header for the server, depending on the dataType
     
    27174980                                s.accepts[ s.dataType ] + ", */*" :
    27184981                                s.accepts._default );
    2719                 } catch(e){}
    2720 
    2721                 // Allow custom headers/mimetypes
    2722                 if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {
    2723                         // cleanup active request counter
    2724                         s.global && jQuery.active--;
     4982                } catch(e) {}
     4983
     4984                // Allow custom headers/mimetypes and early abort
     4985                if ( s.beforeSend && s.beforeSend.call(callbackContext, xhr, s) === false ) {
     4986                        // Handle the global AJAX counter
     4987                        if ( s.global && ! --jQuery.active ) {
     4988                                jQuery.event.trigger( "ajaxStop" );
     4989                        }
     4990
    27254991                        // close opended socket
    27264992                        xhr.abort();
     
    27284994                }
    27294995
    2730                 if ( s.global )
    2731                         jQuery.event.trigger("ajaxSend", [xhr, s]);
     4996                if ( s.global ) {
     4997                        trigger("ajaxSend", [xhr, s]);
     4998                }
    27324999
    27335000                // Wait for a response to come back
    2734                 var onreadystatechange = function(isTimeout){
     5001                var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {
     5002                        // The request was aborted
     5003                        if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) {
     5004                                // Opera doesn't call onreadystatechange before this point
     5005                                // so we simulate the call
     5006                                if ( !requestDone ) {
     5007                                        complete();
     5008                                }
     5009
     5010                                requestDone = true;
     5011                                if ( xhr ) {
     5012                                        xhr.onreadystatechange = jQuery.noop;
     5013                                }
     5014
    27355015                        // The transfer is complete and the data is available, or the request timed out
    2736                         if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {
     5016                        } else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
    27375017                                requestDone = true;
    2738 
    2739                                 // clear poll interval
    2740                                 if (ival) {
    2741                                         clearInterval(ival);
    2742                                         ival = null;
    2743                                 }
    2744 
    2745                                 status = isTimeout == "timeout" && "timeout" ||
    2746                                         !jQuery.httpSuccess( xhr ) && "error" ||
    2747                                         s.ifModified && jQuery.httpNotModified( xhr, s.url ) && "notmodified" ||
    2748                                         "success";
    2749 
    2750                                 if ( status == "success" ) {
     5018                                xhr.onreadystatechange = jQuery.noop;
     5019
     5020                                status = isTimeout === "timeout" ?
     5021                                        "timeout" :
     5022                                        !jQuery.httpSuccess( xhr ) ?
     5023                                                "error" :
     5024                                                s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?
     5025                                                        "notmodified" :
     5026                                                        "success";
     5027
     5028                                var errMsg;
     5029
     5030                                if ( status === "success" ) {
    27515031                                        // Watch for, and catch, XML document parse errors
    27525032                                        try {
    27535033                                                // process the data (runs the xml through httpData regardless of callback)
    2754                                                 data = jQuery.httpData( xhr, s.dataType, s.dataFilter );
    2755                                         } catch(e) {
     5034                                                data = jQuery.httpData( xhr, s.dataType, s );
     5035                                        } catch(err) {
    27565036                                                status = "parsererror";
     5037                                                errMsg = err;
    27575038                                        }
    27585039                                }
    27595040
    27605041                                // Make sure that the request was successful or notmodified
    2761                                 if ( status == "success" ) {
    2762                                         // Cache Last-Modified header, if ifModified mode.
    2763                                         var modRes;
    2764                                         try {
    2765                                                 modRes = xhr.getResponseHeader("Last-Modified");
    2766                                         } catch(e) {} // swallow exception thrown by FF if header is not available
    2767 
    2768                                         if ( s.ifModified && modRes )
    2769                                                 jQuery.lastModified[s.url] = modRes;
    2770 
     5042                                if ( status === "success" || status === "notmodified" ) {
    27715043                                        // JSONP handles its own success callback
    2772                                         if ( !jsonp )
     5044                                        if ( !jsonp ) {
    27735045                                                success();
    2774                                 } else
    2775                                         jQuery.handleError(s, xhr, status);
     5046                                        }
     5047                                } else {
     5048                                        jQuery.handleError(s, xhr, status, errMsg);
     5049                                }
    27765050
    27775051                                // Fire the complete handlers
    27785052                                complete();
    27795053
     5054                                if ( isTimeout === "timeout" ) {
     5055                                        xhr.abort();
     5056                                }
     5057
    27805058                                // Stop memory leaks
    2781                                 if ( s.async )
     5059                                if ( s.async ) {
    27825060                                        xhr = null;
     5061                                }
    27835062                        }
    27845063                };
    27855064
    2786                 if ( s.async ) {
    2787                         // don't attach the handler to the request, just poll it instead
    2788                         var ival = setInterval(onreadystatechange, 13);
    2789 
    2790                         // Timeout checker
    2791                         if ( s.timeout > 0 )
    2792                                 setTimeout(function(){
    2793                                         // Check to see if the request is still happening
    2794                                         if ( xhr ) {
    2795                                                 // Cancel the request
    2796                                                 xhr.abort();
    2797 
    2798                                                 if( !requestDone )
    2799                                                         onreadystatechange( "timeout" );
    2800                                         }
    2801                                 }, s.timeout);
     5065                // Override the abort handler, if we can (IE doesn't allow it, but that's OK)
     5066                // Opera doesn't fire onreadystatechange at all on abort
     5067                try {
     5068                        var oldAbort = xhr.abort;
     5069                        xhr.abort = function() {
     5070                                if ( xhr ) {
     5071                                        oldAbort.call( xhr );
     5072                                }
     5073
     5074                                onreadystatechange( "abort" );
     5075                        };
     5076                } catch(e) { }
     5077
     5078                // Timeout checker
     5079                if ( s.async && s.timeout > 0 ) {
     5080                        setTimeout(function() {
     5081                                // Check to see if the request is still happening
     5082                                if ( xhr && !requestDone ) {
     5083                                        onreadystatechange( "timeout" );
     5084                                }
     5085                        }, s.timeout);
    28025086                }
    28035087
    28045088                // Send the data
    28055089                try {
    2806                         xhr.send(s.data);
     5090                        xhr.send( type === "POST" || type === "PUT" || type === "DELETE" ? s.data : null );
    28075091                } catch(e) {
    28085092                        jQuery.handleError(s, xhr, null, e);
     5093                        // Fire the complete handlers
     5094                        complete();
    28095095                }
    28105096
    28115097                // firefox 1.5 doesn't fire statechange for sync requests
    2812                 if ( !s.async )
     5098                if ( !s.async ) {
    28135099                        onreadystatechange();
    2814 
    2815                 function success(){
     5100                }
     5101
     5102                function success() {
    28165103                        // If a local callback was specified, fire it and pass it the data
    2817                         if ( s.success )
    2818                                 s.success( data, status );
     5104                        if ( s.success ) {
     5105                                s.success.call( callbackContext, data, status, xhr );
     5106                        }
    28195107
    28205108                        // Fire the global callback
    2821                         if ( s.global )
    2822                                 jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
    2823                 }
    2824 
    2825                 function complete(){
     5109                        if ( s.global ) {
     5110                                trigger( "ajaxSuccess", [xhr, s] );
     5111                        }
     5112                }
     5113
     5114                function complete() {
    28265115                        // Process result
    2827                         if ( s.complete )
    2828                                 s.complete(xhr, status);
     5116                        if ( s.complete ) {
     5117                                s.complete.call( callbackContext, xhr, status);
     5118                        }
    28295119
    28305120                        // The request was completed
    2831                         if ( s.global )
    2832                                 jQuery.event.trigger( "ajaxComplete", [xhr, s] );
     5121                        if ( s.global ) {
     5122                                trigger( "ajaxComplete", [xhr, s] );
     5123                        }
    28335124
    28345125                        // Handle the global AJAX counter
    2835                         if ( s.global && ! --jQuery.active )
     5126                        if ( s.global && ! --jQuery.active ) {
    28365127                                jQuery.event.trigger( "ajaxStop" );
     5128                        }
     5129                }
     5130               
     5131                function trigger(type, args) {
     5132                        (s.context ? jQuery(s.context) : jQuery.event).trigger(type, args);
    28375133                }
    28385134
     
    28435139        handleError: function( s, xhr, status, e ) {
    28445140                // If a local callback was specified, fire it
    2845                 if ( s.error ) s.error( xhr, status, e );
     5141                if ( s.error ) {
     5142                        s.error.call( s.context || s, xhr, status, e );
     5143                }
    28465144
    28475145                // Fire the global callback
    2848                 if ( s.global )
    2849                         jQuery.event.trigger( "ajaxError", [xhr, s, e] );
     5146                if ( s.global ) {
     5147                        (s.context ? jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] );
     5148                }
    28505149        },
    28515150
     
    28575156                try {
    28585157                        // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
    2859                         return !xhr.status && location.protocol == "file:" ||
    2860                                 ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223 ||
    2861                                 jQuery.browser.safari && xhr.status == undefined;
    2862                 } catch(e){}
     5158                        return !xhr.status && location.protocol === "file:" ||
     5159                                // Opera returns 0 when status is 304
     5160                                ( xhr.status >= 200 && xhr.status < 300 ) ||
     5161                                xhr.status === 304 || xhr.status === 1223 || xhr.status === 0;
     5162                } catch(e) {}
     5163
    28635164                return false;
    28645165        },
     
    28665167        // Determines if an XMLHttpRequest returns NotModified
    28675168        httpNotModified: function( xhr, url ) {
    2868                 try {
    2869                         var xhrRes = xhr.getResponseHeader("Last-Modified");
    2870 
    2871                         // Firefox always returns 200. check Last-Modified date
    2872                         return xhr.status == 304 || xhrRes == jQuery.lastModified[url] ||
    2873                                 jQuery.browser.safari && xhr.status == undefined;
    2874                 } catch(e){}
    2875                 return false;
    2876         },
    2877 
    2878         httpData: function( xhr, type, filter ) {
    2879                 var ct = xhr.getResponseHeader("content-type"),
    2880                         xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,
     5169                var lastModified = xhr.getResponseHeader("Last-Modified"),
     5170                        etag = xhr.getResponseHeader("Etag");
     5171
     5172                if ( lastModified ) {
     5173                        jQuery.lastModified[url] = lastModified;
     5174                }
     5175
     5176                if ( etag ) {
     5177                        jQuery.etag[url] = etag;
     5178                }
     5179
     5180                // Opera returns 0 when status is 304
     5181                return xhr.status === 304 || xhr.status === 0;
     5182        },
     5183
     5184        httpData: function( xhr, type, s ) {
     5185                var ct = xhr.getResponseHeader("content-type") || "",
     5186                        xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
    28815187                        data = xml ? xhr.responseXML : xhr.responseText;
    28825188
    2883                 if ( xml && data.documentElement.tagName == "parsererror" )
    2884                         throw "parsererror";
    2885                        
     5189                if ( xml && data.documentElement.nodeName === "parsererror" ) {
     5190                        jQuery.error( "parsererror" );
     5191                }
     5192
    28865193                // Allow a pre-filtering function to sanitize the response
    2887                 if( filter )
    2888                         data = filter( data, type );
    2889 
    2890                 // If the type is "script", eval it in global context
    2891                 if ( type == "script" )
    2892                         jQuery.globalEval( data );
    2893 
    2894                 // Get the JavaScript object, if JSON is used.
    2895                 if ( type == "json" )
    2896                         data = eval("(" + data + ")");
     5194                // s is checked to keep backwards compatibility
     5195                if ( s && s.dataFilter ) {
     5196                        data = s.dataFilter( data, type );
     5197                }
     5198
     5199                // The filter can actually parse the response
     5200                if ( typeof data === "string" ) {
     5201                        // Get the JavaScript object, if JSON is used.
     5202                        if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {
     5203                                data = jQuery.parseJSON( data );
     5204
     5205                        // If the type is "script", eval it in global context
     5206                        } else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {
     5207                                jQuery.globalEval( data );
     5208                        }
     5209                }
    28975210
    28985211                return data;
     
    29015214        // Serialize an array of form elements or a set of
    29025215        // key/values into a query string
    2903         param: function( a ) {
     5216        param: function( a, traditional ) {
    29045217                var s = [];
    2905 
    2906                 // If an array was passed in, assume that it is an array
    2907                 // of form elements
    2908                 if ( a.constructor == Array || a.jquery )
     5218               
     5219                // Set traditional to true for jQuery <= 1.3.2 behavior.
     5220                if ( traditional === undefined ) {
     5221                        traditional = jQuery.ajaxSettings.traditional;
     5222                }
     5223               
     5224                // If an array was passed in, assume that it is an array of form elements.
     5225                if ( jQuery.isArray(a) || a.jquery ) {
    29095226                        // Serialize the form elements
    2910                         jQuery.each( a, function(){
    2911                                 s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) );
     5227                        jQuery.each( a, function() {
     5228                                add( this.name, this.value );
    29125229                        });
    2913 
    2914                 // Otherwise, assume that it's an object of key/value pairs
    2915                 else
    2916                         // Serialize the key/values
    2917                         for ( var j in a )
    2918                                 // If the value is an array then the key names need to be repeated
    2919                                 if ( a[j] && a[j].constructor == Array )
    2920                                         jQuery.each( a[j], function(){
    2921                                                 s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) );
    2922                                         });
    2923                                 else
    2924                                         s.push( encodeURIComponent(j) + "=" + encodeURIComponent( jQuery.isFunction(a[j]) ? a[j]() : a[j] ) );
     5230                       
     5231                } else {
     5232                        // If traditional, encode the "old" way (the way 1.3.2 or older
     5233                        // did it), otherwise encode params recursively.
     5234                        for ( var prefix in a ) {
     5235                                buildParams( prefix, a[prefix] );
     5236                        }
     5237                }
    29255238
    29265239                // Return the resulting serialization
    2927                 return s.join("&").replace(/%20/g, "+");
    2928         }
    2929 
     5240                return s.join("&").replace(r20, "+");
     5241
     5242                function buildParams( prefix, obj ) {
     5243                        if ( jQuery.isArray(obj) ) {
     5244                                // Serialize array item.
     5245                                jQuery.each( obj, function( i, v ) {
     5246                                        if ( traditional ) {
     5247                                                // Treat each array item as a scalar.
     5248                                                add( prefix, v );
     5249                                        } else {
     5250                                                // If array item is non-scalar (array or object), encode its
     5251                                                // numeric index to resolve deserialization ambiguity issues.
     5252                                                // Note that rack (as of 1.0.0) can't currently deserialize
     5253                                                // nested arrays properly, and attempting to do so may cause
     5254                                                // a server error. Possible fixes are to modify rack's
     5255                                                // deserialization algorithm or to provide an option or flag
     5256                                                // to force array serialization to be shallow.
     5257                                                buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v );
     5258                                        }
     5259                                });
     5260                                       
     5261                        } else if ( !traditional && obj != null && typeof obj === "object" ) {
     5262                                // Serialize object item.
     5263                                jQuery.each( obj, function( k, v ) {
     5264                                        buildParams( prefix + "[" + k + "]", v );
     5265                                });
     5266                                       
     5267                        } else {
     5268                                // Serialize scalar item.
     5269                                add( prefix, obj );
     5270                        }
     5271                }
     5272
     5273                function add( key, value ) {
     5274                        // If value is a function, invoke it and return its value
     5275                        value = jQuery.isFunction(value) ? value() : value;
     5276                        s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
     5277                }
     5278        }
    29305279});
     5280var elemdisplay = {},
     5281        rfxtypes = /toggle|show|hide/,
     5282        rfxnum = /^([+-]=)?([\d+-.]+)(.*)$/,
     5283        timerId,
     5284        fxAttrs = [
     5285                // height animations
     5286                [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
     5287                // width animations
     5288                [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
     5289                // opacity animations
     5290                [ "opacity" ]
     5291        ];
     5292
    29315293jQuery.fn.extend({
    2932         show: function(speed,callback){
    2933                 return speed ?
    2934                         this.animate({
    2935                                 height: "show", width: "show", opacity: "show"
    2936                         }, speed, callback) :
    2937 
    2938                         this.filter(":hidden").each(function(){
    2939                                 this.style.display = this.oldblock || "";
    2940                                 if ( jQuery.css(this,"display") == "none" ) {
    2941                                         var elem = jQuery("<" + this.tagName + " />").appendTo("body");
    2942                                         this.style.display = elem.css("display");
    2943                                         // handle an edge condition where css is - div { display:none; } or similar
    2944                                         if (this.style.display == "none")
    2945                                                 this.style.display = "block";
    2946                                         elem.remove();
    2947                                 }
    2948                         }).end();
    2949         },
    2950 
    2951         hide: function(speed,callback){
    2952                 return speed ?
    2953                         this.animate({
    2954                                 height: "hide", width: "hide", opacity: "hide"
    2955                         }, speed, callback) :
    2956 
    2957                         this.filter(":visible").each(function(){
    2958                                 this.oldblock = this.oldblock || jQuery.css(this,"display");
    2959                                 this.style.display = "none";
    2960                         }).end();
     5294        show: function( speed, callback ) {
     5295                if ( speed || speed === 0) {
     5296                        return this.animate( genFx("show", 3), speed, callback);
     5297
     5298                } else {
     5299                        for ( var i = 0, l = this.length; i < l; i++ ) {
     5300                                var old = jQuery.data(this[i], "olddisplay");
     5301
     5302                                this[i].style.display = old || "";
     5303
     5304                                if ( jQuery.css(this[i], "display") === "none" ) {
     5305                                        var nodeName = this[i].nodeName, display;
     5306
     5307                                        if ( elemdisplay[ nodeName ] ) {
     5308                                                display = elemdisplay[ nodeName ];
     5309
     5310                                        } else {
     5311                                                var elem = jQuery("<" + nodeName + " />").appendTo("body");
     5312
     5313                                                display = elem.css("display");
     5314
     5315                                                if ( display === "none" ) {
     5316                                                        display = "block";
     5317                                                }
     5318
     5319                                                elem.remove();
     5320
     5321                                                elemdisplay[ nodeName ] = display;
     5322                                        }
     5323
     5324                                        jQuery.data(this[i], "olddisplay", display);
     5325                                }
     5326                        }
     5327
     5328                        // Set the display of the elements in a second loop
     5329                        // to avoid the constant reflow
     5330                        for ( var j = 0, k = this.length; j < k; j++ ) {
     5331                                this[j].style.display = jQuery.data(this[j], "olddisplay") || "";
     5332                        }
     5333
     5334                        return this;
     5335                }
     5336        },
     5337
     5338        hide: function( speed, callback ) {
     5339                if ( speed || speed === 0 ) {
     5340                        return this.animate( genFx("hide", 3), speed, callback);
     5341
     5342                } else {
     5343                        for ( var i = 0, l = this.length; i < l; i++ ) {
     5344                                var old = jQuery.data(this[i], "olddisplay");
     5345                                if ( !old && old !== "none" ) {
     5346                                        jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
     5347                                }
     5348                        }
     5349
     5350                        // Set the display of the elements in a second loop
     5351                        // to avoid the constant reflow
     5352                        for ( var j = 0, k = this.length; j < k; j++ ) {
     5353                                this[j].style.display = "none";
     5354                        }
     5355
     5356                        return this;
     5357                }
    29615358        },
    29625359
     
    29645361        _toggle: jQuery.fn.toggle,
    29655362
    2966         toggle: function( fn, fn2 ){
    2967                 return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
    2968                         this._toggle.apply( this, arguments ) :
    2969                         fn ?
    2970                                 this.animate({
    2971                                         height: "toggle", width: "toggle", opacity: "toggle"
    2972                                 }, fn, fn2) :
    2973                                 this.each(function(){
    2974                                         jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
    2975                                 });
    2976         },
    2977 
    2978         slideDown: function(speed,callback){
    2979                 return this.animate({height: "show"}, speed, callback);
    2980         },
    2981 
    2982         slideUp: function(speed,callback){
    2983                 return this.animate({height: "hide"}, speed, callback);
    2984         },
    2985 
    2986         slideToggle: function(speed, callback){
    2987                 return this.animate({height: "toggle"}, speed, callback);
    2988         },
    2989 
    2990         fadeIn: function(speed, callback){
    2991                 return this.animate({opacity: "show"}, speed, callback);
    2992         },
    2993 
    2994         fadeOut: function(speed, callback){
    2995                 return this.animate({opacity: "hide"}, speed, callback);
    2996         },
    2997 
    2998         fadeTo: function(speed,to,callback){
    2999                 return this.animate({opacity: to}, speed, callback);
     5363        toggle: function( fn, fn2 ) {
     5364                var bool = typeof fn === "boolean";
     5365
     5366                if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
     5367                        this._toggle.apply( this, arguments );
     5368
     5369                } else if ( fn == null || bool ) {
     5370                        this.each(function() {
     5371                                var state = bool ? fn : jQuery(this).is(":hidden");
     5372                                jQuery(this)[ state ? "show" : "hide" ]();
     5373                        });
     5374
     5375                } else {
     5376                        this.animate(genFx("toggle", 3), fn, fn2);
     5377                }
     5378
     5379                return this;
     5380        },
     5381
     5382        fadeTo: function( speed, to, callback ) {
     5383                return this.filter(":hidden").css("opacity", 0).show().end()
     5384                                        .animate({opacity: to}, speed, callback);
    30005385        },
    30015386
     
    30035388                var optall = jQuery.speed(speed, easing, callback);
    30045389
    3005                 return this[ optall.queue === false ? "each" : "queue" ](function(){
    3006                         if ( this.nodeType != 1)
    3007                                 return false;
    3008 
     5390                if ( jQuery.isEmptyObject( prop ) ) {
     5391                        return this.each( optall.complete );
     5392                }
     5393
     5394                return this[ optall.queue === false ? "each" : "queue" ](function() {
    30095395                        var opt = jQuery.extend({}, optall), p,
    3010                                 hidden = jQuery(this).is(":hidden"), self = this;
     5396                                hidden = this.nodeType === 1 && jQuery(this).is(":hidden"),
     5397                                self = this;
    30115398
    30125399                        for ( p in prop ) {
    3013                                 if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
     5400                                var name = p.replace(rdashAlpha, fcamelCase);
     5401
     5402                                if ( p !== name ) {
     5403                                        prop[ name ] = prop[ p ];
     5404                                        delete prop[ p ];
     5405                                        p = name;
     5406                                }
     5407
     5408                                if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) {
    30145409                                        return opt.complete.call(this);
    3015 
    3016                                 if ( p == "height" || p == "width" ) {
     5410                                }
     5411
     5412                                if ( ( p === "height" || p === "width" ) && this.style ) {
    30175413                                        // Store display property
    30185414                                        opt.display = jQuery.css(this, "display");
     
    30215417                                        opt.overflow = this.style.overflow;
    30225418                                }
    3023                         }
    3024 
    3025                         if ( opt.overflow != null )
     5419
     5420                                if ( jQuery.isArray( prop[p] ) ) {
     5421                                        // Create (if needed) and add to specialEasing
     5422                                        (opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];
     5423                                        prop[p] = prop[p][0];
     5424                                }
     5425                        }
     5426
     5427                        if ( opt.overflow != null ) {
    30265428                                this.style.overflow = "hidden";
     5429                        }
    30275430
    30285431                        opt.curAnim = jQuery.extend({}, prop);
    30295432
    3030                         jQuery.each( prop, function(name, val){
     5433                        jQuery.each( prop, function( name, val ) {
    30315434                                var e = new jQuery.fx( self, opt, name );
    30325435
    3033                                 if ( /toggle|show|hide/.test(val) )
    3034                                         e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
    3035                                 else {
    3036                                         var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
     5436                                if ( rfxtypes.test(val) ) {
     5437                                        e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop );
     5438
     5439                                } else {
     5440                                        var parts = rfxnum.exec(val),
    30375441                                                start = e.cur(true) || 0;
    30385442
    30395443                                        if ( parts ) {
    3040                                                 var end = parseFloat(parts[2]),
     5444                                                var end = parseFloat( parts[2] ),
    30415445                                                        unit = parts[3] || "px";
    30425446
    30435447                                                // We need to compute starting value
    3044                                                 if ( unit != "px" ) {
     5448                                                if ( unit !== "px" ) {
    30455449                                                        self.style[ name ] = (end || 1) + unit;
    30465450                                                        start = ((end || 1) / e.cur(true)) * start;
     
    30495453
    30505454                                                // If a +=/-= token was provided, we're doing a relative animation
    3051                                                 if ( parts[1] )
    3052                                                         end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
     5455                                                if ( parts[1] ) {
     5456                                                        end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
     5457                                                }
    30535458
    30545459                                                e.custom( start, end, unit );
    3055                                         } else
     5460
     5461                                        } else {
    30565462                                                e.custom( start, val, "" );
     5463                                        }
    30575464                                }
    30585465                        });
     
    30635470        },
    30645471
    3065         queue: function(type, fn){
    3066                 if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) {
    3067                         fn = type;
    3068                         type = "fx";
    3069                 }
    3070 
    3071                 if ( !type || (typeof type == "string" && !fn) )
    3072                         return queue( this[0], type );
    3073 
    3074                 return this.each(function(){
    3075                         if ( fn.constructor == Array )
    3076                                 queue(this, type, fn);
    3077                         else {
    3078                                 queue(this, type).push( fn );
    3079 
    3080                                 if ( queue(this, type).length == 1 )
    3081                                         fn.call(this);
    3082                         }
    3083                 });
    3084         },
    3085 
    3086         stop: function(clearQueue, gotoEnd){
     5472        stop: function( clearQueue, gotoEnd ) {
    30875473                var timers = jQuery.timers;
    30885474
    3089                 if (clearQueue)
     5475                if ( clearQueue ) {
    30905476                        this.queue([]);
    3091 
    3092                 this.each(function(){
     5477                }
     5478
     5479                this.each(function() {
    30935480                        // go in reverse order so anything added to the queue during the loop is ignored
    3094                         for ( var i = timers.length - 1; i >= 0; i-- )
    3095                                 if ( timers[i].elem == this ) {
    3096                                         if (gotoEnd)
     5481                        for ( var i = timers.length - 1; i >= 0; i-- ) {
     5482                                if ( timers[i].elem === this ) {
     5483                                        if (gotoEnd) {
    30975484                                                // force the next step to be the last
    30985485                                                timers[i](true);
     5486                                        }
     5487
    30995488                                        timers.splice(i, 1);
    31005489                                }
     5490                        }
    31015491                });
    31025492
    31035493                // start the next in the queue if the last step wasn't forced
    3104                 if (!gotoEnd)
     5494                if ( !gotoEnd ) {
    31055495                        this.dequeue();
     5496                }
    31065497
    31075498                return this;
     
    31105501});
    31115502
    3112 var queue = function( elem, type, array ) {
    3113         if ( elem ){
    3114 
    3115                 type = type || "fx";
    3116 
    3117                 var q = jQuery.data( elem, type + "queue" );
    3118 
    3119                 if ( !q || array )
    3120                         q = jQuery.data( elem, type + "queue", jQuery.makeArray(array) );
    3121 
    3122         }
    3123         return q;
    3124 };
    3125 
    3126 jQuery.fn.dequeue = function(type){
    3127         type = type || "fx";
    3128 
    3129         return this.each(function(){
    3130                 var q = queue(this, type);
    3131 
    3132                 q.shift();
    3133 
    3134                 if ( q.length )
    3135                         q[0].call( this );
    3136         });
    3137 };
     5503// Generate shortcuts for custom animations
     5504jQuery.each({
     5505        slideDown: genFx("show", 1),
     5506        slideUp: genFx("hide", 1),
     5507        slideToggle: genFx("toggle", 1),
     5508        fadeIn: { opacity: "show" },
     5509        fadeOut: { opacity: "hide" }
     5510}, function( name, props ) {
     5511        jQuery.fn[ name ] = function( speed, callback ) {
     5512                return this.animate( props, speed, callback );
     5513        };
     5514});
    31385515
    31395516jQuery.extend({
    3140 
    3141         speed: function(speed, easing, fn) {
    3142                 var opt = speed && speed.constructor == Object ? speed : {
     5517        speed: function( speed, easing, fn ) {
     5518                var opt = speed && typeof speed === "object" ? speed : {
    31435519                        complete: fn || !fn && easing ||
    31445520                                jQuery.isFunction( speed ) && speed,
    31455521                        duration: speed,
    3146                         easing: fn && easing || easing && easing.constructor != Function && easing
     5522                        easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
    31475523                };
    31485524
    3149                 opt.duration = (opt.duration && opt.duration.constructor == Number ?
    3150                         opt.duration :
    3151                         jQuery.fx.speeds[opt.duration]) || jQuery.fx.speeds.def;
     5525                opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
     5526                        jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;
    31525527
    31535528                // Queueing
    31545529                opt.old = opt.complete;
    3155                 opt.complete = function(){
    3156                         if ( opt.queue !== false )
     5530                opt.complete = function() {
     5531                        if ( opt.queue !== false ) {
    31575532                                jQuery(this).dequeue();
    3158                         if ( jQuery.isFunction( opt.old ) )
     5533                        }
     5534                        if ( jQuery.isFunction( opt.old ) ) {
    31595535                                opt.old.call( this );
     5536                        }
    31605537                };
    31615538
     
    31735550
    31745551        timers: [],
    3175         timerId: null,
    3176 
    3177         fx: function( elem, options, prop ){
     5552
     5553        fx: function( elem, options, prop ) {
    31785554                this.options = options;
    31795555                this.elem = elem;
    31805556                this.prop = prop;
    31815557
    3182                 if ( !options.orig )
     5558                if ( !options.orig ) {
    31835559                        options.orig = {};
     5560                }
    31845561        }
    31855562
     
    31875564
    31885565jQuery.fx.prototype = {
    3189 
    31905566        // Simple function for setting a style value
    3191         update: function(){
    3192                 if ( this.options.step )
     5567        update: function() {
     5568                if ( this.options.step ) {
    31935569                        this.options.step.call( this.elem, this.now, this );
     5570                }
    31945571
    31955572                (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
    31965573
    31975574                // Set display property to block for height/width animations
    3198                 if ( this.prop == "height" || this.prop == "width" )
     5575                if ( ( this.prop === "height" || this.prop === "width" ) && this.elem.style ) {
    31995576                        this.elem.style.display = "block";
     5577                }
    32005578        },
    32015579
    32025580        // Get the current size
    3203         cur: function(force){
    3204                 if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )
     5581        cur: function( force ) {
     5582                if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
    32055583                        return this.elem[ this.prop ];
     5584                }
    32065585
    32075586                var r = parseFloat(jQuery.css(this.elem, this.prop, force));
     
    32105589
    32115590        // Start an animation from one number to another
    3212         custom: function(from, to, unit){
     5591        custom: function( from, to, unit ) {
    32135592                this.startTime = now();
    32145593                this.start = from;
     
    32175596                this.now = this.start;
    32185597                this.pos = this.state = 0;
    3219                 this.update();
    32205598
    32215599                var self = this;
    3222                 function t(gotoEnd){
     5600                function t( gotoEnd ) {
    32235601                        return self.step(gotoEnd);
    32245602                }
     
    32265604                t.elem = this.elem;
    32275605
    3228                 jQuery.timers.push(t);
    3229 
    3230                 if ( jQuery.timerId == null ) {
    3231                         jQuery.timerId = setInterval(function(){
    3232                                 var timers = jQuery.timers;
    3233 
    3234                                 for ( var i = 0; i < timers.length; i++ )
    3235                                         if ( !timers[i]() )
    3236                                                 timers.splice(i--, 1);
    3237 
    3238                                 if ( !timers.length ) {
    3239                                         clearInterval( jQuery.timerId );
    3240                                         jQuery.timerId = null;
    3241                                 }
    3242                         }, 13);
     5606                if ( t() && jQuery.timers.push(t) && !timerId ) {
     5607                        timerId = setInterval(jQuery.fx.tick, 13);
    32435608                }
    32445609        },
    32455610
    32465611        // Simple 'show' function
    3247         show: function(){
     5612        show: function() {
    32485613                // Remember where we started, so that we can go back to it later
    3249                 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
     5614                this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
    32505615                this.options.show = true;
    32515616
    32525617                // Begin the animation
    3253                 this.custom(0, this.cur());
    3254 
    32555618                // Make sure that we start at a small width/height to avoid any
    32565619                // flash of content
    3257                 if ( this.prop == "width" || this.prop == "height" )
    3258                         this.elem.style[this.prop] = "1px";
     5620                this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
    32595621
    32605622                // Start by showing the element
    3261                 jQuery(this.elem).show();
     5623                jQuery( this.elem ).show();
    32625624        },
    32635625
    32645626        // Simple 'hide' function
    3265         hide: function(){
     5627        hide: function() {
    32665628                // Remember where we started, so that we can go back to it later
    3267                 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
     5629                this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
    32685630                this.options.hide = true;
    32695631
     
    32735635
    32745636        // Each step of an animation
    3275         step: function(gotoEnd){
    3276                 var t = now();
    3277 
    3278                 if ( gotoEnd || t > this.options.duration + this.startTime ) {
     5637        step: function( gotoEnd ) {
     5638                var t = now(), done = true;
     5639
     5640                if ( gotoEnd || t >= this.options.duration + this.startTime ) {
    32795641                        this.now = this.end;
    32805642                        this.pos = this.state = 1;
     
    32835645                        this.options.curAnim[ this.prop ] = true;
    32845646
    3285                         var done = true;
    3286                         for ( var i in this.options.curAnim )
    3287                                 if ( this.options.curAnim[i] !== true )
     5647                        for ( var i in this.options.curAnim ) {
     5648                                if ( this.options.curAnim[i] !== true ) {
    32885649                                        done = false;
     5650                                }
     5651                        }
    32895652
    32905653                        if ( done ) {
     
    32945657
    32955658                                        // Reset the display
    3296                                         this.elem.style.display = this.options.display;
    3297                                         if ( jQuery.css(this.elem, "display") == "none" )
     5659                                        var old = jQuery.data(this.elem, "olddisplay");
     5660                                        this.elem.style.display = old ? old : this.options.display;
     5661
     5662                                        if ( jQuery.css(this.elem, "display") === "none" ) {
    32985663                                                this.elem.style.display = "block";
     5664                                        }
    32995665                                }
    33005666
    33015667                                // Hide the element if the "hide" operation was done
    3302                                 if ( this.options.hide )
    3303                                         this.elem.style.display = "none";
     5668                                if ( this.options.hide ) {
     5669                                        jQuery(this.elem).hide();
     5670                                }
    33045671
    33055672                                // Reset the properties, if the item has been hidden or shown
    3306                                 if ( this.options.hide || this.options.show )
    3307                                         for ( var p in this.options.curAnim )
    3308                                                 jQuery.attr(this.elem.style, p, this.options.orig[p]);
    3309                         }
    3310 
    3311                         if ( done )
     5673                                if ( this.options.hide || this.options.show ) {
     5674                                        for ( var p in this.options.curAnim ) {
     5675                                                jQuery.style(this.elem, p, this.options.orig[p]);
     5676                                        }
     5677                                }
     5678
    33125679                                // Execute the complete function
    33135680                                this.options.complete.call( this.elem );
     5681                        }
    33145682
    33155683                        return false;
     5684
    33165685                } else {
    33175686                        var n = t - this.startTime;
     
    33195688
    33205689                        // Perform the easing function, defaults to swing
    3321                         this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
     5690                        var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop];
     5691                        var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear");
     5692                        this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);
    33225693                        this.now = this.start + ((this.end - this.start) * this.pos);
    33235694
     
    33285699                return true;
    33295700        }
    3330 
    33315701};
    33325702
    33335703jQuery.extend( jQuery.fx, {
    3334         speeds:{
     5704        tick: function() {
     5705                var timers = jQuery.timers;
     5706
     5707                for ( var i = 0; i < timers.length; i++ ) {
     5708                        if ( !timers[i]() ) {
     5709                                timers.splice(i--, 1);
     5710                        }
     5711                }
     5712
     5713                if ( !timers.length ) {
     5714                        jQuery.fx.stop();
     5715                }
     5716        },
     5717               
     5718        stop: function() {
     5719                clearInterval( timerId );
     5720                timerId = null;
     5721        },
     5722       
     5723        speeds: {
    33355724                slow: 600,
    33365725                fast: 200,
    33375726                // Default speed
    3338                 def: 400
    3339         },
     5727                _default: 400
     5728        },
     5729
    33405730        step: {
    3341                 scrollLeft: function(fx){
    3342                         fx.elem.scrollLeft = fx.now;
     5731                opacity: function( fx ) {
     5732                        jQuery.style(fx.elem, "opacity", fx.now);
    33435733                },
    33445734
    3345                 scrollTop: function(fx){
    3346                         fx.elem.scrollTop = fx.now;
    3347                 },
    3348 
    3349                 opacity: function(fx){
    3350                         jQuery.attr(fx.elem.style, "opacity", fx.now);
    3351                 },
    3352 
    3353                 _default: function(fx){
    3354                         fx.elem.style[ fx.prop ] = fx.now + fx.unit;
     5735                _default: function( fx ) {
     5736                        if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
     5737                                fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
     5738                        } else {
     5739                                fx.elem[ fx.prop ] = fx.now;
     5740                        }
    33555741                }
    33565742        }
    33575743});
    3358 // The Offset Method
    3359 // Originally By Brandon Aaron, part of the Dimension Plugin
    3360 // http://jquery.com/plugins/project/dimensions
    3361 jQuery.fn.offset = function() {
    3362         var left = 0, top = 0, elem = this[0], results;
    3363 
    3364         if ( elem ) with ( jQuery.browser ) {
    3365                 var parent       = elem.parentNode,
    3366                     offsetChild  = elem,
    3367                     offsetParent = elem.offsetParent,
    3368                     doc          = elem.ownerDocument,
    3369                     safari2      = safari && parseInt(version) < 522 && !/adobeair/i.test(userAgent),
    3370                     css          = jQuery.curCSS,
    3371                     fixed        = css(elem, "position") == "fixed";
    3372 
    3373                 // Use getBoundingClientRect if available
    3374                 if ( elem.getBoundingClientRect ) {
    3375                         var box = elem.getBoundingClientRect();
    3376 
    3377                         // Add the document scroll offsets
    3378                         add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
    3379                                 box.top  + Math.max(doc.documentElement.scrollTop,  doc.body.scrollTop));
    3380 
    3381                         // IE adds the HTML element's border, by default it is medium which is 2px
    3382                         // IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; }
    3383                         // IE 7 standards mode, the border is always 2px
    3384                         // This border/offset is typically represented by the clientLeft and clientTop properties
    3385                         // However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS
    3386                         // Therefore this method will be off by 2px in IE while in quirksmode
    3387                         add( -doc.documentElement.clientLeft, -doc.documentElement.clientTop );
    3388 
    3389                 // Otherwise loop through the offsetParents and parentNodes
     5744
     5745if ( jQuery.expr && jQuery.expr.filters ) {
     5746        jQuery.expr.filters.animated = function( elem ) {
     5747                return jQuery.grep(jQuery.timers, function( fn ) {
     5748                        return elem === fn.elem;
     5749                }).length;
     5750        };
     5751}
     5752
     5753function genFx( type, num ) {
     5754        var obj = {};
     5755
     5756        jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
     5757                obj[ this ] = type;
     5758        });
     5759
     5760        return obj;
     5761}
     5762if ( "getBoundingClientRect" in document.documentElement ) {
     5763        jQuery.fn.offset = function( options ) {
     5764                var elem = this[0];
     5765
     5766                if ( options ) {
     5767                        return this.each(function( i ) {
     5768                                jQuery.offset.setOffset( this, options, i );
     5769                        });
     5770                }
     5771
     5772                if ( !elem || !elem.ownerDocument ) {
     5773                        return null;
     5774                }
     5775
     5776                if ( elem === elem.ownerDocument.body ) {
     5777                        return jQuery.offset.bodyOffset( elem );
     5778                }
     5779
     5780                var box = elem.getBoundingClientRect(), doc = elem.ownerDocument, body = doc.body, docElem = doc.documentElement,
     5781                        clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
     5782                        top  = box.top  + (self.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop ) - clientTop,
     5783                        left = box.left + (self.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
     5784
     5785                return { top: top, left: left };
     5786        };
     5787
     5788} else {
     5789        jQuery.fn.offset = function( options ) {
     5790                var elem = this[0];
     5791
     5792                if ( options ) {
     5793                        return this.each(function( i ) {
     5794                                jQuery.offset.setOffset( this, options, i );
     5795                        });
     5796                }
     5797
     5798                if ( !elem || !elem.ownerDocument ) {
     5799                        return null;
     5800                }
     5801
     5802                if ( elem === elem.ownerDocument.body ) {
     5803                        return jQuery.offset.bodyOffset( elem );
     5804                }
     5805
     5806                jQuery.offset.initialize();
     5807
     5808                var offsetParent = elem.offsetParent, prevOffsetParent = elem,
     5809                        doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
     5810                        body = doc.body, defaultView = doc.defaultView,
     5811                        prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
     5812                        top = elem.offsetTop, left = elem.offsetLeft;
     5813
     5814                while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
     5815                        if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
     5816                                break;
     5817                        }
     5818
     5819                        computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
     5820                        top  -= elem.scrollTop;
     5821                        left -= elem.scrollLeft;
     5822
     5823                        if ( elem === offsetParent ) {
     5824                                top  += elem.offsetTop;
     5825                                left += elem.offsetLeft;
     5826
     5827                                if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.nodeName)) ) {
     5828                                        top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
     5829                                        left += parseFloat( computedStyle.borderLeftWidth ) || 0;
     5830                                }
     5831
     5832                                prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;
     5833                        }
     5834
     5835                        if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
     5836                                top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
     5837                                left += parseFloat( computedStyle.borderLeftWidth ) || 0;
     5838                        }
     5839
     5840                        prevComputedStyle = computedStyle;
     5841                }
     5842
     5843                if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
     5844                        top  += body.offsetTop;
     5845                        left += body.offsetLeft;
     5846                }
     5847
     5848                if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
     5849                        top  += Math.max( docElem.scrollTop, body.scrollTop );
     5850                        left += Math.max( docElem.scrollLeft, body.scrollLeft );
     5851                }
     5852
     5853                return { top: top, left: left };
     5854        };
     5855}
     5856
     5857jQuery.offset = {
     5858        initialize: function() {
     5859                var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.curCSS(body, "marginTop", true) ) || 0,
     5860                        html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
     5861
     5862                jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
     5863
     5864                container.innerHTML = html;
     5865                body.insertBefore( container, body.firstChild );
     5866                innerDiv = container.firstChild;
     5867                checkDiv = innerDiv.firstChild;
     5868                td = innerDiv.nextSibling.firstChild.firstChild;
     5869
     5870                this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
     5871                this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
     5872
     5873                checkDiv.style.position = "fixed", checkDiv.style.top = "20px";
     5874                // safari subtracts parent border width here which is 5px
     5875                this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
     5876                checkDiv.style.position = checkDiv.style.top = "";
     5877
     5878                innerDiv.style.overflow = "hidden", innerDiv.style.position = "relative";
     5879                this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
     5880
     5881                this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
     5882
     5883                body.removeChild( container );
     5884                body = container = innerDiv = checkDiv = table = td = null;
     5885                jQuery.offset.initialize = jQuery.noop;
     5886        },
     5887
     5888        bodyOffset: function( body ) {
     5889                var top = body.offsetTop, left = body.offsetLeft;
     5890
     5891                jQuery.offset.initialize();
     5892
     5893                if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
     5894                        top  += parseFloat( jQuery.curCSS(body, "marginTop",  true) ) || 0;
     5895                        left += parseFloat( jQuery.curCSS(body, "marginLeft", true) ) || 0;
     5896                }
     5897
     5898                return { top: top, left: left };
     5899        },
     5900       
     5901        setOffset: function( elem, options, i ) {
     5902                // set position first, in-case top/left are set even on static elem
     5903                if ( /static/.test( jQuery.curCSS( elem, "position" ) ) ) {
     5904                        elem.style.position = "relative";
     5905                }
     5906                var curElem   = jQuery( elem ),
     5907                        curOffset = curElem.offset(),
     5908                        curTop    = parseInt( jQuery.curCSS( elem, "top",  true ), 10 ) || 0,
     5909                        curLeft   = parseInt( jQuery.curCSS( elem, "left", true ), 10 ) || 0;
     5910
     5911                if ( jQuery.isFunction( options ) ) {
     5912                        options = options.call( elem, i, curOffset );
     5913                }
     5914
     5915                var props = {
     5916                        top:  (options.top  - curOffset.top)  + curTop,
     5917                        left: (options.left - curOffset.left) + curLeft
     5918                };
     5919               
     5920                if ( "using" in options ) {
     5921                        options.using.call( elem, props );
    33905922                } else {
    3391 
    3392                         // Initial element offsets
    3393                         add( elem.offsetLeft, elem.offsetTop );
    3394 
    3395                         // Get parent offsets
    3396                         while ( offsetParent ) {
    3397                                 // Add offsetParent offsets
    3398                                 add( offsetParent.offsetLeft, offsetParent.offsetTop );
    3399 
    3400                                 // Mozilla and Safari > 2 does not include the border on offset parents
    3401                                 // However Mozilla adds the border for table or table cells
    3402                                 if ( mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2 )
    3403                                         border( offsetParent );
    3404 
    3405                                 // Add the document scroll offsets if position is fixed on any offsetParent
    3406                                 if ( !fixed && css(offsetParent, "position") == "fixed" )
    3407                                         fixed = true;
    3408 
    3409                                 // Set offsetChild to previous offsetParent unless it is the body element
    3410                                 offsetChild  = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent;
    3411                                 // Get next offsetParent
    3412                                 offsetParent = offsetParent.offsetParent;
    3413                         }
    3414 
    3415                         // Get parent scroll offsets
    3416                         while ( parent && parent.tagName && !/^body|html$/i.test(parent.tagName) ) {
    3417                                 // Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug
    3418                                 if ( !/^inline|table.*$/i.test(css(parent, "display")) )
    3419                                         // Subtract parent scroll offsets
    3420                                         add( -parent.scrollLeft, -parent.scrollTop );
    3421 
    3422                                 // Mozilla does not add the border for a parent that has overflow != visible
    3423                                 if ( mozilla && css(parent, "overflow") != "visible" )
    3424                                         border( parent );
    3425 
    3426                                 // Get next parent
    3427                                 parent = parent.parentNode;
    3428                         }
    3429 
    3430                         // Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild
    3431                         // Mozilla doubles body offsets with a non-absolutely positioned offsetChild
    3432                         if ( (safari2 && (fixed || css(offsetChild, "position") == "absolute")) ||
    3433                                 (mozilla && css(offsetChild, "position") != "absolute") )
    3434                                         add( -doc.body.offsetLeft, -doc.body.offsetTop );
    3435 
    3436                         // Add the document scroll offsets if position is fixed
    3437                         if ( fixed )
    3438                                 add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
    3439                                         Math.max(doc.documentElement.scrollTop,  doc.body.scrollTop));
    3440                 }
    3441 
    3442                 // Return an object with top and left properties
    3443                 results = { top: top, left: left };
    3444         }
    3445 
    3446         function border(elem) {
    3447                 add( jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true) );
    3448         }
    3449 
    3450         function add(l, t) {
    3451                 left += parseInt(l, 10) || 0;
    3452                 top += parseInt(t, 10) || 0;
    3453         }
    3454 
    3455         return results;
     5923                        curElem.css( props );
     5924                }
     5925        }
    34565926};
    34575927
     
    34595929jQuery.fn.extend({
    34605930        position: function() {
    3461                 var left = 0, top = 0, results;
    3462 
    3463                 if ( this[0] ) {
    3464                         // Get *real* offsetParent
    3465                         var offsetParent = this.offsetParent(),
    3466 
    3467                         // Get correct offsets
    3468                         offset       = this.offset(),
    3469                         parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();
    3470 
    3471                         // Subtract element margins
    3472                         // note: when an element has margin: auto the offsetLeft and marginLeft
    3473                         // are the same in Safari causing offset.left to incorrectly be 0
    3474                         offset.top  -= num( this, 'marginTop' );
    3475                         offset.left -= num( this, 'marginLeft' );
    3476 
    3477                         // Add offsetParent borders
    3478                         parentOffset.top  += num( offsetParent, 'borderTopWidth' );
    3479                         parentOffset.left += num( offsetParent, 'borderLeftWidth' );
    3480 
    3481                         // Subtract the two offsets
    3482                         results = {
    3483                                 top:  offset.top  - parentOffset.top,
    3484                                 left: offset.left - parentOffset.left
    3485                         };
    3486                 }
    3487 
    3488                 return results;
     5931                if ( !this[0] ) {
     5932                        return null;
     5933                }
     5934
     5935                var elem = this[0],
     5936
     5937                // Get *real* offsetParent
     5938                offsetParent = this.offsetParent(),
     5939
     5940                // Get correct offsets
     5941                offset       = this.offset(),
     5942                parentOffset = /^body|html$/i.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
     5943
     5944                // Subtract element margins
     5945                // note: when an element has margin: auto the offsetLeft and marginLeft
     5946                // are the same in Safari causing offset.left to incorrectly be 0
     5947                offset.top  -= parseFloat( jQuery.curCSS(elem, "marginTop",  true) ) || 0;
     5948                offset.left -= parseFloat( jQuery.curCSS(elem, "marginLeft", true) ) || 0;
     5949
     5950                // Add offsetParent borders
     5951                parentOffset.top  += parseFloat( jQuery.curCSS(offsetParent[0], "borderTopWidth",  true) ) || 0;
     5952                parentOffset.left += parseFloat( jQuery.curCSS(offsetParent[0], "borderLeftWidth", true) ) || 0;
     5953
     5954                // Subtract the two offsets
     5955                return {
     5956                        top:  offset.top  - parentOffset.top,
     5957                        left: offset.left - parentOffset.left
     5958                };
    34895959        },
    34905960
    34915961        offsetParent: function() {
    3492                 var offsetParent = this[0].offsetParent;
    3493                 while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') )
    3494                         offsetParent = offsetParent.offsetParent;
    3495                 return jQuery(offsetParent);
     5962                return this.map(function() {
     5963                        var offsetParent = this.offsetParent || document.body;
     5964                        while ( offsetParent && (!/^body|html$/i.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
     5965                                offsetParent = offsetParent.offsetParent;
     5966                        }
     5967                        return offsetParent;
     5968                });
    34965969        }
    34975970});
     
    34995972
    35005973// Create scrollLeft and scrollTop methods
    3501 jQuery.each( ['Left', 'Top'], function(i, name) {
    3502         var method = 'scroll' + name;
    3503        
     5974jQuery.each( ["Left", "Top"], function( i, name ) {
     5975        var method = "scroll" + name;
     5976
    35045977        jQuery.fn[ method ] = function(val) {
    3505                 if (!this[0]) return;
    3506 
    3507                 return val != undefined ?
    3508 
     5978                var elem = this[0], win;
     5979               
     5980                if ( !elem ) {
     5981                        return null;
     5982                }
     5983
     5984                if ( val !== undefined ) {
    35095985                        // Set the scroll offset
    3510                         this.each(function() {
    3511                                 this == window || this == document ?
    3512                                         window.scrollTo(
    3513                                                 !i ? val : jQuery(window).scrollLeft(),
    3514                                                  i ? val : jQuery(window).scrollTop()
    3515                                         ) :
     5986                        return this.each(function() {
     5987                                win = getWindow( this );
     5988
     5989                                if ( win ) {
     5990                                        win.scrollTo(
     5991                                                !i ? val : jQuery(win).scrollLeft(),
     5992                                                 i ? val : jQuery(win).scrollTop()
     5993                                        );
     5994
     5995                                } else {
    35165996                                        this[ method ] = val;
    3517                         }) :
     5997                                }
     5998                        });
     5999                } else {
     6000                        win = getWindow( elem );
    35186001
    35196002                        // Return the scroll offset
    3520                         this[0] == window || this[0] == document ?
    3521                                 self[ i ? 'pageYOffset' : 'pageXOffset' ] ||
    3522                                         jQuery.boxModel && document.documentElement[ method ] ||
    3523                                         document.body[ method ] :
    3524                                 this[0][ method ];
     6003                        return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
     6004                                jQuery.support.boxModel && win.document.documentElement[ method ] ||
     6005                                        win.document.body[ method ] :
     6006                                elem[ method ];
     6007                }
    35256008        };
    35266009});
     6010
     6011function getWindow( elem ) {
     6012        return ("scrollTo" in elem && elem.document) ?
     6013                elem :
     6014                elem.nodeType === 9 ?
     6015                        elem.defaultView || elem.parentWindow :
     6016                        false;
     6017}
    35276018// Create innerHeight, innerWidth, outerHeight and outerWidth methods
    3528 jQuery.each([ "Height", "Width" ], function(i, name){
    3529 
    3530         var tl = i ? "Left"  : "Top",  // top or left
    3531                 br = i ? "Right" : "Bottom"; // bottom or right
     6019jQuery.each([ "Height", "Width" ], function( i, name ) {
     6020
     6021        var type = name.toLowerCase();
    35326022
    35336023        // innerHeight and innerWidth
    3534         jQuery.fn["inner" + name] = function(){
    3535                 return this[ name.toLowerCase() ]() +
    3536                         num(this, "padding" + tl) +
    3537                         num(this, "padding" + br);
     6024        jQuery.fn["inner" + name] = function() {
     6025                return this[0] ?
     6026                        jQuery.css( this[0], type, false, "padding" ) :
     6027                        null;
    35386028        };
    35396029
    35406030        // outerHeight and outerWidth
    3541         jQuery.fn["outer" + name] = function(margin) {
    3542                 return this["inner" + name]() +
    3543                         num(this, "border" + tl + "Width") +
    3544                         num(this, "border" + br + "Width") +
    3545                         (margin ?
    3546                                 num(this, "margin" + tl) + num(this, "margin" + br) : 0);
     6031        jQuery.fn["outer" + name] = function( margin ) {
     6032                return this[0] ?
     6033                        jQuery.css( this[0], type, false, margin ? "margin" : "border" ) :
     6034                        null;
    35476035        };
    35486036
    3549 });})();
     6037        jQuery.fn[ type ] = function( size ) {
     6038                // Get window width or height
     6039                var elem = this[0];
     6040                if ( !elem ) {
     6041                        return size == null ? null : this;
     6042                }
     6043               
     6044                if ( jQuery.isFunction( size ) ) {
     6045                        return this.each(function( i ) {
     6046                                var self = jQuery( this );
     6047                                self[ type ]( size.call( this, i, self[ type ]() ) );
     6048                        });
     6049                }
     6050
     6051                return ("scrollTo" in elem && elem.document) ? // does it walk and quack like a window?
     6052                        // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
     6053                        elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
     6054                        elem.document.body[ "client" + name ] :
     6055
     6056                        // Get document width or height
     6057                        (elem.nodeType === 9) ? // is it a document
     6058                                // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
     6059                                Math.max(
     6060                                        elem.documentElement["client" + name],
     6061                                        elem.body["scroll" + name], elem.documentElement["scroll" + name],
     6062                                        elem.body["offset" + name], elem.documentElement["offset" + name]
     6063                                ) :
     6064
     6065                                // Get or set width or height on the element
     6066                                size === undefined ?
     6067                                        // Get width or height on the element
     6068                                        jQuery.css( elem, type ) :
     6069
     6070                                        // Set the width or height on the element (default to pixels if value is unitless)
     6071                                        this.css( type, typeof size === "string" ? size : size + "px" );
     6072        };
     6073
     6074});
     6075// Expose jQuery to the global object
     6076window.jQuery = window.$ = jQuery;
     6077
     6078})(window);
Note: See TracChangeset for help on using the changeset viewer.