d96debcd14389caa495208e2c2fa867935c25f6e
[ccsdk/features.git] /
1 /**
2  * Copyright 2010-2013 Ben Birch
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this software except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 /*!
17  * jQuery JavaScript Library v1.6.1
18  * http://jquery.com/
19  *
20  * Copyright 2011, John Resig
21  * Dual licensed under the MIT or GPL Version 2 licenses.
22  * http://jquery.org/license
23  *
24  * Includes Sizzle.js
25  * http://sizzlejs.com/
26  * Copyright 2011, The Dojo Foundation
27  * Released under the MIT, BSD, and GPL Licenses.
28  *
29  * Date: Thu May 12 15:04:36 2011 -0400
30  */
31 (function( window, undefined ) {
32
33 // Use the correct document accordingly with window argument (sandbox)
34 var document = window.document,
35         navigator = window.navigator,
36         location = window.location;
37 var jQuery = (function() {
38
39 // Define a local copy of jQuery
40 var jQuery = function( selector, context ) {
41                 // The jQuery object is actually just the init constructor 'enhanced'
42                 return new jQuery.fn.init( selector, context, rootjQuery );
43         },
44
45         // Map over jQuery in case of overwrite
46         _jQuery = window.jQuery,
47
48         // Map over the $ in case of overwrite
49         _$ = window.$,
50
51         // A central reference to the root jQuery(document)
52         rootjQuery,
53
54         // A simple way to check for HTML strings or ID strings
55         // (both of which we optimize for)
56         quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
57
58         // Check if a string has a non-whitespace character in it
59         rnotwhite = /\S/,
60
61         // Used for trimming whitespace
62         trimLeft = /^\s+/,
63         trimRight = /\s+$/,
64
65         // Check for digits
66         rdigit = /\d/,
67
68         // Match a standalone tag
69         rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
70
71         // JSON RegExp
72         rvalidchars = /^[\],:{}\s]*$/,
73         rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
74         rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
75         rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
76
77         // Useragent RegExp
78         rwebkit = /(webkit)[ \/]([\w.]+)/,
79         ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
80         rmsie = /(msie) ([\w.]+)/,
81         rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
82
83         // Keep a UserAgent string for use with jQuery.browser
84         userAgent = navigator.userAgent,
85
86         // For matching the engine and version of the browser
87         browserMatch,
88
89         // The deferred used on DOM ready
90         readyList,
91
92         // The ready event handler
93         DOMContentLoaded,
94
95         // Save a reference to some core methods
96         toString = Object.prototype.toString,
97         hasOwn = Object.prototype.hasOwnProperty,
98         push = Array.prototype.push,
99         slice = Array.prototype.slice,
100         trim = String.prototype.trim,
101         indexOf = Array.prototype.indexOf,
102
103         // [[Class]] -> type pairs
104         class2type = {};
105
106 jQuery.fn = jQuery.prototype = {
107         constructor: jQuery,
108         init: function( selector, context, rootjQuery ) {
109                 var match, elem, ret, doc;
110
111                 // Handle $(""), $(null), or $(undefined)
112                 if ( !selector ) {
113                         return this;
114                 }
115
116                 // Handle $(DOMElement)
117                 if ( selector.nodeType ) {
118                         this.context = this[0] = selector;
119                         this.length = 1;
120                         return this;
121                 }
122
123                 // The body element only exists once, optimize finding it
124                 if ( selector === "body" && !context && document.body ) {
125                         this.context = document;
126                         this[0] = document.body;
127                         this.selector = selector;
128                         this.length = 1;
129                         return this;
130                 }
131
132                 // Handle HTML strings
133                 if ( typeof selector === "string" ) {
134                         // Are we dealing with HTML string or an ID?
135                         if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
136                                 // Assume that strings that start and end with <> are HTML and skip the regex check
137                                 match = [ null, selector, null ];
138
139                         } else {
140                                 match = quickExpr.exec( selector );
141                         }
142
143                         // Verify a match, and that no context was specified for #id
144                         if ( match && (match[1] || !context) ) {
145
146                                 // HANDLE: $(html) -> $(array)
147                                 if ( match[1] ) {
148                                         context = context instanceof jQuery ? context[0] : context;
149                                         doc = (context ? context.ownerDocument || context : document);
150
151                                         // If a single string is passed in and it's a single tag
152                                         // just do a createElement and skip the rest
153                                         ret = rsingleTag.exec( selector );
154
155                                         if ( ret ) {
156                                                 if ( jQuery.isPlainObject( context ) ) {
157                                                         selector = [ document.createElement( ret[1] ) ];
158                                                         jQuery.fn.attr.call( selector, context, true );
159
160                                                 } else {
161                                                         selector = [ doc.createElement( ret[1] ) ];
162                                                 }
163
164                                         } else {
165                                                 ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
166                                                 selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
167                                         }
168
169                                         return jQuery.merge( this, selector );
170
171                                 // HANDLE: $("#id")
172                                 } else {
173                                         elem = document.getElementById( match[2] );
174
175                                         // Check parentNode to catch when Blackberry 4.6 returns
176                                         // nodes that are no longer in the document #6963
177                                         if ( elem && elem.parentNode ) {
178                                                 // Handle the case where IE and Opera return items
179                                                 // by name instead of ID
180                                                 if ( elem.id !== match[2] ) {
181                                                         return rootjQuery.find( selector );
182                                                 }
183
184                                                 // Otherwise, we inject the element directly into the jQuery object
185                                                 this.length = 1;
186                                                 this[0] = elem;
187                                         }
188
189                                         this.context = document;
190                                         this.selector = selector;
191                                         return this;
192                                 }
193
194                         // HANDLE: $(expr, $(...))
195                         } else if ( !context || context.jquery ) {
196                                 return (context || rootjQuery).find( selector );
197
198                         // HANDLE: $(expr, context)
199                         // (which is just equivalent to: $(context).find(expr)
200                         } else {
201                                 return this.constructor( context ).find( selector );
202                         }
203
204                 // HANDLE: $(function)
205                 // Shortcut for document ready
206                 } else if ( jQuery.isFunction( selector ) ) {
207                         return rootjQuery.ready( selector );
208                 }
209
210                 if (selector.selector !== undefined) {
211                         this.selector = selector.selector;
212                         this.context = selector.context;
213                 }
214
215                 return jQuery.makeArray( selector, this );
216         },
217
218         // Start with an empty selector
219         selector: "",
220
221         // The current version of jQuery being used
222         jquery: "1.6.1",
223
224         // The default length of a jQuery object is 0
225         length: 0,
226
227         // The number of elements contained in the matched element set
228         size: function() {
229                 return this.length;
230         },
231
232         toArray: function() {
233                 return slice.call( this, 0 );
234         },
235
236         // Get the Nth element in the matched element set OR
237         // Get the whole matched element set as a clean array
238         get: function( num ) {
239                 return num == null ?
240
241                         // Return a 'clean' array
242                         this.toArray() :
243
244                         // Return just the object
245                         ( num < 0 ? this[ this.length + num ] : this[ num ] );
246         },
247
248         // Take an array of elements and push it onto the stack
249         // (returning the new matched element set)
250         pushStack: function( elems, name, selector ) {
251                 // Build a new jQuery matched element set
252                 var ret = this.constructor();
253
254                 if ( jQuery.isArray( elems ) ) {
255                         push.apply( ret, elems );
256
257                 } else {
258                         jQuery.merge( ret, elems );
259                 }
260
261                 // Add the old object onto the stack (as a reference)
262                 ret.prevObject = this;
263
264                 ret.context = this.context;
265
266                 if ( name === "find" ) {
267                         ret.selector = this.selector + (this.selector ? " " : "") + selector;
268                 } else if ( name ) {
269                         ret.selector = this.selector + "." + name + "(" + selector + ")";
270                 }
271
272                 // Return the newly-formed element set
273                 return ret;
274         },
275
276         // Execute a callback for every element in the matched set.
277         // (You can seed the arguments with an array of args, but this is
278         // only used internally.)
279         each: function( callback, args ) {
280                 return jQuery.each( this, callback, args );
281         },
282
283         ready: function( fn ) {
284                 // Attach the listeners
285                 jQuery.bindReady();
286
287                 // Add the callback
288                 readyList.done( fn );
289
290                 return this;
291         },
292
293         eq: function( i ) {
294                 return i === -1 ?
295                         this.slice( i ) :
296                         this.slice( i, +i + 1 );
297         },
298
299         first: function() {
300                 return this.eq( 0 );
301         },
302
303         last: function() {
304                 return this.eq( -1 );
305         },
306
307         slice: function() {
308                 return this.pushStack( slice.apply( this, arguments ),
309                         "slice", slice.call(arguments).join(",") );
310         },
311
312         map: function( callback ) {
313                 return this.pushStack( jQuery.map(this, function( elem, i ) {
314                         return callback.call( elem, i, elem );
315                 }));
316         },
317
318         end: function() {
319                 return this.prevObject || this.constructor(null);
320         },
321
322         // For internal use only.
323         // Behaves like an Array's method, not like a jQuery method.
324         push: push,
325         sort: [].sort,
326         splice: [].splice
327 };
328
329 // Give the init function the jQuery prototype for later instantiation
330 jQuery.fn.init.prototype = jQuery.fn;
331
332 jQuery.extend = jQuery.fn.extend = function() {
333         var options, name, src, copy, copyIsArray, clone,
334                 target = arguments[0] || {},
335                 i = 1,
336                 length = arguments.length,
337                 deep = false;
338
339         // Handle a deep copy situation
340         if ( typeof target === "boolean" ) {
341                 deep = target;
342                 target = arguments[1] || {};
343                 // skip the boolean and the target
344                 i = 2;
345         }
346
347         // Handle case when target is a string or something (possible in deep copy)
348         if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
349                 target = {};
350         }
351
352         // extend jQuery itself if only one argument is passed
353         if ( length === i ) {
354                 target = this;
355                 --i;
356         }
357
358         for ( ; i < length; i++ ) {
359                 // Only deal with non-null/undefined values
360                 if ( (options = arguments[ i ]) != null ) {
361                         // Extend the base object
362                         for ( name in options ) {
363                                 src = target[ name ];
364                                 copy = options[ name ];
365
366                                 // Prevent never-ending loop
367                                 if ( target === copy ) {
368                                         continue;
369                                 }
370
371                                 // Recurse if we're merging plain objects or arrays
372                                 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
373                                         if ( copyIsArray ) {
374                                                 copyIsArray = false;
375                                                 clone = src && jQuery.isArray(src) ? src : [];
376
377                                         } else {
378                                                 clone = src && jQuery.isPlainObject(src) ? src : {};
379                                         }
380
381                                         // Never move original objects, clone them
382                                         target[ name ] = jQuery.extend( deep, clone, copy );
383
384                                 // Don't bring in undefined values
385                                 } else if ( copy !== undefined ) {
386                                         target[ name ] = copy;
387                                 }
388                         }
389                 }
390         }
391
392         // Return the modified object
393         return target;
394 };
395
396 jQuery.extend({
397         noConflict: function( deep ) {
398                 if ( window.$ === jQuery ) {
399                         window.$ = _$;
400                 }
401
402                 if ( deep && window.jQuery === jQuery ) {
403                         window.jQuery = _jQuery;
404                 }
405
406                 return jQuery;
407         },
408
409         // Is the DOM ready to be used? Set to true once it occurs.
410         isReady: false,
411
412         // A counter to track how many items to wait for before
413         // the ready event fires. See #6781
414         readyWait: 1,
415
416         // Hold (or release) the ready event
417         holdReady: function( hold ) {
418                 if ( hold ) {
419                         jQuery.readyWait++;
420                 } else {
421                         jQuery.ready( true );
422                 }
423         },
424
425         // Handle when the DOM is ready
426         ready: function( wait ) {
427                 // Either a released hold or an DOMready/load event and not yet ready
428                 if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
429                         // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
430                         if ( !document.body ) {
431                                 return setTimeout( jQuery.ready, 1 );
432                         }
433
434                         // Remember that the DOM is ready
435                         jQuery.isReady = true;
436
437                         // If a normal DOM Ready event fired, decrement, and wait if need be
438                         if ( wait !== true && --jQuery.readyWait > 0 ) {
439                                 return;
440                         }
441
442                         // If there are functions bound, to execute
443                         readyList.resolveWith( document, [ jQuery ] );
444
445                         // Trigger any bound ready events
446                         if ( jQuery.fn.trigger ) {
447                                 jQuery( document ).trigger( "ready" ).unbind( "ready" );
448                         }
449                 }
450         },
451
452         bindReady: function() {
453                 if ( readyList ) {
454                         return;
455                 }
456
457                 readyList = jQuery._Deferred();
458
459                 // Catch cases where $(document).ready() is called after the
460                 // browser event has already occurred.
461                 if ( document.readyState === "complete" ) {
462                         // Handle it asynchronously to allow scripts the opportunity to delay ready
463                         return setTimeout( jQuery.ready, 1 );
464                 }
465
466                 // Mozilla, Opera and webkit nightlies currently support this event
467                 if ( document.addEventListener ) {
468                         // Use the handy event callback
469                         document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
470
471                         // A fallback to window.onload, that will always work
472                         window.addEventListener( "load", jQuery.ready, false );
473
474                 // If IE event model is used
475                 } else if ( document.attachEvent ) {
476                         // ensure firing before onload,
477                         // maybe late but safe also for iframes
478                         document.attachEvent( "onreadystatechange", DOMContentLoaded );
479
480                         // A fallback to window.onload, that will always work
481                         window.attachEvent( "onload", jQuery.ready );
482
483                         // If IE and not a frame
484                         // continually check to see if the document is ready
485                         var toplevel = false;
486
487                         try {
488                                 toplevel = window.frameElement == null;
489                         } catch(e) {}
490
491                         if ( document.documentElement.doScroll && toplevel ) {
492                                 doScrollCheck();
493                         }
494                 }
495         },
496
497         // See test/unit/core.js for details concerning isFunction.
498         // Since version 1.3, DOM methods and functions like alert
499         // aren't supported. They return false on IE (#2968).
500         isFunction: function( obj ) {
501                 return jQuery.type(obj) === "function";
502         },
503
504         isArray: Array.isArray || function( obj ) {
505                 return jQuery.type(obj) === "array";
506         },
507
508         // A crude way of determining if an object is a window
509         isWindow: function( obj ) {
510                 return obj && typeof obj === "object" && "setInterval" in obj;
511         },
512
513         isNaN: function( obj ) {
514                 return obj == null || !rdigit.test( obj ) || isNaN( obj );
515         },
516
517         type: function( obj ) {
518                 return obj == null ?
519                         String( obj ) :
520                         class2type[ toString.call(obj) ] || "object";
521         },
522
523         isPlainObject: function( obj ) {
524                 // Must be an Object.
525                 // Because of IE, we also have to check the presence of the constructor property.
526                 // Make sure that DOM nodes and window objects don't pass through, as well
527                 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
528                         return false;
529                 }
530
531                 // Not own constructor property must be Object
532                 if ( obj.constructor &&
533                         !hasOwn.call(obj, "constructor") &&
534                         !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
535                         return false;
536                 }
537
538                 // Own properties are enumerated firstly, so to speed up,
539                 // if last one is own, then all properties are own.
540
541                 var key;
542                 for ( key in obj ) {}
543
544                 return key === undefined || hasOwn.call( obj, key );
545         },
546
547         isEmptyObject: function( obj ) {
548                 for ( var name in obj ) {
549                         return false;
550                 }
551                 return true;
552         },
553
554         error: function( msg ) {
555                 throw msg;
556         },
557
558         parseJSON: function( data ) {
559                 if ( typeof data !== "string" || !data ) {
560                         return null;
561                 }
562
563                 // Make sure leading/trailing whitespace is removed (IE can't handle it)
564                 data = jQuery.trim( data );
565
566                 // Attempt to parse using the native JSON parser first
567                 if ( window.JSON && window.JSON.parse ) {
568                         return window.JSON.parse( data );
569                 }
570
571                 // Make sure the incoming data is actual JSON
572                 // Logic borrowed from http://json.org/json2.js
573                 if ( rvalidchars.test( data.replace( rvalidescape, "@" )
574                         .replace( rvalidtokens, "]" )
575                         .replace( rvalidbraces, "")) ) {
576
577                         return (new Function( "return " + data ))();
578
579                 }
580                 jQuery.error( "Invalid JSON: " + data );
581         },
582
583         // Cross-browser xml parsing
584         // (xml & tmp used internally)
585         parseXML: function( data , xml , tmp ) {
586
587                 if ( window.DOMParser ) { // Standard
588                         tmp = new DOMParser();
589                         xml = tmp.parseFromString( data , "text/xml" );
590                 } else { // IE
591                         xml = new ActiveXObject( "Microsoft.XMLDOM" );
592                         xml.async = "false";
593                         xml.loadXML( data );
594                 }
595
596                 tmp = xml.documentElement;
597
598                 if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) {
599                         jQuery.error( "Invalid XML: " + data );
600                 }
601
602                 return xml;
603         },
604
605         noop: function() {},
606
607         // Evaluates a script in a global context
608         // Workarounds based on findings by Jim Driscoll
609         // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
610         globalEval: function( data ) {
611                 if ( data && rnotwhite.test( data ) ) {
612                         // We use execScript on Internet Explorer
613                         // We use an anonymous function so that context is window
614                         // rather than jQuery in Firefox
615                         ( window.execScript || function( data ) {
616                                 window[ "eval" ].call( window, data );
617                         } )( data );
618                 }
619         },
620
621         nodeName: function( elem, name ) {
622                 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
623         },
624
625         // args is for internal usage only
626         each: function( object, callback, args ) {
627                 var name, i = 0,
628                         length = object.length,
629                         isObj = length === undefined || jQuery.isFunction( object );
630
631                 if ( args ) {
632                         if ( isObj ) {
633                                 for ( name in object ) {
634                                         if ( callback.apply( object[ name ], args ) === false ) {
635                                                 break;
636                                         }
637                                 }
638                         } else {
639                                 for ( ; i < length; ) {
640                                         if ( callback.apply( object[ i++ ], args ) === false ) {
641                                                 break;
642                                         }
643                                 }
644                         }
645
646                 // A special, fast, case for the most common use of each
647                 } else {
648                         if ( isObj ) {
649                                 for ( name in object ) {
650                                         if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
651                                                 break;
652                                         }
653                                 }
654                         } else {
655                                 for ( ; i < length; ) {
656                                         if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
657                                                 break;
658                                         }
659                                 }
660                         }
661                 }
662
663                 return object;
664         },
665
666         // Use native String.trim function wherever possible
667         trim: trim ?
668                 function( text ) {
669                         return text == null ?
670                                 "" :
671                                 trim.call( text );
672                 } :
673
674                 // Otherwise use our own trimming functionality
675                 function( text ) {
676                         return text == null ?
677                                 "" :
678                                 text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
679                 },
680
681         // results is for internal usage only
682         makeArray: function( array, results ) {
683                 var ret = results || [];
684
685                 if ( array != null ) {
686                         // The window, strings (and functions) also have 'length'
687                         // The extra typeof function check is to prevent crashes
688                         // in Safari 2 (See: #3039)
689                         // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
690                         var type = jQuery.type( array );
691
692                         if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
693                                 push.call( ret, array );
694                         } else {
695                                 jQuery.merge( ret, array );
696                         }
697                 }
698
699                 return ret;
700         },
701
702         inArray: function( elem, array ) {
703
704                 if ( indexOf ) {
705                         return indexOf.call( array, elem );
706                 }
707
708                 for ( var i = 0, length = array.length; i < length; i++ ) {
709                         if ( array[ i ] === elem ) {
710                                 return i;
711                         }
712                 }
713
714                 return -1;
715         },
716
717         merge: function( first, second ) {
718                 var i = first.length,
719                         j = 0;
720
721                 if ( typeof second.length === "number" ) {
722                         for ( var l = second.length; j < l; j++ ) {
723                                 first[ i++ ] = second[ j ];
724                         }
725
726                 } else {
727                         while ( second[j] !== undefined ) {
728                                 first[ i++ ] = second[ j++ ];
729                         }
730                 }
731
732                 first.length = i;
733
734                 return first;
735         },
736
737         grep: function( elems, callback, inv ) {
738                 var ret = [], retVal;
739                 inv = !!inv;
740
741                 // Go through the array, only saving the items
742                 // that pass the validator function
743                 for ( var i = 0, length = elems.length; i < length; i++ ) {
744                         retVal = !!callback( elems[ i ], i );
745                         if ( inv !== retVal ) {
746                                 ret.push( elems[ i ] );
747                         }
748                 }
749
750                 return ret;
751         },
752
753         // arg is for internal usage only
754         map: function( elems, callback, arg ) {
755                 var value, key, ret = [],
756                         i = 0,
757                         length = elems.length,
758                         // jquery objects are treated as arrays
759                         isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
760
761                 // Go through the array, translating each of the items to their
762                 if ( isArray ) {
763                         for ( ; i < length; i++ ) {
764                                 value = callback( elems[ i ], i, arg );
765
766                                 if ( value != null ) {
767                                         ret[ ret.length ] = value;
768                                 }
769                         }
770
771                 // Go through every key on the object,
772                 } else {
773                         for ( key in elems ) {
774                                 value = callback( elems[ key ], key, arg );
775
776                                 if ( value != null ) {
777                                         ret[ ret.length ] = value;
778                                 }
779                         }
780                 }
781
782                 // Flatten any nested arrays
783                 return ret.concat.apply( [], ret );
784         },
785
786         // A global GUID counter for objects
787         guid: 1,
788
789         // Bind a function to a context, optionally partially applying any
790         // arguments.
791         proxy: function( fn, context ) {
792                 if ( typeof context === "string" ) {
793                         var tmp = fn[ context ];
794                         context = fn;
795                         fn = tmp;
796                 }
797
798                 // Quick check to determine if target is callable, in the spec
799                 // this throws a TypeError, but we will just return undefined.
800                 if ( !jQuery.isFunction( fn ) ) {
801                         return undefined;
802                 }
803
804                 // Simulated bind
805                 var args = slice.call( arguments, 2 ),
806                         proxy = function() {
807                                 return fn.apply( context, args.concat( slice.call( arguments ) ) );
808                         };
809
810                 // Set the guid of unique handler to the same of original handler, so it can be removed
811                 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
812
813                 return proxy;
814         },
815
816         // Mutifunctional method to get and set values to a collection
817         // The value/s can be optionally by executed if its a function
818         access: function( elems, key, value, exec, fn, pass ) {
819                 var length = elems.length;
820
821                 // Setting many attributes
822                 if ( typeof key === "object" ) {
823                         for ( var k in key ) {
824                                 jQuery.access( elems, k, key[k], exec, fn, value );
825                         }
826                         return elems;
827                 }
828
829                 // Setting one attribute
830                 if ( value !== undefined ) {
831                         // Optionally, function values get executed if exec is true
832                         exec = !pass && exec && jQuery.isFunction(value);
833
834                         for ( var i = 0; i < length; i++ ) {
835                                 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
836                         }
837
838                         return elems;
839                 }
840
841                 // Getting an attribute
842                 return length ? fn( elems[0], key ) : undefined;
843         },
844
845         now: function() {
846                 return (new Date()).getTime();
847         },
848
849         // Use of jQuery.browser is frowned upon.
850         // More details: http://docs.jquery.com/Utilities/jQuery.browser
851         uaMatch: function( ua ) {
852                 ua = ua.toLowerCase();
853
854                 var match = rwebkit.exec( ua ) ||
855                         ropera.exec( ua ) ||
856                         rmsie.exec( ua ) ||
857                         ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
858                         [];
859
860                 return { browser: match[1] || "", version: match[2] || "0" };
861         },
862
863         sub: function() {
864                 function jQuerySub( selector, context ) {
865                         return new jQuerySub.fn.init( selector, context );
866                 }
867                 jQuery.extend( true, jQuerySub, this );
868                 jQuerySub.superclass = this;
869                 jQuerySub.fn = jQuerySub.prototype = this();
870                 jQuerySub.fn.constructor = jQuerySub;
871                 jQuerySub.sub = this.sub;
872                 jQuerySub.fn.init = function init( selector, context ) {
873                         if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
874                                 context = jQuerySub( context );
875                         }
876
877                         return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
878                 };
879                 jQuerySub.fn.init.prototype = jQuerySub.fn;
880                 var rootjQuerySub = jQuerySub(document);
881                 return jQuerySub;
882         },
883
884         browser: {}
885 });
886
887 // Populate the class2type map
888 jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
889         class2type[ "[object " + name + "]" ] = name.toLowerCase();
890 });
891
892 browserMatch = jQuery.uaMatch( userAgent );
893 if ( browserMatch.browser ) {
894         jQuery.browser[ browserMatch.browser ] = true;
895         jQuery.browser.version = browserMatch.version;
896 }
897
898 // Deprecated, use jQuery.browser.webkit instead
899 if ( jQuery.browser.webkit ) {
900         jQuery.browser.safari = true;
901 }
902
903 // IE doesn't match non-breaking spaces with \s
904 if ( rnotwhite.test( "\xA0" ) ) {
905         trimLeft = /^[\s\xA0]+/;
906         trimRight = /[\s\xA0]+$/;
907 }
908
909 // All jQuery objects should point back to these
910 rootjQuery = jQuery(document);
911
912 // Cleanup functions for the document ready method
913 if ( document.addEventListener ) {
914         DOMContentLoaded = function() {
915                 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
916                 jQuery.ready();
917         };
918
919 } else if ( document.attachEvent ) {
920         DOMContentLoaded = function() {
921                 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
922                 if ( document.readyState === "complete" ) {
923                         document.detachEvent( "onreadystatechange", DOMContentLoaded );
924                         jQuery.ready();
925                 }
926         };
927 }
928
929 // The DOM ready check for Internet Explorer
930 function doScrollCheck() {
931         if ( jQuery.isReady ) {
932                 return;
933         }
934
935         try {
936                 // If IE is used, use the trick by Diego Perini
937                 // http://javascript.nwbox.com/IEContentLoaded/
938                 document.documentElement.doScroll("left");
939         } catch(e) {
940                 setTimeout( doScrollCheck, 1 );
941                 return;
942         }
943
944         // and execute any waiting functions
945         jQuery.ready();
946 }
947
948 // Expose jQuery to the global object
949 return jQuery;
950
951 })();
952
953
954 var // Promise methods
955         promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ),
956         // Static reference to slice
957         sliceDeferred = [].slice;
958
959 jQuery.extend({
960         // Create a simple deferred (one callbacks list)
961         _Deferred: function() {
962                 var // callbacks list
963                         callbacks = [],
964                         // stored [ context , args ]
965                         fired,
966                         // to avoid firing when already doing so
967                         firing,
968                         // flag to know if the deferred has been cancelled
969                         cancelled,
970                         // the deferred itself
971                         deferred  = {
972
973                                 // done( f1, f2, ...)
974                                 done: function() {
975                                         if ( !cancelled ) {
976                                                 var args = arguments,
977                                                         i,
978                                                         length,
979                                                         elem,
980                                                         type,
981                                                         _fired;
982                                                 if ( fired ) {
983                                                         _fired = fired;
984                                                         fired = 0;
985                                                 }
986                                                 for ( i = 0, length = args.length; i < length; i++ ) {
987                                                         elem = args[ i ];
988                                                         type = jQuery.type( elem );
989                                                         if ( type === "array" ) {
990                                                                 deferred.done.apply( deferred, elem );
991                                                         } else if ( type === "function" ) {
992                                                                 callbacks.push( elem );
993                                                         }
994                                                 }
995                                                 if ( _fired ) {
996                                                         deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
997                                                 }
998                                         }
999                                         return this;
1000                                 },
1001
1002                                 // resolve with given context and args
1003                                 resolveWith: function( context, args ) {
1004                                         if ( !cancelled && !fired && !firing ) {
1005                                                 // make sure args are available (#8421)
1006                                                 args = args || [];
1007                                                 firing = 1;
1008                                                 try {
1009                                                         while( callbacks[ 0 ] ) {
1010                                                                 callbacks.shift().apply( context, args );
1011                                                         }
1012                                                 }
1013                                                 finally {
1014                                                         fired = [ context, args ];
1015                                                         firing = 0;
1016                                                 }
1017                                         }
1018                                         return this;
1019                                 },
1020
1021                                 // resolve with this as context and given arguments
1022                                 resolve: function() {
1023                                         deferred.resolveWith( this, arguments );
1024                                         return this;
1025                                 },
1026
1027                                 // Has this deferred been resolved?
1028                                 isResolved: function() {
1029                                         return !!( firing || fired );
1030                                 },
1031
1032                                 // Cancel
1033                                 cancel: function() {
1034                                         cancelled = 1;
1035                                         callbacks = [];
1036                                         return this;
1037                                 }
1038                         };
1039
1040                 return deferred;
1041         },
1042
1043         // Full fledged deferred (two callbacks list)
1044         Deferred: function( func ) {
1045                 var deferred = jQuery._Deferred(),
1046                         failDeferred = jQuery._Deferred(),
1047                         promise;
1048                 // Add errorDeferred methods, then and promise
1049                 jQuery.extend( deferred, {
1050                         then: function( doneCallbacks, failCallbacks ) {
1051                                 deferred.done( doneCallbacks ).fail( failCallbacks );
1052                                 return this;
1053                         },
1054                         always: function() {
1055                                 return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );
1056                         },
1057                         fail: failDeferred.done,
1058                         rejectWith: failDeferred.resolveWith,
1059                         reject: failDeferred.resolve,
1060                         isRejected: failDeferred.isResolved,
1061                         pipe: function( fnDone, fnFail ) {
1062                                 return jQuery.Deferred(function( newDefer ) {
1063                                         jQuery.each( {
1064                                                 done: [ fnDone, "resolve" ],
1065                                                 fail: [ fnFail, "reject" ]
1066                                         }, function( handler, data ) {
1067                                                 var fn = data[ 0 ],
1068                                                         action = data[ 1 ],
1069                                                         returned;
1070                                                 if ( jQuery.isFunction( fn ) ) {
1071                                                         deferred[ handler ](function() {
1072                                                                 returned = fn.apply( this, arguments );
1073                                                                 if ( returned && jQuery.isFunction( returned.promise ) ) {
1074                                                                         returned.promise().then( newDefer.resolve, newDefer.reject );
1075                                                                 } else {
1076                                                                         newDefer[ action ]( returned );
1077                                                                 }
1078                                                         });
1079                                                 } else {
1080                                                         deferred[ handler ]( newDefer[ action ] );
1081                                                 }
1082                                         });
1083                                 }).promise();
1084                         },
1085                         // Get a promise for this deferred
1086                         // If obj is provided, the promise aspect is added to the object
1087                         promise: function( obj ) {
1088                                 if ( obj == null ) {
1089                                         if ( promise ) {
1090                                                 return promise;
1091                                         }
1092                                         promise = obj = {};
1093                                 }
1094                                 var i = promiseMethods.length;
1095                                 while( i-- ) {
1096                                         obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];
1097                                 }
1098                                 return obj;
1099                         }
1100                 });
1101                 // Make sure only one callback list will be used
1102                 deferred.done( failDeferred.cancel ).fail( deferred.cancel );
1103                 // Unexpose cancel
1104                 delete deferred.cancel;
1105                 // Call given func if any
1106                 if ( func ) {
1107                         func.call( deferred, deferred );
1108                 }
1109                 return deferred;
1110         },
1111
1112         // Deferred helper
1113         when: function( firstParam ) {
1114                 var args = arguments,
1115                         i = 0,
1116                         length = args.length,
1117                         count = length,
1118                         deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
1119                                 firstParam :
1120                                 jQuery.Deferred();
1121                 function resolveFunc( i ) {
1122                         return function( value ) {
1123                                 args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
1124                                 if ( !( --count ) ) {
1125                                         // Strange bug in FF4:
1126                                         // Values changed onto the arguments object sometimes end up as undefined values
1127                                         // outside the $.when method. Cloning the object into a fresh array solves the issue
1128                                         deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );
1129                                 }
1130                         };
1131                 }
1132                 if ( length > 1 ) {
1133                         for( ; i < length; i++ ) {
1134                                 if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {
1135                                         args[ i ].promise().then( resolveFunc(i), deferred.reject );
1136                                 } else {
1137                                         --count;
1138                                 }
1139                         }
1140                         if ( !count ) {
1141                                 deferred.resolveWith( deferred, args );
1142                         }
1143                 } else if ( deferred !== firstParam ) {
1144                         deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
1145                 }
1146                 return deferred.promise();
1147         }
1148 });
1149
1150
1151
1152 jQuery.support = (function() {
1153
1154         var div = document.createElement( "div" ),
1155                 documentElement = document.documentElement,
1156                 all,
1157                 a,
1158                 select,
1159                 opt,
1160                 input,
1161                 marginDiv,
1162                 support,
1163                 fragment,
1164                 body,
1165                 bodyStyle,
1166                 tds,
1167                 events,
1168                 eventName,
1169                 i,
1170                 isSupported;
1171
1172         // Preliminary tests
1173         div.setAttribute("className", "t");
1174         div.innerHTML = "   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
1175
1176         all = div.getElementsByTagName( "*" );
1177         a = div.getElementsByTagName( "a" )[ 0 ];
1178
1179         // Can't get basic test support
1180         if ( !all || !all.length || !a ) {
1181                 return {};
1182         }
1183
1184         // First batch of supports tests
1185         select = document.createElement( "select" );
1186         opt = select.appendChild( document.createElement("option") );
1187         input = div.getElementsByTagName( "input" )[ 0 ];
1188
1189         support = {
1190                 // IE strips leading whitespace when .innerHTML is used
1191                 leadingWhitespace: ( div.firstChild.nodeType === 3 ),
1192
1193                 // Make sure that tbody elements aren't automatically inserted
1194                 // IE will insert them into empty tables
1195                 tbody: !div.getElementsByTagName( "tbody" ).length,
1196
1197                 // Make sure that link elements get serialized correctly by innerHTML
1198                 // This requires a wrapper element in IE
1199                 htmlSerialize: !!div.getElementsByTagName( "link" ).length,
1200
1201                 // Get the style information from getAttribute
1202                 // (IE uses .cssText instead)
1203                 style: /top/.test( a.getAttribute("style") ),
1204
1205                 // Make sure that URLs aren't manipulated
1206                 // (IE normalizes it by default)
1207                 hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
1208
1209                 // Make sure that element opacity exists
1210                 // (IE uses filter instead)
1211                 // Use a regex to work around a WebKit issue. See #5145
1212                 opacity: /^0.55$/.test( a.style.opacity ),
1213
1214                 // Verify style float existence
1215                 // (IE uses styleFloat instead of cssFloat)
1216                 cssFloat: !!a.style.cssFloat,
1217
1218                 // Make sure that if no value is specified for a checkbox
1219                 // that it defaults to "on".
1220                 // (WebKit defaults to "" instead)
1221                 checkOn: ( input.value === "on" ),
1222
1223                 // Make sure that a selected-by-default option has a working selected property.
1224                 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
1225                 optSelected: opt.selected,
1226
1227                 // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
1228                 getSetAttribute: div.className !== "t",
1229
1230                 // Will be defined later
1231                 submitBubbles: true,
1232                 changeBubbles: true,
1233                 focusinBubbles: false,
1234                 deleteExpando: true,
1235                 noCloneEvent: true,
1236                 inlineBlockNeedsLayout: false,
1237                 shrinkWrapBlocks: false,
1238                 reliableMarginRight: true
1239         };
1240
1241         // Make sure checked status is properly cloned
1242         input.checked = true;
1243         support.noCloneChecked = input.cloneNode( true ).checked;
1244
1245         // Make sure that the options inside disabled selects aren't marked as disabled
1246         // (WebKit marks them as disabled)
1247         select.disabled = true;
1248         support.optDisabled = !opt.disabled;
1249
1250         // Test to see if it's possible to delete an expando from an element
1251         // Fails in Internet Explorer
1252         try {
1253                 delete div.test;
1254         } catch( e ) {
1255                 support.deleteExpando = false;
1256         }
1257
1258         if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
1259                 div.attachEvent( "onclick", function click() {
1260                         // Cloning a node shouldn't copy over any
1261                         // bound event handlers (IE does this)
1262                         support.noCloneEvent = false;
1263                         div.detachEvent( "onclick", click );
1264                 });
1265                 div.cloneNode( true ).fireEvent( "onclick" );
1266         }
1267
1268         // Check if a radio maintains it's value
1269         // after being appended to the DOM
1270         input = document.createElement("input");
1271         input.value = "t";
1272         input.setAttribute("type", "radio");
1273         support.radioValue = input.value === "t";
1274
1275         input.setAttribute("checked", "checked");
1276         div.appendChild( input );
1277         fragment = document.createDocumentFragment();
1278         fragment.appendChild( div.firstChild );
1279
1280         // WebKit doesn't clone checked state correctly in fragments
1281         support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
1282
1283         div.innerHTML = "";
1284
1285         // Figure out if the W3C box model works as expected
1286         div.style.width = div.style.paddingLeft = "1px";
1287
1288         // We use our own, invisible, body
1289         body = document.createElement( "body" );
1290         bodyStyle = {
1291                 visibility: "hidden",
1292                 width: 0,
1293                 height: 0,
1294                 border: 0,
1295                 margin: 0,
1296                 // Set background to avoid IE crashes when removing (#9028)
1297                 background: "none"
1298         };
1299         for ( i in bodyStyle ) {
1300                 body.style[ i ] = bodyStyle[ i ];
1301         }
1302         body.appendChild( div );
1303         documentElement.insertBefore( body, documentElement.firstChild );
1304
1305         // Check if a disconnected checkbox will retain its checked
1306         // value of true after appended to the DOM (IE6/7)
1307         support.appendChecked = input.checked;
1308
1309         support.boxModel = div.offsetWidth === 2;
1310
1311         if ( "zoom" in div.style ) {
1312                 // Check if natively block-level elements act like inline-block
1313                 // elements when setting their display to 'inline' and giving
1314                 // them layout
1315                 // (IE < 8 does this)
1316                 div.style.display = "inline";
1317                 div.style.zoom = 1;
1318                 support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
1319
1320                 // Check if elements with layout shrink-wrap their children
1321                 // (IE 6 does this)
1322                 div.style.display = "";
1323                 div.innerHTML = "<div style='width:4px;'></div>";
1324                 support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
1325         }
1326
1327         div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
1328         tds = div.getElementsByTagName( "td" );
1329
1330         // Check if table cells still have offsetWidth/Height when they are set
1331         // to display:none and there are still other visible table cells in a
1332         // table row; if so, offsetWidth/Height are not reliable for use when
1333         // determining if an element has been hidden directly using
1334         // display:none (it is still safe to use offsets if a parent element is
1335         // hidden; don safety goggles and see bug #4512 for more information).
1336         // (only IE 8 fails this test)
1337         isSupported = ( tds[ 0 ].offsetHeight === 0 );
1338
1339         tds[ 0 ].style.display = "";
1340         tds[ 1 ].style.display = "none";
1341
1342         // Check if empty table cells still have offsetWidth/Height
1343         // (IE < 8 fail this test)
1344         support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
1345         div.innerHTML = "";
1346
1347         // Check if div with explicit width and no margin-right incorrectly
1348         // gets computed margin-right based on width of container. For more
1349         // info see bug #3333
1350         // Fails in WebKit before Feb 2011 nightlies
1351         // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
1352         if ( document.defaultView && document.defaultView.getComputedStyle ) {
1353                 marginDiv = document.createElement( "div" );
1354                 marginDiv.style.width = "0";
1355                 marginDiv.style.marginRight = "0";
1356                 div.appendChild( marginDiv );
1357                 support.reliableMarginRight =
1358                         ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
1359         }
1360
1361         // Remove the body element we added
1362         body.innerHTML = "";
1363         documentElement.removeChild( body );
1364
1365         // Technique from Juriy Zaytsev
1366         // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
1367         // We only care about the case where non-standard event systems
1368         // are used, namely in IE. Short-circuiting here helps us to
1369         // avoid an eval call (in setAttribute) which can cause CSP
1370         // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
1371         if ( div.attachEvent ) {
1372                 for( i in {
1373                         submit: 1,
1374                         change: 1,
1375                         focusin: 1
1376                 } ) {
1377                         eventName = "on" + i;
1378                         isSupported = ( eventName in div );
1379                         if ( !isSupported ) {
1380                                 div.setAttribute( eventName, "return;" );
1381                                 isSupported = ( typeof div[ eventName ] === "function" );
1382                         }
1383                         support[ i + "Bubbles" ] = isSupported;
1384                 }
1385         }
1386
1387         return support;
1388 })();
1389
1390 // Keep track of boxModel
1391 jQuery.boxModel = jQuery.support.boxModel;
1392
1393
1394
1395
1396 var rbrace = /^(?:\{.*\}|\[.*\])$/,
1397         rmultiDash = /([a-z])([A-Z])/g;
1398
1399 jQuery.extend({
1400         cache: {},
1401
1402         // Please use with caution
1403         uuid: 0,
1404
1405         // Unique for each copy of jQuery on the page
1406         // Non-digits removed to match rinlinejQuery
1407         expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
1408
1409         // The following elements throw uncatchable exceptions if you
1410         // attempt to add expando properties to them.
1411         noData: {
1412                 "embed": true,
1413                 // Ban all objects except for Flash (which handle expandos)
1414                 "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1415                 "applet": true
1416         },
1417
1418         hasData: function( elem ) {
1419                 elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
1420
1421                 return !!elem && !isEmptyDataObject( elem );
1422         },
1423
1424         data: function( elem, name, data, pvt /* Internal Use Only */ ) {
1425                 if ( !jQuery.acceptData( elem ) ) {
1426                         return;
1427                 }
1428
1429                 var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache,
1430
1431                         // We have to handle DOM nodes and JS objects differently because IE6-7
1432                         // can't GC object references properly across the DOM-JS boundary
1433                         isNode = elem.nodeType,
1434
1435                         // Only DOM nodes need the global jQuery cache; JS object data is
1436                         // attached directly to the object so GC can occur automatically
1437                         cache = isNode ? jQuery.cache : elem,
1438
1439                         // Only defining an ID for JS objects if its cache already exists allows
1440                         // the code to shortcut on the same path as a DOM node with no cache
1441                         id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;
1442
1443                 // Avoid doing any more work than we need to when trying to get data on an
1444                 // object that has no data at all
1445                 if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) {
1446                         return;
1447                 }
1448
1449                 if ( !id ) {
1450                         // Only DOM nodes need a new unique ID for each element since their data
1451                         // ends up in the global cache
1452                         if ( isNode ) {
1453                                 elem[ jQuery.expando ] = id = ++jQuery.uuid;
1454                         } else {
1455                                 id = jQuery.expando;
1456                         }
1457                 }
1458
1459                 if ( !cache[ id ] ) {
1460                         cache[ id ] = {};
1461
1462                         // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
1463                         // metadata on plain JS objects when the object is serialized using
1464                         // JSON.stringify
1465                         if ( !isNode ) {
1466                                 cache[ id ].toJSON = jQuery.noop;
1467                         }
1468                 }
1469
1470                 // An object can be passed to jQuery.data instead of a key/value pair; this gets
1471                 // shallow copied over onto the existing cache
1472                 if ( typeof name === "object" || typeof name === "function" ) {
1473                         if ( pvt ) {
1474                                 cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);
1475                         } else {
1476                                 cache[ id ] = jQuery.extend(cache[ id ], name);
1477                         }
1478                 }
1479
1480                 thisCache = cache[ id ];
1481
1482                 // Internal jQuery data is stored in a separate object inside the object's data
1483                 // cache in order to avoid key collisions between internal data and user-defined
1484                 // data
1485                 if ( pvt ) {
1486                         if ( !thisCache[ internalKey ] ) {
1487                                 thisCache[ internalKey ] = {};
1488                         }
1489
1490                         thisCache = thisCache[ internalKey ];
1491                 }
1492
1493                 if ( data !== undefined ) {
1494                         thisCache[ jQuery.camelCase( name ) ] = data;
1495                 }
1496
1497                 // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should
1498                 // not attempt to inspect the internal events object using jQuery.data, as this
1499                 // internal data object is undocumented and subject to change.
1500                 if ( name === "events" && !thisCache[name] ) {
1501                         return thisCache[ internalKey ] && thisCache[ internalKey ].events;
1502                 }
1503
1504                 return getByName ? thisCache[ jQuery.camelCase( name ) ] : thisCache;
1505         },
1506
1507         removeData: function( elem, name, pvt /* Internal Use Only */ ) {
1508                 if ( !jQuery.acceptData( elem ) ) {
1509                         return;
1510                 }
1511
1512                 var internalKey = jQuery.expando, isNode = elem.nodeType,
1513
1514                         // See jQuery.data for more information
1515                         cache = isNode ? jQuery.cache : elem,
1516
1517                         // See jQuery.data for more information
1518                         id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
1519
1520                 // If there is already no cache entry for this object, there is no
1521                 // purpose in continuing
1522                 if ( !cache[ id ] ) {
1523                         return;
1524                 }
1525
1526                 if ( name ) {
1527                         var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];
1528
1529                         if ( thisCache ) {
1530                                 delete thisCache[ name ];
1531
1532                                 // If there is no data left in the cache, we want to continue
1533                                 // and let the cache object itself get destroyed
1534                                 if ( !isEmptyDataObject(thisCache) ) {
1535                                         return;
1536                                 }
1537                         }
1538                 }
1539
1540                 // See jQuery.data for more information
1541                 if ( pvt ) {
1542                         delete cache[ id ][ internalKey ];
1543
1544                         // Don't destroy the parent cache unless the internal data object
1545                         // had been the only thing left in it
1546                         if ( !isEmptyDataObject(cache[ id ]) ) {
1547                                 return;
1548                         }
1549                 }
1550
1551                 var internalCache = cache[ id ][ internalKey ];
1552
1553                 // Browsers that fail expando deletion also refuse to delete expandos on
1554                 // the window, but it will allow it on all other JS objects; other browsers
1555                 // don't care
1556                 if ( jQuery.support.deleteExpando || cache != window ) {
1557                         delete cache[ id ];
1558                 } else {
1559                         cache[ id ] = null;
1560                 }
1561
1562                 // We destroyed the entire user cache at once because it's faster than
1563                 // iterating through each key, but we need to continue to persist internal
1564                 // data if it existed
1565                 if ( internalCache ) {
1566                         cache[ id ] = {};
1567                         // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
1568                         // metadata on plain JS objects when the object is serialized using
1569                         // JSON.stringify
1570                         if ( !isNode ) {
1571                                 cache[ id ].toJSON = jQuery.noop;
1572                         }
1573
1574                         cache[ id ][ internalKey ] = internalCache;
1575
1576                 // Otherwise, we need to eliminate the expando on the node to avoid
1577                 // false lookups in the cache for entries that no longer exist
1578                 } else if ( isNode ) {
1579                         // IE does not allow us to delete expando properties from nodes,
1580                         // nor does it have a removeAttribute function on Document nodes;
1581                         // we must handle all of these cases
1582                         if ( jQuery.support.deleteExpando ) {
1583                                 delete elem[ jQuery.expando ];
1584                         } else if ( elem.removeAttribute ) {
1585                                 elem.removeAttribute( jQuery.expando );
1586                         } else {
1587                                 elem[ jQuery.expando ] = null;
1588                         }
1589                 }
1590         },
1591
1592         // For internal use only.
1593         _data: function( elem, name, data ) {
1594                 return jQuery.data( elem, name, data, true );
1595         },
1596
1597         // A method for determining if a DOM node can handle the data expando
1598         acceptData: function( elem ) {
1599                 if ( elem.nodeName ) {
1600                         var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
1601
1602                         if ( match ) {
1603                                 return !(match === true || elem.getAttribute("classid") !== match);
1604                         }
1605                 }
1606
1607                 return true;
1608         }
1609 });
1610
1611 jQuery.fn.extend({
1612         data: function( key, value ) {
1613                 var data = null;
1614
1615                 if ( typeof key === "undefined" ) {
1616                         if ( this.length ) {
1617                                 data = jQuery.data( this[0] );
1618
1619                                 if ( this[0].nodeType === 1 ) {
1620                             var attr = this[0].attributes, name;
1621                                         for ( var i = 0, l = attr.length; i < l; i++ ) {
1622                                                 name = attr[i].name;
1623
1624                                                 if ( name.indexOf( "data-" ) === 0 ) {
1625                                                         name = jQuery.camelCase( name.substring(5) );
1626
1627                                                         dataAttr( this[0], name, data[ name ] );
1628                                                 }
1629                                         }
1630                                 }
1631                         }
1632
1633                         return data;
1634
1635                 } else if ( typeof key === "object" ) {
1636                         return this.each(function() {
1637                                 jQuery.data( this, key );
1638                         });
1639                 }
1640
1641                 var parts = key.split(".");
1642                 parts[1] = parts[1] ? "." + parts[1] : "";
1643
1644                 if ( value === undefined ) {
1645                         data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1646
1647                         // Try to fetch any internally stored data first
1648                         if ( data === undefined && this.length ) {
1649                                 data = jQuery.data( this[0], key );
1650                                 data = dataAttr( this[0], key, data );
1651                         }
1652
1653                         return data === undefined && parts[1] ?
1654                                 this.data( parts[0] ) :
1655                                 data;
1656
1657                 } else {
1658                         return this.each(function() {
1659                                 var $this = jQuery( this ),
1660                                         args = [ parts[0], value ];
1661
1662                                 $this.triggerHandler( "setData" + parts[1] + "!", args );
1663                                 jQuery.data( this, key, value );
1664                                 $this.triggerHandler( "changeData" + parts[1] + "!", args );
1665                         });
1666                 }
1667         },
1668
1669         removeData: function( key ) {
1670                 return this.each(function() {
1671                         jQuery.removeData( this, key );
1672                 });
1673         }
1674 });
1675
1676 function dataAttr( elem, key, data ) {
1677         // If nothing was found internally, try to fetch any
1678         // data from the HTML5 data-* attribute
1679         if ( data === undefined && elem.nodeType === 1 ) {
1680                 var name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase();
1681
1682                 data = elem.getAttribute( name );
1683
1684                 if ( typeof data === "string" ) {
1685                         try {
1686                                 data = data === "true" ? true :
1687                                 data === "false" ? false :
1688                                 data === "null" ? null :
1689                                 !jQuery.isNaN( data ) ? parseFloat( data ) :
1690                                         rbrace.test( data ) ? jQuery.parseJSON( data ) :
1691                                         data;
1692                         } catch( e ) {}
1693
1694                         // Make sure we set the data so it isn't changed later
1695                         jQuery.data( elem, key, data );
1696
1697                 } else {
1698                         data = undefined;
1699                 }
1700         }
1701
1702         return data;
1703 }
1704
1705 // TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON
1706 // property to be considered empty objects; this property always exists in
1707 // order to make sure JSON.stringify does not expose internal metadata
1708 function isEmptyDataObject( obj ) {
1709         for ( var name in obj ) {
1710                 if ( name !== "toJSON" ) {
1711                         return false;
1712                 }
1713         }
1714
1715         return true;
1716 }
1717
1718
1719
1720
1721 function handleQueueMarkDefer( elem, type, src ) {
1722         var deferDataKey = type + "defer",
1723                 queueDataKey = type + "queue",
1724                 markDataKey = type + "mark",
1725                 defer = jQuery.data( elem, deferDataKey, undefined, true );
1726         if ( defer &&
1727                 ( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) &&
1728                 ( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) {
1729                 // Give room for hard-coded callbacks to fire first
1730                 // and eventually mark/queue something else on the element
1731                 setTimeout( function() {
1732                         if ( !jQuery.data( elem, queueDataKey, undefined, true ) &&
1733                                 !jQuery.data( elem, markDataKey, undefined, true ) ) {
1734                                 jQuery.removeData( elem, deferDataKey, true );
1735                                 defer.resolve();
1736                         }
1737                 }, 0 );
1738         }
1739 }
1740
1741 jQuery.extend({
1742
1743         _mark: function( elem, type ) {
1744                 if ( elem ) {
1745                         type = (type || "fx") + "mark";
1746                         jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true );
1747                 }
1748         },
1749
1750         _unmark: function( force, elem, type ) {
1751                 if ( force !== true ) {
1752                         type = elem;
1753                         elem = force;
1754                         force = false;
1755                 }
1756                 if ( elem ) {
1757                         type = type || "fx";
1758                         var key = type + "mark",
1759                                 count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 );
1760                         if ( count ) {
1761                                 jQuery.data( elem, key, count, true );
1762                         } else {
1763                                 jQuery.removeData( elem, key, true );
1764                                 handleQueueMarkDefer( elem, type, "mark" );
1765                         }
1766                 }
1767         },
1768
1769         queue: function( elem, type, data ) {
1770                 if ( elem ) {
1771                         type = (type || "fx") + "queue";
1772                         var q = jQuery.data( elem, type, undefined, true );
1773                         // Speed up dequeue by getting out quickly if this is just a lookup
1774                         if ( data ) {
1775                                 if ( !q || jQuery.isArray(data) ) {
1776                                         q = jQuery.data( elem, type, jQuery.makeArray(data), true );
1777                                 } else {
1778                                         q.push( data );
1779                                 }
1780                         }
1781                         return q || [];
1782                 }
1783         },
1784
1785         dequeue: function( elem, type ) {
1786                 type = type || "fx";
1787
1788                 var queue = jQuery.queue( elem, type ),
1789                         fn = queue.shift(),
1790                         defer;
1791
1792                 // If the fx queue is dequeued, always remove the progress sentinel
1793                 if ( fn === "inprogress" ) {
1794                         fn = queue.shift();
1795                 }
1796
1797                 if ( fn ) {
1798                         // Add a progress sentinel to prevent the fx queue from being
1799                         // automatically dequeued
1800                         if ( type === "fx" ) {
1801                                 queue.unshift("inprogress");
1802                         }
1803
1804                         fn.call(elem, function() {
1805                                 jQuery.dequeue(elem, type);
1806                         });
1807                 }
1808
1809                 if ( !queue.length ) {
1810                         jQuery.removeData( elem, type + "queue", true );
1811                         handleQueueMarkDefer( elem, type, "queue" );
1812                 }
1813         }
1814 });
1815
1816 jQuery.fn.extend({
1817         queue: function( type, data ) {
1818                 if ( typeof type !== "string" ) {
1819                         data = type;
1820                         type = "fx";
1821                 }
1822
1823                 if ( data === undefined ) {
1824                         return jQuery.queue( this[0], type );
1825                 }
1826                 return this.each(function() {
1827                         var queue = jQuery.queue( this, type, data );
1828
1829                         if ( type === "fx" && queue[0] !== "inprogress" ) {
1830                                 jQuery.dequeue( this, type );
1831                         }
1832                 });
1833         },
1834         dequeue: function( type ) {
1835                 return this.each(function() {
1836                         jQuery.dequeue( this, type );
1837                 });
1838         },
1839         // Based off of the plugin by Clint Helfers, with permission.
1840         // http://blindsignals.com/index.php/2009/07/jquery-delay/
1841         delay: function( time, type ) {
1842                 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
1843                 type = type || "fx";
1844
1845                 return this.queue( type, function() {
1846                         var elem = this;
1847                         setTimeout(function() {
1848                                 jQuery.dequeue( elem, type );
1849                         }, time );
1850                 });
1851         },
1852         clearQueue: function( type ) {
1853                 return this.queue( type || "fx", [] );
1854         },
1855         // Get a promise resolved when queues of a certain type
1856         // are emptied (fx is the type by default)
1857         promise: function( type, object ) {
1858                 if ( typeof type !== "string" ) {
1859                         object = type;
1860                         type = undefined;
1861                 }
1862                 type = type || "fx";
1863                 var defer = jQuery.Deferred(),
1864                         elements = this,
1865                         i = elements.length,
1866                         count = 1,
1867                         deferDataKey = type + "defer",
1868                         queueDataKey = type + "queue",
1869                         markDataKey = type + "mark",
1870                         tmp;
1871                 function resolve() {
1872                         if ( !( --count ) ) {
1873                                 defer.resolveWith( elements, [ elements ] );
1874                         }
1875                 }
1876                 while( i-- ) {
1877                         if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
1878                                         ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
1879                                                 jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
1880                                         jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) {
1881                                 count++;
1882                                 tmp.done( resolve );
1883                         }
1884                 }
1885                 resolve();
1886                 return defer.promise();
1887         }
1888 });
1889
1890
1891
1892
1893 var rclass = /[\n\t\r]/g,
1894         rspace = /\s+/,
1895         rreturn = /\r/g,
1896         rtype = /^(?:button|input)$/i,
1897         rfocusable = /^(?:button|input|object|select|textarea)$/i,
1898         rclickable = /^a(?:rea)?$/i,
1899         rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
1900         rinvalidChar = /\:/,
1901         formHook, boolHook;
1902
1903 jQuery.fn.extend({
1904         attr: function( name, value ) {
1905                 return jQuery.access( this, name, value, true, jQuery.attr );
1906         },
1907
1908         removeAttr: function( name ) {
1909                 return this.each(function() {
1910                         jQuery.removeAttr( this, name );
1911                 });
1912         },
1913         
1914         prop: function( name, value ) {
1915                 return jQuery.access( this, name, value, true, jQuery.prop );
1916         },
1917         
1918         removeProp: function( name ) {
1919                 name = jQuery.propFix[ name ] || name;
1920                 return this.each(function() {
1921                         // try/catch handles cases where IE balks (such as removing a property on window)
1922                         try {
1923                                 this[ name ] = undefined;
1924                                 delete this[ name ];
1925                         } catch( e ) {}
1926                 });
1927         },
1928
1929         addClass: function( value ) {
1930                 if ( jQuery.isFunction( value ) ) {
1931                         return this.each(function(i) {
1932                                 var self = jQuery(this);
1933                                 self.addClass( value.call(this, i, self.attr("class") || "") );
1934                         });
1935                 }
1936
1937                 if ( value && typeof value === "string" ) {
1938                         var classNames = (value || "").split( rspace );
1939
1940                         for ( var i = 0, l = this.length; i < l; i++ ) {
1941                                 var elem = this[i];
1942
1943                                 if ( elem.nodeType === 1 ) {
1944                                         if ( !elem.className ) {
1945                                                 elem.className = value;
1946
1947                                         } else {
1948                                                 var className = " " + elem.className + " ",
1949                                                         setClass = elem.className;
1950
1951                                                 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1952                                                         if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
1953                                                                 setClass += " " + classNames[c];
1954                                                         }
1955                                                 }
1956                                                 elem.className = jQuery.trim( setClass );
1957                                         }
1958                                 }
1959                         }
1960                 }
1961
1962                 return this;
1963         },
1964
1965         removeClass: function( value ) {
1966                 if ( jQuery.isFunction(value) ) {
1967                         return this.each(function(i) {
1968                                 var self = jQuery(this);
1969                                 self.removeClass( value.call(this, i, self.attr("class")) );
1970                         });
1971                 }
1972
1973                 if ( (value && typeof value === "string") || value === undefined ) {
1974                         var classNames = (value || "").split( rspace );
1975
1976                         for ( var i = 0, l = this.length; i < l; i++ ) {
1977                                 var elem = this[i];
1978
1979                                 if ( elem.nodeType === 1 && elem.className ) {
1980                                         if ( value ) {
1981                                                 var className = (" " + elem.className + " ").replace(rclass, " ");
1982                                                 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1983                                                         className = className.replace(" " + classNames[c] + " ", " ");
1984                                                 }
1985                                                 elem.className = jQuery.trim( className );
1986
1987                                         } else {
1988                                                 elem.className = "";
1989                                         }
1990                                 }
1991                         }
1992                 }
1993
1994                 return this;
1995         },
1996
1997         toggleClass: function( value, stateVal ) {
1998                 var type = typeof value,
1999                         isBool = typeof stateVal === "boolean";
2000
2001                 if ( jQuery.isFunction( value ) ) {
2002                         return this.each(function(i) {
2003                                 var self = jQuery(this);
2004                                 self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
2005                         });
2006                 }
2007
2008                 return this.each(function() {
2009                         if ( type === "string" ) {
2010                                 // toggle individual class names
2011                                 var className,
2012                                         i = 0,
2013                                         self = jQuery( this ),
2014                                         state = stateVal,
2015                                         classNames = value.split( rspace );
2016
2017                                 while ( (className = classNames[ i++ ]) ) {
2018                                         // check each className given, space seperated list
2019                                         state = isBool ? state : !self.hasClass( className );
2020                                         self[ state ? "addClass" : "removeClass" ]( className );
2021                                 }
2022
2023                         } else if ( type === "undefined" || type === "boolean" ) {
2024                                 if ( this.className ) {
2025                                         // store className if set
2026                                         jQuery._data( this, "__className__", this.className );
2027                                 }
2028
2029                                 // toggle whole className
2030                                 this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
2031                         }
2032                 });
2033         },
2034
2035         hasClass: function( selector ) {
2036                 var className = " " + selector + " ";
2037                 for ( var i = 0, l = this.length; i < l; i++ ) {
2038                         if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
2039                                 return true;
2040                         }
2041                 }
2042
2043                 return false;
2044         },
2045
2046         val: function( value ) {
2047                 var hooks, ret,
2048                         elem = this[0];
2049                 
2050                 if ( !arguments.length ) {
2051                         if ( elem ) {
2052                                 hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
2053
2054                                 if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
2055                                         return ret;
2056                                 }
2057
2058                                 return (elem.value || "").replace(rreturn, "");
2059                         }
2060
2061                         return undefined;
2062                 }
2063
2064                 var isFunction = jQuery.isFunction( value );
2065
2066                 return this.each(function( i ) {
2067                         var self = jQuery(this), val;
2068
2069                         if ( this.nodeType !== 1 ) {
2070                                 return;
2071                         }
2072
2073                         if ( isFunction ) {
2074                                 val = value.call( this, i, self.val() );
2075                         } else {
2076                                 val = value;
2077                         }
2078
2079                         // Treat null/undefined as ""; convert numbers to string
2080                         if ( val == null ) {
2081                                 val = "";
2082                         } else if ( typeof val === "number" ) {
2083                                 val += "";
2084                         } else if ( jQuery.isArray( val ) ) {
2085                                 val = jQuery.map(val, function ( value ) {
2086                                         return value == null ? "" : value + "";
2087                                 });
2088                         }
2089
2090                         hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
2091
2092                         // If set returns undefined, fall back to normal setting
2093                         if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
2094                                 this.value = val;
2095                         }
2096                 });
2097         }
2098 });
2099
2100 jQuery.extend({
2101         valHooks: {
2102                 option: {
2103                         get: function( elem ) {
2104                                 // attributes.value is undefined in Blackberry 4.7 but
2105                                 // uses .value. See #6932
2106                                 var val = elem.attributes.value;
2107                                 return !val || val.specified ? elem.value : elem.text;
2108                         }
2109                 },
2110                 select: {
2111                         get: function( elem ) {
2112                                 var value,
2113                                         index = elem.selectedIndex,
2114                                         values = [],
2115                                         options = elem.options,
2116                                         one = elem.type === "select-one";
2117
2118                                 // Nothing was selected
2119                                 if ( index < 0 ) {
2120                                         return null;
2121                                 }
2122
2123                                 // Loop through all the selected options
2124                                 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
2125                                         var option = options[ i ];
2126
2127                                         // Don't return options that are disabled or in a disabled optgroup
2128                                         if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
2129                                                         (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
2130
2131                                                 // Get the specific value for the option
2132                                                 value = jQuery( option ).val();
2133
2134                                                 // We don't need an array for one selects
2135                                                 if ( one ) {
2136                                                         return value;
2137                                                 }
2138
2139                                                 // Multi-Selects return an array
2140                                                 values.push( value );
2141                                         }
2142                                 }
2143
2144                                 // Fixes Bug #2551 -- select.val() broken in IE after form.reset()
2145                                 if ( one && !values.length && options.length ) {
2146                                         return jQuery( options[ index ] ).val();
2147                                 }
2148
2149                                 return values;
2150                         },
2151
2152                         set: function( elem, value ) {
2153                                 var values = jQuery.makeArray( value );
2154
2155                                 jQuery(elem).find("option").each(function() {
2156                                         this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
2157                                 });
2158
2159                                 if ( !values.length ) {
2160                                         elem.selectedIndex = -1;
2161                                 }
2162                                 return values;
2163                         }
2164                 }
2165         },
2166
2167         attrFn: {
2168                 val: true,
2169                 css: true,
2170                 html: true,
2171                 text: true,
2172                 data: true,
2173                 width: true,
2174                 height: true,
2175                 offset: true
2176         },
2177         
2178         attrFix: {
2179                 // Always normalize to ensure hook usage
2180                 tabindex: "tabIndex"
2181         },
2182         
2183         attr: function( elem, name, value, pass ) {
2184                 var nType = elem.nodeType;
2185                 
2186                 // don't get/set attributes on text, comment and attribute nodes
2187                 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2188                         return undefined;
2189                 }
2190
2191                 if ( pass && name in jQuery.attrFn ) {
2192                         return jQuery( elem )[ name ]( value );
2193                 }
2194
2195                 // Fallback to prop when attributes are not supported
2196                 if ( !("getAttribute" in elem) ) {
2197                         return jQuery.prop( elem, name, value );
2198                 }
2199
2200                 var ret, hooks,
2201                         notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2202
2203                 // Normalize the name if needed
2204                 name = notxml && jQuery.attrFix[ name ] || name;
2205
2206                 hooks = jQuery.attrHooks[ name ];
2207
2208                 if ( !hooks ) {
2209                         // Use boolHook for boolean attributes
2210                         if ( rboolean.test( name ) &&
2211                                 (typeof value === "boolean" || value === undefined || value.toLowerCase() === name.toLowerCase()) ) {
2212
2213                                 hooks = boolHook;
2214
2215                         // Use formHook for forms and if the name contains certain characters
2216                         } else if ( formHook && (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ) {
2217                                 hooks = formHook;
2218                         }
2219                 }
2220
2221                 if ( value !== undefined ) {
2222
2223                         if ( value === null ) {
2224                                 jQuery.removeAttr( elem, name );
2225                                 return undefined;
2226
2227                         } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
2228                                 return ret;
2229
2230                         } else {
2231                                 elem.setAttribute( name, "" + value );
2232                                 return value;
2233                         }
2234
2235                 } else if ( hooks && "get" in hooks && notxml ) {
2236                         return hooks.get( elem, name );
2237
2238                 } else {
2239
2240                         ret = elem.getAttribute( name );
2241
2242                         // Non-existent attributes return null, we normalize to undefined
2243                         return ret === null ?
2244                                 undefined :
2245                                 ret;
2246                 }
2247         },
2248
2249         removeAttr: function( elem, name ) {
2250                 var propName;
2251                 if ( elem.nodeType === 1 ) {
2252                         name = jQuery.attrFix[ name ] || name;
2253                 
2254                         if ( jQuery.support.getSetAttribute ) {
2255                                 // Use removeAttribute in browsers that support it
2256                                 elem.removeAttribute( name );
2257                         } else {
2258                                 jQuery.attr( elem, name, "" );
2259                                 elem.removeAttributeNode( elem.getAttributeNode( name ) );
2260                         }
2261
2262                         // Set corresponding property to false for boolean attributes
2263                         if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) {
2264                                 elem[ propName ] = false;
2265                         }
2266                 }
2267         },
2268
2269         attrHooks: {
2270                 type: {
2271                         set: function( elem, value ) {
2272                                 // We can't allow the type property to be changed (since it causes problems in IE)
2273                                 if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
2274                                         jQuery.error( "type property can't be changed" );
2275                                 } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
2276                                         // Setting the type on a radio button after the value resets the value in IE6-9
2277                                         // Reset value to it's default in case type is set after value
2278                                         // This is for element creation
2279                                         var val = elem.value;
2280                                         elem.setAttribute( "type", value );
2281                                         if ( val ) {
2282                                                 elem.value = val;
2283                                         }
2284                                         return value;
2285                                 }
2286                         }
2287                 },
2288                 tabIndex: {
2289                         get: function( elem ) {
2290                                 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
2291                                 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
2292                                 var attributeNode = elem.getAttributeNode("tabIndex");
2293
2294                                 return attributeNode && attributeNode.specified ?
2295                                         parseInt( attributeNode.value, 10 ) :
2296                                         rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
2297                                                 0 :
2298                                                 undefined;
2299                         }
2300                 }
2301         },
2302
2303         propFix: {
2304                 tabindex: "tabIndex",
2305                 readonly: "readOnly",
2306                 "for": "htmlFor",
2307                 "class": "className",
2308                 maxlength: "maxLength",
2309                 cellspacing: "cellSpacing",
2310                 cellpadding: "cellPadding",
2311                 rowspan: "rowSpan",
2312                 colspan: "colSpan",
2313                 usemap: "useMap",
2314                 frameborder: "frameBorder",
2315                 contenteditable: "contentEditable"
2316         },
2317         
2318         prop: function( elem, name, value ) {
2319                 var nType = elem.nodeType;
2320
2321                 // don't get/set properties on text, comment and attribute nodes
2322                 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2323                         return undefined;
2324                 }
2325
2326                 var ret, hooks,
2327                         notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2328
2329                 // Try to normalize/fix the name
2330                 name = notxml && jQuery.propFix[ name ] || name;
2331                 
2332                 hooks = jQuery.propHooks[ name ];
2333
2334                 if ( value !== undefined ) {
2335                         if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
2336                                 return ret;
2337
2338                         } else {
2339                                 return (elem[ name ] = value);
2340                         }
2341
2342                 } else {
2343                         if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) {
2344                                 return ret;
2345
2346                         } else {
2347                                 return elem[ name ];
2348                         }
2349                 }
2350         },
2351         
2352         propHooks: {}
2353 });
2354
2355 // Hook for boolean attributes
2356 boolHook = {
2357         get: function( elem, name ) {
2358                 // Align boolean attributes with corresponding properties
2359                 return elem[ jQuery.propFix[ name ] || name ] ?
2360                         name.toLowerCase() :
2361                         undefined;
2362         },
2363         set: function( elem, value, name ) {
2364                 var propName;
2365                 if ( value === false ) {
2366                         // Remove boolean attributes when set to false
2367                         jQuery.removeAttr( elem, name );
2368                 } else {
2369                         // value is true since we know at this point it's type boolean and not false
2370                         // Set boolean attributes to the same name and set the DOM property
2371                         propName = jQuery.propFix[ name ] || name;
2372                         if ( propName in elem ) {
2373                                 // Only set the IDL specifically if it already exists on the element
2374                                 elem[ propName ] = value;
2375                         }
2376
2377                         elem.setAttribute( name, name.toLowerCase() );
2378                 }
2379                 return name;
2380         }
2381 };
2382
2383 // Use the value property for back compat
2384 // Use the formHook for button elements in IE6/7 (#1954)
2385 jQuery.attrHooks.value = {
2386         get: function( elem, name ) {
2387                 if ( formHook && jQuery.nodeName( elem, "button" ) ) {
2388                         return formHook.get( elem, name );
2389                 }
2390                 return elem.value;
2391         },
2392         set: function( elem, value, name ) {
2393                 if ( formHook && jQuery.nodeName( elem, "button" ) ) {
2394                         return formHook.set( elem, value, name );
2395                 }
2396                 // Does not return so that setAttribute is also used
2397                 elem.value = value;
2398         }
2399 };
2400
2401 // IE6/7 do not support getting/setting some attributes with get/setAttribute
2402 if ( !jQuery.support.getSetAttribute ) {
2403
2404         // propFix is more comprehensive and contains all fixes
2405         jQuery.attrFix = jQuery.propFix;
2406         
2407         // Use this for any attribute on a form in IE6/7
2408         formHook = jQuery.attrHooks.name = jQuery.valHooks.button = {
2409                 get: function( elem, name ) {
2410                         var ret;
2411                         ret = elem.getAttributeNode( name );
2412                         // Return undefined if nodeValue is empty string
2413                         return ret && ret.nodeValue !== "" ?
2414                                 ret.nodeValue :
2415                                 undefined;
2416                 },
2417                 set: function( elem, value, name ) {
2418                         // Check form objects in IE (multiple bugs related)
2419                         // Only use nodeValue if the attribute node exists on the form
2420                         var ret = elem.getAttributeNode( name );
2421                         if ( ret ) {
2422                                 ret.nodeValue = value;
2423                                 return value;
2424                         }
2425                 }
2426         };
2427
2428         // Set width and height to auto instead of 0 on empty string( Bug #8150 )
2429         // This is for removals
2430         jQuery.each([ "width", "height" ], function( i, name ) {
2431                 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2432                         set: function( elem, value ) {
2433                                 if ( value === "" ) {
2434                                         elem.setAttribute( name, "auto" );
2435                                         return value;
2436                                 }
2437                         }
2438                 });
2439         });
2440 }
2441
2442
2443 // Some attributes require a special call on IE
2444 if ( !jQuery.support.hrefNormalized ) {
2445         jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
2446                 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2447                         get: function( elem ) {
2448                                 var ret = elem.getAttribute( name, 2 );
2449                                 return ret === null ? undefined : ret;
2450                         }
2451                 });
2452         });
2453 }
2454
2455 if ( !jQuery.support.style ) {
2456         jQuery.attrHooks.style = {
2457                 get: function( elem ) {
2458                         // Return undefined in the case of empty string
2459                         // Normalize to lowercase since IE uppercases css property names
2460                         return elem.style.cssText.toLowerCase() || undefined;
2461                 },
2462                 set: function( elem, value ) {
2463                         return (elem.style.cssText = "" + value);
2464                 }
2465         };
2466 }
2467
2468 // Safari mis-reports the default selected property of an option
2469 // Accessing the parent's selectedIndex property fixes it
2470 if ( !jQuery.support.optSelected ) {
2471         jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
2472                 get: function( elem ) {
2473                         var parent = elem.parentNode;
2474
2475                         if ( parent ) {
2476                                 parent.selectedIndex;
2477
2478                                 // Make sure that it also works with optgroups, see #5701
2479                                 if ( parent.parentNode ) {
2480                                         parent.parentNode.selectedIndex;
2481                                 }
2482                         }
2483                 }
2484         });
2485 }
2486
2487 // Radios and checkboxes getter/setter
2488 if ( !jQuery.support.checkOn ) {
2489         jQuery.each([ "radio", "checkbox" ], function() {
2490                 jQuery.valHooks[ this ] = {
2491                         get: function( elem ) {
2492                                 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
2493                                 return elem.getAttribute("value") === null ? "on" : elem.value;
2494                         }
2495                 };
2496         });
2497 }
2498 jQuery.each([ "radio", "checkbox" ], function() {
2499         jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
2500                 set: function( elem, value ) {
2501                         if ( jQuery.isArray( value ) ) {
2502                                 return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0);
2503                         }
2504                 }
2505         });
2506 });
2507
2508
2509
2510
2511 var hasOwn = Object.prototype.hasOwnProperty,
2512         rnamespaces = /\.(.*)$/,
2513         rformElems = /^(?:textarea|input|select)$/i,
2514         rperiod = /\./g,
2515         rspaces = / /g,
2516         rescape = /[^\w\s.|`]/g,
2517         fcleanup = function( nm ) {
2518                 return nm.replace(rescape, "\\$&");
2519         };
2520
2521 /*
2522  * A number of helper functions used for managing events.
2523  * Many of the ideas behind this code originated from
2524  * Dean Edwards' addEvent library.
2525  */
2526 jQuery.event = {
2527
2528         // Bind an event to an element
2529         // Original by Dean Edwards
2530         add: function( elem, types, handler, data ) {
2531                 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2532                         return;
2533                 }
2534
2535                 if ( handler === false ) {
2536                         handler = returnFalse;
2537                 } else if ( !handler ) {
2538                         // Fixes bug #7229. Fix recommended by jdalton
2539                         return;
2540                 }
2541
2542                 var handleObjIn, handleObj;
2543
2544                 if ( handler.handler ) {
2545                         handleObjIn = handler;
2546                         handler = handleObjIn.handler;
2547                 }
2548
2549                 // Make sure that the function being executed has a unique ID
2550                 if ( !handler.guid ) {
2551                         handler.guid = jQuery.guid++;
2552                 }
2553
2554                 // Init the element's event structure
2555                 var elemData = jQuery._data( elem );
2556
2557                 // If no elemData is found then we must be trying to bind to one of the
2558                 // banned noData elements
2559                 if ( !elemData ) {
2560                         return;
2561                 }
2562
2563                 var events = elemData.events,
2564                         eventHandle = elemData.handle;
2565
2566                 if ( !events ) {
2567                         elemData.events = events = {};
2568                 }
2569
2570                 if ( !eventHandle ) {
2571                         elemData.handle = eventHandle = function( e ) {
2572                                 // Discard the second event of a jQuery.event.trigger() and
2573                                 // when an event is called after a page has unloaded
2574                                 return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
2575                                         jQuery.event.handle.apply( eventHandle.elem, arguments ) :
2576                                         undefined;
2577                         };
2578                 }
2579
2580                 // Add elem as a property of the handle function
2581                 // This is to prevent a memory leak with non-native events in IE.
2582                 eventHandle.elem = elem;
2583
2584                 // Handle multiple events separated by a space
2585                 // jQuery(...).bind("mouseover mouseout", fn);
2586                 types = types.split(" ");
2587
2588                 var type, i = 0, namespaces;
2589
2590                 while ( (type = types[ i++ ]) ) {
2591                         handleObj = handleObjIn ?
2592                                 jQuery.extend({}, handleObjIn) :
2593                                 { handler: handler, data: data };
2594
2595                         // Namespaced event handlers
2596                         if ( type.indexOf(".") > -1 ) {
2597                                 namespaces = type.split(".");
2598                                 type = namespaces.shift();
2599                                 handleObj.namespace = namespaces.slice(0).sort().join(".");
2600
2601                         } else {
2602                                 namespaces = [];
2603                                 handleObj.namespace = "";
2604                         }
2605
2606                         handleObj.type = type;
2607                         if ( !handleObj.guid ) {
2608                                 handleObj.guid = handler.guid;
2609                         }
2610
2611                         // Get the current list of functions bound to this event
2612                         var handlers = events[ type ],
2613                                 special = jQuery.event.special[ type ] || {};
2614
2615                         // Init the event handler queue
2616                         if ( !handlers ) {
2617                                 handlers = events[ type ] = [];
2618
2619                                 // Check for a special event handler
2620                                 // Only use addEventListener/attachEvent if the special
2621                                 // events handler returns false
2622                                 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
2623                                         // Bind the global event handler to the element
2624                                         if ( elem.addEventListener ) {
2625                                                 elem.addEventListener( type, eventHandle, false );
2626
2627                                         } else if ( elem.attachEvent ) {
2628                                                 elem.attachEvent( "on" + type, eventHandle );
2629                                         }
2630                                 }
2631                         }
2632
2633                         if ( special.add ) {
2634                                 special.add.call( elem, handleObj );
2635
2636                                 if ( !handleObj.handler.guid ) {
2637                                         handleObj.handler.guid = handler.guid;
2638                                 }
2639                         }
2640
2641                         // Add the function to the element's handler list
2642                         handlers.push( handleObj );
2643
2644                         // Keep track of which events have been used, for event optimization
2645                         jQuery.event.global[ type ] = true;
2646                 }
2647
2648                 // Nullify elem to prevent memory leaks in IE
2649                 elem = null;
2650         },
2651
2652         global: {},
2653
2654         // Detach an event or set of events from an element
2655         remove: function( elem, types, handler, pos ) {
2656                 // don't do events on text and comment nodes
2657                 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2658                         return;
2659                 }
2660
2661                 if ( handler === false ) {
2662                         handler = returnFalse;
2663                 }
2664
2665                 var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
2666                         elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
2667                         events = elemData && elemData.events;
2668
2669                 if ( !elemData || !events ) {
2670                         return;
2671                 }
2672
2673                 // types is actually an event object here
2674                 if ( types && types.type ) {
2675                         handler = types.handler;
2676                         types = types.type;
2677                 }
2678
2679                 // Unbind all events for the element
2680                 if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
2681                         types = types || "";
2682
2683                         for ( type in events ) {
2684                                 jQuery.event.remove( elem, type + types );
2685                         }
2686
2687                         return;
2688                 }
2689
2690                 // Handle multiple events separated by a space
2691                 // jQuery(...).unbind("mouseover mouseout", fn);
2692                 types = types.split(" ");
2693
2694                 while ( (type = types[ i++ ]) ) {
2695                         origType = type;
2696                         handleObj = null;
2697                         all = type.indexOf(".") < 0;
2698                         namespaces = [];
2699
2700                         if ( !all ) {
2701                                 // Namespaced event handlers
2702                                 namespaces = type.split(".");
2703                                 type = namespaces.shift();
2704
2705                                 namespace = new RegExp("(^|\\.)" +
2706                                         jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
2707                         }
2708
2709                         eventType = events[ type ];
2710
2711                         if ( !eventType ) {
2712                                 continue;
2713                         }
2714
2715                         if ( !handler ) {
2716                                 for ( j = 0; j < eventType.length; j++ ) {
2717                                         handleObj = eventType[ j ];
2718
2719                                         if ( all || namespace.test( handleObj.namespace ) ) {
2720                                                 jQuery.event.remove( elem, origType, handleObj.handler, j );
2721                                                 eventType.splice( j--, 1 );
2722                                         }
2723                                 }
2724
2725                                 continue;
2726                         }
2727
2728                         special = jQuery.event.special[ type ] || {};
2729
2730                         for ( j = pos || 0; j < eventType.length; j++ ) {
2731                                 handleObj = eventType[ j ];
2732
2733                                 if ( handler.guid === handleObj.guid ) {
2734                                         // remove the given handler for the given type
2735                                         if ( all || namespace.test( handleObj.namespace ) ) {
2736                                                 if ( pos == null ) {
2737                                                         eventType.splice( j--, 1 );
2738                                                 }
2739
2740                                                 if ( special.remove ) {
2741                                                         special.remove.call( elem, handleObj );
2742                                                 }
2743                                         }
2744
2745                                         if ( pos != null ) {
2746                                                 break;
2747                                         }
2748                                 }
2749                         }
2750
2751                         // remove generic event handler if no more handlers exist
2752                         if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
2753                                 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
2754                                         jQuery.removeEvent( elem, type, elemData.handle );
2755                                 }
2756
2757                                 ret = null;
2758                                 delete events[ type ];
2759                         }
2760                 }
2761
2762                 // Remove the expando if it's no longer used
2763                 if ( jQuery.isEmptyObject( events ) ) {
2764                         var handle = elemData.handle;
2765                         if ( handle ) {
2766                                 handle.elem = null;
2767                         }
2768
2769                         delete elemData.events;
2770                         delete elemData.handle;
2771
2772                         if ( jQuery.isEmptyObject( elemData ) ) {
2773                                 jQuery.removeData( elem, undefined, true );
2774                         }
2775                 }
2776         },
2777         
2778         // Events that are safe to short-circuit if no handlers are attached.
2779         // Native DOM events should not be added, they may have inline handlers.
2780         customEvent: {
2781                 "getData": true,
2782                 "setData": true,
2783                 "changeData": true
2784         },
2785
2786         trigger: function( event, data, elem, onlyHandlers ) {
2787                 // Event object or event type
2788                 var type = event.type || event,
2789                         namespaces = [],
2790                         exclusive;
2791
2792                 if ( type.indexOf("!") >= 0 ) {
2793                         // Exclusive events trigger only for the exact event (no namespaces)
2794                         type = type.slice(0, -1);
2795                         exclusive = true;
2796                 }
2797
2798                 if ( type.indexOf(".") >= 0 ) {
2799                         // Namespaced trigger; create a regexp to match event type in handle()
2800                         namespaces = type.split(".");
2801                         type = namespaces.shift();
2802                         namespaces.sort();
2803                 }
2804
2805                 if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
2806                         // No jQuery handlers for this event type, and it can't have inline handlers
2807                         return;
2808                 }
2809
2810                 // Caller can pass in an Event, Object, or just an event type string
2811                 event = typeof event === "object" ?
2812                         // jQuery.Event object
2813                         event[ jQuery.expando ] ? event :
2814                         // Object literal
2815                         new jQuery.Event( type, event ) :
2816                         // Just the event type (string)
2817                         new jQuery.Event( type );
2818
2819                 event.type = type;
2820                 event.exclusive = exclusive;
2821                 event.namespace = namespaces.join(".");
2822                 event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
2823                 
2824                 // triggerHandler() and global events don't bubble or run the default action
2825                 if ( onlyHandlers || !elem ) {
2826                         event.preventDefault();
2827                         event.stopPropagation();
2828                 }
2829
2830                 // Handle a global trigger
2831                 if ( !elem ) {
2832                         // TODO: Stop taunting the data cache; remove global events and always attach to document
2833                         jQuery.each( jQuery.cache, function() {
2834                                 // internalKey variable is just used to make it easier to find
2835                                 // and potentially change this stuff later; currently it just
2836                                 // points to jQuery.expando
2837                                 var internalKey = jQuery.expando,
2838                                         internalCache = this[ internalKey ];
2839                                 if ( internalCache && internalCache.events && internalCache.events[ type ] ) {
2840                                         jQuery.event.trigger( event, data, internalCache.handle.elem );
2841                                 }
2842                         });
2843                         return;
2844                 }
2845
2846                 // Don't do events on text and comment nodes
2847                 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2848                         return;
2849                 }
2850
2851                 // Clean up the event in case it is being reused
2852                 event.result = undefined;
2853                 event.target = elem;
2854
2855                 // Clone any incoming data and prepend the event, creating the handler arg list
2856                 data = data ? jQuery.makeArray( data ) : [];
2857                 data.unshift( event );
2858
2859                 var cur = elem,
2860                         // IE doesn't like method names with a colon (#3533, #8272)
2861                         ontype = type.indexOf(":") < 0 ? "on" + type : "";
2862
2863                 // Fire event on the current element, then bubble up the DOM tree
2864                 do {
2865                         var handle = jQuery._data( cur, "handle" );
2866
2867                         event.currentTarget = cur;
2868                         if ( handle ) {
2869                                 handle.apply( cur, data );
2870                         }
2871
2872                         // Trigger an inline bound script
2873                         if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) {
2874                                 event.result = false;
2875                                 event.preventDefault();
2876                         }
2877
2878                         // Bubble up to document, then to window
2879                         cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window;
2880                 } while ( cur && !event.isPropagationStopped() );
2881
2882                 // If nobody prevented the default action, do it now
2883                 if ( !event.isDefaultPrevented() ) {
2884                         var old,
2885                                 special = jQuery.event.special[ type ] || {};
2886
2887                         if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) &&
2888                                 !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
2889
2890                                 // Call a native DOM method on the target with the same name name as the event.
2891                                 // Can't use an .isFunction)() check here because IE6/7 fails that test.
2892                                 // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch.
2893                                 try {
2894                                         if ( ontype && elem[ type ] ) {
2895                                                 // Don't re-trigger an onFOO event when we call its FOO() method
2896                                                 old = elem[ ontype ];
2897
2898                                                 if ( old ) {
2899                                                         elem[ ontype ] = null;
2900                                                 }
2901
2902                                                 jQuery.event.triggered = type;
2903                                                 elem[ type ]();
2904                                         }
2905                                 } catch ( ieError ) {}
2906
2907                                 if ( old ) {
2908                                         elem[ ontype ] = old;
2909                                 }
2910
2911                                 jQuery.event.triggered = undefined;
2912                         }
2913                 }
2914                 
2915                 return event.result;
2916         },
2917
2918         handle: function( event ) {
2919                 event = jQuery.event.fix( event || window.event );
2920                 // Snapshot the handlers list since a called handler may add/remove events.
2921                 var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0),
2922                         run_all = !event.exclusive && !event.namespace,
2923                         args = Array.prototype.slice.call( arguments, 0 );
2924
2925                 // Use the fix-ed Event rather than the (read-only) native event
2926                 args[0] = event;
2927                 event.currentTarget = this;
2928
2929                 for ( var j = 0, l = handlers.length; j < l; j++ ) {
2930                         var handleObj = handlers[ j ];
2931
2932                         // Triggered event must 1) be non-exclusive and have no namespace, or
2933                         // 2) have namespace(s) a subset or equal to those in the bound event.
2934                         if ( run_all || event.namespace_re.test( handleObj.namespace ) ) {
2935                                 // Pass in a reference to the handler function itself
2936                                 // So that we can later remove it
2937                                 event.handler = handleObj.handler;
2938                                 event.data = handleObj.data;
2939                                 event.handleObj = handleObj;
2940
2941                                 var ret = handleObj.handler.apply( this, args );
2942
2943                                 if ( ret !== undefined ) {
2944                                         event.result = ret;
2945                                         if ( ret === false ) {
2946                                                 event.preventDefault();
2947                                                 event.stopPropagation();
2948                                         }
2949                                 }
2950
2951                                 if ( event.isImmediatePropagationStopped() ) {
2952                                         break;
2953                                 }
2954                         }
2955                 }
2956                 return event.result;
2957         },
2958
2959         props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
2960
2961         fix: function( event ) {
2962                 if ( event[ jQuery.expando ] ) {
2963                         return event;
2964                 }
2965
2966                 // store a copy of the original event object
2967                 // and "clone" to set read-only properties
2968                 var originalEvent = event;
2969                 event = jQuery.Event( originalEvent );
2970
2971                 for ( var i = this.props.length, prop; i; ) {
2972                         prop = this.props[ --i ];
2973                         event[ prop ] = originalEvent[ prop ];
2974                 }
2975
2976                 // Fix target property, if necessary
2977                 if ( !event.target ) {
2978                         // Fixes #1925 where srcElement might not be defined either
2979                         event.target = event.srcElement || document;
2980                 }
2981
2982                 // check if target is a textnode (safari)
2983                 if ( event.target.nodeType === 3 ) {
2984                         event.target = event.target.parentNode;
2985                 }
2986
2987                 // Add relatedTarget, if necessary
2988                 if ( !event.relatedTarget && event.fromElement ) {
2989                         event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
2990                 }
2991
2992                 // Calculate pageX/Y if missing and clientX/Y available
2993                 if ( event.pageX == null && event.clientX != null ) {
2994                         var eventDocument = event.target.ownerDocument || document,
2995                                 doc = eventDocument.documentElement,
2996                                 body = eventDocument.body;
2997
2998                         event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
2999                         event.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);
3000                 }
3001
3002                 // Add which for key events
3003                 if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
3004                         event.which = event.charCode != null ? event.charCode : event.keyCode;
3005                 }
3006
3007                 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
3008                 if ( !event.metaKey && event.ctrlKey ) {
3009                         event.metaKey = event.ctrlKey;
3010                 }
3011
3012                 // Add which for click: 1 === left; 2 === middle; 3 === right
3013                 // Note: button is not normalized, so don't use it
3014                 if ( !event.which && event.button !== undefined ) {
3015                         event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
3016                 }
3017
3018                 return event;
3019         },
3020
3021         // Deprecated, use jQuery.guid instead
3022         guid: 1E8,
3023
3024         // Deprecated, use jQuery.proxy instead
3025         proxy: jQuery.proxy,
3026
3027         special: {
3028                 ready: {
3029                         // Make sure the ready event is setup
3030                         setup: jQuery.bindReady,
3031                         teardown: jQuery.noop
3032                 },
3033
3034                 live: {
3035                         add: function( handleObj ) {
3036                                 jQuery.event.add( this,
3037                                         liveConvert( handleObj.origType, handleObj.selector ),
3038                                         jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
3039                         },
3040
3041                         remove: function( handleObj ) {
3042                                 jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
3043                         }
3044                 },
3045
3046                 beforeunload: {
3047                         setup: function( data, namespaces, eventHandle ) {
3048                                 // We only want to do this special case on windows
3049                                 if ( jQuery.isWindow( this ) ) {
3050                                         this.onbeforeunload = eventHandle;
3051                                 }
3052                         },
3053
3054                         teardown: function( namespaces, eventHandle ) {
3055                                 if ( this.onbeforeunload === eventHandle ) {
3056                                         this.onbeforeunload = null;
3057                                 }
3058                         }
3059                 }
3060         }
3061 };
3062
3063 jQuery.removeEvent = document.removeEventListener ?
3064         function( elem, type, handle ) {
3065                 if ( elem.removeEventListener ) {
3066                         elem.removeEventListener( type, handle, false );
3067                 }
3068         } :
3069         function( elem, type, handle ) {
3070                 if ( elem.detachEvent ) {
3071                         elem.detachEvent( "on" + type, handle );
3072                 }
3073         };
3074
3075 jQuery.Event = function( src, props ) {
3076         // Allow instantiation without the 'new' keyword
3077         if ( !this.preventDefault ) {
3078                 return new jQuery.Event( src, props );
3079         }
3080
3081         // Event object
3082         if ( src && src.type ) {
3083                 this.originalEvent = src;
3084                 this.type = src.type;
3085
3086                 // Events bubbling up the document may have been marked as prevented
3087                 // by a handler lower down the tree; reflect the correct value.
3088                 this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
3089                         src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
3090
3091         // Event type
3092         } else {
3093                 this.type = src;
3094         }
3095
3096         // Put explicitly provided properties onto the event object
3097         if ( props ) {
3098                 jQuery.extend( this, props );
3099         }
3100
3101         // timeStamp is buggy for some events on Firefox(#3843)
3102         // So we won't rely on the native value
3103         this.timeStamp = jQuery.now();
3104
3105         // Mark it as fixed
3106         this[ jQuery.expando ] = true;
3107 };
3108
3109 function returnFalse() {
3110         return false;
3111 }
3112 function returnTrue() {
3113         return true;
3114 }
3115
3116 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
3117 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
3118 jQuery.Event.prototype = {
3119         preventDefault: function() {
3120                 this.isDefaultPrevented = returnTrue;
3121
3122                 var e = this.originalEvent;
3123                 if ( !e ) {
3124                         return;
3125                 }
3126
3127                 // if preventDefault exists run it on the original event
3128                 if ( e.preventDefault ) {
3129                         e.preventDefault();
3130
3131                 // otherwise set the returnValue property of the original event to false (IE)
3132                 } else {
3133                         e.returnValue = false;
3134                 }
3135         },
3136         stopPropagation: function() {
3137                 this.isPropagationStopped = returnTrue;
3138
3139                 var e = this.originalEvent;
3140                 if ( !e ) {
3141                         return;
3142                 }
3143                 // if stopPropagation exists run it on the original event
3144                 if ( e.stopPropagation ) {
3145                         e.stopPropagation();
3146                 }
3147                 // otherwise set the cancelBubble property of the original event to true (IE)
3148                 e.cancelBubble = true;
3149         },
3150         stopImmediatePropagation: function() {
3151                 this.isImmediatePropagationStopped = returnTrue;
3152                 this.stopPropagation();
3153         },
3154         isDefaultPrevented: returnFalse,
3155         isPropagationStopped: returnFalse,
3156         isImmediatePropagationStopped: returnFalse
3157 };
3158
3159 // Checks if an event happened on an element within another element
3160 // Used in jQuery.event.special.mouseenter and mouseleave handlers
3161 var withinElement = function( event ) {
3162         // Check if mouse(over|out) are still within the same parent element
3163         var parent = event.relatedTarget;
3164
3165         // set the correct event type
3166         event.type = event.data;
3167
3168         // Firefox sometimes assigns relatedTarget a XUL element
3169         // which we cannot access the parentNode property of
3170         try {
3171
3172                 // Chrome does something similar, the parentNode property
3173                 // can be accessed but is null.
3174                 if ( parent && parent !== document && !parent.parentNode ) {
3175                         return;
3176                 }
3177
3178                 // Traverse up the tree
3179                 while ( parent && parent !== this ) {
3180                         parent = parent.parentNode;
3181                 }
3182
3183                 if ( parent !== this ) {
3184                         // handle event if we actually just moused on to a non sub-element
3185                         jQuery.event.handle.apply( this, arguments );
3186                 }
3187
3188         // assuming we've left the element since we most likely mousedover a xul element
3189         } catch(e) { }
3190 },
3191
3192 // In case of event delegation, we only need to rename the event.type,
3193 // liveHandler will take care of the rest.
3194 delegate = function( event ) {
3195         event.type = event.data;
3196         jQuery.event.handle.apply( this, arguments );
3197 };
3198
3199 // Create mouseenter and mouseleave events
3200 jQuery.each({
3201         mouseenter: "mouseover",
3202         mouseleave: "mouseout"
3203 }, function( orig, fix ) {
3204         jQuery.event.special[ orig ] = {
3205                 setup: function( data ) {
3206                         jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
3207                 },
3208                 teardown: function( data ) {
3209                         jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
3210                 }
3211         };
3212 });
3213
3214 // submit delegation
3215 if ( !jQuery.support.submitBubbles ) {
3216
3217         jQuery.event.special.submit = {
3218                 setup: function( data, namespaces ) {
3219                         if ( !jQuery.nodeName( this, "form" ) ) {
3220                                 jQuery.event.add(this, "click.specialSubmit", function( e ) {
3221                                         var elem = e.target,
3222                                                 type = elem.type;
3223
3224                                         if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
3225                                                 trigger( "submit", this, arguments );
3226                                         }
3227                                 });
3228
3229                                 jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
3230                                         var elem = e.target,
3231                                                 type = elem.type;
3232
3233                                         if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
3234                                                 trigger( "submit", this, arguments );
3235                                         }
3236                                 });
3237
3238                         } else {
3239                                 return false;
3240                         }
3241                 },
3242
3243                 teardown: function( namespaces ) {
3244                         jQuery.event.remove( this, ".specialSubmit" );
3245                 }
3246         };
3247
3248 }
3249
3250 // change delegation, happens here so we have bind.
3251 if ( !jQuery.support.changeBubbles ) {
3252
3253         var changeFilters,
3254
3255         getVal = function( elem ) {
3256                 var type = elem.type, val = elem.value;
3257
3258                 if ( type === "radio" || type === "checkbox" ) {
3259                         val = elem.checked;
3260
3261                 } else if ( type === "select-multiple" ) {
3262                         val = elem.selectedIndex > -1 ?
3263                                 jQuery.map( elem.options, function( elem ) {
3264                                         return elem.selected;
3265                                 }).join("-") :
3266                                 "";
3267
3268                 } else if ( jQuery.nodeName( elem, "select" ) ) {
3269                         val = elem.selectedIndex;
3270                 }
3271
3272                 return val;
3273         },
3274
3275         testChange = function testChange( e ) {
3276                 var elem = e.target, data, val;
3277
3278                 if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
3279                         return;
3280                 }
3281
3282                 data = jQuery._data( elem, "_change_data" );
3283                 val = getVal(elem);
3284
3285                 // the current data will be also retrieved by beforeactivate
3286                 if ( e.type !== "focusout" || elem.type !== "radio" ) {
3287                         jQuery._data( elem, "_change_data", val );
3288                 }
3289
3290                 if ( data === undefined || val === data ) {
3291                         return;
3292                 }
3293
3294                 if ( data != null || val ) {
3295                         e.type = "change";
3296                         e.liveFired = undefined;
3297                         jQuery.event.trigger( e, arguments[1], elem );
3298                 }
3299         };
3300
3301         jQuery.event.special.change = {
3302                 filters: {
3303                         focusout: testChange,
3304
3305                         beforedeactivate: testChange,
3306
3307                         click: function( e ) {
3308                                 var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3309
3310                                 if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) {
3311                                         testChange.call( this, e );
3312                                 }
3313                         },
3314
3315                         // Change has to be called before submit
3316                         // Keydown will be called before keypress, which is used in submit-event delegation
3317                         keydown: function( e ) {
3318                                 var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3319
3320                                 if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) ||
3321                                         (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
3322                                         type === "select-multiple" ) {
3323                                         testChange.call( this, e );
3324                                 }
3325                         },
3326
3327                         // Beforeactivate happens also before the previous element is blurred
3328                         // with this event you can't trigger a change event, but you can store
3329                         // information
3330                         beforeactivate: function( e ) {
3331                                 var elem = e.target;
3332                                 jQuery._data( elem, "_change_data", getVal(elem) );
3333                         }
3334                 },
3335
3336                 setup: function( data, namespaces ) {
3337                         if ( this.type === "file" ) {
3338                                 return false;
3339                         }
3340
3341                         for ( var type in changeFilters ) {
3342                                 jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
3343                         }
3344
3345                         return rformElems.test( this.nodeName );
3346                 },
3347
3348                 teardown: function( namespaces ) {
3349                         jQuery.event.remove( this, ".specialChange" );
3350
3351                         return rformElems.test( this.nodeName );
3352                 }
3353         };
3354
3355         changeFilters = jQuery.event.special.change.filters;
3356
3357         // Handle when the input is .focus()'d
3358         changeFilters.focus = changeFilters.beforeactivate;
3359 }
3360
3361 function trigger( type, elem, args ) {
3362         // Piggyback on a donor event to simulate a different one.
3363         // Fake originalEvent to avoid donor's stopPropagation, but if the
3364         // simulated event prevents default then we do the same on the donor.
3365         // Don't pass args or remember liveFired; they apply to the donor event.
3366         var event = jQuery.extend( {}, args[ 0 ] );
3367         event.type = type;
3368         event.originalEvent = {};
3369         event.liveFired = undefined;
3370         jQuery.event.handle.call( elem, event );
3371         if ( event.isDefaultPrevented() ) {
3372                 args[ 0 ].preventDefault();
3373         }
3374 }
3375
3376 // Create "bubbling" focus and blur events
3377 if ( !jQuery.support.focusinBubbles ) {
3378         jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
3379
3380                 // Attach a single capturing handler while someone wants focusin/focusout
3381                 var attaches = 0;
3382
3383                 jQuery.event.special[ fix ] = {
3384                         setup: function() {
3385                                 if ( attaches++ === 0 ) {
3386                                         document.addEventListener( orig, handler, true );
3387                                 }
3388                         },
3389                         teardown: function() {
3390                                 if ( --attaches === 0 ) {
3391                                         document.removeEventListener( orig, handler, true );
3392                                 }
3393                         }
3394                 };
3395
3396                 function handler( donor ) {
3397                         // Donor event is always a native one; fix it and switch its type.
3398                         // Let focusin/out handler cancel the donor focus/blur event.
3399                         var e = jQuery.event.fix( donor );
3400                         e.type = fix;
3401                         e.originalEvent = {};
3402                         jQuery.event.trigger( e, null, e.target );
3403                         if ( e.isDefaultPrevented() ) {
3404                                 donor.preventDefault();
3405                         }
3406                 }
3407         });
3408 }
3409
3410 jQuery.each(["bind", "one"], function( i, name ) {
3411         jQuery.fn[ name ] = function( type, data, fn ) {
3412                 var handler;
3413
3414                 // Handle object literals
3415                 if ( typeof type === "object" ) {
3416                         for ( var key in type ) {
3417                                 this[ name ](key, data, type[key], fn);
3418                         }
3419                         return this;
3420                 }
3421
3422                 if ( arguments.length === 2 || data === false ) {
3423                         fn = data;
3424                         data = undefined;
3425                 }
3426
3427                 if ( name === "one" ) {
3428                         handler = function( event ) {
3429                                 jQuery( this ).unbind( event, handler );
3430                                 return fn.apply( this, arguments );
3431                         };
3432                         handler.guid = fn.guid || jQuery.guid++;
3433                 } else {
3434                         handler = fn;
3435                 }
3436
3437                 if ( type === "unload" && name !== "one" ) {
3438                         this.one( type, data, fn );
3439
3440                 } else {
3441                         for ( var i = 0, l = this.length; i < l; i++ ) {
3442                                 jQuery.event.add( this[i], type, handler, data );
3443                         }
3444                 }
3445
3446                 return this;
3447         };
3448 });
3449
3450 jQuery.fn.extend({
3451         unbind: function( type, fn ) {
3452                 // Handle object literals
3453                 if ( typeof type === "object" && !type.preventDefault ) {
3454                         for ( var key in type ) {
3455                                 this.unbind(key, type[key]);
3456                         }
3457
3458                 } else {
3459                         for ( var i = 0, l = this.length; i < l; i++ ) {
3460                                 jQuery.event.remove( this[i], type, fn );
3461                         }
3462                 }
3463
3464                 return this;
3465         },
3466
3467         delegate: function( selector, types, data, fn ) {
3468                 return this.live( types, data, fn, selector );
3469         },
3470
3471         undelegate: function( selector, types, fn ) {
3472                 if ( arguments.length === 0 ) {
3473                         return this.unbind( "live" );
3474
3475                 } else {
3476                         return this.die( types, null, fn, selector );
3477                 }
3478         },
3479
3480         trigger: function( type, data ) {
3481                 return this.each(function() {
3482                         jQuery.event.trigger( type, data, this );
3483                 });
3484         },
3485
3486         triggerHandler: function( type, data ) {
3487                 if ( this[0] ) {
3488                         return jQuery.event.trigger( type, data, this[0], true );
3489                 }
3490         },
3491
3492         toggle: function( fn ) {
3493                 // Save reference to arguments for access in closure
3494                 var args = arguments,
3495                         guid = fn.guid || jQuery.guid++,
3496                         i = 0,
3497                         toggler = function( event ) {
3498                                 // Figure out which function to execute
3499                                 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
3500                                 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
3501
3502                                 // Make sure that clicks stop
3503                                 event.preventDefault();
3504
3505                                 // and execute the function
3506                                 return args[ lastToggle ].apply( this, arguments ) || false;
3507                         };
3508
3509                 // link all the functions, so any of them can unbind this click handler
3510                 toggler.guid = guid;
3511                 while ( i < args.length ) {
3512                         args[ i++ ].guid = guid;
3513                 }
3514
3515                 return this.click( toggler );
3516         },
3517
3518         hover: function( fnOver, fnOut ) {
3519                 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
3520         }
3521 });
3522
3523 var liveMap = {
3524         focus: "focusin",
3525         blur: "focusout",
3526         mouseenter: "mouseover",
3527         mouseleave: "mouseout"
3528 };
3529
3530 jQuery.each(["live", "die"], function( i, name ) {
3531         jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
3532                 var type, i = 0, match, namespaces, preType,
3533                         selector = origSelector || this.selector,
3534                         context = origSelector ? this : jQuery( this.context );
3535
3536                 if ( typeof types === "object" && !types.preventDefault ) {
3537                         for ( var key in types ) {
3538                                 context[ name ]( key, data, types[key], selector );
3539                         }
3540
3541                         return this;
3542                 }
3543
3544                 if ( name === "die" && !types &&
3545                                         origSelector && origSelector.charAt(0) === "." ) {
3546
3547                         context.unbind( origSelector );
3548
3549                         return this;
3550                 }
3551
3552                 if ( data === false || jQuery.isFunction( data ) ) {
3553                         fn = data || returnFalse;
3554                         data = undefined;
3555                 }
3556
3557                 types = (types || "").split(" ");
3558
3559                 while ( (type = types[ i++ ]) != null ) {
3560                         match = rnamespaces.exec( type );
3561                         namespaces = "";
3562
3563                         if ( match )  {
3564                                 namespaces = match[0];
3565                                 type = type.replace( rnamespaces, "" );
3566                         }
3567
3568                         if ( type === "hover" ) {
3569                                 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
3570                                 continue;
3571                         }
3572
3573                         preType = type;
3574
3575                         if ( liveMap[ type ] ) {
3576                                 types.push( liveMap[ type ] + namespaces );
3577                                 type = type + namespaces;
3578
3579                         } else {
3580                                 type = (liveMap[ type ] || type) + namespaces;
3581                         }
3582
3583                         if ( name === "live" ) {
3584                                 // bind live handler
3585                                 for ( var j = 0, l = context.length; j < l; j++ ) {
3586                                         jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
3587                                                 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
3588                                 }
3589
3590                         } else {
3591                                 // unbind live handler
3592                                 context.unbind( "live." + liveConvert( type, selector ), fn );
3593                         }
3594                 }
3595
3596                 return this;
3597         };
3598 });
3599
3600 function liveHandler( event ) {
3601         var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
3602                 elems = [],
3603                 selectors = [],
3604                 events = jQuery._data( this, "events" );
3605
3606         // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911)
3607         if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) {
3608                 return;
3609         }
3610
3611         if ( event.namespace ) {
3612                 namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
3613         }
3614
3615         event.liveFired = this;
3616
3617         var live = events.live.slice(0);
3618
3619         for ( j = 0; j < live.length; j++ ) {
3620                 handleObj = live[j];
3621
3622                 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
3623                         selectors.push( handleObj.selector );
3624
3625                 } else {
3626                         live.splice( j--, 1 );
3627                 }
3628         }
3629
3630         match = jQuery( event.target ).closest( selectors, event.currentTarget );
3631
3632         for ( i = 0, l = match.length; i < l; i++ ) {
3633                 close = match[i];
3634
3635                 for ( j = 0; j < live.length; j++ ) {
3636                         handleObj = live[j];
3637
3638                         if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) {
3639                                 elem = close.elem;
3640                                 related = null;
3641
3642                                 // Those two events require additional checking
3643                                 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
3644                                         event.type = handleObj.preType;
3645                                         related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
3646
3647                                         // Make sure not to accidentally match a child element with the same selector
3648                                         if ( related && jQuery.contains( elem, related ) ) {
3649                                                 related = elem;
3650                                         }
3651                                 }
3652
3653                                 if ( !related || related !== elem ) {
3654                                         elems.push({ elem: elem, handleObj: handleObj, level: close.level });
3655                                 }
3656                         }
3657                 }
3658         }
3659
3660         for ( i = 0, l = elems.length; i < l; i++ ) {
3661                 match = elems[i];
3662
3663                 if ( maxLevel && match.level > maxLevel ) {
3664                         break;
3665                 }
3666
3667                 event.currentTarget = match.elem;
3668                 event.data = match.handleObj.data;
3669                 event.handleObj = match.handleObj;
3670
3671                 ret = match.handleObj.origHandler.apply( match.elem, arguments );
3672
3673                 if ( ret === false || event.isPropagationStopped() ) {
3674                         maxLevel = match.level;
3675
3676                         if ( ret === false ) {
3677                                 stop = false;
3678                         }
3679                         if ( event.isImmediatePropagationStopped() ) {
3680                                 break;
3681                         }
3682                 }
3683         }
3684
3685         return stop;
3686 }
3687
3688 function liveConvert( type, selector ) {
3689         return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&");
3690 }
3691
3692 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
3693         "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
3694         "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
3695
3696         // Handle event binding
3697         jQuery.fn[ name ] = function( data, fn ) {
3698                 if ( fn == null ) {
3699                         fn = data;
3700                         data = null;
3701                 }
3702
3703                 return arguments.length > 0 ?
3704                         this.bind( name, data, fn ) :
3705                         this.trigger( name );
3706         };
3707
3708         if ( jQuery.attrFn ) {
3709                 jQuery.attrFn[ name ] = true;
3710         }
3711 });
3712
3713
3714
3715 /*!
3716  * Sizzle CSS Selector Engine
3717  *  Copyright 2011, The Dojo Foundation
3718  *  Released under the MIT, BSD, and GPL Licenses.
3719  *  More information: http://sizzlejs.com/
3720  */
3721 (function(){
3722
3723 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
3724         done = 0,
3725         toString = Object.prototype.toString,
3726         hasDuplicate = false,
3727         baseHasDuplicate = true,
3728         rBackslash = /\\/g,
3729         rNonWord = /\W/;
3730
3731 // Here we check if the JavaScript engine is using some sort of
3732 // optimization where it does not always call our comparision
3733 // function. If that is the case, discard the hasDuplicate value.
3734 //   Thus far that includes Google Chrome.
3735 [0, 0].sort(function() {
3736         baseHasDuplicate = false;
3737         return 0;
3738 });
3739
3740 var Sizzle = function( selector, context, results, seed ) {
3741         results = results || [];
3742         context = context || document;
3743
3744         var origContext = context;
3745
3746         if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
3747                 return [];
3748         }
3749         
3750         if ( !selector || typeof selector !== "string" ) {
3751                 return results;
3752         }
3753
3754         var m, set, checkSet, extra, ret, cur, pop, i,
3755                 prune = true,
3756                 contextXML = Sizzle.isXML( context ),
3757                 parts = [],
3758                 soFar = selector;
3759         
3760         // Reset the position of the chunker regexp (start from head)
3761         do {
3762                 chunker.exec( "" );
3763                 m = chunker.exec( soFar );
3764
3765                 if ( m ) {
3766                         soFar = m[3];
3767                 
3768                         parts.push( m[1] );
3769                 
3770                         if ( m[2] ) {
3771                                 extra = m[3];
3772                                 break;
3773                         }
3774                 }
3775         } while ( m );
3776
3777         if ( parts.length > 1 && origPOS.exec( selector ) ) {
3778
3779                 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
3780                         set = posProcess( parts[0] + parts[1], context );
3781
3782                 } else {
3783                         set = Expr.relative[ parts[0] ] ?
3784                                 [ context ] :
3785                                 Sizzle( parts.shift(), context );
3786
3787                         while ( parts.length ) {
3788                                 selector = parts.shift();
3789
3790                                 if ( Expr.relative[ selector ] ) {
3791                                         selector += parts.shift();
3792                                 }
3793                                 
3794                                 set = posProcess( selector, set );
3795                         }
3796                 }
3797
3798         } else {
3799                 // Take a shortcut and set the context if the root selector is an ID
3800                 // (but not if it'll be faster if the inner selector is an ID)
3801                 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
3802                                 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
3803
3804                         ret = Sizzle.find( parts.shift(), context, contextXML );
3805                         context = ret.expr ?
3806                                 Sizzle.filter( ret.expr, ret.set )[0] :
3807                                 ret.set[0];
3808                 }
3809
3810                 if ( context ) {
3811                         ret = seed ?
3812                                 { expr: parts.pop(), set: makeArray(seed) } :
3813                                 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
3814
3815                         set = ret.expr ?
3816                                 Sizzle.filter( ret.expr, ret.set ) :
3817                                 ret.set;
3818
3819                         if ( parts.length > 0 ) {
3820                                 checkSet = makeArray( set );
3821
3822                         } else {
3823                                 prune = false;
3824                         }
3825
3826                         while ( parts.length ) {
3827                                 cur = parts.pop();
3828                                 pop = cur;
3829
3830                                 if ( !Expr.relative[ cur ] ) {
3831                                         cur = "";
3832                                 } else {
3833                                         pop = parts.pop();
3834                                 }
3835
3836                                 if ( pop == null ) {
3837                                         pop = context;
3838                                 }
3839
3840                                 Expr.relative[ cur ]( checkSet, pop, contextXML );
3841                         }
3842
3843                 } else {
3844                         checkSet = parts = [];
3845                 }
3846         }
3847
3848         if ( !checkSet ) {
3849                 checkSet = set;
3850         }
3851
3852         if ( !checkSet ) {
3853                 Sizzle.error( cur || selector );
3854         }
3855
3856         if ( toString.call(checkSet) === "[object Array]" ) {
3857                 if ( !prune ) {
3858                         results.push.apply( results, checkSet );
3859
3860                 } else if ( context && context.nodeType === 1 ) {
3861                         for ( i = 0; checkSet[i] != null; i++ ) {
3862                                 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
3863                                         results.push( set[i] );
3864                                 }
3865                         }
3866
3867                 } else {
3868                         for ( i = 0; checkSet[i] != null; i++ ) {
3869                                 if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
3870                                         results.push( set[i] );
3871                                 }
3872                         }
3873                 }
3874
3875         } else {
3876                 makeArray( checkSet, results );
3877         }
3878
3879         if ( extra ) {
3880                 Sizzle( extra, origContext, results, seed );
3881                 Sizzle.uniqueSort( results );
3882         }
3883
3884         return results;
3885 };
3886
3887 Sizzle.uniqueSort = function( results ) {
3888         if ( sortOrder ) {
3889                 hasDuplicate = baseHasDuplicate;
3890                 results.sort( sortOrder );
3891
3892                 if ( hasDuplicate ) {
3893                         for ( var i = 1; i < results.length; i++ ) {
3894                                 if ( results[i] === results[ i - 1 ] ) {
3895                                         results.splice( i--, 1 );
3896                                 }
3897                         }
3898                 }
3899         }
3900
3901         return results;
3902 };
3903
3904 Sizzle.matches = function( expr, set ) {
3905         return Sizzle( expr, null, null, set );
3906 };
3907
3908 Sizzle.matchesSelector = function( node, expr ) {
3909         return Sizzle( expr, null, null, [node] ).length > 0;
3910 };
3911
3912 Sizzle.find = function( expr, context, isXML ) {
3913         var set;
3914
3915         if ( !expr ) {
3916                 return [];
3917         }
3918
3919         for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
3920                 var match,
3921                         type = Expr.order[i];
3922                 
3923                 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
3924                         var left = match[1];
3925                         match.splice( 1, 1 );
3926
3927                         if ( left.substr( left.length - 1 ) !== "\\" ) {
3928                                 match[1] = (match[1] || "").replace( rBackslash, "" );
3929                                 set = Expr.find[ type ]( match, context, isXML );
3930
3931                                 if ( set != null ) {
3932                                         expr = expr.replace( Expr.match[ type ], "" );
3933                                         break;
3934                                 }
3935                         }
3936                 }
3937         }
3938
3939         if ( !set ) {
3940                 set = typeof context.getElementsByTagName !== "undefined" ?
3941                         context.getElementsByTagName( "*" ) :
3942                         [];
3943         }
3944
3945         return { set: set, expr: expr };
3946 };
3947
3948 Sizzle.filter = function( expr, set, inplace, not ) {
3949         var match, anyFound,
3950                 old = expr,
3951                 result = [],
3952                 curLoop = set,
3953                 isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
3954
3955         while ( expr && set.length ) {
3956                 for ( var type in Expr.filter ) {
3957                         if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
3958                                 var found, item,
3959                                         filter = Expr.filter[ type ],
3960                                         left = match[1];
3961
3962                                 anyFound = false;
3963
3964                                 match.splice(1,1);
3965
3966                                 if ( left.substr( left.length - 1 ) === "\\" ) {
3967                                         continue;
3968                                 }
3969
3970                                 if ( curLoop === result ) {
3971                                         result = [];
3972                                 }
3973
3974                                 if ( Expr.preFilter[ type ] ) {
3975                                         match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
3976
3977                                         if ( !match ) {
3978                                                 anyFound = found = true;
3979
3980                                         } else if ( match === true ) {
3981                                                 continue;
3982                                         }
3983                                 }
3984
3985                                 if ( match ) {
3986                                         for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
3987                                                 if ( item ) {
3988                                                         found = filter( item, match, i, curLoop );
3989                                                         var pass = not ^ !!found;
3990
3991                                                         if ( inplace && found != null ) {
3992                                                                 if ( pass ) {
3993                                                                         anyFound = true;
3994
3995                                                                 } else {
3996                                                                         curLoop[i] = false;
3997                                                                 }
3998
3999                                                         } else if ( pass ) {
4000                                                                 result.push( item );
4001                                                                 anyFound = true;
4002                                                         }
4003                                                 }
4004                                         }
4005                                 }
4006
4007                                 if ( found !== undefined ) {
4008                                         if ( !inplace ) {
4009                                                 curLoop = result;
4010                                         }
4011
4012                                         expr = expr.replace( Expr.match[ type ], "" );
4013
4014                                         if ( !anyFound ) {
4015                                                 return [];
4016                                         }
4017
4018                                         break;
4019                                 }
4020                         }
4021                 }
4022
4023                 // Improper expression
4024                 if ( expr === old ) {
4025                         if ( anyFound == null ) {
4026                                 Sizzle.error( expr );
4027
4028                         } else {
4029                                 break;
4030                         }
4031                 }
4032
4033                 old = expr;
4034         }
4035
4036         return curLoop;
4037 };
4038
4039 Sizzle.error = function( msg ) {
4040         throw "Syntax error, unrecognized expression: " + msg;
4041 };
4042
4043 var Expr = Sizzle.selectors = {
4044         order: [ "ID", "NAME", "TAG" ],
4045
4046         match: {
4047                 ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4048                 CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4049                 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
4050                 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
4051                 TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
4052                 CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
4053                 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
4054                 PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
4055         },
4056
4057         leftMatch: {},
4058
4059         attrMap: {
4060                 "class": "className",
4061                 "for": "htmlFor"
4062         },
4063
4064         attrHandle: {
4065                 href: function( elem ) {
4066                         return elem.getAttribute( "href" );
4067                 },
4068                 type: function( elem ) {
4069                         return elem.getAttribute( "type" );
4070                 }
4071         },
4072
4073         relative: {
4074                 "+": function(checkSet, part){
4075                         var isPartStr = typeof part === "string",
4076                                 isTag = isPartStr && !rNonWord.test( part ),
4077                                 isPartStrNotTag = isPartStr && !isTag;
4078
4079                         if ( isTag ) {
4080                                 part = part.toLowerCase();
4081                         }
4082
4083                         for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
4084                                 if ( (elem = checkSet[i]) ) {
4085                                         while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
4086
4087                                         checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
4088                                                 elem || false :
4089                                                 elem === part;
4090                                 }
4091                         }
4092
4093                         if ( isPartStrNotTag ) {
4094                                 Sizzle.filter( part, checkSet, true );
4095                         }
4096                 },
4097
4098                 ">": function( checkSet, part ) {
4099                         var elem,
4100                                 isPartStr = typeof part === "string",
4101                                 i = 0,
4102                                 l = checkSet.length;
4103
4104                         if ( isPartStr && !rNonWord.test( part ) ) {
4105                                 part = part.toLowerCase();
4106
4107                                 for ( ; i < l; i++ ) {
4108                                         elem = checkSet[i];
4109
4110                                         if ( elem ) {
4111                                                 var parent = elem.parentNode;
4112                                                 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
4113                                         }
4114                                 }
4115
4116                         } else {
4117                                 for ( ; i < l; i++ ) {
4118                                         elem = checkSet[i];
4119
4120                                         if ( elem ) {
4121                                                 checkSet[i] = isPartStr ?
4122                                                         elem.parentNode :
4123                                                         elem.parentNode === part;
4124                                         }
4125                                 }
4126
4127                                 if ( isPartStr ) {
4128                                         Sizzle.filter( part, checkSet, true );
4129                                 }
4130                         }
4131                 },
4132
4133                 "": function(checkSet, part, isXML){
4134                         var nodeCheck,
4135                                 doneName = done++,
4136                                 checkFn = dirCheck;
4137
4138                         if ( typeof part === "string" && !rNonWord.test( part ) ) {
4139                                 part = part.toLowerCase();
4140                                 nodeCheck = part;
4141                                 checkFn = dirNodeCheck;
4142                         }
4143
4144                         checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
4145                 },
4146
4147                 "~": function( checkSet, part, isXML ) {
4148                         var nodeCheck,
4149                                 doneName = done++,
4150                                 checkFn = dirCheck;
4151
4152                         if ( typeof part === "string" && !rNonWord.test( part ) ) {
4153                                 part = part.toLowerCase();
4154                                 nodeCheck = part;
4155                                 checkFn = dirNodeCheck;
4156                         }
4157
4158                         checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
4159                 }
4160         },
4161
4162         find: {
4163                 ID: function( match, context, isXML ) {
4164                         if ( typeof context.getElementById !== "undefined" && !isXML ) {
4165                                 var m = context.getElementById(match[1]);
4166                                 // Check parentNode to catch when Blackberry 4.6 returns
4167                                 // nodes that are no longer in the document #6963
4168                                 return m && m.parentNode ? [m] : [];
4169                         }
4170                 },
4171
4172                 NAME: function( match, context ) {
4173                         if ( typeof context.getElementsByName !== "undefined" ) {
4174                                 var ret = [],
4175                                         results = context.getElementsByName( match[1] );
4176
4177                                 for ( var i = 0, l = results.length; i < l; i++ ) {
4178                                         if ( results[i].getAttribute("name") === match[1] ) {
4179                                                 ret.push( results[i] );
4180                                         }
4181                                 }
4182
4183                                 return ret.length === 0 ? null : ret;
4184                         }
4185                 },
4186
4187                 TAG: function( match, context ) {
4188                         if ( typeof context.getElementsByTagName !== "undefined" ) {
4189                                 return context.getElementsByTagName( match[1] );
4190                         }
4191                 }
4192         },
4193         preFilter: {
4194                 CLASS: function( match, curLoop, inplace, result, not, isXML ) {
4195                         match = " " + match[1].replace( rBackslash, "" ) + " ";
4196
4197                         if ( isXML ) {
4198                                 return match;
4199                         }
4200
4201                         for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
4202                                 if ( elem ) {
4203                                         if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
4204                                                 if ( !inplace ) {
4205                                                         result.push( elem );
4206                                                 }
4207
4208                                         } else if ( inplace ) {
4209                                                 curLoop[i] = false;
4210                                         }
4211                                 }
4212                         }
4213
4214                         return false;
4215                 },
4216
4217                 ID: function( match ) {
4218                         return match[1].replace( rBackslash, "" );
4219                 },
4220
4221                 TAG: function( match, curLoop ) {
4222                         return match[1].replace( rBackslash, "" ).toLowerCase();
4223                 },
4224
4225                 CHILD: function( match ) {
4226                         if ( match[1] === "nth" ) {
4227                                 if ( !match[2] ) {
4228                                         Sizzle.error( match[0] );
4229                                 }
4230
4231                                 match[2] = match[2].replace(/^\+|\s*/g, '');
4232
4233                                 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
4234                                 var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
4235                                         match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
4236                                         !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
4237
4238                                 // calculate the numbers (first)n+(last) including if they are negative
4239                                 match[2] = (test[1] + (test[2] || 1)) - 0;
4240                                 match[3] = test[3] - 0;
4241                         }
4242                         else if ( match[2] ) {
4243                                 Sizzle.error( match[0] );
4244                         }
4245
4246                         // TODO: Move to normal caching system
4247                         match[0] = done++;
4248
4249                         return match;
4250                 },
4251
4252                 ATTR: function( match, curLoop, inplace, result, not, isXML ) {
4253                         var name = match[1] = match[1].replace( rBackslash, "" );
4254                         
4255                         if ( !isXML && Expr.attrMap[name] ) {
4256                                 match[1] = Expr.attrMap[name];
4257                         }
4258
4259                         // Handle if an un-quoted value was used
4260                         match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
4261
4262                         if ( match[2] === "~=" ) {
4263                                 match[4] = " " + match[4] + " ";
4264                         }
4265
4266                         return match;
4267                 },
4268
4269                 PSEUDO: function( match, curLoop, inplace, result, not ) {
4270                         if ( match[1] === "not" ) {
4271                                 // If we're dealing with a complex expression, or a simple one
4272                                 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
4273                                         match[3] = Sizzle(match[3], null, null, curLoop);
4274
4275                                 } else {
4276                                         var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
4277
4278                                         if ( !inplace ) {
4279                                                 result.push.apply( result, ret );
4280                                         }
4281
4282                                         return false;
4283                                 }
4284
4285                         } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
4286                                 return true;
4287                         }
4288                         
4289                         return match;
4290                 },
4291
4292                 POS: function( match ) {
4293                         match.unshift( true );
4294
4295                         return match;
4296                 }
4297         },
4298         
4299         filters: {
4300                 enabled: function( elem ) {
4301                         return elem.disabled === false && elem.type !== "hidden";
4302                 },
4303
4304                 disabled: function( elem ) {
4305                         return elem.disabled === true;
4306                 },
4307
4308                 checked: function( elem ) {
4309                         return elem.checked === true;
4310                 },
4311                 
4312                 selected: function( elem ) {
4313                         // Accessing this property makes selected-by-default
4314                         // options in Safari work properly
4315                         if ( elem.parentNode ) {
4316                                 elem.parentNode.selectedIndex;
4317                         }
4318                         
4319                         return elem.selected === true;
4320                 },
4321
4322                 parent: function( elem ) {
4323                         return !!elem.firstChild;
4324                 },
4325
4326                 empty: function( elem ) {
4327                         return !elem.firstChild;
4328                 },
4329
4330                 has: function( elem, i, match ) {
4331                         return !!Sizzle( match[3], elem ).length;
4332                 },
4333
4334                 header: function( elem ) {
4335                         return (/h\d/i).test( elem.nodeName );
4336                 },
4337
4338                 text: function( elem ) {
4339                         var attr = elem.getAttribute( "type" ), type = elem.type;
4340                         // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) 
4341                         // use getAttribute instead to test this case
4342                         return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
4343                 },
4344
4345                 radio: function( elem ) {
4346                         return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
4347                 },
4348
4349                 checkbox: function( elem ) {
4350                         return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
4351                 },
4352
4353                 file: function( elem ) {
4354                         return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
4355                 },
4356
4357                 password: function( elem ) {
4358                         return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
4359                 },
4360
4361                 submit: function( elem ) {
4362                         var name = elem.nodeName.toLowerCase();
4363                         return (name === "input" || name === "button") && "submit" === elem.type;
4364                 },
4365
4366                 image: function( elem ) {
4367                         return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
4368                 },
4369
4370                 reset: function( elem ) {
4371                         var name = elem.nodeName.toLowerCase();
4372                         return (name === "input" || name === "button") && "reset" === elem.type;
4373                 },
4374
4375                 button: function( elem ) {
4376                         var name = elem.nodeName.toLowerCase();
4377                         return name === "input" && "button" === elem.type || name === "button";
4378                 },
4379
4380                 input: function( elem ) {
4381                         return (/input|select|textarea|button/i).test( elem.nodeName );
4382                 },
4383
4384                 focus: function( elem ) {
4385                         return elem === elem.ownerDocument.activeElement;
4386                 }
4387         },
4388         setFilters: {
4389                 first: function( elem, i ) {
4390                         return i === 0;
4391                 },
4392
4393                 last: function( elem, i, match, array ) {
4394                         return i === array.length - 1;
4395                 },
4396
4397                 even: function( elem, i ) {
4398                         return i % 2 === 0;
4399                 },
4400
4401                 odd: function( elem, i ) {
4402                         return i % 2 === 1;
4403                 },
4404
4405                 lt: function( elem, i, match ) {
4406                         return i < match[3] - 0;
4407                 },
4408
4409                 gt: function( elem, i, match ) {
4410                         return i > match[3] - 0;
4411                 },
4412
4413                 nth: function( elem, i, match ) {
4414                         return match[3] - 0 === i;
4415                 },
4416
4417                 eq: function( elem, i, match ) {
4418                         return match[3] - 0 === i;
4419                 }
4420         },
4421         filter: {
4422                 PSEUDO: function( elem, match, i, array ) {
4423                         var name = match[1],
4424                                 filter = Expr.filters[ name ];
4425
4426                         if ( filter ) {
4427                                 return filter( elem, i, match, array );
4428
4429                         } else if ( name === "contains" ) {
4430                                 return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
4431
4432                         } else if ( name === "not" ) {
4433                                 var not = match[3];
4434
4435                                 for ( var j = 0, l = not.length; j < l; j++ ) {
4436                                         if ( not[j] === elem ) {
4437                                                 return false;
4438                                         }
4439                                 }
4440
4441                                 return true;
4442
4443                         } else {
4444                                 Sizzle.error( name );
4445                         }
4446                 },
4447
4448                 CHILD: function( elem, match ) {
4449                         var type = match[1],
4450                                 node = elem;
4451
4452                         switch ( type ) {
4453                                 case "only":
4454                                 case "first":
4455                                         while ( (node = node.previousSibling) )  {
4456                                                 if ( node.nodeType === 1 ) { 
4457                                                         return false; 
4458                                                 }
4459                                         }
4460
4461                                         if ( type === "first" ) { 
4462                                                 return true; 
4463                                         }
4464
4465                                         node = elem;
4466
4467                                 case "last":
4468                                         while ( (node = node.nextSibling) )      {
4469                                                 if ( node.nodeType === 1 ) { 
4470                                                         return false; 
4471                                                 }
4472                                         }
4473
4474                                         return true;
4475
4476                                 case "nth":
4477                                         var first = match[2],
4478                                                 last = match[3];
4479
4480                                         if ( first === 1 && last === 0 ) {
4481                                                 return true;
4482                                         }
4483                                         
4484                                         var doneName = match[0],
4485                                                 parent = elem.parentNode;
4486         
4487                                         if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
4488                                                 var count = 0;
4489                                                 
4490                                                 for ( node = parent.firstChild; node; node = node.nextSibling ) {
4491                                                         if ( node.nodeType === 1 ) {
4492                                                                 node.nodeIndex = ++count;
4493                                                         }
4494                                                 } 
4495
4496                                                 parent.sizcache = doneName;
4497                                         }
4498                                         
4499                                         var diff = elem.nodeIndex - last;
4500
4501                                         if ( first === 0 ) {
4502                                                 return diff === 0;
4503
4504                                         } else {
4505                                                 return ( diff % first === 0 && diff / first >= 0 );
4506                                         }
4507                         }
4508                 },
4509
4510                 ID: function( elem, match ) {
4511                         return elem.nodeType === 1 && elem.getAttribute("id") === match;
4512                 },
4513
4514                 TAG: function( elem, match ) {
4515                         return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
4516                 },
4517                 
4518                 CLASS: function( elem, match ) {
4519                         return (" " + (elem.className || elem.getAttribute("class")) + " ")
4520                                 .indexOf( match ) > -1;
4521                 },
4522
4523                 ATTR: function( elem, match ) {
4524                         var name = match[1],
4525                                 result = Expr.attrHandle[ name ] ?
4526                                         Expr.attrHandle[ name ]( elem ) :
4527                                         elem[ name ] != null ?
4528                                                 elem[ name ] :
4529                                                 elem.getAttribute( name ),
4530                                 value = result + "",
4531                                 type = match[2],
4532                                 check = match[4];
4533
4534                         return result == null ?
4535                                 type === "!=" :
4536                                 type === "=" ?
4537                                 value === check :
4538                                 type === "*=" ?
4539                                 value.indexOf(check) >= 0 :
4540                                 type === "~=" ?
4541                                 (" " + value + " ").indexOf(check) >= 0 :
4542                                 !check ?
4543                                 value && result !== false :
4544                                 type === "!=" ?
4545                                 value !== check :
4546                                 type === "^=" ?
4547                                 value.indexOf(check) === 0 :
4548                                 type === "$=" ?
4549                                 value.substr(value.length - check.length) === check :
4550                                 type === "|=" ?
4551                                 value === check || value.substr(0, check.length + 1) === check + "-" :
4552                                 false;
4553                 },
4554
4555                 POS: function( elem, match, i, array ) {
4556                         var name = match[2],
4557                                 filter = Expr.setFilters[ name ];
4558
4559                         if ( filter ) {
4560                                 return filter( elem, i, match, array );
4561                         }
4562                 }
4563         }
4564 };
4565
4566 var origPOS = Expr.match.POS,
4567         fescape = function(all, num){
4568                 return "\\" + (num - 0 + 1);
4569         };
4570
4571 for ( var type in Expr.match ) {
4572         Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
4573         Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
4574 }
4575
4576 var makeArray = function( array, results ) {
4577         array = Array.prototype.slice.call( array, 0 );
4578
4579         if ( results ) {
4580                 results.push.apply( results, array );
4581                 return results;
4582         }
4583         
4584         return array;
4585 };
4586
4587 // Perform a simple check to determine if the browser is capable of
4588 // converting a NodeList to an array using builtin methods.
4589 // Also verifies that the returned array holds DOM nodes
4590 // (which is not the case in the Blackberry browser)
4591 try {
4592         Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
4593
4594 // Provide a fallback method if it does not work
4595 } catch( e ) {
4596         makeArray = function( array, results ) {
4597                 var i = 0,
4598                         ret = results || [];
4599
4600                 if ( toString.call(array) === "[object Array]" ) {
4601                         Array.prototype.push.apply( ret, array );
4602
4603                 } else {
4604                         if ( typeof array.length === "number" ) {
4605                                 for ( var l = array.length; i < l; i++ ) {
4606                                         ret.push( array[i] );
4607                                 }
4608
4609                         } else {
4610                                 for ( ; array[i]; i++ ) {
4611                                         ret.push( array[i] );
4612                                 }
4613                         }
4614                 }
4615
4616                 return ret;
4617         };
4618 }
4619
4620 var sortOrder, siblingCheck;
4621
4622 if ( document.documentElement.compareDocumentPosition ) {
4623         sortOrder = function( a, b ) {
4624                 if ( a === b ) {
4625                         hasDuplicate = true;
4626                         return 0;
4627                 }
4628
4629                 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
4630                         return a.compareDocumentPosition ? -1 : 1;
4631                 }
4632
4633                 return a.compareDocumentPosition(b) & 4 ? -1 : 1;
4634         };
4635
4636 } else {
4637         sortOrder = function( a, b ) {
4638                 // The nodes are identical, we can exit early
4639                 if ( a === b ) {
4640                         hasDuplicate = true;
4641                         return 0;
4642
4643                 // Fallback to using sourceIndex (in IE) if it's available on both nodes
4644                 } else if ( a.sourceIndex && b.sourceIndex ) {
4645                         return a.sourceIndex - b.sourceIndex;
4646                 }
4647
4648                 var al, bl,
4649                         ap = [],
4650                         bp = [],
4651                         aup = a.parentNode,
4652                         bup = b.parentNode,
4653                         cur = aup;
4654
4655                 // If the nodes are siblings (or identical) we can do a quick check
4656                 if ( aup === bup ) {
4657                         return siblingCheck( a, b );
4658
4659                 // If no parents were found then the nodes are disconnected
4660                 } else if ( !aup ) {
4661                         return -1;
4662
4663                 } else if ( !bup ) {
4664                         return 1;
4665                 }
4666
4667                 // Otherwise they're somewhere else in the tree so we need
4668                 // to build up a full list of the parentNodes for comparison
4669                 while ( cur ) {
4670                         ap.unshift( cur );
4671                         cur = cur.parentNode;
4672                 }
4673
4674                 cur = bup;
4675
4676                 while ( cur ) {
4677                         bp.unshift( cur );
4678                         cur = cur.parentNode;
4679                 }
4680
4681                 al = ap.length;
4682                 bl = bp.length;
4683
4684                 // Start walking down the tree looking for a discrepancy
4685                 for ( var i = 0; i < al && i < bl; i++ ) {
4686                         if ( ap[i] !== bp[i] ) {
4687                                 return siblingCheck( ap[i], bp[i] );
4688                         }
4689                 }
4690
4691                 // We ended someplace up the tree so do a sibling check
4692                 return i === al ?
4693                         siblingCheck( a, bp[i], -1 ) :
4694                         siblingCheck( ap[i], b, 1 );
4695         };
4696
4697         siblingCheck = function( a, b, ret ) {
4698                 if ( a === b ) {
4699                         return ret;
4700                 }
4701
4702                 var cur = a.nextSibling;
4703
4704                 while ( cur ) {
4705                         if ( cur === b ) {
4706                                 return -1;
4707                         }
4708
4709                         cur = cur.nextSibling;
4710                 }
4711
4712                 return 1;
4713         };
4714 }
4715
4716 // Utility function for retreiving the text value of an array of DOM nodes
4717 Sizzle.getText = function( elems ) {
4718         var ret = "", elem;
4719
4720         for ( var i = 0; elems[i]; i++ ) {
4721                 elem = elems[i];
4722
4723                 // Get the text from text nodes and CDATA nodes
4724                 if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
4725                         ret += elem.nodeValue;
4726
4727                 // Traverse everything else, except comment nodes
4728                 } else if ( elem.nodeType !== 8 ) {
4729                         ret += Sizzle.getText( elem.childNodes );
4730                 }
4731         }
4732
4733         return ret;
4734 };
4735
4736 // Check to see if the browser returns elements by name when
4737 // querying by getElementById (and provide a workaround)
4738 (function(){
4739         // We're going to inject a fake input element with a specified name
4740         var form = document.createElement("div"),
4741                 id = "script" + (new Date()).getTime(),
4742                 root = document.documentElement;
4743
4744         form.innerHTML = "<a name='" + id + "'/>";
4745
4746         // Inject it into the root element, check its status, and remove it quickly
4747         root.insertBefore( form, root.firstChild );
4748
4749         // The workaround has to do additional checks after a getElementById
4750         // Which slows things down for other browsers (hence the branching)
4751         if ( document.getElementById( id ) ) {
4752                 Expr.find.ID = function( match, context, isXML ) {
4753                         if ( typeof context.getElementById !== "undefined" && !isXML ) {
4754                                 var m = context.getElementById(match[1]);
4755
4756                                 return m ?
4757                                         m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
4758                                                 [m] :
4759                                                 undefined :
4760                                         [];
4761                         }
4762                 };
4763
4764                 Expr.filter.ID = function( elem, match ) {
4765                         var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
4766
4767                         return elem.nodeType === 1 && node && node.nodeValue === match;
4768                 };
4769         }
4770
4771         root.removeChild( form );
4772
4773         // release memory in IE
4774         root = form = null;
4775 })();
4776
4777 (function(){
4778         // Check to see if the browser returns only elements
4779         // when doing getElementsByTagName("*")
4780
4781         // Create a fake element
4782         var div = document.createElement("div");
4783         div.appendChild( document.createComment("") );
4784
4785         // Make sure no comments are found
4786         if ( div.getElementsByTagName("*").length > 0 ) {
4787                 Expr.find.TAG = function( match, context ) {
4788                         var results = context.getElementsByTagName( match[1] );
4789
4790                         // Filter out possible comments
4791                         if ( match[1] === "*" ) {
4792                                 var tmp = [];
4793
4794                                 for ( var i = 0; results[i]; i++ ) {
4795                                         if ( results[i].nodeType === 1 ) {
4796                                                 tmp.push( results[i] );
4797                                         }
4798                                 }
4799
4800                                 results = tmp;
4801                         }
4802
4803                         return results;
4804                 };
4805         }
4806
4807         // Check to see if an attribute returns normalized href attributes
4808         div.innerHTML = "<a href='#'></a>";
4809
4810         if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
4811                         div.firstChild.getAttribute("href") !== "#" ) {
4812
4813                 Expr.attrHandle.href = function( elem ) {
4814                         return elem.getAttribute( "href", 2 );
4815                 };
4816         }
4817
4818         // release memory in IE
4819         div = null;
4820 })();
4821
4822 if ( document.querySelectorAll ) {
4823         (function(){
4824                 var oldSizzle = Sizzle,
4825                         div = document.createElement("div"),
4826                         id = "__sizzle__";
4827
4828                 div.innerHTML = "<p class='TEST'></p>";
4829
4830                 // Safari can't handle uppercase or unicode characters when
4831                 // in quirks mode.
4832                 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
4833                         return;
4834                 }
4835         
4836                 Sizzle = function( query, context, extra, seed ) {
4837                         context = context || document;
4838
4839                         // Only use querySelectorAll on non-XML documents
4840                         // (ID selectors don't work in non-HTML documents)
4841                         if ( !seed && !Sizzle.isXML(context) ) {
4842                                 // See if we find a selector to speed up
4843                                 var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
4844                                 
4845                                 if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
4846                                         // Speed-up: Sizzle("TAG")
4847                                         if ( match[1] ) {
4848                                                 return makeArray( context.getElementsByTagName( query ), extra );
4849                                         
4850                                         // Speed-up: Sizzle(".CLASS")
4851                                         } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
4852                                                 return makeArray( context.getElementsByClassName( match[2] ), extra );
4853                                         }
4854                                 }
4855                                 
4856                                 if ( context.nodeType === 9 ) {
4857                                         // Speed-up: Sizzle("body")
4858                                         // The body element only exists once, optimize finding it
4859                                         if ( query === "body" && context.body ) {
4860                                                 return makeArray( [ context.body ], extra );
4861                                                 
4862                                         // Speed-up: Sizzle("#ID")
4863                                         } else if ( match && match[3] ) {
4864                                                 var elem = context.getElementById( match[3] );
4865
4866                                                 // Check parentNode to catch when Blackberry 4.6 returns
4867                                                 // nodes that are no longer in the document #6963
4868                                                 if ( elem && elem.parentNode ) {
4869                                                         // Handle the case where IE and Opera return items
4870                                                         // by name instead of ID
4871                                                         if ( elem.id === match[3] ) {
4872                                                                 return makeArray( [ elem ], extra );
4873                                                         }
4874                                                         
4875                                                 } else {
4876                                                         return makeArray( [], extra );
4877                                                 }
4878                                         }
4879                                         
4880                                         try {
4881                                                 return makeArray( context.querySelectorAll(query), extra );
4882                                         } catch(qsaError) {}
4883
4884                                 // qSA works strangely on Element-rooted queries
4885                                 // We can work around this by specifying an extra ID on the root
4886                                 // and working up from there (Thanks to Andrew Dupont for the technique)
4887                                 // IE 8 doesn't work on object elements
4888                                 } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
4889                                         var oldContext = context,
4890                                                 old = context.getAttribute( "id" ),
4891                                                 nid = old || id,
4892                                                 hasParent = context.parentNode,
4893                                                 relativeHierarchySelector = /^\s*[+~]/.test( query );
4894
4895                                         if ( !old ) {
4896                                                 context.setAttribute( "id", nid );
4897                                         } else {
4898                                                 nid = nid.replace( /'/g, "\\$&" );
4899                                         }
4900                                         if ( relativeHierarchySelector && hasParent ) {
4901                                                 context = context.parentNode;
4902                                         }
4903
4904                                         try {
4905                                                 if ( !relativeHierarchySelector || hasParent ) {
4906                                                         return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
4907                                                 }
4908
4909                                         } catch(pseudoError) {
4910                                         } finally {
4911                                                 if ( !old ) {
4912                                                         oldContext.removeAttribute( "id" );
4913                                                 }
4914                                         }
4915                                 }
4916                         }
4917                 
4918                         return oldSizzle(query, context, extra, seed);
4919                 };
4920
4921                 for ( var prop in oldSizzle ) {
4922                         Sizzle[ prop ] = oldSizzle[ prop ];
4923                 }
4924
4925                 // release memory in IE
4926                 div = null;
4927         })();
4928 }
4929
4930 (function(){
4931         var html = document.documentElement,
4932                 matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
4933
4934         if ( matches ) {
4935                 // Check to see if it's possible to do matchesSelector
4936                 // on a disconnected node (IE 9 fails this)
4937                 var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
4938                         pseudoWorks = false;
4939
4940                 try {
4941                         // This should fail with an exception
4942                         // Gecko does not error, returns false instead
4943                         matches.call( document.documentElement, "[test!='']:sizzle" );
4944         
4945                 } catch( pseudoError ) {
4946                         pseudoWorks = true;
4947                 }
4948
4949                 Sizzle.matchesSelector = function( node, expr ) {
4950                         // Make sure that attribute selectors are quoted
4951                         expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
4952
4953                         if ( !Sizzle.isXML( node ) ) {
4954                                 try { 
4955                                         if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
4956                                                 var ret = matches.call( node, expr );
4957
4958                                                 // IE 9's matchesSelector returns false on disconnected nodes
4959                                                 if ( ret || !disconnectedMatch ||
4960                                                                 // As well, disconnected nodes are said to be in a document
4961                                                                 // fragment in IE 9, so check for that
4962                                                                 node.document && node.document.nodeType !== 11 ) {
4963                                                         return ret;
4964                                                 }
4965                                         }
4966                                 } catch(e) {}
4967                         }
4968
4969                         return Sizzle(expr, null, null, [node]).length > 0;
4970                 };
4971         }
4972 })();
4973
4974 (function(){
4975         var div = document.createElement("div");
4976
4977         div.innerHTML = "<div class='test e'></div><div class='test'></div>";
4978
4979         // Opera can't find a second classname (in 9.6)
4980         // Also, make sure that getElementsByClassName actually exists
4981         if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
4982                 return;
4983         }
4984
4985         // Safari caches class attributes, doesn't catch changes (in 3.2)
4986         div.lastChild.className = "e";
4987
4988         if ( div.getElementsByClassName("e").length === 1 ) {
4989                 return;
4990         }
4991         
4992         Expr.order.splice(1, 0, "CLASS");
4993         Expr.find.CLASS = function( match, context, isXML ) {
4994                 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
4995                         return context.getElementsByClassName(match[1]);
4996                 }
4997         };
4998
4999         // release memory in IE
5000         div = null;
5001 })();
5002
5003 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5004         for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5005                 var elem = checkSet[i];
5006
5007                 if ( elem ) {
5008                         var match = false;
5009
5010                         elem = elem[dir];
5011
5012                         while ( elem ) {
5013                                 if ( elem.sizcache === doneName ) {
5014                                         match = checkSet[elem.sizset];
5015                                         break;
5016                                 }
5017
5018                                 if ( elem.nodeType === 1 && !isXML ){
5019                                         elem.sizcache = doneName;
5020                                         elem.sizset = i;
5021                                 }
5022
5023                                 if ( elem.nodeName.toLowerCase() === cur ) {
5024                                         match = elem;
5025                                         break;
5026                                 }
5027
5028                                 elem = elem[dir];
5029                         }
5030
5031                         checkSet[i] = match;
5032                 }
5033         }
5034 }
5035
5036 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5037         for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5038                 var elem = checkSet[i];
5039
5040                 if ( elem ) {
5041                         var match = false;
5042                         
5043                         elem = elem[dir];
5044
5045                         while ( elem ) {
5046                                 if ( elem.sizcache === doneName ) {
5047                                         match = checkSet[elem.sizset];
5048                                         break;
5049                                 }
5050
5051                                 if ( elem.nodeType === 1 ) {
5052                                         if ( !isXML ) {
5053                                                 elem.sizcache = doneName;
5054                                                 elem.sizset = i;
5055                                         }
5056
5057                                         if ( typeof cur !== "string" ) {
5058                                                 if ( elem === cur ) {
5059                                                         match = true;
5060                                                         break;
5061                                                 }
5062
5063                                         } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
5064                                                 match = elem;
5065                                                 break;
5066                                         }
5067                                 }
5068
5069                                 elem = elem[dir];
5070                         }
5071
5072                         checkSet[i] = match;
5073                 }
5074         }
5075 }
5076
5077 if ( document.documentElement.contains ) {
5078         Sizzle.contains = function( a, b ) {
5079                 return a !== b && (a.contains ? a.contains(b) : true);
5080         };
5081
5082 } else if ( document.documentElement.compareDocumentPosition ) {
5083         Sizzle.contains = function( a, b ) {
5084                 return !!(a.compareDocumentPosition(b) & 16);
5085         };
5086
5087 } else {
5088         Sizzle.contains = function() {
5089                 return false;
5090         };
5091 }
5092
5093 Sizzle.isXML = function( elem ) {
5094         // documentElement is verified for cases where it doesn't yet exist
5095         // (such as loading iframes in IE - #4833) 
5096         var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
5097
5098         return documentElement ? documentElement.nodeName !== "HTML" : false;
5099 };
5100
5101 var posProcess = function( selector, context ) {
5102         var match,
5103                 tmpSet = [],
5104                 later = "",
5105                 root = context.nodeType ? [context] : context;
5106
5107         // Position selectors must be done after the filter
5108         // And so must :not(positional) so we move all PSEUDOs to the end
5109         while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
5110                 later += match[0];
5111                 selector = selector.replace( Expr.match.PSEUDO, "" );
5112         }
5113
5114         selector = Expr.relative[selector] ? selector + "*" : selector;
5115
5116         for ( var i = 0, l = root.length; i < l; i++ ) {
5117                 Sizzle( selector, root[i], tmpSet );
5118         }
5119
5120         return Sizzle.filter( later, tmpSet );
5121 };
5122
5123 // EXPOSE
5124 jQuery.find = Sizzle;
5125 jQuery.expr = Sizzle.selectors;
5126 jQuery.expr[":"] = jQuery.expr.filters;
5127 jQuery.unique = Sizzle.uniqueSort;
5128 jQuery.text = Sizzle.getText;
5129 jQuery.isXMLDoc = Sizzle.isXML;
5130 jQuery.contains = Sizzle.contains;
5131
5132
5133 })();
5134
5135
5136 var runtil = /Until$/,
5137         rparentsprev = /^(?:parents|prevUntil|prevAll)/,
5138         // Note: This RegExp should be improved, or likely pulled from Sizzle
5139         rmultiselector = /,/,
5140         isSimple = /^.[^:#\[\.,]*$/,
5141         slice = Array.prototype.slice,
5142         POS = jQuery.expr.match.POS,
5143         // methods guaranteed to produce a unique set when starting from a unique set
5144         guaranteedUnique = {
5145                 children: true,
5146                 contents: true,
5147                 next: true,
5148                 prev: true
5149         };
5150
5151 jQuery.fn.extend({
5152         find: function( selector ) {
5153                 var self = this,
5154                         i, l;
5155
5156                 if ( typeof selector !== "string" ) {
5157                         return jQuery( selector ).filter(function() {
5158                                 for ( i = 0, l = self.length; i < l; i++ ) {
5159                                         if ( jQuery.contains( self[ i ], this ) ) {
5160                                                 return true;
5161                                         }
5162                                 }
5163                         });
5164                 }
5165
5166                 var ret = this.pushStack( "", "find", selector ),
5167                         length, n, r;
5168
5169                 for ( i = 0, l = this.length; i < l; i++ ) {
5170                         length = ret.length;
5171                         jQuery.find( selector, this[i], ret );
5172
5173                         if ( i > 0 ) {
5174                                 // Make sure that the results are unique
5175                                 for ( n = length; n < ret.length; n++ ) {
5176                                         for ( r = 0; r < length; r++ ) {
5177                                                 if ( ret[r] === ret[n] ) {
5178                                                         ret.splice(n--, 1);
5179                                                         break;
5180                                                 }
5181                                         }
5182                                 }
5183                         }
5184                 }
5185
5186                 return ret;
5187         },
5188
5189         has: function( target ) {
5190                 var targets = jQuery( target );
5191                 return this.filter(function() {
5192                         for ( var i = 0, l = targets.length; i < l; i++ ) {
5193                                 if ( jQuery.contains( this, targets[i] ) ) {
5194                                         return true;
5195                                 }
5196                         }
5197                 });
5198         },
5199
5200         not: function( selector ) {
5201                 return this.pushStack( winnow(this, selector, false), "not", selector);
5202         },
5203
5204         filter: function( selector ) {
5205                 return this.pushStack( winnow(this, selector, true), "filter", selector );
5206         },
5207
5208         is: function( selector ) {
5209                 return !!selector && ( typeof selector === "string" ?
5210                         jQuery.filter( selector, this ).length > 0 :
5211                         this.filter( selector ).length > 0 );
5212         },
5213
5214         closest: function( selectors, context ) {
5215                 var ret = [], i, l, cur = this[0];
5216                 
5217                 // Array
5218                 if ( jQuery.isArray( selectors ) ) {
5219                         var match, selector,
5220                                 matches = {},
5221                                 level = 1;
5222
5223                         if ( cur && selectors.length ) {
5224                                 for ( i = 0, l = selectors.length; i < l; i++ ) {
5225                                         selector = selectors[i];
5226
5227                                         if ( !matches[ selector ] ) {
5228                                                 matches[ selector ] = POS.test( selector ) ?
5229                                                         jQuery( selector, context || this.context ) :
5230                                                         selector;
5231                                         }
5232                                 }
5233
5234                                 while ( cur && cur.ownerDocument && cur !== context ) {
5235                                         for ( selector in matches ) {
5236                                                 match = matches[ selector ];
5237
5238                                                 if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) {
5239                                                         ret.push({ selector: selector, elem: cur, level: level });
5240                                                 }
5241                                         }
5242
5243                                         cur = cur.parentNode;
5244                                         level++;
5245                                 }
5246                         }
5247
5248                         return ret;
5249                 }
5250
5251                 // String
5252                 var pos = POS.test( selectors ) || typeof selectors !== "string" ?
5253                                 jQuery( selectors, context || this.context ) :
5254                                 0;
5255
5256                 for ( i = 0, l = this.length; i < l; i++ ) {
5257                         cur = this[i];
5258
5259                         while ( cur ) {
5260                                 if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
5261                                         ret.push( cur );
5262                                         break;
5263
5264                                 } else {
5265                                         cur = cur.parentNode;
5266                                         if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
5267                                                 break;
5268                                         }
5269                                 }
5270                         }
5271                 }
5272
5273                 ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
5274
5275                 return this.pushStack( ret, "closest", selectors );
5276         },
5277
5278         // Determine the position of an element within
5279         // the matched set of elements
5280         index: function( elem ) {
5281                 if ( !elem || typeof elem === "string" ) {
5282                         return jQuery.inArray( this[0],
5283                                 // If it receives a string, the selector is used
5284                                 // If it receives nothing, the siblings are used
5285                                 elem ? jQuery( elem ) : this.parent().children() );
5286                 }
5287                 // Locate the position of the desired element
5288                 return jQuery.inArray(
5289                         // If it receives a jQuery object, the first element is used
5290                         elem.jquery ? elem[0] : elem, this );
5291         },
5292
5293         add: function( selector, context ) {
5294                 var set = typeof selector === "string" ?
5295                                 jQuery( selector, context ) :
5296                                 jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
5297                         all = jQuery.merge( this.get(), set );
5298
5299                 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
5300                         all :
5301                         jQuery.unique( all ) );
5302         },
5303
5304         andSelf: function() {
5305                 return this.add( this.prevObject );
5306         }
5307 });
5308
5309 // A painfully simple check to see if an element is disconnected
5310 // from a document (should be improved, where feasible).
5311 function isDisconnected( node ) {
5312         return !node || !node.parentNode || node.parentNode.nodeType === 11;
5313 }
5314
5315 jQuery.each({
5316         parent: function( elem ) {
5317                 var parent = elem.parentNode;
5318                 return parent && parent.nodeType !== 11 ? parent : null;
5319         },
5320         parents: function( elem ) {
5321                 return jQuery.dir( elem, "parentNode" );
5322         },
5323         parentsUntil: function( elem, i, until ) {
5324                 return jQuery.dir( elem, "parentNode", until );
5325         },
5326         next: function( elem ) {
5327                 return jQuery.nth( elem, 2, "nextSibling" );
5328         },
5329         prev: function( elem ) {
5330                 return jQuery.nth( elem, 2, "previousSibling" );
5331         },
5332         nextAll: function( elem ) {
5333                 return jQuery.dir( elem, "nextSibling" );
5334         },
5335         prevAll: function( elem ) {
5336                 return jQuery.dir( elem, "previousSibling" );
5337         },
5338         nextUntil: function( elem, i, until ) {
5339                 return jQuery.dir( elem, "nextSibling", until );
5340         },
5341         prevUntil: function( elem, i, until ) {
5342                 return jQuery.dir( elem, "previousSibling", until );
5343         },
5344         siblings: function( elem ) {
5345                 return jQuery.sibling( elem.parentNode.firstChild, elem );
5346         },
5347         children: function( elem ) {
5348                 return jQuery.sibling( elem.firstChild );
5349         },
5350         contents: function( elem ) {
5351                 return jQuery.nodeName( elem, "iframe" ) ?
5352                         elem.contentDocument || elem.contentWindow.document :
5353                         jQuery.makeArray( elem.childNodes );
5354         }
5355 }, function( name, fn ) {
5356         jQuery.fn[ name ] = function( until, selector ) {
5357                 var ret = jQuery.map( this, fn, until ),
5358                         // The variable 'args' was introduced in
5359                         // https://github.com/jquery/jquery/commit/52a0238
5360                         // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed.
5361                         // http://code.google.com/p/v8/issues/detail?id=1050
5362                         args = slice.call(arguments);
5363
5364                 if ( !runtil.test( name ) ) {
5365                         selector = until;
5366                 }
5367
5368                 if ( selector && typeof selector === "string" ) {
5369                         ret = jQuery.filter( selector, ret );
5370                 }
5371
5372                 ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
5373
5374                 if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
5375                         ret = ret.reverse();
5376                 }
5377
5378                 return this.pushStack( ret, name, args.join(",") );
5379         };
5380 });
5381
5382 jQuery.extend({
5383         filter: function( expr, elems, not ) {
5384                 if ( not ) {
5385                         expr = ":not(" + expr + ")";
5386                 }
5387
5388                 return elems.length === 1 ?
5389                         jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
5390                         jQuery.find.matches(expr, elems);
5391         },
5392
5393         dir: function( elem, dir, until ) {
5394                 var matched = [],
5395                         cur = elem[ dir ];
5396
5397                 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
5398                         if ( cur.nodeType === 1 ) {
5399                                 matched.push( cur );
5400                         }
5401                         cur = cur[dir];
5402                 }
5403                 return matched;
5404         },
5405
5406         nth: function( cur, result, dir, elem ) {
5407                 result = result || 1;
5408                 var num = 0;
5409
5410                 for ( ; cur; cur = cur[dir] ) {
5411                         if ( cur.nodeType === 1 && ++num === result ) {
5412                                 break;
5413                         }
5414                 }
5415
5416                 return cur;
5417         },
5418
5419         sibling: function( n, elem ) {
5420                 var r = [];
5421
5422                 for ( ; n; n = n.nextSibling ) {
5423                         if ( n.nodeType === 1 && n !== elem ) {
5424                                 r.push( n );
5425                         }
5426                 }
5427
5428                 return r;
5429         }
5430 });
5431
5432 // Implement the identical functionality for filter and not
5433 function winnow( elements, qualifier, keep ) {
5434
5435         // Can't pass null or undefined to indexOf in Firefox 4
5436         // Set to 0 to skip string check
5437         qualifier = qualifier || 0;
5438
5439         if ( jQuery.isFunction( qualifier ) ) {
5440                 return jQuery.grep(elements, function( elem, i ) {
5441                         var retVal = !!qualifier.call( elem, i, elem );
5442                         return retVal === keep;
5443                 });
5444
5445         } else if ( qualifier.nodeType ) {
5446                 return jQuery.grep(elements, function( elem, i ) {
5447                         return (elem === qualifier) === keep;
5448                 });
5449
5450         } else if ( typeof qualifier === "string" ) {
5451                 var filtered = jQuery.grep(elements, function( elem ) {
5452                         return elem.nodeType === 1;
5453                 });
5454
5455                 if ( isSimple.test( qualifier ) ) {
5456                         return jQuery.filter(qualifier, filtered, !keep);
5457                 } else {
5458                         qualifier = jQuery.filter( qualifier, filtered );
5459                 }
5460         }
5461
5462         return jQuery.grep(elements, function( elem, i ) {
5463                 return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
5464         });
5465 }
5466
5467
5468
5469
5470 var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
5471         rleadingWhitespace = /^\s+/,
5472         rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
5473         rtagName = /<([\w:]+)/,
5474         rtbody = /<tbody/i,
5475         rhtml = /<|&#?\w+;/,
5476         rnocache = /<(?:script|object|embed|option|style)/i,
5477         // checked="checked" or checked
5478         rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5479         rscriptType = /\/(java|ecma)script/i,
5480         rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/,
5481         wrapMap = {
5482                 option: [ 1, "<select multiple='multiple'>", "</select>" ],
5483                 legend: [ 1, "<fieldset>", "</fieldset>" ],
5484                 thead: [ 1, "<table>", "</table>" ],
5485                 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
5486                 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
5487                 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
5488                 area: [ 1, "<map>", "</map>" ],
5489                 _default: [ 0, "", "" ]
5490         };
5491
5492 wrapMap.optgroup = wrapMap.option;
5493 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5494 wrapMap.th = wrapMap.td;
5495
5496 // IE can't serialize <link> and <script> tags normally
5497 if ( !jQuery.support.htmlSerialize ) {
5498         wrapMap._default = [ 1, "div<div>", "</div>" ];
5499 }
5500
5501 jQuery.fn.extend({
5502         text: function( text ) {
5503                 if ( jQuery.isFunction(text) ) {
5504                         return this.each(function(i) {
5505                                 var self = jQuery( this );
5506
5507                                 self.text( text.call(this, i, self.text()) );
5508                         });
5509                 }
5510
5511                 if ( typeof text !== "object" && text !== undefined ) {
5512                         return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
5513                 }
5514
5515                 return jQuery.text( this );
5516         },
5517
5518         wrapAll: function( html ) {
5519                 if ( jQuery.isFunction( html ) ) {
5520                         return this.each(function(i) {
5521                                 jQuery(this).wrapAll( html.call(this, i) );
5522                         });
5523                 }
5524
5525                 if ( this[0] ) {
5526                         // The elements to wrap the target around
5527                         var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
5528
5529                         if ( this[0].parentNode ) {
5530                                 wrap.insertBefore( this[0] );
5531                         }
5532
5533                         wrap.map(function() {
5534                                 var elem = this;
5535
5536                                 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
5537                                         elem = elem.firstChild;
5538                                 }
5539
5540                                 return elem;
5541                         }).append( this );
5542                 }
5543
5544                 return this;
5545         },
5546
5547         wrapInner: function( html ) {
5548                 if ( jQuery.isFunction( html ) ) {
5549                         return this.each(function(i) {
5550                                 jQuery(this).wrapInner( html.call(this, i) );
5551                         });
5552                 }
5553
5554                 return this.each(function() {
5555                         var self = jQuery( this ),
5556                                 contents = self.contents();
5557
5558                         if ( contents.length ) {
5559                                 contents.wrapAll( html );
5560
5561                         } else {
5562                                 self.append( html );
5563                         }
5564                 });
5565         },
5566
5567         wrap: function( html ) {
5568                 return this.each(function() {
5569                         jQuery( this ).wrapAll( html );
5570                 });
5571         },
5572
5573         unwrap: function() {
5574                 return this.parent().each(function() {
5575                         if ( !jQuery.nodeName( this, "body" ) ) {
5576                                 jQuery( this ).replaceWith( this.childNodes );
5577                         }
5578                 }).end();
5579         },
5580
5581         append: function() {
5582                 return this.domManip(arguments, true, function( elem ) {
5583                         if ( this.nodeType === 1 ) {
5584                                 this.appendChild( elem );
5585                         }
5586                 });
5587         },
5588
5589         prepend: function() {
5590                 return this.domManip(arguments, true, function( elem ) {
5591                         if ( this.nodeType === 1 ) {
5592                                 this.insertBefore( elem, this.firstChild );
5593                         }
5594                 });
5595         },
5596
5597         before: function() {
5598                 if ( this[0] && this[0].parentNode ) {
5599                         return this.domManip(arguments, false, function( elem ) {
5600                                 this.parentNode.insertBefore( elem, this );
5601                         });
5602                 } else if ( arguments.length ) {
5603                         var set = jQuery(arguments[0]);
5604                         set.push.apply( set, this.toArray() );
5605                         return this.pushStack( set, "before", arguments );
5606                 }
5607         },
5608
5609         after: function() {
5610                 if ( this[0] && this[0].parentNode ) {
5611                         return this.domManip(arguments, false, function( elem ) {
5612                                 this.parentNode.insertBefore( elem, this.nextSibling );
5613                         });
5614                 } else if ( arguments.length ) {
5615                         var set = this.pushStack( this, "after", arguments );
5616                         set.push.apply( set, jQuery(arguments[0]).toArray() );
5617                         return set;
5618                 }
5619         },
5620
5621         // keepData is for internal use only--do not document
5622         remove: function( selector, keepData ) {
5623                 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5624                         if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
5625                                 if ( !keepData && elem.nodeType === 1 ) {
5626                                         jQuery.cleanData( elem.getElementsByTagName("*") );
5627                                         jQuery.cleanData( [ elem ] );
5628                                 }
5629
5630                                 if ( elem.parentNode ) {
5631                                         elem.parentNode.removeChild( elem );
5632                                 }
5633                         }
5634                 }
5635
5636                 return this;
5637         },
5638
5639         empty: function() {
5640                 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5641                         // Remove element nodes and prevent memory leaks
5642                         if ( elem.nodeType === 1 ) {
5643                                 jQuery.cleanData( elem.getElementsByTagName("*") );
5644                         }
5645
5646                         // Remove any remaining nodes
5647                         while ( elem.firstChild ) {
5648                                 elem.removeChild( elem.firstChild );
5649                         }
5650                 }
5651
5652                 return this;
5653         },
5654
5655         clone: function( dataAndEvents, deepDataAndEvents ) {
5656                 dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5657                 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5658
5659                 return this.map( function () {
5660                         return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5661                 });
5662         },
5663
5664         html: function( value ) {
5665                 if ( value === undefined ) {
5666                         return this[0] && this[0].nodeType === 1 ?
5667                                 this[0].innerHTML.replace(rinlinejQuery, "") :
5668                                 null;
5669
5670                 // See if we can take a shortcut and just use innerHTML
5671                 } else if ( typeof value === "string" && !rnocache.test( value ) &&
5672                         (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
5673                         !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
5674
5675                         value = value.replace(rxhtmlTag, "<$1></$2>");
5676
5677                         try {
5678                                 for ( var i = 0, l = this.length; i < l; i++ ) {
5679                                         // Remove element nodes and prevent memory leaks
5680                                         if ( this[i].nodeType === 1 ) {
5681                                                 jQuery.cleanData( this[i].getElementsByTagName("*") );
5682                                                 this[i].innerHTML = value;
5683                                         }
5684                                 }
5685
5686                         // If using innerHTML throws an exception, use the fallback method
5687                         } catch(e) {
5688                                 this.empty().append( value );
5689                         }
5690
5691                 } else if ( jQuery.isFunction( value ) ) {
5692                         this.each(function(i){
5693                                 var self = jQuery( this );
5694
5695                                 self.html( value.call(this, i, self.html()) );
5696                         });
5697
5698                 } else {
5699                         this.empty().append( value );
5700                 }
5701
5702                 return this;
5703         },
5704
5705         replaceWith: function( value ) {
5706                 if ( this[0] && this[0].parentNode ) {
5707                         // Make sure that the elements are removed from the DOM before they are inserted
5708                         // this can help fix replacing a parent with child elements
5709                         if ( jQuery.isFunction( value ) ) {
5710                                 return this.each(function(i) {
5711                                         var self = jQuery(this), old = self.html();
5712                                         self.replaceWith( value.call( this, i, old ) );
5713                                 });
5714                         }
5715
5716                         if ( typeof value !== "string" ) {
5717                                 value = jQuery( value ).detach();
5718                         }
5719
5720                         return this.each(function() {
5721                                 var next = this.nextSibling,
5722                                         parent = this.parentNode;
5723
5724                                 jQuery( this ).remove();
5725
5726                                 if ( next ) {
5727                                         jQuery(next).before( value );
5728                                 } else {
5729                                         jQuery(parent).append( value );
5730                                 }
5731                         });
5732                 } else {
5733                         return this.length ?
5734                                 this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
5735                                 this;
5736                 }
5737         },
5738
5739         detach: function( selector ) {
5740                 return this.remove( selector, true );
5741         },
5742
5743         domManip: function( args, table, callback ) {
5744                 var results, first, fragment, parent,
5745                         value = args[0],
5746                         scripts = [];
5747
5748                 // We can't cloneNode fragments that contain checked, in WebKit
5749                 if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
5750                         return this.each(function() {
5751                                 jQuery(this).domManip( args, table, callback, true );
5752                         });
5753                 }
5754
5755                 if ( jQuery.isFunction(value) ) {
5756                         return this.each(function(i) {
5757                                 var self = jQuery(this);
5758                                 args[0] = value.call(this, i, table ? self.html() : undefined);
5759                                 self.domManip( args, table, callback );
5760                         });
5761                 }
5762
5763                 if ( this[0] ) {
5764                         parent = value && value.parentNode;
5765
5766                         // If we're in a fragment, just use that instead of building a new one
5767                         if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
5768                                 results = { fragment: parent };
5769
5770                         } else {
5771                                 results = jQuery.buildFragment( args, this, scripts );
5772                         }
5773
5774                         fragment = results.fragment;
5775
5776                         if ( fragment.childNodes.length === 1 ) {
5777                                 first = fragment = fragment.firstChild;
5778                         } else {
5779                                 first = fragment.firstChild;
5780                         }
5781
5782                         if ( first ) {
5783                                 table = table && jQuery.nodeName( first, "tr" );
5784
5785                                 for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {
5786                                         callback.call(
5787                                                 table ?
5788                                                         root(this[i], first) :
5789                                                         this[i],
5790                                                 // Make sure that we do not leak memory by inadvertently discarding
5791                                                 // the original fragment (which might have attached data) instead of
5792                                                 // using it; in addition, use the original fragment object for the last
5793                                                 // item instead of first because it can end up being emptied incorrectly
5794                                                 // in certain situations (Bug #8070).
5795                                                 // Fragments from the fragment cache must always be cloned and never used
5796                                                 // in place.
5797                                                 results.cacheable || (l > 1 && i < lastIndex) ?
5798                                                         jQuery.clone( fragment, true, true ) :
5799                                                         fragment
5800                                         );
5801                                 }
5802                         }
5803
5804                         if ( scripts.length ) {
5805                                 jQuery.each( scripts, evalScript );
5806                         }
5807                 }
5808
5809                 return this;
5810         }
5811 });
5812
5813 function root( elem, cur ) {
5814         return jQuery.nodeName(elem, "table") ?
5815                 (elem.getElementsByTagName("tbody")[0] ||
5816                 elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
5817                 elem;
5818 }
5819
5820 function cloneCopyEvent( src, dest ) {
5821
5822         if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
5823                 return;
5824         }
5825
5826         var internalKey = jQuery.expando,
5827                 oldData = jQuery.data( src ),
5828                 curData = jQuery.data( dest, oldData );
5829
5830         // Switch to use the internal data object, if it exists, for the next
5831         // stage of data copying
5832         if ( (oldData = oldData[ internalKey ]) ) {
5833                 var events = oldData.events;
5834                                 curData = curData[ internalKey ] = jQuery.extend({}, oldData);
5835
5836                 if ( events ) {
5837                         delete curData.handle;
5838                         curData.events = {};
5839
5840                         for ( var type in events ) {
5841                                 for ( var i = 0, l = events[ type ].length; i < l; i++ ) {
5842                                         jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data );
5843                                 }
5844                         }
5845                 }
5846         }
5847 }
5848
5849 function cloneFixAttributes( src, dest ) {
5850         var nodeName;
5851
5852         // We do not need to do anything for non-Elements
5853         if ( dest.nodeType !== 1 ) {
5854                 return;
5855         }
5856
5857         // clearAttributes removes the attributes, which we don't want,
5858         // but also removes the attachEvent events, which we *do* want
5859         if ( dest.clearAttributes ) {
5860                 dest.clearAttributes();
5861         }
5862
5863         // mergeAttributes, in contrast, only merges back on the
5864         // original attributes, not the events
5865         if ( dest.mergeAttributes ) {
5866                 dest.mergeAttributes( src );
5867         }
5868
5869         nodeName = dest.nodeName.toLowerCase();
5870
5871         // IE6-8 fail to clone children inside object elements that use
5872         // the proprietary classid attribute value (rather than the type
5873         // attribute) to identify the type of content to display
5874         if ( nodeName === "object" ) {
5875                 dest.outerHTML = src.outerHTML;
5876
5877         } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
5878                 // IE6-8 fails to persist the checked state of a cloned checkbox
5879                 // or radio button. Worse, IE6-7 fail to give the cloned element
5880                 // a checked appearance if the defaultChecked value isn't also set
5881                 if ( src.checked ) {
5882                         dest.defaultChecked = dest.checked = src.checked;
5883                 }
5884
5885                 // IE6-7 get confused and end up setting the value of a cloned
5886                 // checkbox/radio button to an empty string instead of "on"
5887                 if ( dest.value !== src.value ) {
5888                         dest.value = src.value;
5889                 }
5890
5891         // IE6-8 fails to return the selected option to the default selected
5892         // state when cloning options
5893         } else if ( nodeName === "option" ) {
5894                 dest.selected = src.defaultSelected;
5895
5896         // IE6-8 fails to set the defaultValue to the correct value when
5897         // cloning other types of input fields
5898         } else if ( nodeName === "input" || nodeName === "textarea" ) {
5899                 dest.defaultValue = src.defaultValue;
5900         }
5901
5902         // Event data gets referenced instead of copied if the expando
5903         // gets copied too
5904         dest.removeAttribute( jQuery.expando );
5905 }
5906
5907 jQuery.buildFragment = function( args, nodes, scripts ) {
5908         var fragment, cacheable, cacheresults,
5909                 doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
5910
5911         // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
5912         // Cloning options loses the selected state, so don't cache them
5913         // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
5914         // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
5915         if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
5916                 args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
5917
5918                 cacheable = true;
5919
5920                 cacheresults = jQuery.fragments[ args[0] ];
5921                 if ( cacheresults && cacheresults !== 1 ) {
5922                         fragment = cacheresults;
5923                 }
5924         }
5925
5926         if ( !fragment ) {
5927                 fragment = doc.createDocumentFragment();
5928                 jQuery.clean( args, doc, fragment, scripts );
5929         }
5930
5931         if ( cacheable ) {
5932                 jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
5933         }
5934
5935         return { fragment: fragment, cacheable: cacheable };
5936 };
5937
5938 jQuery.fragments = {};
5939
5940 jQuery.each({
5941         appendTo: "append",
5942         prependTo: "prepend",
5943         insertBefore: "before",
5944         insertAfter: "after",
5945         replaceAll: "replaceWith"
5946 }, function( name, original ) {
5947         jQuery.fn[ name ] = function( selector ) {
5948                 var ret = [],
5949                         insert = jQuery( selector ),
5950                         parent = this.length === 1 && this[0].parentNode;
5951
5952                 if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
5953                         insert[ original ]( this[0] );
5954                         return this;
5955
5956                 } else {
5957                         for ( var i = 0, l = insert.length; i < l; i++ ) {
5958                                 var elems = (i > 0 ? this.clone(true) : this).get();
5959                                 jQuery( insert[i] )[ original ]( elems );
5960                                 ret = ret.concat( elems );
5961                         }
5962
5963                         return this.pushStack( ret, name, insert.selector );
5964                 }
5965         };
5966 });
5967
5968 function getAll( elem ) {
5969         if ( "getElementsByTagName" in elem ) {
5970                 return elem.getElementsByTagName( "*" );
5971
5972         } else if ( "querySelectorAll" in elem ) {
5973                 return elem.querySelectorAll( "*" );
5974
5975         } else {
5976                 return [];
5977         }
5978 }
5979
5980 // Used in clean, fixes the defaultChecked property
5981 function fixDefaultChecked( elem ) {
5982         if ( elem.type === "checkbox" || elem.type === "radio" ) {
5983                 elem.defaultChecked = elem.checked;
5984         }
5985 }
5986 // Finds all inputs and passes them to fixDefaultChecked
5987 function findInputs( elem ) {
5988         if ( jQuery.nodeName( elem, "input" ) ) {
5989                 fixDefaultChecked( elem );
5990         } else if ( elem.getElementsByTagName ) {
5991                 jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
5992         }
5993 }
5994
5995 jQuery.extend({
5996         clone: function( elem, dataAndEvents, deepDataAndEvents ) {
5997                 var clone = elem.cloneNode(true),
5998                                 srcElements,
5999                                 destElements,
6000                                 i;
6001
6002                 if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
6003                                 (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
6004                         // IE copies events bound via attachEvent when using cloneNode.
6005                         // Calling detachEvent on the clone will also remove the events
6006                         // from the original. In order to get around this, we use some
6007                         // proprietary methods to clear the events. Thanks to MooTools
6008                         // guys for this hotness.
6009
6010                         cloneFixAttributes( elem, clone );
6011
6012                         // Using Sizzle here is crazy slow, so we use getElementsByTagName
6013                         // instead
6014                         srcElements = getAll( elem );
6015                         destElements = getAll( clone );
6016
6017                         // Weird iteration because IE will replace the length property
6018                         // with an element if you are cloning the body and one of the
6019                         // elements on the page has a name or id of "length"
6020                         for ( i = 0; srcElements[i]; ++i ) {
6021                                 cloneFixAttributes( srcElements[i], destElements[i] );
6022                         }
6023                 }
6024
6025                 // Copy the events from the original to the clone
6026                 if ( dataAndEvents ) {
6027                         cloneCopyEvent( elem, clone );
6028
6029                         if ( deepDataAndEvents ) {
6030                                 srcElements = getAll( elem );
6031                                 destElements = getAll( clone );
6032
6033                                 for ( i = 0; srcElements[i]; ++i ) {
6034                                         cloneCopyEvent( srcElements[i], destElements[i] );
6035                                 }
6036                         }
6037                 }
6038
6039                 // Return the cloned set
6040                 return clone;
6041         },
6042
6043         clean: function( elems, context, fragment, scripts ) {
6044                 var checkScriptType;
6045
6046                 context = context || document;
6047
6048                 // !context.createElement fails in IE with an error but returns typeof 'object'
6049                 if ( typeof context.createElement === "undefined" ) {
6050                         context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
6051                 }
6052
6053                 var ret = [], j;
6054
6055                 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6056                         if ( typeof elem === "number" ) {
6057                                 elem += "";
6058                         }
6059
6060                         if ( !elem ) {
6061                                 continue;
6062                         }
6063
6064                         // Convert html string into DOM nodes
6065                         if ( typeof elem === "string" ) {
6066                                 if ( !rhtml.test( elem ) ) {
6067                                         elem = context.createTextNode( elem );
6068                                 } else {
6069                                         // Fix "XHTML"-style tags in all browsers
6070                                         elem = elem.replace(rxhtmlTag, "<$1></$2>");
6071
6072                                         // Trim whitespace, otherwise indexOf won't work as expected
6073                                         var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
6074                                                 wrap = wrapMap[ tag ] || wrapMap._default,
6075                                                 depth = wrap[0],
6076                                                 div = context.createElement("div");
6077
6078                                         // Go to html and back, then peel off extra wrappers
6079                                         div.innerHTML = wrap[1] + elem + wrap[2];
6080
6081                                         // Move to the right depth
6082                                         while ( depth-- ) {
6083                                                 div = div.lastChild;
6084                                         }
6085
6086                                         // Remove IE's autoinserted <tbody> from table fragments
6087                                         if ( !jQuery.support.tbody ) {
6088
6089                                                 // String was a <table>, *may* have spurious <tbody>
6090                                                 var hasBody = rtbody.test(elem),
6091                                                         tbody = tag === "table" && !hasBody ?
6092                                                                 div.firstChild && div.firstChild.childNodes :
6093
6094                                                                 // String was a bare <thead> or <tfoot>
6095                                                                 wrap[1] === "<table>" && !hasBody ?
6096                                                                         div.childNodes :
6097                                                                         [];
6098
6099                                                 for ( j = tbody.length - 1; j >= 0 ; --j ) {
6100                                                         if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
6101                                                                 tbody[ j ].parentNode.removeChild( tbody[ j ] );
6102                                                         }
6103                                                 }
6104                                         }
6105
6106                                         // IE completely kills leading whitespace when innerHTML is used
6107                                         if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
6108                                                 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
6109                                         }
6110
6111                                         elem = div.childNodes;
6112                                 }
6113                         }
6114
6115                         // Resets defaultChecked for any radios and checkboxes
6116                         // about to be appended to the DOM in IE 6/7 (#8060)
6117                         var len;
6118                         if ( !jQuery.support.appendChecked ) {
6119                                 if ( elem[0] && typeof (len = elem.length) === "number" ) {
6120                                         for ( j = 0; j < len; j++ ) {
6121                                                 findInputs( elem[j] );
6122                                         }
6123                                 } else {
6124                                         findInputs( elem );
6125                                 }
6126                         }
6127
6128                         if ( elem.nodeType ) {
6129                                 ret.push( elem );
6130                         } else {
6131                                 ret = jQuery.merge( ret, elem );
6132                         }
6133                 }
6134
6135                 if ( fragment ) {
6136                         checkScriptType = function( elem ) {
6137                                 return !elem.type || rscriptType.test( elem.type );
6138                         };
6139                         for ( i = 0; ret[i]; i++ ) {
6140                                 if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
6141                                         scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
6142
6143                                 } else {
6144                                         if ( ret[i].nodeType === 1 ) {
6145                                                 var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType );
6146
6147                                                 ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
6148                                         }
6149                                         fragment.appendChild( ret[i] );
6150                                 }
6151                         }
6152                 }
6153
6154                 return ret;
6155         },
6156
6157         cleanData: function( elems ) {
6158                 var data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special,
6159                         deleteExpando = jQuery.support.deleteExpando;
6160
6161                 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6162                         if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
6163                                 continue;
6164                         }
6165
6166                         id = elem[ jQuery.expando ];
6167
6168                         if ( id ) {
6169                                 data = cache[ id ] && cache[ id ][ internalKey ];
6170
6171                                 if ( data && data.events ) {
6172                                         for ( var type in data.events ) {
6173                                                 if ( special[ type ] ) {
6174                                                         jQuery.event.remove( elem, type );
6175
6176                                                 // This is a shortcut to avoid jQuery.event.remove's overhead
6177                                                 } else {
6178                                                         jQuery.removeEvent( elem, type, data.handle );
6179                                                 }
6180                                         }
6181
6182                                         // Null the DOM reference to avoid IE6/7/8 leak (#7054)
6183                                         if ( data.handle ) {
6184                                                 data.handle.elem = null;
6185                                         }
6186                                 }
6187
6188                                 if ( deleteExpando ) {
6189                                         delete elem[ jQuery.expando ];
6190
6191                                 } else if ( elem.removeAttribute ) {
6192                                         elem.removeAttribute( jQuery.expando );
6193                                 }
6194
6195                                 delete cache[ id ];
6196                         }
6197                 }
6198         }
6199 });
6200
6201 function evalScript( i, elem ) {
6202         if ( elem.src ) {
6203                 jQuery.ajax({
6204                         url: elem.src,
6205                         async: false,
6206                         dataType: "script"
6207                 });
6208         } else {
6209                 jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) );
6210         }
6211
6212         if ( elem.parentNode ) {
6213                 elem.parentNode.removeChild( elem );
6214         }
6215 }
6216
6217
6218
6219
6220 var ralpha = /alpha\([^)]*\)/i,
6221         ropacity = /opacity=([^)]*)/,
6222         rdashAlpha = /-([a-z])/ig,
6223         // fixed for IE9, see #8346
6224         rupper = /([A-Z]|^ms)/g,
6225         rnumpx = /^-?\d+(?:px)?$/i,
6226         rnum = /^-?\d/,
6227         rrelNum = /^[+\-]=/,
6228         rrelNumFilter = /[^+\-\.\de]+/g,
6229
6230         cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6231         cssWidth = [ "Left", "Right" ],
6232         cssHeight = [ "Top", "Bottom" ],
6233         curCSS,
6234
6235         getComputedStyle,
6236         currentStyle,
6237
6238         fcamelCase = function( all, letter ) {
6239                 return letter.toUpperCase();
6240         };
6241
6242 jQuery.fn.css = function( name, value ) {
6243         // Setting 'undefined' is a no-op
6244         if ( arguments.length === 2 && value === undefined ) {
6245                 return this;
6246         }
6247
6248         return jQuery.access( this, name, value, true, function( elem, name, value ) {
6249                 return value !== undefined ?
6250                         jQuery.style( elem, name, value ) :
6251                         jQuery.css( elem, name );
6252         });
6253 };
6254
6255 jQuery.extend({
6256         // Add in style property hooks for overriding the default
6257         // behavior of getting and setting a style property
6258         cssHooks: {
6259                 opacity: {
6260                         get: function( elem, computed ) {
6261                                 if ( computed ) {
6262                                         // We should always get a number back from opacity
6263                                         var ret = curCSS( elem, "opacity", "opacity" );
6264                                         return ret === "" ? "1" : ret;
6265
6266                                 } else {
6267                                         return elem.style.opacity;
6268                                 }
6269                         }
6270                 }
6271         },
6272
6273         // Exclude the following css properties to add px
6274         cssNumber: {
6275                 "zIndex": true,
6276                 "fontWeight": true,
6277                 "opacity": true,
6278                 "zoom": true,
6279                 "lineHeight": true,
6280                 "widows": true,
6281                 "orphans": true
6282         },
6283
6284         // Add in properties whose names you wish to fix before
6285         // setting or getting the value
6286         cssProps: {
6287                 // normalize float css property
6288                 "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
6289         },
6290
6291         // Get and set the style property on a DOM Node
6292         style: function( elem, name, value, extra ) {
6293                 // Don't set styles on text and comment nodes
6294                 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6295                         return;
6296                 }
6297
6298                 // Make sure that we're working with the right name
6299                 var ret, type, origName = jQuery.camelCase( name ),
6300                         style = elem.style, hooks = jQuery.cssHooks[ origName ];
6301
6302                 name = jQuery.cssProps[ origName ] || origName;
6303
6304                 // Check if we're setting a value
6305                 if ( value !== undefined ) {
6306                         type = typeof value;
6307
6308                         // Make sure that NaN and null values aren't set. See: #7116
6309                         if ( type === "number" && isNaN( value ) || value == null ) {
6310                                 return;
6311                         }
6312
6313                         // convert relative number strings (+= or -=) to relative numbers. #7345
6314                         if ( type === "string" && rrelNum.test( value ) ) {
6315                                 value = +value.replace( rrelNumFilter, "" ) + parseFloat( jQuery.css( elem, name ) );
6316                         }
6317
6318                         // If a number was passed in, add 'px' to the (except for certain CSS properties)
6319                         if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
6320                                 value += "px";
6321                         }
6322
6323                         // If a hook was provided, use that value, otherwise just set the specified value
6324                         if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
6325                                 // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
6326                                 // Fixes bug #5509
6327                                 try {
6328                                         style[ name ] = value;
6329                                 } catch(e) {}
6330                         }
6331
6332                 } else {
6333                         // If a hook was provided get the non-computed value from there
6334                         if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6335                                 return ret;
6336                         }
6337
6338                         // Otherwise just get the value from the style object
6339                         return style[ name ];
6340                 }
6341         },
6342
6343         css: function( elem, name, extra ) {
6344                 var ret, hooks;
6345
6346                 // Make sure that we're working with the right name
6347                 name = jQuery.camelCase( name );
6348                 hooks = jQuery.cssHooks[ name ];
6349                 name = jQuery.cssProps[ name ] || name;
6350
6351                 // cssFloat needs a special treatment
6352                 if ( name === "cssFloat" ) {
6353                         name = "float";
6354                 }
6355
6356                 // If a hook was provided get the computed value from there
6357                 if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
6358                         return ret;
6359
6360                 // Otherwise, if a way to get the computed value exists, use that
6361                 } else if ( curCSS ) {
6362                         return curCSS( elem, name );
6363                 }
6364         },
6365
6366         // A method for quickly swapping in/out CSS properties to get correct calculations
6367         swap: function( elem, options, callback ) {
6368                 var old = {};
6369
6370                 // Remember the old values, and insert the new ones
6371                 for ( var name in options ) {
6372                         old[ name ] = elem.style[ name ];
6373                         elem.style[ name ] = options[ name ];
6374                 }
6375
6376                 callback.call( elem );
6377
6378                 // Revert the old values
6379                 for ( name in options ) {
6380                         elem.style[ name ] = old[ name ];
6381                 }
6382         },
6383
6384         camelCase: function( string ) {
6385                 return string.replace( rdashAlpha, fcamelCase );
6386         }
6387 });
6388
6389 // DEPRECATED, Use jQuery.css() instead
6390 jQuery.curCSS = jQuery.css;
6391
6392 jQuery.each(["height", "width"], function( i, name ) {
6393         jQuery.cssHooks[ name ] = {
6394                 get: function( elem, computed, extra ) {
6395                         var val;
6396
6397                         if ( computed ) {
6398                                 if ( elem.offsetWidth !== 0 ) {
6399                                         val = getWH( elem, name, extra );
6400
6401                                 } else {
6402                                         jQuery.swap( elem, cssShow, function() {
6403                                                 val = getWH( elem, name, extra );
6404                                         });
6405                                 }
6406
6407                                 if ( val <= 0 ) {
6408                                         val = curCSS( elem, name, name );
6409
6410                                         if ( val === "0px" && currentStyle ) {
6411                                                 val = currentStyle( elem, name, name );
6412                                         }
6413
6414                                         if ( val != null ) {
6415                                                 // Should return "auto" instead of 0, use 0 for
6416                                                 // temporary backwards-compat
6417                                                 return val === "" || val === "auto" ? "0px" : val;
6418                                         }
6419                                 }
6420
6421                                 if ( val < 0 || val == null ) {
6422                                         val = elem.style[ name ];
6423
6424                                         // Should return "auto" instead of 0, use 0 for
6425                                         // temporary backwards-compat
6426                                         return val === "" || val === "auto" ? "0px" : val;
6427                                 }
6428
6429                                 return typeof val === "string" ? val : val + "px";
6430                         }
6431                 },
6432
6433                 set: function( elem, value ) {
6434                         if ( rnumpx.test( value ) ) {
6435                                 // ignore negative width and height values #1599
6436                                 value = parseFloat(value);
6437
6438                                 if ( value >= 0 ) {
6439                                         return value + "px";
6440                                 }
6441
6442                         } else {
6443                                 return value;
6444                         }
6445                 }
6446         };
6447 });
6448
6449 if ( !jQuery.support.opacity ) {
6450         jQuery.cssHooks.opacity = {
6451                 get: function( elem, computed ) {
6452                         // IE uses filters for opacity
6453                         return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
6454                                 ( parseFloat( RegExp.$1 ) / 100 ) + "" :
6455                                 computed ? "1" : "";
6456                 },
6457
6458                 set: function( elem, value ) {
6459                         var style = elem.style,
6460                                 currentStyle = elem.currentStyle;
6461
6462                         // IE has trouble with opacity if it does not have layout
6463                         // Force it by setting the zoom level
6464                         style.zoom = 1;
6465
6466                         // Set the alpha filter to set the opacity
6467                         var opacity = jQuery.isNaN( value ) ?
6468                                 "" :
6469                                 "alpha(opacity=" + value * 100 + ")",
6470                                 filter = currentStyle && currentStyle.filter || style.filter || "";
6471
6472                         style.filter = ralpha.test( filter ) ?
6473                                 filter.replace( ralpha, opacity ) :
6474                                 filter + " " + opacity;
6475                 }
6476         };
6477 }
6478
6479 jQuery(function() {
6480         // This hook cannot be added until DOM ready because the support test
6481         // for it is not run until after DOM ready
6482         if ( !jQuery.support.reliableMarginRight ) {
6483                 jQuery.cssHooks.marginRight = {
6484                         get: function( elem, computed ) {
6485                                 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6486                                 // Work around by temporarily setting element display to inline-block
6487                                 var ret;
6488                                 jQuery.swap( elem, { "display": "inline-block" }, function() {
6489                                         if ( computed ) {
6490                                                 ret = curCSS( elem, "margin-right", "marginRight" );
6491                                         } else {
6492                                                 ret = elem.style.marginRight;
6493                                         }
6494                                 });
6495                                 return ret;
6496                         }
6497                 };
6498         }
6499 });
6500
6501 if ( document.defaultView && document.defaultView.getComputedStyle ) {
6502         getComputedStyle = function( elem, name ) {
6503                 var ret, defaultView, computedStyle;
6504
6505                 name = name.replace( rupper, "-$1" ).toLowerCase();
6506
6507                 if ( !(defaultView = elem.ownerDocument.defaultView) ) {
6508                         return undefined;
6509                 }
6510
6511                 if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
6512                         ret = computedStyle.getPropertyValue( name );
6513                         if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
6514                                 ret = jQuery.style( elem, name );
6515                         }
6516                 }
6517
6518                 return ret;
6519         };
6520 }
6521
6522 if ( document.documentElement.currentStyle ) {
6523         currentStyle = function( elem, name ) {
6524                 var left,
6525                         ret = elem.currentStyle && elem.currentStyle[ name ],
6526                         rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ],
6527                         style = elem.style;
6528
6529                 // From the awesome hack by Dean Edwards
6530                 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6531
6532                 // If we're not dealing with a regular pixel number
6533                 // but a number that has a weird ending, we need to convert it to pixels
6534                 if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
6535                         // Remember the original values
6536                         left = style.left;
6537
6538                         // Put in the new values to get a computed value out
6539                         if ( rsLeft ) {
6540                                 elem.runtimeStyle.left = elem.currentStyle.left;
6541                         }
6542                         style.left = name === "fontSize" ? "1em" : (ret || 0);
6543                         ret = style.pixelLeft + "px";
6544
6545                         // Revert the changed values
6546                         style.left = left;
6547                         if ( rsLeft ) {
6548                                 elem.runtimeStyle.left = rsLeft;
6549                         }
6550                 }
6551
6552                 return ret === "" ? "auto" : ret;
6553         };
6554 }
6555
6556 curCSS = getComputedStyle || currentStyle;
6557
6558 function getWH( elem, name, extra ) {
6559         var which = name === "width" ? cssWidth : cssHeight,
6560                 val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
6561
6562         if ( extra === "border" ) {
6563                 return val;
6564         }
6565
6566         jQuery.each( which, function() {
6567                 if ( !extra ) {
6568                         val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0;
6569                 }
6570
6571                 if ( extra === "margin" ) {
6572                         val += parseFloat(jQuery.css( elem, "margin" + this )) || 0;
6573
6574                 } else {
6575                         val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0;
6576                 }
6577         });
6578
6579         return val;
6580 }
6581
6582 if ( jQuery.expr && jQuery.expr.filters ) {
6583         jQuery.expr.filters.hidden = function( elem ) {
6584                 var width = elem.offsetWidth,
6585                         height = elem.offsetHeight;
6586
6587                 return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
6588         };
6589
6590         jQuery.expr.filters.visible = function( elem ) {
6591                 return !jQuery.expr.filters.hidden( elem );
6592         };
6593 }
6594
6595
6596
6597
6598 var r20 = /%20/g,
6599         rbracket = /\[\]$/,
6600         rCRLF = /\r?\n/g,
6601         rhash = /#.*$/,
6602         rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
6603         rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
6604         // #7653, #8125, #8152: local protocol detection
6605         rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|widget):$/,
6606         rnoContent = /^(?:GET|HEAD)$/,
6607         rprotocol = /^\/\//,
6608         rquery = /\?/,
6609         rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
6610         rselectTextarea = /^(?:select|textarea)/i,
6611         rspacesAjax = /\s+/,
6612         rts = /([?&])_=[^&]*/,
6613         rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
6614
6615         // Keep a copy of the old load method
6616         _load = jQuery.fn.load,
6617
6618         /* Prefilters
6619          * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
6620          * 2) These are called:
6621          *    - BEFORE asking for a transport
6622          *    - AFTER param serialization (s.data is a string if s.processData is true)
6623          * 3) key is the dataType
6624          * 4) the catchall symbol "*" can be used
6625          * 5) execution will start with transport dataType and THEN continue down to "*" if needed
6626          */
6627         prefilters = {},
6628
6629         /* Transports bindings
6630          * 1) key is the dataType
6631          * 2) the catchall symbol "*" can be used
6632          * 3) selection will start with transport dataType and THEN go to "*" if needed
6633          */
6634         transports = {},
6635
6636         // Document location
6637         ajaxLocation,
6638
6639         // Document location segments
6640         ajaxLocParts;
6641
6642 // #8138, IE may throw an exception when accessing
6643 // a field from window.location if document.domain has been set
6644 try {
6645         ajaxLocation = location.href;
6646 } catch( e ) {
6647         // Use the href attribute of an A element
6648         // since IE will modify it given document.location
6649         ajaxLocation = document.createElement( "a" );
6650         ajaxLocation.href = "";
6651         ajaxLocation = ajaxLocation.href;
6652 }
6653
6654 // Segment location into parts
6655 ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
6656
6657 // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
6658 function addToPrefiltersOrTransports( structure ) {
6659
6660         // dataTypeExpression is optional and defaults to "*"
6661         return function( dataTypeExpression, func ) {
6662
6663                 if ( typeof dataTypeExpression !== "string" ) {
6664                         func = dataTypeExpression;
6665                         dataTypeExpression = "*";
6666                 }
6667
6668                 if ( jQuery.isFunction( func ) ) {
6669                         var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),
6670                                 i = 0,
6671                                 length = dataTypes.length,
6672                                 dataType,
6673                                 list,
6674                                 placeBefore;
6675
6676                         // For each dataType in the dataTypeExpression
6677                         for(; i < length; i++ ) {
6678                                 dataType = dataTypes[ i ];
6679                                 // We control if we're asked to add before
6680                                 // any existing element
6681                                 placeBefore = /^\+/.test( dataType );
6682                                 if ( placeBefore ) {
6683                                         dataType = dataType.substr( 1 ) || "*";
6684                                 }
6685                                 list = structure[ dataType ] = structure[ dataType ] || [];
6686                                 // then we add to the structure accordingly
6687                                 list[ placeBefore ? "unshift" : "push" ]( func );
6688                         }
6689                 }
6690         };
6691 }
6692
6693 // Base inspection function for prefilters and transports
6694 function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
6695                 dataType /* internal */, inspected /* internal */ ) {
6696
6697         dataType = dataType || options.dataTypes[ 0 ];
6698         inspected = inspected || {};
6699
6700         inspected[ dataType ] = true;
6701
6702         var list = structure[ dataType ],
6703                 i = 0,
6704                 length = list ? list.length : 0,
6705                 executeOnly = ( structure === prefilters ),
6706                 selection;
6707
6708         for(; i < length && ( executeOnly || !selection ); i++ ) {
6709                 selection = list[ i ]( options, originalOptions, jqXHR );
6710                 // If we got redirected to another dataType
6711                 // we try there if executing only and not done already
6712                 if ( typeof selection === "string" ) {
6713                         if ( !executeOnly || inspected[ selection ] ) {
6714                                 selection = undefined;
6715                         } else {
6716                                 options.dataTypes.unshift( selection );
6717                                 selection = inspectPrefiltersOrTransports(
6718                                                 structure, options, originalOptions, jqXHR, selection, inspected );
6719                         }
6720                 }
6721         }
6722         // If we're only executing or nothing was selected
6723         // we try the catchall dataType if not done already
6724         if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
6725                 selection = inspectPrefiltersOrTransports(
6726                                 structure, options, originalOptions, jqXHR, "*", inspected );
6727         }
6728         // unnecessary when only executing (prefilters)
6729         // but it'll be ignored by the caller in that case
6730         return selection;
6731 }
6732
6733 jQuery.fn.extend({
6734         load: function( url, params, callback ) {
6735                 if ( typeof url !== "string" && _load ) {
6736                         return _load.apply( this, arguments );
6737
6738                 // Don't do a request if no elements are being requested
6739                 } else if ( !this.length ) {
6740                         return this;
6741                 }
6742
6743                 var off = url.indexOf( " " );
6744                 if ( off >= 0 ) {
6745                         var selector = url.slice( off, url.length );
6746                         url = url.slice( 0, off );
6747                 }
6748
6749                 // Default to a GET request
6750                 var type = "GET";
6751
6752                 // If the second parameter was provided
6753                 if ( params ) {
6754                         // If it's a function
6755                         if ( jQuery.isFunction( params ) ) {
6756                                 // We assume that it's the callback
6757                                 callback = params;
6758                                 params = undefined;
6759
6760                         // Otherwise, build a param string
6761                         } else if ( typeof params === "object" ) {
6762                                 params = jQuery.param( params, jQuery.ajaxSettings.traditional );
6763                                 type = "POST";
6764                         }
6765                 }
6766
6767                 var self = this;
6768
6769                 // Request the remote document
6770                 jQuery.ajax({
6771                         url: url,
6772                         type: type,
6773                         dataType: "html",
6774                         data: params,
6775                         // Complete callback (responseText is used internally)
6776                         complete: function( jqXHR, status, responseText ) {
6777                                 // Store the response as specified by the jqXHR object
6778                                 responseText = jqXHR.responseText;
6779                                 // If successful, inject the HTML into all the matched elements
6780                                 if ( jqXHR.isResolved() ) {
6781                                         // #4825: Get the actual response in case
6782                                         // a dataFilter is present in ajaxSettings
6783                                         jqXHR.done(function( r ) {
6784                                                 responseText = r;
6785                                         });
6786                                         // See if a selector was specified
6787                                         self.html( selector ?
6788                                                 // Create a dummy div to hold the results
6789                                                 jQuery("<div>")
6790                                                         // inject the contents of the document in, removing the scripts
6791                                                         // to avoid any 'Permission Denied' errors in IE
6792                                                         .append(responseText.replace(rscript, ""))
6793
6794                                                         // Locate the specified elements
6795                                                         .find(selector) :
6796
6797                                                 // If not, just inject the full result
6798                                                 responseText );
6799                                 }
6800
6801                                 if ( callback ) {
6802                                         self.each( callback, [ responseText, status, jqXHR ] );
6803                                 }
6804                         }
6805                 });
6806
6807                 return this;
6808         },
6809
6810         serialize: function() {
6811                 return jQuery.param( this.serializeArray() );
6812         },
6813
6814         serializeArray: function() {
6815                 return this.map(function(){
6816                         return this.elements ? jQuery.makeArray( this.elements ) : this;
6817                 })
6818                 .filter(function(){
6819                         return this.name && !this.disabled &&
6820                                 ( this.checked || rselectTextarea.test( this.nodeName ) ||
6821                                         rinput.test( this.type ) );
6822                 })
6823                 .map(function( i, elem ){
6824                         var val = jQuery( this ).val();
6825
6826                         return val == null ?
6827                                 null :
6828                                 jQuery.isArray( val ) ?
6829                                         jQuery.map( val, function( val, i ){
6830                                                 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
6831                                         }) :
6832                                         { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
6833                 }).get();
6834         }
6835 });
6836
6837 // Attach a bunch of functions for handling common AJAX events
6838 jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
6839         jQuery.fn[ o ] = function( f ){
6840                 return this.bind( o, f );
6841         };
6842 });
6843
6844 jQuery.each( [ "get", "post" ], function( i, method ) {
6845         jQuery[ method ] = function( url, data, callback, type ) {
6846                 // shift arguments if data argument was omitted
6847                 if ( jQuery.isFunction( data ) ) {
6848                         type = type || callback;
6849                         callback = data;
6850                         data = undefined;
6851                 }
6852
6853                 return jQuery.ajax({
6854                         type: method,
6855                         url: url,
6856                         data: data,
6857                         success: callback,
6858                         dataType: type
6859                 });
6860         };
6861 });
6862
6863 jQuery.extend({
6864
6865         getScript: function( url, callback ) {
6866                 return jQuery.get( url, undefined, callback, "script" );
6867         },
6868
6869         getJSON: function( url, data, callback ) {
6870                 return jQuery.get( url, data, callback, "json" );
6871         },
6872
6873         // Creates a full fledged settings object into target
6874         // with both ajaxSettings and settings fields.
6875         // If target is omitted, writes into ajaxSettings.
6876         ajaxSetup: function ( target, settings ) {
6877                 if ( !settings ) {
6878                         // Only one parameter, we extend ajaxSettings
6879                         settings = target;
6880                         target = jQuery.extend( true, jQuery.ajaxSettings, settings );
6881                 } else {
6882                         // target was provided, we extend into it
6883                         jQuery.extend( true, target, jQuery.ajaxSettings, settings );
6884                 }
6885                 // Flatten fields we don't want deep extended
6886                 for( var field in { context: 1, url: 1 } ) {
6887                         if ( field in settings ) {
6888                                 target[ field ] = settings[ field ];
6889                         } else if( field in jQuery.ajaxSettings ) {
6890                                 target[ field ] = jQuery.ajaxSettings[ field ];
6891                         }
6892                 }
6893                 return target;
6894         },
6895
6896         ajaxSettings: {
6897                 url: ajaxLocation,
6898                 isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
6899                 global: true,
6900                 type: "GET",
6901                 contentType: "application/x-www-form-urlencoded",
6902                 processData: true,
6903                 async: true,
6904                 /*
6905                 timeout: 0,
6906                 data: null,
6907                 dataType: null,
6908                 username: null,
6909                 password: null,
6910                 cache: null,
6911                 traditional: false,
6912                 headers: {},
6913                 */
6914
6915                 accepts: {
6916                         xml: "application/xml, text/xml",
6917                         html: "text/html",
6918                         text: "text/plain",
6919                         json: "application/json, text/javascript",
6920                         "*": "*/*"
6921                 },
6922
6923                 contents: {
6924                         xml: /xml/,
6925                         html: /html/,
6926                         json: /json/
6927                 },
6928
6929                 responseFields: {
6930                         xml: "responseXML",
6931                         text: "responseText"
6932                 },
6933
6934                 // List of data converters
6935                 // 1) key format is "source_type destination_type" (a single space in-between)
6936                 // 2) the catchall symbol "*" can be used for source_type
6937                 converters: {
6938
6939                         // Convert anything to text
6940                         "* text": window.String,
6941
6942                         // Text to html (true = no transformation)
6943                         "text html": true,
6944
6945                         // Evaluate text as a json expression
6946                         "text json": jQuery.parseJSON,
6947
6948                         // Parse text as xml
6949                         "text xml": jQuery.parseXML
6950                 }
6951         },
6952
6953         ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
6954         ajaxTransport: addToPrefiltersOrTransports( transports ),
6955
6956         // Main method
6957         ajax: function( url, options ) {
6958
6959                 // If url is an object, simulate pre-1.5 signature
6960                 if ( typeof url === "object" ) {
6961                         options = url;
6962                         url = undefined;
6963                 }
6964
6965                 // Force options to be an object
6966                 options = options || {};
6967
6968                 var // Create the final options object
6969                         s = jQuery.ajaxSetup( {}, options ),
6970                         // Callbacks context
6971                         callbackContext = s.context || s,
6972                         // Context for global events
6973                         // It's the callbackContext if one was provided in the options
6974                         // and if it's a DOM node or a jQuery collection
6975                         globalEventContext = callbackContext !== s &&
6976                                 ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
6977                                                 jQuery( callbackContext ) : jQuery.event,
6978                         // Deferreds
6979                         deferred = jQuery.Deferred(),
6980                         completeDeferred = jQuery._Deferred(),
6981                         // Status-dependent callbacks
6982                         statusCode = s.statusCode || {},
6983                         // ifModified key
6984                         ifModifiedKey,
6985                         // Headers (they are sent all at once)
6986                         requestHeaders = {},
6987                         requestHeadersNames = {},
6988                         // Response headers
6989                         responseHeadersString,
6990                         responseHeaders,
6991                         // transport
6992                         transport,
6993                         // timeout handle
6994                         timeoutTimer,
6995                         // Cross-domain detection vars
6996                         parts,
6997                         // The jqXHR state
6998                         state = 0,
6999                         // To know if global events are to be dispatched
7000                         fireGlobals,
7001                         // Loop variable
7002                         i,
7003                         // Fake xhr
7004                         jqXHR = {
7005
7006                                 readyState: 0,
7007
7008                                 // Caches the header
7009                                 setRequestHeader: function( name, value ) {
7010                                         if ( !state ) {
7011                                                 var lname = name.toLowerCase();
7012                                                 name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
7013                                                 requestHeaders[ name ] = value;
7014                                         }
7015                                         return this;
7016                                 },
7017
7018                                 // Raw string
7019                                 getAllResponseHeaders: function() {
7020                                         return state === 2 ? responseHeadersString : null;
7021                                 },
7022
7023                                 // Builds headers hashtable if needed
7024                                 getResponseHeader: function( key ) {
7025                                         var match;
7026                                         if ( state === 2 ) {
7027                                                 if ( !responseHeaders ) {
7028                                                         responseHeaders = {};
7029                                                         while( ( match = rheaders.exec( responseHeadersString ) ) ) {
7030                                                                 responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
7031                                                         }
7032                                                 }
7033                                                 match = responseHeaders[ key.toLowerCase() ];
7034                                         }
7035                                         return match === undefined ? null : match;
7036                                 },
7037
7038                                 // Overrides response content-type header
7039                                 overrideMimeType: function( type ) {
7040                                         if ( !state ) {
7041                                                 s.mimeType = type;
7042                                         }
7043                                         return this;
7044                                 },
7045
7046                                 // Cancel the request
7047                                 abort: function( statusText ) {
7048                                         statusText = statusText || "abort";
7049                                         if ( transport ) {
7050                                                 transport.abort( statusText );
7051                                         }
7052                                         done( 0, statusText );
7053                                         return this;
7054                                 }
7055                         };
7056
7057                 // Callback for when everything is done
7058                 // It is defined here because jslint complains if it is declared
7059                 // at the end of the function (which would be more logical and readable)
7060                 function done( status, statusText, responses, headers ) {
7061
7062                         // Called once
7063                         if ( state === 2 ) {
7064                                 return;
7065                         }
7066
7067                         // State is "done" now
7068                         state = 2;
7069
7070                         // Clear timeout if it exists
7071                         if ( timeoutTimer ) {
7072                                 clearTimeout( timeoutTimer );
7073                         }
7074
7075                         // Dereference transport for early garbage collection
7076                         // (no matter how long the jqXHR object will be used)
7077                         transport = undefined;
7078
7079                         // Cache response headers
7080                         responseHeadersString = headers || "";
7081
7082                         // Set readyState
7083                         jqXHR.readyState = status ? 4 : 0;
7084
7085                         var isSuccess,
7086                                 success,
7087                                 error,
7088                                 response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
7089                                 lastModified,
7090                                 etag;
7091
7092                         // If successful, handle type chaining
7093                         if ( status >= 200 && status < 300 || status === 304 ) {
7094
7095                                 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7096                                 if ( s.ifModified ) {
7097
7098                                         if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {
7099                                                 jQuery.lastModified[ ifModifiedKey ] = lastModified;
7100                                         }
7101                                         if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {
7102                                                 jQuery.etag[ ifModifiedKey ] = etag;
7103                                         }
7104                                 }
7105
7106                                 // If not modified
7107                                 if ( status === 304 ) {
7108
7109                                         statusText = "notmodified";
7110                                         isSuccess = true;
7111
7112                                 // If we have data
7113                                 } else {
7114
7115                                         try {
7116                                                 success = ajaxConvert( s, response );
7117                                                 statusText = "success";
7118                                                 isSuccess = true;
7119                                         } catch(e) {
7120                                                 // We have a parsererror
7121                                                 statusText = "parsererror";
7122                                                 error = e;
7123                                         }
7124                                 }
7125                         } else {
7126                                 // We extract error from statusText
7127                                 // then normalize statusText and status for non-aborts
7128                                 error = statusText;
7129                                 if( !statusText || status ) {
7130                                         statusText = "error";
7131                                         if ( status < 0 ) {
7132                                                 status = 0;
7133                                         }
7134                                 }
7135                         }
7136
7137                         // Set data for the fake xhr object
7138                         jqXHR.status = status;
7139                         jqXHR.statusText = statusText;
7140
7141                         // Success/Error
7142                         if ( isSuccess ) {
7143                                 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
7144                         } else {
7145                                 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
7146                         }
7147
7148                         // Status-dependent callbacks
7149                         jqXHR.statusCode( statusCode );
7150                         statusCode = undefined;
7151
7152                         if ( fireGlobals ) {
7153                                 globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
7154                                                 [ jqXHR, s, isSuccess ? success : error ] );
7155                         }
7156
7157                         // Complete
7158                         completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] );
7159
7160                         if ( fireGlobals ) {
7161                                 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s] );
7162                                 // Handle the global AJAX counter
7163                                 if ( !( --jQuery.active ) ) {
7164                                         jQuery.event.trigger( "ajaxStop" );
7165                                 }
7166                         }
7167                 }
7168
7169                 // Attach deferreds
7170                 deferred.promise( jqXHR );
7171                 jqXHR.success = jqXHR.done;
7172                 jqXHR.error = jqXHR.fail;
7173                 jqXHR.complete = completeDeferred.done;
7174
7175                 // Status-dependent callbacks
7176                 jqXHR.statusCode = function( map ) {
7177                         if ( map ) {
7178                                 var tmp;
7179                                 if ( state < 2 ) {
7180                                         for( tmp in map ) {
7181                                                 statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
7182                                         }
7183                                 } else {
7184                                         tmp = map[ jqXHR.status ];
7185                                         jqXHR.then( tmp, tmp );
7186                                 }
7187                         }
7188                         return this;
7189                 };
7190
7191                 // Remove hash character (#7531: and string promotion)
7192                 // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
7193                 // We also use the url parameter if available
7194                 s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
7195
7196                 // Extract dataTypes list
7197                 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
7198
7199                 // Determine if a cross-domain request is in order
7200                 if ( s.crossDomain == null ) {
7201                         parts = rurl.exec( s.url.toLowerCase() );
7202                         s.crossDomain = !!( parts &&
7203                                 ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
7204                                         ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
7205                                                 ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
7206                         );
7207                 }
7208
7209                 // Convert data if not already a string
7210                 if ( s.data && s.processData && typeof s.data !== "string" ) {
7211                         s.data = jQuery.param( s.data, s.traditional );
7212                 }
7213
7214                 // Apply prefilters
7215                 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
7216
7217                 // If request was aborted inside a prefiler, stop there
7218                 if ( state === 2 ) {
7219                         return false;
7220                 }
7221
7222                 // We can fire global events as of now if asked to
7223                 fireGlobals = s.global;
7224
7225                 // Uppercase the type
7226                 s.type = s.type.toUpperCase();
7227
7228                 // Determine if request has content
7229                 s.hasContent = !rnoContent.test( s.type );
7230
7231                 // Watch for a new set of requests
7232                 if ( fireGlobals && jQuery.active++ === 0 ) {
7233                         jQuery.event.trigger( "ajaxStart" );
7234                 }
7235
7236                 // More options handling for requests with no content
7237                 if ( !s.hasContent ) {
7238
7239                         // If data is available, append data to url
7240                         if ( s.data ) {
7241                                 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
7242                         }
7243
7244                         // Get ifModifiedKey before adding the anti-cache parameter
7245                         ifModifiedKey = s.url;
7246
7247                         // Add anti-cache in url if needed
7248                         if ( s.cache === false ) {
7249
7250                                 var ts = jQuery.now(),
7251                                         // try replacing _= if it is there
7252                                         ret = s.url.replace( rts, "$1_=" + ts );
7253
7254                                 // if nothing was replaced, add timestamp to the end
7255                                 s.url = ret + ( (ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
7256                         }
7257                 }
7258
7259                 // Set the correct header, if data is being sent
7260                 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
7261                         jqXHR.setRequestHeader( "Content-Type", s.contentType );
7262                 }
7263
7264                 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7265                 if ( s.ifModified ) {
7266                         ifModifiedKey = ifModifiedKey || s.url;
7267                         if ( jQuery.lastModified[ ifModifiedKey ] ) {
7268                                 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
7269                         }
7270                         if ( jQuery.etag[ ifModifiedKey ] ) {
7271                                 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
7272                         }
7273                 }
7274
7275                 // Set the Accepts header for the server, depending on the dataType
7276                 jqXHR.setRequestHeader(
7277                         "Accept",
7278                         s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
7279                                 s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) :
7280                                 s.accepts[ "*" ]
7281                 );
7282
7283                 // Check for headers option
7284                 for ( i in s.headers ) {
7285                         jqXHR.setRequestHeader( i, s.headers[ i ] );
7286                 }
7287
7288                 // Allow custom headers/mimetypes and early abort
7289                 if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
7290                                 // Abort if not done already
7291                                 jqXHR.abort();
7292                                 return false;
7293
7294                 }
7295
7296                 // Install callbacks on deferreds
7297                 for ( i in { success: 1, error: 1, complete: 1 } ) {
7298                         jqXHR[ i ]( s[ i ] );
7299                 }
7300
7301                 // Get transport
7302                 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
7303
7304                 // If no transport, we auto-abort
7305                 if ( !transport ) {
7306                         done( -1, "No Transport" );
7307                 } else {
7308                         jqXHR.readyState = 1;
7309                         // Send global event
7310                         if ( fireGlobals ) {
7311                                 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
7312                         }
7313                         // Timeout
7314                         if ( s.async && s.timeout > 0 ) {
7315                                 timeoutTimer = setTimeout( function(){
7316                                         jqXHR.abort( "timeout" );
7317                                 }, s.timeout );
7318                         }
7319
7320                         try {
7321                                 state = 1;
7322                                 transport.send( requestHeaders, done );
7323                         } catch (e) {
7324                                 // Propagate exception as error if not done
7325                                 if ( status < 2 ) {
7326                                         done( -1, e );
7327                                 // Simply rethrow otherwise
7328                                 } else {
7329                                         jQuery.error( e );
7330                                 }
7331                         }
7332                 }
7333
7334                 return jqXHR;
7335         },
7336
7337         // Serialize an array of form elements or a set of
7338         // key/values into a query string
7339         param: function( a, traditional ) {
7340                 var s = [],
7341                         add = function( key, value ) {
7342                                 // If value is a function, invoke it and return its value
7343                                 value = jQuery.isFunction( value ) ? value() : value;
7344                                 s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
7345                         };
7346
7347                 // Set traditional to true for jQuery <= 1.3.2 behavior.
7348                 if ( traditional === undefined ) {
7349                         traditional = jQuery.ajaxSettings.traditional;
7350                 }
7351
7352                 // If an array was passed in, assume that it is an array of form elements.
7353                 if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
7354                         // Serialize the form elements
7355                         jQuery.each( a, function() {
7356                                 add( this.name, this.value );
7357                         });
7358
7359                 } else {
7360                         // If traditional, encode the "old" way (the way 1.3.2 or older
7361                         // did it), otherwise encode params recursively.
7362                         for ( var prefix in a ) {
7363                                 buildParams( prefix, a[ prefix ], traditional, add );
7364                         }
7365                 }
7366
7367                 // Return the resulting serialization
7368                 return s.join( "&" ).replace( r20, "+" );
7369         }
7370 });
7371
7372 function buildParams( prefix, obj, traditional, add ) {
7373         if ( jQuery.isArray( obj ) ) {
7374                 // Serialize array item.
7375                 jQuery.each( obj, function( i, v ) {
7376                         if ( traditional || rbracket.test( prefix ) ) {
7377                                 // Treat each array item as a scalar.
7378                                 add( prefix, v );
7379
7380                         } else {
7381                                 // If array item is non-scalar (array or object), encode its
7382                                 // numeric index to resolve deserialization ambiguity issues.
7383                                 // Note that rack (as of 1.0.0) can't currently deserialize
7384                                 // nested arrays properly, and attempting to do so may cause
7385                                 // a server error. Possible fixes are to modify rack's
7386                                 // deserialization algorithm or to provide an option or flag
7387                                 // to force array serialization to be shallow.
7388                                 buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
7389                         }
7390                 });
7391
7392         } else if ( !traditional && obj != null && typeof obj === "object" ) {
7393                 // Serialize object item.
7394                 for ( var name in obj ) {
7395                         buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
7396                 }
7397
7398         } else {
7399                 // Serialize scalar item.
7400                 add( prefix, obj );
7401         }
7402 }
7403
7404 // This is still on the jQuery object... for now
7405 // Want to move this to jQuery.ajax some day
7406 jQuery.extend({
7407
7408         // Counter for holding the number of active queries
7409         active: 0,
7410
7411         // Last-Modified header cache for next request
7412         lastModified: {},
7413         etag: {}
7414
7415 });
7416
7417 /* Handles responses to an ajax request:
7418  * - sets all responseXXX fields accordingly
7419  * - finds the right dataType (mediates between content-type and expected dataType)
7420  * - returns the corresponding response
7421  */
7422 function ajaxHandleResponses( s, jqXHR, responses ) {
7423
7424         var contents = s.contents,
7425                 dataTypes = s.dataTypes,
7426                 responseFields = s.responseFields,
7427                 ct,
7428                 type,
7429                 finalDataType,
7430                 firstDataType;
7431
7432         // Fill responseXXX fields
7433         for( type in responseFields ) {
7434                 if ( type in responses ) {
7435                         jqXHR[ responseFields[type] ] = responses[ type ];
7436                 }
7437         }
7438
7439         // Remove auto dataType and get content-type in the process
7440         while( dataTypes[ 0 ] === "*" ) {
7441                 dataTypes.shift();
7442                 if ( ct === undefined ) {
7443                         ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
7444                 }
7445         }
7446
7447         // Check if we're dealing with a known content-type
7448         if ( ct ) {
7449                 for ( type in contents ) {
7450                         if ( contents[ type ] && contents[ type ].test( ct ) ) {
7451                                 dataTypes.unshift( type );
7452                                 break;
7453                         }
7454                 }
7455         }
7456
7457         // Check to see if we have a response for the expected dataType
7458         if ( dataTypes[ 0 ] in responses ) {
7459                 finalDataType = dataTypes[ 0 ];
7460         } else {
7461                 // Try convertible dataTypes
7462                 for ( type in responses ) {
7463                         if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
7464                                 finalDataType = type;
7465                                 break;
7466                         }
7467                         if ( !firstDataType ) {
7468                                 firstDataType = type;
7469                         }
7470                 }
7471                 // Or just use first one
7472                 finalDataType = finalDataType || firstDataType;
7473         }
7474
7475         // If we found a dataType
7476         // We add the dataType to the list if needed
7477         // and return the corresponding response
7478         if ( finalDataType ) {
7479                 if ( finalDataType !== dataTypes[ 0 ] ) {
7480                         dataTypes.unshift( finalDataType );
7481                 }
7482                 return responses[ finalDataType ];
7483         }
7484 }
7485
7486 // Chain conversions given the request and the original response
7487 function ajaxConvert( s, response ) {
7488
7489         // Apply the dataFilter if provided
7490         if ( s.dataFilter ) {
7491                 response = s.dataFilter( response, s.dataType );
7492         }
7493
7494         var dataTypes = s.dataTypes,
7495                 converters = {},
7496                 i,
7497                 key,
7498                 length = dataTypes.length,
7499                 tmp,
7500                 // Current and previous dataTypes
7501                 current = dataTypes[ 0 ],
7502                 prev,
7503                 // Conversion expression
7504                 conversion,
7505                 // Conversion function
7506                 conv,
7507                 // Conversion functions (transitive conversion)
7508                 conv1,
7509                 conv2;
7510
7511         // For each dataType in the chain
7512         for( i = 1; i < length; i++ ) {
7513
7514                 // Create converters map
7515                 // with lowercased keys
7516                 if ( i === 1 ) {
7517                         for( key in s.converters ) {
7518                                 if( typeof key === "string" ) {
7519                                         converters[ key.toLowerCase() ] = s.converters[ key ];
7520                                 }
7521                         }
7522                 }
7523
7524                 // Get the dataTypes
7525                 prev = current;
7526                 current = dataTypes[ i ];
7527
7528                 // If current is auto dataType, update it to prev
7529                 if( current === "*" ) {
7530                         current = prev;
7531                 // If no auto and dataTypes are actually different
7532                 } else if ( prev !== "*" && prev !== current ) {
7533
7534                         // Get the converter
7535                         conversion = prev + " " + current;
7536                         conv = converters[ conversion ] || converters[ "* " + current ];
7537
7538                         // If there is no direct converter, search transitively
7539                         if ( !conv ) {
7540                                 conv2 = undefined;
7541                                 for( conv1 in converters ) {
7542                                         tmp = conv1.split( " " );
7543                                         if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {
7544                                                 conv2 = converters[ tmp[1] + " " + current ];
7545                                                 if ( conv2 ) {
7546                                                         conv1 = converters[ conv1 ];
7547                                                         if ( conv1 === true ) {
7548                                                                 conv = conv2;
7549                                                         } else if ( conv2 === true ) {
7550                                                                 conv = conv1;
7551                                                         }
7552                                                         break;
7553                                                 }
7554                                         }
7555                                 }
7556                         }
7557                         // If we found no converter, dispatch an error
7558                         if ( !( conv || conv2 ) ) {
7559                                 jQuery.error( "No conversion from " + conversion.replace(" "," to ") );
7560                         }
7561                         // If found converter is not an equivalence
7562                         if ( conv !== true ) {
7563                                 // Convert with 1 or 2 converters accordingly
7564                                 response = conv ? conv( response ) : conv2( conv1(response) );
7565                         }
7566                 }
7567         }
7568         return response;
7569 }
7570
7571
7572
7573
7574 var jsc = jQuery.now(),
7575         jsre = /(\=)\?(&|$)|\?\?/i;
7576
7577 // Default jsonp settings
7578 jQuery.ajaxSetup({
7579         jsonp: "callback",
7580         jsonpCallback: function() {
7581                 return jQuery.expando + "_" + ( jsc++ );
7582         }
7583 });
7584
7585 // Detect, normalize options and install callbacks for jsonp requests
7586 jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
7587
7588         var inspectData = s.contentType === "application/x-www-form-urlencoded" &&
7589                 ( typeof s.data === "string" );
7590
7591         if ( s.dataTypes[ 0 ] === "jsonp" ||
7592                 s.jsonp !== false && ( jsre.test( s.url ) ||
7593                                 inspectData && jsre.test( s.data ) ) ) {
7594
7595                 var responseContainer,
7596                         jsonpCallback = s.jsonpCallback =
7597                                 jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
7598                         previous = window[ jsonpCallback ],
7599                         url = s.url,
7600                         data = s.data,
7601                         replace = "$1" + jsonpCallback + "$2";
7602
7603                 if ( s.jsonp !== false ) {
7604                         url = url.replace( jsre, replace );
7605                         if ( s.url === url ) {
7606                                 if ( inspectData ) {
7607                                         data = data.replace( jsre, replace );
7608                                 }
7609                                 if ( s.data === data ) {
7610                                         // Add callback manually
7611                                         url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
7612                                 }
7613                         }
7614                 }
7615
7616                 s.url = url;
7617                 s.data = data;
7618
7619                 // Install callback
7620                 window[ jsonpCallback ] = function( response ) {
7621                         responseContainer = [ response ];
7622                 };
7623
7624                 // Clean-up function
7625                 jqXHR.always(function() {
7626                         // Set callback back to previous value
7627                         window[ jsonpCallback ] = previous;
7628                         // Call if it was a function and we have a response
7629                         if ( responseContainer && jQuery.isFunction( previous ) ) {
7630                                 window[ jsonpCallback ]( responseContainer[ 0 ] );
7631                         }
7632                 });
7633
7634                 // Use data converter to retrieve json after script execution
7635                 s.converters["script json"] = function() {
7636                         if ( !responseContainer ) {
7637                                 jQuery.error( jsonpCallback + " was not called" );
7638                         }
7639                         return responseContainer[ 0 ];
7640                 };
7641
7642                 // force json dataType
7643                 s.dataTypes[ 0 ] = "json";
7644
7645                 // Delegate to script
7646                 return "script";
7647         }
7648 });
7649
7650
7651
7652
7653 // Install script dataType
7654 jQuery.ajaxSetup({
7655         accepts: {
7656                 script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
7657         },
7658         contents: {
7659                 script: /javascript|ecmascript/
7660         },
7661         converters: {
7662                 "text script": function( text ) {
7663                         jQuery.globalEval( text );
7664                         return text;
7665                 }
7666         }
7667 });
7668
7669 // Handle cache's special case and global
7670 jQuery.ajaxPrefilter( "script", function( s ) {
7671         if ( s.cache === undefined ) {
7672                 s.cache = false;
7673         }
7674         if ( s.crossDomain ) {
7675                 s.type = "GET";
7676                 s.global = false;
7677         }
7678 });
7679
7680 // Bind script tag hack transport
7681 jQuery.ajaxTransport( "script", function(s) {
7682
7683         // This transport only deals with cross domain requests
7684         if ( s.crossDomain ) {
7685
7686                 var script,
7687                         head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
7688
7689                 return {
7690
7691                         send: function( _, callback ) {
7692
7693                                 script = document.createElement( "script" );
7694
7695                                 script.async = "async";
7696
7697                                 if ( s.scriptCharset ) {
7698                                         script.charset = s.scriptCharset;
7699                                 }
7700
7701                                 script.src = s.url;
7702
7703                                 // Attach handlers for all browsers
7704                                 script.onload = script.onreadystatechange = function( _, isAbort ) {
7705
7706                                         if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
7707
7708                                                 // Handle memory leak in IE
7709                                                 script.onload = script.onreadystatechange = null;
7710
7711                                                 // Remove the script
7712                                                 if ( head && script.parentNode ) {
7713                                                         head.removeChild( script );
7714                                                 }
7715
7716                                                 // Dereference the script
7717                                                 script = undefined;
7718
7719                                                 // Callback if not abort
7720                                                 if ( !isAbort ) {
7721                                                         callback( 200, "success" );
7722                                                 }
7723                                         }
7724                                 };
7725                                 // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
7726                                 // This arises when a base node is used (#2709 and #4378).
7727                                 head.insertBefore( script, head.firstChild );
7728                         },
7729
7730                         abort: function() {
7731                                 if ( script ) {
7732                                         script.onload( 0, 1 );
7733                                 }
7734                         }
7735                 };
7736         }
7737 });
7738
7739
7740
7741
7742 var // #5280: Internet Explorer will keep connections alive if we don't abort on unload
7743         xhrOnUnloadAbort = window.ActiveXObject ? function() {
7744                 // Abort all pending requests
7745                 for ( var key in xhrCallbacks ) {
7746                         xhrCallbacks[ key ]( 0, 1 );
7747                 }
7748         } : false,
7749         xhrId = 0,
7750         xhrCallbacks;
7751
7752 // Functions to create xhrs
7753 function createStandardXHR() {
7754         try {
7755                 return new window.XMLHttpRequest();
7756         } catch( e ) {}
7757 }
7758
7759 function createActiveXHR() {
7760         try {
7761                 return new window.ActiveXObject( "Microsoft.XMLHTTP" );
7762         } catch( e ) {}
7763 }
7764
7765 // Create the request object
7766 // (This is still attached to ajaxSettings for backward compatibility)
7767 jQuery.ajaxSettings.xhr = window.ActiveXObject ?
7768         /* Microsoft failed to properly
7769          * implement the XMLHttpRequest in IE7 (can't request local files),
7770          * so we use the ActiveXObject when it is available
7771          * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
7772          * we need a fallback.
7773          */
7774         function() {
7775                 return !this.isLocal && createStandardXHR() || createActiveXHR();
7776         } :
7777         // For all other browsers, use the standard XMLHttpRequest object
7778         createStandardXHR;
7779
7780 // Determine support properties
7781 (function( xhr ) {
7782         jQuery.extend( jQuery.support, {
7783                 ajax: !!xhr,
7784                 cors: !!xhr && ( "withCredentials" in xhr )
7785         });
7786 })( jQuery.ajaxSettings.xhr() );
7787
7788 // Create transport if the browser can provide an xhr
7789 if ( jQuery.support.ajax ) {
7790
7791         jQuery.ajaxTransport(function( s ) {
7792                 // Cross domain only allowed if supported through XMLHttpRequest
7793                 if ( !s.crossDomain || jQuery.support.cors ) {
7794
7795                         var callback;
7796
7797                         return {
7798                                 send: function( headers, complete ) {
7799
7800                                         // Get a new xhr
7801                                         var xhr = s.xhr(),
7802                                                 handle,
7803                                                 i;
7804
7805                                         // Open the socket
7806                                         // Passing null username, generates a login popup on Opera (#2865)
7807                                         if ( s.username ) {
7808                                                 xhr.open( s.type, s.url, s.async, s.username, s.password );
7809                                         } else {
7810                                                 xhr.open( s.type, s.url, s.async );
7811                                         }
7812
7813                                         // Apply custom fields if provided
7814                                         if ( s.xhrFields ) {
7815                                                 for ( i in s.xhrFields ) {
7816                                                         xhr[ i ] = s.xhrFields[ i ];
7817                                                 }
7818                                         }
7819
7820                                         // Override mime type if needed
7821                                         if ( s.mimeType && xhr.overrideMimeType ) {
7822                                                 xhr.overrideMimeType( s.mimeType );
7823                                         }
7824
7825                                         // X-Requested-With header
7826                                         // For cross-domain requests, seeing as conditions for a preflight are
7827                                         // akin to a jigsaw puzzle, we simply never set it to be sure.
7828                                         // (it can always be set on a per-request basis or even using ajaxSetup)
7829                                         // For same-domain requests, won't change header if already provided.
7830                                         if ( !s.crossDomain && !headers["X-Requested-With"] ) {
7831                                                 headers[ "X-Requested-With" ] = "XMLHttpRequest";
7832                                         }
7833
7834                                         // Need an extra try/catch for cross domain requests in Firefox 3
7835                                         try {
7836                                                 for ( i in headers ) {
7837                                                         xhr.setRequestHeader( i, headers[ i ] );
7838                                                 }
7839                                         } catch( _ ) {}
7840
7841                                         // Do send the request
7842                                         // This may raise an exception which is actually
7843                                         // handled in jQuery.ajax (so no try/catch here)
7844                                         xhr.send( ( s.hasContent && s.data ) || null );
7845
7846                                         // Listener
7847                                         callback = function( _, isAbort ) {
7848
7849                                                 var status,
7850                                                         statusText,
7851                                                         responseHeaders,
7852                                                         responses,
7853                                                         xml;
7854
7855                                                 // Firefox throws exceptions when accessing properties
7856                                                 // of an xhr when a network error occured
7857                                                 // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
7858                                                 try {
7859
7860                                                         // Was never called and is aborted or complete
7861                                                         if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
7862
7863                                                                 // Only called once
7864                                                                 callback = undefined;
7865
7866                                                                 // Do not keep as active anymore
7867                                                                 if ( handle ) {
7868                                                                         xhr.onreadystatechange = jQuery.noop;
7869                                                                         if ( xhrOnUnloadAbort ) {
7870                                                                                 delete xhrCallbacks[ handle ];
7871                                                                         }
7872                                                                 }
7873
7874                                                                 // If it's an abort
7875                                                                 if ( isAbort ) {
7876                                                                         // Abort it manually if needed
7877                                                                         if ( xhr.readyState !== 4 ) {
7878                                                                                 xhr.abort();
7879                                                                         }
7880                                                                 } else {
7881                                                                         status = xhr.status;
7882                                                                         responseHeaders = xhr.getAllResponseHeaders();
7883                                                                         responses = {};
7884                                                                         xml = xhr.responseXML;
7885
7886                                                                         // Construct response list
7887                                                                         if ( xml && xml.documentElement /* #4958 */ ) {
7888                                                                                 responses.xml = xml;
7889                                                                         }
7890                                                                         responses.text = xhr.responseText;
7891
7892                                                                         // Firefox throws an exception when accessing
7893                                                                         // statusText for faulty cross-domain requests
7894                                                                         try {
7895                                                                                 statusText = xhr.statusText;
7896                                                                         } catch( e ) {
7897                                                                                 // We normalize with Webkit giving an empty statusText
7898                                                                                 statusText = "";
7899                                                                         }
7900
7901                                                                         // Filter status for non standard behaviors
7902
7903                                                                         // If the request is local and we have data: assume a success
7904                                                                         // (success with no data won't get notified, that's the best we
7905                                                                         // can do given current implementations)
7906                                                                         if ( !status && s.isLocal && !s.crossDomain ) {
7907                                                                                 status = responses.text ? 200 : 404;
7908                                                                         // IE - #1450: sometimes returns 1223 when it should be 204
7909                                                                         } else if ( status === 1223 ) {
7910                                                                                 status = 204;
7911                                                                         }
7912                                                                 }
7913                                                         }
7914                                                 } catch( firefoxAccessException ) {
7915                                                         if ( !isAbort ) {
7916                                                                 complete( -1, firefoxAccessException );
7917                                                         }
7918                                                 }
7919
7920                                                 // Call complete if needed
7921                                                 if ( responses ) {
7922                                                         complete( status, statusText, responses, responseHeaders );
7923                                                 }
7924                                         };
7925
7926                                         // if we're in sync mode or it's in cache
7927                                         // and has been retrieved directly (IE6 & IE7)
7928                                         // we need to manually fire the callback
7929                                         if ( !s.async || xhr.readyState === 4 ) {
7930                                                 callback();
7931                                         } else {
7932                                                 handle = ++xhrId;
7933                                                 if ( xhrOnUnloadAbort ) {
7934                                                         // Create the active xhrs callbacks list if needed
7935                                                         // and attach the unload handler
7936                                                         if ( !xhrCallbacks ) {
7937                                                                 xhrCallbacks = {};
7938                                                                 jQuery( window ).unload( xhrOnUnloadAbort );
7939                                                         }
7940                                                         // Add to list of active xhrs callbacks
7941                                                         xhrCallbacks[ handle ] = callback;
7942                                                 }
7943                                                 xhr.onreadystatechange = callback;
7944                                         }
7945                                 },
7946
7947                                 abort: function() {
7948                                         if ( callback ) {
7949                                                 callback(0,1);
7950                                         }
7951                                 }
7952                         };
7953                 }
7954         });
7955 }
7956
7957
7958
7959
7960 var elemdisplay = {},
7961         iframe, iframeDoc,
7962         rfxtypes = /^(?:toggle|show|hide)$/,
7963         rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
7964         timerId,
7965         fxAttrs = [
7966                 // height animations
7967                 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
7968                 // width animations
7969                 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
7970                 // opacity animations
7971                 [ "opacity" ]
7972         ],
7973         fxNow,
7974         requestAnimationFrame = window.webkitRequestAnimationFrame ||
7975             window.mozRequestAnimationFrame ||
7976             window.oRequestAnimationFrame;
7977
7978 jQuery.fn.extend({
7979         show: function( speed, easing, callback ) {
7980                 var elem, display;
7981
7982                 if ( speed || speed === 0 ) {
7983                         return this.animate( genFx("show", 3), speed, easing, callback);
7984
7985                 } else {
7986                         for ( var i = 0, j = this.length; i < j; i++ ) {
7987                                 elem = this[i];
7988
7989                                 if ( elem.style ) {
7990                                         display = elem.style.display;
7991
7992                                         // Reset the inline display of this element to learn if it is
7993                                         // being hidden by cascaded rules or not
7994                                         if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
7995                                                 display = elem.style.display = "";
7996                                         }
7997
7998                                         // Set elements which have been overridden with display: none
7999                                         // in a stylesheet to whatever the default browser style is
8000                                         // for such an element
8001                                         if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
8002                                                 jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName));
8003                                         }
8004                                 }
8005                         }
8006
8007                         // Set the display of most of the elements in a second loop
8008                         // to avoid the constant reflow
8009                         for ( i = 0; i < j; i++ ) {
8010                                 elem = this[i];
8011
8012                                 if ( elem.style ) {
8013                                         display = elem.style.display;
8014
8015                                         if ( display === "" || display === "none" ) {
8016                                                 elem.style.display = jQuery._data(elem, "olddisplay") || "";
8017                                         }
8018                                 }
8019                         }
8020
8021                         return this;
8022                 }
8023         },
8024
8025         hide: function( speed, easing, callback ) {
8026                 if ( speed || speed === 0 ) {
8027                         return this.animate( genFx("hide", 3), speed, easing, callback);
8028
8029                 } else {
8030                         for ( var i = 0, j = this.length; i < j; i++ ) {
8031                                 if ( this[i].style ) {
8032                                         var display = jQuery.css( this[i], "display" );
8033
8034                                         if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) {
8035                                                 jQuery._data( this[i], "olddisplay", display );
8036                                         }
8037                                 }
8038                         }
8039
8040                         // Set the display of the elements in a second loop
8041                         // to avoid the constant reflow
8042                         for ( i = 0; i < j; i++ ) {
8043                                 if ( this[i].style ) {
8044                                         this[i].style.display = "none";
8045                                 }
8046                         }
8047
8048                         return this;
8049                 }
8050         },
8051
8052         // Save the old toggle function
8053         _toggle: jQuery.fn.toggle,
8054
8055         toggle: function( fn, fn2, callback ) {
8056                 var bool = typeof fn === "boolean";
8057
8058                 if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
8059                         this._toggle.apply( this, arguments );
8060
8061                 } else if ( fn == null || bool ) {
8062                         this.each(function() {
8063                                 var state = bool ? fn : jQuery(this).is(":hidden");
8064                                 jQuery(this)[ state ? "show" : "hide" ]();
8065                         });
8066
8067                 } else {
8068                         this.animate(genFx("toggle", 3), fn, fn2, callback);
8069                 }
8070
8071                 return this;
8072         },
8073
8074         fadeTo: function( speed, to, easing, callback ) {
8075                 return this.filter(":hidden").css("opacity", 0).show().end()
8076                                         .animate({opacity: to}, speed, easing, callback);
8077         },
8078
8079         animate: function( prop, speed, easing, callback ) {
8080                 var optall = jQuery.speed(speed, easing, callback);
8081
8082                 if ( jQuery.isEmptyObject( prop ) ) {
8083                         return this.each( optall.complete, [ false ] );
8084                 }
8085
8086                 // Do not change referenced properties as per-property easing will be lost
8087                 prop = jQuery.extend( {}, prop );
8088
8089                 return this[ optall.queue === false ? "each" : "queue" ](function() {
8090                         // XXX 'this' does not always have a nodeName when running the
8091                         // test suite
8092
8093                         if ( optall.queue === false ) {
8094                                 jQuery._mark( this );
8095                         }
8096
8097                         var opt = jQuery.extend( {}, optall ),
8098                                 isElement = this.nodeType === 1,
8099                                 hidden = isElement && jQuery(this).is(":hidden"),
8100                                 name, val, p,
8101                                 display, e,
8102                                 parts, start, end, unit;
8103
8104                         // will store per property easing and be used to determine when an animation is complete
8105                         opt.animatedProperties = {};
8106
8107                         for ( p in prop ) {
8108
8109                                 // property name normalization
8110                                 name = jQuery.camelCase( p );
8111                                 if ( p !== name ) {
8112                                         prop[ name ] = prop[ p ];
8113                                         delete prop[ p ];
8114                                 }
8115
8116                                 val = prop[ name ];
8117
8118                                 // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
8119                                 if ( jQuery.isArray( val ) ) {
8120                                         opt.animatedProperties[ name ] = val[ 1 ];
8121                                         val = prop[ name ] = val[ 0 ];
8122                                 } else {
8123                                         opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';
8124                                 }
8125
8126                                 if ( val === "hide" && hidden || val === "show" && !hidden ) {
8127                                         return opt.complete.call( this );
8128                                 }
8129
8130                                 if ( isElement && ( name === "height" || name === "width" ) ) {
8131                                         // Make sure that nothing sneaks out
8132                                         // Record all 3 overflow attributes because IE does not
8133                                         // change the overflow attribute when overflowX and
8134                                         // overflowY are set to the same value
8135                                         opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
8136
8137                                         // Set display property to inline-block for height/width
8138                                         // animations on inline elements that are having width/height
8139                                         // animated
8140                                         if ( jQuery.css( this, "display" ) === "inline" &&
8141                                                         jQuery.css( this, "float" ) === "none" ) {
8142                                                 if ( !jQuery.support.inlineBlockNeedsLayout ) {
8143                                                         this.style.display = "inline-block";
8144
8145                                                 } else {
8146                                                         display = defaultDisplay( this.nodeName );
8147
8148                                                         // inline-level elements accept inline-block;
8149                                                         // block-level elements need to be inline with layout
8150                                                         if ( display === "inline" ) {
8151                                                                 this.style.display = "inline-block";
8152
8153                                                         } else {
8154                                                                 this.style.display = "inline";
8155                                                                 this.style.zoom = 1;
8156                                                         }
8157                                                 }
8158                                         }
8159                                 }
8160                         }
8161
8162                         if ( opt.overflow != null ) {
8163                                 this.style.overflow = "hidden";
8164                         }
8165
8166                         for ( p in prop ) {
8167                                 e = new jQuery.fx( this, opt, p );
8168                                 val = prop[ p ];
8169
8170                                 if ( rfxtypes.test(val) ) {
8171                                         e[ val === "toggle" ? hidden ? "show" : "hide" : val ]();
8172
8173                                 } else {
8174                                         parts = rfxnum.exec( val );
8175                                         start = e.cur();
8176
8177                                         if ( parts ) {
8178                                                 end = parseFloat( parts[2] );
8179                                                 unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );
8180
8181                                                 // We need to compute starting value
8182                                                 if ( unit !== "px" ) {
8183                                                         jQuery.style( this, p, (end || 1) + unit);
8184                                                         start = ((end || 1) / e.cur()) * start;
8185                                                         jQuery.style( this, p, start + unit);
8186                                                 }
8187
8188                                                 // If a +=/-= token was provided, we're doing a relative animation
8189                                                 if ( parts[1] ) {
8190                                                         end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start;
8191                                                 }
8192
8193                                                 e.custom( start, end, unit );
8194
8195                                         } else {
8196                                                 e.custom( start, val, "" );
8197                                         }
8198                                 }
8199                         }
8200
8201                         // For JS strict compliance
8202                         return true;
8203                 });
8204         },
8205
8206         stop: function( clearQueue, gotoEnd ) {
8207                 if ( clearQueue ) {
8208                         this.queue([]);
8209                 }
8210
8211                 this.each(function() {
8212                         var timers = jQuery.timers,
8213                                 i = timers.length;
8214                         // clear marker counters if we know they won't be
8215                         if ( !gotoEnd ) {
8216                                 jQuery._unmark( true, this );
8217                         }
8218                         while ( i-- ) {
8219                                 if ( timers[i].elem === this ) {
8220                                         if (gotoEnd) {
8221                                                 // force the next step to be the last
8222                                                 timers[i](true);
8223                                         }
8224
8225                                         timers.splice(i, 1);
8226                                 }
8227                         }
8228                 });
8229
8230                 // start the next in the queue if the last step wasn't forced
8231                 if ( !gotoEnd ) {
8232                         this.dequeue();
8233                 }
8234
8235                 return this;
8236         }
8237
8238 });
8239
8240 // Animations created synchronously will run synchronously
8241 function createFxNow() {
8242         setTimeout( clearFxNow, 0 );
8243         return ( fxNow = jQuery.now() );
8244 }
8245
8246 function clearFxNow() {
8247         fxNow = undefined;
8248 }
8249
8250 // Generate parameters to create a standard animation
8251 function genFx( type, num ) {
8252         var obj = {};
8253
8254         jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
8255                 obj[ this ] = type;
8256         });
8257
8258         return obj;
8259 }
8260
8261 // Generate shortcuts for custom animations
8262 jQuery.each({
8263         slideDown: genFx("show", 1),
8264         slideUp: genFx("hide", 1),
8265         slideToggle: genFx("toggle", 1),
8266         fadeIn: { opacity: "show" },
8267         fadeOut: { opacity: "hide" },
8268         fadeToggle: { opacity: "toggle" }
8269 }, function( name, props ) {
8270         jQuery.fn[ name ] = function( speed, easing, callback ) {
8271                 return this.animate( props, speed, easing, callback );
8272         };
8273 });
8274
8275 jQuery.extend({
8276         speed: function( speed, easing, fn ) {
8277                 var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
8278                         complete: fn || !fn && easing ||
8279                                 jQuery.isFunction( speed ) && speed,
8280                         duration: speed,
8281                         easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
8282                 };
8283
8284                 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
8285                         opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
8286
8287                 // Queueing
8288                 opt.old = opt.complete;
8289                 opt.complete = function( noUnmark ) {
8290                         if ( opt.queue !== false ) {
8291                                 jQuery.dequeue( this );
8292                         } else if ( noUnmark !== false ) {
8293                                 jQuery._unmark( this );
8294                         }
8295
8296                         if ( jQuery.isFunction( opt.old ) ) {
8297                                 opt.old.call( this );
8298                         }
8299                 };
8300
8301                 return opt;
8302         },
8303
8304         easing: {
8305                 linear: function( p, n, firstNum, diff ) {
8306                         return firstNum + diff * p;
8307                 },
8308                 swing: function( p, n, firstNum, diff ) {
8309                         return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
8310                 }
8311         },
8312
8313         timers: [],
8314
8315         fx: function( elem, options, prop ) {
8316                 this.options = options;
8317                 this.elem = elem;
8318                 this.prop = prop;
8319
8320                 options.orig = options.orig || {};
8321         }
8322
8323 });
8324
8325 jQuery.fx.prototype = {
8326         // Simple function for setting a style value
8327         update: function() {
8328                 if ( this.options.step ) {
8329                         this.options.step.call( this.elem, this.now, this );
8330                 }
8331
8332                 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
8333         },
8334
8335         // Get the current size
8336         cur: function() {
8337                 if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
8338                         return this.elem[ this.prop ];
8339                 }
8340
8341                 var parsed,
8342                         r = jQuery.css( this.elem, this.prop );
8343                 // Empty strings, null, undefined and "auto" are converted to 0,
8344                 // complex values such as "rotate(1rad)" are returned as is,
8345                 // simple values such as "10px" are parsed to Float.
8346                 return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;
8347         },
8348
8349         // Start an animation from one number to another
8350         custom: function( from, to, unit ) {
8351                 var self = this,
8352                         fx = jQuery.fx,
8353                         raf;
8354
8355                 this.startTime = fxNow || createFxNow();
8356                 this.start = from;
8357                 this.end = to;
8358                 this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
8359                 this.now = this.start;
8360                 this.pos = this.state = 0;
8361
8362                 function t( gotoEnd ) {
8363                         return self.step(gotoEnd);
8364                 }
8365
8366                 t.elem = this.elem;
8367
8368                 if ( t() && jQuery.timers.push(t) && !timerId ) {
8369                         // Use requestAnimationFrame instead of setInterval if available
8370                         if ( requestAnimationFrame ) {
8371                                 timerId = 1;
8372                                 raf = function() {
8373                                         // When timerId gets set to null at any point, this stops
8374                                         if ( timerId ) {
8375                                                 requestAnimationFrame( raf );
8376                                                 fx.tick();
8377                                         }
8378                                 };
8379                                 requestAnimationFrame( raf );
8380                         } else {
8381                                 timerId = setInterval( fx.tick, fx.interval );
8382                         }
8383                 }
8384         },
8385
8386         // Simple 'show' function
8387         show: function() {
8388                 // Remember where we started, so that we can go back to it later
8389                 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
8390                 this.options.show = true;
8391
8392                 // Begin the animation
8393                 // Make sure that we start at a small width/height to avoid any
8394                 // flash of content
8395                 this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
8396
8397                 // Start by showing the element
8398                 jQuery( this.elem ).show();
8399         },
8400
8401         // Simple 'hide' function
8402         hide: function() {
8403                 // Remember where we started, so that we can go back to it later
8404                 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
8405                 this.options.hide = true;
8406
8407                 // Begin the animation
8408                 this.custom(this.cur(), 0);
8409         },
8410
8411         // Each step of an animation
8412         step: function( gotoEnd ) {
8413                 var t = fxNow || createFxNow(),
8414                         done = true,
8415                         elem = this.elem,
8416                         options = this.options,
8417                         i, n;
8418
8419                 if ( gotoEnd || t >= options.duration + this.startTime ) {
8420                         this.now = this.end;
8421                         this.pos = this.state = 1;
8422                         this.update();
8423
8424                         options.animatedProperties[ this.prop ] = true;
8425
8426                         for ( i in options.animatedProperties ) {
8427                                 if ( options.animatedProperties[i] !== true ) {
8428                                         done = false;
8429                                 }
8430                         }
8431
8432                         if ( done ) {
8433                                 // Reset the overflow
8434                                 if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
8435
8436                                         jQuery.each( [ "", "X", "Y" ], function (index, value) {
8437                                                 elem.style[ "overflow" + value ] = options.overflow[index];
8438                                         });
8439                                 }
8440
8441                                 // Hide the element if the "hide" operation was done
8442                                 if ( options.hide ) {
8443                                         jQuery(elem).hide();
8444                                 }
8445
8446                                 // Reset the properties, if the item has been hidden or shown
8447                                 if ( options.hide || options.show ) {
8448                                         for ( var p in options.animatedProperties ) {
8449                                                 jQuery.style( elem, p, options.orig[p] );
8450                                         }
8451                                 }
8452
8453                                 // Execute the complete function
8454                                 options.complete.call( elem );
8455                         }
8456
8457                         return false;
8458
8459                 } else {
8460                         // classical easing cannot be used with an Infinity duration
8461                         if ( options.duration == Infinity ) {
8462                                 this.now = t;
8463                         } else {
8464                                 n = t - this.startTime;
8465                                 this.state = n / options.duration;
8466
8467                                 // Perform the easing function, defaults to swing
8468                                 this.pos = jQuery.easing[ options.animatedProperties[ this.prop ] ]( this.state, n, 0, 1, options.duration );
8469                                 this.now = this.start + ((this.end - this.start) * this.pos);
8470                         }
8471                         // Perform the next step of the animation
8472                         this.update();
8473                 }
8474
8475                 return true;
8476         }
8477 };
8478
8479 jQuery.extend( jQuery.fx, {
8480         tick: function() {
8481                 for ( var timers = jQuery.timers, i = 0 ; i < timers.length ; ++i ) {
8482                         if ( !timers[i]() ) {
8483                                 timers.splice(i--, 1);
8484                         }
8485                 }
8486
8487                 if ( !timers.length ) {
8488                         jQuery.fx.stop();
8489                 }
8490         },
8491
8492         interval: 13,
8493
8494         stop: function() {
8495                 clearInterval( timerId );
8496                 timerId = null;
8497         },
8498
8499         speeds: {
8500                 slow: 600,
8501                 fast: 200,
8502                 // Default speed
8503                 _default: 400
8504         },
8505
8506         step: {
8507                 opacity: function( fx ) {
8508                         jQuery.style( fx.elem, "opacity", fx.now );
8509                 },
8510
8511                 _default: function( fx ) {
8512                         if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
8513                                 fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
8514                         } else {
8515                                 fx.elem[ fx.prop ] = fx.now;
8516                         }
8517                 }
8518         }
8519 });
8520
8521 if ( jQuery.expr && jQuery.expr.filters ) {
8522         jQuery.expr.filters.animated = function( elem ) {
8523                 return jQuery.grep(jQuery.timers, function( fn ) {
8524                         return elem === fn.elem;
8525                 }).length;
8526         };
8527 }
8528
8529 // Try to restore the default display value of an element
8530 function defaultDisplay( nodeName ) {
8531
8532         if ( !elemdisplay[ nodeName ] ) {
8533
8534                 var elem = jQuery( "<" + nodeName + ">" ).appendTo( "body" ),
8535                         display = elem.css( "display" );
8536
8537                 elem.remove();
8538
8539                 // If the simple way fails,
8540                 // get element's real default display by attaching it to a temp iframe
8541                 if ( display === "none" || display === "" ) {
8542                         // No iframe to use yet, so create it
8543                         if ( !iframe ) {
8544                                 iframe = document.createElement( "iframe" );
8545                                 iframe.frameBorder = iframe.width = iframe.height = 0;
8546                         }
8547
8548                         document.body.appendChild( iframe );
8549
8550                         // Create a cacheable copy of the iframe document on first call.
8551                         // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake html
8552                         // document to it, Webkit & Firefox won't allow reusing the iframe document
8553                         if ( !iframeDoc || !iframe.createElement ) {
8554                                 iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
8555                                 iframeDoc.write( "<!doctype><html><body></body></html>" );
8556                         }
8557
8558                         elem = iframeDoc.createElement( nodeName );
8559
8560                         iframeDoc.body.appendChild( elem );
8561
8562                         display = jQuery.css( elem, "display" );
8563
8564                         document.body.removeChild( iframe );
8565                 }
8566
8567                 // Store the correct default display
8568                 elemdisplay[ nodeName ] = display;
8569         }
8570
8571         return elemdisplay[ nodeName ];
8572 }
8573
8574
8575
8576
8577 var rtable = /^t(?:able|d|h)$/i,
8578         rroot = /^(?:body|html)$/i;
8579
8580 if ( "getBoundingClientRect" in document.documentElement ) {
8581         jQuery.fn.offset = function( options ) {
8582                 var elem = this[0], box;
8583
8584                 if ( options ) {
8585                         return this.each(function( i ) {
8586                                 jQuery.offset.setOffset( this, options, i );
8587                         });
8588                 }
8589
8590                 if ( !elem || !elem.ownerDocument ) {
8591                         return null;
8592                 }
8593
8594                 if ( elem === elem.ownerDocument.body ) {
8595                         return jQuery.offset.bodyOffset( elem );
8596                 }
8597
8598                 try {
8599                         box = elem.getBoundingClientRect();
8600                 } catch(e) {}
8601
8602                 var doc = elem.ownerDocument,
8603                         docElem = doc.documentElement;
8604
8605                 // Make sure we're not dealing with a disconnected DOM node
8606                 if ( !box || !jQuery.contains( docElem, elem ) ) {
8607                         return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
8608                 }
8609
8610                 var body = doc.body,
8611                         win = getWindow(doc),
8612                         clientTop  = docElem.clientTop  || body.clientTop  || 0,
8613                         clientLeft = docElem.clientLeft || body.clientLeft || 0,
8614                         scrollTop  = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop,
8615                         scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
8616                         top  = box.top  + scrollTop  - clientTop,
8617                         left = box.left + scrollLeft - clientLeft;
8618
8619                 return { top: top, left: left };
8620         };
8621
8622 } else {
8623         jQuery.fn.offset = function( options ) {
8624                 var elem = this[0];
8625
8626                 if ( options ) {
8627                         return this.each(function( i ) {
8628                                 jQuery.offset.setOffset( this, options, i );
8629                         });
8630                 }
8631
8632                 if ( !elem || !elem.ownerDocument ) {
8633                         return null;
8634                 }
8635
8636                 if ( elem === elem.ownerDocument.body ) {
8637                         return jQuery.offset.bodyOffset( elem );
8638                 }
8639
8640                 jQuery.offset.initialize();
8641
8642                 var computedStyle,
8643                         offsetParent = elem.offsetParent,
8644                         prevOffsetParent = elem,
8645                         doc = elem.ownerDocument,
8646                         docElem = doc.documentElement,
8647                         body = doc.body,
8648                         defaultView = doc.defaultView,
8649                         prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
8650                         top = elem.offsetTop,
8651                         left = elem.offsetLeft;
8652
8653                 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
8654                         if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
8655                                 break;
8656                         }
8657
8658                         computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
8659                         top  -= elem.scrollTop;
8660                         left -= elem.scrollLeft;
8661
8662                         if ( elem === offsetParent ) {
8663                                 top  += elem.offsetTop;
8664                                 left += elem.offsetLeft;
8665
8666                                 if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
8667                                         top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
8668                                         left += parseFloat( computedStyle.borderLeftWidth ) || 0;
8669                                 }
8670
8671                                 prevOffsetParent = offsetParent;
8672                                 offsetParent = elem.offsetParent;
8673                         }
8674
8675                         if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
8676                                 top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
8677                                 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
8678                         }
8679
8680                         prevComputedStyle = computedStyle;
8681                 }
8682
8683                 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
8684                         top  += body.offsetTop;
8685                         left += body.offsetLeft;
8686                 }
8687
8688                 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
8689                         top  += Math.max( docElem.scrollTop, body.scrollTop );
8690                         left += Math.max( docElem.scrollLeft, body.scrollLeft );
8691                 }
8692
8693                 return { top: top, left: left };
8694         };
8695 }
8696
8697 jQuery.offset = {
8698         initialize: function() {
8699                 var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
8700                         html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
8701
8702                 jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
8703
8704                 container.innerHTML = html;
8705                 body.insertBefore( container, body.firstChild );
8706                 innerDiv = container.firstChild;
8707                 checkDiv = innerDiv.firstChild;
8708                 td = innerDiv.nextSibling.firstChild.firstChild;
8709
8710                 this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
8711                 this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
8712
8713                 checkDiv.style.position = "fixed";
8714                 checkDiv.style.top = "20px";
8715
8716                 // safari subtracts parent border width here which is 5px
8717                 this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
8718                 checkDiv.style.position = checkDiv.style.top = "";
8719
8720                 innerDiv.style.overflow = "hidden";
8721                 innerDiv.style.position = "relative";
8722
8723                 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
8724
8725                 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
8726
8727                 body.removeChild( container );
8728                 jQuery.offset.initialize = jQuery.noop;
8729         },
8730
8731         bodyOffset: function( body ) {
8732                 var top = body.offsetTop,
8733                         left = body.offsetLeft;
8734
8735                 jQuery.offset.initialize();
8736
8737                 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
8738                         top  += parseFloat( jQuery.css(body, "marginTop") ) || 0;
8739                         left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
8740                 }
8741
8742                 return { top: top, left: left };
8743         },
8744
8745         setOffset: function( elem, options, i ) {
8746                 var position = jQuery.css( elem, "position" );
8747
8748                 // set position first, in-case top/left are set even on static elem
8749                 if ( position === "static" ) {
8750                         elem.style.position = "relative";
8751                 }
8752
8753                 var curElem = jQuery( elem ),
8754                         curOffset = curElem.offset(),
8755                         curCSSTop = jQuery.css( elem, "top" ),
8756                         curCSSLeft = jQuery.css( elem, "left" ),
8757                         calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
8758                         props = {}, curPosition = {}, curTop, curLeft;
8759
8760                 // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
8761                 if ( calculatePosition ) {
8762                         curPosition = curElem.position();
8763                         curTop = curPosition.top;
8764                         curLeft = curPosition.left;
8765                 } else {
8766                         curTop = parseFloat( curCSSTop ) || 0;
8767                         curLeft = parseFloat( curCSSLeft ) || 0;
8768                 }
8769
8770                 if ( jQuery.isFunction( options ) ) {
8771                         options = options.call( elem, i, curOffset );
8772                 }
8773
8774                 if (options.top != null) {
8775                         props.top = (options.top - curOffset.top) + curTop;
8776                 }
8777                 if (options.left != null) {
8778                         props.left = (options.left - curOffset.left) + curLeft;
8779                 }
8780
8781                 if ( "using" in options ) {
8782                         options.using.call( elem, props );
8783                 } else {
8784                         curElem.css( props );
8785                 }
8786         }
8787 };
8788
8789
8790 jQuery.fn.extend({
8791         position: function() {
8792                 if ( !this[0] ) {
8793                         return null;
8794                 }
8795
8796                 var elem = this[0],
8797
8798                 // Get *real* offsetParent
8799                 offsetParent = this.offsetParent(),
8800
8801                 // Get correct offsets
8802                 offset       = this.offset(),
8803                 parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
8804
8805                 // Subtract element margins
8806                 // note: when an element has margin: auto the offsetLeft and marginLeft
8807                 // are the same in Safari causing offset.left to incorrectly be 0
8808                 offset.top  -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
8809                 offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
8810
8811                 // Add offsetParent borders
8812                 parentOffset.top  += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
8813                 parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
8814
8815                 // Subtract the two offsets
8816                 return {
8817                         top:  offset.top  - parentOffset.top,
8818                         left: offset.left - parentOffset.left
8819                 };
8820         },
8821
8822         offsetParent: function() {
8823                 return this.map(function() {
8824                         var offsetParent = this.offsetParent || document.body;
8825                         while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
8826                                 offsetParent = offsetParent.offsetParent;
8827                         }
8828                         return offsetParent;
8829                 });
8830         }
8831 });
8832
8833
8834 // Create scrollLeft and scrollTop methods
8835 jQuery.each( ["Left", "Top"], function( i, name ) {
8836         var method = "scroll" + name;
8837
8838         jQuery.fn[ method ] = function( val ) {
8839                 var elem, win;
8840
8841                 if ( val === undefined ) {
8842                         elem = this[ 0 ];
8843
8844                         if ( !elem ) {
8845                                 return null;
8846                         }
8847
8848                         win = getWindow( elem );
8849
8850                         // Return the scroll offset
8851                         return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
8852                                 jQuery.support.boxModel && win.document.documentElement[ method ] ||
8853                                         win.document.body[ method ] :
8854                                 elem[ method ];
8855                 }
8856
8857                 // Set the scroll offset
8858                 return this.each(function() {
8859                         win = getWindow( this );
8860
8861                         if ( win ) {
8862                                 win.scrollTo(
8863                                         !i ? val : jQuery( win ).scrollLeft(),
8864                                          i ? val : jQuery( win ).scrollTop()
8865                                 );
8866
8867                         } else {
8868                                 this[ method ] = val;
8869                         }
8870                 });
8871         };
8872 });
8873
8874 function getWindow( elem ) {
8875         return jQuery.isWindow( elem ) ?
8876                 elem :
8877                 elem.nodeType === 9 ?
8878                         elem.defaultView || elem.parentWindow :
8879                         false;
8880 }
8881
8882
8883
8884
8885 // Create innerHeight, innerWidth, outerHeight and outerWidth methods
8886 jQuery.each([ "Height", "Width" ], function( i, name ) {
8887
8888         var type = name.toLowerCase();
8889
8890         // innerHeight and innerWidth
8891         jQuery.fn["inner" + name] = function() {
8892                 return this[0] ?
8893                         parseFloat( jQuery.css( this[0], type, "padding" ) ) :
8894                         null;
8895         };
8896
8897         // outerHeight and outerWidth
8898         jQuery.fn["outer" + name] = function( margin ) {
8899                 return this[0] ?
8900                         parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) :
8901                         null;
8902         };
8903
8904         jQuery.fn[ type ] = function( size ) {
8905                 // Get window width or height
8906                 var elem = this[0];
8907                 if ( !elem ) {
8908                         return size == null ? null : this;
8909                 }
8910
8911                 if ( jQuery.isFunction( size ) ) {
8912                         return this.each(function( i ) {
8913                                 var self = jQuery( this );
8914                                 self[ type ]( size.call( this, i, self[ type ]() ) );
8915                         });
8916                 }
8917
8918                 if ( jQuery.isWindow( elem ) ) {
8919                         // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
8920                         // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
8921                         var docElemProp = elem.document.documentElement[ "client" + name ];
8922                         return elem.document.compatMode === "CSS1Compat" && docElemProp ||
8923                                 elem.document.body[ "client" + name ] || docElemProp;
8924
8925                 // Get document width or height
8926                 } else if ( elem.nodeType === 9 ) {
8927                         // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
8928                         return Math.max(
8929                                 elem.documentElement["client" + name],
8930                                 elem.body["scroll" + name], elem.documentElement["scroll" + name],
8931                                 elem.body["offset" + name], elem.documentElement["offset" + name]
8932                         );
8933
8934                 // Get or set width or height on the element
8935                 } else if ( size === undefined ) {
8936                         var orig = jQuery.css( elem, type ),
8937                                 ret = parseFloat( orig );
8938
8939                         return jQuery.isNaN( ret ) ? orig : ret;
8940
8941                 // Set the width or height on the element (default to pixels if value is unitless)
8942                 } else {
8943                         return this.css( type, typeof size === "string" ? size : size + "px" );
8944                 }
8945         };
8946
8947 });
8948
8949
8950 window.jQuery = window.$ = jQuery;
8951 })(window);