Added jquery.qunit.completenessTest.js (A jQuery/QUnit test coverage utility)
authorKrinkle <krinkle@users.mediawiki.org>
Fri, 10 Jun 2011 22:15:14 +0000 (22:15 +0000)
committerKrinkle <krinkle@users.mediawiki.org>
Fri, 10 Jun 2011 22:15:14 +0000 (22:15 +0000)
* Added to /resources
* Conditionally loaded (condition being that the url parameter "completenesstest" has a truthy value)
* Fixed a test that was using === and true
* Setting an added method somewhere back to undefined so it won't be listed as a potential "missing test".

resources/jquery/jquery.js
resources/jquery/jquery.qunit.completenessTest.js [new file with mode: 0644]
tests/qunit/index.html
tests/qunit/jquery.qunit.completenessTest.config.js [new file with mode: 0644]
tests/qunit/suites/resources/mediawiki/mediawiki.js

index a4f1145..5d5a1d5 100644 (file)
@@ -1,28 +1,30 @@
 /*!
- * jQuery JavaScript Library v1.4.4
+ * jQuery JavaScript Library v1.6.1
  * http://jquery.com/
  *
- * Copyright 2010, John Resig
+ * Copyright 2011, John Resig
  * Dual licensed under the MIT or GPL Version 2 licenses.
  * http://jquery.org/license
  *
  * Includes Sizzle.js
  * http://sizzlejs.com/
- * Copyright 2010, The Dojo Foundation
+ * Copyright 2011, The Dojo Foundation
  * Released under the MIT, BSD, and GPL Licenses.
  *
- * Date: Thu Nov 11 19:04:53 2010 -0500
+ * Date: Thu May 12 15:04:36 2011 -0400
  */
 (function( window, undefined ) {
 
 // Use the correct document accordingly with window argument (sandbox)
-var document = window.document;
+var document = window.document,
+       navigator = window.navigator,
+       location = window.location;
 var jQuery = (function() {
 
 // Define a local copy of jQuery
 var jQuery = function( selector, context ) {
                // The jQuery object is actually just the init constructor 'enhanced'
-               return new jQuery.fn.init( selector, context );
+               return new jQuery.fn.init( selector, context, rootjQuery );
        },
 
        // Map over jQuery in case of overwrite
@@ -36,22 +38,15 @@ var jQuery = function( selector, context ) {
 
        // A simple way to check for HTML strings or ID strings
        // (both of which we optimize for)
-       quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,
-
-       // Is it a simple selector
-       isSimple = /^.[^:#\[\.,]*$/,
+       quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
 
        // Check if a string has a non-whitespace character in it
        rnotwhite = /\S/,
-       rwhite = /\s/,
 
        // Used for trimming whitespace
        trimLeft = /^\s+/,
        trimRight = /\s+$/,
 
-       // Check for non-word characters
-       rnonword = /\W/,
-
        // Check for digits
        rdigit = /\d/,
 
@@ -75,12 +70,9 @@ var jQuery = function( selector, context ) {
 
        // For matching the engine and version of the browser
        browserMatch,
-       
-       // Has the ready events already been bound?
-       readyBound = false,
-       
-       // The functions to execute on DOM ready
-       readyList = [],
+
+       // The deferred used on DOM ready
+       readyList,
 
        // The ready event handler
        DOMContentLoaded,
@@ -92,12 +84,13 @@ var jQuery = function( selector, context ) {
        slice = Array.prototype.slice,
        trim = String.prototype.trim,
        indexOf = Array.prototype.indexOf,
-       
+
        // [[Class]] -> type pairs
        class2type = {};
 
 jQuery.fn = jQuery.prototype = {
-       init: function( selector, context ) {
+       constructor: jQuery,
+       init: function( selector, context, rootjQuery ) {
                var match, elem, ret, doc;
 
                // Handle $(""), $(null), or $(undefined)
@@ -111,12 +104,12 @@ jQuery.fn = jQuery.prototype = {
                        this.length = 1;
                        return this;
                }
-               
+
                // The body element only exists once, optimize finding it
                if ( selector === "body" && !context && document.body ) {
                        this.context = document;
                        this[0] = document.body;
-                       this.selector = "body";
+                       this.selector = selector;
                        this.length = 1;
                        return this;
                }
@@ -124,13 +117,20 @@ jQuery.fn = jQuery.prototype = {
                // Handle HTML strings
                if ( typeof selector === "string" ) {
                        // Are we dealing with HTML string or an ID?
-                       match = quickExpr.exec( selector );
+                       if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
+                               // Assume that strings that start and end with <> are HTML and skip the regex check
+                               match = [ null, selector, null ];
+
+                       } else {
+                               match = quickExpr.exec( selector );
+                       }
 
                        // Verify a match, and that no context was specified for #id
                        if ( match && (match[1] || !context) ) {
 
                                // HANDLE: $(html) -> $(array)
                                if ( match[1] ) {
+                                       context = context instanceof jQuery ? context[0] : context;
                                        doc = (context ? context.ownerDocument || context : document);
 
                                        // If a single string is passed in and it's a single tag
@@ -148,11 +148,11 @@ jQuery.fn = jQuery.prototype = {
 
                                        } else {
                                                ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
-                                               selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
+                                               selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
                                        }
-                                       
+
                                        return jQuery.merge( this, selector );
-                                       
+
                                // HANDLE: $("#id")
                                } else {
                                        elem = document.getElementById( match[2] );
@@ -176,13 +176,6 @@ jQuery.fn = jQuery.prototype = {
                                        return this;
                                }
 
-                       // HANDLE: $("TAG")
-                       } else if ( !context && !rnonword.test( selector ) ) {
-                               this.selector = selector;
-                               this.context = document;
-                               selector = document.getElementsByTagName( selector );
-                               return jQuery.merge( this, selector );
-
                        // HANDLE: $(expr, $(...))
                        } else if ( !context || context.jquery ) {
                                return (context || rootjQuery).find( selector );
@@ -190,7 +183,7 @@ jQuery.fn = jQuery.prototype = {
                        // HANDLE: $(expr, context)
                        // (which is just equivalent to: $(context).find(expr)
                        } else {
-                               return jQuery( context ).find( selector );
+                               return this.constructor( context ).find( selector );
                        }
 
                // HANDLE: $(function)
@@ -211,7 +204,7 @@ jQuery.fn = jQuery.prototype = {
        selector: "",
 
        // The current version of jQuery being used
-       jquery: "1.4.4",
+       jquery: "1.6.1",
 
        // The default length of a jQuery object is 0
        length: 0,
@@ -234,18 +227,18 @@ jQuery.fn = jQuery.prototype = {
                        this.toArray() :
 
                        // Return just the object
-                       ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
+                       ( num < 0 ? this[ this.length + num ] : this[ num ] );
        },
 
        // Take an array of elements and push it onto the stack
        // (returning the new matched element set)
        pushStack: function( elems, name, selector ) {
                // Build a new jQuery matched element set
-               var ret = jQuery();
+               var ret = this.constructor();
 
                if ( jQuery.isArray( elems ) ) {
                        push.apply( ret, elems );
-               
+
                } else {
                        jQuery.merge( ret, elems );
                }
@@ -271,25 +264,17 @@ jQuery.fn = jQuery.prototype = {
        each: function( callback, args ) {
                return jQuery.each( this, callback, args );
        },
-       
+
        ready: function( fn ) {
                // Attach the listeners
                jQuery.bindReady();
 
-               // If the DOM is already ready
-               if ( jQuery.isReady ) {
-                       // Execute the function immediately
-                       fn.call( document, jQuery );
-
-               // Otherwise, remember the function for later
-               } else if ( readyList ) {
-                       // Add the function to the wait list
-                       readyList.push( fn );
-               }
+               // Add the callback
+               readyList.done( fn );
 
                return this;
        },
-       
+
        eq: function( i ) {
                return i === -1 ?
                        this.slice( i ) :
@@ -314,9 +299,9 @@ jQuery.fn = jQuery.prototype = {
                        return callback.call( elem, i, elem );
                }));
        },
-       
+
        end: function() {
-               return this.prevObject || jQuery(null);
+               return this.prevObject || this.constructor(null);
        },
 
        // For internal use only.
@@ -330,7 +315,7 @@ jQuery.fn = jQuery.prototype = {
 jQuery.fn.init.prototype = jQuery.fn;
 
 jQuery.extend = jQuery.fn.extend = function() {
-        var options, name, src, copy, copyIsArray, clone,
+       var options, name, src, copy, copyIsArray, clone,
                target = arguments[0] || {},
                i = 1,
                length = arguments.length,
@@ -395,31 +380,37 @@ jQuery.extend = jQuery.fn.extend = function() {
 
 jQuery.extend({
        noConflict: function( deep ) {
-               window.$ = _$;
+               if ( window.$ === jQuery ) {
+                       window.$ = _$;
+               }
 
-               if ( deep ) {
+               if ( deep && window.jQuery === jQuery ) {
                        window.jQuery = _jQuery;
                }
 
                return jQuery;
        },
-       
+
        // Is the DOM ready to be used? Set to true once it occurs.
        isReady: false,
 
        // A counter to track how many items to wait for before
        // the ready event fires. See #6781
        readyWait: 1,
-       
-       // Handle when the DOM is ready
-       ready: function( wait ) {
-               // A third-party is pushing the ready event forwards
-               if ( wait === true ) {
-                       jQuery.readyWait--;
+
+       // Hold (or release) the ready event
+       holdReady: function( hold ) {
+               if ( hold ) {
+                       jQuery.readyWait++;
+               } else {
+                       jQuery.ready( true );
                }
+       },
 
-               // Make sure that the DOM is not already loaded
-               if ( !jQuery.readyWait || (wait !== true && !jQuery.isReady) ) {
+       // Handle when the DOM is ready
+       ready: function( wait ) {
+               // Either a released hold or an DOMready/load event and not yet ready
+               if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
                        // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
                        if ( !document.body ) {
                                return setTimeout( jQuery.ready, 1 );
@@ -434,33 +425,21 @@ jQuery.extend({
                        }
 
                        // If there are functions bound, to execute
-                       if ( readyList ) {
-                               // Execute all of them
-                               var fn,
-                                       i = 0,
-                                       ready = readyList;
+                       readyList.resolveWith( document, [ jQuery ] );
 
-                               // Reset the list of functions
-                               readyList = null;
-
-                               while ( (fn = ready[ i++ ]) ) {
-                                       fn.call( document, jQuery );
-                               }
-
-                               // Trigger any bound ready events
-                               if ( jQuery.fn.trigger ) {
-                                       jQuery( document ).trigger( "ready" ).unbind( "ready" );
-                               }
+                       // Trigger any bound ready events
+                       if ( jQuery.fn.trigger ) {
+                               jQuery( document ).trigger( "ready" ).unbind( "ready" );
                        }
                }
        },
-       
+
        bindReady: function() {
-               if ( readyBound ) {
+               if ( readyList ) {
                        return;
                }
 
-               readyBound = true;
+               readyList = jQuery._Deferred();
 
                // Catch cases where $(document).ready() is called after the
                // browser event has already occurred.
@@ -473,7 +452,7 @@ jQuery.extend({
                if ( document.addEventListener ) {
                        // Use the handy event callback
                        document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
-                       
+
                        // A fallback to window.onload, that will always work
                        window.addEventListener( "load", jQuery.ready, false );
 
@@ -481,8 +460,8 @@ jQuery.extend({
                } else if ( document.attachEvent ) {
                        // ensure firing before onload,
                        // maybe late but safe also for iframes
-                       document.attachEvent("onreadystatechange", DOMContentLoaded);
-                       
+                       document.attachEvent( "onreadystatechange", DOMContentLoaded );
+
                        // A fallback to window.onload, that will always work
                        window.attachEvent( "onload", jQuery.ready );
 
@@ -533,20 +512,20 @@ jQuery.extend({
                if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
                        return false;
                }
-               
+
                // Not own constructor property must be Object
                if ( obj.constructor &&
                        !hasOwn.call(obj, "constructor") &&
                        !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
                        return false;
                }
-               
+
                // Own properties are enumerated firstly, so to speed up,
                // if last one is own, then all properties are own.
-       
+
                var key;
                for ( key in obj ) {}
-               
+
                return key === undefined || hasOwn.call( obj, key );
        },
 
@@ -556,11 +535,11 @@ jQuery.extend({
                }
                return true;
        },
-       
+
        error: function( msg ) {
                throw msg;
        },
-       
+
        parseJSON: function( data ) {
                if ( typeof data !== "string" || !data ) {
                        return null;
@@ -568,45 +547,59 @@ jQuery.extend({
 
                // Make sure leading/trailing whitespace is removed (IE can't handle it)
                data = jQuery.trim( data );
-               
+
+               // Attempt to parse using the native JSON parser first
+               if ( window.JSON && window.JSON.parse ) {
+                       return window.JSON.parse( data );
+               }
+
                // Make sure the incoming data is actual JSON
                // Logic borrowed from http://json.org/json2.js
-               if ( rvalidchars.test(data.replace(rvalidescape, "@")
-                       .replace(rvalidtokens, "]")
-                       .replace(rvalidbraces, "")) ) {
+               if ( rvalidchars.test( data.replace( rvalidescape, "@" )
+                       .replace( rvalidtokens, "]" )
+                       .replace( rvalidbraces, "")) ) {
 
-                       // Try to use the native JSON parser first
-                       return window.JSON && window.JSON.parse ?
-                               window.JSON.parse( data ) :
-                               (new Function("return " + data))();
+                       return (new Function( "return " + data ))();
 
-               } else {
-                       jQuery.error( "Invalid JSON: " + data );
                }
+               jQuery.error( "Invalid JSON: " + data );
        },
 
-       noop: function() {},
+       // Cross-browser xml parsing
+       // (xml & tmp used internally)
+       parseXML: function( data , xml , tmp ) {
 
-       // Evalulates a script in a global context
-       globalEval: function( data ) {
-               if ( data && rnotwhite.test(data) ) {
-                       // Inspired by code by Andrea Giammarchi
-                       // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
-                       var head = document.getElementsByTagName("head")[0] || document.documentElement,
-                               script = document.createElement("script");
+               if ( window.DOMParser ) { // Standard
+                       tmp = new DOMParser();
+                       xml = tmp.parseFromString( data , "text/xml" );
+               } else { // IE
+                       xml = new ActiveXObject( "Microsoft.XMLDOM" );
+                       xml.async = "false";
+                       xml.loadXML( data );
+               }
 
-                       script.type = "text/javascript";
+               tmp = xml.documentElement;
 
-                       if ( jQuery.support.scriptEval ) {
-                               script.appendChild( document.createTextNode( data ) );
-                       } else {
-                               script.text = data;
-                       }
+               if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) {
+                       jQuery.error( "Invalid XML: " + data );
+               }
+
+               return xml;
+       },
+
+       noop: function() {},
 
-                       // Use insertBefore instead of appendChild to circumvent an IE6 bug.
-                       // This arises when a base node is used (#2709).
-                       head.insertBefore( script, head.firstChild );
-                       head.removeChild( script );
+       // Evaluates a script in a global context
+       // Workarounds based on findings by Jim Driscoll
+       // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
+       globalEval: function( data ) {
+               if ( data && rnotwhite.test( data ) ) {
+                       // We use execScript on Internet Explorer
+                       // We use an anonymous function so that context is window
+                       // rather than jQuery in Firefox
+                       ( window.execScript || function( data ) {
+                               window[ "eval" ].call( window, data );
+                       } )( data );
                }
        },
 
@@ -618,7 +611,7 @@ jQuery.extend({
        each: function( object, callback, args ) {
                var name, i = 0,
                        length = object.length,
-                       isObj = length === undefined || jQuery.isFunction(object);
+                       isObj = length === undefined || jQuery.isFunction( object );
 
                if ( args ) {
                        if ( isObj ) {
@@ -644,8 +637,11 @@ jQuery.extend({
                                        }
                                }
                        } else {
-                               for ( var value = object[0];
-                                       i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
+                               for ( ; i < length; ) {
+                                       if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
+                                               break;
+                                       }
+                               }
                        }
                }
 
@@ -676,7 +672,7 @@ jQuery.extend({
                        // The extra typeof function check is to prevent crashes
                        // in Safari 2 (See: #3039)
                        // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
-                       var type = jQuery.type(array);
+                       var type = jQuery.type( array );
 
                        if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
                                push.call( ret, array );
@@ -689,8 +685,9 @@ jQuery.extend({
        },
 
        inArray: function( elem, array ) {
-               if ( array.indexOf ) {
-                       return array.indexOf( elem );
+
+               if ( indexOf ) {
+                       return indexOf.call( array, elem );
                }
 
                for ( var i = 0, length = array.length; i < length; i++ ) {
@@ -710,7 +707,7 @@ jQuery.extend({
                        for ( var l = second.length; j < l; j++ ) {
                                first[ i++ ] = second[ j ];
                        }
-               
+
                } else {
                        while ( second[j] !== undefined ) {
                                first[ i++ ] = second[ j++ ];
@@ -740,49 +737,64 @@ jQuery.extend({
 
        // arg is for internal usage only
        map: function( elems, callback, arg ) {
-               var ret = [], value;
+               var value, key, ret = [],
+                       i = 0,
+                       length = elems.length,
+                       // jquery objects are treated as arrays
+                       isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
 
                // Go through the array, translating each of the items to their
-               // new value (or values).
-               for ( var i = 0, length = elems.length; i < length; i++ ) {
-                       value = callback( elems[ i ], i, arg );
+               if ( isArray ) {
+                       for ( ; i < length; i++ ) {
+                               value = callback( elems[ i ], i, arg );
+
+                               if ( value != null ) {
+                                       ret[ ret.length ] = value;
+                               }
+                       }
+
+               // Go through every key on the object,
+               } else {
+                       for ( key in elems ) {
+                               value = callback( elems[ key ], key, arg );
 
-                       if ( value != null ) {
-                               ret[ ret.length ] = value;
+                               if ( value != null ) {
+                                       ret[ ret.length ] = value;
+                               }
                        }
                }
 
+               // Flatten any nested arrays
                return ret.concat.apply( [], ret );
        },
 
        // A global GUID counter for objects
        guid: 1,
 
-       proxy: function( fn, proxy, thisObject ) {
-               if ( arguments.length === 2 ) {
-                       if ( typeof proxy === "string" ) {
-                               thisObject = fn;
-                               fn = thisObject[ proxy ];
-                               proxy = undefined;
+       // Bind a function to a context, optionally partially applying any
+       // arguments.
+       proxy: function( fn, context ) {
+               if ( typeof context === "string" ) {
+                       var tmp = fn[ context ];
+                       context = fn;
+                       fn = tmp;
+               }
 
-                       } else if ( proxy && !jQuery.isFunction( proxy ) ) {
-                               thisObject = proxy;
-                               proxy = undefined;
-                       }
+               // Quick check to determine if target is callable, in the spec
+               // this throws a TypeError, but we will just return undefined.
+               if ( !jQuery.isFunction( fn ) ) {
+                       return undefined;
                }
 
-               if ( !proxy && fn ) {
+               // Simulated bind
+               var args = slice.call( arguments, 2 ),
                        proxy = function() {
-                               return fn.apply( thisObject || this, arguments );
+                               return fn.apply( context, args.concat( slice.call( arguments ) ) );
                        };
-               }
 
                // Set the guid of unique handler to the same of original handler, so it can be removed
-               if ( fn ) {
-                       proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
-               }
+               proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
 
-               // So proxy can be declared as an argument
                return proxy;
        },
 
@@ -790,7 +802,7 @@ jQuery.extend({
        // The value/s can be optionally by executed if its a function
        access: function( elems, key, value, exec, fn, pass ) {
                var length = elems.length;
-       
+
                // Setting many attributes
                if ( typeof key === "object" ) {
                        for ( var k in key ) {
@@ -798,19 +810,19 @@ jQuery.extend({
                        }
                        return elems;
                }
-       
+
                // Setting one attribute
                if ( value !== undefined ) {
                        // Optionally, function values get executed if exec is true
                        exec = !pass && exec && jQuery.isFunction(value);
-               
+
                        for ( var i = 0; i < length; i++ ) {
                                fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
                        }
-               
+
                        return elems;
                }
-       
+
                // Getting an attribute
                return length ? fn( elems[0], key ) : undefined;
        },
@@ -833,6 +845,27 @@ jQuery.extend({
                return { browser: match[1] || "", version: match[2] || "0" };
        },
 
+       sub: function() {
+               function jQuerySub( selector, context ) {
+                       return new jQuerySub.fn.init( selector, context );
+               }
+               jQuery.extend( true, jQuerySub, this );
+               jQuerySub.superclass = this;
+               jQuerySub.fn = jQuerySub.prototype = this();
+               jQuerySub.fn.constructor = jQuerySub;
+               jQuerySub.sub = this.sub;
+               jQuerySub.fn.init = function init( selector, context ) {
+                       if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
+                               context = jQuerySub( context );
+                       }
+
+                       return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
+               };
+               jQuerySub.fn.init.prototype = jQuerySub.fn;
+               var rootjQuerySub = jQuerySub(document);
+               return jQuerySub;
+       },
+
        browser: {}
 });
 
@@ -852,15 +885,8 @@ if ( jQuery.browser.webkit ) {
        jQuery.browser.safari = true;
 }
 
-if ( indexOf ) {
-       jQuery.inArray = function( elem, array ) {
-               return indexOf.call( array, elem );
-       };
-}
-
-// Verify that \s matches non-breaking spaces
-// (IE fails on this test)
-if ( !rwhite.test( "\xA0" ) ) {
+// IE doesn't match non-breaking spaces with \s
+if ( rnotwhite.test( "\xA0" ) ) {
        trimLeft = /^[\s\xA0]+/;
        trimRight = /[\s\xA0]+$/;
 }
@@ -905,52 +931,265 @@ function doScrollCheck() {
 }
 
 // Expose jQuery to the global object
-return (window.jQuery = window.$ = jQuery);
+return jQuery;
 
 })();
 
 
-(function() {
+var // Promise methods
+       promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ),
+       // Static reference to slice
+       sliceDeferred = [].slice;
+
+jQuery.extend({
+       // Create a simple deferred (one callbacks list)
+       _Deferred: function() {
+               var // callbacks list
+                       callbacks = [],
+                       // stored [ context , args ]
+                       fired,
+                       // to avoid firing when already doing so
+                       firing,
+                       // flag to know if the deferred has been cancelled
+                       cancelled,
+                       // the deferred itself
+                       deferred  = {
+
+                               // done( f1, f2, ...)
+                               done: function() {
+                                       if ( !cancelled ) {
+                                               var args = arguments,
+                                                       i,
+                                                       length,
+                                                       elem,
+                                                       type,
+                                                       _fired;
+                                               if ( fired ) {
+                                                       _fired = fired;
+                                                       fired = 0;
+                                               }
+                                               for ( i = 0, length = args.length; i < length; i++ ) {
+                                                       elem = args[ i ];
+                                                       type = jQuery.type( elem );
+                                                       if ( type === "array" ) {
+                                                               deferred.done.apply( deferred, elem );
+                                                       } else if ( type === "function" ) {
+                                                               callbacks.push( elem );
+                                                       }
+                                               }
+                                               if ( _fired ) {
+                                                       deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
+                                               }
+                                       }
+                                       return this;
+                               },
+
+                               // resolve with given context and args
+                               resolveWith: function( context, args ) {
+                                       if ( !cancelled && !fired && !firing ) {
+                                               // make sure args are available (#8421)
+                                               args = args || [];
+                                               firing = 1;
+                                               try {
+                                                       while( callbacks[ 0 ] ) {
+                                                               callbacks.shift().apply( context, args );
+                                                       }
+                                               }
+                                               finally {
+                                                       fired = [ context, args ];
+                                                       firing = 0;
+                                               }
+                                       }
+                                       return this;
+                               },
+
+                               // resolve with this as context and given arguments
+                               resolve: function() {
+                                       deferred.resolveWith( this, arguments );
+                                       return this;
+                               },
+
+                               // Has this deferred been resolved?
+                               isResolved: function() {
+                                       return !!( firing || fired );
+                               },
+
+                               // Cancel
+                               cancel: function() {
+                                       cancelled = 1;
+                                       callbacks = [];
+                                       return this;
+                               }
+                       };
+
+               return deferred;
+       },
+
+       // Full fledged deferred (two callbacks list)
+       Deferred: function( func ) {
+               var deferred = jQuery._Deferred(),
+                       failDeferred = jQuery._Deferred(),
+                       promise;
+               // Add errorDeferred methods, then and promise
+               jQuery.extend( deferred, {
+                       then: function( doneCallbacks, failCallbacks ) {
+                               deferred.done( doneCallbacks ).fail( failCallbacks );
+                               return this;
+                       },
+                       always: function() {
+                               return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );
+                       },
+                       fail: failDeferred.done,
+                       rejectWith: failDeferred.resolveWith,
+                       reject: failDeferred.resolve,
+                       isRejected: failDeferred.isResolved,
+                       pipe: function( fnDone, fnFail ) {
+                               return jQuery.Deferred(function( newDefer ) {
+                                       jQuery.each( {
+                                               done: [ fnDone, "resolve" ],
+                                               fail: [ fnFail, "reject" ]
+                                       }, function( handler, data ) {
+                                               var fn = data[ 0 ],
+                                                       action = data[ 1 ],
+                                                       returned;
+                                               if ( jQuery.isFunction( fn ) ) {
+                                                       deferred[ handler ](function() {
+                                                               returned = fn.apply( this, arguments );
+                                                               if ( returned && jQuery.isFunction( returned.promise ) ) {
+                                                                       returned.promise().then( newDefer.resolve, newDefer.reject );
+                                                               } else {
+                                                                       newDefer[ action ]( returned );
+                                                               }
+                                                       });
+                                               } else {
+                                                       deferred[ handler ]( newDefer[ action ] );
+                                               }
+                                       });
+                               }).promise();
+                       },
+                       // Get a promise for this deferred
+                       // If obj is provided, the promise aspect is added to the object
+                       promise: function( obj ) {
+                               if ( obj == null ) {
+                                       if ( promise ) {
+                                               return promise;
+                                       }
+                                       promise = obj = {};
+                               }
+                               var i = promiseMethods.length;
+                               while( i-- ) {
+                                       obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];
+                               }
+                               return obj;
+                       }
+               });
+               // Make sure only one callback list will be used
+               deferred.done( failDeferred.cancel ).fail( deferred.cancel );
+               // Unexpose cancel
+               delete deferred.cancel;
+               // Call given func if any
+               if ( func ) {
+                       func.call( deferred, deferred );
+               }
+               return deferred;
+       },
+
+       // Deferred helper
+       when: function( firstParam ) {
+               var args = arguments,
+                       i = 0,
+                       length = args.length,
+                       count = length,
+                       deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
+                               firstParam :
+                               jQuery.Deferred();
+               function resolveFunc( i ) {
+                       return function( value ) {
+                               args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
+                               if ( !( --count ) ) {
+                                       // Strange bug in FF4:
+                                       // Values changed onto the arguments object sometimes end up as undefined values
+                                       // outside the $.when method. Cloning the object into a fresh array solves the issue
+                                       deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );
+                               }
+                       };
+               }
+               if ( length > 1 ) {
+                       for( ; i < length; i++ ) {
+                               if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {
+                                       args[ i ].promise().then( resolveFunc(i), deferred.reject );
+                               } else {
+                                       --count;
+                               }
+                       }
+                       if ( !count ) {
+                               deferred.resolveWith( deferred, args );
+                       }
+               } else if ( deferred !== firstParam ) {
+                       deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
+               }
+               return deferred.promise();
+       }
+});
+
+
 
-       jQuery.support = {};
+jQuery.support = (function() {
 
-       var root = document.documentElement,
-               script = document.createElement("script"),
-               div = document.createElement("div"),
-               id = "script" + jQuery.now();
+       var div = document.createElement( "div" ),
+               documentElement = document.documentElement,
+               all,
+               a,
+               select,
+               opt,
+               input,
+               marginDiv,
+               support,
+               fragment,
+               body,
+               bodyStyle,
+               tds,
+               events,
+               eventName,
+               i,
+               isSupported;
 
-       div.style.display = "none";
-       div.innerHTML = "   <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+       // Preliminary tests
+       div.setAttribute("className", "t");
+       div.innerHTML = "   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
 
-       var all = div.getElementsByTagName("*"),
-               a = div.getElementsByTagName("a")[0],
-               select = document.createElement("select"),
-               opt = select.appendChild( document.createElement("option") );
+       all = div.getElementsByTagName( "*" );
+       a = div.getElementsByTagName( "a" )[ 0 ];
 
        // Can't get basic test support
        if ( !all || !all.length || !a ) {
-               return;
+               return {};
        }
 
-       jQuery.support = {
+       // First batch of supports tests
+       select = document.createElement( "select" );
+       opt = select.appendChild( document.createElement("option") );
+       input = div.getElementsByTagName( "input" )[ 0 ];
+
+       support = {
                // IE strips leading whitespace when .innerHTML is used
-               leadingWhitespace: div.firstChild.nodeType === 3,
+               leadingWhitespace: ( div.firstChild.nodeType === 3 ),
 
                // Make sure that tbody elements aren't automatically inserted
                // IE will insert them into empty tables
-               tbody: !div.getElementsByTagName("tbody").length,
+               tbody: !div.getElementsByTagName( "tbody" ).length,
 
                // Make sure that link elements get serialized correctly by innerHTML
                // This requires a wrapper element in IE
-               htmlSerialize: !!div.getElementsByTagName("link").length,
+               htmlSerialize: !!div.getElementsByTagName( "link" ).length,
 
                // Get the style information from getAttribute
-               // (IE uses .cssText insted)
-               style: /red/.test( a.getAttribute("style") ),
+               // (IE uses .cssText instead)
+               style: /top/.test( a.getAttribute("style") ),
 
                // Make sure that URLs aren't manipulated
                // (IE normalizes it by default)
-               hrefNormalized: a.getAttribute("href") === "/a",
+               hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
 
                // Make sure that element opacity exists
                // (IE uses filter instead)
@@ -964,150 +1203,183 @@ return (window.jQuery = window.$ = jQuery);
                // Make sure that if no value is specified for a checkbox
                // that it defaults to "on".
                // (WebKit defaults to "" instead)
-               checkOn: div.getElementsByTagName("input")[0].value === "on",
+               checkOn: ( input.value === "on" ),
 
                // Make sure that a selected-by-default option has a working selected property.
                // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
                optSelected: opt.selected,
 
+               // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
+               getSetAttribute: div.className !== "t",
+
                // Will be defined later
+               submitBubbles: true,
+               changeBubbles: true,
+               focusinBubbles: false,
                deleteExpando: true,
-               optDisabled: false,
-               checkClone: false,
-               scriptEval: false,
                noCloneEvent: true,
-               boxModel: null,
                inlineBlockNeedsLayout: false,
                shrinkWrapBlocks: false,
-               reliableHiddenOffsets: true
+               reliableMarginRight: true
        };
 
+       // Make sure checked status is properly cloned
+       input.checked = true;
+       support.noCloneChecked = input.cloneNode( true ).checked;
+
        // Make sure that the options inside disabled selects aren't marked as disabled
-       // (WebKit marks them as diabled)
+       // (WebKit marks them as disabled)
        select.disabled = true;
-       jQuery.support.optDisabled = !opt.disabled;
-
-       script.type = "text/javascript";
-       try {
-               script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
-       } catch(e) {}
-
-       root.insertBefore( script, root.firstChild );
-
-       // Make sure that the execution of code works by injecting a script
-       // tag with appendChild/createTextNode
-       // (IE doesn't support this, fails, and uses .text instead)
-       if ( window[ id ] ) {
-               jQuery.support.scriptEval = true;
-               delete window[ id ];
-       }
+       support.optDisabled = !opt.disabled;
 
        // Test to see if it's possible to delete an expando from an element
        // Fails in Internet Explorer
        try {
-               delete script.test;
-
-       } catch(e) {
-               jQuery.support.deleteExpando = false;
+               delete div.test;
+       } catch( e ) {
+               support.deleteExpando = false;
        }
 
-       root.removeChild( script );
-
-       if ( div.attachEvent && div.fireEvent ) {
-               div.attachEvent("onclick", function click() {
+       if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
+               div.attachEvent( "onclick", function click() {
                        // Cloning a node shouldn't copy over any
                        // bound event handlers (IE does this)
-                       jQuery.support.noCloneEvent = false;
-                       div.detachEvent("onclick", click);
+                       support.noCloneEvent = false;
+                       div.detachEvent( "onclick", click );
                });
-               div.cloneNode(true).fireEvent("onclick");
+               div.cloneNode( true ).fireEvent( "onclick" );
        }
 
-       div = document.createElement("div");
-       div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
+       // Check if a radio maintains it's value
+       // after being appended to the DOM
+       input = document.createElement("input");
+       input.value = "t";
+       input.setAttribute("type", "radio");
+       support.radioValue = input.value === "t";
 
-       var fragment = document.createDocumentFragment();
+       input.setAttribute("checked", "checked");
+       div.appendChild( input );
+       fragment = document.createDocumentFragment();
        fragment.appendChild( div.firstChild );
 
        // WebKit doesn't clone checked state correctly in fragments
-       jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
+       support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
+
+       div.innerHTML = "";
 
        // Figure out if the W3C box model works as expected
-       // document.body must exist before we can do this
-       jQuery(function() {
-               var div = document.createElement("div");
-               div.style.width = div.style.paddingLeft = "1px";
-
-               document.body.appendChild( div );
-               jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
-
-               if ( "zoom" in div.style ) {
-                       // Check if natively block-level elements act like inline-block
-                       // elements when setting their display to 'inline' and giving
-                       // them layout
-                       // (IE < 8 does this)
-                       div.style.display = "inline";
-                       div.style.zoom = 1;
-                       jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2;
-
-                       // Check if elements with layout shrink-wrap their children
-                       // (IE 6 does this)
-                       div.style.display = "";
-                       div.innerHTML = "<div style='width:4px;'></div>";
-                       jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2;
-               }
-
-               div.innerHTML = "<table><tr><td style='padding:0;display:none'></td><td>t</td></tr></table>";
-               var tds = div.getElementsByTagName("td");
-
-               // Check if table cells still have offsetWidth/Height when they are set
-               // to display:none and there are still other visible table cells in a
-               // table row; if so, offsetWidth/Height are not reliable for use when
-               // determining if an element has been hidden directly using
-               // display:none (it is still safe to use offsets if a parent element is
-               // hidden; don safety goggles and see bug #4512 for more information).
-               // (only IE 8 fails this test)
-               jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0;
-
-               tds[0].style.display = "";
-               tds[1].style.display = "none";
-
-               // Check if empty table cells still have offsetWidth/Height
-               // (IE < 8 fail this test)
-               jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0;
-               div.innerHTML = "";
-
-               document.body.removeChild( div ).style.display = "none";
-               div = tds = null;
-       });
+       div.style.width = div.style.paddingLeft = "1px";
+
+       // We use our own, invisible, body
+       body = document.createElement( "body" );
+       bodyStyle = {
+               visibility: "hidden",
+               width: 0,
+               height: 0,
+               border: 0,
+               margin: 0,
+               // Set background to avoid IE crashes when removing (#9028)
+               background: "none"
+       };
+       for ( i in bodyStyle ) {
+               body.style[ i ] = bodyStyle[ i ];
+       }
+       body.appendChild( div );
+       documentElement.insertBefore( body, documentElement.firstChild );
+
+       // Check if a disconnected checkbox will retain its checked
+       // value of true after appended to the DOM (IE6/7)
+       support.appendChecked = input.checked;
+
+       support.boxModel = div.offsetWidth === 2;
+
+       if ( "zoom" in div.style ) {
+               // Check if natively block-level elements act like inline-block
+               // elements when setting their display to 'inline' and giving
+               // them layout
+               // (IE < 8 does this)
+               div.style.display = "inline";
+               div.style.zoom = 1;
+               support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
+
+               // Check if elements with layout shrink-wrap their children
+               // (IE 6 does this)
+               div.style.display = "";
+               div.innerHTML = "<div style='width:4px;'></div>";
+               support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
+       }
+
+       div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
+       tds = div.getElementsByTagName( "td" );
+
+       // Check if table cells still have offsetWidth/Height when they are set
+       // to display:none and there are still other visible table cells in a
+       // table row; if so, offsetWidth/Height are not reliable for use when
+       // determining if an element has been hidden directly using
+       // display:none (it is still safe to use offsets if a parent element is
+       // hidden; don safety goggles and see bug #4512 for more information).
+       // (only IE 8 fails this test)
+       isSupported = ( tds[ 0 ].offsetHeight === 0 );
+
+       tds[ 0 ].style.display = "";
+       tds[ 1 ].style.display = "none";
+
+       // Check if empty table cells still have offsetWidth/Height
+       // (IE < 8 fail this test)
+       support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
+       div.innerHTML = "";
+
+       // Check if div with explicit width and no margin-right incorrectly
+       // gets computed margin-right based on width of container. For more
+       // info see bug #3333
+       // Fails in WebKit before Feb 2011 nightlies
+       // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+       if ( document.defaultView && document.defaultView.getComputedStyle ) {
+               marginDiv = document.createElement( "div" );
+               marginDiv.style.width = "0";
+               marginDiv.style.marginRight = "0";
+               div.appendChild( marginDiv );
+               support.reliableMarginRight =
+                       ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
+       }
+
+       // Remove the body element we added
+       body.innerHTML = "";
+       documentElement.removeChild( body );
 
        // Technique from Juriy Zaytsev
        // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
-       var eventSupported = function( eventName ) {
-               var el = document.createElement("div");
-               eventName = "on" + eventName;
-
-               var isSupported = (eventName in el);
-               if ( !isSupported ) {
-                       el.setAttribute(eventName, "return;");
-                       isSupported = typeof el[eventName] === "function";
+       // We only care about the case where non-standard event systems
+       // are used, namely in IE. Short-circuiting here helps us to
+       // avoid an eval call (in setAttribute) which can cause CSP
+       // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
+       if ( div.attachEvent ) {
+               for( i in {
+                       submit: 1,
+                       change: 1,
+                       focusin: 1
+               } ) {
+                       eventName = "on" + i;
+                       isSupported = ( eventName in div );
+                       if ( !isSupported ) {
+                               div.setAttribute( eventName, "return;" );
+                               isSupported = ( typeof div[ eventName ] === "function" );
+                       }
+                       support[ i + "Bubbles" ] = isSupported;
                }
-               el = null;
+       }
 
-               return isSupported;
-       };
+       return support;
+})();
 
-       jQuery.support.submitBubbles = eventSupported("submit");
-       jQuery.support.changeBubbles = eventSupported("change");
+// Keep track of boxModel
+jQuery.boxModel = jQuery.support.boxModel;
 
-       // release memory in IE
-       root = script = div = all = a = null;
-})();
 
 
 
-var windowData = {},
-       rbrace = /^(?:\{.*\}|\[.*\])$/;
+var rbrace = /^(?:\{.*\}|\[.*\])$/,
+       rmultiDash = /([a-z])([A-Z])/g;
 
 jQuery.extend({
        cache: {},
@@ -1115,8 +1387,9 @@ jQuery.extend({
        // Please use with caution
        uuid: 0,
 
-       // Unique for each copy of jQuery on the page   
-       expando: "jQuery" + jQuery.now(),
+       // Unique for each copy of jQuery on the page
+       // Non-digits removed to match rinlinejQuery
+       expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
 
        // The following elements throw uncatchable exceptions if you
        // attempt to add expando properties to them.
@@ -1127,103 +1400,185 @@ jQuery.extend({
                "applet": true
        },
 
-       data: function( elem, name, data ) {
+       hasData: function( elem ) {
+               elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
+
+               return !!elem && !isEmptyDataObject( elem );
+       },
+
+       data: function( elem, name, data, pvt /* Internal Use Only */ ) {
                if ( !jQuery.acceptData( elem ) ) {
                        return;
                }
 
-               elem = elem == window ?
-                       windowData :
-                       elem;
+               var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache,
 
-               var isNode = elem.nodeType,
-                       id = isNode ? elem[ jQuery.expando ] : null,
-                       cache = jQuery.cache, thisCache;
+                       // We have to handle DOM nodes and JS objects differently because IE6-7
+                       // can't GC object references properly across the DOM-JS boundary
+                       isNode = elem.nodeType,
 
-               if ( isNode && !id && typeof name === "string" && data === undefined ) {
-                       return;
-               }
+                       // Only DOM nodes need the global jQuery cache; JS object data is
+                       // attached directly to the object so GC can occur automatically
+                       cache = isNode ? jQuery.cache : elem,
 
-               // Get the data from the object directly
-               if ( !isNode ) {
-                       cache = elem;
+                       // Only defining an ID for JS objects if its cache already exists allows
+                       // the code to shortcut on the same path as a DOM node with no cache
+                       id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;
 
-               // Compute a unique ID for the element
-               } else if ( !id ) {
-                       elem[ jQuery.expando ] = id = ++jQuery.uuid;
+               // Avoid doing any more work than we need to when trying to get data on an
+               // object that has no data at all
+               if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) {
+                       return;
                }
 
-               // Avoid generating a new cache unless none exists and we
-               // want to manipulate it.
-               if ( typeof name === "object" ) {
+               if ( !id ) {
+                       // Only DOM nodes need a new unique ID for each element since their data
+                       // ends up in the global cache
                        if ( isNode ) {
-                               cache[ id ] = jQuery.extend(cache[ id ], name);
-
+                               elem[ jQuery.expando ] = id = ++jQuery.uuid;
                        } else {
-                               jQuery.extend( cache, name );
+                               id = jQuery.expando;
                        }
+               }
 
-               } else if ( isNode && !cache[ id ] ) {
+               if ( !cache[ id ] ) {
                        cache[ id ] = {};
+
+                       // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
+                       // metadata on plain JS objects when the object is serialized using
+                       // JSON.stringify
+                       if ( !isNode ) {
+                               cache[ id ].toJSON = jQuery.noop;
+                       }
+               }
+
+               // An object can be passed to jQuery.data instead of a key/value pair; this gets
+               // shallow copied over onto the existing cache
+               if ( typeof name === "object" || typeof name === "function" ) {
+                       if ( pvt ) {
+                               cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);
+                       } else {
+                               cache[ id ] = jQuery.extend(cache[ id ], name);
+                       }
                }
 
-               thisCache = isNode ? cache[ id ] : cache;
+               thisCache = cache[ id ];
+
+               // Internal jQuery data is stored in a separate object inside the object's data
+               // cache in order to avoid key collisions between internal data and user-defined
+               // data
+               if ( pvt ) {
+                       if ( !thisCache[ internalKey ] ) {
+                               thisCache[ internalKey ] = {};
+                       }
+
+                       thisCache = thisCache[ internalKey ];
+               }
 
-               // Prevent overriding the named cache with undefined values
                if ( data !== undefined ) {
-                       thisCache[ name ] = data;
+                       thisCache[ jQuery.camelCase( name ) ] = data;
+               }
+
+               // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should
+               // not attempt to inspect the internal events object using jQuery.data, as this
+               // internal data object is undocumented and subject to change.
+               if ( name === "events" && !thisCache[name] ) {
+                       return thisCache[ internalKey ] && thisCache[ internalKey ].events;
                }
 
-               return typeof name === "string" ? thisCache[ name ] : thisCache;
+               return getByName ? thisCache[ jQuery.camelCase( name ) ] : thisCache;
        },
 
-       removeData: function( elem, name ) {
+       removeData: function( elem, name, pvt /* Internal Use Only */ ) {
                if ( !jQuery.acceptData( elem ) ) {
                        return;
                }
 
-               elem = elem == window ?
-                       windowData :
-                       elem;
+               var internalKey = jQuery.expando, isNode = elem.nodeType,
+
+                       // See jQuery.data for more information
+                       cache = isNode ? jQuery.cache : elem,
 
-               var isNode = elem.nodeType,
-                       id = isNode ? elem[ jQuery.expando ] : elem,
-                       cache = jQuery.cache,
-                       thisCache = isNode ? cache[ id ] : id;
+                       // See jQuery.data for more information
+                       id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
+
+               // If there is already no cache entry for this object, there is no
+               // purpose in continuing
+               if ( !cache[ id ] ) {
+                       return;
+               }
 
-               // If we want to remove a specific section of the element's data
                if ( name ) {
+                       var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];
+
                        if ( thisCache ) {
-                               // Remove the section of cache data
                                delete thisCache[ name ];
 
-                               // If we've removed all the data, remove the element's cache
-                               if ( isNode && jQuery.isEmptyObject(thisCache) ) {
-                                       jQuery.removeData( elem );
+                               // If there is no data left in the cache, we want to continue
+                               // and let the cache object itself get destroyed
+                               if ( !isEmptyDataObject(thisCache) ) {
+                                       return;
                                }
                        }
+               }
+
+               // See jQuery.data for more information
+               if ( pvt ) {
+                       delete cache[ id ][ internalKey ];
+
+                       // Don't destroy the parent cache unless the internal data object
+                       // had been the only thing left in it
+                       if ( !isEmptyDataObject(cache[ id ]) ) {
+                               return;
+                       }
+               }
 
-               // Otherwise, we want to remove all of the element's data
+               var internalCache = cache[ id ][ internalKey ];
+
+               // Browsers that fail expando deletion also refuse to delete expandos on
+               // the window, but it will allow it on all other JS objects; other browsers
+               // don't care
+               if ( jQuery.support.deleteExpando || cache != window ) {
+                       delete cache[ id ];
                } else {
-                       if ( isNode && jQuery.support.deleteExpando ) {
-                               delete elem[ jQuery.expando ];
+                       cache[ id ] = null;
+               }
 
+               // We destroyed the entire user cache at once because it's faster than
+               // iterating through each key, but we need to continue to persist internal
+               // data if it existed
+               if ( internalCache ) {
+                       cache[ id ] = {};
+                       // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
+                       // metadata on plain JS objects when the object is serialized using
+                       // JSON.stringify
+                       if ( !isNode ) {
+                               cache[ id ].toJSON = jQuery.noop;
+                       }
+
+                       cache[ id ][ internalKey ] = internalCache;
+
+               // Otherwise, we need to eliminate the expando on the node to avoid
+               // false lookups in the cache for entries that no longer exist
+               } else if ( isNode ) {
+                       // IE does not allow us to delete expando properties from nodes,
+                       // nor does it have a removeAttribute function on Document nodes;
+                       // we must handle all of these cases
+                       if ( jQuery.support.deleteExpando ) {
+                               delete elem[ jQuery.expando ];
                        } else if ( elem.removeAttribute ) {
                                elem.removeAttribute( jQuery.expando );
-
-                       // Completely remove the data cache
-                       } else if ( isNode ) {
-                               delete cache[ id ];
-
-                       // Remove all fields from the object
                        } else {
-                               for ( var n in elem ) {
-                                       delete elem[ n ];
-                               }
+                               elem[ jQuery.expando ] = null;
                        }
                }
        },
 
+       // For internal use only.
+       _data: function( elem, name, data ) {
+               return jQuery.data( elem, name, data, true );
+       },
+
        // A method for determining if a DOM node can handle the data expando
        acceptData: function( elem ) {
                if ( elem.nodeName ) {
@@ -1244,15 +1599,18 @@ jQuery.fn.extend({
 
                if ( typeof key === "undefined" ) {
                        if ( this.length ) {
-                               var attr = this[0].attributes, name;
                                data = jQuery.data( this[0] );
 
-                               for ( var i = 0, l = attr.length; i < l; i++ ) {
-                                       name = attr[i].name;
+                               if ( this[0].nodeType === 1 ) {
+                           var attr = this[0].attributes, name;
+                                       for ( var i = 0, l = attr.length; i < l; i++ ) {
+                                               name = attr[i].name;
 
-                                       if ( name.indexOf( "data-" ) === 0 ) {
-                                               name = name.substr( 5 );
-                                               dataAttr( this[0], name, data[ name ] );
+                                               if ( name.indexOf( "data-" ) === 0 ) {
+                                                       name = jQuery.camelCase( name.substring(5) );
+
+                                                       dataAttr( this[0], name, data[ name ] );
+                                               }
                                        }
                                }
                        }
@@ -1304,7 +1662,9 @@ function dataAttr( elem, key, data ) {
        // If nothing was found internally, try to fetch any
        // data from the HTML5 data-* attribute
        if ( data === undefined && elem.nodeType === 1 ) {
-               data = elem.getAttribute( "data-" + key );
+               var name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase();
+
+               data = elem.getAttribute( name );
 
                if ( typeof data === "string" ) {
                        try {
@@ -1327,38 +1687,92 @@ function dataAttr( elem, key, data ) {
        return data;
 }
 
-
-
-
-jQuery.extend({
-       queue: function( elem, type, data ) {
-               if ( !elem ) {
-                       return;
+// TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON
+// property to be considered empty objects; this property always exists in
+// order to make sure JSON.stringify does not expose internal metadata
+function isEmptyDataObject( obj ) {
+       for ( var name in obj ) {
+               if ( name !== "toJSON" ) {
+                       return false;
                }
+       }
 
-               type = (type || "fx") + "queue";
-               var q = jQuery.data( elem, type );
+       return true;
+}
 
-               // Speed up dequeue by getting out quickly if this is just a lookup
-               if ( !data ) {
-                       return q || [];
-               }
 
-               if ( !q || jQuery.isArray(data) ) {
-                       q = jQuery.data( elem, type, jQuery.makeArray(data) );
 
-               } else {
-                       q.push( data );
+
+function handleQueueMarkDefer( elem, type, src ) {
+       var deferDataKey = type + "defer",
+               queueDataKey = type + "queue",
+               markDataKey = type + "mark",
+               defer = jQuery.data( elem, deferDataKey, undefined, true );
+       if ( defer &&
+               ( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) &&
+               ( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) {
+               // Give room for hard-coded callbacks to fire first
+               // and eventually mark/queue something else on the element
+               setTimeout( function() {
+                       if ( !jQuery.data( elem, queueDataKey, undefined, true ) &&
+                               !jQuery.data( elem, markDataKey, undefined, true ) ) {
+                               jQuery.removeData( elem, deferDataKey, true );
+                               defer.resolve();
+                       }
+               }, 0 );
+       }
+}
+
+jQuery.extend({
+
+       _mark: function( elem, type ) {
+               if ( elem ) {
+                       type = (type || "fx") + "mark";
+                       jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true );
                }
+       },
 
-               return q;
+       _unmark: function( force, elem, type ) {
+               if ( force !== true ) {
+                       type = elem;
+                       elem = force;
+                       force = false;
+               }
+               if ( elem ) {
+                       type = type || "fx";
+                       var key = type + "mark",
+                               count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 );
+                       if ( count ) {
+                               jQuery.data( elem, key, count, true );
+                       } else {
+                               jQuery.removeData( elem, key, true );
+                               handleQueueMarkDefer( elem, type, "mark" );
+                       }
+               }
+       },
+
+       queue: function( elem, type, data ) {
+               if ( elem ) {
+                       type = (type || "fx") + "queue";
+                       var q = jQuery.data( elem, type, undefined, true );
+                       // Speed up dequeue by getting out quickly if this is just a lookup
+                       if ( data ) {
+                               if ( !q || jQuery.isArray(data) ) {
+                                       q = jQuery.data( elem, type, jQuery.makeArray(data), true );
+                               } else {
+                                       q.push( data );
+                               }
+                       }
+                       return q || [];
+               }
        },
 
        dequeue: function( elem, type ) {
                type = type || "fx";
 
                var queue = jQuery.queue( elem, type ),
-                       fn = queue.shift();
+                       fn = queue.shift(),
+                       defer;
 
                // If the fx queue is dequeued, always remove the progress sentinel
                if ( fn === "inprogress" ) {
@@ -1376,6 +1790,11 @@ jQuery.extend({
                                jQuery.dequeue(elem, type);
                        });
                }
+
+               if ( !queue.length ) {
+                       jQuery.removeData( elem, type + "queue", true );
+                       handleQueueMarkDefer( elem, type, "queue" );
+               }
        }
 });
 
@@ -1389,7 +1808,7 @@ jQuery.fn.extend({
                if ( data === undefined ) {
                        return jQuery.queue( this[0], type );
                }
-               return this.each(function( i ) {
+               return this.each(function() {
                        var queue = jQuery.queue( this, type, data );
 
                        if ( type === "fx" && queue[0] !== "inprogress" ) {
@@ -1402,7 +1821,6 @@ jQuery.fn.extend({
                        jQuery.dequeue( this, type );
                });
        },
-
        // Based off of the plugin by Clint Helfers, with permission.
        // http://blindsignals.com/index.php/2009/07/jquery-delay/
        delay: function( time, type ) {
@@ -1416,61 +1834,93 @@ jQuery.fn.extend({
                        }, time );
                });
        },
-
        clearQueue: function( type ) {
                return this.queue( type || "fx", [] );
+       },
+       // Get a promise resolved when queues of a certain type
+       // are emptied (fx is the type by default)
+       promise: function( type, object ) {
+               if ( typeof type !== "string" ) {
+                       object = type;
+                       type = undefined;
+               }
+               type = type || "fx";
+               var defer = jQuery.Deferred(),
+                       elements = this,
+                       i = elements.length,
+                       count = 1,
+                       deferDataKey = type + "defer",
+                       queueDataKey = type + "queue",
+                       markDataKey = type + "mark",
+                       tmp;
+               function resolve() {
+                       if ( !( --count ) ) {
+                               defer.resolveWith( elements, [ elements ] );
+                       }
+               }
+               while( i-- ) {
+                       if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
+                                       ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
+                                               jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
+                                       jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) {
+                               count++;
+                               tmp.done( resolve );
+                       }
+               }
+               resolve();
+               return defer.promise();
        }
 });
 
 
 
 
-var rclass = /[\n\t]/g,
-       rspaces = /\s+/,
+var rclass = /[\n\t\r]/g,
+       rspace = /\s+/,
        rreturn = /\r/g,
-       rspecialurl = /^(?:href|src|style)$/,
        rtype = /^(?:button|input)$/i,
        rfocusable = /^(?:button|input|object|select|textarea)$/i,
        rclickable = /^a(?:rea)?$/i,
-       rradiocheck = /^(?:radio|checkbox)$/i;
-
-jQuery.props = {
-       "for": "htmlFor",
-       "class": "className",
-       readonly: "readOnly",
-       maxlength: "maxLength",
-       cellspacing: "cellSpacing",
-       rowspan: "rowSpan",
-       colspan: "colSpan",
-       tabindex: "tabIndex",
-       usemap: "useMap",
-       frameborder: "frameBorder"
-};
+       rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
+       rinvalidChar = /\:/,
+       formHook, boolHook;
 
 jQuery.fn.extend({
        attr: function( name, value ) {
                return jQuery.access( this, name, value, true, jQuery.attr );
        },
 
-       removeAttr: function( name, fn ) {
-               return this.each(function(){
-                       jQuery.attr( this, name, "" );
-                       if ( this.nodeType === 1 ) {
-                               this.removeAttribute( name );
-                       }
+       removeAttr: function( name ) {
+               return this.each(function() {
+                       jQuery.removeAttr( this, name );
+               });
+       },
+       
+       prop: function( name, value ) {
+               return jQuery.access( this, name, value, true, jQuery.prop );
+       },
+       
+       removeProp: function( name ) {
+               name = jQuery.propFix[ name ] || name;
+               return this.each(function() {
+                       // try/catch handles cases where IE balks (such as removing a property on window)
+                       try {
+                               this[ name ] = undefined;
+                               delete this[ name ];
+                       } catch( e ) {}
                });
        },
 
        addClass: function( value ) {
-               if ( jQuery.isFunction(value) ) {
+               if ( jQuery.isFunction( value ) ) {
                        return this.each(function(i) {
                                var self = jQuery(this);
-                               self.addClass( value.call(this, i, self.attr("class")) );
+                               self.addClass( value.call(this, i, self.attr("class") || "") );
                        });
                }
 
                if ( value && typeof value === "string" ) {
-                       var classNames = (value || "").split( rspaces );
+                       var classNames = (value || "").split( rspace );
 
                        for ( var i = 0, l = this.length; i < l; i++ ) {
                                var elem = this[i];
@@ -1506,7 +1956,7 @@ jQuery.fn.extend({
                }
 
                if ( (value && typeof value === "string") || value === undefined ) {
-                       var classNames = (value || "").split( rspaces );
+                       var classNames = (value || "").split( rspace );
 
                        for ( var i = 0, l = this.length; i < l; i++ ) {
                                var elem = this[i];
@@ -1547,7 +1997,7 @@ jQuery.fn.extend({
                                        i = 0,
                                        self = jQuery( this ),
                                        state = stateVal,
-                                       classNames = value.split( rspaces );
+                                       classNames = value.split( rspace );
 
                                while ( (className = classNames[ i++ ]) ) {
                                        // check each className given, space seperated list
@@ -1558,11 +2008,11 @@ jQuery.fn.extend({
                        } else if ( type === "undefined" || type === "boolean" ) {
                                if ( this.className ) {
                                        // store className if set
-                                       jQuery.data( this, "__className__", this.className );
+                                       jQuery._data( this, "__className__", this.className );
                                }
 
                                // toggle whole className
-                               this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
+                               this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
                        }
                });
        },
@@ -1579,78 +2029,36 @@ jQuery.fn.extend({
        },
 
        val: function( value ) {
+               var hooks, ret,
+                       elem = this[0];
+               
                if ( !arguments.length ) {
-                       var elem = this[0];
-
                        if ( elem ) {
-                               if ( jQuery.nodeName( elem, "option" ) ) {
-                                       // attributes.value is undefined in Blackberry 4.7 but
-                                       // uses .value. See #6932
-                                       var val = elem.attributes.value;
-                                       return !val || val.specified ? elem.value : elem.text;
-                               }
-
-                               // We need to handle select boxes special
-                               if ( jQuery.nodeName( elem, "select" ) ) {
-                                       var index = elem.selectedIndex,
-                                               values = [],
-                                               options = elem.options,
-                                               one = elem.type === "select-one";
-
-                                       // Nothing was selected
-                                       if ( index < 0 ) {
-                                               return null;
-                                       }
-
-                                       // Loop through all the selected options
-                                       for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
-                                               var option = options[ i ];
-
-                                               // Don't return options that are disabled or in a disabled optgroup
-                                               if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && 
-                                                               (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
-
-                                                       // Get the specific value for the option
-                                                       value = jQuery(option).val();
+                               hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
 
-                                                       // We don't need an array for one selects
-                                                       if ( one ) {
-                                                               return value;
-                                                       }
-
-                                                       // Multi-Selects return an array
-                                                       values.push( value );
-                                               }
-                                       }
-
-                                       return values;
+                               if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
+                                       return ret;
                                }
 
-                               // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
-                               if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
-                                       return elem.getAttribute("value") === null ? "on" : elem.value;
-                               }
-                               
-
-                               // Everything else, we just grab the value
                                return (elem.value || "").replace(rreturn, "");
-
                        }
 
                        return undefined;
                }
 
-               var isFunction = jQuery.isFunction(value);
+               var isFunction = jQuery.isFunction( value );
 
-               return this.each(function(i) {
-                       var self = jQuery(this), val = value;
+               return this.each(function( i ) {
+                       var self = jQuery(this), val;
 
                        if ( this.nodeType !== 1 ) {
                                return;
                        }
 
                        if ( isFunction ) {
-                               val = value.call(this, i, self.val());
+                               val = value.call( this, i, self.val() );
+                       } else {
+                               val = value;
                        }
 
                        // Treat null/undefined as ""; convert numbers to string
@@ -1658,34 +2066,89 @@ jQuery.fn.extend({
                                val = "";
                        } else if ( typeof val === "number" ) {
                                val += "";
-                       } else if ( jQuery.isArray(val) ) {
-                               val = jQuery.map(val, function (value) {
+                       } else if ( jQuery.isArray( val ) ) {
+                               val = jQuery.map(val, function ( value ) {
                                        return value == null ? "" : value + "";
                                });
                        }
 
-                       if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
-                               this.checked = jQuery.inArray( self.val(), val ) >= 0;
+                       hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
+
+                       // If set returns undefined, fall back to normal setting
+                       if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
+                               this.value = val;
+                       }
+               });
+       }
+});
+
+jQuery.extend({
+       valHooks: {
+               option: {
+                       get: function( elem ) {
+                               // attributes.value is undefined in Blackberry 4.7 but
+                               // uses .value. See #6932
+                               var val = elem.attributes.value;
+                               return !val || val.specified ? elem.value : elem.text;
+                       }
+               },
+               select: {
+                       get: function( elem ) {
+                               var value,
+                                       index = elem.selectedIndex,
+                                       values = [],
+                                       options = elem.options,
+                                       one = elem.type === "select-one";
+
+                               // Nothing was selected
+                               if ( index < 0 ) {
+                                       return null;
+                               }
 
-                       } else if ( jQuery.nodeName( this, "select" ) ) {
-                               var values = jQuery.makeArray(val);
+                               // Loop through all the selected options
+                               for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+                                       var option = options[ i ];
 
-                               jQuery( "option", this ).each(function() {
+                                       // Don't return options that are disabled or in a disabled optgroup
+                                       if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
+                                                       (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
+
+                                               // Get the specific value for the option
+                                               value = jQuery( option ).val();
+
+                                               // We don't need an array for one selects
+                                               if ( one ) {
+                                                       return value;
+                                               }
+
+                                               // Multi-Selects return an array
+                                               values.push( value );
+                                       }
+                               }
+
+                               // Fixes Bug #2551 -- select.val() broken in IE after form.reset()
+                               if ( one && !values.length && options.length ) {
+                                       return jQuery( options[ index ] ).val();
+                               }
+
+                               return values;
+                       },
+
+                       set: function( elem, value ) {
+                               var values = jQuery.makeArray( value );
+
+                               jQuery(elem).find("option").each(function() {
                                        this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
                                });
 
                                if ( !values.length ) {
-                                       this.selectedIndex = -1;
+                                       elem.selectedIndex = -1;
                                }
-
-                       } else {
-                               this.value = val;
+                               return values;
                        }
-               });
-       }
-});
+               }
+       },
 
-jQuery.extend({
        attrFn: {
                val: true,
                css: true,
@@ -1696,121 +2159,349 @@ jQuery.extend({
                height: true,
                offset: true
        },
-               
+       
+       attrFix: {
+               // Always normalize to ensure hook usage
+               tabindex: "tabIndex"
+       },
+       
        attr: function( elem, name, value, pass ) {
-               // don't set attributes on text and comment nodes
-               if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+               var nType = elem.nodeType;
+               
+               // don't get/set attributes on text, comment and attribute nodes
+               if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
                        return undefined;
                }
 
                if ( pass && name in jQuery.attrFn ) {
-                       return jQuery(elem)[name](value);
+                       return jQuery( elem )[ name ]( value );
                }
 
-               var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
-                       // Whether we are setting (or getting)
-                       set = value !== undefined;
+               // Fallback to prop when attributes are not supported
+               if ( !("getAttribute" in elem) ) {
+                       return jQuery.prop( elem, name, value );
+               }
 
-               // Try to normalize/fix the name
-               name = notxml && jQuery.props[ name ] || name;
+               var ret, hooks,
+                       notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
 
-               // These attributes require special treatment
-               var special = rspecialurl.test( name );
+               // Normalize the name if needed
+               name = notxml && jQuery.attrFix[ name ] || name;
 
-               // Safari mis-reports the default selected property of an option
-               // Accessing the parent's selectedIndex property fixes it
-               if ( name === "selected" && !jQuery.support.optSelected ) {
-                       var parent = elem.parentNode;
-                       if ( parent ) {
-                               parent.selectedIndex;
+               hooks = jQuery.attrHooks[ name ];
 
-                               // Make sure that it also works with optgroups, see #5701
-                               if ( parent.parentNode ) {
-                                       parent.parentNode.selectedIndex;
-                               }
+               if ( !hooks ) {
+                       // Use boolHook for boolean attributes
+                       if ( rboolean.test( name ) &&
+                               (typeof value === "boolean" || value === undefined || value.toLowerCase() === name.toLowerCase()) ) {
+
+                               hooks = boolHook;
+
+                       // Use formHook for forms and if the name contains certain characters
+                       } else if ( formHook && (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ) {
+                               hooks = formHook;
                        }
                }
 
-               // If applicable, access the attribute via the DOM 0 way
-               // 'in' checks fail in Blackberry 4.7 #6931
-               if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) {
-                       if ( set ) {
-                               // We can't allow the type property to be changed (since it causes problems in IE)
-                               if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
-                                       jQuery.error( "type property can't be changed" );
-                               }
+               if ( value !== undefined ) {
 
-                               if ( value === null ) {
-                                       if ( elem.nodeType === 1 ) {
-                                               elem.removeAttribute( name );
-                                       }
+                       if ( value === null ) {
+                               jQuery.removeAttr( elem, name );
+                               return undefined;
 
-                               } else {
-                                       elem[ name ] = value;
-                               }
+                       } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
+                               return ret;
+
+                       } else {
+                               elem.setAttribute( name, "" + value );
+                               return value;
                        }
 
-                       // browsers index elements by id/name on forms, give priority to attributes.
-                       if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
-                               return elem.getAttributeNode( name ).nodeValue;
+               } else if ( hooks && "get" in hooks && notxml ) {
+                       return hooks.get( elem, name );
+
+               } else {
+
+                       ret = elem.getAttribute( name );
+
+                       // Non-existent attributes return null, we normalize to undefined
+                       return ret === null ?
+                               undefined :
+                               ret;
+               }
+       },
+
+       removeAttr: function( elem, name ) {
+               var propName;
+               if ( elem.nodeType === 1 ) {
+                       name = jQuery.attrFix[ name ] || name;
+               
+                       if ( jQuery.support.getSetAttribute ) {
+                               // Use removeAttribute in browsers that support it
+                               elem.removeAttribute( name );
+                       } else {
+                               jQuery.attr( elem, name, "" );
+                               elem.removeAttributeNode( elem.getAttributeNode( name ) );
                        }
 
-                       // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
-                       // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
-                       if ( name === "tabIndex" ) {
-                               var attributeNode = elem.getAttributeNode( "tabIndex" );
+                       // Set corresponding property to false for boolean attributes
+                       if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) {
+                               elem[ propName ] = false;
+                       }
+               }
+       },
+
+       attrHooks: {
+               type: {
+                       set: function( elem, value ) {
+                               // We can't allow the type property to be changed (since it causes problems in IE)
+                               if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
+                                       jQuery.error( "type property can't be changed" );
+                               } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
+                                       // Setting the type on a radio button after the value resets the value in IE6-9
+                                       // Reset value to it's default in case type is set after value
+                                       // This is for element creation
+                                       var val = elem.value;
+                                       elem.setAttribute( "type", value );
+                                       if ( val ) {
+                                               elem.value = val;
+                                       }
+                                       return value;
+                               }
+                       }
+               },
+               tabIndex: {
+                       get: function( elem ) {
+                               // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+                               // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+                               var attributeNode = elem.getAttributeNode("tabIndex");
 
                                return attributeNode && attributeNode.specified ?
-                                       attributeNode.value :
+                                       parseInt( attributeNode.value, 10 ) :
                                        rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
                                                0 :
                                                undefined;
                        }
+               }
+       },
 
-                       return elem[ name ];
+       propFix: {
+               tabindex: "tabIndex",
+               readonly: "readOnly",
+               "for": "htmlFor",
+               "class": "className",
+               maxlength: "maxLength",
+               cellspacing: "cellSpacing",
+               cellpadding: "cellPadding",
+               rowspan: "rowSpan",
+               colspan: "colSpan",
+               usemap: "useMap",
+               frameborder: "frameBorder",
+               contenteditable: "contentEditable"
+       },
+       
+       prop: function( elem, name, value ) {
+               var nType = elem.nodeType;
+
+               // don't get/set properties on text, comment and attribute nodes
+               if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+                       return undefined;
                }
 
-               if ( !jQuery.support.style && notxml && name === "style" ) {
-                       if ( set ) {
-                               elem.style.cssText = "" + value;
+               var ret, hooks,
+                       notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
+
+               // Try to normalize/fix the name
+               name = notxml && jQuery.propFix[ name ] || name;
+               
+               hooks = jQuery.propHooks[ name ];
+
+               if ( value !== undefined ) {
+                       if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
+                               return ret;
+
+                       } else {
+                               return (elem[ name ] = value);
                        }
 
-                       return elem.style.cssText;
+               } else {
+                       if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) {
+                               return ret;
+
+                       } else {
+                               return elem[ name ];
+                       }
                }
+       },
+       
+       propHooks: {}
+});
 
-               if ( set ) {
-                       // convert the value to a string (all browsers do this but IE) see #1070
-                       elem.setAttribute( name, "" + value );
+// Hook for boolean attributes
+boolHook = {
+       get: function( elem, name ) {
+               // Align boolean attributes with corresponding properties
+               return elem[ jQuery.propFix[ name ] || name ] ?
+                       name.toLowerCase() :
+                       undefined;
+       },
+       set: function( elem, value, name ) {
+               var propName;
+               if ( value === false ) {
+                       // Remove boolean attributes when set to false
+                       jQuery.removeAttr( elem, name );
+               } else {
+                       // value is true since we know at this point it's type boolean and not false
+                       // Set boolean attributes to the same name and set the DOM property
+                       propName = jQuery.propFix[ name ] || name;
+                       if ( propName in elem ) {
+                               // Only set the IDL specifically if it already exists on the element
+                               elem[ propName ] = value;
+                       }
+
+                       elem.setAttribute( name, name.toLowerCase() );
                }
+               return name;
+       }
+};
 
-               // Ensure that missing attributes return undefined
-               // Blackberry 4.7 returns "" from getAttribute #6938
-               if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) {
-                       return undefined;
+// Use the value property for back compat
+// Use the formHook for button elements in IE6/7 (#1954)
+jQuery.attrHooks.value = {
+       get: function( elem, name ) {
+               if ( formHook && jQuery.nodeName( elem, "button" ) ) {
+                       return formHook.get( elem, name );
+               }
+               return elem.value;
+       },
+       set: function( elem, value, name ) {
+               if ( formHook && jQuery.nodeName( elem, "button" ) ) {
+                       return formHook.set( elem, value, name );
                }
+               // Does not return so that setAttribute is also used
+               elem.value = value;
+       }
+};
 
-               var attr = !jQuery.support.hrefNormalized && notxml && special ?
-                               // Some attributes require a special call on IE
-                               elem.getAttribute( name, 2 ) :
-                               elem.getAttribute( name );
+// IE6/7 do not support getting/setting some attributes with get/setAttribute
+if ( !jQuery.support.getSetAttribute ) {
 
-               // Non-existent attributes return null, we normalize to undefined
-               return attr === null ? undefined : attr;
-       }
+       // propFix is more comprehensive and contains all fixes
+       jQuery.attrFix = jQuery.propFix;
+       
+       // Use this for any attribute on a form in IE6/7
+       formHook = jQuery.attrHooks.name = jQuery.valHooks.button = {
+               get: function( elem, name ) {
+                       var ret;
+                       ret = elem.getAttributeNode( name );
+                       // Return undefined if nodeValue is empty string
+                       return ret && ret.nodeValue !== "" ?
+                               ret.nodeValue :
+                               undefined;
+               },
+               set: function( elem, value, name ) {
+                       // Check form objects in IE (multiple bugs related)
+                       // Only use nodeValue if the attribute node exists on the form
+                       var ret = elem.getAttributeNode( name );
+                       if ( ret ) {
+                               ret.nodeValue = value;
+                               return value;
+                       }
+               }
+       };
+
+       // Set width and height to auto instead of 0 on empty string( Bug #8150 )
+       // This is for removals
+       jQuery.each([ "width", "height" ], function( i, name ) {
+               jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
+                       set: function( elem, value ) {
+                               if ( value === "" ) {
+                                       elem.setAttribute( name, "auto" );
+                                       return value;
+                               }
+                       }
+               });
+       });
+}
+
+
+// Some attributes require a special call on IE
+if ( !jQuery.support.hrefNormalized ) {
+       jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
+               jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
+                       get: function( elem ) {
+                               var ret = elem.getAttribute( name, 2 );
+                               return ret === null ? undefined : ret;
+                       }
+               });
+       });
+}
+
+if ( !jQuery.support.style ) {
+       jQuery.attrHooks.style = {
+               get: function( elem ) {
+                       // Return undefined in the case of empty string
+                       // Normalize to lowercase since IE uppercases css property names
+                       return elem.style.cssText.toLowerCase() || undefined;
+               },
+               set: function( elem, value ) {
+                       return (elem.style.cssText = "" + value);
+               }
+       };
+}
+
+// Safari mis-reports the default selected property of an option
+// Accessing the parent's selectedIndex property fixes it
+if ( !jQuery.support.optSelected ) {
+       jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
+               get: function( elem ) {
+                       var parent = elem.parentNode;
+
+                       if ( parent ) {
+                               parent.selectedIndex;
+
+                               // Make sure that it also works with optgroups, see #5701
+                               if ( parent.parentNode ) {
+                                       parent.parentNode.selectedIndex;
+                               }
+                       }
+               }
+       });
+}
+
+// Radios and checkboxes getter/setter
+if ( !jQuery.support.checkOn ) {
+       jQuery.each([ "radio", "checkbox" ], function() {
+               jQuery.valHooks[ this ] = {
+                       get: function( elem ) {
+                               // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
+                               return elem.getAttribute("value") === null ? "on" : elem.value;
+                       }
+               };
+       });
+}
+jQuery.each([ "radio", "checkbox" ], function() {
+       jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
+               set: function( elem, value ) {
+                       if ( jQuery.isArray( value ) ) {
+                               return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0);
+                       }
+               }
+       });
 });
 
 
 
 
-var rnamespaces = /\.(.*)$/,
+var hasOwn = Object.prototype.hasOwnProperty,
+       rnamespaces = /\.(.*)$/,
        rformElems = /^(?:textarea|input|select)$/i,
        rperiod = /\./g,
-       rspace = / /g,
+       rspaces = / /g,
        rescape = /[^\w\s.|`]/g,
        fcleanup = function( nm ) {
                return nm.replace(rescape, "\\$&");
-       },
-       focusCounts = { focusin: 0, focusout: 0 };
+       };
 
 /*
  * A number of helper functions used for managing events.
@@ -1826,17 +2517,11 @@ jQuery.event = {
                        return;
                }
 
-               // For whatever reason, IE has trouble passing the window object
-               // around, causing it to be cloned in the process
-               if ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) {
-                       elem = window;
-               }
-
                if ( handler === false ) {
                        handler = returnFalse;
                } else if ( !handler ) {
                        // Fixes bug #7229. Fix recommended by jdalton
-                 return;
+                       return;
                }
 
                var handleObjIn, handleObj;
@@ -1852,7 +2537,7 @@ jQuery.event = {
                }
 
                // Init the element's event structure
-               var elemData = jQuery.data( elem );
+               var elemData = jQuery._data( elem );
 
                // If no elemData is found then we must be trying to bind to one of the
                // banned noData elements
@@ -1860,34 +2545,18 @@ jQuery.event = {
                        return;
                }
 
-               // Use a key less likely to result in collisions for plain JS objects.
-               // Fixes bug #7150.
-               var eventKey = elem.nodeType ? "events" : "__events__",
-                       events = elemData[ eventKey ],
+               var events = elemData.events,
                        eventHandle = elemData.handle;
-                       
-               if ( typeof events === "function" ) {
-                       // On plain objects events is a fn that holds the the data
-                       // which prevents this data from being JSON serialized
-                       // the function does not need to be called, it just contains the data
-                       eventHandle = events.handle;
-                       events = events.events;
-
-               } else if ( !events ) {
-                       if ( !elem.nodeType ) {
-                               // On plain objects, create a fn that acts as the holder
-                               // of the values to avoid JSON serialization of event data
-                               elemData[ eventKey ] = elemData = function(){};
-                       }
 
+               if ( !events ) {
                        elemData.events = events = {};
                }
 
                if ( !eventHandle ) {
-                       elemData.handle = eventHandle = function() {
-                               // Handle the second event of a trigger and when
-                               // an event is called after a page has unloaded
-                               return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
+                       elemData.handle = eventHandle = function( e ) {
+                               // Discard the second event of a jQuery.event.trigger() and
+                               // when an event is called after a page has unloaded
+                               return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
                                        jQuery.event.handle.apply( eventHandle.elem, arguments ) :
                                        undefined;
                        };
@@ -1945,9 +2614,9 @@ jQuery.event = {
                                        }
                                }
                        }
-                       
-                       if ( special.add ) { 
-                               special.add.call( elem, handleObj ); 
+
+                       if ( special.add ) {
+                               special.add.call( elem, handleObj );
 
                                if ( !handleObj.handler.guid ) {
                                        handleObj.handler.guid = handler.guid;
@@ -1957,7 +2626,7 @@ jQuery.event = {
                        // Add the function to the element's handler list
                        handlers.push( handleObj );
 
-                       // Keep track of which events have been used, for global triggering
+                       // Keep track of which events have been used, for event optimization
                        jQuery.event.global[ type ] = true;
                }
 
@@ -1979,18 +2648,12 @@ jQuery.event = {
                }
 
                var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
-                       eventKey = elem.nodeType ? "events" : "__events__",
-                       elemData = jQuery.data( elem ),
-                       events = elemData && elemData[ eventKey ];
+                       elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
+                       events = elemData && elemData.events;
 
                if ( !elemData || !events ) {
                        return;
                }
-               
-               if ( typeof events === "function" ) {
-                       elemData = events;
-                       events = events.events;
-               }
 
                // types is actually an event object here
                if ( types && types.type ) {
@@ -2024,7 +2687,7 @@ jQuery.event = {
                                namespaces = type.split(".");
                                type = namespaces.shift();
 
-                               namespace = new RegExp("(^|\\.)" + 
+                               namespace = new RegExp("(^|\\.)" +
                                        jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
                        }
 
@@ -2091,189 +2754,190 @@ jQuery.event = {
                        delete elemData.events;
                        delete elemData.handle;
 
-                       if ( typeof elemData === "function" ) {
-                               jQuery.removeData( elem, eventKey );
-
-                       } else if ( jQuery.isEmptyObject( elemData ) ) {
-                               jQuery.removeData( elem );
+                       if ( jQuery.isEmptyObject( elemData ) ) {
+                               jQuery.removeData( elem, undefined, true );
                        }
                }
        },
+       
+       // Events that are safe to short-circuit if no handlers are attached.
+       // Native DOM events should not be added, they may have inline handlers.
+       customEvent: {
+               "getData": true,
+               "setData": true,
+               "changeData": true
+       },
 
-       // bubbling is internal
-       trigger: function( event, data, elem /*, bubbling */ ) {
+       trigger: function( event, data, elem, onlyHandlers ) {
                // Event object or event type
                var type = event.type || event,
-                       bubbling = arguments[3];
+                       namespaces = [],
+                       exclusive;
 
-               if ( !bubbling ) {
-                       event = typeof event === "object" ?
-                               // jQuery.Event object
-                               event[ jQuery.expando ] ? event :
-                               // Object literal
-                               jQuery.extend( jQuery.Event(type), event ) :
-                               // Just the event type (string)
-                               jQuery.Event(type);
+               if ( type.indexOf("!") >= 0 ) {
+                       // Exclusive events trigger only for the exact event (no namespaces)
+                       type = type.slice(0, -1);
+                       exclusive = true;
+               }
 
-                       if ( type.indexOf("!") >= 0 ) {
-                               event.type = type = type.slice(0, -1);
-                               event.exclusive = true;
-                       }
+               if ( type.indexOf(".") >= 0 ) {
+                       // Namespaced trigger; create a regexp to match event type in handle()
+                       namespaces = type.split(".");
+                       type = namespaces.shift();
+                       namespaces.sort();
+               }
 
-                       // Handle a global trigger
-                       if ( !elem ) {
-                               // Don't bubble custom events when global (to avoid too much overhead)
-                               event.stopPropagation();
-
-                               // Only trigger if we've ever bound an event for it
-                               if ( jQuery.event.global[ type ] ) {
-                                       jQuery.each( jQuery.cache, function() {
-                                               if ( this.events && this.events[type] ) {
-                                                       jQuery.event.trigger( event, data, this.handle.elem );
-                                               }
-                                       });
-                               }
-                       }
+               if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
+                       // No jQuery handlers for this event type, and it can't have inline handlers
+                       return;
+               }
 
-                       // Handle triggering a single element
+               // Caller can pass in an Event, Object, or just an event type string
+               event = typeof event === "object" ?
+                       // jQuery.Event object
+                       event[ jQuery.expando ] ? event :
+                       // Object literal
+                       new jQuery.Event( type, event ) :
+                       // Just the event type (string)
+                       new jQuery.Event( type );
 
-                       // don't do events on text and comment nodes
-                       if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
-                               return undefined;
-                       }
+               event.type = type;
+               event.exclusive = exclusive;
+               event.namespace = namespaces.join(".");
+               event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
+               
+               // triggerHandler() and global events don't bubble or run the default action
+               if ( onlyHandlers || !elem ) {
+                       event.preventDefault();
+                       event.stopPropagation();
+               }
 
-                       // Clean up in case it is reused
-                       event.result = undefined;
-                       event.target = elem;
+               // Handle a global trigger
+               if ( !elem ) {
+                       // TODO: Stop taunting the data cache; remove global events and always attach to document
+                       jQuery.each( jQuery.cache, function() {
+                               // internalKey variable is just used to make it easier to find
+                               // and potentially change this stuff later; currently it just
+                               // points to jQuery.expando
+                               var internalKey = jQuery.expando,
+                                       internalCache = this[ internalKey ];
+                               if ( internalCache && internalCache.events && internalCache.events[ type ] ) {
+                                       jQuery.event.trigger( event, data, internalCache.handle.elem );
+                               }
+                       });
+                       return;
+               }
 
-                       // Clone the incoming data, if any
-                       data = jQuery.makeArray( data );
-                       data.unshift( event );
+               // Don't do events on text and comment nodes
+               if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+                       return;
                }
 
-               event.currentTarget = elem;
+               // Clean up the event in case it is being reused
+               event.result = undefined;
+               event.target = elem;
 
-               // Trigger the event, it is assumed that "handle" is a function
-               var handle = elem.nodeType ?
-                       jQuery.data( elem, "handle" ) :
-                       (jQuery.data( elem, "__events__" ) || {}).handle;
+               // Clone any incoming data and prepend the event, creating the handler arg list
+               data = data ? jQuery.makeArray( data ) : [];
+               data.unshift( event );
 
-               if ( handle ) {
-                       handle.apply( elem, data );
-               }
+               var cur = elem,
+                       // IE doesn't like method names with a colon (#3533, #8272)
+                       ontype = type.indexOf(":") < 0 ? "on" + type : "";
 
-               var parent = elem.parentNode || elem.ownerDocument;
+               // Fire event on the current element, then bubble up the DOM tree
+               do {
+                       var handle = jQuery._data( cur, "handle" );
 
-               // Trigger an inline bound script
-               try {
-                       if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
-                               if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
-                                       event.result = false;
-                                       event.preventDefault();
-                               }
+                       event.currentTarget = cur;
+                       if ( handle ) {
+                               handle.apply( cur, data );
                        }
 
-               // prevent IE from throwing an error for some elements with some event types, see #3533
-               } catch (inlineError) {}
+                       // Trigger an inline bound script
+                       if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) {
+                               event.result = false;
+                               event.preventDefault();
+                       }
 
-               if ( !event.isPropagationStopped() && parent ) {
-                       jQuery.event.trigger( event, data, parent, true );
+                       // Bubble up to document, then to window
+                       cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window;
+               } while ( cur && !event.isPropagationStopped() );
 
-               } else if ( !event.isDefaultPrevented() ) {
+               // If nobody prevented the default action, do it now
+               if ( !event.isDefaultPrevented() ) {
                        var old,
-                               target = event.target,
-                               targetType = type.replace( rnamespaces, "" ),
-                               isClick = jQuery.nodeName( target, "a" ) && targetType === "click",
-                               special = jQuery.event.special[ targetType ] || {};
+                               special = jQuery.event.special[ type ] || {};
 
-                       if ( (!special._default || special._default.call( elem, event ) === false) && 
-                               !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
+                       if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) &&
+                               !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
 
+                               // Call a native DOM method on the target with the same name name as the event.
+                               // Can't use an .isFunction)() check here because IE6/7 fails that test.
+                               // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch.
                                try {
-                                       if ( target[ targetType ] ) {
-                                               // Make sure that we don't accidentally re-trigger the onFOO events
-                                               old = target[ "on" + targetType ];
+                                       if ( ontype && elem[ type ] ) {
+                                               // Don't re-trigger an onFOO event when we call its FOO() method
+                                               old = elem[ ontype ];
 
                                                if ( old ) {
-                                                       target[ "on" + targetType ] = null;
+                                                       elem[ ontype ] = null;
                                                }
 
-                                               jQuery.event.triggered = true;
-                                               target[ targetType ]();
+                                               jQuery.event.triggered = type;
+                                               elem[ type ]();
                                        }
-
-                               // prevent IE from throwing an error for some elements with some event types, see #3533
-                               } catch (triggerError) {}
+                               } catch ( ieError ) {}
 
                                if ( old ) {
-                                       target[ "on" + targetType ] = old;
+                                       elem[ ontype ] = old;
                                }
 
-                               jQuery.event.triggered = false;
+                               jQuery.event.triggered = undefined;
                        }
                }
+               
+               return event.result;
        },
 
        handle: function( event ) {
-               var all, handlers, namespaces, namespace_re, events,
-                       namespace_sort = [],
-                       args = jQuery.makeArray( arguments );
-
-               event = args[0] = jQuery.event.fix( event || window.event );
+               event = jQuery.event.fix( event || window.event );
+               // Snapshot the handlers list since a called handler may add/remove events.
+               var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0),
+                       run_all = !event.exclusive && !event.namespace,
+                       args = Array.prototype.slice.call( arguments, 0 );
+
+               // Use the fix-ed Event rather than the (read-only) native event
+               args[0] = event;
                event.currentTarget = this;
 
-               // Namespaced event handlers
-               all = event.type.indexOf(".") < 0 && !event.exclusive;
-
-               if ( !all ) {
-                       namespaces = event.type.split(".");
-                       event.type = namespaces.shift();
-                       namespace_sort = namespaces.slice(0).sort();
-                       namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)");
-               }
-
-               event.namespace = event.namespace || namespace_sort.join(".");
-
-               events = jQuery.data(this, this.nodeType ? "events" : "__events__");
-
-               if ( typeof events === "function" ) {
-                       events = events.events;
-               }
-
-               handlers = (events || {})[ event.type ];
-
-               if ( events && handlers ) {
-                       // Clone the handlers to prevent manipulation
-                       handlers = handlers.slice(0);
-
-                       for ( var j = 0, l = handlers.length; j < l; j++ ) {
-                               var handleObj = handlers[ j ];
-
-                               // Filter the functions by class
-                               if ( all || namespace_re.test( handleObj.namespace ) ) {
-                                       // Pass in a reference to the handler function itself
-                                       // So that we can later remove it
-                                       event.handler = handleObj.handler;
-                                       event.data = handleObj.data;
-                                       event.handleObj = handleObj;
-       
-                                       var ret = handleObj.handler.apply( this, args );
-
-                                       if ( ret !== undefined ) {
-                                               event.result = ret;
-                                               if ( ret === false ) {
-                                                       event.preventDefault();
-                                                       event.stopPropagation();
-                                               }
+               for ( var j = 0, l = handlers.length; j < l; j++ ) {
+                       var handleObj = handlers[ j ];
+
+                       // Triggered event must 1) be non-exclusive and have no namespace, or
+                       // 2) have namespace(s) a subset or equal to those in the bound event.
+                       if ( run_all || event.namespace_re.test( handleObj.namespace ) ) {
+                               // Pass in a reference to the handler function itself
+                               // So that we can later remove it
+                               event.handler = handleObj.handler;
+                               event.data = handleObj.data;
+                               event.handleObj = handleObj;
+
+                               var ret = handleObj.handler.apply( this, args );
+
+                               if ( ret !== undefined ) {
+                                       event.result = ret;
+                                       if ( ret === false ) {
+                                               event.preventDefault();
+                                               event.stopPropagation();
                                        }
+                               }
 
-                                       if ( event.isImmediatePropagationStopped() ) {
-                                               break;
-                                       }
+                               if ( event.isImmediatePropagationStopped() ) {
+                                       break;
                                }
                        }
                }
-
                return event.result;
        },
 
@@ -2312,8 +2976,9 @@ jQuery.event = {
 
                // Calculate pageX/Y if missing and clientX/Y available
                if ( event.pageX == null && event.clientX != null ) {
-                       var doc = document.documentElement,
-                               body = document.body;
+                       var eventDocument = event.target.ownerDocument || document,
+                               doc = eventDocument.documentElement,
+                               body = eventDocument.body;
 
                        event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
                        event.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);
@@ -2355,7 +3020,7 @@ jQuery.event = {
                        add: function( handleObj ) {
                                jQuery.event.add( this,
                                        liveConvert( handleObj.origType, handleObj.selector ),
-                                       jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) ); 
+                                       jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
                        },
 
                        remove: function( handleObj ) {
@@ -2385,28 +3050,39 @@ jQuery.removeEvent = document.removeEventListener ?
                if ( elem.removeEventListener ) {
                        elem.removeEventListener( type, handle, false );
                }
-       } : 
+       } :
        function( elem, type, handle ) {
                if ( elem.detachEvent ) {
                        elem.detachEvent( "on" + type, handle );
                }
        };
 
-jQuery.Event = function( src ) {
+jQuery.Event = function( src, props ) {
        // Allow instantiation without the 'new' keyword
        if ( !this.preventDefault ) {
-               return new jQuery.Event( src );
+               return new jQuery.Event( src, props );
        }
 
        // Event object
        if ( src && src.type ) {
                this.originalEvent = src;
                this.type = src.type;
+
+               // Events bubbling up the document may have been marked as prevented
+               // by a handler lower down the tree; reflect the correct value.
+               this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
+                       src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
+
        // Event type
        } else {
                this.type = src;
        }
 
+       // Put explicitly provided properties onto the event object
+       if ( props ) {
+               jQuery.extend( this, props );
+       }
+
        // timeStamp is buggy for some events on Firefox(#3843)
        // So we won't rely on the native value
        this.timeStamp = jQuery.now();
@@ -2432,7 +3108,7 @@ jQuery.Event.prototype = {
                if ( !e ) {
                        return;
                }
-               
+
                // if preventDefault exists run it on the original event
                if ( e.preventDefault ) {
                        e.preventDefault();
@@ -2471,18 +3147,25 @@ var withinElement = function( event ) {
        // Check if mouse(over|out) are still within the same parent element
        var parent = event.relatedTarget;
 
+       // set the correct event type
+       event.type = event.data;
+
        // Firefox sometimes assigns relatedTarget a XUL element
        // which we cannot access the parentNode property of
        try {
+
+               // Chrome does something similar, the parentNode property
+               // can be accessed but is null.
+               if ( parent && parent !== document && !parent.parentNode ) {
+                       return;
+               }
+
                // Traverse up the tree
                while ( parent && parent !== this ) {
                        parent = parent.parentNode;
                }
 
                if ( parent !== this ) {
-                       // set the correct event type
-                       event.type = event.data;
-
                        // handle event if we actually just moused on to a non sub-element
                        jQuery.event.handle.apply( this, arguments );
                }
@@ -2518,24 +3201,22 @@ if ( !jQuery.support.submitBubbles ) {
 
        jQuery.event.special.submit = {
                setup: function( data, namespaces ) {
-                       if ( this.nodeName.toLowerCase() !== "form" ) {
+                       if ( !jQuery.nodeName( this, "form" ) ) {
                                jQuery.event.add(this, "click.specialSubmit", function( e ) {
                                        var elem = e.target,
                                                type = elem.type;
 
                                        if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
-                                               e.liveFired = undefined;
-                                               return trigger( "submit", this, arguments );
+                                               trigger( "submit", this, arguments );
                                        }
                                });
-        
+
                                jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
                                        var elem = e.target,
                                                type = elem.type;
 
                                        if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
-                                               e.liveFired = undefined;
-                                               return trigger( "submit", this, arguments );
+                                               trigger( "submit", this, arguments );
                                        }
                                });
 
@@ -2569,7 +3250,7 @@ if ( !jQuery.support.changeBubbles ) {
                                }).join("-") :
                                "";
 
-               } else if ( elem.nodeName.toLowerCase() === "select" ) {
+               } else if ( jQuery.nodeName( elem, "select" ) ) {
                        val = elem.selectedIndex;
                }
 
@@ -2583,14 +3264,14 @@ if ( !jQuery.support.changeBubbles ) {
                        return;
                }
 
-               data = jQuery.data( elem, "_change_data" );
+               data = jQuery._data( elem, "_change_data" );
                val = getVal(elem);
 
                // the current data will be also retrieved by beforeactivate
                if ( e.type !== "focusout" || elem.type !== "radio" ) {
-                       jQuery.data( elem, "_change_data", val );
+                       jQuery._data( elem, "_change_data", val );
                }
-               
+
                if ( data === undefined || val === data ) {
                        return;
                }
@@ -2598,33 +3279,33 @@ if ( !jQuery.support.changeBubbles ) {
                if ( data != null || val ) {
                        e.type = "change";
                        e.liveFired = undefined;
-                       return jQuery.event.trigger( e, arguments[1], elem );
+                       jQuery.event.trigger( e, arguments[1], elem );
                }
        };
 
        jQuery.event.special.change = {
                filters: {
-                       focusout: testChange, 
+                       focusout: testChange,
 
                        beforedeactivate: testChange,
 
                        click: function( e ) {
-                               var elem = e.target, type = elem.type;
+                               var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
 
-                               if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
-                                       return testChange.call( this, e );
+                               if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) {
+                                       testChange.call( this, e );
                                }
                        },
 
                        // Change has to be called before submit
                        // Keydown will be called before keypress, which is used in submit-event delegation
                        keydown: function( e ) {
-                               var elem = e.target, type = elem.type;
+                               var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
 
-                               if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
+                               if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) ||
                                        (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
                                        type === "select-multiple" ) {
-                                       return testChange.call( this, e );
+                                       testChange.call( this, e );
                                }
                        },
 
@@ -2633,7 +3314,7 @@ if ( !jQuery.support.changeBubbles ) {
                        // information
                        beforeactivate: function( e ) {
                                var elem = e.target;
-                               jQuery.data( elem, "_change_data", getVal(elem) );
+                               jQuery._data( elem, "_change_data", getVal(elem) );
                        }
                },
 
@@ -2663,36 +3344,58 @@ if ( !jQuery.support.changeBubbles ) {
 }
 
 function trigger( type, elem, args ) {
-       args[0].type = type;
-       return jQuery.event.handle.apply( elem, args );
+       // Piggyback on a donor event to simulate a different one.
+       // Fake originalEvent to avoid donor's stopPropagation, but if the
+       // simulated event prevents default then we do the same on the donor.
+       // Don't pass args or remember liveFired; they apply to the donor event.
+       var event = jQuery.extend( {}, args[ 0 ] );
+       event.type = type;
+       event.originalEvent = {};
+       event.liveFired = undefined;
+       jQuery.event.handle.call( elem, event );
+       if ( event.isDefaultPrevented() ) {
+               args[ 0 ].preventDefault();
+       }
 }
 
 // Create "bubbling" focus and blur events
-if ( document.addEventListener ) {
+if ( !jQuery.support.focusinBubbles ) {
        jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+
+               // Attach a single capturing handler while someone wants focusin/focusout
+               var attaches = 0;
+
                jQuery.event.special[ fix ] = {
                        setup: function() {
-                               if ( focusCounts[fix]++ === 0 ) {
+                               if ( attaches++ === 0 ) {
                                        document.addEventListener( orig, handler, true );
                                }
-                       }, 
-                       teardown: function() { 
-                               if ( --focusCounts[fix] === 0 ) {
+                       },
+                       teardown: function() {
+                               if ( --attaches === 0 ) {
                                        document.removeEventListener( orig, handler, true );
                                }
                        }
                };
 
-               function handler( e ) { 
-                       e = jQuery.event.fix( e );
+               function handler( donor ) {
+                       // Donor event is always a native one; fix it and switch its type.
+                       // Let focusin/out handler cancel the donor focus/blur event.
+                       var e = jQuery.event.fix( donor );
                        e.type = fix;
-                       return jQuery.event.trigger( e, null, e.target );
+                       e.originalEvent = {};
+                       jQuery.event.trigger( e, null, e.target );
+                       if ( e.isDefaultPrevented() ) {
+                               donor.preventDefault();
+                       }
                }
        });
 }
 
 jQuery.each(["bind", "one"], function( i, name ) {
        jQuery.fn[ name ] = function( type, data, fn ) {
+               var handler;
+
                // Handle object literals
                if ( typeof type === "object" ) {
                        for ( var key in type ) {
@@ -2700,16 +3403,21 @@ jQuery.each(["bind", "one"], function( i, name ) {
                        }
                        return this;
                }
-               
-               if ( jQuery.isFunction( data ) || data === false ) {
+
+               if ( arguments.length === 2 || data === false ) {
                        fn = data;
                        data = undefined;
                }
 
-               var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
-                       jQuery( this ).unbind( event, handler );
-                       return fn.apply( this, arguments );
-               }) : fn;
+               if ( name === "one" ) {
+                       handler = function( event ) {
+                               jQuery( this ).unbind( event, handler );
+                               return fn.apply( this, arguments );
+                       };
+                       handler.guid = fn.guid || jQuery.guid++;
+               } else {
+                       handler = fn;
+               }
 
                if ( type === "unload" && name !== "one" ) {
                        this.one( type, data, fn );
@@ -2740,20 +3448,20 @@ jQuery.fn.extend({
 
                return this;
        },
-       
+
        delegate: function( selector, types, data, fn ) {
                return this.live( types, data, fn, selector );
        },
-       
+
        undelegate: function( selector, types, fn ) {
                if ( arguments.length === 0 ) {
-                               return this.unbind( "live" );
-               
+                       return this.unbind( "live" );
+
                } else {
                        return this.die( types, null, fn, selector );
                }
        },
-       
+
        trigger: function( type, data ) {
                return this.each(function() {
                        jQuery.event.trigger( type, data, this );
@@ -2762,35 +3470,34 @@ jQuery.fn.extend({
 
        triggerHandler: function( type, data ) {
                if ( this[0] ) {
-                       var event = jQuery.Event( type );
-                       event.preventDefault();
-                       event.stopPropagation();
-                       jQuery.event.trigger( event, data, this[0] );
-                       return event.result;
+                       return jQuery.event.trigger( type, data, this[0], true );
                }
        },
 
        toggle: function( fn ) {
                // Save reference to arguments for access in closure
                var args = arguments,
-                       i = 1;
+                       guid = fn.guid || jQuery.guid++,
+                       i = 0,
+                       toggler = function( event ) {
+                               // Figure out which function to execute
+                               var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
+                               jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
+
+                               // Make sure that clicks stop
+                               event.preventDefault();
+
+                               // and execute the function
+                               return args[ lastToggle ].apply( this, arguments ) || false;
+                       };
 
                // link all the functions, so any of them can unbind this click handler
+               toggler.guid = guid;
                while ( i < args.length ) {
-                       jQuery.proxy( fn, args[ i++ ] );
+                       args[ i++ ].guid = guid;
                }
 
-               return this.click( jQuery.proxy( fn, function( event ) {
-                       // Figure out which function to execute
-                       var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
-                       jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
-
-                       // Make sure that clicks stop
-                       event.preventDefault();
-
-                       // and execute the function
-                       return args[ lastToggle ].apply( this, arguments ) || false;
-               }));
+               return this.click( toggler );
        },
 
        hover: function( fnOver, fnOut ) {
@@ -2810,17 +3517,25 @@ jQuery.each(["live", "die"], function( i, name ) {
                var type, i = 0, match, namespaces, preType,
                        selector = origSelector || this.selector,
                        context = origSelector ? this : jQuery( this.context );
-               
+
                if ( typeof types === "object" && !types.preventDefault ) {
                        for ( var key in types ) {
                                context[ name ]( key, data, types[key], selector );
                        }
-                       
+
                        return this;
                }
 
-               if ( jQuery.isFunction( data ) ) {
-                       fn = data;
+               if ( name === "die" && !types &&
+                                       origSelector && origSelector.charAt(0) === "." ) {
+
+                       context.unbind( origSelector );
+
+                       return this;
+               }
+
+               if ( data === false || jQuery.isFunction( data ) ) {
+                       fn = data || returnFalse;
                        data = undefined;
                }
 
@@ -2842,7 +3557,7 @@ jQuery.each(["live", "die"], function( i, name ) {
 
                        preType = type;
 
-                       if ( type === "focus" || type === "blur" ) {
+                       if ( liveMap[ type ] ) {
                                types.push( liveMap[ type ] + namespaces );
                                type = type + namespaces;
 
@@ -2862,7 +3577,7 @@ jQuery.each(["live", "die"], function( i, name ) {
                                context.unbind( "live." + liveConvert( type, selector ), fn );
                        }
                }
-               
+
                return this;
        };
 });
@@ -2871,17 +3586,13 @@ function liveHandler( event ) {
        var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
                elems = [],
                selectors = [],
-               events = jQuery.data( this, this.nodeType ? "events" : "__events__" );
+               events = jQuery._data( this, "events" );
 
-       if ( typeof events === "function" ) {
-               events = events.events;
-       }
-
-       // Make sure we avoid non-left-click bubbling in Firefox (#3861)
-       if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
+       // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911)
+       if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) {
                return;
        }
-       
+
        if ( event.namespace ) {
                namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
        }
@@ -2909,7 +3620,7 @@ function liveHandler( event ) {
                for ( j = 0; j < live.length; j++ ) {
                        handleObj = live[j];
 
-                       if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) ) {
+                       if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) {
                                elem = close.elem;
                                related = null;
 
@@ -2917,6 +3628,11 @@ function liveHandler( event ) {
                                if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
                                        event.type = handleObj.preType;
                                        related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
+
+                                       // Make sure not to accidentally match a child element with the same selector
+                                       if ( related && jQuery.contains( elem, related ) ) {
+                                               related = elem;
+                                       }
                                }
 
                                if ( !related || related !== elem ) {
@@ -2955,7 +3671,7 @@ function liveHandler( event ) {
 }
 
 function liveConvert( type, selector ) {
-       return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspace, "&");
+       return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&");
 }
 
 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
@@ -2979,27 +3695,11 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl
        }
 });
 
-// Prevent memory leaks in IE
-// Window isn't included so as not to unbind existing unload events
-// More info:
-//  - http://isaacschlueter.com/2006/10/msie-memory-leaks/
-if ( window.attachEvent && !window.addEventListener ) {
-       jQuery(window).bind("unload", function() {
-               for ( var id in jQuery.cache ) {
-                       if ( jQuery.cache[ id ].handle ) {
-                               // Try/Catch is to handle iframes being unloaded, see #4280
-                               try {
-                                       jQuery.event.remove( jQuery.cache[ id ].handle.elem );
-                               } catch(e) {}
-                       }
-               }
-       });
-}
 
 
 /*!
- * Sizzle CSS Selector Engine - v1.0
- *  Copyright 2009, The Dojo Foundation
+ * Sizzle CSS Selector Engine
+ *  Copyright 2011, The Dojo Foundation
  *  Released under the MIT, BSD, and GPL Licenses.
  *  More information: http://sizzlejs.com/
  */
@@ -3009,7 +3709,9 @@ var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[
        done = 0,
        toString = Object.prototype.toString,
        hasDuplicate = false,
-       baseHasDuplicate = true;
+       baseHasDuplicate = true,
+       rBackslash = /\\/g,
+       rNonWord = /\W/;
 
 // Here we check if the JavaScript engine is using some sort of
 // optimization where it does not always call our comparision
@@ -3208,7 +3910,7 @@ Sizzle.find = function( expr, context, isXML ) {
                        match.splice( 1, 1 );
 
                        if ( left.substr( left.length - 1 ) !== "\\" ) {
-                               match[1] = (match[1] || "").replace(/\\/g, "");
+                               match[1] = (match[1] || "").replace( rBackslash, "" );
                                set = Expr.find[ type ]( match, context, isXML );
 
                                if ( set != null ) {
@@ -3220,7 +3922,9 @@ Sizzle.find = function( expr, context, isXML ) {
        }
 
        if ( !set ) {
-               set = context.getElementsByTagName( "*" );
+               set = typeof context.getElementsByTagName !== "undefined" ?
+                       context.getElementsByTagName( "*" ) :
+                       [];
        }
 
        return { set: set, expr: expr };
@@ -3328,9 +4032,9 @@ var Expr = Sizzle.selectors = {
                ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
                CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
                NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
-               ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
+               ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
                TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
-               CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/,
+               CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
                POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
                PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
        },
@@ -3345,13 +4049,16 @@ var Expr = Sizzle.selectors = {
        attrHandle: {
                href: function( elem ) {
                        return elem.getAttribute( "href" );
+               },
+               type: function( elem ) {
+                       return elem.getAttribute( "type" );
                }
        },
 
        relative: {
                "+": function(checkSet, part){
                        var isPartStr = typeof part === "string",
-                               isTag = isPartStr && !/\W/.test( part ),
+                               isTag = isPartStr && !rNonWord.test( part ),
                                isPartStrNotTag = isPartStr && !isTag;
 
                        if ( isTag ) {
@@ -3379,7 +4086,7 @@ var Expr = Sizzle.selectors = {
                                i = 0,
                                l = checkSet.length;
 
-                       if ( isPartStr && !/\W/.test( part ) ) {
+                       if ( isPartStr && !rNonWord.test( part ) ) {
                                part = part.toLowerCase();
 
                                for ( ; i < l; i++ ) {
@@ -3413,7 +4120,7 @@ var Expr = Sizzle.selectors = {
                                doneName = done++,
                                checkFn = dirCheck;
 
-                       if ( typeof part === "string" && !/\W/.test(part) ) {
+                       if ( typeof part === "string" && !rNonWord.test( part ) ) {
                                part = part.toLowerCase();
                                nodeCheck = part;
                                checkFn = dirNodeCheck;
@@ -3427,7 +4134,7 @@ var Expr = Sizzle.selectors = {
                                doneName = done++,
                                checkFn = dirCheck;
 
-                       if ( typeof part === "string" && !/\W/.test( part ) ) {
+                       if ( typeof part === "string" && !rNonWord.test( part ) ) {
                                part = part.toLowerCase();
                                nodeCheck = part;
                                checkFn = dirNodeCheck;
@@ -3463,12 +4170,14 @@ var Expr = Sizzle.selectors = {
                },
 
                TAG: function( match, context ) {
-                       return context.getElementsByTagName( match[1] );
+                       if ( typeof context.getElementsByTagName !== "undefined" ) {
+                               return context.getElementsByTagName( match[1] );
+                       }
                }
        },
        preFilter: {
                CLASS: function( match, curLoop, inplace, result, not, isXML ) {
-                       match = " " + match[1].replace(/\\/g, "") + " ";
+                       match = " " + match[1].replace( rBackslash, "" ) + " ";
 
                        if ( isXML ) {
                                return match;
@@ -3476,7 +4185,7 @@ var Expr = Sizzle.selectors = {
 
                        for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
                                if ( elem ) {
-                                       if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
+                                       if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
                                                if ( !inplace ) {
                                                        result.push( elem );
                                                }
@@ -3491,17 +4200,23 @@ var Expr = Sizzle.selectors = {
                },
 
                ID: function( match ) {
-                       return match[1].replace(/\\/g, "");
+                       return match[1].replace( rBackslash, "" );
                },
 
                TAG: function( match, curLoop ) {
-                       return match[1].toLowerCase();
+                       return match[1].replace( rBackslash, "" ).toLowerCase();
                },
 
                CHILD: function( match ) {
                        if ( match[1] === "nth" ) {
+                               if ( !match[2] ) {
+                                       Sizzle.error( match[0] );
+                               }
+
+                               match[2] = match[2].replace(/^\+|\s*/g, '');
+
                                // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
-                               var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
+                               var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
                                        match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
                                        !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
 
@@ -3509,6 +4224,9 @@ var Expr = Sizzle.selectors = {
                                match[2] = (test[1] + (test[2] || 1)) - 0;
                                match[3] = test[3] - 0;
                        }
+                       else if ( match[2] ) {
+                               Sizzle.error( match[0] );
+                       }
 
                        // TODO: Move to normal caching system
                        match[0] = done++;
@@ -3517,12 +4235,15 @@ var Expr = Sizzle.selectors = {
                },
 
                ATTR: function( match, curLoop, inplace, result, not, isXML ) {
-                       var name = match[1].replace(/\\/g, "");
+                       var name = match[1] = match[1].replace( rBackslash, "" );
                        
                        if ( !isXML && Expr.attrMap[name] ) {
                                match[1] = Expr.attrMap[name];
                        }
 
+                       // Handle if an un-quoted value was used
+                       match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
+
                        if ( match[2] === "~=" ) {
                                match[4] = " " + match[4] + " ";
                        }
@@ -3576,7 +4297,9 @@ var Expr = Sizzle.selectors = {
                selected: function( elem ) {
                        // Accessing this property makes selected-by-default
                        // options in Safari work properly
-                       elem.parentNode.selectedIndex;
+                       if ( elem.parentNode ) {
+                               elem.parentNode.selectedIndex;
+                       }
                        
                        return elem.selected === true;
                },
@@ -3598,41 +4321,53 @@ var Expr = Sizzle.selectors = {
                },
 
                text: function( elem ) {
-                       return "text" === elem.type;
+                       var attr = elem.getAttribute( "type" ), type = elem.type;
+                       // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) 
+                       // use getAttribute instead to test this case
+                       return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
                },
+
                radio: function( elem ) {
-                       return "radio" === elem.type;
+                       return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
                },
 
                checkbox: function( elem ) {
-                       return "checkbox" === elem.type;
+                       return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
                },
 
                file: function( elem ) {
-                       return "file" === elem.type;
+                       return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
                },
+
                password: function( elem ) {
-                       return "password" === elem.type;
+                       return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
                },
 
                submit: function( elem ) {
-                       return "submit" === elem.type;
+                       var name = elem.nodeName.toLowerCase();
+                       return (name === "input" || name === "button") && "submit" === elem.type;
                },
 
                image: function( elem ) {
-                       return "image" === elem.type;
+                       return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
                },
 
                reset: function( elem ) {
-                       return "reset" === elem.type;
+                       var name = elem.nodeName.toLowerCase();
+                       return (name === "input" || name === "button") && "reset" === elem.type;
                },
 
                button: function( elem ) {
-                       return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
+                       var name = elem.nodeName.toLowerCase();
+                       return name === "input" && "button" === elem.type || name === "button";
                },
 
                input: function( elem ) {
                        return (/input|select|textarea|button/i).test( elem.nodeName );
+               },
+
+               focus: function( elem ) {
+                       return elem === elem.ownerDocument.activeElement;
                }
        },
        setFilters: {
@@ -3691,7 +4426,7 @@ var Expr = Sizzle.selectors = {
                                return true;
 
                        } else {
-                               Sizzle.error( "Syntax error, unrecognized expression: " + name );
+                               Sizzle.error( name );
                        }
                },
 
@@ -3885,6 +4620,16 @@ if ( document.documentElement.compareDocumentPosition ) {
 
 } else {
        sortOrder = function( a, b ) {
+               // The nodes are identical, we can exit early
+               if ( a === b ) {
+                       hasDuplicate = true;
+                       return 0;
+
+               // Fallback to using sourceIndex (in IE) if it's available on both nodes
+               } else if ( a.sourceIndex && b.sourceIndex ) {
+                       return a.sourceIndex - b.sourceIndex;
+               }
+
                var al, bl,
                        ap = [],
                        bp = [],
@@ -3892,13 +4637,8 @@ if ( document.documentElement.compareDocumentPosition ) {
                        bup = b.parentNode,
                        cur = aup;
 
-               // The nodes are identical, we can exit early
-               if ( a === b ) {
-                       hasDuplicate = true;
-                       return 0;
-
                // If the nodes are siblings (or identical) we can do a quick check
-               } else if ( aup === bup ) {
+               if ( aup === bup ) {
                        return siblingCheck( a, b );
 
                // If no parents were found then the nodes are disconnected
@@ -4081,13 +4821,47 @@ if ( document.querySelectorAll ) {
                Sizzle = function( query, context, extra, seed ) {
                        context = context || document;
 
-                       // Make sure that attribute selectors are quoted
-                       query = query.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
-
                        // Only use querySelectorAll on non-XML documents
                        // (ID selectors don't work in non-HTML documents)
                        if ( !seed && !Sizzle.isXML(context) ) {
+                               // See if we find a selector to speed up
+                               var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
+                               
+                               if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
+                                       // Speed-up: Sizzle("TAG")
+                                       if ( match[1] ) {
+                                               return makeArray( context.getElementsByTagName( query ), extra );
+                                       
+                                       // Speed-up: Sizzle(".CLASS")
+                                       } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
+                                               return makeArray( context.getElementsByClassName( match[2] ), extra );
+                                       }
+                               }
+                               
                                if ( context.nodeType === 9 ) {
+                                       // Speed-up: Sizzle("body")
+                                       // The body element only exists once, optimize finding it
+                                       if ( query === "body" && context.body ) {
+                                               return makeArray( [ context.body ], extra );
+                                               
+                                       // Speed-up: Sizzle("#ID")
+                                       } else if ( match && match[3] ) {
+                                               var elem = context.getElementById( match[3] );
+
+                                               // Check parentNode to catch when Blackberry 4.6 returns
+                                               // nodes that are no longer in the document #6963
+                                               if ( elem && elem.parentNode ) {
+                                                       // Handle the case where IE and Opera return items
+                                                       // by name instead of ID
+                                                       if ( elem.id === match[3] ) {
+                                                               return makeArray( [ elem ], extra );
+                                                       }
+                                                       
+                                               } else {
+                                                       return makeArray( [], extra );
+                                               }
+                                       }
+                                       
                                        try {
                                                return makeArray( context.querySelectorAll(query), extra );
                                        } catch(qsaError) {}
@@ -4097,20 +4871,30 @@ if ( document.querySelectorAll ) {
                                // and working up from there (Thanks to Andrew Dupont for the technique)
                                // IE 8 doesn't work on object elements
                                } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
-                                       var old = context.getAttribute( "id" ),
-                                               nid = old || id;
+                                       var oldContext = context,
+                                               old = context.getAttribute( "id" ),
+                                               nid = old || id,
+                                               hasParent = context.parentNode,
+                                               relativeHierarchySelector = /^\s*[+~]/.test( query );
 
                                        if ( !old ) {
                                                context.setAttribute( "id", nid );
+                                       } else {
+                                               nid = nid.replace( /'/g, "\\$&" );
+                                       }
+                                       if ( relativeHierarchySelector && hasParent ) {
+                                               context = context.parentNode;
                                        }
 
                                        try {
-                                               return makeArray( context.querySelectorAll( "#" + nid + " " + query ), extra );
+                                               if ( !relativeHierarchySelector || hasParent ) {
+                                                       return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
+                                               }
 
                                        } catch(pseudoError) {
                                        } finally {
                                                if ( !old ) {
-                                                       context.removeAttribute( "id" );
+                                                       oldContext.removeAttribute( "id" );
                                                }
                                        }
                                }
@@ -4130,19 +4914,23 @@ if ( document.querySelectorAll ) {
 
 (function(){
        var html = document.documentElement,
-               matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector,
-               pseudoWorks = false;
+               matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
 
-       try {
-               // This should fail with an exception
-               // Gecko does not error, returns false instead
-               matches.call( document.documentElement, "[test!='']:sizzle" );
+       if ( matches ) {
+               // Check to see if it's possible to do matchesSelector
+               // on a disconnected node (IE 9 fails this)
+               var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
+                       pseudoWorks = false;
+
+               try {
+                       // This should fail with an exception
+                       // Gecko does not error, returns false instead
+                       matches.call( document.documentElement, "[test!='']:sizzle" );
        
-       } catch( pseudoError ) {
-               pseudoWorks = true;
-       }
+               } catch( pseudoError ) {
+                       pseudoWorks = true;
+               }
 
-       if ( matches ) {
                Sizzle.matchesSelector = function( node, expr ) {
                        // Make sure that attribute selectors are quoted
                        expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
@@ -4150,7 +4938,15 @@ if ( document.querySelectorAll ) {
                        if ( !Sizzle.isXML( node ) ) {
                                try { 
                                        if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
-                                               return matches.call( node, expr );
+                                               var ret = matches.call( node, expr );
+
+                                               // IE 9's matchesSelector returns false on disconnected nodes
+                                               if ( ret || !disconnectedMatch ||
+                                                               // As well, disconnected nodes are said to be in a document
+                                                               // fragment in IE 9, so check for that
+                                                               node.document && node.document.nodeType !== 11 ) {
+                                                       return ret;
+                                               }
                                        }
                                } catch(e) {}
                        }
@@ -4328,21 +5124,41 @@ var runtil = /Until$/,
        rmultiselector = /,/,
        isSimple = /^.[^:#\[\.,]*$/,
        slice = Array.prototype.slice,
-       POS = jQuery.expr.match.POS;
+       POS = jQuery.expr.match.POS,
+       // methods guaranteed to produce a unique set when starting from a unique set
+       guaranteedUnique = {
+               children: true,
+               contents: true,
+               next: true,
+               prev: true
+       };
 
 jQuery.fn.extend({
        find: function( selector ) {
+               var self = this,
+                       i, l;
+
+               if ( typeof selector !== "string" ) {
+                       return jQuery( selector ).filter(function() {
+                               for ( i = 0, l = self.length; i < l; i++ ) {
+                                       if ( jQuery.contains( self[ i ], this ) ) {
+                                               return true;
+                                       }
+                               }
+                       });
+               }
+
                var ret = this.pushStack( "", "find", selector ),
-                       length = 0;
+                       length, n, r;
 
-               for ( var i = 0, l = this.length; i < l; i++ ) {
+               for ( i = 0, l = this.length; i < l; i++ ) {
                        length = ret.length;
                        jQuery.find( selector, this[i], ret );
 
                        if ( i > 0 ) {
                                // Make sure that the results are unique
-                               for ( var n = length; n < ret.length; n++ ) {
-                                       for ( var r = 0; r < length; r++ ) {
+                               for ( n = length; n < ret.length; n++ ) {
+                                       for ( r = 0; r < length; r++ ) {
                                                if ( ret[r] === ret[n] ) {
                                                        ret.splice(n--, 1);
                                                        break;
@@ -4373,14 +5189,17 @@ jQuery.fn.extend({
        filter: function( selector ) {
                return this.pushStack( winnow(this, selector, true), "filter", selector );
        },
-       
+
        is: function( selector ) {
-               return !!selector && jQuery.filter( selector, this ).length > 0;
+               return !!selector && ( typeof selector === "string" ?
+                       jQuery.filter( selector, this ).length > 0 :
+                       this.filter( selector ).length > 0 );
        },
 
        closest: function( selectors, context ) {
                var ret = [], i, l, cur = this[0];
-
+               
+               // Array
                if ( jQuery.isArray( selectors ) ) {
                        var match, selector,
                                matches = {},
@@ -4390,8 +5209,8 @@ jQuery.fn.extend({
                                for ( i = 0, l = selectors.length; i < l; i++ ) {
                                        selector = selectors[i];
 
-                                       if ( !matches[selector] ) {
-                                               matches[selector] = jQuery.expr.match.POS.test( selector ) ? 
+                                       if ( !matches[ selector ] ) {
+                                               matches[ selector ] = POS.test( selector ) ?
                                                        jQuery( selector, context || this.context ) :
                                                        selector;
                                        }
@@ -4399,9 +5218,9 @@ jQuery.fn.extend({
 
                                while ( cur && cur.ownerDocument && cur !== context ) {
                                        for ( selector in matches ) {
-                                               match = matches[selector];
+                                               match = matches[ selector ];
 
-                                               if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
+                                               if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) {
                                                        ret.push({ selector: selector, elem: cur, level: level });
                                                }
                                        }
@@ -4414,8 +5233,10 @@ jQuery.fn.extend({
                        return ret;
                }
 
-               var pos = POS.test( selectors ) ? 
-                       jQuery( selectors, context || this.context ) : null;
+               // String
+               var pos = POS.test( selectors ) || typeof selectors !== "string" ?
+                               jQuery( selectors, context || this.context ) :
+                               0;
 
                for ( i = 0, l = this.length; i < l; i++ ) {
                        cur = this[i];
@@ -4427,18 +5248,18 @@ jQuery.fn.extend({
 
                                } else {
                                        cur = cur.parentNode;
-                                       if ( !cur || !cur.ownerDocument || cur === context ) {
+                                       if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
                                                break;
                                        }
                                }
                        }
                }
 
-               ret = ret.length > 1 ? jQuery.unique(ret) : ret;
-               
+               ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
+
                return this.pushStack( ret, "closest", selectors );
        },
-       
+
        // Determine the position of an element within
        // the matched set of elements
        index: function( elem ) {
@@ -4456,8 +5277,8 @@ jQuery.fn.extend({
 
        add: function( selector, context ) {
                var set = typeof selector === "string" ?
-                               jQuery( selector, context || this.context ) :
-                               jQuery.makeArray( selector ),
+                               jQuery( selector, context ) :
+                               jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
                        all = jQuery.merge( this.get(), set );
 
                return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
@@ -4518,8 +5339,13 @@ jQuery.each({
        }
 }, function( name, fn ) {
        jQuery.fn[ name ] = function( until, selector ) {
-               var ret = jQuery.map( this, fn, until );
-               
+               var ret = jQuery.map( this, fn, until ),
+                       // The variable 'args' was introduced in
+                       // https://github.com/jquery/jquery/commit/52a0238
+                       // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed.
+                       // http://code.google.com/p/v8/issues/detail?id=1050
+                       args = slice.call(arguments);
+
                if ( !runtil.test( name ) ) {
                        selector = until;
                }
@@ -4528,13 +5354,13 @@ jQuery.each({
                        ret = jQuery.filter( selector, ret );
                }
 
-               ret = this.length > 1 ? jQuery.unique( ret ) : ret;
+               ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
 
                if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
                        ret = ret.reverse();
                }
 
-               return this.pushStack( ret, name, slice.call(arguments).join(",") );
+               return this.pushStack( ret, name, args.join(",") );
        };
 });
 
@@ -4548,7 +5374,7 @@ jQuery.extend({
                        jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
                        jQuery.find.matches(expr, elems);
        },
-       
+
        dir: function( elem, dir, until ) {
                var matched = [],
                        cur = elem[ dir ];
@@ -4590,6 +5416,11 @@ jQuery.extend({
 
 // Implement the identical functionality for filter and not
 function winnow( elements, qualifier, keep ) {
+
+       // Can't pass null or undefined to indexOf in Firefox 4
+       // Set to 0 to skip string check
+       qualifier = qualifier || 0;
+
        if ( jQuery.isFunction( qualifier ) ) {
                return jQuery.grep(elements, function( elem, i ) {
                        var retVal = !!qualifier.call( elem, i, elem );
@@ -4628,9 +5459,10 @@ var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
        rtbody = /<tbody/i,
        rhtml = /<|&#?\w+;/,
        rnocache = /<(?:script|object|embed|option|style)/i,
-       // checked="checked" or checked (html5)
+       // checked="checked" or checked
        rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
-       raction = /\=([^="'>\s]+\/)>/g,
+       rscriptType = /\/(java|ecma)script/i,
+       rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/,
        wrapMap = {
                option: [ 1, "<select multiple='multiple'>", "</select>" ],
                legend: [ 1, "<fieldset>", "</fieldset>" ],
@@ -4691,7 +5523,7 @@ jQuery.fn.extend({
                                }
 
                                return elem;
-                       }).append(this);
+                       }).append( this );
                }
 
                return this;
@@ -4770,7 +5602,7 @@ jQuery.fn.extend({
                        return set;
                }
        },
-       
+
        // keepData is for internal use only--do not document
        remove: function( selector, keepData ) {
                for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
@@ -4781,11 +5613,11 @@ jQuery.fn.extend({
                                }
 
                                if ( elem.parentNode ) {
-                                        elem.parentNode.removeChild( elem );
+                                       elem.parentNode.removeChild( elem );
                                }
                        }
                }
-               
+
                return this;
        },
 
@@ -4801,48 +5633,17 @@ jQuery.fn.extend({
                                elem.removeChild( elem.firstChild );
                        }
                }
-               
+
                return this;
        },
 
-       clone: function( events ) {
-               // Do the clone
-               var ret = this.map(function() {
-                       if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
-                               // IE copies events bound via attachEvent when
-                               // using cloneNode. Calling detachEvent on the
-                               // clone will also remove the events from the orignal
-                               // In order to get around this, we use innerHTML.
-                               // Unfortunately, this means some modifications to
-                               // attributes in IE that are actually only stored
-                               // as properties will not be copied (such as the
-                               // the name attribute on an input).
-                               var html = this.outerHTML,
-                                       ownerDocument = this.ownerDocument;
-
-                               if ( !html ) {
-                                       var div = ownerDocument.createElement("div");
-                                       div.appendChild( this.cloneNode(true) );
-                                       html = div.innerHTML;
-                               }
-
-                               return jQuery.clean([html.replace(rinlinejQuery, "")
-                                       // Handle the case in IE 8 where action=/test/> self-closes a tag
-                                       .replace(raction, '="$1">')
-                                       .replace(rleadingWhitespace, "")], ownerDocument)[0];
-                       } else {
-                               return this.cloneNode(true);
-                       }
-               });
+       clone: function( dataAndEvents, deepDataAndEvents ) {
+               dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
+               deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
 
-               // Copy the events from the original to the clone
-               if ( events === true ) {
-                       cloneCopyEvent( this, ret );
-                       cloneCopyEvent( this.find("*"), ret.find("*") );
-               }
-
-               // Return the cloned set
-               return ret;
+               return this.map( function () {
+                       return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
+               });
        },
 
        html: function( value ) {
@@ -4914,7 +5715,9 @@ jQuery.fn.extend({
                                }
                        });
                } else {
-                       return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value );
+                       return this.length ?
+                               this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
+                               this;
                }
        },
 
@@ -4952,9 +5755,9 @@ jQuery.fn.extend({
                        } else {
                                results = jQuery.buildFragment( args, this, scripts );
                        }
-                       
+
                        fragment = results.fragment;
-                       
+
                        if ( fragment.childNodes.length === 1 ) {
                                first = fragment = fragment.firstChild;
                        } else {
@@ -4964,13 +5767,20 @@ jQuery.fn.extend({
                        if ( first ) {
                                table = table && jQuery.nodeName( first, "tr" );
 
-                               for ( var i = 0, l = this.length; i < l; i++ ) {
+                               for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {
                                        callback.call(
                                                table ?
                                                        root(this[i], first) :
                                                        this[i],
-                                               i > 0 || results.cacheable || this.length > 1  ?
-                                                       fragment.cloneNode(true) :
+                                               // Make sure that we do not leak memory by inadvertently discarding
+                                               // the original fragment (which might have attached data) instead of
+                                               // using it; in addition, use the original fragment object for the last
+                                               // item instead of first because it can end up being emptied incorrectly
+                                               // in certain situations (Bug #8070).
+                                               // Fragments from the fragment cache must always be cloned and never used
+                                               // in place.
+                                               results.cacheable || (l > 1 && i < lastIndex) ?
+                                                       jQuery.clone( fragment, true, true ) :
                                                        fragment
                                        );
                                }
@@ -4992,48 +5802,109 @@ function root( elem, cur ) {
                elem;
 }
 
-function cloneCopyEvent(orig, ret) {
-       var i = 0;
+function cloneCopyEvent( src, dest ) {
 
-       ret.each(function() {
-               if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) {
-                       return;
-               }
+       if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
+               return;
+       }
 
-               var oldData = jQuery.data( orig[i++] ),
-                       curData = jQuery.data( this, oldData ),
-                       events = oldData && oldData.events;
+       var internalKey = jQuery.expando,
+               oldData = jQuery.data( src ),
+               curData = jQuery.data( dest, oldData );
+
+       // Switch to use the internal data object, if it exists, for the next
+       // stage of data copying
+       if ( (oldData = oldData[ internalKey ]) ) {
+               var events = oldData.events;
+                               curData = curData[ internalKey ] = jQuery.extend({}, oldData);
 
                if ( events ) {
                        delete curData.handle;
                        curData.events = {};
 
                        for ( var type in events ) {
-                               for ( var handler in events[ type ] ) {
-                                       jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
+                               for ( var i = 0, l = events[ type ].length; i < l; i++ ) {
+                                       jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data );
                                }
                        }
                }
-       });
+       }
+}
+
+function cloneFixAttributes( src, dest ) {
+       var nodeName;
+
+       // We do not need to do anything for non-Elements
+       if ( dest.nodeType !== 1 ) {
+               return;
+       }
+
+       // clearAttributes removes the attributes, which we don't want,
+       // but also removes the attachEvent events, which we *do* want
+       if ( dest.clearAttributes ) {
+               dest.clearAttributes();
+       }
+
+       // mergeAttributes, in contrast, only merges back on the
+       // original attributes, not the events
+       if ( dest.mergeAttributes ) {
+               dest.mergeAttributes( src );
+       }
+
+       nodeName = dest.nodeName.toLowerCase();
+
+       // IE6-8 fail to clone children inside object elements that use
+       // the proprietary classid attribute value (rather than the type
+       // attribute) to identify the type of content to display
+       if ( nodeName === "object" ) {
+               dest.outerHTML = src.outerHTML;
+
+       } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
+               // IE6-8 fails to persist the checked state of a cloned checkbox
+               // or radio button. Worse, IE6-7 fail to give the cloned element
+               // a checked appearance if the defaultChecked value isn't also set
+               if ( src.checked ) {
+                       dest.defaultChecked = dest.checked = src.checked;
+               }
+
+               // IE6-7 get confused and end up setting the value of a cloned
+               // checkbox/radio button to an empty string instead of "on"
+               if ( dest.value !== src.value ) {
+                       dest.value = src.value;
+               }
+
+       // IE6-8 fails to return the selected option to the default selected
+       // state when cloning options
+       } else if ( nodeName === "option" ) {
+               dest.selected = src.defaultSelected;
+
+       // IE6-8 fails to set the defaultValue to the correct value when
+       // cloning other types of input fields
+       } else if ( nodeName === "input" || nodeName === "textarea" ) {
+               dest.defaultValue = src.defaultValue;
+       }
+
+       // Event data gets referenced instead of copied if the expando
+       // gets copied too
+       dest.removeAttribute( jQuery.expando );
 }
 
 jQuery.buildFragment = function( args, nodes, scripts ) {
        var fragment, cacheable, cacheresults,
                doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
 
-       // Only cache "small" (1/2 KB) strings that are associated with the main document
+       // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
        // Cloning options loses the selected state, so don't cache them
        // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
        // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
        if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
-               !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
+               args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
 
                cacheable = true;
+
                cacheresults = jQuery.fragments[ args[0] ];
-               if ( cacheresults ) {
-                       if ( cacheresults !== 1 ) {
-                               fragment = cacheresults;
-                       }
+               if ( cacheresults && cacheresults !== 1 ) {
+                       fragment = cacheresults;
                }
        }
 
@@ -5062,25 +5933,101 @@ jQuery.each({
                var ret = [],
                        insert = jQuery( selector ),
                        parent = this.length === 1 && this[0].parentNode;
-               
+
                if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
                        insert[ original ]( this[0] );
                        return this;
-                       
+
                } else {
                        for ( var i = 0, l = insert.length; i < l; i++ ) {
                                var elems = (i > 0 ? this.clone(true) : this).get();
                                jQuery( insert[i] )[ original ]( elems );
                                ret = ret.concat( elems );
                        }
-               
+
                        return this.pushStack( ret, name, insert.selector );
                }
        };
 });
 
+function getAll( elem ) {
+       if ( "getElementsByTagName" in elem ) {
+               return elem.getElementsByTagName( "*" );
+
+       } else if ( "querySelectorAll" in elem ) {
+               return elem.querySelectorAll( "*" );
+
+       } else {
+               return [];
+       }
+}
+
+// Used in clean, fixes the defaultChecked property
+function fixDefaultChecked( elem ) {
+       if ( elem.type === "checkbox" || elem.type === "radio" ) {
+               elem.defaultChecked = elem.checked;
+       }
+}
+// Finds all inputs and passes them to fixDefaultChecked
+function findInputs( elem ) {
+       if ( jQuery.nodeName( elem, "input" ) ) {
+               fixDefaultChecked( elem );
+       } else if ( elem.getElementsByTagName ) {
+               jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
+       }
+}
+
 jQuery.extend({
+       clone: function( elem, dataAndEvents, deepDataAndEvents ) {
+               var clone = elem.cloneNode(true),
+                               srcElements,
+                               destElements,
+                               i;
+
+               if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
+                               (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
+                       // IE copies events bound via attachEvent when using cloneNode.
+                       // Calling detachEvent on the clone will also remove the events
+                       // from the original. In order to get around this, we use some
+                       // proprietary methods to clear the events. Thanks to MooTools
+                       // guys for this hotness.
+
+                       cloneFixAttributes( elem, clone );
+
+                       // Using Sizzle here is crazy slow, so we use getElementsByTagName
+                       // instead
+                       srcElements = getAll( elem );
+                       destElements = getAll( clone );
+
+                       // Weird iteration because IE will replace the length property
+                       // with an element if you are cloning the body and one of the
+                       // elements on the page has a name or id of "length"
+                       for ( i = 0; srcElements[i]; ++i ) {
+                               cloneFixAttributes( srcElements[i], destElements[i] );
+                       }
+               }
+
+               // Copy the events from the original to the clone
+               if ( dataAndEvents ) {
+                       cloneCopyEvent( elem, clone );
+
+                       if ( deepDataAndEvents ) {
+                               srcElements = getAll( elem );
+                               destElements = getAll( clone );
+
+                               for ( i = 0; srcElements[i]; ++i ) {
+                                       cloneCopyEvent( srcElements[i], destElements[i] );
+                               }
+                       }
+               }
+
+               // Return the cloned set
+               return clone;
+       },
+
        clean: function( elems, context, fragment, scripts ) {
+               var checkScriptType;
+
                context = context || document;
 
                // !context.createElement fails in IE with an error but returns typeof 'object'
@@ -5088,7 +6035,7 @@ jQuery.extend({
                        context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
                }
 
-               var ret = [];
+               var ret = [], j;
 
                for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
                        if ( typeof elem === "number" ) {
@@ -5100,54 +6047,67 @@ jQuery.extend({
                        }
 
                        // Convert html string into DOM nodes
-                       if ( typeof elem === "string" && !rhtml.test( elem ) ) {
-                               elem = context.createTextNode( elem );
-
-                       } else if ( typeof elem === "string" ) {
-                               // Fix "XHTML"-style tags in all browsers
-                               elem = elem.replace(rxhtmlTag, "<$1></$2>");
+                       if ( typeof elem === "string" ) {
+                               if ( !rhtml.test( elem ) ) {
+                                       elem = context.createTextNode( elem );
+                               } else {
+                                       // Fix "XHTML"-style tags in all browsers
+                                       elem = elem.replace(rxhtmlTag, "<$1></$2>");
 
-                               // Trim whitespace, otherwise indexOf won't work as expected
-                               var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
-                                       wrap = wrapMap[ tag ] || wrapMap._default,
-                                       depth = wrap[0],
-                                       div = context.createElement("div");
+                                       // Trim whitespace, otherwise indexOf won't work as expected
+                                       var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
+                                               wrap = wrapMap[ tag ] || wrapMap._default,
+                                               depth = wrap[0],
+                                               div = context.createElement("div");
 
-                               // Go to html and back, then peel off extra wrappers
-                               div.innerHTML = wrap[1] + elem + wrap[2];
+                                       // Go to html and back, then peel off extra wrappers
+                                       div.innerHTML = wrap[1] + elem + wrap[2];
 
-                               // Move to the right depth
-                               while ( depth-- ) {
-                                       div = div.lastChild;
-                               }
+                                       // Move to the right depth
+                                       while ( depth-- ) {
+                                               div = div.lastChild;
+                                       }
 
-                               // Remove IE's autoinserted <tbody> from table fragments
-                               if ( !jQuery.support.tbody ) {
+                                       // Remove IE's autoinserted <tbody> from table fragments
+                                       if ( !jQuery.support.tbody ) {
 
-                                       // String was a <table>, *may* have spurious <tbody>
-                                       var hasBody = rtbody.test(elem),
-                                               tbody = tag === "table" && !hasBody ?
-                                                       div.firstChild && div.firstChild.childNodes :
+                                               // String was a <table>, *may* have spurious <tbody>
+                                               var hasBody = rtbody.test(elem),
+                                                       tbody = tag === "table" && !hasBody ?
+                                                               div.firstChild && div.firstChild.childNodes :
 
-                                                       // String was a bare <thead> or <tfoot>
-                                                       wrap[1] === "<table>" && !hasBody ?
-                                                               div.childNodes :
-                                                               [];
+                                                               // String was a bare <thead> or <tfoot>
+                                                               wrap[1] === "<table>" && !hasBody ?
+                                                                       div.childNodes :
+                                                                       [];
 
-                                       for ( var j = tbody.length - 1; j >= 0 ; --j ) {
-                                               if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
-                                                       tbody[ j ].parentNode.removeChild( tbody[ j ] );
+                                               for ( j = tbody.length - 1; j >= 0 ; --j ) {
+                                                       if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
+                                                               tbody[ j ].parentNode.removeChild( tbody[ j ] );
+                                                       }
                                                }
                                        }
 
-                               }
+                                       // IE completely kills leading whitespace when innerHTML is used
+                                       if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
+                                               div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
+                                       }
 
-                               // IE completely kills leading whitespace when innerHTML is used
-                               if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
-                                       div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
+                                       elem = div.childNodes;
                                }
+                       }
 
-                               elem = div.childNodes;
+                       // Resets defaultChecked for any radios and checkboxes
+                       // about to be appended to the DOM in IE 6/7 (#8060)
+                       var len;
+                       if ( !jQuery.support.appendChecked ) {
+                               if ( elem[0] && typeof (len = elem.length) === "number" ) {
+                                       for ( j = 0; j < len; j++ ) {
+                                               findInputs( elem[j] );
+                                       }
+                               } else {
+                                       findInputs( elem );
+                               }
                        }
 
                        if ( elem.nodeType ) {
@@ -5158,13 +6118,18 @@ jQuery.extend({
                }
 
                if ( fragment ) {
+                       checkScriptType = function( elem ) {
+                               return !elem.type || rscriptType.test( elem.type );
+                       };
                        for ( i = 0; ret[i]; i++ ) {
                                if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
                                        scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
-                               
+
                                } else {
                                        if ( ret[i].nodeType === 1 ) {
-                                               ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
+                                               var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType );
+
+                                               ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
                                        }
                                        fragment.appendChild( ret[i] );
                                }
@@ -5173,40 +6138,45 @@ jQuery.extend({
 
                return ret;
        },
-       
+
        cleanData: function( elems ) {
-               var data, id, cache = jQuery.cache,
-                       special = jQuery.event.special,
+               var data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special,
                        deleteExpando = jQuery.support.deleteExpando;
-               
+
                for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
                        if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
                                continue;
                        }
 
                        id = elem[ jQuery.expando ];
-                       
+
                        if ( id ) {
-                               data = cache[ id ];
-                               
+                               data = cache[ id ] && cache[ id ][ internalKey ];
+
                                if ( data && data.events ) {
                                        for ( var type in data.events ) {
                                                if ( special[ type ] ) {
                                                        jQuery.event.remove( elem, type );
 
+                                               // This is a shortcut to avoid jQuery.event.remove's overhead
                                                } else {
                                                        jQuery.removeEvent( elem, type, data.handle );
                                                }
                                        }
+
+                                       // Null the DOM reference to avoid IE6/7/8 leak (#7054)
+                                       if ( data.handle ) {
+                                               data.handle.elem = null;
+                                       }
                                }
-                               
+
                                if ( deleteExpando ) {
                                        delete elem[ jQuery.expando ];
 
                                } else if ( elem.removeAttribute ) {
                                        elem.removeAttribute( jQuery.expando );
                                }
-                               
+
                                delete cache[ id ];
                        }
                }
@@ -5221,7 +6191,7 @@ function evalScript( i, elem ) {
                        dataType: "script"
                });
        } else {
-               jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+               jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) );
        }
 
        if ( elem.parentNode ) {
@@ -5235,9 +6205,12 @@ function evalScript( i, elem ) {
 var ralpha = /alpha\([^)]*\)/i,
        ropacity = /opacity=([^)]*)/,
        rdashAlpha = /-([a-z])/ig,
-       rupper = /([A-Z])/g,
+       // fixed for IE9, see #8346
+       rupper = /([A-Z]|^ms)/g,
        rnumpx = /^-?\d+(?:px)?$/i,
        rnum = /^-?\d/,
+       rrelNum = /^[+\-]=/,
+       rrelNumFilter = /[^+\-\.\de]+/g,
 
        cssShow = { position: "absolute", visibility: "hidden", display: "block" },
        cssWidth = [ "Left", "Right" ],
@@ -5288,7 +6261,9 @@ jQuery.extend({
                "fontWeight": true,
                "opacity": true,
                "zoom": true,
-               "lineHeight": true
+               "lineHeight": true,
+               "widows": true,
+               "orphans": true
        },
 
        // Add in properties whose names you wish to fix before
@@ -5306,20 +6281,27 @@ jQuery.extend({
                }
 
                // Make sure that we're working with the right name
-               var ret, origName = jQuery.camelCase( name ),
+               var ret, type, origName = jQuery.camelCase( name ),
                        style = elem.style, hooks = jQuery.cssHooks[ origName ];
 
                name = jQuery.cssProps[ origName ] || origName;
 
                // Check if we're setting a value
                if ( value !== undefined ) {
+                       type = typeof value;
+
                        // Make sure that NaN and null values aren't set. See: #7116
-                       if ( typeof value === "number" && isNaN( value ) || value == null ) {
+                       if ( type === "number" && isNaN( value ) || value == null ) {
                                return;
                        }
 
+                       // convert relative number strings (+= or -=) to relative numbers. #7345
+                       if ( type === "string" && rrelNum.test( value ) ) {
+                               value = +value.replace( rrelNumFilter, "" ) + parseFloat( jQuery.css( elem, name ) );
+                       }
+
                        // If a number was passed in, add 'px' to the (except for certain CSS properties)
-                       if ( typeof value === "number" && !jQuery.cssNumber[ origName ] ) {
+                       if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
                                value += "px";
                        }
 
@@ -5344,11 +6326,17 @@ jQuery.extend({
        },
 
        css: function( elem, name, extra ) {
+               var ret, hooks;
+
                // Make sure that we're working with the right name
-               var ret, origName = jQuery.camelCase( name ),
-                       hooks = jQuery.cssHooks[ origName ];
+               name = jQuery.camelCase( name );
+               hooks = jQuery.cssHooks[ name ];
+               name = jQuery.cssProps[ name ] || name;
 
-               name = jQuery.cssProps[ origName ] || origName;
+               // cssFloat needs a special treatment
+               if ( name === "cssFloat" ) {
+                       name = "float";
+               }
 
                // If a hook was provided get the computed value from there
                if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
@@ -5356,7 +6344,7 @@ jQuery.extend({
 
                // Otherwise, if a way to get the computed value exists, use that
                } else if ( curCSS ) {
-                       return curCSS( elem, name, origName );
+                       return curCSS( elem, name );
                }
        },
 
@@ -5447,33 +6435,56 @@ if ( !jQuery.support.opacity ) {
        jQuery.cssHooks.opacity = {
                get: function( elem, computed ) {
                        // IE uses filters for opacity
-                       return ropacity.test((computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "") ?
-                               (parseFloat(RegExp.$1) / 100) + "" :
+                       return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
+                               ( parseFloat( RegExp.$1 ) / 100 ) + "" :
                                computed ? "1" : "";
                },
 
                set: function( elem, value ) {
-                       var style = elem.style;
+                       var style = elem.style,
+                               currentStyle = elem.currentStyle;
 
                        // IE has trouble with opacity if it does not have layout
                        // Force it by setting the zoom level
                        style.zoom = 1;
 
                        // Set the alpha filter to set the opacity
-                       var opacity = jQuery.isNaN(value) ?
+                       var opacity = jQuery.isNaN( value ) ?
                                "" :
                                "alpha(opacity=" + value * 100 + ")",
-                               filter = style.filter || "";
+                               filter = currentStyle && currentStyle.filter || style.filter || "";
 
-                       style.filter = ralpha.test(filter) ?
-                               filter.replace(ralpha, opacity) :
-                               style.filter + ' ' + opacity;
+                       style.filter = ralpha.test( filter ) ?
+                               filter.replace( ralpha, opacity ) :
+                               filter + " " + opacity;
                }
        };
 }
 
+jQuery(function() {
+       // This hook cannot be added until DOM ready because the support test
+       // for it is not run until after DOM ready
+       if ( !jQuery.support.reliableMarginRight ) {
+               jQuery.cssHooks.marginRight = {
+                       get: function( elem, computed ) {
+                               // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+                               // Work around by temporarily setting element display to inline-block
+                               var ret;
+                               jQuery.swap( elem, { "display": "inline-block" }, function() {
+                                       if ( computed ) {
+                                               ret = curCSS( elem, "margin-right", "marginRight" );
+                                       } else {
+                                               ret = elem.style.marginRight;
+                                       }
+                               });
+                               return ret;
+                       }
+               };
+       }
+});
+
 if ( document.defaultView && document.defaultView.getComputedStyle ) {
-       getComputedStyle = function( elem, newName, name ) {
+       getComputedStyle = function( elem, name ) {
                var ret, defaultView, computedStyle;
 
                name = name.replace( rupper, "-$1" ).toLowerCase();
@@ -5495,8 +6506,9 @@ if ( document.defaultView && document.defaultView.getComputedStyle ) {
 
 if ( document.documentElement.currentStyle ) {
        currentStyle = function( elem, name ) {
-               var left, rsLeft,
+               var left,
                        ret = elem.currentStyle && elem.currentStyle[ name ],
+                       rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ],
                        style = elem.style;
 
                // From the awesome hack by Dean Edwards
@@ -5507,16 +6519,19 @@ if ( document.documentElement.currentStyle ) {
                if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
                        // Remember the original values
                        left = style.left;
-                       rsLeft = elem.runtimeStyle.left;
 
                        // Put in the new values to get a computed value out
-                       elem.runtimeStyle.left = elem.currentStyle.left;
+                       if ( rsLeft ) {
+                               elem.runtimeStyle.left = elem.currentStyle.left;
+                       }
                        style.left = name === "fontSize" ? "1em" : (ret || 0);
                        ret = style.pixelLeft + "px";
 
                        // Revert the changed values
                        style.left = left;
-                       elem.runtimeStyle.left = rsLeft;
+                       if ( rsLeft ) {
+                               elem.runtimeStyle.left = rsLeft;
+                       }
                }
 
                return ret === "" ? "auto" : ret;
@@ -5565,21 +6580,140 @@ if ( jQuery.expr && jQuery.expr.filters ) {
 
 
 
-var jsc = jQuery.now(),
-       rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
-       rselectTextarea = /^(?:select|textarea)/i,
+var r20 = /%20/g,
+       rbracket = /\[\]$/,
+       rCRLF = /\r?\n/g,
+       rhash = /#.*$/,
+       rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
        rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
+       // #7653, #8125, #8152: local protocol detection
+       rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|widget):$/,
        rnoContent = /^(?:GET|HEAD)$/,
-       rbracket = /\[\]$/,
-       jsre = /\=\?(&|$)/,
+       rprotocol = /^\/\//,
        rquery = /\?/,
+       rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
+       rselectTextarea = /^(?:select|textarea)/i,
+       rspacesAjax = /\s+/,
        rts = /([?&])_=[^&]*/,
-       rurl = /^(\w+:)?\/\/([^\/?#]+)/,
-       r20 = /%20/g,
-       rhash = /#.*$/,
+       rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
 
        // Keep a copy of the old load method
-       _load = jQuery.fn.load;
+       _load = jQuery.fn.load,
+
+       /* Prefilters
+        * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
+        * 2) These are called:
+        *    - BEFORE asking for a transport
+        *    - AFTER param serialization (s.data is a string if s.processData is true)
+        * 3) key is the dataType
+        * 4) the catchall symbol "*" can be used
+        * 5) execution will start with transport dataType and THEN continue down to "*" if needed
+        */
+       prefilters = {},
+
+       /* Transports bindings
+        * 1) key is the dataType
+        * 2) the catchall symbol "*" can be used
+        * 3) selection will start with transport dataType and THEN go to "*" if needed
+        */
+       transports = {},
+
+       // Document location
+       ajaxLocation,
+
+       // Document location segments
+       ajaxLocParts;
+
+// #8138, IE may throw an exception when accessing
+// a field from window.location if document.domain has been set
+try {
+       ajaxLocation = location.href;
+} catch( e ) {
+       // Use the href attribute of an A element
+       // since IE will modify it given document.location
+       ajaxLocation = document.createElement( "a" );
+       ajaxLocation.href = "";
+       ajaxLocation = ajaxLocation.href;
+}
+
+// Segment location into parts
+ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
+
+// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
+function addToPrefiltersOrTransports( structure ) {
+
+       // dataTypeExpression is optional and defaults to "*"
+       return function( dataTypeExpression, func ) {
+
+               if ( typeof dataTypeExpression !== "string" ) {
+                       func = dataTypeExpression;
+                       dataTypeExpression = "*";
+               }
+
+               if ( jQuery.isFunction( func ) ) {
+                       var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),
+                               i = 0,
+                               length = dataTypes.length,
+                               dataType,
+                               list,
+                               placeBefore;
+
+                       // For each dataType in the dataTypeExpression
+                       for(; i < length; i++ ) {
+                               dataType = dataTypes[ i ];
+                               // We control if we're asked to add before
+                               // any existing element
+                               placeBefore = /^\+/.test( dataType );
+                               if ( placeBefore ) {
+                                       dataType = dataType.substr( 1 ) || "*";
+                               }
+                               list = structure[ dataType ] = structure[ dataType ] || [];
+                               // then we add to the structure accordingly
+                               list[ placeBefore ? "unshift" : "push" ]( func );
+                       }
+               }
+       };
+}
+
+// Base inspection function for prefilters and transports
+function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
+               dataType /* internal */, inspected /* internal */ ) {
+
+       dataType = dataType || options.dataTypes[ 0 ];
+       inspected = inspected || {};
+
+       inspected[ dataType ] = true;
+
+       var list = structure[ dataType ],
+               i = 0,
+               length = list ? list.length : 0,
+               executeOnly = ( structure === prefilters ),
+               selection;
+
+       for(; i < length && ( executeOnly || !selection ); i++ ) {
+               selection = list[ i ]( options, originalOptions, jqXHR );
+               // If we got redirected to another dataType
+               // we try there if executing only and not done already
+               if ( typeof selection === "string" ) {
+                       if ( !executeOnly || inspected[ selection ] ) {
+                               selection = undefined;
+                       } else {
+                               options.dataTypes.unshift( selection );
+                               selection = inspectPrefiltersOrTransports(
+                                               structure, options, originalOptions, jqXHR, selection, inspected );
+                       }
+               }
+       }
+       // If we're only executing or nothing was selected
+       // we try the catchall dataType if not done already
+       if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
+               selection = inspectPrefiltersOrTransports(
+                               structure, options, originalOptions, jqXHR, "*", inspected );
+       }
+       // unnecessary when only executing (prefilters)
+       // but it'll be ignored by the caller in that case
+       return selection;
+}
 
 jQuery.fn.extend({
        load: function( url, params, callback ) {
@@ -5591,10 +6725,10 @@ jQuery.fn.extend({
                        return this;
                }
 
-               var off = url.indexOf(" ");
+               var off = url.indexOf( " " );
                if ( off >= 0 ) {
-                       var selector = url.slice(off, url.length);
-                       url = url.slice(0, off);
+                       var selector = url.slice( off, url.length );
+                       url = url.slice( 0, off );
                }
 
                // Default to a GET request
@@ -5606,7 +6740,7 @@ jQuery.fn.extend({
                        if ( jQuery.isFunction( params ) ) {
                                // We assume that it's the callback
                                callback = params;
-                               params = null;
+                               params = undefined;
 
                        // Otherwise, build a param string
                        } else if ( typeof params === "object" ) {
@@ -5623,26 +6757,34 @@ jQuery.fn.extend({
                        type: type,
                        dataType: "html",
                        data: params,
-                       complete: function( res, status ) {
+                       // Complete callback (responseText is used internally)
+                       complete: function( jqXHR, status, responseText ) {
+                               // Store the response as specified by the jqXHR object
+                               responseText = jqXHR.responseText;
                                // If successful, inject the HTML into all the matched elements
-                               if ( status === "success" || status === "notmodified" ) {
+                               if ( jqXHR.isResolved() ) {
+                                       // #4825: Get the actual response in case
+                                       // a dataFilter is present in ajaxSettings
+                                       jqXHR.done(function( r ) {
+                                               responseText = r;
+                                       });
                                        // See if a selector was specified
                                        self.html( selector ?
                                                // Create a dummy div to hold the results
                                                jQuery("<div>")
                                                        // inject the contents of the document in, removing the scripts
                                                        // to avoid any 'Permission Denied' errors in IE
-                                                       .append(res.responseText.replace(rscript, ""))
+                                                       .append(responseText.replace(rscript, ""))
 
                                                        // Locate the specified elements
                                                        .find(selector) :
 
                                                // If not, just inject the full result
-                                               res.responseText );
+                                               responseText );
                                }
 
                                if ( callback ) {
-                                       self.each( callback, [res.responseText, status, res] );
+                                       self.each( callback, [ responseText, status, jqXHR ] );
                                }
                        }
                });
@@ -5651,88 +6793,94 @@ jQuery.fn.extend({
        },
 
        serialize: function() {
-               return jQuery.param(this.serializeArray());
+               return jQuery.param( this.serializeArray() );
        },
 
        serializeArray: function() {
-               return this.map(function() {
-                       return this.elements ? jQuery.makeArray(this.elements) : this;
+               return this.map(function(){
+                       return this.elements ? jQuery.makeArray( this.elements ) : this;
                })
-               .filter(function() {
+               .filter(function(){
                        return this.name && !this.disabled &&
-                               (this.checked || rselectTextarea.test(this.nodeName) ||
-                                       rinput.test(this.type));
+                               ( this.checked || rselectTextarea.test( this.nodeName ) ||
+                                       rinput.test( this.type ) );
                })
-               .map(function( i, elem ) {
-                       var val = jQuery(this).val();
+               .map(function( i, elem ){
+                       var val = jQuery( this ).val();
 
                        return val == null ?
                                null :
-                               jQuery.isArray(val) ?
-                                       jQuery.map( val, function( val, i ) {
-                                               return { name: elem.name, value: val };
+                               jQuery.isArray( val ) ?
+                                       jQuery.map( val, function( val, i ){
+                                               return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
                                        }) :
-                                       { name: elem.name, value: val };
+                                       { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
                }).get();
        }
 });
 
 // Attach a bunch of functions for handling common AJAX events
-jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) {
-       jQuery.fn[o] = function( f ) {
-               return this.bind(o, f);
+jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
+       jQuery.fn[ o ] = function( f ){
+               return this.bind( o, f );
        };
 });
 
-jQuery.extend({
-       get: function( url, data, callback, type ) {
-               // shift arguments if data argument was omited
+jQuery.each( [ "get", "post" ], function( i, method ) {
+       jQuery[ method ] = function( url, data, callback, type ) {
+               // shift arguments if data argument was omitted
                if ( jQuery.isFunction( data ) ) {
                        type = type || callback;
                        callback = data;
-                       data = null;
+                       data = undefined;
                }
 
                return jQuery.ajax({
-                       type: "GET",
+                       type: method,
                        url: url,
                        data: data,
                        success: callback,
                        dataType: type
                });
-       },
+       };
+});
+
+jQuery.extend({
 
        getScript: function( url, callback ) {
-               return jQuery.get(url, null, callback, "script");
+               return jQuery.get( url, undefined, callback, "script" );
        },
 
        getJSON: function( url, data, callback ) {
-               return jQuery.get(url, data, callback, "json");
+               return jQuery.get( url, data, callback, "json" );
        },
 
-       post: function( url, data, callback, type ) {
-               // shift arguments if data argument was omited
-               if ( jQuery.isFunction( data ) ) {
-                       type = type || callback;
-                       callback = data;
-                       data = {};
+       // Creates a full fledged settings object into target
+       // with both ajaxSettings and settings fields.
+       // If target is omitted, writes into ajaxSettings.
+       ajaxSetup: function ( target, settings ) {
+               if ( !settings ) {
+                       // Only one parameter, we extend ajaxSettings
+                       settings = target;
+                       target = jQuery.extend( true, jQuery.ajaxSettings, settings );
+               } else {
+                       // target was provided, we extend into it
+                       jQuery.extend( true, target, jQuery.ajaxSettings, settings );
                }
-
-               return jQuery.ajax({
-                       type: "POST",
-                       url: url,
-                       data: data,
-                       success: callback,
-                       dataType: type
-               });
-       },
-
-       ajaxSetup: function( settings ) {
-               jQuery.extend( jQuery.ajaxSettings, settings );
+               // Flatten fields we don't want deep extended
+               for( var field in { context: 1, url: 1 } ) {
+                       if ( field in settings ) {
+                               target[ field ] = settings[ field ];
+                       } else if( field in jQuery.ajaxSettings ) {
+                               target[ field ] = jQuery.ajaxSettings[ field ];
+                       }
+               }
+               return target;
        },
 
        ajaxSettings: {
-               url: location.href,
+               url: ajaxLocation,
+               isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
                global: true,
                type: "GET",
                contentType: "application/x-www-form-urlencoded",
@@ -5741,332 +6889,434 @@ jQuery.extend({
                /*
                timeout: 0,
                data: null,
+               dataType: null,
                username: null,
                password: null,
+               cache: null,
                traditional: false,
+               headers: {},
                */
-               // This function can be overriden by calling jQuery.ajaxSetup
-               xhr: function() {
-                       return new window.XMLHttpRequest();
-               },
+
                accepts: {
                        xml: "application/xml, text/xml",
                        html: "text/html",
-                       script: "text/javascript, application/javascript",
-                       json: "application/json, text/javascript",
                        text: "text/plain",
-                       _default: "*/*"
-               }
-       },
+                       json: "application/json, text/javascript",
+                       "*": "*/*"
+               },
 
-       ajax: function( origSettings ) {
-               var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings),
-                       jsonp, status, data, type = s.type.toUpperCase(), noContent = rnoContent.test(type);
+               contents: {
+                       xml: /xml/,
+                       html: /html/,
+                       json: /json/
+               },
 
-               s.url = s.url.replace( rhash, "" );
+               responseFields: {
+                       xml: "responseXML",
+                       text: "responseText"
+               },
 
-               // Use original (not extended) context object if it was provided
-               s.context = origSettings && origSettings.context != null ? origSettings.context : s;
+               // List of data converters
+               // 1) key format is "source_type destination_type" (a single space in-between)
+               // 2) the catchall symbol "*" can be used for source_type
+               converters: {
+
+                       // Convert anything to text
+                       "* text": window.String,
+
+                       // Text to html (true = no transformation)
+                       "text html": true,
+
+                       // Evaluate text as a json expression
+                       "text json": jQuery.parseJSON,
+
+                       // Parse text as xml
+                       "text xml": jQuery.parseXML
+               }
+       },
+
+       ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
+       ajaxTransport: addToPrefiltersOrTransports( transports ),
+
+       // Main method
+       ajax: function( url, options ) {
+
+               // If url is an object, simulate pre-1.5 signature
+               if ( typeof url === "object" ) {
+                       options = url;
+                       url = undefined;
+               }
+
+               // Force options to be an object
+               options = options || {};
+
+               var // Create the final options object
+                       s = jQuery.ajaxSetup( {}, options ),
+                       // Callbacks context
+                       callbackContext = s.context || s,
+                       // Context for global events
+                       // It's the callbackContext if one was provided in the options
+                       // and if it's a DOM node or a jQuery collection
+                       globalEventContext = callbackContext !== s &&
+                               ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
+                                               jQuery( callbackContext ) : jQuery.event,
+                       // Deferreds
+                       deferred = jQuery.Deferred(),
+                       completeDeferred = jQuery._Deferred(),
+                       // Status-dependent callbacks
+                       statusCode = s.statusCode || {},
+                       // ifModified key
+                       ifModifiedKey,
+                       // Headers (they are sent all at once)
+                       requestHeaders = {},
+                       requestHeadersNames = {},
+                       // Response headers
+                       responseHeadersString,
+                       responseHeaders,
+                       // transport
+                       transport,
+                       // timeout handle
+                       timeoutTimer,
+                       // Cross-domain detection vars
+                       parts,
+                       // The jqXHR state
+                       state = 0,
+                       // To know if global events are to be dispatched
+                       fireGlobals,
+                       // Loop variable
+                       i,
+                       // Fake xhr
+                       jqXHR = {
+
+                               readyState: 0,
+
+                               // Caches the header
+                               setRequestHeader: function( name, value ) {
+                                       if ( !state ) {
+                                               var lname = name.toLowerCase();
+                                               name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
+                                               requestHeaders[ name ] = value;
+                                       }
+                                       return this;
+                               },
+
+                               // Raw string
+                               getAllResponseHeaders: function() {
+                                       return state === 2 ? responseHeadersString : null;
+                               },
+
+                               // Builds headers hashtable if needed
+                               getResponseHeader: function( key ) {
+                                       var match;
+                                       if ( state === 2 ) {
+                                               if ( !responseHeaders ) {
+                                                       responseHeaders = {};
+                                                       while( ( match = rheaders.exec( responseHeadersString ) ) ) {
+                                                               responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
+                                                       }
+                                               }
+                                               match = responseHeaders[ key.toLowerCase() ];
+                                       }
+                                       return match === undefined ? null : match;
+                               },
 
-               // convert data if not already a string
-               if ( s.data && s.processData && typeof s.data !== "string" ) {
-                       s.data = jQuery.param( s.data, s.traditional );
-               }
+                               // Overrides response content-type header
+                               overrideMimeType: function( type ) {
+                                       if ( !state ) {
+                                               s.mimeType = type;
+                                       }
+                                       return this;
+                               },
 
-               // Handle JSONP Parameter Callbacks
-               if ( s.dataType === "jsonp" ) {
-                       if ( type === "GET" ) {
-                               if ( !jsre.test( s.url ) ) {
-                                       s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";
+                               // Cancel the request
+                               abort: function( statusText ) {
+                                       statusText = statusText || "abort";
+                                       if ( transport ) {
+                                               transport.abort( statusText );
+                                       }
+                                       done( 0, statusText );
+                                       return this;
                                }
-                       } else if ( !s.data || !jsre.test(s.data) ) {
-                               s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
-                       }
-                       s.dataType = "json";
-               }
+                       };
 
-               // Build temporary JSONP function
-               if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
-                       jsonp = s.jsonpCallback || ("jsonp" + jsc++);
+               // Callback for when everything is done
+               // It is defined here because jslint complains if it is declared
+               // at the end of the function (which would be more logical and readable)
+               function done( status, statusText, responses, headers ) {
 
-                       // Replace the =? sequence both in the query string and the data
-                       if ( s.data ) {
-                               s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
+                       // Called once
+                       if ( state === 2 ) {
+                               return;
                        }
 
-                       s.url = s.url.replace(jsre, "=" + jsonp + "$1");
-
-                       // We need to make sure
-                       // that a JSONP style response is executed properly
-                       s.dataType = "script";
-
-                       // Handle JSONP-style loading
-                       var customJsonp = window[ jsonp ];
-
-                       window[ jsonp ] = function( tmp ) {
-                               if ( jQuery.isFunction( customJsonp ) ) {
-                                       customJsonp( tmp );
-
-                               } else {
-                                       // Garbage collect
-                                       window[ jsonp ] = undefined;
-
-                                       try {
-                                               delete window[ jsonp ];
-                                       } catch( jsonpError ) {}
-                               }
+                       // State is "done" now
+                       state = 2;
 
-                               data = tmp;
-                               jQuery.handleSuccess( s, xhr, status, data );
-                               jQuery.handleComplete( s, xhr, status, data );
-                               
-                               if ( head ) {
-                                       head.removeChild( script );
-                               }
-                       };
-               }
+                       // Clear timeout if it exists
+                       if ( timeoutTimer ) {
+                               clearTimeout( timeoutTimer );
+                       }
 
-               if ( s.dataType === "script" && s.cache === null ) {
-                       s.cache = false;
-               }
+                       // Dereference transport for early garbage collection
+                       // (no matter how long the jqXHR object will be used)
+                       transport = undefined;
 
-               if ( s.cache === false && noContent ) {
-                       var ts = jQuery.now();
+                       // Cache response headers
+                       responseHeadersString = headers || "";
 
-                       // try replacing _= if it is there
-                       var ret = s.url.replace(rts, "$1_=" + ts);
+                       // Set readyState
+                       jqXHR.readyState = status ? 4 : 0;
 
-                       // if nothing was replaced, add timestamp to the end
-                       s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
-               }
+                       var isSuccess,
+                               success,
+                               error,
+                               response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
+                               lastModified,
+                               etag;
 
-               // If data is available, append data to url for GET/HEAD requests
-               if ( s.data && noContent ) {
-                       s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
-               }
+                       // If successful, handle type chaining
+                       if ( status >= 200 && status < 300 || status === 304 ) {
 
-               // Watch for a new set of requests
-               if ( s.global && jQuery.active++ === 0 ) {
-                       jQuery.event.trigger( "ajaxStart" );
-               }
+                               // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+                               if ( s.ifModified ) {
 
-               // Matches an absolute URL, and saves the domain
-               var parts = rurl.exec( s.url ),
-                       remote = parts && (parts[1] && parts[1].toLowerCase() !== location.protocol || parts[2].toLowerCase() !== location.host);
+                                       if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {
+                                               jQuery.lastModified[ ifModifiedKey ] = lastModified;
+                                       }
+                                       if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {
+                                               jQuery.etag[ ifModifiedKey ] = etag;
+                                       }
+                               }
 
-               // If we're requesting a remote document
-               // and trying to load JSON or Script with a GET
-               if ( s.dataType === "script" && type === "GET" && remote ) {
-                       var head = document.getElementsByTagName("head")[0] || document.documentElement;
-                       var script = document.createElement("script");
-                       if ( s.scriptCharset ) {
-                               script.charset = s.scriptCharset;
-                       }
-                       script.src = s.url;
+                               // If not modified
+                               if ( status === 304 ) {
 
-                       // Handle Script loading
-                       if ( !jsonp ) {
-                               var done = false;
+                                       statusText = "notmodified";
+                                       isSuccess = true;
 
-                               // Attach handlers for all browsers
-                               script.onload = script.onreadystatechange = function() {
-                                       if ( !done && (!this.readyState ||
-                                                       this.readyState === "loaded" || this.readyState === "complete") ) {
-                                               done = true;
-                                               jQuery.handleSuccess( s, xhr, status, data );
-                                               jQuery.handleComplete( s, xhr, status, data );
+                               // If we have data
+                               } else {
 
-                                               // Handle memory leak in IE
-                                               script.onload = script.onreadystatechange = null;
-                                               if ( head && script.parentNode ) {
-                                                       head.removeChild( script );
-                                               }
+                                       try {
+                                               success = ajaxConvert( s, response );
+                                               statusText = "success";
+                                               isSuccess = true;
+                                       } catch(e) {
+                                               // We have a parsererror
+                                               statusText = "parsererror";
+                                               error = e;
                                        }
-                               };
+                               }
+                       } else {
+                               // We extract error from statusText
+                               // then normalize statusText and status for non-aborts
+                               error = statusText;
+                               if( !statusText || status ) {
+                                       statusText = "error";
+                                       if ( status < 0 ) {
+                                               status = 0;
+                                       }
+                               }
                        }
 
-                       // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
-                       // This arises when a base node is used (#2709 and #4378).
-                       head.insertBefore( script, head.firstChild );
-
-                       // We handle everything using the script element injection
-                       return undefined;
-               }
+                       // Set data for the fake xhr object
+                       jqXHR.status = status;
+                       jqXHR.statusText = statusText;
 
-               var requestDone = false;
+                       // Success/Error
+                       if ( isSuccess ) {
+                               deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
+                       } else {
+                               deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
+                       }
 
-               // Create the request object
-               var xhr = s.xhr();
+                       // Status-dependent callbacks
+                       jqXHR.statusCode( statusCode );
+                       statusCode = undefined;
 
-               if ( !xhr ) {
-                       return;
-               }
+                       if ( fireGlobals ) {
+                               globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
+                                               [ jqXHR, s, isSuccess ? success : error ] );
+                       }
 
-               // Open the socket
-               // Passing null username, generates a login popup on Opera (#2865)
-               if ( s.username ) {
-                       xhr.open(type, s.url, s.async, s.username, s.password);
-               } else {
-                       xhr.open(type, s.url, s.async);
-               }
+                       // Complete
+                       completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] );
 
-               // Need an extra try/catch for cross domain requests in Firefox 3
-               try {
-                       // Set content-type if data specified and content-body is valid for this type
-                       if ( (s.data != null && !noContent) || (origSettings && origSettings.contentType) ) {
-                               xhr.setRequestHeader("Content-Type", s.contentType);
+                       if ( fireGlobals ) {
+                               globalEventContext.trigger( "ajaxComplete", [ jqXHR, s] );
+                               // Handle the global AJAX counter
+                               if ( !( --jQuery.active ) ) {
+                                       jQuery.event.trigger( "ajaxStop" );
+                               }
                        }
+               }
 
-                       // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
-                       if ( s.ifModified ) {
-                               if ( jQuery.lastModified[s.url] ) {
-                                       xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);
-                               }
+               // Attach deferreds
+               deferred.promise( jqXHR );
+               jqXHR.success = jqXHR.done;
+               jqXHR.error = jqXHR.fail;
+               jqXHR.complete = completeDeferred.done;
 
-                               if ( jQuery.etag[s.url] ) {
-                                       xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]);
+               // Status-dependent callbacks
+               jqXHR.statusCode = function( map ) {
+                       if ( map ) {
+                               var tmp;
+                               if ( state < 2 ) {
+                                       for( tmp in map ) {
+                                               statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
+                                       }
+                               } else {
+                                       tmp = map[ jqXHR.status ];
+                                       jqXHR.then( tmp, tmp );
                                }
                        }
+                       return this;
+               };
 
-                       // Set header so the called script knows that it's an XMLHttpRequest
-                       // Only send the header if it's not a remote XHR
-                       if ( !remote ) {
-                               xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
-                       }
+               // Remove hash character (#7531: and string promotion)
+               // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
+               // We also use the url parameter if available
+               s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
+
+               // Extract dataTypes list
+               s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
+
+               // Determine if a cross-domain request is in order
+               if ( s.crossDomain == null ) {
+                       parts = rurl.exec( s.url.toLowerCase() );
+                       s.crossDomain = !!( parts &&
+                               ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
+                                       ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
+                                               ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
+                       );
+               }
 
-                       // Set the Accepts header for the server, depending on the dataType
-                       xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
-                               s.accepts[ s.dataType ] + ", */*; q=0.01" :
-                               s.accepts._default );
-               } catch( headerError ) {}
+               // Convert data if not already a string
+               if ( s.data && s.processData && typeof s.data !== "string" ) {
+                       s.data = jQuery.param( s.data, s.traditional );
+               }
 
-               // Allow custom headers/mimetypes and early abort
-               if ( s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false ) {
-                       // Handle the global AJAX counter
-                       if ( s.global && jQuery.active-- === 1 ) {
-                               jQuery.event.trigger( "ajaxStop" );
-                       }
+               // Apply prefilters
+               inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
 
-                       // close opended socket
-                       xhr.abort();
+               // If request was aborted inside a prefiler, stop there
+               if ( state === 2 ) {
                        return false;
                }
 
-               if ( s.global ) {
-                       jQuery.triggerGlobal( s, "ajaxSend", [xhr, s] );
-               }
+               // We can fire global events as of now if asked to
+               fireGlobals = s.global;
 
-               // Wait for a response to come back
-               var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {
-                       // The request was aborted
-                       if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) {
-                               // Opera doesn't call onreadystatechange before this point
-                               // so we simulate the call
-                               if ( !requestDone ) {
-                                       jQuery.handleComplete( s, xhr, status, data );
-                               }
+               // Uppercase the type
+               s.type = s.type.toUpperCase();
 
-                               requestDone = true;
-                               if ( xhr ) {
-                                       xhr.onreadystatechange = jQuery.noop;
-                               }
+               // Determine if request has content
+               s.hasContent = !rnoContent.test( s.type );
 
-                       // The transfer is complete and the data is available, or the request timed out
-                       } else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
-                               requestDone = true;
-                               xhr.onreadystatechange = jQuery.noop;
+               // Watch for a new set of requests
+               if ( fireGlobals && jQuery.active++ === 0 ) {
+                       jQuery.event.trigger( "ajaxStart" );
+               }
 
-                               status = isTimeout === "timeout" ?
-                                       "timeout" :
-                                       !jQuery.httpSuccess( xhr ) ?
-                                               "error" :
-                                               s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?
-                                                       "notmodified" :
-                                                       "success";
+               // More options handling for requests with no content
+               if ( !s.hasContent ) {
 
-                               var errMsg;
+                       // If data is available, append data to url
+                       if ( s.data ) {
+                               s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
+                       }
 
-                               if ( status === "success" ) {
-                                       // Watch for, and catch, XML document parse errors
-                                       try {
-                                               // process the data (runs the xml through httpData regardless of callback)
-                                               data = jQuery.httpData( xhr, s.dataType, s );
-                                       } catch( parserError ) {
-                                               status = "parsererror";
-                                               errMsg = parserError;
-                                       }
-                               }
+                       // Get ifModifiedKey before adding the anti-cache parameter
+                       ifModifiedKey = s.url;
 
-                               // Make sure that the request was successful or notmodified
-                               if ( status === "success" || status === "notmodified" ) {
-                                       // JSONP handles its own success callback
-                                       if ( !jsonp ) {
-                                               jQuery.handleSuccess( s, xhr, status, data );
-                                       }
-                               } else {
-                                       jQuery.handleError( s, xhr, status, errMsg );
-                               }
+                       // Add anti-cache in url if needed
+                       if ( s.cache === false ) {
 
-                               // Fire the complete handlers
-                               if ( !jsonp ) {
-                                       jQuery.handleComplete( s, xhr, status, data );
-                               }
+                               var ts = jQuery.now(),
+                                       // try replacing _= if it is there
+                                       ret = s.url.replace( rts, "$1_=" + ts );
 
-                               if ( isTimeout === "timeout" ) {
-                                       xhr.abort();
-                               }
+                               // if nothing was replaced, add timestamp to the end
+                               s.url = ret + ( (ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
+                       }
+               }
 
-                               // Stop memory leaks
-                               if ( s.async ) {
-                                       xhr = null;
-                               }
+               // Set the correct header, if data is being sent
+               if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
+                       jqXHR.setRequestHeader( "Content-Type", s.contentType );
+               }
+
+               // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+               if ( s.ifModified ) {
+                       ifModifiedKey = ifModifiedKey || s.url;
+                       if ( jQuery.lastModified[ ifModifiedKey ] ) {
+                               jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
                        }
-               };
+                       if ( jQuery.etag[ ifModifiedKey ] ) {
+                               jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
+                       }
+               }
 
-               // Override the abort handler, if we can (IE 6 doesn't allow it, but that's OK)
-               // Opera doesn't fire onreadystatechange at all on abort
-               try {
-                       var oldAbort = xhr.abort;
-                       xhr.abort = function() {
-                               if ( xhr ) {
-                                       // oldAbort has no call property in IE7 so
-                                       // just do it this way, which works in all
-                                       // browsers
-                                       Function.prototype.call.call( oldAbort, xhr );
-                               }
+               // Set the Accepts header for the server, depending on the dataType
+               jqXHR.setRequestHeader(
+                       "Accept",
+                       s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
+                               s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) :
+                               s.accepts[ "*" ]
+               );
 
-                               onreadystatechange( "abort" );
-                       };
-               } catch( abortError ) {}
+               // Check for headers option
+               for ( i in s.headers ) {
+                       jqXHR.setRequestHeader( i, s.headers[ i ] );
+               }
+
+               // Allow custom headers/mimetypes and early abort
+               if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
+                               // Abort if not done already
+                               jqXHR.abort();
+                               return false;
 
-               // Timeout checker
-               if ( s.async && s.timeout > 0 ) {
-                       setTimeout(function() {
-                               // Check to see if the request is still happening
-                               if ( xhr && !requestDone ) {
-                                       onreadystatechange( "timeout" );
-                               }
-                       }, s.timeout);
                }
 
-               // Send the data
-               try {
-                       xhr.send( noContent || s.data == null ? null : s.data );
+               // Install callbacks on deferreds
+               for ( i in { success: 1, error: 1, complete: 1 } ) {
+                       jqXHR[ i ]( s[ i ] );
+               }
 
-               } catch( sendError ) {
-                       jQuery.handleError( s, xhr, null, sendError );
+               // Get transport
+               transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
 
-                       // Fire the complete handlers
-                       jQuery.handleComplete( s, xhr, status, data );
-               }
+               // If no transport, we auto-abort
+               if ( !transport ) {
+                       done( -1, "No Transport" );
+               } else {
+                       jqXHR.readyState = 1;
+                       // Send global event
+                       if ( fireGlobals ) {
+                               globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
+                       }
+                       // Timeout
+                       if ( s.async && s.timeout > 0 ) {
+                               timeoutTimer = setTimeout( function(){
+                                       jqXHR.abort( "timeout" );
+                               }, s.timeout );
+                       }
 
-               // firefox 1.5 doesn't fire statechange for sync requests
-               if ( !s.async ) {
-                       onreadystatechange();
+                       try {
+                               state = 1;
+                               transport.send( requestHeaders, done );
+                       } catch (e) {
+                               // Propagate exception as error if not done
+                               if ( status < 2 ) {
+                                       done( -1, e );
+                               // Simply rethrow otherwise
+                               } else {
+                                       jQuery.error( e );
+                               }
+                       }
                }
 
-               // return XMLHttpRequest to allow aborting the request etc.
-               return xhr;
+               return jqXHR;
        },
 
        // Serialize an array of form elements or a set of
@@ -6075,37 +7325,37 @@ jQuery.extend({
                var s = [],
                        add = function( key, value ) {
                                // If value is a function, invoke it and return its value
-                               value = jQuery.isFunction(value) ? value() : value;
-                               s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
+                               value = jQuery.isFunction( value ) ? value() : value;
+                               s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
                        };
-               
+
                // Set traditional to true for jQuery <= 1.3.2 behavior.
                if ( traditional === undefined ) {
                        traditional = jQuery.ajaxSettings.traditional;
                }
-               
+
                // If an array was passed in, assume that it is an array of form elements.
-               if ( jQuery.isArray(a) || a.jquery ) {
+               if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
                        // Serialize the form elements
                        jQuery.each( a, function() {
                                add( this.name, this.value );
                        });
-                       
+
                } else {
                        // If traditional, encode the "old" way (the way 1.3.2 or older
                        // did it), otherwise encode params recursively.
                        for ( var prefix in a ) {
-                               buildParams( prefix, a[prefix], traditional, add );
+                               buildParams( prefix, a[ prefix ], traditional, add );
                        }
                }
 
                // Return the resulting serialization
-               return s.join("&").replace(r20, "+");
+               return s.join( "&" ).replace( r20, "+" );
        }
 });
 
 function buildParams( prefix, obj, traditional, add ) {
-       if ( jQuery.isArray(obj) && obj.length ) {
+       if ( jQuery.isArray( obj ) ) {
                // Serialize array item.
                jQuery.each( obj, function( i, v ) {
                        if ( traditional || rbracket.test( prefix ) ) {
@@ -6123,18 +7373,13 @@ function buildParams( prefix, obj, traditional, add ) {
                                buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
                        }
                });
-                       
-       } else if ( !traditional && obj != null && typeof obj === "object" ) {
-               if ( jQuery.isEmptyObject( obj ) ) {
-                       add( prefix, "" );
 
+       } else if ( !traditional && obj != null && typeof obj === "object" ) {
                // Serialize object item.
-               } else {
-                       jQuery.each( obj, function( k, v ) {
-                               buildParams( prefix + "[" + k + "]", v, traditional, add );
-                       });
+               for ( var name in obj ) {
+                       buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
                }
-                                       
+
        } else {
                // Serialize scalar item.
                add( prefix, obj );
@@ -6150,143 +7395,557 @@ jQuery.extend({
 
        // Last-Modified header cache for next request
        lastModified: {},
-       etag: {},
+       etag: {}
 
-       handleError: function( s, xhr, status, e ) {
-               // If a local callback was specified, fire it
-               if ( s.error ) {
-                       s.error.call( s.context, xhr, status, e );
-               }
+});
 
-               // Fire the global callback
-               if ( s.global ) {
-                       jQuery.triggerGlobal( s, "ajaxError", [xhr, s, e] );
-               }
-       },
+/* Handles responses to an ajax request:
+ * - sets all responseXXX fields accordingly
+ * - finds the right dataType (mediates between content-type and expected dataType)
+ * - returns the corresponding response
+ */
+function ajaxHandleResponses( s, jqXHR, responses ) {
 
-       handleSuccess: function( s, xhr, status, data ) {
-               // If a local callback was specified, fire it and pass it the data
-               if ( s.success ) {
-                       s.success.call( s.context, data, status, xhr );
-               }
+       var contents = s.contents,
+               dataTypes = s.dataTypes,
+               responseFields = s.responseFields,
+               ct,
+               type,
+               finalDataType,
+               firstDataType;
 
-               // Fire the global callback
-               if ( s.global ) {
-                       jQuery.triggerGlobal( s, "ajaxSuccess", [xhr, s] );
+       // Fill responseXXX fields
+       for( type in responseFields ) {
+               if ( type in responses ) {
+                       jqXHR[ responseFields[type] ] = responses[ type ];
                }
-       },
+       }
 
-       handleComplete: function( s, xhr, status ) {
-               // Process result
-               if ( s.complete ) {
-                       s.complete.call( s.context, xhr, status );
+       // Remove auto dataType and get content-type in the process
+       while( dataTypes[ 0 ] === "*" ) {
+               dataTypes.shift();
+               if ( ct === undefined ) {
+                       ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
                }
+       }
 
-               // The request was completed
-               if ( s.global ) {
-                       jQuery.triggerGlobal( s, "ajaxComplete", [xhr, s] );
+       // Check if we're dealing with a known content-type
+       if ( ct ) {
+               for ( type in contents ) {
+                       if ( contents[ type ] && contents[ type ].test( ct ) ) {
+                               dataTypes.unshift( type );
+                               break;
+                       }
                }
+       }
 
-               // Handle the global AJAX counter
-               if ( s.global && jQuery.active-- === 1 ) {
-                       jQuery.event.trigger( "ajaxStop" );
+       // Check to see if we have a response for the expected dataType
+       if ( dataTypes[ 0 ] in responses ) {
+               finalDataType = dataTypes[ 0 ];
+       } else {
+               // Try convertible dataTypes
+               for ( type in responses ) {
+                       if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
+                               finalDataType = type;
+                               break;
+                       }
+                       if ( !firstDataType ) {
+                               firstDataType = type;
+                       }
                }
-       },
-               
-       triggerGlobal: function( s, type, args ) {
-               (s.context && s.context.url == null ? jQuery(s.context) : jQuery.event).trigger(type, args);
-       },
+               // Or just use first one
+               finalDataType = finalDataType || firstDataType;
+       }
 
-       // Determines if an XMLHttpRequest was successful or not
-       httpSuccess: function( xhr ) {
-               try {
-                       // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
-                       return !xhr.status && location.protocol === "file:" ||
-                               xhr.status >= 200 && xhr.status < 300 ||
-                               xhr.status === 304 || xhr.status === 1223;
-               } catch(e) {}
+       // If we found a dataType
+       // We add the dataType to the list if needed
+       // and return the corresponding response
+       if ( finalDataType ) {
+               if ( finalDataType !== dataTypes[ 0 ] ) {
+                       dataTypes.unshift( finalDataType );
+               }
+               return responses[ finalDataType ];
+       }
+}
 
-               return false;
-       },
+// Chain conversions given the request and the original response
+function ajaxConvert( s, response ) {
 
-       // Determines if an XMLHttpRequest returns NotModified
-       httpNotModified: function( xhr, url ) {
-               var lastModified = xhr.getResponseHeader("Last-Modified"),
-                       etag = xhr.getResponseHeader("Etag");
+       // Apply the dataFilter if provided
+       if ( s.dataFilter ) {
+               response = s.dataFilter( response, s.dataType );
+       }
 
-               if ( lastModified ) {
-                       jQuery.lastModified[url] = lastModified;
+       var dataTypes = s.dataTypes,
+               converters = {},
+               i,
+               key,
+               length = dataTypes.length,
+               tmp,
+               // Current and previous dataTypes
+               current = dataTypes[ 0 ],
+               prev,
+               // Conversion expression
+               conversion,
+               // Conversion function
+               conv,
+               // Conversion functions (transitive conversion)
+               conv1,
+               conv2;
+
+       // For each dataType in the chain
+       for( i = 1; i < length; i++ ) {
+
+               // Create converters map
+               // with lowercased keys
+               if ( i === 1 ) {
+                       for( key in s.converters ) {
+                               if( typeof key === "string" ) {
+                                       converters[ key.toLowerCase() ] = s.converters[ key ];
+                               }
+                       }
                }
 
-               if ( etag ) {
-                       jQuery.etag[url] = etag;
+               // Get the dataTypes
+               prev = current;
+               current = dataTypes[ i ];
+
+               // If current is auto dataType, update it to prev
+               if( current === "*" ) {
+                       current = prev;
+               // If no auto and dataTypes are actually different
+               } else if ( prev !== "*" && prev !== current ) {
+
+                       // Get the converter
+                       conversion = prev + " " + current;
+                       conv = converters[ conversion ] || converters[ "* " + current ];
+
+                       // If there is no direct converter, search transitively
+                       if ( !conv ) {
+                               conv2 = undefined;
+                               for( conv1 in converters ) {
+                                       tmp = conv1.split( " " );
+                                       if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {
+                                               conv2 = converters[ tmp[1] + " " + current ];
+                                               if ( conv2 ) {
+                                                       conv1 = converters[ conv1 ];
+                                                       if ( conv1 === true ) {
+                                                               conv = conv2;
+                                                       } else if ( conv2 === true ) {
+                                                               conv = conv1;
+                                                       }
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+                       // If we found no converter, dispatch an error
+                       if ( !( conv || conv2 ) ) {
+                               jQuery.error( "No conversion from " + conversion.replace(" "," to ") );
+                       }
+                       // If found converter is not an equivalence
+                       if ( conv !== true ) {
+                               // Convert with 1 or 2 converters accordingly
+                               response = conv ? conv( response ) : conv2( conv1(response) );
+                       }
                }
+       }
+       return response;
+}
 
-               return xhr.status === 304;
-       },
 
-       httpData: function( xhr, type, s ) {
-               var ct = xhr.getResponseHeader("content-type") || "",
-                       xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
-                       data = xml ? xhr.responseXML : xhr.responseText;
 
-               if ( xml && data.documentElement.nodeName === "parsererror" ) {
-                       jQuery.error( "parsererror" );
-               }
 
-               // Allow a pre-filtering function to sanitize the response
-               // s is checked to keep backwards compatibility
-               if ( s && s.dataFilter ) {
-                       data = s.dataFilter( data, type );
+var jsc = jQuery.now(),
+       jsre = /(\=)\?(&|$)|\?\?/i;
+
+// Default jsonp settings
+jQuery.ajaxSetup({
+       jsonp: "callback",
+       jsonpCallback: function() {
+               return jQuery.expando + "_" + ( jsc++ );
+       }
+});
+
+// Detect, normalize options and install callbacks for jsonp requests
+jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
+
+       var inspectData = s.contentType === "application/x-www-form-urlencoded" &&
+               ( typeof s.data === "string" );
+
+       if ( s.dataTypes[ 0 ] === "jsonp" ||
+               s.jsonp !== false && ( jsre.test( s.url ) ||
+                               inspectData && jsre.test( s.data ) ) ) {
+
+               var responseContainer,
+                       jsonpCallback = s.jsonpCallback =
+                               jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
+                       previous = window[ jsonpCallback ],
+                       url = s.url,
+                       data = s.data,
+                       replace = "$1" + jsonpCallback + "$2";
+
+               if ( s.jsonp !== false ) {
+                       url = url.replace( jsre, replace );
+                       if ( s.url === url ) {
+                               if ( inspectData ) {
+                                       data = data.replace( jsre, replace );
+                               }
+                               if ( s.data === data ) {
+                                       // Add callback manually
+                                       url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
+                               }
+                       }
                }
 
-               // The filter can actually parse the response
-               if ( typeof data === "string" ) {
-                       // Get the JavaScript object, if JSON is used.
-                       if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {
-                               data = jQuery.parseJSON( data );
+               s.url = url;
+               s.data = data;
+
+               // Install callback
+               window[ jsonpCallback ] = function( response ) {
+                       responseContainer = [ response ];
+               };
+
+               // Clean-up function
+               jqXHR.always(function() {
+                       // Set callback back to previous value
+                       window[ jsonpCallback ] = previous;
+                       // Call if it was a function and we have a response
+                       if ( responseContainer && jQuery.isFunction( previous ) ) {
+                               window[ jsonpCallback ]( responseContainer[ 0 ] );
+                       }
+               });
 
-                       // If the type is "script", eval it in global context
-                       } else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {
-                               jQuery.globalEval( data );
+               // Use data converter to retrieve json after script execution
+               s.converters["script json"] = function() {
+                       if ( !responseContainer ) {
+                               jQuery.error( jsonpCallback + " was not called" );
                        }
+                       return responseContainer[ 0 ];
+               };
+
+               // force json dataType
+               s.dataTypes[ 0 ] = "json";
+
+               // Delegate to script
+               return "script";
+       }
+});
+
+
+
+
+// Install script dataType
+jQuery.ajaxSetup({
+       accepts: {
+               script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
+       },
+       contents: {
+               script: /javascript|ecmascript/
+       },
+       converters: {
+               "text script": function( text ) {
+                       jQuery.globalEval( text );
+                       return text;
                }
+       }
+});
 
-               return data;
+// Handle cache's special case and global
+jQuery.ajaxPrefilter( "script", function( s ) {
+       if ( s.cache === undefined ) {
+               s.cache = false;
+       }
+       if ( s.crossDomain ) {
+               s.type = "GET";
+               s.global = false;
        }
+});
+
+// Bind script tag hack transport
+jQuery.ajaxTransport( "script", function(s) {
+
+       // This transport only deals with cross domain requests
+       if ( s.crossDomain ) {
+
+               var script,
+                       head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
+
+               return {
+
+                       send: function( _, callback ) {
+
+                               script = document.createElement( "script" );
+
+                               script.async = "async";
+
+                               if ( s.scriptCharset ) {
+                                       script.charset = s.scriptCharset;
+                               }
+
+                               script.src = s.url;
+
+                               // Attach handlers for all browsers
+                               script.onload = script.onreadystatechange = function( _, isAbort ) {
+
+                                       if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
+
+                                               // Handle memory leak in IE
+                                               script.onload = script.onreadystatechange = null;
+
+                                               // Remove the script
+                                               if ( head && script.parentNode ) {
+                                                       head.removeChild( script );
+                                               }
+
+                                               // Dereference the script
+                                               script = undefined;
+
+                                               // Callback if not abort
+                                               if ( !isAbort ) {
+                                                       callback( 200, "success" );
+                                               }
+                                       }
+                               };
+                               // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
+                               // This arises when a base node is used (#2709 and #4378).
+                               head.insertBefore( script, head.firstChild );
+                       },
 
+                       abort: function() {
+                               if ( script ) {
+                                       script.onload( 0, 1 );
+                               }
+                       }
+               };
+       }
 });
 
-/*
- * Create the request object; Microsoft failed to properly
- * implement the XMLHttpRequest in IE7 (can't request local files),
- * so we use the ActiveXObject when it is available
- * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
- * we need a fallback.
- */
-if ( window.ActiveXObject ) {
-       jQuery.ajaxSettings.xhr = function() {
-               if ( window.location.protocol !== "file:" ) {
-                       try {
-                               return new window.XMLHttpRequest();
-                       } catch(xhrError) {}
+
+
+
+var // #5280: Internet Explorer will keep connections alive if we don't abort on unload
+       xhrOnUnloadAbort = window.ActiveXObject ? function() {
+               // Abort all pending requests
+               for ( var key in xhrCallbacks ) {
+                       xhrCallbacks[ key ]( 0, 1 );
                }
+       } : false,
+       xhrId = 0,
+       xhrCallbacks;
 
-               try {
-                       return new window.ActiveXObject("Microsoft.XMLHTTP");
-               } catch(activeError) {}
-       };
+// Functions to create xhrs
+function createStandardXHR() {
+       try {
+               return new window.XMLHttpRequest();
+       } catch( e ) {}
+}
+
+function createActiveXHR() {
+       try {
+               return new window.ActiveXObject( "Microsoft.XMLHTTP" );
+       } catch( e ) {}
 }
 
-// Does this browser support XHR requests?
-jQuery.support.ajax = !!jQuery.ajaxSettings.xhr();
+// Create the request object
+// (This is still attached to ajaxSettings for backward compatibility)
+jQuery.ajaxSettings.xhr = window.ActiveXObject ?
+       /* Microsoft failed to properly
+        * implement the XMLHttpRequest in IE7 (can't request local files),
+        * so we use the ActiveXObject when it is available
+        * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
+        * we need a fallback.
+        */
+       function() {
+               return !this.isLocal && createStandardXHR() || createActiveXHR();
+       } :
+       // For all other browsers, use the standard XMLHttpRequest object
+       createStandardXHR;
+
+// Determine support properties
+(function( xhr ) {
+       jQuery.extend( jQuery.support, {
+               ajax: !!xhr,
+               cors: !!xhr && ( "withCredentials" in xhr )
+       });
+})( jQuery.ajaxSettings.xhr() );
+
+// Create transport if the browser can provide an xhr
+if ( jQuery.support.ajax ) {
+
+       jQuery.ajaxTransport(function( s ) {
+               // Cross domain only allowed if supported through XMLHttpRequest
+               if ( !s.crossDomain || jQuery.support.cors ) {
+
+                       var callback;
+
+                       return {
+                               send: function( headers, complete ) {
+
+                                       // Get a new xhr
+                                       var xhr = s.xhr(),
+                                               handle,
+                                               i;
+
+                                       // Open the socket
+                                       // Passing null username, generates a login popup on Opera (#2865)
+                                       if ( s.username ) {
+                                               xhr.open( s.type, s.url, s.async, s.username, s.password );
+                                       } else {
+                                               xhr.open( s.type, s.url, s.async );
+                                       }
+
+                                       // Apply custom fields if provided
+                                       if ( s.xhrFields ) {
+                                               for ( i in s.xhrFields ) {
+                                                       xhr[ i ] = s.xhrFields[ i ];
+                                               }
+                                       }
+
+                                       // Override mime type if needed
+                                       if ( s.mimeType && xhr.overrideMimeType ) {
+                                               xhr.overrideMimeType( s.mimeType );
+                                       }
+
+                                       // X-Requested-With header
+                                       // For cross-domain requests, seeing as conditions for a preflight are
+                                       // akin to a jigsaw puzzle, we simply never set it to be sure.
+                                       // (it can always be set on a per-request basis or even using ajaxSetup)
+                                       // For same-domain requests, won't change header if already provided.
+                                       if ( !s.crossDomain && !headers["X-Requested-With"] ) {
+                                               headers[ "X-Requested-With" ] = "XMLHttpRequest";
+                                       }
+
+                                       // Need an extra try/catch for cross domain requests in Firefox 3
+                                       try {
+                                               for ( i in headers ) {
+                                                       xhr.setRequestHeader( i, headers[ i ] );
+                                               }
+                                       } catch( _ ) {}
+
+                                       // Do send the request
+                                       // This may raise an exception which is actually
+                                       // handled in jQuery.ajax (so no try/catch here)
+                                       xhr.send( ( s.hasContent && s.data ) || null );
+
+                                       // Listener
+                                       callback = function( _, isAbort ) {
+
+                                               var status,
+                                                       statusText,
+                                                       responseHeaders,
+                                                       responses,
+                                                       xml;
+
+                                               // Firefox throws exceptions when accessing properties
+                                               // of an xhr when a network error occured
+                                               // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
+                                               try {
+
+                                                       // Was never called and is aborted or complete
+                                                       if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
+
+                                                               // Only called once
+                                                               callback = undefined;
+
+                                                               // Do not keep as active anymore
+                                                               if ( handle ) {
+                                                                       xhr.onreadystatechange = jQuery.noop;
+                                                                       if ( xhrOnUnloadAbort ) {
+                                                                               delete xhrCallbacks[ handle ];
+                                                                       }
+                                                               }
+
+                                                               // If it's an abort
+                                                               if ( isAbort ) {
+                                                                       // Abort it manually if needed
+                                                                       if ( xhr.readyState !== 4 ) {
+                                                                               xhr.abort();
+                                                                       }
+                                                               } else {
+                                                                       status = xhr.status;
+                                                                       responseHeaders = xhr.getAllResponseHeaders();
+                                                                       responses = {};
+                                                                       xml = xhr.responseXML;
+
+                                                                       // Construct response list
+                                                                       if ( xml && xml.documentElement /* #4958 */ ) {
+                                                                               responses.xml = xml;
+                                                                       }
+                                                                       responses.text = xhr.responseText;
+
+                                                                       // Firefox throws an exception when accessing
+                                                                       // statusText for faulty cross-domain requests
+                                                                       try {
+                                                                               statusText = xhr.statusText;
+                                                                       } catch( e ) {
+                                                                               // We normalize with Webkit giving an empty statusText
+                                                                               statusText = "";
+                                                                       }
+
+                                                                       // Filter status for non standard behaviors
+
+                                                                       // If the request is local and we have data: assume a success
+                                                                       // (success with no data won't get notified, that's the best we
+                                                                       // can do given current implementations)
+                                                                       if ( !status && s.isLocal && !s.crossDomain ) {
+                                                                               status = responses.text ? 200 : 404;
+                                                                       // IE - #1450: sometimes returns 1223 when it should be 204
+                                                                       } else if ( status === 1223 ) {
+                                                                               status = 204;
+                                                                       }
+                                                               }
+                                                       }
+                                               } catch( firefoxAccessException ) {
+                                                       if ( !isAbort ) {
+                                                               complete( -1, firefoxAccessException );
+                                                       }
+                                               }
+
+                                               // Call complete if needed
+                                               if ( responses ) {
+                                                       complete( status, statusText, responses, responseHeaders );
+                                               }
+                                       };
+
+                                       // if we're in sync mode or it's in cache
+                                       // and has been retrieved directly (IE6 & IE7)
+                                       // we need to manually fire the callback
+                                       if ( !s.async || xhr.readyState === 4 ) {
+                                               callback();
+                                       } else {
+                                               handle = ++xhrId;
+                                               if ( xhrOnUnloadAbort ) {
+                                                       // Create the active xhrs callbacks list if needed
+                                                       // and attach the unload handler
+                                                       if ( !xhrCallbacks ) {
+                                                               xhrCallbacks = {};
+                                                               jQuery( window ).unload( xhrOnUnloadAbort );
+                                                       }
+                                                       // Add to list of active xhrs callbacks
+                                                       xhrCallbacks[ handle ] = callback;
+                                               }
+                                               xhr.onreadystatechange = callback;
+                                       }
+                               },
+
+                               abort: function() {
+                                       if ( callback ) {
+                                               callback(0,1);
+                                       }
+                               }
+                       };
+               }
+       });
+}
 
 
 
 
 var elemdisplay = {},
+       iframe, iframeDoc,
        rfxtypes = /^(?:toggle|show|hide)$/,
-       rfxnum = /^([+\-]=)?([\d+.\-]+)(.*)$/,
+       rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
        timerId,
        fxAttrs = [
                // height animations
@@ -6295,7 +7954,11 @@ var elemdisplay = {},
                [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
                // opacity animations
                [ "opacity" ]
-       ];
+       ],
+       fxNow,
+       requestAnimationFrame = window.webkitRequestAnimationFrame ||
+           window.mozRequestAnimationFrame ||
+           window.oRequestAnimationFrame;
 
 jQuery.fn.extend({
        show: function( speed, easing, callback ) {
@@ -6307,19 +7970,22 @@ jQuery.fn.extend({
                } else {
                        for ( var i = 0, j = this.length; i < j; i++ ) {
                                elem = this[i];
-                               display = elem.style.display;
 
-                               // Reset the inline display of this element to learn if it is
-                               // being hidden by cascaded rules or not
-                               if ( !jQuery.data(elem, "olddisplay") && display === "none" ) {
-                                       display = elem.style.display = "";
-                               }
+                               if ( elem.style ) {
+                                       display = elem.style.display;
+
+                                       // Reset the inline display of this element to learn if it is
+                                       // being hidden by cascaded rules or not
+                                       if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
+                                               display = elem.style.display = "";
+                                       }
 
-                               // Set elements which have been overridden with display: none
-                               // in a stylesheet to whatever the default browser style is
-                               // for such an element
-                               if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
-                                       jQuery.data(elem, "olddisplay", defaultDisplay(elem.nodeName));
+                                       // Set elements which have been overridden with display: none
+                                       // in a stylesheet to whatever the default browser style is
+                                       // for such an element
+                                       if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
+                                               jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName));
+                                       }
                                }
                        }
 
@@ -6327,10 +7993,13 @@ jQuery.fn.extend({
                        // to avoid the constant reflow
                        for ( i = 0; i < j; i++ ) {
                                elem = this[i];
-                               display = elem.style.display;
 
-                               if ( display === "" || display === "none" ) {
-                                       elem.style.display = jQuery.data(elem, "olddisplay") || "";
+                               if ( elem.style ) {
+                                       display = elem.style.display;
+
+                                       if ( display === "" || display === "none" ) {
+                                               elem.style.display = jQuery._data(elem, "olddisplay") || "";
+                                       }
                                }
                        }
 
@@ -6344,17 +8013,21 @@ jQuery.fn.extend({
 
                } else {
                        for ( var i = 0, j = this.length; i < j; i++ ) {
-                               var display = jQuery.css( this[i], "display" );
+                               if ( this[i].style ) {
+                                       var display = jQuery.css( this[i], "display" );
 
-                               if ( display !== "none" ) {
-                                       jQuery.data( this[i], "olddisplay", display );
+                                       if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) {
+                                               jQuery._data( this[i], "olddisplay", display );
+                                       }
                                }
                        }
 
                        // Set the display of the elements in a second loop
                        // to avoid the constant reflow
                        for ( i = 0; i < j; i++ ) {
-                               this[i].style.display = "none";
+                               if ( this[i].style ) {
+                                       this[i].style.display = "none";
+                               }
                        }
 
                        return this;
@@ -6392,32 +8065,54 @@ jQuery.fn.extend({
                var optall = jQuery.speed(speed, easing, callback);
 
                if ( jQuery.isEmptyObject( prop ) ) {
-                       return this.each( optall.complete );
+                       return this.each( optall.complete, [ false ] );
                }
 
+               // Do not change referenced properties as per-property easing will be lost
+               prop = jQuery.extend( {}, prop );
+
                return this[ optall.queue === false ? "each" : "queue" ](function() {
                        // XXX 'this' does not always have a nodeName when running the
                        // test suite
 
-                       var opt = jQuery.extend({}, optall), p,
+                       if ( optall.queue === false ) {
+                               jQuery._mark( this );
+                       }
+
+                       var opt = jQuery.extend( {}, optall ),
                                isElement = this.nodeType === 1,
                                hidden = isElement && jQuery(this).is(":hidden"),
-                               self = this;
+                               name, val, p,
+                               display, e,
+                               parts, start, end, unit;
+
+                       // will store per property easing and be used to determine when an animation is complete
+                       opt.animatedProperties = {};
 
                        for ( p in prop ) {
-                               var name = jQuery.camelCase( p );
 
+                               // property name normalization
+                               name = jQuery.camelCase( p );
                                if ( p !== name ) {
                                        prop[ name ] = prop[ p ];
                                        delete prop[ p ];
-                                       p = name;
                                }
 
-                               if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) {
-                                       return opt.complete.call(this);
+                               val = prop[ name ];
+
+                               // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
+                               if ( jQuery.isArray( val ) ) {
+                                       opt.animatedProperties[ name ] = val[ 1 ];
+                                       val = prop[ name ] = val[ 0 ];
+                               } else {
+                                       opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';
+                               }
+
+                               if ( val === "hide" && hidden || val === "show" && !hidden ) {
+                                       return opt.complete.call( this );
                                }
 
-                               if ( isElement && ( p === "height" || p === "width" ) ) {
+                               if ( isElement && ( name === "height" || name === "width" ) ) {
                                        // Make sure that nothing sneaks out
                                        // Record all 3 overflow attributes because IE does not
                                        // change the overflow attribute when overflowX and
@@ -6433,7 +8128,7 @@ jQuery.fn.extend({
                                                        this.style.display = "inline-block";
 
                                                } else {
-                                                       var display = defaultDisplay(this.nodeName);
+                                                       display = defaultDisplay( this.nodeName );
 
                                                        // inline-level elements accept inline-block;
                                                        // block-level elements need to be inline with layout
@@ -6447,44 +8142,37 @@ jQuery.fn.extend({
                                                }
                                        }
                                }
-
-                               if ( jQuery.isArray( prop[p] ) ) {
-                                       // Create (if needed) and add to specialEasing
-                                       (opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];
-                                       prop[p] = prop[p][0];
-                               }
                        }
 
                        if ( opt.overflow != null ) {
                                this.style.overflow = "hidden";
                        }
 
-                       opt.curAnim = jQuery.extend({}, prop);
-
-                       jQuery.each( prop, function( name, val ) {
-                               var e = new jQuery.fx( self, opt, name );
+                       for ( p in prop ) {
+                               e = new jQuery.fx( this, opt, p );
+                               val = prop[ p ];
 
                                if ( rfxtypes.test(val) ) {
-                                       e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop );
+                                       e[ val === "toggle" ? hidden ? "show" : "hide" : val ]();
 
                                } else {
-                                       var parts = rfxnum.exec(val),
-                                               start = e.cur() || 0;
+                                       parts = rfxnum.exec( val );
+                                       start = e.cur();
 
                                        if ( parts ) {
-                                               var end = parseFloat( parts[2] ),
-                                                       unit = parts[3] || "px";
+                                               end = parseFloat( parts[2] );
+                                               unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );
 
                                                // We need to compute starting value
                                                if ( unit !== "px" ) {
-                                                       jQuery.style( self, name, (end || 1) + unit);
+                                                       jQuery.style( this, p, (end || 1) + unit);
                                                        start = ((end || 1) / e.cur()) * start;
-                                                       jQuery.style( self, name, start + unit);
+                                                       jQuery.style( this, p, start + unit);
                                                }
 
                                                // If a +=/-= token was provided, we're doing a relative animation
                                                if ( parts[1] ) {
-                                                       end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
+                                                       end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start;
                                                }
 
                                                e.custom( start, end, unit );
@@ -6493,7 +8181,7 @@ jQuery.fn.extend({
                                                e.custom( start, val, "" );
                                        }
                                }
-                       });
+                       }
 
                        // For JS strict compliance
                        return true;
@@ -6501,15 +8189,18 @@ jQuery.fn.extend({
        },
 
        stop: function( clearQueue, gotoEnd ) {
-               var timers = jQuery.timers;
-
                if ( clearQueue ) {
                        this.queue([]);
                }
 
                this.each(function() {
-                       // go in reverse order so anything added to the queue during the loop is ignored
-                       for ( var i = timers.length - 1; i >= 0; i-- ) {
+                       var timers = jQuery.timers,
+                               i = timers.length;
+                       // clear marker counters if we know they won't be
+                       if ( !gotoEnd ) {
+                               jQuery._unmark( true, this );
+                       }
+                       while ( i-- ) {
                                if ( timers[i].elem === this ) {
                                        if (gotoEnd) {
                                                // force the next step to be the last
@@ -6531,6 +8222,17 @@ jQuery.fn.extend({
 
 });
 
+// Animations created synchronously will run synchronously
+function createFxNow() {
+       setTimeout( clearFxNow, 0 );
+       return ( fxNow = jQuery.now() );
+}
+
+function clearFxNow() {
+       fxNow = undefined;
+}
+
+// Generate parameters to create a standard animation
 function genFx( type, num ) {
        var obj = {};
 
@@ -6569,10 +8271,13 @@ jQuery.extend({
 
                // Queueing
                opt.old = opt.complete;
-               opt.complete = function() {
+               opt.complete = function( noUnmark ) {
                        if ( opt.queue !== false ) {
-                               jQuery(this).dequeue();
+                               jQuery.dequeue( this );
+                       } else if ( noUnmark !== false ) {
+                               jQuery._unmark( this );
                        }
+
                        if ( jQuery.isFunction( opt.old ) ) {
                                opt.old.call( this );
                        }
@@ -6597,9 +8302,7 @@ jQuery.extend({
                this.elem = elem;
                this.prop = prop;
 
-               if ( !options.orig ) {
-                       options.orig = {};
-               }
+               options.orig = options.orig || {};
        }
 
 });
@@ -6620,19 +8323,24 @@ jQuery.fx.prototype = {
                        return this.elem[ this.prop ];
                }
 
-               var r = parseFloat( jQuery.css( this.elem, this.prop ) );
-               return r && r > -10000 ? r : 0;
+               var parsed,
+                       r = jQuery.css( this.elem, this.prop );
+               // Empty strings, null, undefined and "auto" are converted to 0,
+               // complex values such as "rotate(1rad)" are returned as is,
+               // simple values such as "10px" are parsed to Float.
+               return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;
        },
 
        // Start an animation from one number to another
        custom: function( from, to, unit ) {
                var self = this,
-                       fx = jQuery.fx;
+                       fx = jQuery.fx,
+                       raf;
 
-               this.startTime = jQuery.now();
+               this.startTime = fxNow || createFxNow();
                this.start = from;
                this.end = to;
-               this.unit = unit || this.unit || "px";
+               this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
                this.now = this.start;
                this.pos = this.state = 0;
 
@@ -6643,7 +8351,20 @@ jQuery.fx.prototype = {
                t.elem = this.elem;
 
                if ( t() && jQuery.timers.push(t) && !timerId ) {
-                       timerId = setInterval(fx.tick, fx.interval);
+                       // Use requestAnimationFrame instead of setInterval if available
+                       if ( requestAnimationFrame ) {
+                               timerId = 1;
+                               raf = function() {
+                                       // When timerId gets set to null at any point, this stops
+                                       if ( timerId ) {
+                                               requestAnimationFrame( raf );
+                                               fx.tick();
+                                       }
+                               };
+                               requestAnimationFrame( raf );
+                       } else {
+                               timerId = setInterval( fx.tick, fx.interval );
+                       }
                }
        },
 
@@ -6674,60 +8395,64 @@ jQuery.fx.prototype = {
 
        // Each step of an animation
        step: function( gotoEnd ) {
-               var t = jQuery.now(), done = true;
+               var t = fxNow || createFxNow(),
+                       done = true,
+                       elem = this.elem,
+                       options = this.options,
+                       i, n;
 
-               if ( gotoEnd || t >= this.options.duration + this.startTime ) {
+               if ( gotoEnd || t >= options.duration + this.startTime ) {
                        this.now = this.end;
                        this.pos = this.state = 1;
                        this.update();
 
-                       this.options.curAnim[ this.prop ] = true;
+                       options.animatedProperties[ this.prop ] = true;
 
-                       for ( var i in this.options.curAnim ) {
-                               if ( this.options.curAnim[i] !== true ) {
+                       for ( i in options.animatedProperties ) {
+                               if ( options.animatedProperties[i] !== true ) {
                                        done = false;
                                }
                        }
 
                        if ( done ) {
                                // Reset the overflow
-                               if ( this.options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
-                                       var elem = this.elem,
-                                               options = this.options;
+                               if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
 
                                        jQuery.each( [ "", "X", "Y" ], function (index, value) {
                                                elem.style[ "overflow" + value ] = options.overflow[index];
-                                       } );
+                                       });
                                }
 
                                // Hide the element if the "hide" operation was done
-                               if ( this.options.hide ) {
-                                       jQuery(this.elem).hide();
+                               if ( options.hide ) {
+                                       jQuery(elem).hide();
                                }
 
                                // Reset the properties, if the item has been hidden or shown
-                               if ( this.options.hide || this.options.show ) {
-                                       for ( var p in this.options.curAnim ) {
-                                               jQuery.style( this.elem, p, this.options.orig[p] );
+                               if ( options.hide || options.show ) {
+                                       for ( var p in options.animatedProperties ) {
+                                               jQuery.style( elem, p, options.orig[p] );
                                        }
                                }
 
                                // Execute the complete function
-                               this.options.complete.call( this.elem );
+                               options.complete.call( elem );
                        }
 
                        return false;
 
                } else {
-                       var n = t - this.startTime;
-                       this.state = n / this.options.duration;
-
-                       // Perform the easing function, defaults to swing
-                       var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop];
-                       var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear");
-                       this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);
-                       this.now = this.start + ((this.end - this.start) * this.pos);
+                       // classical easing cannot be used with an Infinity duration
+                       if ( options.duration == Infinity ) {
+                               this.now = t;
+                       } else {
+                               n = t - this.startTime;
+                               this.state = n / options.duration;
 
+                               // Perform the easing function, defaults to swing
+                               this.pos = jQuery.easing[ options.animatedProperties[ this.prop ] ]( this.state, n, 0, 1, options.duration );
+                               this.now = this.start + ((this.end - this.start) * this.pos);
+                       }
                        // Perform the next step of the animation
                        this.update();
                }
@@ -6738,9 +8463,7 @@ jQuery.fx.prototype = {
 
 jQuery.extend( jQuery.fx, {
        tick: function() {
-               var timers = jQuery.timers;
-
-               for ( var i = 0; i < timers.length; i++ ) {
+               for ( var timers = jQuery.timers, i = 0 ; i < timers.length ; ++i ) {
                        if ( !timers[i]() ) {
                                timers.splice(i--, 1);
                        }
@@ -6788,17 +8511,45 @@ if ( jQuery.expr && jQuery.expr.filters ) {
        };
 }
 
+// Try to restore the default display value of an element
 function defaultDisplay( nodeName ) {
+
        if ( !elemdisplay[ nodeName ] ) {
-               var elem = jQuery("<" + nodeName + ">").appendTo("body"),
-                       display = elem.css("display");
+
+               var elem = jQuery( "<" + nodeName + ">" ).appendTo( "body" ),
+                       display = elem.css( "display" );
 
                elem.remove();
 
+               // If the simple way fails,
+               // get element's real default display by attaching it to a temp iframe
                if ( display === "none" || display === "" ) {
-                       display = "block";
+                       // No iframe to use yet, so create it
+                       if ( !iframe ) {
+                               iframe = document.createElement( "iframe" );
+                               iframe.frameBorder = iframe.width = iframe.height = 0;
+                       }
+
+                       document.body.appendChild( iframe );
+
+                       // Create a cacheable copy of the iframe document on first call.
+                       // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake html
+                       // document to it, Webkit & Firefox won't allow reusing the iframe document
+                       if ( !iframeDoc || !iframe.createElement ) {
+                               iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
+                               iframeDoc.write( "<!doctype><html><body></body></html>" );
+                       }
+
+                       elem = iframeDoc.createElement( nodeName );
+
+                       iframeDoc.body.appendChild( elem );
+
+                       display = jQuery.css( elem, "display" );
+
+                       document.body.removeChild( iframe );
                }
 
+               // Store the correct default display
                elemdisplay[ nodeName ] = display;
        }
 
@@ -6815,7 +8566,7 @@ if ( "getBoundingClientRect" in document.documentElement ) {
        jQuery.fn.offset = function( options ) {
                var elem = this[0], box;
 
-               if ( options ) { 
+               if ( options ) {
                        return this.each(function( i ) {
                                jQuery.offset.setOffset( this, options, i );
                        });
@@ -6838,15 +8589,15 @@ if ( "getBoundingClientRect" in document.documentElement ) {
 
                // Make sure we're not dealing with a disconnected DOM node
                if ( !box || !jQuery.contains( docElem, elem ) ) {
-                       return box || { top: 0, left: 0 };
+                       return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
                }
 
                var body = doc.body,
                        win = getWindow(doc),
                        clientTop  = docElem.clientTop  || body.clientTop  || 0,
                        clientLeft = docElem.clientLeft || body.clientLeft || 0,
-                       scrollTop  = (win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop ),
-                       scrollLeft = (win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft),
+                       scrollTop  = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop,
+                       scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
                        top  = box.top  + scrollTop  - clientTop,
                        left = box.left + scrollLeft - clientLeft;
 
@@ -6857,7 +8608,7 @@ if ( "getBoundingClientRect" in document.documentElement ) {
        jQuery.fn.offset = function( options ) {
                var elem = this[0];
 
-               if ( options ) { 
+               if ( options ) {
                        return this.each(function( i ) {
                                jQuery.offset.setOffset( this, options, i );
                        });
@@ -6959,7 +8710,6 @@ jQuery.offset = {
                this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
 
                body.removeChild( container );
-               body = container = innerDiv = checkDiv = table = td = null;
                jQuery.offset.initialize = jQuery.noop;
        },
 
@@ -6976,7 +8726,7 @@ jQuery.offset = {
 
                return { top: top, left: left };
        },
-       
+
        setOffset: function( elem, options, i ) {
                var position = jQuery.css( elem, "position" );
 
@@ -6989,17 +8739,19 @@ jQuery.offset = {
                        curOffset = curElem.offset(),
                        curCSSTop = jQuery.css( elem, "top" ),
                        curCSSLeft = jQuery.css( elem, "left" ),
-                       calculatePosition = (position === "absolute" && jQuery.inArray('auto', [curCSSTop, curCSSLeft]) > -1),
+                       calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
                        props = {}, curPosition = {}, curTop, curLeft;
 
-               // need to be able to calculate position if either top or left is auto and position is absolute
+               // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
                if ( calculatePosition ) {
                        curPosition = curElem.position();
+                       curTop = curPosition.top;
+                       curLeft = curPosition.left;
+               } else {
+                       curTop = parseFloat( curCSSTop ) || 0;
+                       curLeft = parseFloat( curCSSLeft ) || 0;
                }
 
-               curTop  = calculatePosition ? curPosition.top  : parseInt( curCSSTop,  10 ) || 0;
-               curLeft = calculatePosition ? curPosition.left : parseInt( curCSSLeft, 10 ) || 0;
-
                if ( jQuery.isFunction( options ) ) {
                        options = options.call( elem, i, curOffset );
                }
@@ -7010,7 +8762,7 @@ jQuery.offset = {
                if (options.left != null) {
                        props.left = (options.left - curOffset.left) + curLeft;
                }
-               
+
                if ( "using" in options ) {
                        options.using.call( elem, props );
                } else {
@@ -7068,29 +8820,16 @@ jQuery.fn.extend({
 jQuery.each( ["Left", "Top"], function( i, name ) {
        var method = "scroll" + name;
 
-       jQuery.fn[ method ] = function(val) {
-               var elem = this[0], win;
-               
-               if ( !elem ) {
-                       return null;
-               }
+       jQuery.fn[ method ] = function( val ) {
+               var elem, win;
 
-               if ( val !== undefined ) {
-                       // Set the scroll offset
-                       return this.each(function() {
-                               win = getWindow( this );
+               if ( val === undefined ) {
+                       elem = this[ 0 ];
 
-                               if ( win ) {
-                                       win.scrollTo(
-                                               !i ? val : jQuery(win).scrollLeft(),
-                                                i ? val : jQuery(win).scrollTop()
-                                       );
+                       if ( !elem ) {
+                               return null;
+                       }
 
-                               } else {
-                                       this[ method ] = val;
-                               }
-                       });
-               } else {
                        win = getWindow( elem );
 
                        // Return the scroll offset
@@ -7099,6 +8838,21 @@ jQuery.each( ["Left", "Top"], function( i, name ) {
                                        win.document.body[ method ] :
                                elem[ method ];
                }
+
+               // Set the scroll offset
+               return this.each(function() {
+                       win = getWindow( this );
+
+                       if ( win ) {
+                               win.scrollTo(
+                                       !i ? val : jQuery( win ).scrollLeft(),
+                                        i ? val : jQuery( win ).scrollTop()
+                               );
+
+                       } else {
+                               this[ method ] = val;
+                       }
+               });
        };
 });
 
@@ -7138,7 +8892,7 @@ jQuery.each([ "Height", "Width" ], function( i, name ) {
                if ( !elem ) {
                        return size == null ? null : this;
                }
-               
+
                if ( jQuery.isFunction( size ) ) {
                        return this.each(function( i ) {
                                var self = jQuery( this );
@@ -7148,8 +8902,10 @@ jQuery.each([ "Height", "Width" ], function( i, name ) {
 
                if ( jQuery.isWindow( elem ) ) {
                        // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
-                       return elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
-                               elem.document.body[ "client" + name ];
+                       // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
+                       var docElemProp = elem.document.documentElement[ "client" + name ];
+                       return elem.document.compatMode === "CSS1Compat" && docElemProp ||
+                               elem.document.body[ "client" + name ] || docElemProp;
 
                // Get document width or height
                } else if ( elem.nodeType === 9 ) {
@@ -7176,4 +8932,5 @@ jQuery.each([ "Height", "Width" ], function( i, name ) {
 });
 
 
+window.jQuery = window.$ = jQuery;
 })(window);
diff --git a/resources/jquery/jquery.qunit.completenessTest.js b/resources/jquery/jquery.qunit.completenessTest.js
new file mode 100644 (file)
index 0000000..5c26586
--- /dev/null
@@ -0,0 +1,223 @@
+/**
+ * jQuery QUnit CompletenessTest 0.3
+ *
+ * Tests the completeness of test suites for object oriented javascript
+ * libraries. Written to be used in enviroments with jQuery and QUnit.
+ * Requires jQuery 1.5.2 or higher.
+ *
+ * Globals: jQuery, $, QUnit, console.log
+ *
+ * Built for and tested with:
+ * - Safari 5
+ * - Firefox 4
+ *
+ * @author Timo Tijhof, 2011
+ */
+(function(){
+
+/* Private members */
+var TYPE_SIMPLEFUNC = 101;
+var TYPE_OBJCONSTRFUNC = 100;
+
+/**
+ * CompletenessTest
+ * @constructor
+ *
+ * @example
+ *  var myTester = new CompletenessTest( myLib );
+ * @param masterVariable {Object} The root variable that contains all object
+ *  members. CompletenessTest will recursively traverse objects and keep track
+ *  of all methods.
+ * @param ignoreFn {Function} Optionally pass a function to filter out certain
+ *  methods. Example: You may want to filter out instances of jQuery or some
+ *  other constructor. Otherwise "missingTests" will include all methods that
+ *  were not called from that instance.
+ */
+var CompletenessTest = function ( masterVariable, ignoreFn ) {
+
+       // Keep track in these objects. Keyed by strings with the
+       // method names (ie. 'my.foo', 'my.bar', etc.) values are boolean true.
+       this.methodCallTracker = {};
+       this.missingTests = {};
+
+       this.ignoreFn = undefined === ignoreFn ? function(){ return false; } : ignoreFn;
+
+       // Lazy limit in case something weird happends (like recurse (part of) ourself).
+       this.lazyLimit = 1000;
+       this.lazyCounter = 0;
+
+       // Bind begin and end to QUnit.
+       var that = this;
+       QUnit.begin = function(){
+               that.checkTests( null, masterVariable, masterVariable, [], CompletenessTest.ACTION_INJECT );
+       };
+       QUnit.done = function(){
+               that.checkTests( null, masterVariable, masterVariable, [], CompletenessTest.ACTION_CHECK );
+               console.log( 'CompletenessTest.ACTION_CHECK', that );
+
+               // Insert HTML into header
+
+               var makeList = function( blob, title, style ) {
+                       title = title || 'Values';
+                       var html = '<div style="'+style+'">'
+                       + '<strong>' + mw.html.escape(title) + '</strong>';
+                       $.each( blob, function( key ) {
+                               html += '<br />' + mw.html.escape(key);
+                       });
+                       return html + '<br /><br /><em>&mdash; CompletenessTest</em></div>';
+               };
+               if ( $.isEmptyObject( that.missingTests ) ) { 
+                       var testResults = makeList( { 'No missing tests!': true }, 'missingTests', 'background: #D2E0E6; color: #366097; padding:1em' );
+               } else {
+                       var testResults = makeList( that.missingTests, 'missingTests', 'background: #EE5757; color: black; padding: 1em' );
+               }
+               $( '#qunit-testrunner-toolbar' ).prepend( testResults );
+       };
+
+       return this;
+};
+
+/* Static members */
+CompletenessTest.ACTION_INJECT = 500;
+CompletenessTest.ACTION_CHECK = 501;
+
+/* Public methods */
+CompletenessTest.fn = CompletenessTest.prototype = {
+
+       /**
+        * CompletenessTest.fn.checkTests
+        *
+        * @param currName {String}
+        * @param currVar {mixed}
+        * @param masterVariable {Object}
+        * @param parentPathArray {Array}
+        * @param action {Number} What action is checkTests commanded to do ?
+        */
+       checkTests: function( currName, currVar, masterVariable, parentPathArray, action ) {
+
+               // Handle the lazy limit
+               this.lazyCounter++;
+               if ( this.lazyCounter > this.lazyLimit ) {
+                       console.log( 'CompletenessTest.fn.checkTests> Limit reached: ' + this.lazyCounter );
+                       return null;
+               }
+
+               var     type = $.type( currVar ),
+                       that = this;
+
+               // Hard ignores
+               if ( this.ignoreFn( currVar, that, parentPathArray ) ) {
+
+
+               // Functions
+               } else  if ( type === 'function' ) {
+
+                       /* CHECK MODE */
+
+                       if ( action === CompletenessTest.ACTION_CHECK ) {
+
+                               if ( !currVar.prototype || $.isEmptyObject( currVar.prototype ) ) {
+
+                                       that.hasTest( parentPathArray.join( '.' ) );
+
+                               // We don't support checking object constructors yet...
+                               } else {
+
+                                       // ...the prototypes are fine tho
+                                       $.each( currVar.prototype, function( key, value ) {
+
+                                               // Clone and brake reference to parentPathArray
+                                               var tmpPathArray = $.extend([], parentPathArray);
+                                               tmpPathArray.push('prototype'); tmpPathArray.push(key);
+
+                                               that.hasTest( tmpPathArray.join( '.' ) );
+                                       } );
+                               }
+
+                       /* INJET MODE */
+
+                       } else if ( action === CompletenessTest.ACTION_INJECT ) {
+
+                               if ( !currVar.prototype || $.isEmptyObject( currVar.prototype ) ) {
+
+                                       // Inject check
+                                       that.injectCheck( masterVariable, parentPathArray, function(){
+
+                                               that.methodCallTracker[ parentPathArray.join( '.' ) ] = true;
+
+                                       }, TYPE_SIMPLEFUNC );
+
+                               // We don't support checking object constructors yet...
+                               } else {
+
+                                       // ... the prototypes are fine tho
+                                       $.each( currVar.prototype, function( key, value ) {
+
+                                               // Clone and brake reference to parentPathArray
+                                               var tmpPathArray = $.extend([], parentPathArray);
+                                               tmpPathArray.push('prototype'); tmpPathArray.push(key);
+
+                                               that.checkTests( key, value, masterVariable, tmpPathArray, action );
+                                       } );
+                               }
+
+                       } //else { }
+
+               // Recursively. After all, this *is* the completness test
+               } else if ( type === 'object' ) {
+
+                       $.each( currVar, function( key, value ) {
+
+                               // Clone and brake reference to parentPathArray
+                               var tmpPathArray = $.extend([], parentPathArray);
+                               tmpPathArray.push(key);
+
+                               that.checkTests( key, value, masterVariable, tmpPathArray, action );
+
+                       } );
+
+               } // else { }
+
+               return 'End of checkTests';
+       },
+
+       /**
+        * CompletenessTest.fn.hasTest
+        *
+        * @param fnName {String}
+        */
+       hasTest: function( fnName ) {
+               if ( !(fnName in this.methodCallTracker) ) {
+                       this.missingTests[fnName] = true;
+               }
+       },
+
+       /**
+        * CompletenessTest.fn.injectCheck
+        *
+        * @param masterVariable {Object}
+        * @param objectPathArray {Array}
+        * @param injectFn {Function}
+        */
+       injectCheck: function( masterVariable, objectPathArray, injectFn, functionType ) {
+               var     prev,
+                       curr = masterVariable,
+                       lastMember;
+
+               $.each(objectPathArray, function(i, memberName){
+                       prev = curr;
+                       curr = prev[memberName];
+                       lastMember = memberName;
+               });
+
+               // Objects are by reference, members (unless objects) are not.
+               prev[lastMember] = function(){
+                       injectFn();
+                       return curr.apply(this, arguments );
+               };
+       }
+};
+
+window.CompletenessTest = CompletenessTest;
+
+})();
index f9e345b..60d8920 100644 (file)
             the following script will allow it to extract the results.
             Harmless otherwise. -->
        <script src="testswarm.inject.js"></script>
+
+       <!-- CompletenessTest -->
+       <script>
+               if ( QUnit.urlParams.completenesstest ) {
+                       document.write( '\x3Cscript src="../../resources/jquery/jquery.qunit.completenessTest.js">\x3C/script>' );
+                       document.write( '\x3Cscript src="jquery.qunit.completenessTest.config.js">\x3C/script>' );
+               }
+       </script>
 </head>
 <body>
        <h1 id="qunit-header">MediaWiki JavaScript Test Suite</h1>
diff --git a/tests/qunit/jquery.qunit.completenessTest.config.js b/tests/qunit/jquery.qunit.completenessTest.config.js
new file mode 100644 (file)
index 0000000..d3eefe2
--- /dev/null
@@ -0,0 +1,20 @@
+// Return true to ignore
+var mwTestIgnore = function( val, tester, funcPath ) {
+
+       // Don't record methods of the properties of mw.Map instances
+       // Because we're therefor skipping any injection for
+       // "new mw.Map()", manually set it to true here.
+       if ( val instanceof mw.Map ) {
+               tester.methodCallTracker['Map'] = true;
+               return true;
+       }
+
+       // Don't record methods of the properties of a jQuery object
+       if ( val instanceof $ ) {
+               return true;
+       }
+
+       return false;
+};
+
+var mwTester = new CompletenessTest( mw, mwTestIgnore );
index 2fd8452..8b65659 100644 (file)
@@ -16,7 +16,6 @@ test( '-- Initial check', function() {
 
 test( 'mw.Map', function() {
        expect(15);
-
        ok( mw.Map, 'mw.Map defined' );
 
        var     conf = new mw.Map(),
@@ -49,7 +48,7 @@ test( 'mw.Map', function() {
 
        strictEqual( conf.exists( 'foo' ), true, 'Map.exists returns boolean true if a key exists' );
        strictEqual( conf.exists( 'notExist' ), false, 'Map.exists returns boolean false if a key does not exists' );
-       strictEqual( conf.get() === conf.values, true, 'Map.get returns the entire values object by reference (if called without arguments)' );
+       strictEqual( conf.get(), conf.values, 'Map.get returns the entire values object by reference (if called without arguments)' );
 
        conf.set( 'globalMapChecker', 'Hi' );
 
@@ -107,7 +106,6 @@ test( 'mw.message & mw.messages', function() {
        strictEqual( goodbye.exists(), false, 'Message.exists returns false for inexisting messages' );
 
        equal( goodbye.toString(), '<goodbye>', 'Message.toString returns <key> if key does not exist' );
-
 });
 
 test( 'mw.msg', function() {
@@ -160,6 +158,7 @@ test( 'mw.loader', function() {
                // /sample/awesome.js declares the "mw.loader.testCallback" function
                // which contains a call to start() and ok()
                mw.loader.testCallback();
+               mw.loader.testCallback = undefined;
 
        }, function() {
                start();