Finish framework, include W3.css build web site via templates and jQuery
[infodrom/musiikki-web.git] / html / jquery-1.10.2.js
1 /*!
2  * jQuery JavaScript Library v1.10.2
3  * http://jquery.com/
4  *
5  * Includes Sizzle.js
6  * http://sizzlejs.com/
7  *
8  * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors
9  * Released under the MIT license
10  * http://jquery.org/license
11  *
12  * Date: 2013-07-03T13:48Z
13  */
14 (function( window, undefined ) {
15
16 // Can't do this because several apps including ASP.NET trace
17 // the stack via arguments.caller.callee and Firefox dies if
18 // you try to trace through "use strict" call chains. (#13335)
19 // Support: Firefox 18+
20 //"use strict";
21 var
22         // The deferred used on DOM ready
23         readyList,
24
25         // A central reference to the root jQuery(document)
26         rootjQuery,
27
28         // Support: IE<10
29         // For `typeof xmlNode.method` instead of `xmlNode.method !== undefined`
30         core_strundefined = typeof undefined,
31
32         // Use the correct document accordingly with window argument (sandbox)
33         location = window.location,
34         document = window.document,
35         docElem = document.documentElement,
36
37         // Map over jQuery in case of overwrite
38         _jQuery = window.jQuery,
39
40         // Map over the $ in case of overwrite
41         _$ = window.$,
42
43         // [[Class]] -> type pairs
44         class2type = {},
45
46         // List of deleted data cache ids, so we can reuse them
47         core_deletedIds = [],
48
49         core_version = "1.10.2",
50
51         // Save a reference to some core methods
52         core_concat = core_deletedIds.concat,
53         core_push = core_deletedIds.push,
54         core_slice = core_deletedIds.slice,
55         core_indexOf = core_deletedIds.indexOf,
56         core_toString = class2type.toString,
57         core_hasOwn = class2type.hasOwnProperty,
58         core_trim = core_version.trim,
59
60         // Define a local copy of jQuery
61         jQuery = function( selector, context ) {
62                 // The jQuery object is actually just the init constructor 'enhanced'
63                 return new jQuery.fn.init( selector, context, rootjQuery );
64         },
65
66         // Used for matching numbers
67         core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,
68
69         // Used for splitting on whitespace
70         core_rnotwhite = /\S+/g,
71
72         // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)
73         rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
74
75         // A simple way to check for HTML strings
76         // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
77         // Strict HTML recognition (#11290: must start with <)
78         rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
79
80         // Match a standalone tag
81         rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
82
83         // JSON RegExp
84         rvalidchars = /^[\],:{}\s]*$/,
85         rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
86         rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,
87         rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,
88
89         // Matches dashed string for camelizing
90         rmsPrefix = /^-ms-/,
91         rdashAlpha = /-([\da-z])/gi,
92
93         // Used by jQuery.camelCase as callback to replace()
94         fcamelCase = function( all, letter ) {
95                 return letter.toUpperCase();
96         },
97
98         // The ready event handler
99         completed = function( event ) {
100
101                 // readyState === "complete" is good enough for us to call the dom ready in oldIE
102                 if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
103                         detach();
104                         jQuery.ready();
105                 }
106         },
107         // Clean-up method for dom ready events
108         detach = function() {
109                 if ( document.addEventListener ) {
110                         document.removeEventListener( "DOMContentLoaded", completed, false );
111                         window.removeEventListener( "load", completed, false );
112
113                 } else {
114                         document.detachEvent( "onreadystatechange", completed );
115                         window.detachEvent( "onload", completed );
116                 }
117         };
118
119 jQuery.fn = jQuery.prototype = {
120         // The current version of jQuery being used
121         jquery: core_version,
122
123         constructor: jQuery,
124         init: function( selector, context, rootjQuery ) {
125                 var match, elem;
126
127                 // HANDLE: $(""), $(null), $(undefined), $(false)
128                 if ( !selector ) {
129                         return this;
130                 }
131
132                 // Handle HTML strings
133                 if ( typeof selector === "string" ) {
134                         if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
135                                 // Assume that strings that start and end with <> are HTML and skip the regex check
136                                 match = [ null, selector, null ];
137
138                         } else {
139                                 match = rquickExpr.exec( selector );
140                         }
141
142                         // Match html or make sure no context is specified for #id
143                         if ( match && (match[1] || !context) ) {
144
145                                 // HANDLE: $(html) -> $(array)
146                                 if ( match[1] ) {
147                                         context = context instanceof jQuery ? context[0] : context;
148
149                                         // scripts is true for back-compat
150                                         jQuery.merge( this, jQuery.parseHTML(
151                                                 match[1],
152                                                 context && context.nodeType ? context.ownerDocument || context : document,
153                                                 true
154                                         ) );
155
156                                         // HANDLE: $(html, props)
157                                         if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
158                                                 for ( match in context ) {
159                                                         // Properties of context are called as methods if possible
160                                                         if ( jQuery.isFunction( this[ match ] ) ) {
161                                                                 this[ match ]( context[ match ] );
162
163                                                         // ...and otherwise set as attributes
164                                                         } else {
165                                                                 this.attr( match, context[ match ] );
166                                                         }
167                                                 }
168                                         }
169
170                                         return this;
171
172                                 // HANDLE: $(#id)
173                                 } else {
174                                         elem = document.getElementById( match[2] );
175
176                                         // Check parentNode to catch when Blackberry 4.6 returns
177                                         // nodes that are no longer in the document #6963
178                                         if ( elem && elem.parentNode ) {
179                                                 // Handle the case where IE and Opera return items
180                                                 // by name instead of ID
181                                                 if ( elem.id !== match[2] ) {
182                                                         return rootjQuery.find( selector );
183                                                 }
184
185                                                 // Otherwise, we inject the element directly into the jQuery object
186                                                 this.length = 1;
187                                                 this[0] = elem;
188                                         }
189
190                                         this.context = document;
191                                         this.selector = selector;
192                                         return this;
193                                 }
194
195                         // HANDLE: $(expr, $(...))
196                         } else if ( !context || context.jquery ) {
197                                 return ( context || rootjQuery ).find( selector );
198
199                         // HANDLE: $(expr, context)
200                         // (which is just equivalent to: $(context).find(expr)
201                         } else {
202                                 return this.constructor( context ).find( selector );
203                         }
204
205                 // HANDLE: $(DOMElement)
206                 } else if ( selector.nodeType ) {
207                         this.context = this[0] = selector;
208                         this.length = 1;
209                         return this;
210
211                 // HANDLE: $(function)
212                 // Shortcut for document ready
213                 } else if ( jQuery.isFunction( selector ) ) {
214                         return rootjQuery.ready( selector );
215                 }
216
217                 if ( selector.selector !== undefined ) {
218                         this.selector = selector.selector;
219                         this.context = selector.context;
220                 }
221
222                 return jQuery.makeArray( selector, this );
223         },
224
225         // Start with an empty selector
226         selector: "",
227
228         // The default length of a jQuery object is 0
229         length: 0,
230
231         toArray: function() {
232                 return core_slice.call( this );
233         },
234
235         // Get the Nth element in the matched element set OR
236         // Get the whole matched element set as a clean array
237         get: function( num ) {
238                 return num == null ?
239
240                         // Return a 'clean' array
241                         this.toArray() :
242
243                         // Return just the object
244                         ( num < 0 ? this[ this.length + num ] : this[ num ] );
245         },
246
247         // Take an array of elements and push it onto the stack
248         // (returning the new matched element set)
249         pushStack: function( elems ) {
250
251                 // Build a new jQuery matched element set
252                 var ret = jQuery.merge( this.constructor(), elems );
253
254                 // Add the old object onto the stack (as a reference)
255                 ret.prevObject = this;
256                 ret.context = this.context;
257
258                 // Return the newly-formed element set
259                 return ret;
260         },
261
262         // Execute a callback for every element in the matched set.
263         // (You can seed the arguments with an array of args, but this is
264         // only used internally.)
265         each: function( callback, args ) {
266                 return jQuery.each( this, callback, args );
267         },
268
269         ready: function( fn ) {
270                 // Add the callback
271                 jQuery.ready.promise().done( fn );
272
273                 return this;
274         },
275
276         slice: function() {
277                 return this.pushStack( core_slice.apply( this, arguments ) );
278         },
279
280         first: function() {
281                 return this.eq( 0 );
282         },
283
284         last: function() {
285                 return this.eq( -1 );
286         },
287
288         eq: function( i ) {
289                 var len = this.length,
290                         j = +i + ( i < 0 ? len : 0 );
291                 return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
292         },
293
294         map: function( callback ) {
295                 return this.pushStack( jQuery.map(this, function( elem, i ) {
296                         return callback.call( elem, i, elem );
297                 }));
298         },
299
300         end: function() {
301                 return this.prevObject || this.constructor(null);
302         },
303
304         // For internal use only.
305         // Behaves like an Array's method, not like a jQuery method.
306         push: core_push,
307         sort: [].sort,
308         splice: [].splice
309 };
310
311 // Give the init function the jQuery prototype for later instantiation
312 jQuery.fn.init.prototype = jQuery.fn;
313
314 jQuery.extend = jQuery.fn.extend = function() {
315         var src, copyIsArray, copy, name, options, clone,
316                 target = arguments[0] || {},
317                 i = 1,
318                 length = arguments.length,
319                 deep = false;
320
321         // Handle a deep copy situation
322         if ( typeof target === "boolean" ) {
323                 deep = target;
324                 target = arguments[1] || {};
325                 // skip the boolean and the target
326                 i = 2;
327         }
328
329         // Handle case when target is a string or something (possible in deep copy)
330         if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
331                 target = {};
332         }
333
334         // extend jQuery itself if only one argument is passed
335         if ( length === i ) {
336                 target = this;
337                 --i;
338         }
339
340         for ( ; i < length; i++ ) {
341                 // Only deal with non-null/undefined values
342                 if ( (options = arguments[ i ]) != null ) {
343                         // Extend the base object
344                         for ( name in options ) {
345                                 src = target[ name ];
346                                 copy = options[ name ];
347
348                                 // Prevent never-ending loop
349                                 if ( target === copy ) {
350                                         continue;
351                                 }
352
353                                 // Recurse if we're merging plain objects or arrays
354                                 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
355                                         if ( copyIsArray ) {
356                                                 copyIsArray = false;
357                                                 clone = src && jQuery.isArray(src) ? src : [];
358
359                                         } else {
360                                                 clone = src && jQuery.isPlainObject(src) ? src : {};
361                                         }
362
363                                         // Never move original objects, clone them
364                                         target[ name ] = jQuery.extend( deep, clone, copy );
365
366                                 // Don't bring in undefined values
367                                 } else if ( copy !== undefined ) {
368                                         target[ name ] = copy;
369                                 }
370                         }
371                 }
372         }
373
374         // Return the modified object
375         return target;
376 };
377
378 jQuery.extend({
379         // Unique for each copy of jQuery on the page
380         // Non-digits removed to match rinlinejQuery
381         expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ),
382
383         noConflict: function( deep ) {
384                 if ( window.$ === jQuery ) {
385                         window.$ = _$;
386                 }
387
388                 if ( deep && window.jQuery === jQuery ) {
389                         window.jQuery = _jQuery;
390                 }
391
392                 return jQuery;
393         },
394
395         // Is the DOM ready to be used? Set to true once it occurs.
396         isReady: false,
397
398         // A counter to track how many items to wait for before
399         // the ready event fires. See #6781
400         readyWait: 1,
401
402         // Hold (or release) the ready event
403         holdReady: function( hold ) {
404                 if ( hold ) {
405                         jQuery.readyWait++;
406                 } else {
407                         jQuery.ready( true );
408                 }
409         },
410
411         // Handle when the DOM is ready
412         ready: function( wait ) {
413
414                 // Abort if there are pending holds or we're already ready
415                 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
416                         return;
417                 }
418
419                 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
420                 if ( !document.body ) {
421                         return setTimeout( jQuery.ready );
422                 }
423
424                 // Remember that the DOM is ready
425                 jQuery.isReady = true;
426
427                 // If a normal DOM Ready event fired, decrement, and wait if need be
428                 if ( wait !== true && --jQuery.readyWait > 0 ) {
429                         return;
430                 }
431
432                 // If there are functions bound, to execute
433                 readyList.resolveWith( document, [ jQuery ] );
434
435                 // Trigger any bound ready events
436                 if ( jQuery.fn.trigger ) {
437                         jQuery( document ).trigger("ready").off("ready");
438                 }
439         },
440
441         // See test/unit/core.js for details concerning isFunction.
442         // Since version 1.3, DOM methods and functions like alert
443         // aren't supported. They return false on IE (#2968).
444         isFunction: function( obj ) {
445                 return jQuery.type(obj) === "function";
446         },
447
448         isArray: Array.isArray || function( obj ) {
449                 return jQuery.type(obj) === "array";
450         },
451
452         isWindow: function( obj ) {
453                 /* jshint eqeqeq: false */
454                 return obj != null && obj == obj.window;
455         },
456
457         isNumeric: function( obj ) {
458                 return !isNaN( parseFloat(obj) ) && isFinite( obj );
459         },
460
461         type: function( obj ) {
462                 if ( obj == null ) {
463                         return String( obj );
464                 }
465                 return typeof obj === "object" || typeof obj === "function" ?
466                         class2type[ core_toString.call(obj) ] || "object" :
467                         typeof obj;
468         },
469
470         isPlainObject: function( obj ) {
471                 var key;
472
473                 // Must be an Object.
474                 // Because of IE, we also have to check the presence of the constructor property.
475                 // Make sure that DOM nodes and window objects don't pass through, as well
476                 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
477                         return false;
478                 }
479
480                 try {
481                         // Not own constructor property must be Object
482                         if ( obj.constructor &&
483                                 !core_hasOwn.call(obj, "constructor") &&
484                                 !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
485                                 return false;
486                         }
487                 } catch ( e ) {
488                         // IE8,9 Will throw exceptions on certain host objects #9897
489                         return false;
490                 }
491
492                 // Support: IE<9
493                 // Handle iteration over inherited properties before own properties.
494                 if ( jQuery.support.ownLast ) {
495                         for ( key in obj ) {
496                                 return core_hasOwn.call( obj, key );
497                         }
498                 }
499
500                 // Own properties are enumerated firstly, so to speed up,
501                 // if last one is own, then all properties are own.
502                 for ( key in obj ) {}
503
504                 return key === undefined || core_hasOwn.call( obj, key );
505         },
506
507         isEmptyObject: function( obj ) {
508                 var name;
509                 for ( name in obj ) {
510                         return false;
511                 }
512                 return true;
513         },
514
515         error: function( msg ) {
516                 throw new Error( msg );
517         },
518
519         // data: string of html
520         // context (optional): If specified, the fragment will be created in this context, defaults to document
521         // keepScripts (optional): If true, will include scripts passed in the html string
522         parseHTML: function( data, context, keepScripts ) {
523                 if ( !data || typeof data !== "string" ) {
524                         return null;
525                 }
526                 if ( typeof context === "boolean" ) {
527                         keepScripts = context;
528                         context = false;
529                 }
530                 context = context || document;
531
532                 var parsed = rsingleTag.exec( data ),
533                         scripts = !keepScripts && [];
534
535                 // Single tag
536                 if ( parsed ) {
537                         return [ context.createElement( parsed[1] ) ];
538                 }
539
540                 parsed = jQuery.buildFragment( [ data ], context, scripts );
541                 if ( scripts ) {
542                         jQuery( scripts ).remove();
543                 }
544                 return jQuery.merge( [], parsed.childNodes );
545         },
546
547         parseJSON: function( data ) {
548                 // Attempt to parse using the native JSON parser first
549                 if ( window.JSON && window.JSON.parse ) {
550                         return window.JSON.parse( data );
551                 }
552
553                 if ( data === null ) {
554                         return data;
555                 }
556
557                 if ( typeof data === "string" ) {
558
559                         // Make sure leading/trailing whitespace is removed (IE can't handle it)
560                         data = jQuery.trim( data );
561
562                         if ( data ) {
563                                 // Make sure the incoming data is actual JSON
564                                 // Logic borrowed from http://json.org/json2.js
565                                 if ( rvalidchars.test( data.replace( rvalidescape, "@" )
566                                         .replace( rvalidtokens, "]" )
567                                         .replace( rvalidbraces, "")) ) {
568
569                                         return ( new Function( "return " + data ) )();
570                                 }
571                         }
572                 }
573
574                 jQuery.error( "Invalid JSON: " + data );
575         },
576
577         // Cross-browser xml parsing
578         parseXML: function( data ) {
579                 var xml, tmp;
580                 if ( !data || typeof data !== "string" ) {
581                         return null;
582                 }
583                 try {
584                         if ( window.DOMParser ) { // Standard
585                                 tmp = new DOMParser();
586                                 xml = tmp.parseFromString( data , "text/xml" );
587                         } else { // IE
588                                 xml = new ActiveXObject( "Microsoft.XMLDOM" );
589                                 xml.async = "false";
590                                 xml.loadXML( data );
591                         }
592                 } catch( e ) {
593                         xml = undefined;
594                 }
595                 if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
596                         jQuery.error( "Invalid XML: " + data );
597                 }
598                 return xml;
599         },
600
601         noop: function() {},
602
603         // Evaluates a script in a global context
604         // Workarounds based on findings by Jim Driscoll
605         // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
606         globalEval: function( data ) {
607                 if ( data && jQuery.trim( data ) ) {
608                         // We use execScript on Internet Explorer
609                         // We use an anonymous function so that context is window
610                         // rather than jQuery in Firefox
611                         ( window.execScript || function( data ) {
612                                 window[ "eval" ].call( window, data );
613                         } )( data );
614                 }
615         },
616
617         // Convert dashed to camelCase; used by the css and data modules
618         // Microsoft forgot to hump their vendor prefix (#9572)
619         camelCase: function( string ) {
620                 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
621         },
622
623         nodeName: function( elem, name ) {
624                 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
625         },
626
627         // args is for internal usage only
628         each: function( obj, callback, args ) {
629                 var value,
630                         i = 0,
631                         length = obj.length,
632                         isArray = isArraylike( obj );
633
634                 if ( args ) {
635                         if ( isArray ) {
636                                 for ( ; i < length; i++ ) {
637                                         value = callback.apply( obj[ i ], args );
638
639                                         if ( value === false ) {
640                                                 break;
641                                         }
642                                 }
643                         } else {
644                                 for ( i in obj ) {
645                                         value = callback.apply( obj[ i ], args );
646
647                                         if ( value === false ) {
648                                                 break;
649                                         }
650                                 }
651                         }
652
653                 // A special, fast, case for the most common use of each
654                 } else {
655                         if ( isArray ) {
656                                 for ( ; i < length; i++ ) {
657                                         value = callback.call( obj[ i ], i, obj[ i ] );
658
659                                         if ( value === false ) {
660                                                 break;
661                                         }
662                                 }
663                         } else {
664                                 for ( i in obj ) {
665                                         value = callback.call( obj[ i ], i, obj[ i ] );
666
667                                         if ( value === false ) {
668                                                 break;
669                                         }
670                                 }
671                         }
672                 }
673
674                 return obj;
675         },
676
677         // Use native String.trim function wherever possible
678         trim: core_trim && !core_trim.call("\uFEFF\xA0") ?
679                 function( text ) {
680                         return text == null ?
681                                 "" :
682                                 core_trim.call( text );
683                 } :
684
685                 // Otherwise use our own trimming functionality
686                 function( text ) {
687                         return text == null ?
688                                 "" :
689                                 ( text + "" ).replace( rtrim, "" );
690                 },
691
692         // results is for internal usage only
693         makeArray: function( arr, results ) {
694                 var ret = results || [];
695
696                 if ( arr != null ) {
697                         if ( isArraylike( Object(arr) ) ) {
698                                 jQuery.merge( ret,
699                                         typeof arr === "string" ?
700                                         [ arr ] : arr
701                                 );
702                         } else {
703                                 core_push.call( ret, arr );
704                         }
705                 }
706
707                 return ret;
708         },
709
710         inArray: function( elem, arr, i ) {
711                 var len;
712
713                 if ( arr ) {
714                         if ( core_indexOf ) {
715                                 return core_indexOf.call( arr, elem, i );
716                         }
717
718                         len = arr.length;
719                         i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
720
721                         for ( ; i < len; i++ ) {
722                                 // Skip accessing in sparse arrays
723                                 if ( i in arr && arr[ i ] === elem ) {
724                                         return i;
725                                 }
726                         }
727                 }
728
729                 return -1;
730         },
731
732         merge: function( first, second ) {
733                 var l = second.length,
734                         i = first.length,
735                         j = 0;
736
737                 if ( typeof l === "number" ) {
738                         for ( ; j < l; j++ ) {
739                                 first[ i++ ] = second[ j ];
740                         }
741                 } else {
742                         while ( second[j] !== undefined ) {
743                                 first[ i++ ] = second[ j++ ];
744                         }
745                 }
746
747                 first.length = i;
748
749                 return first;
750         },
751
752         grep: function( elems, callback, inv ) {
753                 var retVal,
754                         ret = [],
755                         i = 0,
756                         length = elems.length;
757                 inv = !!inv;
758
759                 // Go through the array, only saving the items
760                 // that pass the validator function
761                 for ( ; i < length; i++ ) {
762                         retVal = !!callback( elems[ i ], i );
763                         if ( inv !== retVal ) {
764                                 ret.push( elems[ i ] );
765                         }
766                 }
767
768                 return ret;
769         },
770
771         // arg is for internal usage only
772         map: function( elems, callback, arg ) {
773                 var value,
774                         i = 0,
775                         length = elems.length,
776                         isArray = isArraylike( elems ),
777                         ret = [];
778
779                 // Go through the array, translating each of the items to their
780                 if ( isArray ) {
781                         for ( ; i < length; i++ ) {
782                                 value = callback( elems[ i ], i, arg );
783
784                                 if ( value != null ) {
785                                         ret[ ret.length ] = value;
786                                 }
787                         }
788
789                 // Go through every key on the object,
790                 } else {
791                         for ( i in elems ) {
792                                 value = callback( elems[ i ], i, arg );
793
794                                 if ( value != null ) {
795                                         ret[ ret.length ] = value;
796                                 }
797                         }
798                 }
799
800                 // Flatten any nested arrays
801                 return core_concat.apply( [], ret );
802         },
803
804         // A global GUID counter for objects
805         guid: 1,
806
807         // Bind a function to a context, optionally partially applying any
808         // arguments.
809         proxy: function( fn, context ) {
810                 var args, proxy, tmp;
811
812                 if ( typeof context === "string" ) {
813                         tmp = fn[ context ];
814                         context = fn;
815                         fn = tmp;
816                 }
817
818                 // Quick check to determine if target is callable, in the spec
819                 // this throws a TypeError, but we will just return undefined.
820                 if ( !jQuery.isFunction( fn ) ) {
821                         return undefined;
822                 }
823
824                 // Simulated bind
825                 args = core_slice.call( arguments, 2 );
826                 proxy = function() {
827                         return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) );
828                 };
829
830                 // Set the guid of unique handler to the same of original handler, so it can be removed
831                 proxy.guid = fn.guid = fn.guid || jQuery.guid++;
832
833                 return proxy;
834         },
835
836         // Multifunctional method to get and set values of a collection
837         // The value/s can optionally be executed if it's a function
838         access: function( elems, fn, key, value, chainable, emptyGet, raw ) {
839                 var i = 0,
840                         length = elems.length,
841                         bulk = key == null;
842
843                 // Sets many values
844                 if ( jQuery.type( key ) === "object" ) {
845                         chainable = true;
846                         for ( i in key ) {
847                                 jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
848                         }
849
850                 // Sets one value
851                 } else if ( value !== undefined ) {
852                         chainable = true;
853
854                         if ( !jQuery.isFunction( value ) ) {
855                                 raw = true;
856                         }
857
858                         if ( bulk ) {
859                                 // Bulk operations run against the entire set
860                                 if ( raw ) {
861                                         fn.call( elems, value );
862                                         fn = null;
863
864                                 // ...except when executing function values
865                                 } else {
866                                         bulk = fn;
867                                         fn = function( elem, key, value ) {
868                                                 return bulk.call( jQuery( elem ), value );
869                                         };
870                                 }
871                         }
872
873                         if ( fn ) {
874                                 for ( ; i < length; i++ ) {
875                                         fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
876                                 }
877                         }
878                 }
879
880                 return chainable ?
881                         elems :
882
883                         // Gets
884                         bulk ?
885                                 fn.call( elems ) :
886                                 length ? fn( elems[0], key ) : emptyGet;
887         },
888
889         now: function() {
890                 return ( new Date() ).getTime();
891         },
892
893         // A method for quickly swapping in/out CSS properties to get correct calculations.
894         // Note: this method belongs to the css module but it's needed here for the support module.
895         // If support gets modularized, this method should be moved back to the css module.
896         swap: function( elem, options, callback, args ) {
897                 var ret, name,
898                         old = {};
899
900                 // Remember the old values, and insert the new ones
901                 for ( name in options ) {
902                         old[ name ] = elem.style[ name ];
903                         elem.style[ name ] = options[ name ];
904                 }
905
906                 ret = callback.apply( elem, args || [] );
907
908                 // Revert the old values
909                 for ( name in options ) {
910                         elem.style[ name ] = old[ name ];
911                 }
912
913                 return ret;
914         }
915 });
916
917 jQuery.ready.promise = function( obj ) {
918         if ( !readyList ) {
919
920                 readyList = jQuery.Deferred();
921
922                 // Catch cases where $(document).ready() is called after the browser event has already occurred.
923                 // we once tried to use readyState "interactive" here, but it caused issues like the one
924                 // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
925                 if ( document.readyState === "complete" ) {
926                         // Handle it asynchronously to allow scripts the opportunity to delay ready
927                         setTimeout( jQuery.ready );
928
929                 // Standards-based browsers support DOMContentLoaded
930                 } else if ( document.addEventListener ) {
931                         // Use the handy event callback
932                         document.addEventListener( "DOMContentLoaded", completed, false );
933
934                         // A fallback to window.onload, that will always work
935                         window.addEventListener( "load", completed, false );
936
937                 // If IE event model is used
938                 } else {
939                         // Ensure firing before onload, maybe late but safe also for iframes
940                         document.attachEvent( "onreadystatechange", completed );
941
942                         // A fallback to window.onload, that will always work
943                         window.attachEvent( "onload", completed );
944
945                         // If IE and not a frame
946                         // continually check to see if the document is ready
947                         var top = false;
948
949                         try {
950                                 top = window.frameElement == null && document.documentElement;
951                         } catch(e) {}
952
953                         if ( top && top.doScroll ) {
954                                 (function doScrollCheck() {
955                                         if ( !jQuery.isReady ) {
956
957                                                 try {
958                                                         // Use the trick by Diego Perini
959                                                         // http://javascript.nwbox.com/IEContentLoaded/
960                                                         top.doScroll("left");
961                                                 } catch(e) {
962                                                         return setTimeout( doScrollCheck, 50 );
963                                                 }
964
965                                                 // detach all dom ready events
966                                                 detach();
967
968                                                 // and execute any waiting functions
969                                                 jQuery.ready();
970                                         }
971                                 })();
972                         }
973                 }
974         }
975         return readyList.promise( obj );
976 };
977
978 // Populate the class2type map
979 jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
980         class2type[ "[object " + name + "]" ] = name.toLowerCase();
981 });
982
983 function isArraylike( obj ) {
984         var length = obj.length,
985                 type = jQuery.type( obj );
986
987         if ( jQuery.isWindow( obj ) ) {
988                 return false;
989         }
990
991         if ( obj.nodeType === 1 && length ) {
992                 return true;
993         }
994
995         return type === "array" || type !== "function" &&
996                 ( length === 0 ||
997                 typeof length === "number" && length > 0 && ( length - 1 ) in obj );
998 }
999
1000 // All jQuery objects should point back to these
1001 rootjQuery = jQuery(document);
1002 /*!
1003  * Sizzle CSS Selector Engine v1.10.2
1004  * http://sizzlejs.com/
1005  *
1006  * Copyright 2013 jQuery Foundation, Inc. and other contributors
1007  * Released under the MIT license
1008  * http://jquery.org/license
1009  *
1010  * Date: 2013-07-03
1011  */
1012 (function( window, undefined ) {
1013
1014 var i,
1015         support,
1016         cachedruns,
1017         Expr,
1018         getText,
1019         isXML,
1020         compile,
1021         outermostContext,
1022         sortInput,
1023
1024         // Local document vars
1025         setDocument,
1026         document,
1027         docElem,
1028         documentIsHTML,
1029         rbuggyQSA,
1030         rbuggyMatches,
1031         matches,
1032         contains,
1033
1034         // Instance-specific data
1035         expando = "sizzle" + -(new Date()),
1036         preferredDoc = window.document,
1037         dirruns = 0,
1038         done = 0,
1039         classCache = createCache(),
1040         tokenCache = createCache(),
1041         compilerCache = createCache(),
1042         hasDuplicate = false,
1043         sortOrder = function( a, b ) {
1044                 if ( a === b ) {
1045                         hasDuplicate = true;
1046                         return 0;
1047                 }
1048                 return 0;
1049         },
1050
1051         // General-purpose constants
1052         strundefined = typeof undefined,
1053         MAX_NEGATIVE = 1 << 31,
1054
1055         // Instance methods
1056         hasOwn = ({}).hasOwnProperty,
1057         arr = [],
1058         pop = arr.pop,
1059         push_native = arr.push,
1060         push = arr.push,
1061         slice = arr.slice,
1062         // Use a stripped-down indexOf if we can't use a native one
1063         indexOf = arr.indexOf || function( elem ) {
1064                 var i = 0,
1065                         len = this.length;
1066                 for ( ; i < len; i++ ) {
1067                         if ( this[i] === elem ) {
1068                                 return i;
1069                         }
1070                 }
1071                 return -1;
1072         },
1073
1074         booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
1075
1076         // Regular expressions
1077
1078         // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
1079         whitespace = "[\\x20\\t\\r\\n\\f]",
1080         // http://www.w3.org/TR/css3-syntax/#characters
1081         characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
1082
1083         // Loosely modeled on CSS identifier characters
1084         // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
1085         // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
1086         identifier = characterEncoding.replace( "w", "w#" ),
1087
1088         // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
1089         attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
1090                 "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
1091
1092         // Prefer arguments quoted,
1093         //   then not containing pseudos/brackets,
1094         //   then attribute selectors/non-parenthetical expressions,
1095         //   then anything else
1096         // These preferences are here to reduce the number of selectors
1097         //   needing tokenize in the PSEUDO preFilter
1098         pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)",
1099
1100         // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
1101         rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
1102
1103         rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
1104         rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
1105
1106         rsibling = new RegExp( whitespace + "*[+~]" ),
1107         rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*)" + whitespace + "*\\]", "g" ),
1108
1109         rpseudo = new RegExp( pseudos ),
1110         ridentifier = new RegExp( "^" + identifier + "$" ),
1111
1112         matchExpr = {
1113                 "ID": new RegExp( "^#(" + characterEncoding + ")" ),
1114                 "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
1115                 "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
1116                 "ATTR": new RegExp( "^" + attributes ),
1117                 "PSEUDO": new RegExp( "^" + pseudos ),
1118                 "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
1119                         "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
1120                         "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
1121                 "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
1122                 // For use in libraries implementing .is()
1123                 // We use this for POS matching in `select`
1124                 "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
1125                         whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
1126         },
1127
1128         rnative = /^[^{]+\{\s*\[native \w/,
1129
1130         // Easily-parseable/retrievable ID or TAG or CLASS selectors
1131         rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
1132
1133         rinputs = /^(?:input|select|textarea|button)$/i,
1134         rheader = /^h\d$/i,
1135
1136         rescape = /'|\\/g,
1137
1138         // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
1139         runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
1140         funescape = function( _, escaped, escapedWhitespace ) {
1141                 var high = "0x" + escaped - 0x10000;
1142                 // NaN means non-codepoint
1143                 // Support: Firefox
1144                 // Workaround erroneous numeric interpretation of +"0x"
1145                 return high !== high || escapedWhitespace ?
1146                         escaped :
1147                         // BMP codepoint
1148                         high < 0 ?
1149                                 String.fromCharCode( high + 0x10000 ) :
1150                                 // Supplemental Plane codepoint (surrogate pair)
1151                                 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
1152         };
1153
1154 // Optimize for push.apply( _, NodeList )
1155 try {
1156         push.apply(
1157                 (arr = slice.call( preferredDoc.childNodes )),
1158                 preferredDoc.childNodes
1159         );
1160         // Support: Android<4.0
1161         // Detect silently failing push.apply
1162         arr[ preferredDoc.childNodes.length ].nodeType;
1163 } catch ( e ) {
1164         push = { apply: arr.length ?
1165
1166                 // Leverage slice if possible
1167                 function( target, els ) {
1168                         push_native.apply( target, slice.call(els) );
1169                 } :
1170
1171                 // Support: IE<9
1172                 // Otherwise append directly
1173                 function( target, els ) {
1174                         var j = target.length,
1175                                 i = 0;
1176                         // Can't trust NodeList.length
1177                         while ( (target[j++] = els[i++]) ) {}
1178                         target.length = j - 1;
1179                 }
1180         };
1181 }
1182
1183 function Sizzle( selector, context, results, seed ) {
1184         var match, elem, m, nodeType,
1185                 // QSA vars
1186                 i, groups, old, nid, newContext, newSelector;
1187
1188         if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
1189                 setDocument( context );
1190         }
1191
1192         context = context || document;
1193         results = results || [];
1194
1195         if ( !selector || typeof selector !== "string" ) {
1196                 return results;
1197         }
1198
1199         if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
1200                 return [];
1201         }
1202
1203         if ( documentIsHTML && !seed ) {
1204
1205                 // Shortcuts
1206                 if ( (match = rquickExpr.exec( selector )) ) {
1207                         // Speed-up: Sizzle("#ID")
1208                         if ( (m = match[1]) ) {
1209                                 if ( nodeType === 9 ) {
1210                                         elem = context.getElementById( m );
1211                                         // Check parentNode to catch when Blackberry 4.6 returns
1212                                         // nodes that are no longer in the document #6963
1213                                         if ( elem && elem.parentNode ) {
1214                                                 // Handle the case where IE, Opera, and Webkit return items
1215                                                 // by name instead of ID
1216                                                 if ( elem.id === m ) {
1217                                                         results.push( elem );
1218                                                         return results;
1219                                                 }
1220                                         } else {
1221                                                 return results;
1222                                         }
1223                                 } else {
1224                                         // Context is not a document
1225                                         if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
1226                                                 contains( context, elem ) && elem.id === m ) {
1227                                                 results.push( elem );
1228                                                 return results;
1229                                         }
1230                                 }
1231
1232                         // Speed-up: Sizzle("TAG")
1233                         } else if ( match[2] ) {
1234                                 push.apply( results, context.getElementsByTagName( selector ) );
1235                                 return results;
1236
1237                         // Speed-up: Sizzle(".CLASS")
1238                         } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
1239                                 push.apply( results, context.getElementsByClassName( m ) );
1240                                 return results;
1241                         }
1242                 }
1243
1244                 // QSA path
1245                 if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
1246                         nid = old = expando;
1247                         newContext = context;
1248                         newSelector = nodeType === 9 && selector;
1249
1250                         // qSA works strangely on Element-rooted queries
1251                         // We can work around this by specifying an extra ID on the root
1252                         // and working up from there (Thanks to Andrew Dupont for the technique)
1253                         // IE 8 doesn't work on object elements
1254                         if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
1255                                 groups = tokenize( selector );
1256
1257                                 if ( (old = context.getAttribute("id")) ) {
1258                                         nid = old.replace( rescape, "\\$&" );
1259                                 } else {
1260                                         context.setAttribute( "id", nid );
1261                                 }
1262                                 nid = "[id='" + nid + "'] ";
1263
1264                                 i = groups.length;
1265                                 while ( i-- ) {
1266                                         groups[i] = nid + toSelector( groups[i] );
1267                                 }
1268                                 newContext = rsibling.test( selector ) && context.parentNode || context;
1269                                 newSelector = groups.join(",");
1270                         }
1271
1272                         if ( newSelector ) {
1273                                 try {
1274                                         push.apply( results,
1275                                                 newContext.querySelectorAll( newSelector )
1276                                         );
1277                                         return results;
1278                                 } catch(qsaError) {
1279                                 } finally {
1280                                         if ( !old ) {
1281                                                 context.removeAttribute("id");
1282                                         }
1283                                 }
1284                         }
1285                 }
1286         }
1287
1288         // All others
1289         return select( selector.replace( rtrim, "$1" ), context, results, seed );
1290 }
1291
1292 /**
1293  * Create key-value caches of limited size
1294  * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
1295  *      property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
1296  *      deleting the oldest entry
1297  */
1298 function createCache() {
1299         var keys = [];
1300
1301         function cache( key, value ) {
1302                 // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
1303                 if ( keys.push( key += " " ) > Expr.cacheLength ) {
1304                         // Only keep the most recent entries
1305                         delete cache[ keys.shift() ];
1306                 }
1307                 return (cache[ key ] = value);
1308         }
1309         return cache;
1310 }
1311
1312 /**
1313  * Mark a function for special use by Sizzle
1314  * @param {Function} fn The function to mark
1315  */
1316 function markFunction( fn ) {
1317         fn[ expando ] = true;
1318         return fn;
1319 }
1320
1321 /**
1322  * Support testing using an element
1323  * @param {Function} fn Passed the created div and expects a boolean result
1324  */
1325 function assert( fn ) {
1326         var div = document.createElement("div");
1327
1328         try {
1329                 return !!fn( div );
1330         } catch (e) {
1331                 return false;
1332         } finally {
1333                 // Remove from its parent by default
1334                 if ( div.parentNode ) {
1335                         div.parentNode.removeChild( div );
1336                 }
1337                 // release memory in IE
1338                 div = null;
1339         }
1340 }
1341
1342 /**
1343  * Adds the same handler for all of the specified attrs
1344  * @param {String} attrs Pipe-separated list of attributes
1345  * @param {Function} handler The method that will be applied
1346  */
1347 function addHandle( attrs, handler ) {
1348         var arr = attrs.split("|"),
1349                 i = attrs.length;
1350
1351         while ( i-- ) {
1352                 Expr.attrHandle[ arr[i] ] = handler;
1353         }
1354 }
1355
1356 /**
1357  * Checks document order of two siblings
1358  * @param {Element} a
1359  * @param {Element} b
1360  * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
1361  */
1362 function siblingCheck( a, b ) {
1363         var cur = b && a,
1364                 diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
1365                         ( ~b.sourceIndex || MAX_NEGATIVE ) -
1366                         ( ~a.sourceIndex || MAX_NEGATIVE );
1367
1368         // Use IE sourceIndex if available on both nodes
1369         if ( diff ) {
1370                 return diff;
1371         }
1372
1373         // Check if b follows a
1374         if ( cur ) {
1375                 while ( (cur = cur.nextSibling) ) {
1376                         if ( cur === b ) {
1377                                 return -1;
1378                         }
1379                 }
1380         }
1381
1382         return a ? 1 : -1;
1383 }
1384
1385 /**
1386  * Returns a function to use in pseudos for input types
1387  * @param {String} type
1388  */
1389 function createInputPseudo( type ) {
1390         return function( elem ) {
1391                 var name = elem.nodeName.toLowerCase();
1392                 return name === "input" && elem.type === type;
1393         };
1394 }
1395
1396 /**
1397  * Returns a function to use in pseudos for buttons
1398  * @param {String} type
1399  */
1400 function createButtonPseudo( type ) {
1401         return function( elem ) {
1402                 var name = elem.nodeName.toLowerCase();
1403                 return (name === "input" || name === "button") && elem.type === type;
1404         };
1405 }
1406
1407 /**
1408  * Returns a function to use in pseudos for positionals
1409  * @param {Function} fn
1410  */
1411 function createPositionalPseudo( fn ) {
1412         return markFunction(function( argument ) {
1413                 argument = +argument;
1414                 return markFunction(function( seed, matches ) {
1415                         var j,
1416                                 matchIndexes = fn( [], seed.length, argument ),
1417                                 i = matchIndexes.length;
1418
1419                         // Match elements found at the specified indexes
1420                         while ( i-- ) {
1421                                 if ( seed[ (j = matchIndexes[i]) ] ) {
1422                                         seed[j] = !(matches[j] = seed[j]);
1423                                 }
1424                         }
1425                 });
1426         });
1427 }
1428
1429 /**
1430  * Detect xml
1431  * @param {Element|Object} elem An element or a document
1432  */
1433 isXML = Sizzle.isXML = function( elem ) {
1434         // documentElement is verified for cases where it doesn't yet exist
1435         // (such as loading iframes in IE - #4833)
1436         var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1437         return documentElement ? documentElement.nodeName !== "HTML" : false;
1438 };
1439
1440 // Expose support vars for convenience
1441 support = Sizzle.support = {};
1442
1443 /**
1444  * Sets document-related variables once based on the current document
1445  * @param {Element|Object} [doc] An element or document object to use to set the document
1446  * @returns {Object} Returns the current document
1447  */
1448 setDocument = Sizzle.setDocument = function( node ) {
1449         var doc = node ? node.ownerDocument || node : preferredDoc,
1450                 parent = doc.defaultView;
1451
1452         // If no document and documentElement is available, return
1453         if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
1454                 return document;
1455         }
1456
1457         // Set our document
1458         document = doc;
1459         docElem = doc.documentElement;
1460
1461         // Support tests
1462         documentIsHTML = !isXML( doc );
1463
1464         // Support: IE>8
1465         // If iframe document is assigned to "document" variable and if iframe has been reloaded,
1466         // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
1467         // IE6-8 do not support the defaultView property so parent will be undefined
1468         if ( parent && parent.attachEvent && parent !== parent.top ) {
1469                 parent.attachEvent( "onbeforeunload", function() {
1470                         setDocument();
1471                 });
1472         }
1473
1474         /* Attributes
1475         ---------------------------------------------------------------------- */
1476
1477         // Support: IE<8
1478         // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
1479         support.attributes = assert(function( div ) {
1480                 div.className = "i";
1481                 return !div.getAttribute("className");
1482         });
1483
1484         /* getElement(s)By*
1485         ---------------------------------------------------------------------- */
1486
1487         // Check if getElementsByTagName("*") returns only elements
1488         support.getElementsByTagName = assert(function( div ) {
1489                 div.appendChild( doc.createComment("") );
1490                 return !div.getElementsByTagName("*").length;
1491         });
1492
1493         // Check if getElementsByClassName can be trusted
1494         support.getElementsByClassName = assert(function( div ) {
1495                 div.innerHTML = "<div class='a'></div><div class='a i'></div>";
1496
1497                 // Support: Safari<4
1498                 // Catch class over-caching
1499                 div.firstChild.className = "i";
1500                 // Support: Opera<10
1501                 // Catch gEBCN failure to find non-leading classes
1502                 return div.getElementsByClassName("i").length === 2;
1503         });
1504
1505         // Support: IE<10
1506         // Check if getElementById returns elements by name
1507         // The broken getElementById methods don't pick up programatically-set names,
1508         // so use a roundabout getElementsByName test
1509         support.getById = assert(function( div ) {
1510                 docElem.appendChild( div ).id = expando;
1511                 return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
1512         });
1513
1514         // ID find and filter
1515         if ( support.getById ) {
1516                 Expr.find["ID"] = function( id, context ) {
1517                         if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
1518                                 var m = context.getElementById( id );
1519                                 // Check parentNode to catch when Blackberry 4.6 returns
1520                                 // nodes that are no longer in the document #6963
1521                                 return m && m.parentNode ? [m] : [];
1522                         }
1523                 };
1524                 Expr.filter["ID"] = function( id ) {
1525                         var attrId = id.replace( runescape, funescape );
1526                         return function( elem ) {
1527                                 return elem.getAttribute("id") === attrId;
1528                         };
1529                 };
1530         } else {
1531                 // Support: IE6/7
1532                 // getElementById is not reliable as a find shortcut
1533                 delete Expr.find["ID"];
1534
1535                 Expr.filter["ID"] =  function( id ) {
1536                         var attrId = id.replace( runescape, funescape );
1537                         return function( elem ) {
1538                                 var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
1539                                 return node && node.value === attrId;
1540                         };
1541                 };
1542         }
1543
1544         // Tag
1545         Expr.find["TAG"] = support.getElementsByTagName ?
1546                 function( tag, context ) {
1547                         if ( typeof context.getElementsByTagName !== strundefined ) {
1548                                 return context.getElementsByTagName( tag );
1549                         }
1550                 } :
1551                 function( tag, context ) {
1552                         var elem,
1553                                 tmp = [],
1554                                 i = 0,
1555                                 results = context.getElementsByTagName( tag );
1556
1557                         // Filter out possible comments
1558                         if ( tag === "*" ) {
1559                                 while ( (elem = results[i++]) ) {
1560                                         if ( elem.nodeType === 1 ) {
1561                                                 tmp.push( elem );
1562                                         }
1563                                 }
1564
1565                                 return tmp;
1566                         }
1567                         return results;
1568                 };
1569
1570         // Class
1571         Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
1572                 if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
1573                         return context.getElementsByClassName( className );
1574                 }
1575         };
1576
1577         /* QSA/matchesSelector
1578         ---------------------------------------------------------------------- */
1579
1580         // QSA and matchesSelector support
1581
1582         // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1583         rbuggyMatches = [];
1584
1585         // qSa(:focus) reports false when true (Chrome 21)
1586         // We allow this because of a bug in IE8/9 that throws an error
1587         // whenever `document.activeElement` is accessed on an iframe
1588         // So, we allow :focus to pass through QSA all the time to avoid the IE error
1589         // See http://bugs.jquery.com/ticket/13378
1590         rbuggyQSA = [];
1591
1592         if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
1593                 // Build QSA regex
1594                 // Regex strategy adopted from Diego Perini
1595                 assert(function( div ) {
1596                         // Select is set to empty string on purpose
1597                         // This is to test IE's treatment of not explicitly
1598                         // setting a boolean content attribute,
1599                         // since its presence should be enough
1600                         // http://bugs.jquery.com/ticket/12359
1601                         div.innerHTML = "<select><option selected=''></option></select>";
1602
1603                         // Support: IE8
1604                         // Boolean attributes and "value" are not treated correctly
1605                         if ( !div.querySelectorAll("[selected]").length ) {
1606                                 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1607                         }
1608
1609                         // Webkit/Opera - :checked should return selected option elements
1610                         // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1611                         // IE8 throws error here and will not see later tests
1612                         if ( !div.querySelectorAll(":checked").length ) {
1613                                 rbuggyQSA.push(":checked");
1614                         }
1615                 });
1616
1617                 assert(function( div ) {
1618
1619                         // Support: Opera 10-12/IE8
1620                         // ^= $= *= and empty values
1621                         // Should not select anything
1622                         // Support: Windows 8 Native Apps
1623                         // The type attribute is restricted during .innerHTML assignment
1624                         var input = doc.createElement("input");
1625                         input.setAttribute( "type", "hidden" );
1626                         div.appendChild( input ).setAttribute( "t", "" );
1627
1628                         if ( div.querySelectorAll("[t^='']").length ) {
1629                                 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1630                         }
1631
1632                         // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1633                         // IE8 throws error here and will not see later tests
1634                         if ( !div.querySelectorAll(":enabled").length ) {
1635                                 rbuggyQSA.push( ":enabled", ":disabled" );
1636                         }
1637
1638                         // Opera 10-11 does not throw on post-comma invalid pseudos
1639                         div.querySelectorAll("*,:x");
1640                         rbuggyQSA.push(",.*:");
1641                 });
1642         }
1643
1644         if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector ||
1645                 docElem.mozMatchesSelector ||
1646                 docElem.oMatchesSelector ||
1647                 docElem.msMatchesSelector) )) ) {
1648
1649                 assert(function( div ) {
1650                         // Check to see if it's possible to do matchesSelector
1651                         // on a disconnected node (IE 9)
1652                         support.disconnectedMatch = matches.call( div, "div" );
1653
1654                         // This should fail with an exception
1655                         // Gecko does not error, returns false instead
1656                         matches.call( div, "[s!='']:x" );
1657                         rbuggyMatches.push( "!=", pseudos );
1658                 });
1659         }
1660
1661         rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
1662         rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
1663
1664         /* Contains
1665         ---------------------------------------------------------------------- */
1666
1667         // Element contains another
1668         // Purposefully does not implement inclusive descendent
1669         // As in, an element does not contain itself
1670         contains = rnative.test( docElem.contains ) || docElem.compareDocumentPosition ?
1671                 function( a, b ) {
1672                         var adown = a.nodeType === 9 ? a.documentElement : a,
1673                                 bup = b && b.parentNode;
1674                         return a === bup || !!( bup && bup.nodeType === 1 && (
1675                                 adown.contains ?
1676                                         adown.contains( bup ) :
1677                                         a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1678                         ));
1679                 } :
1680                 function( a, b ) {
1681                         if ( b ) {
1682                                 while ( (b = b.parentNode) ) {
1683                                         if ( b === a ) {
1684                                                 return true;
1685                                         }
1686                                 }
1687                         }
1688                         return false;
1689                 };
1690
1691         /* Sorting
1692         ---------------------------------------------------------------------- */
1693
1694         // Document order sorting
1695         sortOrder = docElem.compareDocumentPosition ?
1696         function( a, b ) {
1697
1698                 // Flag for duplicate removal
1699                 if ( a === b ) {
1700                         hasDuplicate = true;
1701                         return 0;
1702                 }
1703
1704                 var compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b );
1705
1706                 if ( compare ) {
1707                         // Disconnected nodes
1708                         if ( compare & 1 ||
1709                                 (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
1710
1711                                 // Choose the first element that is related to our preferred document
1712                                 if ( a === doc || contains(preferredDoc, a) ) {
1713                                         return -1;
1714                                 }
1715                                 if ( b === doc || contains(preferredDoc, b) ) {
1716                                         return 1;
1717                                 }
1718
1719                                 // Maintain original order
1720                                 return sortInput ?
1721                                         ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
1722                                         0;
1723                         }
1724
1725                         return compare & 4 ? -1 : 1;
1726                 }
1727
1728                 // Not directly comparable, sort on existence of method
1729                 return a.compareDocumentPosition ? -1 : 1;
1730         } :
1731         function( a, b ) {
1732                 var cur,
1733                         i = 0,
1734                         aup = a.parentNode,
1735                         bup = b.parentNode,
1736                         ap = [ a ],
1737                         bp = [ b ];
1738
1739                 // Exit early if the nodes are identical
1740                 if ( a === b ) {
1741                         hasDuplicate = true;
1742                         return 0;
1743
1744                 // Parentless nodes are either documents or disconnected
1745                 } else if ( !aup || !bup ) {
1746                         return a === doc ? -1 :
1747                                 b === doc ? 1 :
1748                                 aup ? -1 :
1749                                 bup ? 1 :
1750                                 sortInput ?
1751                                 ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
1752                                 0;
1753
1754                 // If the nodes are siblings, we can do a quick check
1755                 } else if ( aup === bup ) {
1756                         return siblingCheck( a, b );
1757                 }
1758
1759                 // Otherwise we need full lists of their ancestors for comparison
1760                 cur = a;
1761                 while ( (cur = cur.parentNode) ) {
1762                         ap.unshift( cur );
1763                 }
1764                 cur = b;
1765                 while ( (cur = cur.parentNode) ) {
1766                         bp.unshift( cur );
1767                 }
1768
1769                 // Walk down the tree looking for a discrepancy
1770                 while ( ap[i] === bp[i] ) {
1771                         i++;
1772                 }
1773
1774                 return i ?
1775                         // Do a sibling check if the nodes have a common ancestor
1776                         siblingCheck( ap[i], bp[i] ) :
1777
1778                         // Otherwise nodes in our document sort first
1779                         ap[i] === preferredDoc ? -1 :
1780                         bp[i] === preferredDoc ? 1 :
1781                         0;
1782         };
1783
1784         return doc;
1785 };
1786
1787 Sizzle.matches = function( expr, elements ) {
1788         return Sizzle( expr, null, null, elements );
1789 };
1790
1791 Sizzle.matchesSelector = function( elem, expr ) {
1792         // Set document vars if needed
1793         if ( ( elem.ownerDocument || elem ) !== document ) {
1794                 setDocument( elem );
1795         }
1796
1797         // Make sure that attribute selectors are quoted
1798         expr = expr.replace( rattributeQuotes, "='$1']" );
1799
1800         if ( support.matchesSelector && documentIsHTML &&
1801                 ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1802                 ( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
1803
1804                 try {
1805                         var ret = matches.call( elem, expr );
1806
1807                         // IE 9's matchesSelector returns false on disconnected nodes
1808                         if ( ret || support.disconnectedMatch ||
1809                                         // As well, disconnected nodes are said to be in a document
1810                                         // fragment in IE 9
1811                                         elem.document && elem.document.nodeType !== 11 ) {
1812                                 return ret;
1813                         }
1814                 } catch(e) {}
1815         }
1816
1817         return Sizzle( expr, document, null, [elem] ).length > 0;
1818 };
1819
1820 Sizzle.contains = function( context, elem ) {
1821         // Set document vars if needed
1822         if ( ( context.ownerDocument || context ) !== document ) {
1823                 setDocument( context );
1824         }
1825         return contains( context, elem );
1826 };
1827
1828 Sizzle.attr = function( elem, name ) {
1829         // Set document vars if needed
1830         if ( ( elem.ownerDocument || elem ) !== document ) {
1831                 setDocument( elem );
1832         }
1833
1834         var fn = Expr.attrHandle[ name.toLowerCase() ],
1835                 // Don't get fooled by Object.prototype properties (jQuery #13807)
1836                 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1837                         fn( elem, name, !documentIsHTML ) :
1838                         undefined;
1839
1840         return val === undefined ?
1841                 support.attributes || !documentIsHTML ?
1842                         elem.getAttribute( name ) :
1843                         (val = elem.getAttributeNode(name)) && val.specified ?
1844                                 val.value :
1845                                 null :
1846                 val;
1847 };
1848
1849 Sizzle.error = function( msg ) {
1850         throw new Error( "Syntax error, unrecognized expression: " + msg );
1851 };
1852
1853 /**
1854  * Document sorting and removing duplicates
1855  * @param {ArrayLike} results
1856  */
1857 Sizzle.uniqueSort = function( results ) {
1858         var elem,
1859                 duplicates = [],
1860                 j = 0,
1861                 i = 0;
1862
1863         // Unless we *know* we can detect duplicates, assume their presence
1864         hasDuplicate = !support.detectDuplicates;
1865         sortInput = !support.sortStable && results.slice( 0 );
1866         results.sort( sortOrder );
1867
1868         if ( hasDuplicate ) {
1869                 while ( (elem = results[i++]) ) {
1870                         if ( elem === results[ i ] ) {
1871                                 j = duplicates.push( i );
1872                         }
1873                 }
1874                 while ( j-- ) {
1875                         results.splice( duplicates[ j ], 1 );
1876                 }
1877         }
1878
1879         return results;
1880 };
1881
1882 /**
1883  * Utility function for retrieving the text value of an array of DOM nodes
1884  * @param {Array|Element} elem
1885  */
1886 getText = Sizzle.getText = function( elem ) {
1887         var node,
1888                 ret = "",
1889                 i = 0,
1890                 nodeType = elem.nodeType;
1891
1892         if ( !nodeType ) {
1893                 // If no nodeType, this is expected to be an array
1894                 for ( ; (node = elem[i]); i++ ) {
1895                         // Do not traverse comment nodes
1896                         ret += getText( node );
1897                 }
1898         } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1899                 // Use textContent for elements
1900                 // innerText usage removed for consistency of new lines (see #11153)
1901                 if ( typeof elem.textContent === "string" ) {
1902                         return elem.textContent;
1903                 } else {
1904                         // Traverse its children
1905                         for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1906                                 ret += getText( elem );
1907                         }
1908                 }
1909         } else if ( nodeType === 3 || nodeType === 4 ) {
1910                 return elem.nodeValue;
1911         }
1912         // Do not include comment or processing instruction nodes
1913
1914         return ret;
1915 };
1916
1917 Expr = Sizzle.selectors = {
1918
1919         // Can be adjusted by the user
1920         cacheLength: 50,
1921
1922         createPseudo: markFunction,
1923
1924         match: matchExpr,
1925
1926         attrHandle: {},
1927
1928         find: {},
1929
1930         relative: {
1931                 ">": { dir: "parentNode", first: true },
1932                 " ": { dir: "parentNode" },
1933                 "+": { dir: "previousSibling", first: true },
1934                 "~": { dir: "previousSibling" }
1935         },
1936
1937         preFilter: {
1938                 "ATTR": function( match ) {
1939                         match[1] = match[1].replace( runescape, funescape );
1940
1941                         // Move the given value to match[3] whether quoted or unquoted
1942                         match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape );
1943
1944                         if ( match[2] === "~=" ) {
1945                                 match[3] = " " + match[3] + " ";
1946                         }
1947
1948                         return match.slice( 0, 4 );
1949                 },
1950
1951                 "CHILD": function( match ) {
1952                         /* matches from matchExpr["CHILD"]
1953                                 1 type (only|nth|...)
1954                                 2 what (child|of-type)
1955                                 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1956                                 4 xn-component of xn+y argument ([+-]?\d*n|)
1957                                 5 sign of xn-component
1958                                 6 x of xn-component
1959                                 7 sign of y-component
1960                                 8 y of y-component
1961                         */
1962                         match[1] = match[1].toLowerCase();
1963
1964                         if ( match[1].slice( 0, 3 ) === "nth" ) {
1965                                 // nth-* requires argument
1966                                 if ( !match[3] ) {
1967                                         Sizzle.error( match[0] );
1968                                 }
1969
1970                                 // numeric x and y parameters for Expr.filter.CHILD
1971                                 // remember that false/true cast respectively to 0/1
1972                                 match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
1973                                 match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
1974
1975                         // other types prohibit arguments
1976                         } else if ( match[3] ) {
1977                                 Sizzle.error( match[0] );
1978                         }
1979
1980                         return match;
1981                 },
1982
1983                 "PSEUDO": function( match ) {
1984                         var excess,
1985                                 unquoted = !match[5] && match[2];
1986
1987                         if ( matchExpr["CHILD"].test( match[0] ) ) {
1988                                 return null;
1989                         }
1990
1991                         // Accept quoted arguments as-is
1992                         if ( match[3] && match[4] !== undefined ) {
1993                                 match[2] = match[4];
1994
1995                         // Strip excess characters from unquoted arguments
1996                         } else if ( unquoted && rpseudo.test( unquoted ) &&
1997                                 // Get excess from tokenize (recursively)
1998                                 (excess = tokenize( unquoted, true )) &&
1999                                 // advance to the next closing parenthesis
2000                                 (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
2001
2002                                 // excess is a negative index
2003                                 match[0] = match[0].slice( 0, excess );
2004                                 match[2] = unquoted.slice( 0, excess );
2005                         }
2006
2007                         // Return only captures needed by the pseudo filter method (type and argument)
2008                         return match.slice( 0, 3 );
2009                 }
2010         },
2011
2012         filter: {
2013
2014                 "TAG": function( nodeNameSelector ) {
2015                         var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
2016                         return nodeNameSelector === "*" ?
2017                                 function() { return true; } :
2018                                 function( elem ) {
2019                                         return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
2020                                 };
2021                 },
2022
2023                 "CLASS": function( className ) {
2024                         var pattern = classCache[ className + " " ];
2025
2026                         return pattern ||
2027                                 (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
2028                                 classCache( className, function( elem ) {
2029                                         return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
2030                                 });
2031                 },
2032
2033                 "ATTR": function( name, operator, check ) {
2034                         return function( elem ) {
2035                                 var result = Sizzle.attr( elem, name );
2036
2037                                 if ( result == null ) {
2038                                         return operator === "!=";
2039                                 }
2040                                 if ( !operator ) {
2041                                         return true;
2042                                 }
2043
2044                                 result += "";
2045
2046                                 return operator === "=" ? result === check :
2047                                         operator === "!=" ? result !== check :
2048                                         operator === "^=" ? check && result.indexOf( check ) === 0 :
2049                                         operator === "*=" ? check && result.indexOf( check ) > -1 :
2050                                         operator === "$=" ? check && result.slice( -check.length ) === check :
2051                                         operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
2052                                         operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
2053                                         false;
2054                         };
2055                 },
2056
2057                 "CHILD": function( type, what, argument, first, last ) {
2058                         var simple = type.slice( 0, 3 ) !== "nth",
2059                                 forward = type.slice( -4 ) !== "last",
2060                                 ofType = what === "of-type";
2061
2062                         return first === 1 && last === 0 ?
2063
2064                                 // Shortcut for :nth-*(n)
2065                                 function( elem ) {
2066                                         return !!elem.parentNode;
2067                                 } :
2068
2069                                 function( elem, context, xml ) {
2070                                         var cache, outerCache, node, diff, nodeIndex, start,
2071                                                 dir = simple !== forward ? "nextSibling" : "previousSibling",
2072                                                 parent = elem.parentNode,
2073                                                 name = ofType && elem.nodeName.toLowerCase(),
2074                                                 useCache = !xml && !ofType;
2075
2076                                         if ( parent ) {
2077
2078                                                 // :(first|last|only)-(child|of-type)
2079                                                 if ( simple ) {
2080                                                         while ( dir ) {
2081                                                                 node = elem;
2082                                                                 while ( (node = node[ dir ]) ) {
2083                                                                         if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
2084                                                                                 return false;
2085                                                                         }
2086                                                                 }
2087                                                                 // Reverse direction for :only-* (if we haven't yet done so)
2088                                                                 start = dir = type === "only" && !start && "nextSibling";
2089                                                         }
2090                                                         return true;
2091                                                 }
2092
2093                                                 start = [ forward ? parent.firstChild : parent.lastChild ];
2094
2095                                                 // non-xml :nth-child(...) stores cache data on `parent`
2096                                                 if ( forward && useCache ) {
2097                                                         // Seek `elem` from a previously-cached index
2098                                                         outerCache = parent[ expando ] || (parent[ expando ] = {});
2099                                                         cache = outerCache[ type ] || [];
2100                                                         nodeIndex = cache[0] === dirruns && cache[1];
2101                                                         diff = cache[0] === dirruns && cache[2];
2102                                                         node = nodeIndex && parent.childNodes[ nodeIndex ];
2103
2104                                                         while ( (node = ++nodeIndex && node && node[ dir ] ||
2105
2106                                                                 // Fallback to seeking `elem` from the start
2107                                                                 (diff = nodeIndex = 0) || start.pop()) ) {
2108
2109                                                                 // When found, cache indexes on `parent` and break
2110                                                                 if ( node.nodeType === 1 && ++diff && node === elem ) {
2111                                                                         outerCache[ type ] = [ dirruns, nodeIndex, diff ];
2112                                                                         break;
2113                                                                 }
2114                                                         }
2115
2116                                                 // Use previously-cached element index if available
2117                                                 } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
2118                                                         diff = cache[1];
2119
2120                                                 // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
2121                                                 } else {
2122                                                         // Use the same loop as above to seek `elem` from the start
2123                                                         while ( (node = ++nodeIndex && node && node[ dir ] ||
2124                                                                 (diff = nodeIndex = 0) || start.pop()) ) {
2125
2126                                                                 if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
2127                                                                         // Cache the index of each encountered element
2128                                                                         if ( useCache ) {
2129                                                                                 (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
2130                                                                         }
2131
2132                                                                         if ( node === elem ) {
2133                                                                                 break;
2134                                                                         }
2135                                                                 }
2136                                                         }
2137                                                 }
2138
2139                                                 // Incorporate the offset, then check against cycle size
2140                                                 diff -= last;
2141                                                 return diff === first || ( diff % first === 0 && diff / first >= 0 );
2142                                         }
2143                                 };
2144                 },
2145
2146                 "PSEUDO": function( pseudo, argument ) {
2147                         // pseudo-class names are case-insensitive
2148                         // http://www.w3.org/TR/selectors/#pseudo-classes
2149                         // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
2150                         // Remember that setFilters inherits from pseudos
2151                         var args,
2152                                 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
2153                                         Sizzle.error( "unsupported pseudo: " + pseudo );
2154
2155                         // The user may use createPseudo to indicate that
2156                         // arguments are needed to create the filter function
2157                         // just as Sizzle does
2158                         if ( fn[ expando ] ) {
2159                                 return fn( argument );
2160                         }
2161
2162                         // But maintain support for old signatures
2163                         if ( fn.length > 1 ) {
2164                                 args = [ pseudo, pseudo, "", argument ];
2165                                 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
2166                                         markFunction(function( seed, matches ) {
2167                                                 var idx,
2168                                                         matched = fn( seed, argument ),
2169                                                         i = matched.length;
2170                                                 while ( i-- ) {
2171                                                         idx = indexOf.call( seed, matched[i] );
2172                                                         seed[ idx ] = !( matches[ idx ] = matched[i] );
2173                                                 }
2174                                         }) :
2175                                         function( elem ) {
2176                                                 return fn( elem, 0, args );
2177                                         };
2178                         }
2179
2180                         return fn;
2181                 }
2182         },
2183
2184         pseudos: {
2185                 // Potentially complex pseudos
2186                 "not": markFunction(function( selector ) {
2187                         // Trim the selector passed to compile
2188                         // to avoid treating leading and trailing
2189                         // spaces as combinators
2190                         var input = [],
2191                                 results = [],
2192                                 matcher = compile( selector.replace( rtrim, "$1" ) );
2193
2194                         return matcher[ expando ] ?
2195                                 markFunction(function( seed, matches, context, xml ) {
2196                                         var elem,
2197                                                 unmatched = matcher( seed, null, xml, [] ),
2198                                                 i = seed.length;
2199
2200                                         // Match elements unmatched by `matcher`
2201                                         while ( i-- ) {
2202                                                 if ( (elem = unmatched[i]) ) {
2203                                                         seed[i] = !(matches[i] = elem);
2204                                                 }
2205                                         }
2206                                 }) :
2207                                 function( elem, context, xml ) {
2208                                         input[0] = elem;
2209                                         matcher( input, null, xml, results );
2210                                         return !results.pop();
2211                                 };
2212                 }),
2213
2214                 "has": markFunction(function( selector ) {
2215                         return function( elem ) {
2216                                 return Sizzle( selector, elem ).length > 0;
2217                         };
2218                 }),
2219
2220                 "contains": markFunction(function( text ) {
2221                         return function( elem ) {
2222                                 return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
2223                         };
2224                 }),
2225
2226                 // "Whether an element is represented by a :lang() selector
2227                 // is based solely on the element's language value
2228                 // being equal to the identifier C,
2229                 // or beginning with the identifier C immediately followed by "-".
2230                 // The matching of C against the element's language value is performed case-insensitively.
2231                 // The identifier C does not have to be a valid language name."
2232                 // http://www.w3.org/TR/selectors/#lang-pseudo
2233                 "lang": markFunction( function( lang ) {
2234                         // lang value must be a valid identifier
2235                         if ( !ridentifier.test(lang || "") ) {
2236                                 Sizzle.error( "unsupported lang: " + lang );
2237                         }
2238                         lang = lang.replace( runescape, funescape ).toLowerCase();
2239                         return function( elem ) {
2240                                 var elemLang;
2241                                 do {
2242                                         if ( (elemLang = documentIsHTML ?
2243                                                 elem.lang :
2244                                                 elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
2245
2246                                                 elemLang = elemLang.toLowerCase();
2247                                                 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
2248                                         }
2249                                 } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
2250                                 return false;
2251                         };
2252                 }),
2253
2254                 // Miscellaneous
2255                 "target": function( elem ) {
2256                         var hash = window.location && window.location.hash;
2257                         return hash && hash.slice( 1 ) === elem.id;
2258                 },
2259
2260                 "root": function( elem ) {
2261                         return elem === docElem;
2262                 },
2263
2264                 "focus": function( elem ) {
2265                         return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
2266                 },
2267
2268                 // Boolean properties
2269                 "enabled": function( elem ) {
2270                         return elem.disabled === false;
2271                 },
2272
2273                 "disabled": function( elem ) {
2274                         return elem.disabled === true;
2275                 },
2276
2277                 "checked": function( elem ) {
2278                         // In CSS3, :checked should return both checked and selected elements
2279                         // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
2280                         var nodeName = elem.nodeName.toLowerCase();
2281                         return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
2282                 },
2283
2284                 "selected": function( elem ) {
2285                         // Accessing this property makes selected-by-default
2286                         // options in Safari work properly
2287                         if ( elem.parentNode ) {
2288                                 elem.parentNode.selectedIndex;
2289                         }
2290
2291                         return elem.selected === true;
2292                 },
2293
2294                 // Contents
2295                 "empty": function( elem ) {
2296                         // http://www.w3.org/TR/selectors/#empty-pseudo
2297                         // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),
2298                         //   not comment, processing instructions, or others
2299                         // Thanks to Diego Perini for the nodeName shortcut
2300                         //   Greater than "@" means alpha characters (specifically not starting with "#" or "?")
2301                         for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
2302                                 if ( elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4 ) {
2303                                         return false;
2304                                 }
2305                         }
2306                         return true;
2307                 },
2308
2309                 "parent": function( elem ) {
2310                         return !Expr.pseudos["empty"]( elem );
2311                 },
2312
2313                 // Element/input types
2314                 "header": function( elem ) {
2315                         return rheader.test( elem.nodeName );
2316                 },
2317
2318                 "input": function( elem ) {
2319                         return rinputs.test( elem.nodeName );
2320                 },
2321
2322                 "button": function( elem ) {
2323                         var name = elem.nodeName.toLowerCase();
2324                         return name === "input" && elem.type === "button" || name === "button";
2325                 },
2326
2327                 "text": function( elem ) {
2328                         var attr;
2329                         // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
2330                         // use getAttribute instead to test this case
2331                         return elem.nodeName.toLowerCase() === "input" &&
2332                                 elem.type === "text" &&
2333                                 ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type );
2334                 },
2335
2336                 // Position-in-collection
2337                 "first": createPositionalPseudo(function() {
2338                         return [ 0 ];
2339                 }),
2340
2341                 "last": createPositionalPseudo(function( matchIndexes, length ) {
2342                         return [ length - 1 ];
2343                 }),
2344
2345                 "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
2346                         return [ argument < 0 ? argument + length : argument ];
2347                 }),
2348
2349                 "even": createPositionalPseudo(function( matchIndexes, length ) {
2350                         var i = 0;
2351                         for ( ; i < length; i += 2 ) {
2352                                 matchIndexes.push( i );
2353                         }
2354                         return matchIndexes;
2355                 }),
2356
2357                 "odd": createPositionalPseudo(function( matchIndexes, length ) {
2358                         var i = 1;
2359                         for ( ; i < length; i += 2 ) {
2360                                 matchIndexes.push( i );
2361                         }
2362                         return matchIndexes;
2363                 }),
2364
2365                 "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2366                         var i = argument < 0 ? argument + length : argument;
2367                         for ( ; --i >= 0; ) {
2368                                 matchIndexes.push( i );
2369                         }
2370                         return matchIndexes;
2371                 }),
2372
2373                 "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2374                         var i = argument < 0 ? argument + length : argument;
2375                         for ( ; ++i < length; ) {
2376                                 matchIndexes.push( i );
2377                         }
2378                         return matchIndexes;
2379                 })
2380         }
2381 };
2382
2383 Expr.pseudos["nth"] = Expr.pseudos["eq"];
2384
2385 // Add button/input type pseudos
2386 for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2387         Expr.pseudos[ i ] = createInputPseudo( i );
2388 }
2389 for ( i in { submit: true, reset: true } ) {
2390         Expr.pseudos[ i ] = createButtonPseudo( i );
2391 }
2392
2393 // Easy API for creating new setFilters
2394 function setFilters() {}
2395 setFilters.prototype = Expr.filters = Expr.pseudos;
2396 Expr.setFilters = new setFilters();
2397
2398 function tokenize( selector, parseOnly ) {
2399         var matched, match, tokens, type,
2400                 soFar, groups, preFilters,
2401                 cached = tokenCache[ selector + " " ];
2402
2403         if ( cached ) {
2404                 return parseOnly ? 0 : cached.slice( 0 );
2405         }
2406
2407         soFar = selector;
2408         groups = [];
2409         preFilters = Expr.preFilter;
2410
2411         while ( soFar ) {
2412
2413                 // Comma and first run
2414                 if ( !matched || (match = rcomma.exec( soFar )) ) {
2415                         if ( match ) {
2416                                 // Don't consume trailing commas as valid
2417                                 soFar = soFar.slice( match[0].length ) || soFar;
2418                         }
2419                         groups.push( tokens = [] );
2420                 }
2421
2422                 matched = false;
2423
2424                 // Combinators
2425                 if ( (match = rcombinators.exec( soFar )) ) {
2426                         matched = match.shift();
2427                         tokens.push({
2428                                 value: matched,
2429                                 // Cast descendant combinators to space
2430                                 type: match[0].replace( rtrim, " " )
2431                         });
2432                         soFar = soFar.slice( matched.length );
2433                 }
2434
2435                 // Filters
2436                 for ( type in Expr.filter ) {
2437                         if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
2438                                 (match = preFilters[ type ]( match ))) ) {
2439                                 matched = match.shift();
2440                                 tokens.push({
2441                                         value: matched,
2442                                         type: type,
2443                                         matches: match
2444                                 });
2445                                 soFar = soFar.slice( matched.length );
2446                         }
2447                 }
2448
2449                 if ( !matched ) {
2450                         break;
2451                 }
2452         }
2453
2454         // Return the length of the invalid excess
2455         // if we're just parsing
2456         // Otherwise, throw an error or return tokens
2457         return parseOnly ?
2458                 soFar.length :
2459                 soFar ?
2460                         Sizzle.error( selector ) :
2461                         // Cache the tokens
2462                         tokenCache( selector, groups ).slice( 0 );
2463 }
2464
2465 function toSelector( tokens ) {
2466         var i = 0,
2467                 len = tokens.length,
2468                 selector = "";
2469         for ( ; i < len; i++ ) {
2470                 selector += tokens[i].value;
2471         }
2472         return selector;
2473 }
2474
2475 function addCombinator( matcher, combinator, base ) {
2476         var dir = combinator.dir,
2477                 checkNonElements = base && dir === "parentNode",
2478                 doneName = done++;
2479
2480         return combinator.first ?
2481                 // Check against closest ancestor/preceding element
2482                 function( elem, context, xml ) {
2483                         while ( (elem = elem[ dir ]) ) {
2484                                 if ( elem.nodeType === 1 || checkNonElements ) {
2485                                         return matcher( elem, context, xml );
2486                                 }
2487                         }
2488                 } :
2489
2490                 // Check against all ancestor/preceding elements
2491                 function( elem, context, xml ) {
2492                         var data, cache, outerCache,
2493                                 dirkey = dirruns + " " + doneName;
2494
2495                         // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
2496                         if ( xml ) {
2497                                 while ( (elem = elem[ dir ]) ) {
2498                                         if ( elem.nodeType === 1 || checkNonElements ) {
2499                                                 if ( matcher( elem, context, xml ) ) {
2500                                                         return true;
2501                                                 }
2502                                         }
2503                                 }
2504                         } else {
2505                                 while ( (elem = elem[ dir ]) ) {
2506                                         if ( elem.nodeType === 1 || checkNonElements ) {
2507                                                 outerCache = elem[ expando ] || (elem[ expando ] = {});
2508                                                 if ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) {
2509                                                         if ( (data = cache[1]) === true || data === cachedruns ) {
2510                                                                 return data === true;
2511                                                         }
2512                                                 } else {
2513                                                         cache = outerCache[ dir ] = [ dirkey ];
2514                                                         cache[1] = matcher( elem, context, xml ) || cachedruns;
2515                                                         if ( cache[1] === true ) {
2516                                                                 return true;
2517                                                         }
2518                                                 }
2519                                         }
2520                                 }
2521                         }
2522                 };
2523 }
2524
2525 function elementMatcher( matchers ) {
2526         return matchers.length > 1 ?
2527                 function( elem, context, xml ) {
2528                         var i = matchers.length;
2529                         while ( i-- ) {
2530                                 if ( !matchers[i]( elem, context, xml ) ) {
2531                                         return false;
2532                                 }
2533                         }
2534                         return true;
2535                 } :
2536                 matchers[0];
2537 }
2538
2539 function condense( unmatched, map, filter, context, xml ) {
2540         var elem,
2541                 newUnmatched = [],
2542                 i = 0,
2543                 len = unmatched.length,
2544                 mapped = map != null;
2545
2546         for ( ; i < len; i++ ) {
2547                 if ( (elem = unmatched[i]) ) {
2548                         if ( !filter || filter( elem, context, xml ) ) {
2549                                 newUnmatched.push( elem );
2550                                 if ( mapped ) {
2551                                         map.push( i );
2552                                 }
2553                         }
2554                 }
2555         }
2556
2557         return newUnmatched;
2558 }
2559
2560 function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2561         if ( postFilter && !postFilter[ expando ] ) {
2562                 postFilter = setMatcher( postFilter );
2563         }
2564         if ( postFinder && !postFinder[ expando ] ) {
2565                 postFinder = setMatcher( postFinder, postSelector );
2566         }
2567         return markFunction(function( seed, results, context, xml ) {
2568                 var temp, i, elem,
2569                         preMap = [],
2570                         postMap = [],
2571                         preexisting = results.length,
2572
2573                         // Get initial elements from seed or context
2574                         elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
2575
2576                         // Prefilter to get matcher input, preserving a map for seed-results synchronization
2577                         matcherIn = preFilter && ( seed || !selector ) ?
2578                                 condense( elems, preMap, preFilter, context, xml ) :
2579                                 elems,
2580
2581                         matcherOut = matcher ?
2582                                 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2583                                 postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2584
2585                                         // ...intermediate processing is necessary
2586                                         [] :
2587
2588                                         // ...otherwise use results directly
2589                                         results :
2590                                 matcherIn;
2591
2592                 // Find primary matches
2593                 if ( matcher ) {
2594                         matcher( matcherIn, matcherOut, context, xml );
2595                 }
2596
2597                 // Apply postFilter
2598                 if ( postFilter ) {
2599                         temp = condense( matcherOut, postMap );
2600                         postFilter( temp, [], context, xml );
2601
2602                         // Un-match failing elements by moving them back to matcherIn
2603                         i = temp.length;
2604                         while ( i-- ) {
2605                                 if ( (elem = temp[i]) ) {
2606                                         matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
2607                                 }
2608                         }
2609                 }
2610
2611                 if ( seed ) {
2612                         if ( postFinder || preFilter ) {
2613                                 if ( postFinder ) {
2614                                         // Get the final matcherOut by condensing this intermediate into postFinder contexts
2615                                         temp = [];
2616                                         i = matcherOut.length;
2617                                         while ( i-- ) {
2618                                                 if ( (elem = matcherOut[i]) ) {
2619                                                         // Restore matcherIn since elem is not yet a final match
2620                                                         temp.push( (matcherIn[i] = elem) );
2621                                                 }
2622                                         }
2623                                         postFinder( null, (matcherOut = []), temp, xml );
2624                                 }
2625
2626                                 // Move matched elements from seed to results to keep them synchronized
2627                                 i = matcherOut.length;
2628                                 while ( i-- ) {
2629                                         if ( (elem = matcherOut[i]) &&
2630                                                 (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
2631
2632                                                 seed[temp] = !(results[temp] = elem);
2633                                         }
2634                                 }
2635                         }
2636
2637                 // Add elements to results, through postFinder if defined
2638                 } else {
2639                         matcherOut = condense(
2640                                 matcherOut === results ?
2641                                         matcherOut.splice( preexisting, matcherOut.length ) :
2642                                         matcherOut
2643                         );
2644                         if ( postFinder ) {
2645                                 postFinder( null, results, matcherOut, xml );
2646                         } else {
2647                                 push.apply( results, matcherOut );
2648                         }
2649                 }
2650         });
2651 }
2652
2653 function matcherFromTokens( tokens ) {
2654         var checkContext, matcher, j,
2655                 len = tokens.length,
2656                 leadingRelative = Expr.relative[ tokens[0].type ],
2657                 implicitRelative = leadingRelative || Expr.relative[" "],
2658                 i = leadingRelative ? 1 : 0,
2659
2660                 // The foundational matcher ensures that elements are reachable from top-level context(s)
2661                 matchContext = addCombinator( function( elem ) {
2662                         return elem === checkContext;
2663                 }, implicitRelative, true ),
2664                 matchAnyContext = addCombinator( function( elem ) {
2665                         return indexOf.call( checkContext, elem ) > -1;
2666                 }, implicitRelative, true ),
2667                 matchers = [ function( elem, context, xml ) {
2668                         return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2669                                 (checkContext = context).nodeType ?
2670                                         matchContext( elem, context, xml ) :
2671                                         matchAnyContext( elem, context, xml ) );
2672                 } ];
2673
2674         for ( ; i < len; i++ ) {
2675                 if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
2676                         matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
2677                 } else {
2678                         matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
2679
2680                         // Return special upon seeing a positional matcher
2681                         if ( matcher[ expando ] ) {
2682                                 // Find the next relative operator (if any) for proper handling
2683                                 j = ++i;
2684                                 for ( ; j < len; j++ ) {
2685                                         if ( Expr.relative[ tokens[j].type ] ) {
2686                                                 break;
2687                                         }
2688                                 }
2689                                 return setMatcher(
2690                                         i > 1 && elementMatcher( matchers ),
2691                                         i > 1 && toSelector(
2692                                                 // If the preceding token was a descendant combinator, insert an implicit any-element `*`
2693                                                 tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
2694                                         ).replace( rtrim, "$1" ),
2695                                         matcher,
2696                                         i < j && matcherFromTokens( tokens.slice( i, j ) ),
2697                                         j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
2698                                         j < len && toSelector( tokens )
2699                                 );
2700                         }
2701                         matchers.push( matcher );
2702                 }
2703         }
2704
2705         return elementMatcher( matchers );
2706 }
2707
2708 function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2709         // A counter to specify which element is currently being matched
2710         var matcherCachedRuns = 0,
2711                 bySet = setMatchers.length > 0,
2712                 byElement = elementMatchers.length > 0,
2713                 superMatcher = function( seed, context, xml, results, expandContext ) {
2714                         var elem, j, matcher,
2715                                 setMatched = [],
2716                                 matchedCount = 0,
2717                                 i = "0",
2718                                 unmatched = seed && [],
2719                                 outermost = expandContext != null,
2720                                 contextBackup = outermostContext,
2721                                 // We must always have either seed elements or context
2722                                 elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ),
2723                                 // Use integer dirruns iff this is the outermost matcher
2724                                 dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1);
2725
2726                         if ( outermost ) {
2727                                 outermostContext = context !== document && context;
2728                                 cachedruns = matcherCachedRuns;
2729                         }
2730
2731                         // Add elements passing elementMatchers directly to results
2732                         // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
2733                         for ( ; (elem = elems[i]) != null; i++ ) {
2734                                 if ( byElement && elem ) {
2735                                         j = 0;
2736                                         while ( (matcher = elementMatchers[j++]) ) {
2737                                                 if ( matcher( elem, context, xml ) ) {
2738                                                         results.push( elem );
2739                                                         break;
2740                                                 }
2741                                         }
2742                                         if ( outermost ) {
2743                                                 dirruns = dirrunsUnique;
2744                                                 cachedruns = ++matcherCachedRuns;
2745                                         }
2746                                 }
2747
2748                                 // Track unmatched elements for set filters
2749                                 if ( bySet ) {
2750                                         // They will have gone through all possible matchers
2751                                         if ( (elem = !matcher && elem) ) {
2752                                                 matchedCount--;
2753                                         }
2754
2755                                         // Lengthen the array for every element, matched or not
2756                                         if ( seed ) {
2757                                                 unmatched.push( elem );
2758                                         }
2759                                 }
2760                         }
2761
2762                         // Apply set filters to unmatched elements
2763                         matchedCount += i;
2764                         if ( bySet && i !== matchedCount ) {
2765                                 j = 0;
2766                                 while ( (matcher = setMatchers[j++]) ) {
2767                                         matcher( unmatched, setMatched, context, xml );
2768                                 }
2769
2770                                 if ( seed ) {
2771                                         // Reintegrate element matches to eliminate the need for sorting
2772                                         if ( matchedCount > 0 ) {
2773                                                 while ( i-- ) {
2774                                                         if ( !(unmatched[i] || setMatched[i]) ) {
2775                                                                 setMatched[i] = pop.call( results );
2776                                                         }
2777                                                 }
2778                                         }
2779
2780                                         // Discard index placeholder values to get only actual matches
2781                                         setMatched = condense( setMatched );
2782                                 }
2783
2784                                 // Add matches to results
2785                                 push.apply( results, setMatched );
2786
2787                                 // Seedless set matches succeeding multiple successful matchers stipulate sorting
2788                                 if ( outermost && !seed && setMatched.length > 0 &&
2789                                         ( matchedCount + setMatchers.length ) > 1 ) {
2790
2791                                         Sizzle.uniqueSort( results );
2792                                 }
2793                         }
2794
2795                         // Override manipulation of globals by nested matchers
2796                         if ( outermost ) {
2797                                 dirruns = dirrunsUnique;
2798                                 outermostContext = contextBackup;
2799                         }
2800
2801                         return unmatched;
2802                 };
2803
2804         return bySet ?
2805                 markFunction( superMatcher ) :
2806                 superMatcher;
2807 }
2808
2809 compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {
2810         var i,
2811                 setMatchers = [],
2812                 elementMatchers = [],
2813                 cached = compilerCache[ selector + " " ];
2814
2815         if ( !cached ) {
2816                 // Generate a function of recursive functions that can be used to check each element
2817                 if ( !group ) {
2818                         group = tokenize( selector );
2819                 }
2820                 i = group.length;
2821                 while ( i-- ) {
2822                         cached = matcherFromTokens( group[