PageSourceSearch

https://www.highup-ent.com/wp-content/themes/highup/js/jquery.js?ver=1.9.1

js highup-ent.com collected 2026-09-25 06:12:13 UTC 290,323 bytes, 9,597 lines download raw bytes

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

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.