Project

General

Profile

1
/*!
2
 * jQuery JavaScript Library v2.2.4
3
 * http://jquery.com/
4
 *
5
 * Includes Sizzle.js
6
 * http://sizzlejs.com/
7
 *
8
 * Copyright jQuery Foundation and other contributors
9
 * Released under the MIT license
10
 * http://jquery.org/license
11
 *
12
 * Date: 2016-05-20T17:23Z
13
 */
14

    
15
(function( global, factory ) {
16

    
17
	if ( typeof module === "object" && typeof module.exports === "object" ) {
18
		// For CommonJS and CommonJS-like environments where a proper `window`
19
		// is present, execute the factory and get jQuery.
20
		// For environments that do not have a `window` with a `document`
21
		// (such as Node.js), expose a factory as module.exports.
22
		// This accentuates the need for the creation of a real `window`.
23
		// e.g. var jQuery = require("jquery")(window);
24
		// See ticket #14549 for more info.
25
		module.exports = global.document ?
26
			factory( global, true ) :
27
			function( w ) {
28
				if ( !w.document ) {
29
					throw new Error( "jQuery requires a window with a document" );
30
				}
31
				return factory( w );
32
			};
33
	} else {
34
		factory( global );
35
	}
36

    
37
// Pass this if window is not defined yet
38
}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
39

    
40
// Support: Firefox 18+
41
// Can't be in strict mode, several libs including ASP.NET trace
42
// the stack via arguments.caller.callee and Firefox dies if
43
// you try to trace through "use strict" call chains. (#13335)
44
//"use strict";
45
var arr = [];
46

    
47
var document = window.document;
48

    
49
var slice = arr.slice;
50

    
51
var concat = arr.concat;
52

    
53
var push = arr.push;
54

    
55
var indexOf = arr.indexOf;
56

    
57
var class2type = {};
58

    
59
var toString = class2type.toString;
60

    
61
var hasOwn = class2type.hasOwnProperty;
62

    
63
var support = {};
64

    
65

    
66

    
67
var
68
	version = "2.2.4",
69

    
70
	// Define a local copy of jQuery
71
	jQuery = function( selector, context ) {
72

    
73
		// The jQuery object is actually just the init constructor 'enhanced'
74
		// Need init if jQuery is called (just allow error to be thrown if not included)
75
		return new jQuery.fn.init( selector, context );
76
	},
77

    
78
	// Support: Android<4.1
79
	// Make sure we trim BOM and NBSP
80
	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
81

    
82
	// Matches dashed string for camelizing
83
	rmsPrefix = /^-ms-/,
84
	rdashAlpha = /-([\da-z])/gi,
85

    
86
	// Used by jQuery.camelCase as callback to replace()
87
	fcamelCase = function( all, letter ) {
88
		return letter.toUpperCase();
89
	};
90

    
91
jQuery.fn = jQuery.prototype = {
92

    
93
	// The current version of jQuery being used
94
	jquery: version,
95

    
96
	constructor: jQuery,
97

    
98
	// Start with an empty selector
99
	selector: "",
100

    
101
	// The default length of a jQuery object is 0
102
	length: 0,
103

    
104
	toArray: function() {
105
		return slice.call( this );
106
	},
107

    
108
	// Get the Nth element in the matched element set OR
109
	// Get the whole matched element set as a clean array
110
	get: function( num ) {
111
		return num != null ?
112

    
113
			// Return just the one element from the set
114
			( num < 0 ? this[ num + this.length ] : this[ num ] ) :
115

    
116
			// Return all the elements in a clean array
117
			slice.call( this );
118
	},
119

    
120
	// Take an array of elements and push it onto the stack
121
	// (returning the new matched element set)
122
	pushStack: function( elems ) {
123

    
124
		// Build a new jQuery matched element set
125
		var ret = jQuery.merge( this.constructor(), elems );
126

    
127
		// Add the old object onto the stack (as a reference)
128
		ret.prevObject = this;
129
		ret.context = this.context;
130

    
131
		// Return the newly-formed element set
132
		return ret;
133
	},
134

    
135
	// Execute a callback for every element in the matched set.
136
	each: function( callback ) {
137
		return jQuery.each( this, callback );
138
	},
139

    
140
	map: function( callback ) {
141
		return this.pushStack( jQuery.map( this, function( elem, i ) {
142
			return callback.call( elem, i, elem );
143
		} ) );
144
	},
145

    
146
	slice: function() {
147
		return this.pushStack( slice.apply( this, arguments ) );
148
	},
149

    
150
	first: function() {
151
		return this.eq( 0 );
152
	},
153

    
154
	last: function() {
155
		return this.eq( -1 );
156
	},
157

    
158
	eq: function( i ) {
159
		var len = this.length,
160
			j = +i + ( i < 0 ? len : 0 );
161
		return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
162
	},
163

    
164
	end: function() {
165
		return this.prevObject || this.constructor();
166
	},
167

    
168
	// For internal use only.
169
	// Behaves like an Array's method, not like a jQuery method.
170
	push: push,
171
	sort: arr.sort,
172
	splice: arr.splice
173
};
174

    
175
jQuery.extend = jQuery.fn.extend = function() {
176
	var options, name, src, copy, copyIsArray, clone,
177
		target = arguments[ 0 ] || {},
178
		i = 1,
179
		length = arguments.length,
180
		deep = false;
181

    
182
	// Handle a deep copy situation
183
	if ( typeof target === "boolean" ) {
184
		deep = target;
185

    
186
		// Skip the boolean and the target
187
		target = arguments[ i ] || {};
188
		i++;
189
	}
190

    
191
	// Handle case when target is a string or something (possible in deep copy)
192
	if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
193
		target = {};
194
	}
195

    
196
	// Extend jQuery itself if only one argument is passed
197
	if ( i === length ) {
198
		target = this;
199
		i--;
200
	}
201

    
202
	for ( ; i < length; i++ ) {
203

    
204
		// Only deal with non-null/undefined values
205
		if ( ( options = arguments[ i ] ) != null ) {
206

    
207
			// Extend the base object
208
			for ( name in options ) {
209
				src = target[ name ];
210
				copy = options[ name ];
211

    
212
				// Prevent never-ending loop
213
				if ( target === copy ) {
214
					continue;
215
				}
216

    
217
				// Recurse if we're merging plain objects or arrays
218
				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
219
					( copyIsArray = jQuery.isArray( copy ) ) ) ) {
220

    
221
					if ( copyIsArray ) {
222
						copyIsArray = false;
223
						clone = src && jQuery.isArray( src ) ? src : [];
224

    
225
					} else {
226
						clone = src && jQuery.isPlainObject( src ) ? src : {};
227
					}
228

    
229
					// Never move original objects, clone them
230
					target[ name ] = jQuery.extend( deep, clone, copy );
231

    
232
				// Don't bring in undefined values
233
				} else if ( copy !== undefined ) {
234
					target[ name ] = copy;
235
				}
236
			}
237
		}
238
	}
239

    
240
	// Return the modified object
241
	return target;
242
};
243

    
244
jQuery.extend( {
245

    
246
	// Unique for each copy of jQuery on the page
247
	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
248

    
249
	// Assume jQuery is ready without the ready module
250
	isReady: true,
251

    
252
	error: function( msg ) {
253
		throw new Error( msg );
254
	},
255

    
256
	noop: function() {},
257

    
258
	isFunction: function( obj ) {
259
		return jQuery.type( obj ) === "function";
260
	},
261

    
262
	isArray: Array.isArray,
263

    
264
	isWindow: function( obj ) {
265
		return obj != null && obj === obj.window;
266
	},
267

    
268
	isNumeric: function( obj ) {
269

    
270
		// parseFloat NaNs numeric-cast false positives (null|true|false|"")
271
		// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
272
		// subtraction forces infinities to NaN
273
		// adding 1 corrects loss of precision from parseFloat (#15100)
274
		var realStringObj = obj && obj.toString();
275
		return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;
276
	},
277

    
278
	isPlainObject: function( obj ) {
279
		var key;
280

    
281
		// Not plain objects:
282
		// - Any object or value whose internal [[Class]] property is not "[object Object]"
283
		// - DOM nodes
284
		// - window
285
		if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
286
			return false;
287
		}
288

    
289
		// Not own constructor property must be Object
290
		if ( obj.constructor &&
291
				!hasOwn.call( obj, "constructor" ) &&
292
				!hasOwn.call( obj.constructor.prototype || {}, "isPrototypeOf" ) ) {
293
			return false;
294
		}
295

    
296
		// Own properties are enumerated firstly, so to speed up,
297
		// if last one is own, then all properties are own
298
		for ( key in obj ) {}
299

    
300
		return key === undefined || hasOwn.call( obj, key );
301
	},
302

    
303
	isEmptyObject: function( obj ) {
304
		var name;
305
		for ( name in obj ) {
306
			return false;
307
		}
308
		return true;
309
	},
310

    
311
	type: function( obj ) {
312
		if ( obj == null ) {
313
			return obj + "";
314
		}
315

    
316
		// Support: Android<4.0, iOS<6 (functionish RegExp)
317
		return typeof obj === "object" || typeof obj === "function" ?
318
			class2type[ toString.call( obj ) ] || "object" :
319
			typeof obj;
320
	},
321

    
322
	// Evaluates a script in a global context
323
	globalEval: function( code ) {
324
		var script,
325
			indirect = eval;
326

    
327
		code = jQuery.trim( code );
328

    
329
		if ( code ) {
330

    
331
			// If the code includes a valid, prologue position
332
			// strict mode pragma, execute code by injecting a
333
			// script tag into the document.
334
			if ( code.indexOf( "use strict" ) === 1 ) {
335
				script = document.createElement( "script" );
336
				script.text = code;
337
				document.head.appendChild( script ).parentNode.removeChild( script );
338
			} else {
339

    
340
				// Otherwise, avoid the DOM node creation, insertion
341
				// and removal by using an indirect global eval
342

    
343
				indirect( code );
344
			}
345
		}
346
	},
347

    
348
	// Convert dashed to camelCase; used by the css and data modules
349
	// Support: IE9-11+
350
	// Microsoft forgot to hump their vendor prefix (#9572)
351
	camelCase: function( string ) {
352
		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
353
	},
354

    
355
	nodeName: function( elem, name ) {
356
		return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
357
	},
358

    
359
	each: function( obj, callback ) {
360
		var length, i = 0;
361

    
362
		if ( isArrayLike( obj ) ) {
363
			length = obj.length;
364
			for ( ; i < length; i++ ) {
365
				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
366
					break;
367
				}
368
			}
369
		} else {
370
			for ( i in obj ) {
371
				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
372
					break;
373
				}
374
			}
375
		}
376

    
377
		return obj;
378
	},
379

    
380
	// Support: Android<4.1
381
	trim: function( text ) {
382
		return text == null ?
383
			"" :
384
			( text + "" ).replace( rtrim, "" );
385
	},
386

    
387
	// results is for internal usage only
388
	makeArray: function( arr, results ) {
389
		var ret = results || [];
390

    
391
		if ( arr != null ) {
392
			if ( isArrayLike( Object( arr ) ) ) {
393
				jQuery.merge( ret,
394
					typeof arr === "string" ?
395
					[ arr ] : arr
396
				);
397
			} else {
398
				push.call( ret, arr );
399
			}
400
		}
401

    
402
		return ret;
403
	},
404

    
405
	inArray: function( elem, arr, i ) {
406
		return arr == null ? -1 : indexOf.call( arr, elem, i );
407
	},
408

    
409
	merge: function( first, second ) {
410
		var len = +second.length,
411
			j = 0,
412
			i = first.length;
413

    
414
		for ( ; j < len; j++ ) {
415
			first[ i++ ] = second[ j ];
416
		}
417

    
418
		first.length = i;
419

    
420
		return first;
421
	},
422

    
423
	grep: function( elems, callback, invert ) {
424
		var callbackInverse,
425
			matches = [],
426
			i = 0,
427
			length = elems.length,
428
			callbackExpect = !invert;
429

    
430
		// Go through the array, only saving the items
431
		// that pass the validator function
432
		for ( ; i < length; i++ ) {
433
			callbackInverse = !callback( elems[ i ], i );
434
			if ( callbackInverse !== callbackExpect ) {
435
				matches.push( elems[ i ] );
436
			}
437
		}
438

    
439
		return matches;
440
	},
441

    
442
	// arg is for internal usage only
443
	map: function( elems, callback, arg ) {
444
		var length, value,
445
			i = 0,
446
			ret = [];
447

    
448
		// Go through the array, translating each of the items to their new values
449
		if ( isArrayLike( elems ) ) {
450
			length = elems.length;
451
			for ( ; i < length; i++ ) {
452
				value = callback( elems[ i ], i, arg );
453

    
454
				if ( value != null ) {
455
					ret.push( value );
456
				}
457
			}
458

    
459
		// Go through every key on the object,
460
		} else {
461
			for ( i in elems ) {
462
				value = callback( elems[ i ], i, arg );
463

    
464
				if ( value != null ) {
465
					ret.push( value );
466
				}
467
			}
468
		}
469

    
470
		// Flatten any nested arrays
471
		return concat.apply( [], ret );
472
	},
473

    
474
	// A global GUID counter for objects
475
	guid: 1,
476

    
477
	// Bind a function to a context, optionally partially applying any
478
	// arguments.
479
	proxy: function( fn, context ) {
480
		var tmp, args, proxy;
481

    
482
		if ( typeof context === "string" ) {
483
			tmp = fn[ context ];
484
			context = fn;
485
			fn = tmp;
486
		}
487

    
488
		// Quick check to determine if target is callable, in the spec
489
		// this throws a TypeError, but we will just return undefined.
490
		if ( !jQuery.isFunction( fn ) ) {
491
			return undefined;
492
		}
493

    
494
		// Simulated bind
495
		args = slice.call( arguments, 2 );
496
		proxy = function() {
497
			return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
498
		};
499

    
500
		// Set the guid of unique handler to the same of original handler, so it can be removed
501
		proxy.guid = fn.guid = fn.guid || jQuery.guid++;
502

    
503
		return proxy;
504
	},
505

    
506
	now: Date.now,
507

    
508
	// jQuery.support is not used in Core but other projects attach their
509
	// properties to it so it needs to exist.
510
	support: support
511
} );
512

    
513
// JSHint would error on this code due to the Symbol not being defined in ES5.
514
// Defining this global in .jshintrc would create a danger of using the global
515
// unguarded in another place, it seems safer to just disable JSHint for these
516
// three lines.
517
/* jshint ignore: start */
518
if ( typeof Symbol === "function" ) {
519
	jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
520
}
521
/* jshint ignore: end */
522

    
523
// Populate the class2type map
524
jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
525
function( i, name ) {
526
	class2type[ "[object " + name + "]" ] = name.toLowerCase();
527
} );
528

    
529
function isArrayLike( obj ) {
530

    
531
	// Support: iOS 8.2 (not reproducible in simulator)
532
	// `in` check used to prevent JIT error (gh-2145)
533
	// hasOwn isn't used here due to false negatives
534
	// regarding Nodelist length in IE
535
	var length = !!obj && "length" in obj && obj.length,
536
		type = jQuery.type( obj );
537

    
538
	if ( type === "function" || jQuery.isWindow( obj ) ) {
539
		return false;
540
	}
541

    
542
	return type === "array" || length === 0 ||
543
		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
544
}
545
var Sizzle =
546
/*!
547
 * Sizzle CSS Selector Engine v2.2.1
548
 * http://sizzlejs.com/
549
 *
550
 * Copyright jQuery Foundation and other contributors
551
 * Released under the MIT license
552
 * http://jquery.org/license
553
 *
554
 * Date: 2015-10-17
555
 */
556
(function( window ) {
557

    
558
var i,
559
	support,
560
	Expr,
561
	getText,
562
	isXML,
563
	tokenize,
564
	compile,
565
	select,
566
	outermostContext,
567
	sortInput,
568
	hasDuplicate,
569

    
570
	// Local document vars
571
	setDocument,
572
	document,
573
	docElem,
574
	documentIsHTML,
575
	rbuggyQSA,
576
	rbuggyMatches,
577
	matches,
578
	contains,
579

    
580
	// Instance-specific data
581
	expando = "sizzle" + 1 * new Date(),
582
	preferredDoc = window.document,
583
	dirruns = 0,
584
	done = 0,
585
	classCache = createCache(),
586
	tokenCache = createCache(),
587
	compilerCache = createCache(),
588
	sortOrder = function( a, b ) {
589
		if ( a === b ) {
590
			hasDuplicate = true;
591
		}
592
		return 0;
593
	},
594

    
595
	// General-purpose constants
596
	MAX_NEGATIVE = 1 << 31,
597

    
598
	// Instance methods
599
	hasOwn = ({}).hasOwnProperty,
600
	arr = [],
601
	pop = arr.pop,
602
	push_native = arr.push,
603
	push = arr.push,
604
	slice = arr.slice,
605
	// Use a stripped-down indexOf as it's faster than native
606
	// http://jsperf.com/thor-indexof-vs-for/5
607
	indexOf = function( list, elem ) {
608
		var i = 0,
609
			len = list.length;
610
		for ( ; i < len; i++ ) {
611
			if ( list[i] === elem ) {
612
				return i;
613
			}
614
		}
615
		return -1;
616
	},
617

    
618
	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
619

    
620
	// Regular expressions
621

    
622
	// http://www.w3.org/TR/css3-selectors/#whitespace
623
	whitespace = "[\\x20\\t\\r\\n\\f]",
624

    
625
	// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
626
	identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
627

    
628
	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
629
	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
630
		// Operator (capture 2)
631
		"*([*^$|!~]?=)" + whitespace +
632
		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
633
		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
634
		"*\\]",
635

    
636
	pseudos = ":(" + identifier + ")(?:\\((" +
637
		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
638
		// 1. quoted (capture 3; capture 4 or capture 5)
639
		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
640
		// 2. simple (capture 6)
641
		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
642
		// 3. anything else (capture 2)
643
		".*" +
644
		")\\)|)",
645

    
646
	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
647
	rwhitespace = new RegExp( whitespace + "+", "g" ),
648
	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
649

    
650
	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
651
	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
652

    
653
	rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
654

    
655
	rpseudo = new RegExp( pseudos ),
656
	ridentifier = new RegExp( "^" + identifier + "$" ),
657

    
658
	matchExpr = {
659
		"ID": new RegExp( "^#(" + identifier + ")" ),
660
		"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
661
		"TAG": new RegExp( "^(" + identifier + "|[*])" ),
662
		"ATTR": new RegExp( "^" + attributes ),
663
		"PSEUDO": new RegExp( "^" + pseudos ),
664
		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
665
			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
666
			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
667
		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
668
		// For use in libraries implementing .is()
669
		// We use this for POS matching in `select`
670
		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
671
			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
672
	},
673

    
674
	rinputs = /^(?:input|select|textarea|button)$/i,
675
	rheader = /^h\d$/i,
676

    
677
	rnative = /^[^{]+\{\s*\[native \w/,
678

    
679
	// Easily-parseable/retrievable ID or TAG or CLASS selectors
680
	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
681

    
682
	rsibling = /[+~]/,
683
	rescape = /'|\\/g,
684

    
685
	// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
686
	runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
687
	funescape = function( _, escaped, escapedWhitespace ) {
688
		var high = "0x" + escaped - 0x10000;
689
		// NaN means non-codepoint
690
		// Support: Firefox<24
691
		// Workaround erroneous numeric interpretation of +"0x"
692
		return high !== high || escapedWhitespace ?
693
			escaped :
694
			high < 0 ?
695
				// BMP codepoint
696
				String.fromCharCode( high + 0x10000 ) :
697
				// Supplemental Plane codepoint (surrogate pair)
698
				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
699
	},
700

    
701
	// Used for iframes
702
	// See setDocument()
703
	// Removing the function wrapper causes a "Permission Denied"
704
	// error in IE
705
	unloadHandler = function() {
706
		setDocument();
707
	};
708

    
709
// Optimize for push.apply( _, NodeList )
710
try {
711
	push.apply(
712
		(arr = slice.call( preferredDoc.childNodes )),
713
		preferredDoc.childNodes
714
	);
715
	// Support: Android<4.0
716
	// Detect silently failing push.apply
717
	arr[ preferredDoc.childNodes.length ].nodeType;
718
} catch ( e ) {
719
	push = { apply: arr.length ?
720

    
721
		// Leverage slice if possible
722
		function( target, els ) {
723
			push_native.apply( target, slice.call(els) );
724
		} :
725

    
726
		// Support: IE<9
727
		// Otherwise append directly
728
		function( target, els ) {
729
			var j = target.length,
730
				i = 0;
731
			// Can't trust NodeList.length
732
			while ( (target[j++] = els[i++]) ) {}
733
			target.length = j - 1;
734
		}
735
	};
736
}
737

    
738
function Sizzle( selector, context, results, seed ) {
739
	var m, i, elem, nid, nidselect, match, groups, newSelector,
740
		newContext = context && context.ownerDocument,
741

    
742
		// nodeType defaults to 9, since context defaults to document
743
		nodeType = context ? context.nodeType : 9;
744

    
745
	results = results || [];
746

    
747
	// Return early from calls with invalid selector or context
748
	if ( typeof selector !== "string" || !selector ||
749
		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
750

    
751
		return results;
752
	}
753

    
754
	// Try to shortcut find operations (as opposed to filters) in HTML documents
755
	if ( !seed ) {
756

    
757
		if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
758
			setDocument( context );
759
		}
760
		context = context || document;
761

    
762
		if ( documentIsHTML ) {
763

    
764
			// If the selector is sufficiently simple, try using a "get*By*" DOM method
765
			// (excepting DocumentFragment context, where the methods don't exist)
766
			if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
767

    
768
				// ID selector
769
				if ( (m = match[1]) ) {
770

    
771
					// Document context
772
					if ( nodeType === 9 ) {
773
						if ( (elem = context.getElementById( m )) ) {
774

    
775
							// Support: IE, Opera, Webkit
776
							// TODO: identify versions
777
							// getElementById can match elements by name instead of ID
778
							if ( elem.id === m ) {
779
								results.push( elem );
780
								return results;
781
							}
782
						} else {
783
							return results;
784
						}
785

    
786
					// Element context
787
					} else {
788

    
789
						// Support: IE, Opera, Webkit
790
						// TODO: identify versions
791
						// getElementById can match elements by name instead of ID
792
						if ( newContext && (elem = newContext.getElementById( m )) &&
793
							contains( context, elem ) &&
794
							elem.id === m ) {
795

    
796
							results.push( elem );
797
							return results;
798
						}
799
					}
800

    
801
				// Type selector
802
				} else if ( match[2] ) {
803
					push.apply( results, context.getElementsByTagName( selector ) );
804
					return results;
805

    
806
				// Class selector
807
				} else if ( (m = match[3]) && support.getElementsByClassName &&
808
					context.getElementsByClassName ) {
809

    
810
					push.apply( results, context.getElementsByClassName( m ) );
811
					return results;
812
				}
813
			}
814

    
815
			// Take advantage of querySelectorAll
816
			if ( support.qsa &&
817
				!compilerCache[ selector + " " ] &&
818
				(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
819

    
820
				if ( nodeType !== 1 ) {
821
					newContext = context;
822
					newSelector = selector;
823

    
824
				// qSA looks outside Element context, which is not what we want
825
				// Thanks to Andrew Dupont for this workaround technique
826
				// Support: IE <=8
827
				// Exclude object elements
828
				} else if ( context.nodeName.toLowerCase() !== "object" ) {
829

    
830
					// Capture the context ID, setting it first if necessary
831
					if ( (nid = context.getAttribute( "id" )) ) {
832
						nid = nid.replace( rescape, "\\$&" );
833
					} else {
834
						context.setAttribute( "id", (nid = expando) );
835
					}
836

    
837
					// Prefix every selector in the list
838
					groups = tokenize( selector );
839
					i = groups.length;
840
					nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']";
841
					while ( i-- ) {
842
						groups[i] = nidselect + " " + toSelector( groups[i] );
843
					}
844
					newSelector = groups.join( "," );
845

    
846
					// Expand context for sibling selectors
847
					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
848
						context;
849
				}
850

    
851
				if ( newSelector ) {
852
					try {
853
						push.apply( results,
854
							newContext.querySelectorAll( newSelector )
855
						);
856
						return results;
857
					} catch ( qsaError ) {
858
					} finally {
859
						if ( nid === expando ) {
860
							context.removeAttribute( "id" );
861
						}
862
					}
863
				}
864
			}
865
		}
866
	}
867

    
868
	// All others
869
	return select( selector.replace( rtrim, "$1" ), context, results, seed );
870
}
871

    
872
/**
873
 * Create key-value caches of limited size
874
 * @returns {function(string, object)} Returns the Object data after storing it on itself with
875
 *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
876
 *	deleting the oldest entry
877
 */
878
function createCache() {
879
	var keys = [];
880

    
881
	function cache( key, value ) {
882
		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
883
		if ( keys.push( key + " " ) > Expr.cacheLength ) {
884
			// Only keep the most recent entries
885
			delete cache[ keys.shift() ];
886
		}
887
		return (cache[ key + " " ] = value);
888
	}
889
	return cache;
890
}
891

    
892
/**
893
 * Mark a function for special use by Sizzle
894
 * @param {Function} fn The function to mark
895
 */
896
function markFunction( fn ) {
897
	fn[ expando ] = true;
898
	return fn;
899
}
900

    
901
/**
902
 * Support testing using an element
903
 * @param {Function} fn Passed the created div and expects a boolean result
904
 */
905
function assert( fn ) {
906
	var div = document.createElement("div");
907

    
908
	try {
909
		return !!fn( div );
910
	} catch (e) {
911
		return false;
912
	} finally {
913
		// Remove from its parent by default
914
		if ( div.parentNode ) {
915
			div.parentNode.removeChild( div );
916
		}
917
		// release memory in IE
918
		div = null;
919
	}
920
}
921

    
922
/**
923
 * Adds the same handler for all of the specified attrs
924
 * @param {String} attrs Pipe-separated list of attributes
925
 * @param {Function} handler The method that will be applied
926
 */
927
function addHandle( attrs, handler ) {
928
	var arr = attrs.split("|"),
929
		i = arr.length;
930

    
931
	while ( i-- ) {
932
		Expr.attrHandle[ arr[i] ] = handler;
933
	}
934
}
935

    
936
/**
937
 * Checks document order of two siblings
938
 * @param {Element} a
939
 * @param {Element} b
940
 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
941
 */
942
function siblingCheck( a, b ) {
943
	var cur = b && a,
944
		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
945
			( ~b.sourceIndex || MAX_NEGATIVE ) -
946
			( ~a.sourceIndex || MAX_NEGATIVE );
947

    
948
	// Use IE sourceIndex if available on both nodes
949
	if ( diff ) {
950
		return diff;
951
	}
952

    
953
	// Check if b follows a
954
	if ( cur ) {
955
		while ( (cur = cur.nextSibling) ) {
956
			if ( cur === b ) {
957
				return -1;
958
			}
959
		}
960
	}
961

    
962
	return a ? 1 : -1;
963
}
964

    
965
/**
966
 * Returns a function to use in pseudos for input types
967
 * @param {String} type
968
 */
969
function createInputPseudo( type ) {
970
	return function( elem ) {
971
		var name = elem.nodeName.toLowerCase();
972
		return name === "input" && elem.type === type;
973
	};
974
}
975

    
976
/**
977
 * Returns a function to use in pseudos for buttons
978
 * @param {String} type
979
 */
980
function createButtonPseudo( type ) {
981
	return function( elem ) {
982
		var name = elem.nodeName.toLowerCase();
983
		return (name === "input" || name === "button") && elem.type === type;
984
	};
985
}
986

    
987
/**
988
 * Returns a function to use in pseudos for positionals
989
 * @param {Function} fn
990
 */
991
function createPositionalPseudo( fn ) {
992
	return markFunction(function( argument ) {
993
		argument = +argument;
994
		return markFunction(function( seed, matches ) {
995
			var j,
996
				matchIndexes = fn( [], seed.length, argument ),
997
				i = matchIndexes.length;
998

    
999
			// Match elements found at the specified indexes
1000
			while ( i-- ) {
1001
				if ( seed[ (j = matchIndexes[i]) ] ) {
1002
					seed[j] = !(matches[j] = seed[j]);
1003
				}
1004
			}
1005
		});
1006
	});
1007
}
1008

    
1009
/**
1010
 * Checks a node for validity as a Sizzle context
1011
 * @param {Element|Object=} context
1012
 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1013
 */
1014
function testContext( context ) {
1015
	return context && typeof context.getElementsByTagName !== "undefined" && context;
1016
}
1017

    
1018
// Expose support vars for convenience
1019
support = Sizzle.support = {};
1020

    
1021
/**
1022
 * Detects XML nodes
1023
 * @param {Element|Object} elem An element or a document
1024
 * @returns {Boolean} True iff elem is a non-HTML XML node
1025
 */
1026
isXML = Sizzle.isXML = function( elem ) {
1027
	// documentElement is verified for cases where it doesn't yet exist
1028
	// (such as loading iframes in IE - #4833)
1029
	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1030
	return documentElement ? documentElement.nodeName !== "HTML" : false;
1031
};
1032

    
1033
/**
1034
 * Sets document-related variables once based on the current document
1035
 * @param {Element|Object} [doc] An element or document object to use to set the document
1036
 * @returns {Object} Returns the current document
1037
 */
1038
setDocument = Sizzle.setDocument = function( node ) {
1039
	var hasCompare, parent,
1040
		doc = node ? node.ownerDocument || node : preferredDoc;
1041

    
1042
	// Return early if doc is invalid or already selected
1043
	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
1044
		return document;
1045
	}
1046

    
1047
	// Update global variables
1048
	document = doc;
1049
	docElem = document.documentElement;
1050
	documentIsHTML = !isXML( document );
1051

    
1052
	// Support: IE 9-11, Edge
1053
	// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
1054
	if ( (parent = document.defaultView) && parent.top !== parent ) {
1055
		// Support: IE 11
1056
		if ( parent.addEventListener ) {
1057
			parent.addEventListener( "unload", unloadHandler, false );
1058

    
1059
		// Support: IE 9 - 10 only
1060
		} else if ( parent.attachEvent ) {
1061
			parent.attachEvent( "onunload", unloadHandler );
1062
		}
1063
	}
1064

    
1065
	/* Attributes
1066
	---------------------------------------------------------------------- */
1067

    
1068
	// Support: IE<8
1069
	// Verify that getAttribute really returns attributes and not properties
1070
	// (excepting IE8 booleans)
1071
	support.attributes = assert(function( div ) {
1072
		div.className = "i";
1073
		return !div.getAttribute("className");
1074
	});
1075

    
1076
	/* getElement(s)By*
1077
	---------------------------------------------------------------------- */
1078

    
1079
	// Check if getElementsByTagName("*") returns only elements
1080
	support.getElementsByTagName = assert(function( div ) {
1081
		div.appendChild( document.createComment("") );
1082
		return !div.getElementsByTagName("*").length;
1083
	});
1084

    
1085
	// Support: IE<9
1086
	support.getElementsByClassName = rnative.test( document.getElementsByClassName );
1087

    
1088
	// Support: IE<10
1089
	// Check if getElementById returns elements by name
1090
	// The broken getElementById methods don't pick up programatically-set names,
1091
	// so use a roundabout getElementsByName test
1092
	support.getById = assert(function( div ) {
1093
		docElem.appendChild( div ).id = expando;
1094
		return !document.getElementsByName || !document.getElementsByName( expando ).length;
1095
	});
1096

    
1097
	// ID find and filter
1098
	if ( support.getById ) {
1099
		Expr.find["ID"] = function( id, context ) {
1100
			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1101
				var m = context.getElementById( id );
1102
				return m ? [ m ] : [];
1103
			}
1104
		};
1105
		Expr.filter["ID"] = function( id ) {
1106
			var attrId = id.replace( runescape, funescape );
1107
			return function( elem ) {
1108
				return elem.getAttribute("id") === attrId;
1109
			};
1110
		};
1111
	} else {
1112
		// Support: IE6/7
1113
		// getElementById is not reliable as a find shortcut
1114
		delete Expr.find["ID"];
1115

    
1116
		Expr.filter["ID"] =  function( id ) {
1117
			var attrId = id.replace( runescape, funescape );
1118
			return function( elem ) {
1119
				var node = typeof elem.getAttributeNode !== "undefined" &&
1120
					elem.getAttributeNode("id");
1121
				return node && node.value === attrId;
1122
			};
1123
		};
1124
	}
1125

    
1126
	// Tag
1127
	Expr.find["TAG"] = support.getElementsByTagName ?
1128
		function( tag, context ) {
1129
			if ( typeof context.getElementsByTagName !== "undefined" ) {
1130
				return context.getElementsByTagName( tag );
1131

    
1132
			// DocumentFragment nodes don't have gEBTN
1133
			} else if ( support.qsa ) {
1134
				return context.querySelectorAll( tag );
1135
			}
1136
		} :
1137

    
1138
		function( tag, context ) {
1139
			var elem,
1140
				tmp = [],
1141
				i = 0,
1142
				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
1143
				results = context.getElementsByTagName( tag );
1144

    
1145
			// Filter out possible comments
1146
			if ( tag === "*" ) {
1147
				while ( (elem = results[i++]) ) {
1148
					if ( elem.nodeType === 1 ) {
1149
						tmp.push( elem );
1150
					}
1151
				}
1152

    
1153
				return tmp;
1154
			}
1155
			return results;
1156
		};
1157

    
1158
	// Class
1159
	Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
1160
		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
1161
			return context.getElementsByClassName( className );
1162
		}
1163
	};
1164

    
1165
	/* QSA/matchesSelector
1166
	---------------------------------------------------------------------- */
1167

    
1168
	// QSA and matchesSelector support
1169

    
1170
	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1171
	rbuggyMatches = [];
1172

    
1173
	// qSa(:focus) reports false when true (Chrome 21)
1174
	// We allow this because of a bug in IE8/9 that throws an error
1175
	// whenever `document.activeElement` is accessed on an iframe
1176
	// So, we allow :focus to pass through QSA all the time to avoid the IE error
1177
	// See http://bugs.jquery.com/ticket/13378
1178
	rbuggyQSA = [];
1179

    
1180
	if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
1181
		// Build QSA regex
1182
		// Regex strategy adopted from Diego Perini
1183
		assert(function( div ) {
1184
			// Select is set to empty string on purpose
1185
			// This is to test IE's treatment of not explicitly
1186
			// setting a boolean content attribute,
1187
			// since its presence should be enough
1188
			// http://bugs.jquery.com/ticket/12359
1189
			docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
1190
				"<select id='" + expando + "-\r\\' msallowcapture=''>" +
1191
				"<option selected=''></option></select>";
1192

    
1193
			// Support: IE8, Opera 11-12.16
1194
			// Nothing should be selected when empty strings follow ^= or $= or *=
1195
			// The test attribute must be unknown in Opera but "safe" for WinRT
1196
			// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1197
			if ( div.querySelectorAll("[msallowcapture^='']").length ) {
1198
				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1199
			}
1200

    
1201
			// Support: IE8
1202
			// Boolean attributes and "value" are not treated correctly
1203
			if ( !div.querySelectorAll("[selected]").length ) {
1204
				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1205
			}
1206

    
1207
			// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
1208
			if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
1209
				rbuggyQSA.push("~=");
1210
			}
1211

    
1212
			// Webkit/Opera - :checked should return selected option elements
1213
			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1214
			// IE8 throws error here and will not see later tests
1215
			if ( !div.querySelectorAll(":checked").length ) {
1216
				rbuggyQSA.push(":checked");
1217
			}
1218

    
1219
			// Support: Safari 8+, iOS 8+
1220
			// https://bugs.webkit.org/show_bug.cgi?id=136851
1221
			// In-page `selector#id sibing-combinator selector` fails
1222
			if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
1223
				rbuggyQSA.push(".#.+[+~]");
1224
			}
1225
		});
1226

    
1227
		assert(function( div ) {
1228
			// Support: Windows 8 Native Apps
1229
			// The type and name attributes are restricted during .innerHTML assignment
1230
			var input = document.createElement("input");
1231
			input.setAttribute( "type", "hidden" );
1232
			div.appendChild( input ).setAttribute( "name", "D" );
1233

    
1234
			// Support: IE8
1235
			// Enforce case-sensitivity of name attribute
1236
			if ( div.querySelectorAll("[name=d]").length ) {
1237
				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1238
			}
1239

    
1240
			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1241
			// IE8 throws error here and will not see later tests
1242
			if ( !div.querySelectorAll(":enabled").length ) {
1243
				rbuggyQSA.push( ":enabled", ":disabled" );
1244
			}
1245

    
1246
			// Opera 10-11 does not throw on post-comma invalid pseudos
1247
			div.querySelectorAll("*,:x");
1248
			rbuggyQSA.push(",.*:");
1249
		});
1250
	}
1251

    
1252
	if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
1253
		docElem.webkitMatchesSelector ||
1254
		docElem.mozMatchesSelector ||
1255
		docElem.oMatchesSelector ||
1256
		docElem.msMatchesSelector) )) ) {
1257

    
1258
		assert(function( div ) {
1259
			// Check to see if it's possible to do matchesSelector
1260
			// on a disconnected node (IE 9)
1261
			support.disconnectedMatch = matches.call( div, "div" );
1262

    
1263
			// This should fail with an exception
1264
			// Gecko does not error, returns false instead
1265
			matches.call( div, "[s!='']:x" );
1266
			rbuggyMatches.push( "!=", pseudos );
1267
		});
1268
	}
1269

    
1270
	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
1271
	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
1272

    
1273
	/* Contains
1274
	---------------------------------------------------------------------- */
1275
	hasCompare = rnative.test( docElem.compareDocumentPosition );
1276

    
1277
	// Element contains another
1278
	// Purposefully self-exclusive
1279
	// As in, an element does not contain itself
1280
	contains = hasCompare || rnative.test( docElem.contains ) ?
1281
		function( a, b ) {
1282
			var adown = a.nodeType === 9 ? a.documentElement : a,
1283
				bup = b && b.parentNode;
1284
			return a === bup || !!( bup && bup.nodeType === 1 && (
1285
				adown.contains ?
1286
					adown.contains( bup ) :
1287
					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1288
			));
1289
		} :
1290
		function( a, b ) {
1291
			if ( b ) {
1292
				while ( (b = b.parentNode) ) {
1293
					if ( b === a ) {
1294
						return true;
1295
					}
1296
				}
1297
			}
1298
			return false;
1299
		};
1300

    
1301
	/* Sorting
1302
	---------------------------------------------------------------------- */
1303

    
1304
	// Document order sorting
1305
	sortOrder = hasCompare ?
1306
	function( a, b ) {
1307

    
1308
		// Flag for duplicate removal
1309
		if ( a === b ) {
1310
			hasDuplicate = true;
1311
			return 0;
1312
		}
1313

    
1314
		// Sort on method existence if only one input has compareDocumentPosition
1315
		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1316
		if ( compare ) {
1317
			return compare;
1318
		}
1319

    
1320
		// Calculate position if both inputs belong to the same document
1321
		compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
1322
			a.compareDocumentPosition( b ) :
1323

    
1324
			// Otherwise we know they are disconnected
1325
			1;
1326

    
1327
		// Disconnected nodes
1328
		if ( compare & 1 ||
1329
			(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
1330

    
1331
			// Choose the first element that is related to our preferred document
1332
			if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
1333
				return -1;
1334
			}
1335
			if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
1336
				return 1;
1337
			}
1338

    
1339
			// Maintain original order
1340
			return sortInput ?
1341
				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1342
				0;
1343
		}
1344

    
1345
		return compare & 4 ? -1 : 1;
1346
	} :
1347
	function( a, b ) {
1348
		// Exit early if the nodes are identical
1349
		if ( a === b ) {
1350
			hasDuplicate = true;
1351
			return 0;
1352
		}
1353

    
1354
		var cur,
1355
			i = 0,
1356
			aup = a.parentNode,
1357
			bup = b.parentNode,
1358
			ap = [ a ],
1359
			bp = [ b ];
1360

    
1361
		// Parentless nodes are either documents or disconnected
1362
		if ( !aup || !bup ) {
1363
			return a === document ? -1 :
1364
				b === document ? 1 :
1365
				aup ? -1 :
1366
				bup ? 1 :
1367
				sortInput ?
1368
				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1369
				0;
1370

    
1371
		// If the nodes are siblings, we can do a quick check
1372
		} else if ( aup === bup ) {
1373
			return siblingCheck( a, b );
1374
		}
1375

    
1376
		// Otherwise we need full lists of their ancestors for comparison
1377
		cur = a;
1378
		while ( (cur = cur.parentNode) ) {
1379
			ap.unshift( cur );
1380
		}
1381
		cur = b;
1382
		while ( (cur = cur.parentNode) ) {
1383
			bp.unshift( cur );
1384
		}
1385

    
1386
		// Walk down the tree looking for a discrepancy
1387
		while ( ap[i] === bp[i] ) {
1388
			i++;
1389
		}
1390

    
1391
		return i ?
1392
			// Do a sibling check if the nodes have a common ancestor
1393
			siblingCheck( ap[i], bp[i] ) :
1394

    
1395
			// Otherwise nodes in our document sort first
1396
			ap[i] === preferredDoc ? -1 :
1397
			bp[i] === preferredDoc ? 1 :
1398
			0;
1399
	};
1400

    
1401
	return document;
1402
};
1403

    
1404
Sizzle.matches = function( expr, elements ) {
1405
	return Sizzle( expr, null, null, elements );
1406
};
1407

    
1408
Sizzle.matchesSelector = function( elem, expr ) {
1409
	// Set document vars if needed
1410
	if ( ( elem.ownerDocument || elem ) !== document ) {
1411
		setDocument( elem );
1412
	}
1413

    
1414
	// Make sure that attribute selectors are quoted
1415
	expr = expr.replace( rattributeQuotes, "='$1']" );
1416

    
1417
	if ( support.matchesSelector && documentIsHTML &&
1418
		!compilerCache[ expr + " " ] &&
1419
		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1420
		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
1421

    
1422
		try {
1423
			var ret = matches.call( elem, expr );
1424

    
1425
			// IE 9's matchesSelector returns false on disconnected nodes
1426
			if ( ret || support.disconnectedMatch ||
1427
					// As well, disconnected nodes are said to be in a document
1428
					// fragment in IE 9
1429
					elem.document && elem.document.nodeType !== 11 ) {
1430
				return ret;
1431
			}
1432
		} catch (e) {}
1433
	}
1434

    
1435
	return Sizzle( expr, document, null, [ elem ] ).length > 0;
1436
};
1437

    
1438
Sizzle.contains = function( context, elem ) {
1439
	// Set document vars if needed
1440
	if ( ( context.ownerDocument || context ) !== document ) {
1441
		setDocument( context );
1442
	}
1443
	return contains( context, elem );
1444
};
1445

    
1446
Sizzle.attr = function( elem, name ) {
1447
	// Set document vars if needed
1448
	if ( ( elem.ownerDocument || elem ) !== document ) {
1449
		setDocument( elem );
1450
	}
1451

    
1452
	var fn = Expr.attrHandle[ name.toLowerCase() ],
1453
		// Don't get fooled by Object.prototype properties (jQuery #13807)
1454
		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1455
			fn( elem, name, !documentIsHTML ) :
1456
			undefined;
1457

    
1458
	return val !== undefined ?
1459
		val :
1460
		support.attributes || !documentIsHTML ?
1461
			elem.getAttribute( name ) :
1462
			(val = elem.getAttributeNode(name)) && val.specified ?
1463
				val.value :
1464
				null;
1465
};
1466

    
1467
Sizzle.error = function( msg ) {
1468
	throw new Error( "Syntax error, unrecognized expression: " + msg );
1469
};
1470

    
1471
/**
1472
 * Document sorting and removing duplicates
1473
 * @param {ArrayLike} results
1474
 */
1475
Sizzle.uniqueSort = function( results ) {
1476
	var elem,
1477
		duplicates = [],
1478
		j = 0,
1479
		i = 0;
1480

    
1481
	// Unless we *know* we can detect duplicates, assume their presence
1482
	hasDuplicate = !support.detectDuplicates;
1483
	sortInput = !support.sortStable && results.slice( 0 );
1484
	results.sort( sortOrder );
1485

    
1486
	if ( hasDuplicate ) {
1487
		while ( (elem = results[i++]) ) {
1488
			if ( elem === results[ i ] ) {
1489
				j = duplicates.push( i );
1490
			}
1491
		}
1492
		while ( j-- ) {
1493
			results.splice( duplicates[ j ], 1 );
1494
		}
1495
	}
1496

    
1497
	// Clear input after sorting to release objects
1498
	// See https://github.com/jquery/sizzle/pull/225
1499
	sortInput = null;
1500

    
1501
	return results;
1502
};
1503

    
1504
/**
1505
 * Utility function for retrieving the text value of an array of DOM nodes
1506
 * @param {Array|Element} elem
1507
 */
1508
getText = Sizzle.getText = function( elem ) {
1509
	var node,
1510
		ret = "",
1511
		i = 0,
1512
		nodeType = elem.nodeType;
1513

    
1514
	if ( !nodeType ) {
1515
		// If no nodeType, this is expected to be an array
1516
		while ( (node = elem[i++]) ) {
1517
			// Do not traverse comment nodes
1518
			ret += getText( node );
1519
		}
1520
	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1521
		// Use textContent for elements
1522
		// innerText usage removed for consistency of new lines (jQuery #11153)
1523
		if ( typeof elem.textContent === "string" ) {
1524
			return elem.textContent;
1525
		} else {
1526
			// Traverse its children
1527
			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1528
				ret += getText( elem );
1529
			}
1530
		}
1531
	} else if ( nodeType === 3 || nodeType === 4 ) {
1532
		return elem.nodeValue;
1533
	}
1534
	// Do not include comment or processing instruction nodes
1535

    
1536
	return ret;
1537
};
1538

    
1539
Expr = Sizzle.selectors = {
1540

    
1541
	// Can be adjusted by the user
1542
	cacheLength: 50,
1543

    
1544
	createPseudo: markFunction,
1545

    
1546
	match: matchExpr,
1547

    
1548
	attrHandle: {},
1549

    
1550
	find: {},
1551

    
1552
	relative: {
1553
		">": { dir: "parentNode", first: true },
1554
		" ": { dir: "parentNode" },
1555
		"+": { dir: "previousSibling", first: true },
1556
		"~": { dir: "previousSibling" }
1557
	},
1558

    
1559
	preFilter: {
1560
		"ATTR": function( match ) {
1561
			match[1] = match[1].replace( runescape, funescape );
1562

    
1563
			// Move the given value to match[3] whether quoted or unquoted
1564
			match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
1565

    
1566
			if ( match[2] === "~=" ) {
1567
				match[3] = " " + match[3] + " ";
1568
			}
1569

    
1570
			return match.slice( 0, 4 );
1571
		},
1572

    
1573
		"CHILD": function( match ) {
1574
			/* matches from matchExpr["CHILD"]
1575
				1 type (only|nth|...)
1576
				2 what (child|of-type)
1577
				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1578
				4 xn-component of xn+y argument ([+-]?\d*n|)
1579
				5 sign of xn-component
1580
				6 x of xn-component
1581
				7 sign of y-component
1582
				8 y of y-component
1583
			*/
1584
			match[1] = match[1].toLowerCase();
1585

    
1586
			if ( match[1].slice( 0, 3 ) === "nth" ) {
1587
				// nth-* requires argument
1588
				if ( !match[3] ) {
1589
					Sizzle.error( match[0] );
1590
				}
1591

    
1592
				// numeric x and y parameters for Expr.filter.CHILD
1593
				// remember that false/true cast respectively to 0/1
1594
				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
1595
				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
1596

    
1597
			// other types prohibit arguments
1598
			} else if ( match[3] ) {
1599
				Sizzle.error( match[0] );
1600
			}
1601

    
1602
			return match;
1603
		},
1604

    
1605
		"PSEUDO": function( match ) {
1606
			var excess,
1607
				unquoted = !match[6] && match[2];
1608

    
1609
			if ( matchExpr["CHILD"].test( match[0] ) ) {
1610
				return null;
1611
			}
1612

    
1613
			// Accept quoted arguments as-is
1614
			if ( match[3] ) {
1615
				match[2] = match[4] || match[5] || "";
1616

    
1617
			// Strip excess characters from unquoted arguments
1618
			} else if ( unquoted && rpseudo.test( unquoted ) &&
1619
				// Get excess from tokenize (recursively)
1620
				(excess = tokenize( unquoted, true )) &&
1621
				// advance to the next closing parenthesis
1622
				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
1623

    
1624
				// excess is a negative index
1625
				match[0] = match[0].slice( 0, excess );
1626
				match[2] = unquoted.slice( 0, excess );
1627
			}
1628

    
1629
			// Return only captures needed by the pseudo filter method (type and argument)
1630
			return match.slice( 0, 3 );
1631
		}
1632
	},
1633

    
1634
	filter: {
1635

    
1636
		"TAG": function( nodeNameSelector ) {
1637
			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1638
			return nodeNameSelector === "*" ?
1639
				function() { return true; } :
1640
				function( elem ) {
1641
					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1642
				};
1643
		},
1644

    
1645
		"CLASS": function( className ) {
1646
			var pattern = classCache[ className + " " ];
1647

    
1648
			return pattern ||
1649
				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
1650
				classCache( className, function( elem ) {
1651
					return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
1652
				});
1653
		},
1654

    
1655
		"ATTR": function( name, operator, check ) {
1656
			return function( elem ) {
1657
				var result = Sizzle.attr( elem, name );
1658

    
1659
				if ( result == null ) {
1660
					return operator === "!=";
1661
				}
1662
				if ( !operator ) {
1663
					return true;
1664
				}
1665

    
1666
				result += "";
1667

    
1668
				return operator === "=" ? result === check :
1669
					operator === "!=" ? result !== check :
1670
					operator === "^=" ? check && result.indexOf( check ) === 0 :
1671
					operator === "*=" ? check && result.indexOf( check ) > -1 :
1672
					operator === "$=" ? check && result.slice( -check.length ) === check :
1673
					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
1674
					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1675
					false;
1676
			};
1677
		},
1678

    
1679
		"CHILD": function( type, what, argument, first, last ) {
1680
			var simple = type.slice( 0, 3 ) !== "nth",
1681
				forward = type.slice( -4 ) !== "last",
1682
				ofType = what === "of-type";
1683

    
1684
			return first === 1 && last === 0 ?
1685

    
1686
				// Shortcut for :nth-*(n)
1687
				function( elem ) {
1688
					return !!elem.parentNode;
1689
				} :
1690

    
1691
				function( elem, context, xml ) {
1692
					var cache, uniqueCache, outerCache, node, nodeIndex, start,
1693
						dir = simple !== forward ? "nextSibling" : "previousSibling",
1694
						parent = elem.parentNode,
1695
						name = ofType && elem.nodeName.toLowerCase(),
1696
						useCache = !xml && !ofType,
1697
						diff = false;
1698

    
1699
					if ( parent ) {
1700

    
1701
						// :(first|last|only)-(child|of-type)
1702
						if ( simple ) {
1703
							while ( dir ) {
1704
								node = elem;
1705
								while ( (node = node[ dir ]) ) {
1706
									if ( ofType ?
1707
										node.nodeName.toLowerCase() === name :
1708
										node.nodeType === 1 ) {
1709

    
1710
										return false;
1711
									}
1712
								}
1713
								// Reverse direction for :only-* (if we haven't yet done so)
1714
								start = dir = type === "only" && !start && "nextSibling";
1715
							}
1716
							return true;
1717
						}
1718

    
1719
						start = [ forward ? parent.firstChild : parent.lastChild ];
1720

    
1721
						// non-xml :nth-child(...) stores cache data on `parent`
1722
						if ( forward && useCache ) {
1723

    
1724
							// Seek `elem` from a previously-cached index
1725

    
1726
							// ...in a gzip-friendly way
1727
							node = parent;
1728
							outerCache = node[ expando ] || (node[ expando ] = {});
1729

    
1730
							// Support: IE <9 only
1731
							// Defend against cloned attroperties (jQuery gh-1709)
1732
							uniqueCache = outerCache[ node.uniqueID ] ||
1733
								(outerCache[ node.uniqueID ] = {});
1734

    
1735
							cache = uniqueCache[ type ] || [];
1736
							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1737
							diff = nodeIndex && cache[ 2 ];
1738
							node = nodeIndex && parent.childNodes[ nodeIndex ];
1739

    
1740
							while ( (node = ++nodeIndex && node && node[ dir ] ||
1741

    
1742
								// Fallback to seeking `elem` from the start
1743
								(diff = nodeIndex = 0) || start.pop()) ) {
1744

    
1745
								// When found, cache indexes on `parent` and break
1746
								if ( node.nodeType === 1 && ++diff && node === elem ) {
1747
									uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
1748
									break;
1749
								}
1750
							}
1751

    
1752
						} else {
1753
							// Use previously-cached element index if available
1754
							if ( useCache ) {
1755
								// ...in a gzip-friendly way
1756
								node = elem;
1757
								outerCache = node[ expando ] || (node[ expando ] = {});
1758

    
1759
								// Support: IE <9 only
1760
								// Defend against cloned attroperties (jQuery gh-1709)
1761
								uniqueCache = outerCache[ node.uniqueID ] ||
1762
									(outerCache[ node.uniqueID ] = {});
1763

    
1764
								cache = uniqueCache[ type ] || [];
1765
								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1766
								diff = nodeIndex;
1767
							}
1768

    
1769
							// xml :nth-child(...)
1770
							// or :nth-last-child(...) or :nth(-last)?-of-type(...)
1771
							if ( diff === false ) {
1772
								// Use the same loop as above to seek `elem` from the start
1773
								while ( (node = ++nodeIndex && node && node[ dir ] ||
1774
									(diff = nodeIndex = 0) || start.pop()) ) {
1775

    
1776
									if ( ( ofType ?
1777
										node.nodeName.toLowerCase() === name :
1778
										node.nodeType === 1 ) &&
1779
										++diff ) {
1780

    
1781
										// Cache the index of each encountered element
1782
										if ( useCache ) {
1783
											outerCache = node[ expando ] || (node[ expando ] = {});
1784

    
1785
											// Support: IE <9 only
1786
											// Defend against cloned attroperties (jQuery gh-1709)
1787
											uniqueCache = outerCache[ node.uniqueID ] ||
1788
												(outerCache[ node.uniqueID ] = {});
1789

    
1790
											uniqueCache[ type ] = [ dirruns, diff ];
1791
										}
1792

    
1793
										if ( node === elem ) {
1794
											break;
1795
										}
1796
									}
1797
								}
1798
							}
1799
						}
1800

    
1801
						// Incorporate the offset, then check against cycle size
1802
						diff -= last;
1803
						return diff === first || ( diff % first === 0 && diff / first >= 0 );
1804
					}
1805
				};
1806
		},
1807

    
1808
		"PSEUDO": function( pseudo, argument ) {
1809
			// pseudo-class names are case-insensitive
1810
			// http://www.w3.org/TR/selectors/#pseudo-classes
1811
			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1812
			// Remember that setFilters inherits from pseudos
1813
			var args,
1814
				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
1815
					Sizzle.error( "unsupported pseudo: " + pseudo );
1816

    
1817
			// The user may use createPseudo to indicate that
1818
			// arguments are needed to create the filter function
1819
			// just as Sizzle does
1820
			if ( fn[ expando ] ) {
1821
				return fn( argument );
1822
			}
1823

    
1824
			// But maintain support for old signatures
1825
			if ( fn.length > 1 ) {
1826
				args = [ pseudo, pseudo, "", argument ];
1827
				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
1828
					markFunction(function( seed, matches ) {
1829
						var idx,
1830
							matched = fn( seed, argument ),
1831
							i = matched.length;
1832
						while ( i-- ) {
1833
							idx = indexOf( seed, matched[i] );
1834
							seed[ idx ] = !( matches[ idx ] = matched[i] );
1835
						}
1836
					}) :
1837
					function( elem ) {
1838
						return fn( elem, 0, args );
1839
					};
1840
			}
1841

    
1842
			return fn;
1843
		}
1844
	},
1845

    
1846
	pseudos: {
1847
		// Potentially complex pseudos
1848
		"not": markFunction(function( selector ) {
1849
			// Trim the selector passed to compile
1850
			// to avoid treating leading and trailing
1851
			// spaces as combinators
1852
			var input = [],
1853
				results = [],
1854
				matcher = compile( selector.replace( rtrim, "$1" ) );
1855

    
1856
			return matcher[ expando ] ?
1857
				markFunction(function( seed, matches, context, xml ) {
1858
					var elem,
1859
						unmatched = matcher( seed, null, xml, [] ),
1860
						i = seed.length;
1861

    
1862
					// Match elements unmatched by `matcher`
1863
					while ( i-- ) {
1864
						if ( (elem = unmatched[i]) ) {
1865
							seed[i] = !(matches[i] = elem);
1866
						}
1867
					}
1868
				}) :
1869
				function( elem, context, xml ) {
1870
					input[0] = elem;
1871
					matcher( input, null, xml, results );
1872
					// Don't keep the element (issue #299)
1873
					input[0] = null;
1874
					return !results.pop();
1875
				};
1876
		}),
1877

    
1878
		"has": markFunction(function( selector ) {
1879
			return function( elem ) {
1880
				return Sizzle( selector, elem ).length > 0;
1881
			};
1882
		}),
1883

    
1884
		"contains": markFunction(function( text ) {
1885
			text = text.replace( runescape, funescape );
1886
			return function( elem ) {
1887
				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
1888
			};
1889
		}),
1890

    
1891
		// "Whether an element is represented by a :lang() selector
1892
		// is based solely on the element's language value
1893
		// being equal to the identifier C,
1894
		// or beginning with the identifier C immediately followed by "-".
1895
		// The matching of C against the element's language value is performed case-insensitively.
1896
		// The identifier C does not have to be a valid language name."
1897
		// http://www.w3.org/TR/selectors/#lang-pseudo
1898
		"lang": markFunction( function( lang ) {
1899
			// lang value must be a valid identifier
1900
			if ( !ridentifier.test(lang || "") ) {
1901
				Sizzle.error( "unsupported lang: " + lang );
1902
			}
1903
			lang = lang.replace( runescape, funescape ).toLowerCase();
1904
			return function( elem ) {
1905
				var elemLang;
1906
				do {
1907
					if ( (elemLang = documentIsHTML ?
1908
						elem.lang :
1909
						elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
1910

    
1911
						elemLang = elemLang.toLowerCase();
1912
						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
1913
					}
1914
				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
1915
				return false;
1916
			};
1917
		}),
1918

    
1919
		// Miscellaneous
1920
		"target": function( elem ) {
1921
			var hash = window.location && window.location.hash;
1922
			return hash && hash.slice( 1 ) === elem.id;
1923
		},
1924

    
1925
		"root": function( elem ) {
1926
			return elem === docElem;
1927
		},
1928

    
1929
		"focus": function( elem ) {
1930
			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
1931
		},
1932

    
1933
		// Boolean properties
1934
		"enabled": function( elem ) {
1935
			return elem.disabled === false;
1936
		},
1937

    
1938
		"disabled": function( elem ) {
1939
			return elem.disabled === true;
1940
		},
1941

    
1942
		"checked": function( elem ) {
1943
			// In CSS3, :checked should return both checked and selected elements
1944
			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1945
			var nodeName = elem.nodeName.toLowerCase();
1946
			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
1947
		},
1948

    
1949
		"selected": function( elem ) {
1950
			// Accessing this property makes selected-by-default
1951
			// options in Safari work properly
1952
			if ( elem.parentNode ) {
1953
				elem.parentNode.selectedIndex;
1954
			}
1955

    
1956
			return elem.selected === true;
1957
		},
1958

    
1959
		// Contents
1960
		"empty": function( elem ) {
1961
			// http://www.w3.org/TR/selectors/#empty-pseudo
1962
			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
1963
			//   but not by others (comment: 8; processing instruction: 7; etc.)
1964
			// nodeType < 6 works because attributes (2) do not appear as children
1965
			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1966
				if ( elem.nodeType < 6 ) {
1967
					return false;
1968
				}
1969
			}
1970
			return true;
1971
		},
1972

    
1973
		"parent": function( elem ) {
1974
			return !Expr.pseudos["empty"]( elem );
1975
		},
1976

    
1977
		// Element/input types
1978
		"header": function( elem ) {
1979
			return rheader.test( elem.nodeName );
1980
		},
1981

    
1982
		"input": function( elem ) {
1983
			return rinputs.test( elem.nodeName );
1984
		},
1985

    
1986
		"button": function( elem ) {
1987
			var name = elem.nodeName.toLowerCase();
1988
			return name === "input" && elem.type === "button" || name === "button";
1989
		},
1990

    
1991
		"text": function( elem ) {
1992
			var attr;
1993
			return elem.nodeName.toLowerCase() === "input" &&
1994
				elem.type === "text" &&
1995

    
1996
				// Support: IE<8
1997
				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
1998
				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
1999
		},
2000

    
2001
		// Position-in-collection
2002
		"first": createPositionalPseudo(function() {
2003
			return [ 0 ];
2004
		}),
2005

    
2006
		"last": createPositionalPseudo(function( matchIndexes, length ) {
2007
			return [ length - 1 ];
2008
		}),
2009

    
2010
		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
2011
			return [ argument < 0 ? argument + length : argument ];
2012
		}),
2013

    
2014
		"even": createPositionalPseudo(function( matchIndexes, length ) {
2015
			var i = 0;
2016
			for ( ; i < length; i += 2 ) {
2017
				matchIndexes.push( i );
2018
			}
2019
			return matchIndexes;
2020
		}),
2021

    
2022
		"odd": createPositionalPseudo(function( matchIndexes, length ) {
2023
			var i = 1;
2024
			for ( ; i < length; i += 2 ) {
2025
				matchIndexes.push( i );
2026
			}
2027
			return matchIndexes;
2028
		}),
2029

    
2030
		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2031
			var i = argument < 0 ? argument + length : argument;
2032
			for ( ; --i >= 0; ) {
2033
				matchIndexes.push( i );
2034
			}
2035
			return matchIndexes;
2036
		}),
2037

    
2038
		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2039
			var i = argument < 0 ? argument + length : argument;
2040
			for ( ; ++i < length; ) {
2041
				matchIndexes.push( i );
2042
			}
2043
			return matchIndexes;
2044
		})
2045
	}
2046
};
2047

    
2048
Expr.pseudos["nth"] = Expr.pseudos["eq"];
2049

    
2050
// Add button/input type pseudos
2051
for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2052
	Expr.pseudos[ i ] = createInputPseudo( i );
2053
}
2054
for ( i in { submit: true, reset: true } ) {
2055
	Expr.pseudos[ i ] = createButtonPseudo( i );
2056
}
2057

    
2058
// Easy API for creating new setFilters
2059
function setFilters() {}
2060
setFilters.prototype = Expr.filters = Expr.pseudos;
2061
Expr.setFilters = new setFilters();
2062

    
2063
tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
2064
	var matched, match, tokens, type,
2065
		soFar, groups, preFilters,
2066
		cached = tokenCache[ selector + " " ];
2067

    
2068
	if ( cached ) {
2069
		return parseOnly ? 0 : cached.slice( 0 );
2070
	}
2071

    
2072
	soFar = selector;
2073
	groups = [];
2074
	preFilters = Expr.preFilter;
2075

    
2076
	while ( soFar ) {
2077

    
2078
		// Comma and first run
2079
		if ( !matched || (match = rcomma.exec( soFar )) ) {
2080
			if ( match ) {
2081
				// Don't consume trailing commas as valid
2082
				soFar = soFar.slice( match[0].length ) || soFar;
2083
			}
2084
			groups.push( (tokens = []) );
2085
		}
2086

    
2087
		matched = false;
2088

    
2089
		// Combinators
2090
		if ( (match = rcombinators.exec( soFar )) ) {
2091
			matched = match.shift();
2092
			tokens.push({
2093
				value: matched,
2094
				// Cast descendant combinators to space
2095
				type: match[0].replace( rtrim, " " )
2096
			});
2097
			soFar = soFar.slice( matched.length );
2098
		}
2099

    
2100
		// Filters
2101
		for ( type in Expr.filter ) {
2102
			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
2103
				(match = preFilters[ type ]( match ))) ) {
2104
				matched = match.shift();
2105
				tokens.push({
2106
					value: matched,
2107
					type: type,
2108
					matches: match
2109
				});
2110
				soFar = soFar.slice( matched.length );
2111
			}
2112
		}
2113

    
2114
		if ( !matched ) {
2115
			break;
2116
		}
2117
	}
2118

    
2119
	// Return the length of the invalid excess
2120
	// if we're just parsing
2121
	// Otherwise, throw an error or return tokens
2122
	return parseOnly ?
2123
		soFar.length :
2124
		soFar ?
2125
			Sizzle.error( selector ) :
2126
			// Cache the tokens
2127
			tokenCache( selector, groups ).slice( 0 );
2128
};
2129

    
2130
function toSelector( tokens ) {
2131
	var i = 0,
2132
		len = tokens.length,
2133
		selector = "";
2134
	for ( ; i < len; i++ ) {
2135
		selector += tokens[i].value;
2136
	}
2137
	return selector;
2138
}
2139

    
2140
function addCombinator( matcher, combinator, base ) {
2141
	var dir = combinator.dir,
2142
		checkNonElements = base && dir === "parentNode",
2143
		doneName = done++;
2144

    
2145
	return combinator.first ?
2146
		// Check against closest ancestor/preceding element
2147
		function( elem, context, xml ) {
2148
			while ( (elem = elem[ dir ]) ) {
2149
				if ( elem.nodeType === 1 || checkNonElements ) {
2150
					return matcher( elem, context, xml );
2151
				}
2152
			}
2153
		} :
2154

    
2155
		// Check against all ancestor/preceding elements
2156
		function( elem, context, xml ) {
2157
			var oldCache, uniqueCache, outerCache,
2158
				newCache = [ dirruns, doneName ];
2159

    
2160
			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
2161
			if ( xml ) {
2162
				while ( (elem = elem[ dir ]) ) {
2163
					if ( elem.nodeType === 1 || checkNonElements ) {
2164
						if ( matcher( elem, context, xml ) ) {
2165
							return true;
2166
						}
2167
					}
2168
				}
2169
			} else {
2170
				while ( (elem = elem[ dir ]) ) {
2171
					if ( elem.nodeType === 1 || checkNonElements ) {
2172
						outerCache = elem[ expando ] || (elem[ expando ] = {});
2173

    
2174
						// Support: IE <9 only
2175
						// Defend against cloned attroperties (jQuery gh-1709)
2176
						uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
2177

    
2178
						if ( (oldCache = uniqueCache[ dir ]) &&
2179
							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2180

    
2181
							// Assign to newCache so results back-propagate to previous elements
2182
							return (newCache[ 2 ] = oldCache[ 2 ]);
2183
						} else {
2184
							// Reuse newcache so results back-propagate to previous elements
2185
							uniqueCache[ dir ] = newCache;
2186

    
2187
							// A match means we're done; a fail means we have to keep checking
2188
							if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
2189
								return true;
2190
							}
2191
						}
2192
					}
2193
				}
2194
			}
2195
		};
2196
}
2197

    
2198
function elementMatcher( matchers ) {
2199
	return matchers.length > 1 ?
2200
		function( elem, context, xml ) {
2201
			var i = matchers.length;
2202
			while ( i-- ) {
2203
				if ( !matchers[i]( elem, context, xml ) ) {
2204
					return false;
2205
				}
2206
			}
2207
			return true;
2208
		} :
2209
		matchers[0];
2210
}
2211

    
2212
function multipleContexts( selector, contexts, results ) {
2213
	var i = 0,
2214
		len = contexts.length;
2215
	for ( ; i < len; i++ ) {
2216
		Sizzle( selector, contexts[i], results );
2217
	}
2218
	return results;
2219
}
2220

    
2221
function condense( unmatched, map, filter, context, xml ) {
2222
	var elem,
2223
		newUnmatched = [],
2224
		i = 0,
2225
		len = unmatched.length,
2226
		mapped = map != null;
2227

    
2228
	for ( ; i < len; i++ ) {
2229
		if ( (elem = unmatched[i]) ) {
2230
			if ( !filter || filter( elem, context, xml ) ) {
2231
				newUnmatched.push( elem );
2232
				if ( mapped ) {
2233
					map.push( i );
2234
				}
2235
			}
2236
		}
2237
	}
2238

    
2239
	return newUnmatched;
2240
}
2241

    
2242
function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2243
	if ( postFilter && !postFilter[ expando ] ) {
2244
		postFilter = setMatcher( postFilter );
2245
	}
2246
	if ( postFinder && !postFinder[ expando ] ) {
2247
		postFinder = setMatcher( postFinder, postSelector );
2248
	}
2249
	return markFunction(function( seed, results, context, xml ) {
2250
		var temp, i, elem,
2251
			preMap = [],
2252
			postMap = [],
2253
			preexisting = results.length,
2254

    
2255
			// Get initial elements from seed or context
2256
			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
2257

    
2258
			// Prefilter to get matcher input, preserving a map for seed-results synchronization
2259
			matcherIn = preFilter && ( seed || !selector ) ?
2260
				condense( elems, preMap, preFilter, context, xml ) :
2261
				elems,
2262

    
2263
			matcherOut = matcher ?
2264
				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2265
				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2266

    
2267
					// ...intermediate processing is necessary
2268
					[] :
2269

    
2270
					// ...otherwise use results directly
2271
					results :
2272
				matcherIn;
2273

    
2274
		// Find primary matches
2275
		if ( matcher ) {
2276
			matcher( matcherIn, matcherOut, context, xml );
2277
		}
2278

    
2279
		// Apply postFilter
2280
		if ( postFilter ) {
2281
			temp = condense( matcherOut, postMap );
2282
			postFilter( temp, [], context, xml );
2283

    
2284
			// Un-match failing elements by moving them back to matcherIn
2285
			i = temp.length;
2286
			while ( i-- ) {
2287
				if ( (elem = temp[i]) ) {
2288
					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
2289
				}
2290
			}
2291
		}
2292

    
2293
		if ( seed ) {
2294
			if ( postFinder || preFilter ) {
2295
				if ( postFinder ) {
2296
					// Get the final matcherOut by condensing this intermediate into postFinder contexts
2297
					temp = [];
2298
					i = matcherOut.length;
2299
					while ( i-- ) {
2300
						if ( (elem = matcherOut[i]) ) {
2301
							// Restore matcherIn since elem is not yet a final match
2302
							temp.push( (matcherIn[i] = elem) );
2303
						}
2304
					}
2305
					postFinder( null, (matcherOut = []), temp, xml );
2306
				}
2307

    
2308
				// Move matched elements from seed to results to keep them synchronized
2309
				i = matcherOut.length;
2310
				while ( i-- ) {
2311
					if ( (elem = matcherOut[i]) &&
2312
						(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
2313

    
2314
						seed[temp] = !(results[temp] = elem);
2315
					}
2316
				}
2317
			}
2318

    
2319
		// Add elements to results, through postFinder if defined
2320
		} else {
2321
			matcherOut = condense(
2322
				matcherOut === results ?
2323
					matcherOut.splice( preexisting, matcherOut.length ) :
2324
					matcherOut
2325
			);
2326
			if ( postFinder ) {
2327
				postFinder( null, results, matcherOut, xml );
2328
			} else {
2329
				push.apply( results, matcherOut );
2330
			}
2331
		}
2332
	});
2333
}
2334

    
2335
function matcherFromTokens( tokens ) {
2336
	var checkContext, matcher, j,
2337
		len = tokens.length,
2338
		leadingRelative = Expr.relative[ tokens[0].type ],
2339
		implicitRelative = leadingRelative || Expr.relative[" "],
2340
		i = leadingRelative ? 1 : 0,
2341

    
2342
		// The foundational matcher ensures that elements are reachable from top-level context(s)
2343
		matchContext = addCombinator( function( elem ) {
2344
			return elem === checkContext;
2345
		}, implicitRelative, true ),
2346
		matchAnyContext = addCombinator( function( elem ) {
2347
			return indexOf( checkContext, elem ) > -1;
2348
		}, implicitRelative, true ),
2349
		matchers = [ function( elem, context, xml ) {
2350
			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2351
				(checkContext = context).nodeType ?
2352
					matchContext( elem, context, xml ) :
2353
					matchAnyContext( elem, context, xml ) );
2354
			// Avoid hanging onto element (issue #299)
2355
			checkContext = null;
2356
			return ret;
2357
		} ];
2358

    
2359
	for ( ; i < len; i++ ) {
2360
		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
2361
			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
2362
		} else {
2363
			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
2364

    
2365
			// Return special upon seeing a positional matcher
2366
			if ( matcher[ expando ] ) {
2367
				// Find the next relative operator (if any) for proper handling
2368
				j = ++i;
2369
				for ( ; j < len; j++ ) {
2370
					if ( Expr.relative[ tokens[j].type ] ) {
2371
						break;
2372
					}
2373
				}
2374
				return setMatcher(
2375
					i > 1 && elementMatcher( matchers ),
2376
					i > 1 && toSelector(
2377
						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
2378
						tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
2379
					).replace( rtrim, "$1" ),
2380
					matcher,
2381
					i < j && matcherFromTokens( tokens.slice( i, j ) ),
2382
					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
2383
					j < len && toSelector( tokens )
2384
				);
2385
			}
2386
			matchers.push( matcher );
2387
		}
2388
	}
2389

    
2390
	return elementMatcher( matchers );
2391
}
2392

    
2393
function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2394
	var bySet = setMatchers.length > 0,
2395
		byElement = elementMatchers.length > 0,
2396
		superMatcher = function( seed, context, xml, results, outermost ) {
2397
			var elem, j, matcher,
2398
				matchedCount = 0,
2399
				i = "0",
2400
				unmatched = seed && [],
2401
				setMatched = [],
2402
				contextBackup = outermostContext,
2403
				// We must always have either seed elements or outermost context
2404
				elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
2405
				// Use integer dirruns iff this is the outermost matcher
2406
				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
2407
				len = elems.length;
2408

    
2409
			if ( outermost ) {
2410
				outermostContext = context === document || context || outermost;
2411
			}
2412

    
2413
			// Add elements passing elementMatchers directly to results
2414
			// Support: IE<9, Safari
2415
			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2416
			for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
2417
				if ( byElement && elem ) {
2418
					j = 0;
2419
					if ( !context && elem.ownerDocument !== document ) {
2420
						setDocument( elem );
2421
						xml = !documentIsHTML;
2422
					}
2423
					while ( (matcher = elementMatchers[j++]) ) {
2424
						if ( matcher( elem, context || document, xml) ) {
2425
							results.push( elem );
2426
							break;
2427
						}
2428
					}
2429
					if ( outermost ) {
2430
						dirruns = dirrunsUnique;
2431
					}
2432
				}
2433

    
2434
				// Track unmatched elements for set filters
2435
				if ( bySet ) {
2436
					// They will have gone through all possible matchers
2437
					if ( (elem = !matcher && elem) ) {
2438
						matchedCount--;
2439
					}
2440

    
2441
					// Lengthen the array for every element, matched or not
2442
					if ( seed ) {
2443
						unmatched.push( elem );
2444
					}
2445
				}
2446
			}
2447

    
2448
			// `i` is now the count of elements visited above, and adding it to `matchedCount`
2449
			// makes the latter nonnegative.
2450
			matchedCount += i;
2451

    
2452
			// Apply set filters to unmatched elements
2453
			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
2454
			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
2455
			// no element matchers and no seed.
2456
			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
2457
			// case, which will result in a "00" `matchedCount` that differs from `i` but is also
2458
			// numerically zero.
2459
			if ( bySet && i !== matchedCount ) {
2460
				j = 0;
2461
				while ( (matcher = setMatchers[j++]) ) {
2462
					matcher( unmatched, setMatched, context, xml );
2463
				}
2464

    
2465
				if ( seed ) {
2466
					// Reintegrate element matches to eliminate the need for sorting
2467
					if ( matchedCount > 0 ) {
2468
						while ( i-- ) {
2469
							if ( !(unmatched[i] || setMatched[i]) ) {
2470
								setMatched[i] = pop.call( results );
2471
							}
2472
						}
2473
					}
2474

    
2475
					// Discard index placeholder values to get only actual matches
2476
					setMatched = condense( setMatched );
2477
				}
2478

    
2479
				// Add matches to results
2480
				push.apply( results, setMatched );
2481

    
2482
				// Seedless set matches succeeding multiple successful matchers stipulate sorting
2483
				if ( outermost && !seed && setMatched.length > 0 &&
2484
					( matchedCount + setMatchers.length ) > 1 ) {
2485

    
2486
					Sizzle.uniqueSort( results );
2487
				}
2488
			}
2489

    
2490
			// Override manipulation of globals by nested matchers
2491
			if ( outermost ) {
2492
				dirruns = dirrunsUnique;
2493
				outermostContext = contextBackup;
2494
			}
2495

    
2496
			return unmatched;
2497
		};
2498

    
2499
	return bySet ?
2500
		markFunction( superMatcher ) :
2501
		superMatcher;
2502
}
2503

    
2504
compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
2505
	var i,
2506
		setMatchers = [],
2507
		elementMatchers = [],
2508
		cached = compilerCache[ selector + " " ];
2509

    
2510
	if ( !cached ) {
2511
		// Generate a function of recursive functions that can be used to check each element
2512
		if ( !match ) {
2513
			match = tokenize( selector );
2514
		}
2515
		i = match.length;
2516
		while ( i-- ) {
2517
			cached = matcherFromTokens( match[i] );
2518
			if ( cached[ expando ] ) {
2519
				setMatchers.push( cached );
2520
			} else {
2521
				elementMatchers.push( cached );
2522
			}
2523
		}
2524

    
2525
		// Cache the compiled function
2526
		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
2527

    
2528
		// Save selector and tokenization
2529
		cached.selector = selector;
2530
	}
2531
	return cached;
2532
};
2533

    
2534
/**
2535
 * A low-level selection function that works with Sizzle's compiled
2536
 *  selector functions
2537
 * @param {String|Function} selector A selector or a pre-compiled
2538
 *  selector function built with Sizzle.compile
2539
 * @param {Element} context
2540
 * @param {Array} [results]
2541
 * @param {Array} [seed] A set of elements to match against
2542
 */
2543
select = Sizzle.select = function( selector, context, results, seed ) {
2544
	var i, tokens, token, type, find,
2545
		compiled = typeof selector === "function" && selector,
2546
		match = !seed && tokenize( (selector = compiled.selector || selector) );
2547

    
2548
	results = results || [];
2549

    
2550
	// Try to minimize operations if there is only one selector in the list and no seed
2551
	// (the latter of which guarantees us context)
2552
	if ( match.length === 1 ) {
2553

    
2554
		// Reduce context if the leading compound selector is an ID
2555
		tokens = match[0] = match[0].slice( 0 );
2556
		if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
2557
				support.getById && context.nodeType === 9 && documentIsHTML &&
2558
				Expr.relative[ tokens[1].type ] ) {
2559

    
2560
			context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
2561
			if ( !context ) {
2562
				return results;
2563

    
2564
			// Precompiled matchers will still verify ancestry, so step up a level
2565
			} else if ( compiled ) {
2566
				context = context.parentNode;
2567
			}
2568

    
2569
			selector = selector.slice( tokens.shift().value.length );
2570
		}
2571

    
2572
		// Fetch a seed set for right-to-left matching
2573
		i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
2574
		while ( i-- ) {
2575
			token = tokens[i];
2576

    
2577
			// Abort if we hit a combinator
2578
			if ( Expr.relative[ (type = token.type) ] ) {
2579
				break;
2580
			}
2581
			if ( (find = Expr.find[ type ]) ) {
2582
				// Search, expanding context for leading sibling combinators
2583
				if ( (seed = find(
2584
					token.matches[0].replace( runescape, funescape ),
2585
					rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
2586
				)) ) {
2587

    
2588
					// If seed is empty or no tokens remain, we can return early
2589
					tokens.splice( i, 1 );
2590
					selector = seed.length && toSelector( tokens );
2591
					if ( !selector ) {
2592
						push.apply( results, seed );
2593
						return results;
2594
					}
2595

    
2596
					break;
2597
				}
2598
			}
2599
		}
2600
	}
2601

    
2602
	// Compile and execute a filtering function if one is not provided
2603
	// Provide `match` to avoid retokenization if we modified the selector above
2604
	( compiled || compile( selector, match ) )(
2605
		seed,
2606
		context,
2607
		!documentIsHTML,
2608
		results,
2609
		!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
2610
	);
2611
	return results;
2612
};
2613

    
2614
// One-time assignments
2615

    
2616
// Sort stability
2617
support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
2618

    
2619
// Support: Chrome 14-35+
2620
// Always assume duplicates if they aren't passed to the comparison function
2621
support.detectDuplicates = !!hasDuplicate;
2622

    
2623
// Initialize against the default document
2624
setDocument();
2625

    
2626
// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2627
// Detached nodes confoundingly follow *each other*
2628
support.sortDetached = assert(function( div1 ) {
2629
	// Should return 1, but returns 4 (following)
2630
	return div1.compareDocumentPosition( document.createElement("div") ) & 1;
2631
});
2632

    
2633
// Support: IE<8
2634
// Prevent attribute/property "interpolation"
2635
// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2636
if ( !assert(function( div ) {
2637
	div.innerHTML = "<a href='#'></a>";
2638
	return div.firstChild.getAttribute("href") === "#" ;
2639
}) ) {
2640
	addHandle( "type|href|height|width", function( elem, name, isXML ) {
2641
		if ( !isXML ) {
2642
			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
2643
		}
2644
	});
2645
}
2646

    
2647
// Support: IE<9
2648
// Use defaultValue in place of getAttribute("value")
2649
if ( !support.attributes || !assert(function( div ) {
2650
	div.innerHTML = "<input/>";
2651
	div.firstChild.setAttribute( "value", "" );
2652
	return div.firstChild.getAttribute( "value" ) === "";
2653
}) ) {
2654
	addHandle( "value", function( elem, name, isXML ) {
2655
		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
2656
			return elem.defaultValue;
2657
		}
2658
	});
2659
}
2660

    
2661
// Support: IE<9
2662
// Use getAttributeNode to fetch booleans when getAttribute lies
2663
if ( !assert(function( div ) {
2664
	return div.getAttribute("disabled") == null;
2665
}) ) {
2666
	addHandle( booleans, function( elem, name, isXML ) {
2667
		var val;
2668
		if ( !isXML ) {
2669
			return elem[ name ] === true ? name.toLowerCase() :
2670
					(val = elem.getAttributeNode( name )) && val.specified ?
2671
					val.value :
2672
				null;
2673
		}
2674
	});
2675
}
2676

    
2677
return Sizzle;
2678

    
2679
})( window );
2680

    
2681

    
2682

    
2683
jQuery.find = Sizzle;
2684
jQuery.expr = Sizzle.selectors;
2685
jQuery.expr[ ":" ] = jQuery.expr.pseudos;
2686
jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
2687
jQuery.text = Sizzle.getText;
2688
jQuery.isXMLDoc = Sizzle.isXML;
2689
jQuery.contains = Sizzle.contains;
2690

    
2691

    
2692

    
2693
var dir = function( elem, dir, until ) {
2694
	var matched = [],
2695
		truncate = until !== undefined;
2696

    
2697
	while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
2698
		if ( elem.nodeType === 1 ) {
2699
			if ( truncate && jQuery( elem ).is( until ) ) {
2700
				break;
2701
			}
2702
			matched.push( elem );
2703
		}
2704
	}
2705
	return matched;
2706
};
2707

    
2708

    
2709
var siblings = function( n, elem ) {
2710
	var matched = [];
2711

    
2712
	for ( ; n; n = n.nextSibling ) {
2713
		if ( n.nodeType === 1 && n !== elem ) {
2714
			matched.push( n );
2715
		}
2716
	}
2717

    
2718
	return matched;
2719
};
2720

    
2721

    
2722
var rneedsContext = jQuery.expr.match.needsContext;
2723

    
2724
var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );
2725

    
2726

    
2727

    
2728
var risSimple = /^.[^:#\[\.,]*$/;
2729

    
2730
// Implement the identical functionality for filter and not
2731
function winnow( elements, qualifier, not ) {
2732
	if ( jQuery.isFunction( qualifier ) ) {
2733
		return jQuery.grep( elements, function( elem, i ) {
2734
			/* jshint -W018 */
2735
			return !!qualifier.call( elem, i, elem ) !== not;
2736
		} );
2737

    
2738
	}
2739

    
2740
	if ( qualifier.nodeType ) {
2741
		return jQuery.grep( elements, function( elem ) {
2742
			return ( elem === qualifier ) !== not;
2743
		} );
2744

    
2745
	}
2746

    
2747
	if ( typeof qualifier === "string" ) {
2748
		if ( risSimple.test( qualifier ) ) {
2749
			return jQuery.filter( qualifier, elements, not );
2750
		}
2751

    
2752
		qualifier = jQuery.filter( qualifier, elements );
2753
	}
2754

    
2755
	return jQuery.grep( elements, function( elem ) {
2756
		return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
2757
	} );
2758
}
2759

    
2760
jQuery.filter = function( expr, elems, not ) {
2761
	var elem = elems[ 0 ];
2762

    
2763
	if ( not ) {
2764
		expr = ":not(" + expr + ")";
2765
	}
2766

    
2767
	return elems.length === 1 && elem.nodeType === 1 ?
2768
		jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
2769
		jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
2770
			return elem.nodeType === 1;
2771
		} ) );
2772
};
2773

    
2774
jQuery.fn.extend( {
2775
	find: function( selector ) {
2776
		var i,
2777
			len = this.length,
2778
			ret = [],
2779
			self = this;
2780

    
2781
		if ( typeof selector !== "string" ) {
2782
			return this.pushStack( jQuery( selector ).filter( function() {
2783
				for ( i = 0; i < len; i++ ) {
2784
					if ( jQuery.contains( self[ i ], this ) ) {
2785
						return true;
2786
					}
2787
				}
2788
			} ) );
2789
		}
2790

    
2791
		for ( i = 0; i < len; i++ ) {
2792
			jQuery.find( selector, self[ i ], ret );
2793
		}
2794

    
2795
		// Needed because $( selector, context ) becomes $( context ).find( selector )
2796
		ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
2797
		ret.selector = this.selector ? this.selector + " " + selector : selector;
2798
		return ret;
2799
	},
2800
	filter: function( selector ) {
2801
		return this.pushStack( winnow( this, selector || [], false ) );
2802
	},
2803
	not: function( selector ) {
2804
		return this.pushStack( winnow( this, selector || [], true ) );
2805
	},
2806
	is: function( selector ) {
2807
		return !!winnow(
2808
			this,
2809

    
2810
			// If this is a positional/relative selector, check membership in the returned set
2811
			// so $("p:first").is("p:last") won't return true for a doc with two "p".
2812
			typeof selector === "string" && rneedsContext.test( selector ) ?
2813
				jQuery( selector ) :
2814
				selector || [],
2815
			false
2816
		).length;
2817
	}
2818
} );
2819

    
2820

    
2821
// Initialize a jQuery object
2822

    
2823

    
2824
// A central reference to the root jQuery(document)
2825
var rootjQuery,
2826

    
2827
	// A simple way to check for HTML strings
2828
	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
2829
	// Strict HTML recognition (#11290: must start with <)
2830
	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
2831

    
2832
	init = jQuery.fn.init = function( selector, context, root ) {
2833
		var match, elem;
2834

    
2835
		// HANDLE: $(""), $(null), $(undefined), $(false)
2836
		if ( !selector ) {
2837
			return this;
2838
		}
2839

    
2840
		// Method init() accepts an alternate rootjQuery
2841
		// so migrate can support jQuery.sub (gh-2101)
2842
		root = root || rootjQuery;
2843

    
2844
		// Handle HTML strings
2845
		if ( typeof selector === "string" ) {
2846
			if ( selector[ 0 ] === "<" &&
2847
				selector[ selector.length - 1 ] === ">" &&
2848
				selector.length >= 3 ) {
2849

    
2850
				// Assume that strings that start and end with <> are HTML and skip the regex check
2851
				match = [ null, selector, null ];
2852

    
2853
			} else {
2854
				match = rquickExpr.exec( selector );
2855
			}
2856

    
2857
			// Match html or make sure no context is specified for #id
2858
			if ( match && ( match[ 1 ] || !context ) ) {
2859

    
2860
				// HANDLE: $(html) -> $(array)
2861
				if ( match[ 1 ] ) {
2862
					context = context instanceof jQuery ? context[ 0 ] : context;
2863

    
2864
					// Option to run scripts is true for back-compat
2865
					// Intentionally let the error be thrown if parseHTML is not present
2866
					jQuery.merge( this, jQuery.parseHTML(
2867
						match[ 1 ],
2868
						context && context.nodeType ? context.ownerDocument || context : document,
2869
						true
2870
					) );
2871

    
2872
					// HANDLE: $(html, props)
2873
					if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
2874
						for ( match in context ) {
2875

    
2876
							// Properties of context are called as methods if possible
2877
							if ( jQuery.isFunction( this[ match ] ) ) {
2878
								this[ match ]( context[ match ] );
2879

    
2880
							// ...and otherwise set as attributes
2881
							} else {
2882
								this.attr( match, context[ match ] );
2883
							}
2884
						}
2885
					}
2886

    
2887
					return this;
2888

    
2889
				// HANDLE: $(#id)
2890
				} else {
2891
					elem = document.getElementById( match[ 2 ] );
2892

    
2893
					// Support: Blackberry 4.6
2894
					// gEBID returns nodes no longer in the document (#6963)
2895
					if ( elem && elem.parentNode ) {
2896

    
2897
						// Inject the element directly into the jQuery object
2898
						this.length = 1;
2899
						this[ 0 ] = elem;
2900
					}
2901

    
2902
					this.context = document;
2903
					this.selector = selector;
2904
					return this;
2905
				}
2906

    
2907
			// HANDLE: $(expr, $(...))
2908
			} else if ( !context || context.jquery ) {
2909
				return ( context || root ).find( selector );
2910

    
2911
			// HANDLE: $(expr, context)
2912
			// (which is just equivalent to: $(context).find(expr)
2913
			} else {
2914
				return this.constructor( context ).find( selector );
2915
			}
2916

    
2917
		// HANDLE: $(DOMElement)
2918
		} else if ( selector.nodeType ) {
2919
			this.context = this[ 0 ] = selector;
2920
			this.length = 1;
2921
			return this;
2922

    
2923
		// HANDLE: $(function)
2924
		// Shortcut for document ready
2925
		} else if ( jQuery.isFunction( selector ) ) {
2926
			return root.ready !== undefined ?
2927
				root.ready( selector ) :
2928

    
2929
				// Execute immediately if ready is not present
2930
				selector( jQuery );
2931
		}
2932

    
2933
		if ( selector.selector !== undefined ) {
2934
			this.selector = selector.selector;
2935
			this.context = selector.context;
2936
		}
2937

    
2938
		return jQuery.makeArray( selector, this );
2939
	};
2940

    
2941
// Give the init function the jQuery prototype for later instantiation
2942
init.prototype = jQuery.fn;
2943

    
2944
// Initialize central reference
2945
rootjQuery = jQuery( document );
2946

    
2947

    
2948
var rparentsprev = /^(?:parents|prev(?:Until|All))/,
2949

    
2950
	// Methods guaranteed to produce a unique set when starting from a unique set
2951
	guaranteedUnique = {
2952
		children: true,
2953
		contents: true,
2954
		next: true,
2955
		prev: true
2956
	};
2957

    
2958
jQuery.fn.extend( {
2959
	has: function( target ) {
2960
		var targets = jQuery( target, this ),
2961
			l = targets.length;
2962

    
2963
		return this.filter( function() {
2964
			var i = 0;
2965
			for ( ; i < l; i++ ) {
2966
				if ( jQuery.contains( this, targets[ i ] ) ) {
2967
					return true;
2968
				}
2969
			}
2970
		} );
2971
	},
2972

    
2973
	closest: function( selectors, context ) {
2974
		var cur,
2975
			i = 0,
2976
			l = this.length,
2977
			matched = [],
2978
			pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
2979
				jQuery( selectors, context || this.context ) :
2980
				0;
2981

    
2982
		for ( ; i < l; i++ ) {
2983
			for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
2984

    
2985
				// Always skip document fragments
2986
				if ( cur.nodeType < 11 && ( pos ?
2987
					pos.index( cur ) > -1 :
2988

    
2989
					// Don't pass non-elements to Sizzle
2990
					cur.nodeType === 1 &&
2991
						jQuery.find.matchesSelector( cur, selectors ) ) ) {
2992

    
2993
					matched.push( cur );
2994
					break;
2995
				}
2996
			}
2997
		}
2998

    
2999
		return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
3000
	},
3001

    
3002
	// Determine the position of an element within the set
3003
	index: function( elem ) {
3004

    
3005
		// No argument, return index in parent
3006
		if ( !elem ) {
3007
			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
3008
		}
3009

    
3010
		// Index in selector
3011
		if ( typeof elem === "string" ) {
3012
			return indexOf.call( jQuery( elem ), this[ 0 ] );
3013
		}
3014

    
3015
		// Locate the position of the desired element
3016
		return indexOf.call( this,
3017

    
3018
			// If it receives a jQuery object, the first element is used
3019
			elem.jquery ? elem[ 0 ] : elem
3020
		);
3021
	},
3022

    
3023
	add: function( selector, context ) {
3024
		return this.pushStack(
3025
			jQuery.uniqueSort(
3026
				jQuery.merge( this.get(), jQuery( selector, context ) )
3027
			)
3028
		);
3029
	},
3030

    
3031
	addBack: function( selector ) {
3032
		return this.add( selector == null ?
3033
			this.prevObject : this.prevObject.filter( selector )
3034
		);
3035
	}
3036
} );
3037

    
3038
function sibling( cur, dir ) {
3039
	while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
3040
	return cur;
3041
}
3042

    
3043
jQuery.each( {
3044
	parent: function( elem ) {
3045
		var parent = elem.parentNode;
3046
		return parent && parent.nodeType !== 11 ? parent : null;
3047
	},
3048
	parents: function( elem ) {
3049
		return dir( elem, "parentNode" );
3050
	},
3051
	parentsUntil: function( elem, i, until ) {
3052
		return dir( elem, "parentNode", until );
3053
	},
3054
	next: function( elem ) {
3055
		return sibling( elem, "nextSibling" );
3056
	},
3057
	prev: function( elem ) {
3058
		return sibling( elem, "previousSibling" );
3059
	},
3060
	nextAll: function( elem ) {
3061
		return dir( elem, "nextSibling" );
3062
	},
3063
	prevAll: function( elem ) {
3064
		return dir( elem, "previousSibling" );
3065
	},
3066
	nextUntil: function( elem, i, until ) {
3067
		return dir( elem, "nextSibling", until );
3068
	},
3069
	prevUntil: function( elem, i, until ) {
3070
		return dir( elem, "previousSibling", until );
3071
	},
3072
	siblings: function( elem ) {
3073
		return siblings( ( elem.parentNode || {} ).firstChild, elem );
3074
	},
3075
	children: function( elem ) {
3076
		return siblings( elem.firstChild );
3077
	},
3078
	contents: function( elem ) {
3079
		return elem.contentDocument || jQuery.merge( [], elem.childNodes );
3080
	}
3081
}, function( name, fn ) {
3082
	jQuery.fn[ name ] = function( until, selector ) {
3083
		var matched = jQuery.map( this, fn, until );
3084

    
3085
		if ( name.slice( -5 ) !== "Until" ) {
3086
			selector = until;
3087
		}
3088

    
3089
		if ( selector && typeof selector === "string" ) {
3090
			matched = jQuery.filter( selector, matched );
3091
		}
3092

    
3093
		if ( this.length > 1 ) {
3094

    
3095
			// Remove duplicates
3096
			if ( !guaranteedUnique[ name ] ) {
3097
				jQuery.uniqueSort( matched );
3098
			}
3099

    
3100
			// Reverse order for parents* and prev-derivatives
3101
			if ( rparentsprev.test( name ) ) {
3102
				matched.reverse();
3103
			}
3104
		}
3105

    
3106
		return this.pushStack( matched );
3107
	};
3108
} );
3109
var rnotwhite = ( /\S+/g );
3110

    
3111

    
3112

    
3113
// Convert String-formatted options into Object-formatted ones
3114
function createOptions( options ) {
3115
	var object = {};
3116
	jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
3117
		object[ flag ] = true;
3118
	} );
3119
	return object;
3120
}
3121

    
3122
/*
3123
 * Create a callback list using the following parameters:
3124
 *
3125
 *	options: an optional list of space-separated options that will change how
3126
 *			the callback list behaves or a more traditional option object
3127
 *
3128
 * By default a callback list will act like an event callback list and can be
3129
 * "fired" multiple times.
3130
 *
3131
 * Possible options:
3132
 *
3133
 *	once:			will ensure the callback list can only be fired once (like a Deferred)
3134
 *
3135
 *	memory:			will keep track of previous values and will call any callback added
3136
 *					after the list has been fired right away with the latest "memorized"
3137
 *					values (like a Deferred)
3138
 *
3139
 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
3140
 *
3141
 *	stopOnFalse:	interrupt callings when a callback returns false
3142
 *
3143
 */
3144
jQuery.Callbacks = function( options ) {
3145

    
3146
	// Convert options from String-formatted to Object-formatted if needed
3147
	// (we check in cache first)
3148
	options = typeof options === "string" ?
3149
		createOptions( options ) :
3150
		jQuery.extend( {}, options );
3151

    
3152
	var // Flag to know if list is currently firing
3153
		firing,
3154

    
3155
		// Last fire value for non-forgettable lists
3156
		memory,
3157

    
3158
		// Flag to know if list was already fired
3159
		fired,
3160

    
3161
		// Flag to prevent firing
3162
		locked,
3163

    
3164
		// Actual callback list
3165
		list = [],
3166

    
3167
		// Queue of execution data for repeatable lists
3168
		queue = [],
3169

    
3170
		// Index of currently firing callback (modified by add/remove as needed)
3171
		firingIndex = -1,
3172

    
3173
		// Fire callbacks
3174
		fire = function() {
3175

    
3176
			// Enforce single-firing
3177
			locked = options.once;
3178

    
3179
			// Execute callbacks for all pending executions,
3180
			// respecting firingIndex overrides and runtime changes
3181
			fired = firing = true;
3182
			for ( ; queue.length; firingIndex = -1 ) {
3183
				memory = queue.shift();
3184
				while ( ++firingIndex < list.length ) {
3185

    
3186
					// Run callback and check for early termination
3187
					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
3188
						options.stopOnFalse ) {
3189

    
3190
						// Jump to end and forget the data so .add doesn't re-fire
3191
						firingIndex = list.length;
3192
						memory = false;
3193
					}
3194
				}
3195
			}
3196

    
3197
			// Forget the data if we're done with it
3198
			if ( !options.memory ) {
3199
				memory = false;
3200
			}
3201

    
3202
			firing = false;
3203

    
3204
			// Clean up if we're done firing for good
3205
			if ( locked ) {
3206

    
3207
				// Keep an empty list if we have data for future add calls
3208
				if ( memory ) {
3209
					list = [];
3210

    
3211
				// Otherwise, this object is spent
3212
				} else {
3213
					list = "";
3214
				}
3215
			}
3216
		},
3217

    
3218
		// Actual Callbacks object
3219
		self = {
3220

    
3221
			// Add a callback or a collection of callbacks to the list
3222
			add: function() {
3223
				if ( list ) {
3224

    
3225
					// If we have memory from a past run, we should fire after adding
3226
					if ( memory && !firing ) {
3227
						firingIndex = list.length - 1;
3228
						queue.push( memory );
3229
					}
3230

    
3231
					( function add( args ) {
3232
						jQuery.each( args, function( _, arg ) {
3233
							if ( jQuery.isFunction( arg ) ) {
3234
								if ( !options.unique || !self.has( arg ) ) {
3235
									list.push( arg );
3236
								}
3237
							} else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
3238

    
3239
								// Inspect recursively
3240
								add( arg );
3241
							}
3242
						} );
3243
					} )( arguments );
3244

    
3245
					if ( memory && !firing ) {
3246
						fire();
3247
					}
3248
				}
3249
				return this;
3250
			},
3251

    
3252
			// Remove a callback from the list
3253
			remove: function() {
3254
				jQuery.each( arguments, function( _, arg ) {
3255
					var index;
3256
					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3257
						list.splice( index, 1 );
3258

    
3259
						// Handle firing indexes
3260
						if ( index <= firingIndex ) {
3261
							firingIndex--;
3262
						}
3263
					}
3264
				} );
3265
				return this;
3266
			},
3267

    
3268
			// Check if a given callback is in the list.
3269
			// If no argument is given, return whether or not list has callbacks attached.
3270
			has: function( fn ) {
3271
				return fn ?
3272
					jQuery.inArray( fn, list ) > -1 :
3273
					list.length > 0;
3274
			},
3275

    
3276
			// Remove all callbacks from the list
3277
			empty: function() {
3278
				if ( list ) {
3279
					list = [];
3280
				}
3281
				return this;
3282
			},
3283

    
3284
			// Disable .fire and .add
3285
			// Abort any current/pending executions
3286
			// Clear all callbacks and values
3287
			disable: function() {
3288
				locked = queue = [];
3289
				list = memory = "";
3290
				return this;
3291
			},
3292
			disabled: function() {
3293
				return !list;
3294
			},
3295

    
3296
			// Disable .fire
3297
			// Also disable .add unless we have memory (since it would have no effect)
3298
			// Abort any pending executions
3299
			lock: function() {
3300
				locked = queue = [];
3301
				if ( !memory ) {
3302
					list = memory = "";
3303
				}
3304
				return this;
3305
			},
3306
			locked: function() {
3307
				return !!locked;
3308
			},
3309

    
3310
			// Call all callbacks with the given context and arguments
3311
			fireWith: function( context, args ) {
3312
				if ( !locked ) {
3313
					args = args || [];
3314
					args = [ context, args.slice ? args.slice() : args ];
3315
					queue.push( args );
3316
					if ( !firing ) {
3317
						fire();
3318
					}
3319
				}
3320
				return this;
3321
			},
3322

    
3323
			// Call all the callbacks with the given arguments
3324
			fire: function() {
3325
				self.fireWith( this, arguments );
3326
				return this;
3327
			},
3328

    
3329
			// To know if the callbacks have already been called at least once
3330
			fired: function() {
3331
				return !!fired;
3332
			}
3333
		};
3334

    
3335
	return self;
3336
};
3337

    
3338

    
3339
jQuery.extend( {
3340

    
3341
	Deferred: function( func ) {
3342
		var tuples = [
3343

    
3344
				// action, add listener, listener list, final state
3345
				[ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ],
3346
				[ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ],
3347
				[ "notify", "progress", jQuery.Callbacks( "memory" ) ]
3348
			],
3349
			state = "pending",
3350
			promise = {
3351
				state: function() {
3352
					return state;
3353
				},
3354
				always: function() {
3355
					deferred.done( arguments ).fail( arguments );
3356
					return this;
3357
				},
3358
				then: function( /* fnDone, fnFail, fnProgress */ ) {
3359
					var fns = arguments;
3360
					return jQuery.Deferred( function( newDefer ) {
3361
						jQuery.each( tuples, function( i, tuple ) {
3362
							var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
3363

    
3364
							// deferred[ done | fail | progress ] for forwarding actions to newDefer
3365
							deferred[ tuple[ 1 ] ]( function() {
3366
								var returned = fn && fn.apply( this, arguments );
3367
								if ( returned && jQuery.isFunction( returned.promise ) ) {
3368
									returned.promise()
3369
										.progress( newDefer.notify )
3370
										.done( newDefer.resolve )
3371
										.fail( newDefer.reject );
3372
								} else {
3373
									newDefer[ tuple[ 0 ] + "With" ](
3374
										this === promise ? newDefer.promise() : this,
3375
										fn ? [ returned ] : arguments
3376
									);
3377
								}
3378
							} );
3379
						} );
3380
						fns = null;
3381
					} ).promise();
3382
				},
3383

    
3384
				// Get a promise for this deferred
3385
				// If obj is provided, the promise aspect is added to the object
3386
				promise: function( obj ) {
3387
					return obj != null ? jQuery.extend( obj, promise ) : promise;
3388
				}
3389
			},
3390
			deferred = {};
3391

    
3392
		// Keep pipe for back-compat
3393
		promise.pipe = promise.then;
3394

    
3395
		// Add list-specific methods
3396
		jQuery.each( tuples, function( i, tuple ) {
3397
			var list = tuple[ 2 ],
3398
				stateString = tuple[ 3 ];
3399

    
3400
			// promise[ done | fail | progress ] = list.add
3401
			promise[ tuple[ 1 ] ] = list.add;
3402

    
3403
			// Handle state
3404
			if ( stateString ) {
3405
				list.add( function() {
3406

    
3407
					// state = [ resolved | rejected ]
3408
					state = stateString;
3409

    
3410
				// [ reject_list | resolve_list ].disable; progress_list.lock
3411
				}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
3412
			}
3413

    
3414
			// deferred[ resolve | reject | notify ]
3415
			deferred[ tuple[ 0 ] ] = function() {
3416
				deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
3417
				return this;
3418
			};
3419
			deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
3420
		} );
3421

    
3422
		// Make the deferred a promise
3423
		promise.promise( deferred );
3424

    
3425
		// Call given func if any
3426
		if ( func ) {
3427
			func.call( deferred, deferred );
3428
		}
3429

    
3430
		// All done!
3431
		return deferred;
3432
	},
3433

    
3434
	// Deferred helper
3435
	when: function( subordinate /* , ..., subordinateN */ ) {
3436
		var i = 0,
3437
			resolveValues = slice.call( arguments ),
3438
			length = resolveValues.length,
3439

    
3440
			// the count of uncompleted subordinates
3441
			remaining = length !== 1 ||
3442
				( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
3443

    
3444
			// the master Deferred.
3445
			// If resolveValues consist of only a single Deferred, just use that.
3446
			deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
3447

    
3448
			// Update function for both resolve and progress values
3449
			updateFunc = function( i, contexts, values ) {
3450
				return function( value ) {
3451
					contexts[ i ] = this;
3452
					values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
3453
					if ( values === progressValues ) {
3454
						deferred.notifyWith( contexts, values );
3455
					} else if ( !( --remaining ) ) {
3456
						deferred.resolveWith( contexts, values );
3457
					}
3458
				};
3459
			},
3460

    
3461
			progressValues, progressContexts, resolveContexts;
3462

    
3463
		// Add listeners to Deferred subordinates; treat others as resolved
3464
		if ( length > 1 ) {
3465
			progressValues = new Array( length );
3466
			progressContexts = new Array( length );
3467
			resolveContexts = new Array( length );
3468
			for ( ; i < length; i++ ) {
3469
				if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
3470
					resolveValues[ i ].promise()
3471
						.progress( updateFunc( i, progressContexts, progressValues ) )
3472
						.done( updateFunc( i, resolveContexts, resolveValues ) )
3473
						.fail( deferred.reject );
3474
				} else {
3475
					--remaining;
3476
				}
3477
			}
3478
		}
3479

    
3480
		// If we're not waiting on anything, resolve the master
3481
		if ( !remaining ) {
3482
			deferred.resolveWith( resolveContexts, resolveValues );
3483
		}
3484

    
3485
		return deferred.promise();
3486
	}
3487
} );
3488

    
3489

    
3490
// The deferred used on DOM ready
3491
var readyList;
3492

    
3493
jQuery.fn.ready = function( fn ) {
3494

    
3495
	// Add the callback
3496
	jQuery.ready.promise().done( fn );
3497

    
3498
	return this;
3499
};
3500

    
3501
jQuery.extend( {
3502

    
3503
	// Is the DOM ready to be used? Set to true once it occurs.
3504
	isReady: false,
3505

    
3506
	// A counter to track how many items to wait for before
3507
	// the ready event fires. See #6781
3508
	readyWait: 1,
3509

    
3510
	// Hold (or release) the ready event
3511
	holdReady: function( hold ) {
3512
		if ( hold ) {
3513
			jQuery.readyWait++;
3514
		} else {
3515
			jQuery.ready( true );
3516
		}
3517
	},
3518

    
3519
	// Handle when the DOM is ready
3520
	ready: function( wait ) {
3521

    
3522
		// Abort if there are pending holds or we're already ready
3523
		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
3524
			return;
3525
		}
3526

    
3527
		// Remember that the DOM is ready
3528
		jQuery.isReady = true;
3529

    
3530
		// If a normal DOM Ready event fired, decrement, and wait if need be
3531
		if ( wait !== true && --jQuery.readyWait > 0 ) {
3532
			return;
3533
		}
3534

    
3535
		// If there are functions bound, to execute
3536
		readyList.resolveWith( document, [ jQuery ] );
3537

    
3538
		// Trigger any bound ready events
3539
		if ( jQuery.fn.triggerHandler ) {
3540
			jQuery( document ).triggerHandler( "ready" );
3541
			jQuery( document ).off( "ready" );
3542
		}
3543
	}
3544
} );
3545

    
3546
/**
3547
 * The ready event handler and self cleanup method
3548
 */
3549
function completed() {
3550
	document.removeEventListener( "DOMContentLoaded", completed );
3551
	window.removeEventListener( "load", completed );
3552
	jQuery.ready();
3553
}
3554

    
3555
jQuery.ready.promise = function( obj ) {
3556
	if ( !readyList ) {
3557

    
3558
		readyList = jQuery.Deferred();
3559

    
3560
		// Catch cases where $(document).ready() is called
3561
		// after the browser event has already occurred.
3562
		// Support: IE9-10 only
3563
		// Older IE sometimes signals "interactive" too soon
3564
		if ( document.readyState === "complete" ||
3565
			( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
3566

    
3567
			// Handle it asynchronously to allow scripts the opportunity to delay ready
3568
			window.setTimeout( jQuery.ready );
3569

    
3570
		} else {
3571

    
3572
			// Use the handy event callback
3573
			document.addEventListener( "DOMContentLoaded", completed );
3574

    
3575
			// A fallback to window.onload, that will always work
3576
			window.addEventListener( "load", completed );
3577
		}
3578
	}
3579
	return readyList.promise( obj );
3580
};
3581

    
3582
// Kick off the DOM ready check even if the user does not
3583
jQuery.ready.promise();
3584

    
3585

    
3586

    
3587

    
3588
// Multifunctional method to get and set values of a collection
3589
// The value/s can optionally be executed if it's a function
3590
var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
3591
	var i = 0,
3592
		len = elems.length,
3593
		bulk = key == null;
3594

    
3595
	// Sets many values
3596
	if ( jQuery.type( key ) === "object" ) {
3597
		chainable = true;
3598
		for ( i in key ) {
3599
			access( elems, fn, i, key[ i ], true, emptyGet, raw );
3600
		}
3601

    
3602
	// Sets one value
3603
	} else if ( value !== undefined ) {
3604
		chainable = true;
3605

    
3606
		if ( !jQuery.isFunction( value ) ) {
3607
			raw = true;
3608
		}
3609

    
3610
		if ( bulk ) {
3611

    
3612
			// Bulk operations run against the entire set
3613
			if ( raw ) {
3614
				fn.call( elems, value );
3615
				fn = null;
3616

    
3617
			// ...except when executing function values
3618
			} else {
3619
				bulk = fn;
3620
				fn = function( elem, key, value ) {
3621
					return bulk.call( jQuery( elem ), value );
3622
				};
3623
			}
3624
		}
3625

    
3626
		if ( fn ) {
3627
			for ( ; i < len; i++ ) {
3628
				fn(
3629
					elems[ i ], key, raw ?
3630
					value :
3631
					value.call( elems[ i ], i, fn( elems[ i ], key ) )
3632
				);
3633
			}
3634
		}
3635
	}
3636

    
3637
	return chainable ?
3638
		elems :
3639

    
3640
		// Gets
3641
		bulk ?
3642
			fn.call( elems ) :
3643
			len ? fn( elems[ 0 ], key ) : emptyGet;
3644
};
3645
var acceptData = function( owner ) {
3646

    
3647
	// Accepts only:
3648
	//  - Node
3649
	//    - Node.ELEMENT_NODE
3650
	//    - Node.DOCUMENT_NODE
3651
	//  - Object
3652
	//    - Any
3653
	/* jshint -W018 */
3654
	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
3655
};
3656

    
3657

    
3658

    
3659

    
3660
function Data() {
3661
	this.expando = jQuery.expando + Data.uid++;
3662
}
3663

    
3664
Data.uid = 1;
3665

    
3666
Data.prototype = {
3667

    
3668
	register: function( owner, initial ) {
3669
		var value = initial || {};
3670

    
3671
		// If it is a node unlikely to be stringify-ed or looped over
3672
		// use plain assignment
3673
		if ( owner.nodeType ) {
3674
			owner[ this.expando ] = value;
3675

    
3676
		// Otherwise secure it in a non-enumerable, non-writable property
3677
		// configurability must be true to allow the property to be
3678
		// deleted with the delete operator
3679
		} else {
3680
			Object.defineProperty( owner, this.expando, {
3681
				value: value,
3682
				writable: true,
3683
				configurable: true
3684
			} );
3685
		}
3686
		return owner[ this.expando ];
3687
	},
3688
	cache: function( owner ) {
3689

    
3690
		// We can accept data for non-element nodes in modern browsers,
3691
		// but we should not, see #8335.
3692
		// Always return an empty object.
3693
		if ( !acceptData( owner ) ) {
3694
			return {};
3695
		}
3696

    
3697
		// Check if the owner object already has a cache
3698
		var value = owner[ this.expando ];
3699

    
3700
		// If not, create one
3701
		if ( !value ) {
3702
			value = {};
3703

    
3704
			// We can accept data for non-element nodes in modern browsers,
3705
			// but we should not, see #8335.
3706
			// Always return an empty object.
3707
			if ( acceptData( owner ) ) {
3708

    
3709
				// If it is a node unlikely to be stringify-ed or looped over
3710
				// use plain assignment
3711
				if ( owner.nodeType ) {
3712
					owner[ this.expando ] = value;
3713

    
3714
				// Otherwise secure it in a non-enumerable property
3715
				// configurable must be true to allow the property to be
3716
				// deleted when data is removed
3717
				} else {
3718
					Object.defineProperty( owner, this.expando, {
3719
						value: value,
3720
						configurable: true
3721
					} );
3722
				}
3723
			}
3724
		}
3725

    
3726
		return value;
3727
	},
3728
	set: function( owner, data, value ) {
3729
		var prop,
3730
			cache = this.cache( owner );
3731

    
3732
		// Handle: [ owner, key, value ] args
3733
		if ( typeof data === "string" ) {
3734
			cache[ data ] = value;
3735

    
3736
		// Handle: [ owner, { properties } ] args
3737
		} else {
3738

    
3739
			// Copy the properties one-by-one to the cache object
3740
			for ( prop in data ) {
3741
				cache[ prop ] = data[ prop ];
3742
			}
3743
		}
3744
		return cache;
3745
	},
3746
	get: function( owner, key ) {
3747
		return key === undefined ?
3748
			this.cache( owner ) :
3749
			owner[ this.expando ] && owner[ this.expando ][ key ];
3750
	},
3751
	access: function( owner, key, value ) {
3752
		var stored;
3753

    
3754
		// In cases where either:
3755
		//
3756
		//   1. No key was specified
3757
		//   2. A string key was specified, but no value provided
3758
		//
3759
		// Take the "read" path and allow the get method to determine
3760
		// which value to return, respectively either:
3761
		//
3762
		//   1. The entire cache object
3763
		//   2. The data stored at the key
3764
		//
3765
		if ( key === undefined ||
3766
				( ( key && typeof key === "string" ) && value === undefined ) ) {
3767

    
3768
			stored = this.get( owner, key );
3769

    
3770
			return stored !== undefined ?
3771
				stored : this.get( owner, jQuery.camelCase( key ) );
3772
		}
3773

    
3774
		// When the key is not a string, or both a key and value
3775
		// are specified, set or extend (existing objects) with either:
3776
		//
3777
		//   1. An object of properties
3778
		//   2. A key and value
3779
		//
3780
		this.set( owner, key, value );
3781

    
3782
		// Since the "set" path can have two possible entry points
3783
		// return the expected data based on which path was taken[*]
3784
		return value !== undefined ? value : key;
3785
	},
3786
	remove: function( owner, key ) {
3787
		var i, name, camel,
3788
			cache = owner[ this.expando ];
3789

    
3790
		if ( cache === undefined ) {
3791
			return;
3792
		}
3793

    
3794
		if ( key === undefined ) {
3795
			this.register( owner );
3796

    
3797
		} else {
3798

    
3799
			// Support array or space separated string of keys
3800
			if ( jQuery.isArray( key ) ) {
3801

    
3802
				// If "name" is an array of keys...
3803
				// When data is initially created, via ("key", "val") signature,
3804
				// keys will be converted to camelCase.
3805
				// Since there is no way to tell _how_ a key was added, remove
3806
				// both plain key and camelCase key. #12786
3807
				// This will only penalize the array argument path.
3808
				name = key.concat( key.map( jQuery.camelCase ) );
3809
			} else {
3810
				camel = jQuery.camelCase( key );
3811

    
3812
				// Try the string as a key before any manipulation
3813
				if ( key in cache ) {
3814
					name = [ key, camel ];
3815
				} else {
3816

    
3817
					// If a key with the spaces exists, use it.
3818
					// Otherwise, create an array by matching non-whitespace
3819
					name = camel;
3820
					name = name in cache ?
3821
						[ name ] : ( name.match( rnotwhite ) || [] );
3822
				}
3823
			}
3824

    
3825
			i = name.length;
3826

    
3827
			while ( i-- ) {
3828
				delete cache[ name[ i ] ];
3829
			}
3830
		}
3831

    
3832
		// Remove the expando if there's no more data
3833
		if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
3834

    
3835
			// Support: Chrome <= 35-45+
3836
			// Webkit & Blink performance suffers when deleting properties
3837
			// from DOM nodes, so set to undefined instead
3838
			// https://code.google.com/p/chromium/issues/detail?id=378607
3839
			if ( owner.nodeType ) {
3840
				owner[ this.expando ] = undefined;
3841
			} else {
3842
				delete owner[ this.expando ];
3843
			}
3844
		}
3845
	},
3846
	hasData: function( owner ) {
3847
		var cache = owner[ this.expando ];
3848
		return cache !== undefined && !jQuery.isEmptyObject( cache );
3849
	}
3850
};
3851
var dataPriv = new Data();
3852

    
3853
var dataUser = new Data();
3854

    
3855

    
3856

    
3857
//	Implementation Summary
3858
//
3859
//	1. Enforce API surface and semantic compatibility with 1.9.x branch
3860
//	2. Improve the module's maintainability by reducing the storage
3861
//		paths to a single mechanism.
3862
//	3. Use the same single mechanism to support "private" and "user" data.
3863
//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
3864
//	5. Avoid exposing implementation details on user objects (eg. expando properties)
3865
//	6. Provide a clear path for implementation upgrade to WeakMap in 2014
3866

    
3867
var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
3868
	rmultiDash = /[A-Z]/g;
3869

    
3870
function dataAttr( elem, key, data ) {
3871
	var name;
3872

    
3873
	// If nothing was found internally, try to fetch any
3874
	// data from the HTML5 data-* attribute
3875
	if ( data === undefined && elem.nodeType === 1 ) {
3876
		name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
3877
		data = elem.getAttribute( name );
3878

    
3879
		if ( typeof data === "string" ) {
3880
			try {
3881
				data = data === "true" ? true :
3882
					data === "false" ? false :
3883
					data === "null" ? null :
3884

    
3885
					// Only convert to a number if it doesn't change the string
3886
					+data + "" === data ? +data :
3887
					rbrace.test( data ) ? jQuery.parseJSON( data ) :
3888
					data;
3889
			} catch ( e ) {}
3890

    
3891
			// Make sure we set the data so it isn't changed later
3892
			dataUser.set( elem, key, data );
3893
		} else {
3894
			data = undefined;
3895
		}
3896
	}
3897
	return data;
3898
}
3899

    
3900
jQuery.extend( {
3901
	hasData: function( elem ) {
3902
		return dataUser.hasData( elem ) || dataPriv.hasData( elem );
3903
	},
3904

    
3905
	data: function( elem, name, data ) {
3906
		return dataUser.access( elem, name, data );
3907
	},
3908

    
3909
	removeData: function( elem, name ) {
3910
		dataUser.remove( elem, name );
3911
	},
3912

    
3913
	// TODO: Now that all calls to _data and _removeData have been replaced
3914
	// with direct calls to dataPriv methods, these can be deprecated.
3915
	_data: function( elem, name, data ) {
3916
		return dataPriv.access( elem, name, data );
3917
	},
3918

    
3919
	_removeData: function( elem, name ) {
3920
		dataPriv.remove( elem, name );
3921
	}
3922
} );
3923

    
3924
jQuery.fn.extend( {
3925
	data: function( key, value ) {
3926
		var i, name, data,
3927
			elem = this[ 0 ],
3928
			attrs = elem && elem.attributes;
3929

    
3930
		// Gets all values
3931
		if ( key === undefined ) {
3932
			if ( this.length ) {
3933
				data = dataUser.get( elem );
3934

    
3935
				if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
3936
					i = attrs.length;
3937
					while ( i-- ) {
3938

    
3939
						// Support: IE11+
3940
						// The attrs elements can be null (#14894)
3941
						if ( attrs[ i ] ) {
3942
							name = attrs[ i ].name;
3943
							if ( name.indexOf( "data-" ) === 0 ) {
3944
								name = jQuery.camelCase( name.slice( 5 ) );
3945
								dataAttr( elem, name, data[ name ] );
3946
							}
3947
						}
3948
					}
3949
					dataPriv.set( elem, "hasDataAttrs", true );
3950
				}
3951
			}
3952

    
3953
			return data;
3954
		}
3955

    
3956
		// Sets multiple values
3957
		if ( typeof key === "object" ) {
3958
			return this.each( function() {
3959
				dataUser.set( this, key );
3960
			} );
3961
		}
3962

    
3963
		return access( this, function( value ) {
3964
			var data, camelKey;
3965

    
3966
			// The calling jQuery object (element matches) is not empty
3967
			// (and therefore has an element appears at this[ 0 ]) and the
3968
			// `value` parameter was not undefined. An empty jQuery object
3969
			// will result in `undefined` for elem = this[ 0 ] which will
3970
			// throw an exception if an attempt to read a data cache is made.
3971
			if ( elem && value === undefined ) {
3972

    
3973
				// Attempt to get data from the cache
3974
				// with the key as-is
3975
				data = dataUser.get( elem, key ) ||
3976

    
3977
					// Try to find dashed key if it exists (gh-2779)
3978
					// This is for 2.2.x only
3979
					dataUser.get( elem, key.replace( rmultiDash, "-$&" ).toLowerCase() );
3980

    
3981
				if ( data !== undefined ) {
3982
					return data;
3983
				}
3984

    
3985
				camelKey = jQuery.camelCase( key );
3986

    
3987
				// Attempt to get data from the cache
3988
				// with the key camelized
3989
				data = dataUser.get( elem, camelKey );
3990
				if ( data !== undefined ) {
3991
					return data;
3992
				}
3993

    
3994
				// Attempt to "discover" the data in
3995
				// HTML5 custom data-* attrs
3996
				data = dataAttr( elem, camelKey, undefined );
3997
				if ( data !== undefined ) {
3998
					return data;
3999
				}
4000

    
4001
				// We tried really hard, but the data doesn't exist.
4002
				return;
4003
			}
4004

    
4005
			// Set the data...
4006
			camelKey = jQuery.camelCase( key );
4007
			this.each( function() {
4008

    
4009
				// First, attempt to store a copy or reference of any
4010
				// data that might've been store with a camelCased key.
4011
				var data = dataUser.get( this, camelKey );
4012

    
4013
				// For HTML5 data-* attribute interop, we have to
4014
				// store property names with dashes in a camelCase form.
4015
				// This might not apply to all properties...*
4016
				dataUser.set( this, camelKey, value );
4017

    
4018
				// *... In the case of properties that might _actually_
4019
				// have dashes, we need to also store a copy of that
4020
				// unchanged property.
4021
				if ( key.indexOf( "-" ) > -1 && data !== undefined ) {
4022
					dataUser.set( this, key, value );
4023
				}
4024
			} );
4025
		}, null, value, arguments.length > 1, null, true );
4026
	},
4027

    
4028
	removeData: function( key ) {
4029
		return this.each( function() {
4030
			dataUser.remove( this, key );
4031
		} );
4032
	}
4033
} );
4034

    
4035

    
4036
jQuery.extend( {
4037
	queue: function( elem, type, data ) {
4038
		var queue;
4039

    
4040
		if ( elem ) {
4041
			type = ( type || "fx" ) + "queue";
4042
			queue = dataPriv.get( elem, type );
4043

    
4044
			// Speed up dequeue by getting out quickly if this is just a lookup
4045
			if ( data ) {
4046
				if ( !queue || jQuery.isArray( data ) ) {
4047
					queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
4048
				} else {
4049
					queue.push( data );
4050
				}
4051
			}
4052
			return queue || [];
4053
		}
4054
	},
4055

    
4056
	dequeue: function( elem, type ) {
4057
		type = type || "fx";
4058

    
4059
		var queue = jQuery.queue( elem, type ),
4060
			startLength = queue.length,
4061
			fn = queue.shift(),
4062
			hooks = jQuery._queueHooks( elem, type ),
4063
			next = function() {
4064
				jQuery.dequeue( elem, type );
4065
			};
4066

    
4067
		// If the fx queue is dequeued, always remove the progress sentinel
4068
		if ( fn === "inprogress" ) {
4069
			fn = queue.shift();
4070
			startLength--;
4071
		}
4072

    
4073
		if ( fn ) {
4074

    
4075
			// Add a progress sentinel to prevent the fx queue from being
4076
			// automatically dequeued
4077
			if ( type === "fx" ) {
4078
				queue.unshift( "inprogress" );
4079
			}
4080

    
4081
			// Clear up the last queue stop function
4082
			delete hooks.stop;
4083
			fn.call( elem, next, hooks );
4084
		}
4085

    
4086
		if ( !startLength && hooks ) {
4087
			hooks.empty.fire();
4088
		}
4089
	},
4090

    
4091
	// Not public - generate a queueHooks object, or return the current one
4092
	_queueHooks: function( elem, type ) {
4093
		var key = type + "queueHooks";
4094
		return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
4095
			empty: jQuery.Callbacks( "once memory" ).add( function() {
4096
				dataPriv.remove( elem, [ type + "queue", key ] );
4097
			} )
4098
		} );
4099
	}
4100
} );
4101

    
4102
jQuery.fn.extend( {
4103
	queue: function( type, data ) {
4104
		var setter = 2;
4105

    
4106
		if ( typeof type !== "string" ) {
4107
			data = type;
4108
			type = "fx";
4109
			setter--;
4110
		}
4111

    
4112
		if ( arguments.length < setter ) {
4113
			return jQuery.queue( this[ 0 ], type );
4114
		}
4115

    
4116
		return data === undefined ?
4117
			this :
4118
			this.each( function() {
4119
				var queue = jQuery.queue( this, type, data );
4120

    
4121
				// Ensure a hooks for this queue
4122
				jQuery._queueHooks( this, type );
4123

    
4124
				if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
4125
					jQuery.dequeue( this, type );
4126
				}
4127
			} );
4128
	},
4129
	dequeue: function( type ) {
4130
		return this.each( function() {
4131
			jQuery.dequeue( this, type );
4132
		} );
4133
	},
4134
	clearQueue: function( type ) {
4135
		return this.queue( type || "fx", [] );
4136
	},
4137

    
4138
	// Get a promise resolved when queues of a certain type
4139
	// are emptied (fx is the type by default)
4140
	promise: function( type, obj ) {
4141
		var tmp,
4142
			count = 1,
4143
			defer = jQuery.Deferred(),
4144
			elements = this,
4145
			i = this.length,
4146
			resolve = function() {
4147
				if ( !( --count ) ) {
4148
					defer.resolveWith( elements, [ elements ] );
4149
				}
4150
			};
4151

    
4152
		if ( typeof type !== "string" ) {
4153
			obj = type;
4154
			type = undefined;
4155
		}
4156
		type = type || "fx";
4157

    
4158
		while ( i-- ) {
4159
			tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
4160
			if ( tmp && tmp.empty ) {
4161
				count++;
4162
				tmp.empty.add( resolve );
4163
			}
4164
		}
4165
		resolve();
4166
		return defer.promise( obj );
4167
	}
4168
} );
4169
var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
4170

    
4171
var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
4172

    
4173

    
4174
var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
4175

    
4176
var isHidden = function( elem, el ) {
4177

    
4178
		// isHidden might be called from jQuery#filter function;
4179
		// in that case, element will be second argument
4180
		elem = el || elem;
4181
		return jQuery.css( elem, "display" ) === "none" ||
4182
			!jQuery.contains( elem.ownerDocument, elem );
4183
	};
4184

    
4185

    
4186

    
4187
function adjustCSS( elem, prop, valueParts, tween ) {
4188
	var adjusted,
4189
		scale = 1,
4190
		maxIterations = 20,
4191
		currentValue = tween ?
4192
			function() { return tween.cur(); } :
4193
			function() { return jQuery.css( elem, prop, "" ); },
4194
		initial = currentValue(),
4195
		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
4196

    
4197
		// Starting value computation is required for potential unit mismatches
4198
		initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
4199
			rcssNum.exec( jQuery.css( elem, prop ) );
4200

    
4201
	if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
4202

    
4203
		// Trust units reported by jQuery.css
4204
		unit = unit || initialInUnit[ 3 ];
4205

    
4206
		// Make sure we update the tween properties later on
4207
		valueParts = valueParts || [];
4208

    
4209
		// Iteratively approximate from a nonzero starting point
4210
		initialInUnit = +initial || 1;
4211

    
4212
		do {
4213

    
4214
			// If previous iteration zeroed out, double until we get *something*.
4215
			// Use string for doubling so we don't accidentally see scale as unchanged below
4216
			scale = scale || ".5";
4217

    
4218
			// Adjust and apply
4219
			initialInUnit = initialInUnit / scale;
4220
			jQuery.style( elem, prop, initialInUnit + unit );
4221

    
4222
		// Update scale, tolerating zero or NaN from tween.cur()
4223
		// Break the loop if scale is unchanged or perfect, or if we've just had enough.
4224
		} while (
4225
			scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
4226
		);
4227
	}
4228

    
4229
	if ( valueParts ) {
4230
		initialInUnit = +initialInUnit || +initial || 0;
4231

    
4232
		// Apply relative offset (+=/-=) if specified
4233
		adjusted = valueParts[ 1 ] ?
4234
			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
4235
			+valueParts[ 2 ];
4236
		if ( tween ) {
4237
			tween.unit = unit;
4238
			tween.start = initialInUnit;
4239
			tween.end = adjusted;
4240
		}
4241
	}
4242
	return adjusted;
4243
}
4244
var rcheckableType = ( /^(?:checkbox|radio)$/i );
4245

    
4246
var rtagName = ( /<([\w:-]+)/ );
4247

    
4248
var rscriptType = ( /^$|\/(?:java|ecma)script/i );
4249

    
4250

    
4251

    
4252
// We have to close these tags to support XHTML (#13200)
4253
var wrapMap = {
4254

    
4255
	// Support: IE9
4256
	option: [ 1, "<select multiple='multiple'>", "</select>" ],
4257

    
4258
	// XHTML parsers do not magically insert elements in the
4259
	// same way that tag soup parsers do. So we cannot shorten
4260
	// this by omitting <tbody> or other required elements.
4261
	thead: [ 1, "<table>", "</table>" ],
4262
	col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
4263
	tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4264
	td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4265

    
4266
	_default: [ 0, "", "" ]
4267
};
4268

    
4269
// Support: IE9
4270
wrapMap.optgroup = wrapMap.option;
4271

    
4272
wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4273
wrapMap.th = wrapMap.td;
4274

    
4275

    
4276
function getAll( context, tag ) {
4277

    
4278
	// Support: IE9-11+
4279
	// Use typeof to avoid zero-argument method invocation on host objects (#15151)
4280
	var ret = typeof context.getElementsByTagName !== "undefined" ?
4281
			context.getElementsByTagName( tag || "*" ) :
4282
			typeof context.querySelectorAll !== "undefined" ?
4283
				context.querySelectorAll( tag || "*" ) :
4284
			[];
4285

    
4286
	return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
4287
		jQuery.merge( [ context ], ret ) :
4288
		ret;
4289
}
4290

    
4291

    
4292
// Mark scripts as having already been evaluated
4293
function setGlobalEval( elems, refElements ) {
4294
	var i = 0,
4295
		l = elems.length;
4296

    
4297
	for ( ; i < l; i++ ) {
4298
		dataPriv.set(
4299
			elems[ i ],
4300
			"globalEval",
4301
			!refElements || dataPriv.get( refElements[ i ], "globalEval" )
4302
		);
4303
	}
4304
}
4305

    
4306

    
4307
var rhtml = /<|&#?\w+;/;
4308

    
4309
function buildFragment( elems, context, scripts, selection, ignored ) {
4310
	var elem, tmp, tag, wrap, contains, j,
4311
		fragment = context.createDocumentFragment(),
4312
		nodes = [],
4313
		i = 0,
4314
		l = elems.length;
4315

    
4316
	for ( ; i < l; i++ ) {
4317
		elem = elems[ i ];
4318

    
4319
		if ( elem || elem === 0 ) {
4320

    
4321
			// Add nodes directly
4322
			if ( jQuery.type( elem ) === "object" ) {
4323

    
4324
				// Support: Android<4.1, PhantomJS<2
4325
				// push.apply(_, arraylike) throws on ancient WebKit
4326
				jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
4327

    
4328
			// Convert non-html into a text node
4329
			} else if ( !rhtml.test( elem ) ) {
4330
				nodes.push( context.createTextNode( elem ) );
4331

    
4332
			// Convert html into DOM nodes
4333
			} else {
4334
				tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
4335

    
4336
				// Deserialize a standard representation
4337
				tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
4338
				wrap = wrapMap[ tag ] || wrapMap._default;
4339
				tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
4340

    
4341
				// Descend through wrappers to the right content
4342
				j = wrap[ 0 ];
4343
				while ( j-- ) {
4344
					tmp = tmp.lastChild;
4345
				}
4346

    
4347
				// Support: Android<4.1, PhantomJS<2
4348
				// push.apply(_, arraylike) throws on ancient WebKit
4349
				jQuery.merge( nodes, tmp.childNodes );
4350

    
4351
				// Remember the top-level container
4352
				tmp = fragment.firstChild;
4353

    
4354
				// Ensure the created nodes are orphaned (#12392)
4355
				tmp.textContent = "";
4356
			}
4357
		}
4358
	}
4359

    
4360
	// Remove wrapper from fragment
4361
	fragment.textContent = "";
4362

    
4363
	i = 0;
4364
	while ( ( elem = nodes[ i++ ] ) ) {
4365

    
4366
		// Skip elements already in the context collection (trac-4087)
4367
		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
4368
			if ( ignored ) {
4369
				ignored.push( elem );
4370
			}
4371
			continue;
4372
		}
4373

    
4374
		contains = jQuery.contains( elem.ownerDocument, elem );
4375

    
4376
		// Append to fragment
4377
		tmp = getAll( fragment.appendChild( elem ), "script" );
4378

    
4379
		// Preserve script evaluation history
4380
		if ( contains ) {
4381
			setGlobalEval( tmp );
4382
		}
4383

    
4384
		// Capture executables
4385
		if ( scripts ) {
4386
			j = 0;
4387
			while ( ( elem = tmp[ j++ ] ) ) {
4388
				if ( rscriptType.test( elem.type || "" ) ) {
4389
					scripts.push( elem );
4390
				}
4391
			}
4392
		}
4393
	}
4394

    
4395
	return fragment;
4396
}
4397

    
4398

    
4399
( function() {
4400
	var fragment = document.createDocumentFragment(),
4401
		div = fragment.appendChild( document.createElement( "div" ) ),
4402
		input = document.createElement( "input" );
4403

    
4404
	// Support: Android 4.0-4.3, Safari<=5.1
4405
	// Check state lost if the name is set (#11217)
4406
	// Support: Windows Web Apps (WWA)
4407
	// `name` and `type` must use .setAttribute for WWA (#14901)
4408
	input.setAttribute( "type", "radio" );
4409
	input.setAttribute( "checked", "checked" );
4410
	input.setAttribute( "name", "t" );
4411

    
4412
	div.appendChild( input );
4413

    
4414
	// Support: Safari<=5.1, Android<4.2
4415
	// Older WebKit doesn't clone checked state correctly in fragments
4416
	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
4417

    
4418
	// Support: IE<=11+
4419
	// Make sure textarea (and checkbox) defaultValue is properly cloned
4420
	div.innerHTML = "<textarea>x</textarea>";
4421
	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
4422
} )();
4423

    
4424

    
4425
var
4426
	rkeyEvent = /^key/,
4427
	rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
4428
	rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
4429

    
4430
function returnTrue() {
4431
	return true;
4432
}
4433

    
4434
function returnFalse() {
4435
	return false;
4436
}
4437

    
4438
// Support: IE9
4439
// See #13393 for more info
4440
function safeActiveElement() {
4441
	try {
4442
		return document.activeElement;
4443
	} catch ( err ) { }
4444
}
4445

    
4446
function on( elem, types, selector, data, fn, one ) {
4447
	var origFn, type;
4448

    
4449
	// Types can be a map of types/handlers
4450
	if ( typeof types === "object" ) {
4451

    
4452
		// ( types-Object, selector, data )
4453
		if ( typeof selector !== "string" ) {
4454

    
4455
			// ( types-Object, data )
4456
			data = data || selector;
4457
			selector = undefined;
4458
		}
4459
		for ( type in types ) {
4460
			on( elem, type, selector, data, types[ type ], one );
4461
		}
4462
		return elem;
4463
	}
4464

    
4465
	if ( data == null && fn == null ) {
4466

    
4467
		// ( types, fn )
4468
		fn = selector;
4469
		data = selector = undefined;
4470
	} else if ( fn == null ) {
4471
		if ( typeof selector === "string" ) {
4472

    
4473
			// ( types, selector, fn )
4474
			fn = data;
4475
			data = undefined;
4476
		} else {
4477

    
4478
			// ( types, data, fn )
4479
			fn = data;
4480
			data = selector;
4481
			selector = undefined;
4482
		}
4483
	}
4484
	if ( fn === false ) {
4485
		fn = returnFalse;
4486
	} else if ( !fn ) {
4487
		return elem;
4488
	}
4489

    
4490
	if ( one === 1 ) {
4491
		origFn = fn;
4492
		fn = function( event ) {
4493

    
4494
			// Can use an empty set, since event contains the info
4495
			jQuery().off( event );
4496
			return origFn.apply( this, arguments );
4497
		};
4498

    
4499
		// Use same guid so caller can remove using origFn
4500
		fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
4501
	}
4502
	return elem.each( function() {
4503
		jQuery.event.add( this, types, fn, data, selector );
4504
	} );
4505
}
4506

    
4507
/*
4508
 * Helper functions for managing events -- not part of the public interface.
4509
 * Props to Dean Edwards' addEvent library for many of the ideas.
4510
 */
4511
jQuery.event = {
4512

    
4513
	global: {},
4514

    
4515
	add: function( elem, types, handler, data, selector ) {
4516

    
4517
		var handleObjIn, eventHandle, tmp,
4518
			events, t, handleObj,
4519
			special, handlers, type, namespaces, origType,
4520
			elemData = dataPriv.get( elem );
4521

    
4522
		// Don't attach events to noData or text/comment nodes (but allow plain objects)
4523
		if ( !elemData ) {
4524
			return;
4525
		}
4526

    
4527
		// Caller can pass in an object of custom data in lieu of the handler
4528
		if ( handler.handler ) {
4529
			handleObjIn = handler;
4530
			handler = handleObjIn.handler;
4531
			selector = handleObjIn.selector;
4532
		}
4533

    
4534
		// Make sure that the handler has a unique ID, used to find/remove it later
4535
		if ( !handler.guid ) {
4536
			handler.guid = jQuery.guid++;
4537
		}
4538

    
4539
		// Init the element's event structure and main handler, if this is the first
4540
		if ( !( events = elemData.events ) ) {
4541
			events = elemData.events = {};
4542
		}
4543
		if ( !( eventHandle = elemData.handle ) ) {
4544
			eventHandle = elemData.handle = function( e ) {
4545

    
4546
				// Discard the second event of a jQuery.event.trigger() and
4547
				// when an event is called after a page has unloaded
4548
				return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
4549
					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
4550
			};
4551
		}
4552

    
4553
		// Handle multiple events separated by a space
4554
		types = ( types || "" ).match( rnotwhite ) || [ "" ];
4555
		t = types.length;
4556
		while ( t-- ) {
4557
			tmp = rtypenamespace.exec( types[ t ] ) || [];
4558
			type = origType = tmp[ 1 ];
4559
			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
4560

    
4561
			// There *must* be a type, no attaching namespace-only handlers
4562
			if ( !type ) {
4563
				continue;
4564
			}
4565

    
4566
			// If event changes its type, use the special event handlers for the changed type
4567
			special = jQuery.event.special[ type ] || {};
4568

    
4569
			// If selector defined, determine special event api type, otherwise given type
4570
			type = ( selector ? special.delegateType : special.bindType ) || type;
4571

    
4572
			// Update special based on newly reset type
4573
			special = jQuery.event.special[ type ] || {};
4574

    
4575
			// handleObj is passed to all event handlers
4576
			handleObj = jQuery.extend( {
4577
				type: type,
4578
				origType: origType,
4579
				data: data,
4580
				handler: handler,
4581
				guid: handler.guid,
4582
				selector: selector,
4583
				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
4584
				namespace: namespaces.join( "." )
4585
			}, handleObjIn );
4586

    
4587
			// Init the event handler queue if we're the first
4588
			if ( !( handlers = events[ type ] ) ) {
4589
				handlers = events[ type ] = [];
4590
				handlers.delegateCount = 0;
4591

    
4592
				// Only use addEventListener if the special events handler returns false
4593
				if ( !special.setup ||
4594
					special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
4595

    
4596
					if ( elem.addEventListener ) {
4597
						elem.addEventListener( type, eventHandle );
4598
					}
4599
				}
4600
			}
4601

    
4602
			if ( special.add ) {
4603
				special.add.call( elem, handleObj );
4604

    
4605
				if ( !handleObj.handler.guid ) {
4606
					handleObj.handler.guid = handler.guid;
4607
				}
4608
			}
4609

    
4610
			// Add to the element's handler list, delegates in front
4611
			if ( selector ) {
4612
				handlers.splice( handlers.delegateCount++, 0, handleObj );
4613
			} else {
4614
				handlers.push( handleObj );
4615
			}
4616

    
4617
			// Keep track of which events have ever been used, for event optimization
4618
			jQuery.event.global[ type ] = true;
4619
		}
4620

    
4621
	},
4622

    
4623
	// Detach an event or set of events from an element
4624
	remove: function( elem, types, handler, selector, mappedTypes ) {
4625

    
4626
		var j, origCount, tmp,
4627
			events, t, handleObj,
4628
			special, handlers, type, namespaces, origType,
4629
			elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
4630

    
4631
		if ( !elemData || !( events = elemData.events ) ) {
4632
			return;
4633
		}
4634

    
4635
		// Once for each type.namespace in types; type may be omitted
4636
		types = ( types || "" ).match( rnotwhite ) || [ "" ];
4637
		t = types.length;
4638
		while ( t-- ) {
4639
			tmp = rtypenamespace.exec( types[ t ] ) || [];
4640
			type = origType = tmp[ 1 ];
4641
			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
4642

    
4643
			// Unbind all events (on this namespace, if provided) for the element
4644
			if ( !type ) {
4645
				for ( type in events ) {
4646
					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
4647
				}
4648
				continue;
4649
			}
4650

    
4651
			special = jQuery.event.special[ type ] || {};
4652
			type = ( selector ? special.delegateType : special.bindType ) || type;
4653
			handlers = events[ type ] || [];
4654
			tmp = tmp[ 2 ] &&
4655
				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
4656

    
4657
			// Remove matching events
4658
			origCount = j = handlers.length;
4659
			while ( j-- ) {
4660
				handleObj = handlers[ j ];
4661

    
4662
				if ( ( mappedTypes || origType === handleObj.origType ) &&
4663
					( !handler || handler.guid === handleObj.guid ) &&
4664
					( !tmp || tmp.test( handleObj.namespace ) ) &&
4665
					( !selector || selector === handleObj.selector ||
4666
						selector === "**" && handleObj.selector ) ) {
4667
					handlers.splice( j, 1 );
4668

    
4669
					if ( handleObj.selector ) {
4670
						handlers.delegateCount--;
4671
					}
4672
					if ( special.remove ) {
4673
						special.remove.call( elem, handleObj );
4674
					}
4675
				}
4676
			}
4677

    
4678
			// Remove generic event handler if we removed something and no more handlers exist
4679
			// (avoids potential for endless recursion during removal of special event handlers)
4680
			if ( origCount && !handlers.length ) {
4681
				if ( !special.teardown ||
4682
					special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
4683

    
4684
					jQuery.removeEvent( elem, type, elemData.handle );
4685
				}
4686

    
4687
				delete events[ type ];
4688
			}
4689
		}
4690

    
4691
		// Remove data and the expando if it's no longer used
4692
		if ( jQuery.isEmptyObject( events ) ) {
4693
			dataPriv.remove( elem, "handle events" );
4694
		}
4695
	},
4696

    
4697
	dispatch: function( event ) {
4698

    
4699
		// Make a writable jQuery.Event from the native event object
4700
		event = jQuery.event.fix( event );
4701

    
4702
		var i, j, ret, matched, handleObj,
4703
			handlerQueue = [],
4704
			args = slice.call( arguments ),
4705
			handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
4706
			special = jQuery.event.special[ event.type ] || {};
4707

    
4708
		// Use the fix-ed jQuery.Event rather than the (read-only) native event
4709
		args[ 0 ] = event;
4710
		event.delegateTarget = this;
4711

    
4712
		// Call the preDispatch hook for the mapped type, and let it bail if desired
4713
		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
4714
			return;
4715
		}
4716

    
4717
		// Determine handlers
4718
		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
4719

    
4720
		// Run delegates first; they may want to stop propagation beneath us
4721
		i = 0;
4722
		while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
4723
			event.currentTarget = matched.elem;
4724

    
4725
			j = 0;
4726
			while ( ( handleObj = matched.handlers[ j++ ] ) &&
4727
				!event.isImmediatePropagationStopped() ) {
4728

    
4729
				// Triggered event must either 1) have no namespace, or 2) have namespace(s)
4730
				// a subset or equal to those in the bound event (both can have no namespace).
4731
				if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
4732

    
4733
					event.handleObj = handleObj;
4734
					event.data = handleObj.data;
4735

    
4736
					ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
4737
						handleObj.handler ).apply( matched.elem, args );
4738

    
4739
					if ( ret !== undefined ) {
4740
						if ( ( event.result = ret ) === false ) {
4741
							event.preventDefault();
4742
							event.stopPropagation();
4743
						}
4744
					}
4745
				}
4746
			}
4747
		}
4748

    
4749
		// Call the postDispatch hook for the mapped type
4750
		if ( special.postDispatch ) {
4751
			special.postDispatch.call( this, event );
4752
		}
4753

    
4754
		return event.result;
4755
	},
4756

    
4757
	handlers: function( event, handlers ) {
4758
		var i, matches, sel, handleObj,
4759
			handlerQueue = [],
4760
			delegateCount = handlers.delegateCount,
4761
			cur = event.target;
4762

    
4763
		// Support (at least): Chrome, IE9
4764
		// Find delegate handlers
4765
		// Black-hole SVG <use> instance trees (#13180)
4766
		//
4767
		// Support: Firefox<=42+
4768
		// Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)
4769
		if ( delegateCount && cur.nodeType &&
4770
			( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) {
4771

    
4772
			for ( ; cur !== this; cur = cur.parentNode || this ) {
4773

    
4774
				// Don't check non-elements (#13208)
4775
				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
4776
				if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) {
4777
					matches = [];
4778
					for ( i = 0; i < delegateCount; i++ ) {
4779
						handleObj = handlers[ i ];
4780

    
4781
						// Don't conflict with Object.prototype properties (#13203)
4782
						sel = handleObj.selector + " ";
4783

    
4784
						if ( matches[ sel ] === undefined ) {
4785
							matches[ sel ] = handleObj.needsContext ?
4786
								jQuery( sel, this ).index( cur ) > -1 :
4787
								jQuery.find( sel, this, null, [ cur ] ).length;
4788
						}
4789
						if ( matches[ sel ] ) {
4790
							matches.push( handleObj );
4791
						}
4792
					}
4793
					if ( matches.length ) {
4794
						handlerQueue.push( { elem: cur, handlers: matches } );
4795
					}
4796
				}
4797
			}
4798
		}
4799

    
4800
		// Add the remaining (directly-bound) handlers
4801
		if ( delegateCount < handlers.length ) {
4802
			handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } );
4803
		}
4804

    
4805
		return handlerQueue;
4806
	},
4807

    
4808
	// Includes some event props shared by KeyEvent and MouseEvent
4809
	props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " +
4810
		"metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ),
4811

    
4812
	fixHooks: {},
4813

    
4814
	keyHooks: {
4815
		props: "char charCode key keyCode".split( " " ),
4816
		filter: function( event, original ) {
4817

    
4818
			// Add which for key events
4819
			if ( event.which == null ) {
4820
				event.which = original.charCode != null ? original.charCode : original.keyCode;
4821
			}
4822

    
4823
			return event;
4824
		}
4825
	},
4826

    
4827
	mouseHooks: {
4828
		props: ( "button buttons clientX clientY offsetX offsetY pageX pageY " +
4829
			"screenX screenY toElement" ).split( " " ),
4830
		filter: function( event, original ) {
4831
			var eventDoc, doc, body,
4832
				button = original.button;
4833

    
4834
			// Calculate pageX/Y if missing and clientX/Y available
4835
			if ( event.pageX == null && original.clientX != null ) {
4836
				eventDoc = event.target.ownerDocument || document;
4837
				doc = eventDoc.documentElement;
4838
				body = eventDoc.body;
4839

    
4840
				event.pageX = original.clientX +
4841
					( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) -
4842
					( doc && doc.clientLeft || body && body.clientLeft || 0 );
4843
				event.pageY = original.clientY +
4844
					( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) -
4845
					( doc && doc.clientTop  || body && body.clientTop  || 0 );
4846
			}
4847

    
4848
			// Add which for click: 1 === left; 2 === middle; 3 === right
4849
			// Note: button is not normalized, so don't use it
4850
			if ( !event.which && button !== undefined ) {
4851
				event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
4852
			}
4853

    
4854
			return event;
4855
		}
4856
	},
4857

    
4858
	fix: function( event ) {
4859
		if ( event[ jQuery.expando ] ) {
4860
			return event;
4861
		}
4862

    
4863
		// Create a writable copy of the event object and normalize some properties
4864
		var i, prop, copy,
4865
			type = event.type,
4866
			originalEvent = event,
4867
			fixHook = this.fixHooks[ type ];
4868

    
4869
		if ( !fixHook ) {
4870
			this.fixHooks[ type ] = fixHook =
4871
				rmouseEvent.test( type ) ? this.mouseHooks :
4872
				rkeyEvent.test( type ) ? this.keyHooks :
4873
				{};
4874
		}
4875
		copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
4876

    
4877
		event = new jQuery.Event( originalEvent );
4878

    
4879
		i = copy.length;
4880
		while ( i-- ) {
4881
			prop = copy[ i ];
4882
			event[ prop ] = originalEvent[ prop ];
4883
		}
4884

    
4885
		// Support: Cordova 2.5 (WebKit) (#13255)
4886
		// All events should have a target; Cordova deviceready doesn't
4887
		if ( !event.target ) {
4888
			event.target = document;
4889
		}
4890

    
4891
		// Support: Safari 6.0+, Chrome<28
4892
		// Target should not be a text node (#504, #13143)
4893
		if ( event.target.nodeType === 3 ) {
4894
			event.target = event.target.parentNode;
4895
		}
4896

    
4897
		return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
4898
	},
4899

    
4900
	special: {
4901
		load: {
4902

    
4903
			// Prevent triggered image.load events from bubbling to window.load
4904
			noBubble: true
4905
		},
4906
		focus: {
4907

    
4908
			// Fire native event if possible so blur/focus sequence is correct
4909
			trigger: function() {
4910
				if ( this !== safeActiveElement() && this.focus ) {
4911
					this.focus();
4912
					return false;
4913
				}
4914
			},
4915
			delegateType: "focusin"
4916
		},
4917
		blur: {
4918
			trigger: function() {
4919
				if ( this === safeActiveElement() && this.blur ) {
4920
					this.blur();
4921
					return false;
4922
				}
4923
			},
4924
			delegateType: "focusout"
4925
		},
4926
		click: {
4927

    
4928
			// For checkbox, fire native event so checked state will be right
4929
			trigger: function() {
4930
				if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
4931
					this.click();
4932
					return false;
4933
				}
4934
			},
4935

    
4936
			// For cross-browser consistency, don't fire native .click() on links
4937
			_default: function( event ) {
4938
				return jQuery.nodeName( event.target, "a" );
4939
			}
4940
		},
4941

    
4942
		beforeunload: {
4943
			postDispatch: function( event ) {
4944

    
4945
				// Support: Firefox 20+
4946
				// Firefox doesn't alert if the returnValue field is not set.
4947
				if ( event.result !== undefined && event.originalEvent ) {
4948
					event.originalEvent.returnValue = event.result;
4949
				}
4950
			}
4951
		}
4952
	}
4953
};
4954

    
4955
jQuery.removeEvent = function( elem, type, handle ) {
4956

    
4957
	// This "if" is needed for plain objects
4958
	if ( elem.removeEventListener ) {
4959
		elem.removeEventListener( type, handle );
4960
	}
4961
};
4962

    
4963
jQuery.Event = function( src, props ) {
4964

    
4965
	// Allow instantiation without the 'new' keyword
4966
	if ( !( this instanceof jQuery.Event ) ) {
4967
		return new jQuery.Event( src, props );
4968
	}
4969

    
4970
	// Event object
4971
	if ( src && src.type ) {
4972
		this.originalEvent = src;
4973
		this.type = src.type;
4974

    
4975
		// Events bubbling up the document may have been marked as prevented
4976
		// by a handler lower down the tree; reflect the correct value.
4977
		this.isDefaultPrevented = src.defaultPrevented ||
4978
				src.defaultPrevented === undefined &&
4979

    
4980
				// Support: Android<4.0
4981
				src.returnValue === false ?
4982
			returnTrue :
4983
			returnFalse;
4984

    
4985
	// Event type
4986
	} else {
4987
		this.type = src;
4988
	}
4989

    
4990
	// Put explicitly provided properties onto the event object
4991
	if ( props ) {
4992
		jQuery.extend( this, props );
4993
	}
4994

    
4995
	// Create a timestamp if incoming event doesn't have one
4996
	this.timeStamp = src && src.timeStamp || jQuery.now();
4997

    
4998
	// Mark it as fixed
4999
	this[ jQuery.expando ] = true;
5000
};
5001

    
5002
// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
5003
// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
5004
jQuery.Event.prototype = {
5005
	constructor: jQuery.Event,
5006
	isDefaultPrevented: returnFalse,
5007
	isPropagationStopped: returnFalse,
5008
	isImmediatePropagationStopped: returnFalse,
5009
	isSimulated: false,
5010

    
5011
	preventDefault: function() {
5012
		var e = this.originalEvent;
5013

    
5014
		this.isDefaultPrevented = returnTrue;
5015

    
5016
		if ( e && !this.isSimulated ) {
5017
			e.preventDefault();
5018
		}
5019
	},
5020
	stopPropagation: function() {
5021
		var e = this.originalEvent;
5022

    
5023
		this.isPropagationStopped = returnTrue;
5024

    
5025
		if ( e && !this.isSimulated ) {
5026
			e.stopPropagation();
5027
		}
5028
	},
5029
	stopImmediatePropagation: function() {
5030
		var e = this.originalEvent;
5031

    
5032
		this.isImmediatePropagationStopped = returnTrue;
5033

    
5034
		if ( e && !this.isSimulated ) {
5035
			e.stopImmediatePropagation();
5036
		}
5037

    
5038
		this.stopPropagation();
5039
	}
5040
};
5041

    
5042
// Create mouseenter/leave events using mouseover/out and event-time checks
5043
// so that event delegation works in jQuery.
5044
// Do the same for pointerenter/pointerleave and pointerover/pointerout
5045
//
5046
// Support: Safari 7 only
5047
// Safari sends mouseenter too often; see:
5048
// https://code.google.com/p/chromium/issues/detail?id=470258
5049
// for the description of the bug (it existed in older Chrome versions as well).
5050
jQuery.each( {
5051
	mouseenter: "mouseover",
5052
	mouseleave: "mouseout",
5053
	pointerenter: "pointerover",
5054
	pointerleave: "pointerout"
5055
}, function( orig, fix ) {
5056
	jQuery.event.special[ orig ] = {
5057
		delegateType: fix,
5058
		bindType: fix,
5059

    
5060
		handle: function( event ) {
5061
			var ret,
5062
				target = this,
5063
				related = event.relatedTarget,
5064
				handleObj = event.handleObj;
5065

    
5066
			// For mouseenter/leave call the handler if related is outside the target.
5067
			// NB: No relatedTarget if the mouse left/entered the browser window
5068
			if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
5069
				event.type = handleObj.origType;
5070
				ret = handleObj.handler.apply( this, arguments );
5071
				event.type = fix;
5072
			}
5073
			return ret;
5074
		}
5075
	};
5076
} );
5077

    
5078
jQuery.fn.extend( {
5079
	on: function( types, selector, data, fn ) {
5080
		return on( this, types, selector, data, fn );
5081
	},
5082
	one: function( types, selector, data, fn ) {
5083
		return on( this, types, selector, data, fn, 1 );
5084
	},
5085
	off: function( types, selector, fn ) {
5086
		var handleObj, type;
5087
		if ( types && types.preventDefault && types.handleObj ) {
5088

    
5089
			// ( event )  dispatched jQuery.Event
5090
			handleObj = types.handleObj;
5091
			jQuery( types.delegateTarget ).off(
5092
				handleObj.namespace ?
5093
					handleObj.origType + "." + handleObj.namespace :
5094
					handleObj.origType,
5095
				handleObj.selector,
5096
				handleObj.handler
5097
			);
5098
			return this;
5099
		}
5100
		if ( typeof types === "object" ) {
5101

    
5102
			// ( types-object [, selector] )
5103
			for ( type in types ) {
5104
				this.off( type, selector, types[ type ] );
5105
			}
5106
			return this;
5107
		}
5108
		if ( selector === false || typeof selector === "function" ) {
5109

    
5110
			// ( types [, fn] )
5111
			fn = selector;
5112
			selector = undefined;
5113
		}
5114
		if ( fn === false ) {
5115
			fn = returnFalse;
5116
		}
5117
		return this.each( function() {
5118
			jQuery.event.remove( this, types, fn, selector );
5119
		} );
5120
	}
5121
} );
5122

    
5123

    
5124
var
5125
	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,
5126

    
5127
	// Support: IE 10-11, Edge 10240+
5128
	// In IE/Edge using regex groups here causes severe slowdowns.
5129
	// See https://connect.microsoft.com/IE/feedback/details/1736512/
5130
	rnoInnerhtml = /<script|<style|<link/i,
5131

    
5132
	// checked="checked" or checked
5133
	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5134
	rscriptTypeMasked = /^true\/(.*)/,
5135
	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
5136

    
5137
// Manipulating tables requires a tbody
5138
function manipulationTarget( elem, content ) {
5139
	return jQuery.nodeName( elem, "table" ) &&
5140
		jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
5141

    
5142
		elem.getElementsByTagName( "tbody" )[ 0 ] ||
5143
			elem.appendChild( elem.ownerDocument.createElement( "tbody" ) ) :
5144
		elem;
5145
}
5146

    
5147
// Replace/restore the type attribute of script elements for safe DOM manipulation
5148
function disableScript( elem ) {
5149
	elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
5150
	return elem;
5151
}
5152
function restoreScript( elem ) {
5153
	var match = rscriptTypeMasked.exec( elem.type );
5154

    
5155
	if ( match ) {
5156
		elem.type = match[ 1 ];
5157
	} else {
5158
		elem.removeAttribute( "type" );
5159
	}
5160

    
5161
	return elem;
5162
}
5163

    
5164
function cloneCopyEvent( src, dest ) {
5165
	var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
5166

    
5167
	if ( dest.nodeType !== 1 ) {
5168
		return;
5169
	}
5170

    
5171
	// 1. Copy private data: events, handlers, etc.
5172
	if ( dataPriv.hasData( src ) ) {
5173
		pdataOld = dataPriv.access( src );
5174
		pdataCur = dataPriv.set( dest, pdataOld );
5175
		events = pdataOld.events;
5176

    
5177
		if ( events ) {
5178
			delete pdataCur.handle;
5179
			pdataCur.events = {};
5180

    
5181
			for ( type in events ) {
5182
				for ( i = 0, l = events[ type ].length; i < l; i++ ) {
5183
					jQuery.event.add( dest, type, events[ type ][ i ] );
5184
				}
5185
			}
5186
		}
5187
	}
5188

    
5189
	// 2. Copy user data
5190
	if ( dataUser.hasData( src ) ) {
5191
		udataOld = dataUser.access( src );
5192
		udataCur = jQuery.extend( {}, udataOld );
5193

    
5194
		dataUser.set( dest, udataCur );
5195
	}
5196
}
5197

    
5198
// Fix IE bugs, see support tests
5199
function fixInput( src, dest ) {
5200
	var nodeName = dest.nodeName.toLowerCase();
5201

    
5202
	// Fails to persist the checked state of a cloned checkbox or radio button.
5203
	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
5204
		dest.checked = src.checked;
5205

    
5206
	// Fails to return the selected option to the default selected state when cloning options
5207
	} else if ( nodeName === "input" || nodeName === "textarea" ) {
5208
		dest.defaultValue = src.defaultValue;
5209
	}
5210
}
5211

    
5212
function domManip( collection, args, callback, ignored ) {
5213

    
5214
	// Flatten any nested arrays
5215
	args = concat.apply( [], args );
5216

    
5217
	var fragment, first, scripts, hasScripts, node, doc,
5218
		i = 0,
5219
		l = collection.length,
5220
		iNoClone = l - 1,
5221
		value = args[ 0 ],
5222
		isFunction = jQuery.isFunction( value );
5223

    
5224
	// We can't cloneNode fragments that contain checked, in WebKit
5225
	if ( isFunction ||
5226
			( l > 1 && typeof value === "string" &&
5227
				!support.checkClone && rchecked.test( value ) ) ) {
5228
		return collection.each( function( index ) {
5229
			var self = collection.eq( index );
5230
			if ( isFunction ) {
5231
				args[ 0 ] = value.call( this, index, self.html() );
5232
			}
5233
			domManip( self, args, callback, ignored );
5234
		} );
5235
	}
5236

    
5237
	if ( l ) {
5238
		fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
5239
		first = fragment.firstChild;
5240

    
5241
		if ( fragment.childNodes.length === 1 ) {
5242
			fragment = first;
5243
		}
5244

    
5245
		// Require either new content or an interest in ignored elements to invoke the callback
5246
		if ( first || ignored ) {
5247
			scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
5248
			hasScripts = scripts.length;
5249

    
5250
			// Use the original fragment for the last item
5251
			// instead of the first because it can end up
5252
			// being emptied incorrectly in certain situations (#8070).
5253
			for ( ; i < l; i++ ) {
5254
				node = fragment;
5255

    
5256
				if ( i !== iNoClone ) {
5257
					node = jQuery.clone( node, true, true );
5258

    
5259
					// Keep references to cloned scripts for later restoration
5260
					if ( hasScripts ) {
5261

    
5262
						// Support: Android<4.1, PhantomJS<2
5263
						// push.apply(_, arraylike) throws on ancient WebKit
5264
						jQuery.merge( scripts, getAll( node, "script" ) );
5265
					}
5266
				}
5267

    
5268
				callback.call( collection[ i ], node, i );
5269
			}
5270

    
5271
			if ( hasScripts ) {
5272
				doc = scripts[ scripts.length - 1 ].ownerDocument;
5273

    
5274
				// Reenable scripts
5275
				jQuery.map( scripts, restoreScript );
5276

    
5277
				// Evaluate executable scripts on first document insertion
5278
				for ( i = 0; i < hasScripts; i++ ) {
5279
					node = scripts[ i ];
5280
					if ( rscriptType.test( node.type || "" ) &&
5281
						!dataPriv.access( node, "globalEval" ) &&
5282
						jQuery.contains( doc, node ) ) {
5283

    
5284
						if ( node.src ) {
5285

    
5286
							// Optional AJAX dependency, but won't run scripts if not present
5287
							if ( jQuery._evalUrl ) {
5288
								jQuery._evalUrl( node.src );
5289
							}
5290
						} else {
5291
							jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) );
5292
						}
5293
					}
5294
				}
5295
			}
5296
		}
5297
	}
5298

    
5299
	return collection;
5300
}
5301

    
5302
function remove( elem, selector, keepData ) {
5303
	var node,
5304
		nodes = selector ? jQuery.filter( selector, elem ) : elem,
5305
		i = 0;
5306

    
5307
	for ( ; ( node = nodes[ i ] ) != null; i++ ) {
5308
		if ( !keepData && node.nodeType === 1 ) {
5309
			jQuery.cleanData( getAll( node ) );
5310
		}
5311

    
5312
		if ( node.parentNode ) {
5313
			if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
5314
				setGlobalEval( getAll( node, "script" ) );
5315
			}
5316
			node.parentNode.removeChild( node );
5317
		}
5318
	}
5319

    
5320
	return elem;
5321
}
5322

    
5323
jQuery.extend( {
5324
	htmlPrefilter: function( html ) {
5325
		return html.replace( rxhtmlTag, "<$1></$2>" );
5326
	},
5327

    
5328
	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
5329
		var i, l, srcElements, destElements,
5330
			clone = elem.cloneNode( true ),
5331
			inPage = jQuery.contains( elem.ownerDocument, elem );
5332

    
5333
		// Fix IE cloning issues
5334
		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
5335
				!jQuery.isXMLDoc( elem ) ) {
5336

    
5337
			// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
5338
			destElements = getAll( clone );
5339
			srcElements = getAll( elem );
5340

    
5341
			for ( i = 0, l = srcElements.length; i < l; i++ ) {
5342
				fixInput( srcElements[ i ], destElements[ i ] );
5343
			}
5344
		}
5345

    
5346
		// Copy the events from the original to the clone
5347
		if ( dataAndEvents ) {
5348
			if ( deepDataAndEvents ) {
5349
				srcElements = srcElements || getAll( elem );
5350
				destElements = destElements || getAll( clone );
5351

    
5352
				for ( i = 0, l = srcElements.length; i < l; i++ ) {
5353
					cloneCopyEvent( srcElements[ i ], destElements[ i ] );
5354
				}
5355
			} else {
5356
				cloneCopyEvent( elem, clone );
5357
			}
5358
		}
5359

    
5360
		// Preserve script evaluation history
5361
		destElements = getAll( clone, "script" );
5362
		if ( destElements.length > 0 ) {
5363
			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
5364
		}
5365

    
5366
		// Return the cloned set
5367
		return clone;
5368
	},
5369

    
5370
	cleanData: function( elems ) {
5371
		var data, elem, type,
5372
			special = jQuery.event.special,
5373
			i = 0;
5374

    
5375
		for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
5376
			if ( acceptData( elem ) ) {
5377
				if ( ( data = elem[ dataPriv.expando ] ) ) {
5378
					if ( data.events ) {
5379
						for ( type in data.events ) {
5380
							if ( special[ type ] ) {
5381
								jQuery.event.remove( elem, type );
5382

    
5383
							// This is a shortcut to avoid jQuery.event.remove's overhead
5384
							} else {
5385
								jQuery.removeEvent( elem, type, data.handle );
5386
							}
5387
						}
5388
					}
5389

    
5390
					// Support: Chrome <= 35-45+
5391
					// Assign undefined instead of using delete, see Data#remove
5392
					elem[ dataPriv.expando ] = undefined;
5393
				}
5394
				if ( elem[ dataUser.expando ] ) {
5395

    
5396
					// Support: Chrome <= 35-45+
5397
					// Assign undefined instead of using delete, see Data#remove
5398
					elem[ dataUser.expando ] = undefined;
5399
				}
5400
			}
5401
		}
5402
	}
5403
} );
5404

    
5405
jQuery.fn.extend( {
5406

    
5407
	// Keep domManip exposed until 3.0 (gh-2225)
5408
	domManip: domManip,
5409

    
5410
	detach: function( selector ) {
5411
		return remove( this, selector, true );
5412
	},
5413

    
5414
	remove: function( selector ) {
5415
		return remove( this, selector );
5416
	},
5417

    
5418
	text: function( value ) {
5419
		return access( this, function( value ) {
5420
			return value === undefined ?
5421
				jQuery.text( this ) :
5422
				this.empty().each( function() {
5423
					if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5424
						this.textContent = value;
5425
					}
5426
				} );
5427
		}, null, value, arguments.length );
5428
	},
5429

    
5430
	append: function() {
5431
		return domManip( this, arguments, function( elem ) {
5432
			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5433
				var target = manipulationTarget( this, elem );
5434
				target.appendChild( elem );
5435
			}
5436
		} );
5437
	},
5438

    
5439
	prepend: function() {
5440
		return domManip( this, arguments, function( elem ) {
5441
			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5442
				var target = manipulationTarget( this, elem );
5443
				target.insertBefore( elem, target.firstChild );
5444
			}
5445
		} );
5446
	},
5447

    
5448
	before: function() {
5449
		return domManip( this, arguments, function( elem ) {
5450
			if ( this.parentNode ) {
5451
				this.parentNode.insertBefore( elem, this );
5452
			}
5453
		} );
5454
	},
5455

    
5456
	after: function() {
5457
		return domManip( this, arguments, function( elem ) {
5458
			if ( this.parentNode ) {
5459
				this.parentNode.insertBefore( elem, this.nextSibling );
5460
			}
5461
		} );
5462
	},
5463

    
5464
	empty: function() {
5465
		var elem,
5466
			i = 0;
5467

    
5468
		for ( ; ( elem = this[ i ] ) != null; i++ ) {
5469
			if ( elem.nodeType === 1 ) {
5470

    
5471
				// Prevent memory leaks
5472
				jQuery.cleanData( getAll( elem, false ) );
5473

    
5474
				// Remove any remaining nodes
5475
				elem.textContent = "";
5476
			}
5477
		}
5478

    
5479
		return this;
5480
	},
5481

    
5482
	clone: function( dataAndEvents, deepDataAndEvents ) {
5483
		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5484
		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5485

    
5486
		return this.map( function() {
5487
			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5488
		} );
5489
	},
5490

    
5491
	html: function( value ) {
5492
		return access( this, function( value ) {
5493
			var elem = this[ 0 ] || {},
5494
				i = 0,
5495
				l = this.length;
5496

    
5497
			if ( value === undefined && elem.nodeType === 1 ) {
5498
				return elem.innerHTML;
5499
			}
5500

    
5501
			// See if we can take a shortcut and just use innerHTML
5502
			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
5503
				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
5504

    
5505
				value = jQuery.htmlPrefilter( value );
5506

    
5507
				try {
5508
					for ( ; i < l; i++ ) {
5509
						elem = this[ i ] || {};
5510

    
5511
						// Remove element nodes and prevent memory leaks
5512
						if ( elem.nodeType === 1 ) {
5513
							jQuery.cleanData( getAll( elem, false ) );
5514
							elem.innerHTML = value;
5515
						}
5516
					}
5517

    
5518
					elem = 0;
5519

    
5520
				// If using innerHTML throws an exception, use the fallback method
5521
				} catch ( e ) {}
5522
			}
5523

    
5524
			if ( elem ) {
5525
				this.empty().append( value );
5526
			}
5527
		}, null, value, arguments.length );
5528
	},
5529

    
5530
	replaceWith: function() {
5531
		var ignored = [];
5532

    
5533
		// Make the changes, replacing each non-ignored context element with the new content
5534
		return domManip( this, arguments, function( elem ) {
5535
			var parent = this.parentNode;
5536

    
5537
			if ( jQuery.inArray( this, ignored ) < 0 ) {
5538
				jQuery.cleanData( getAll( this ) );
5539
				if ( parent ) {
5540
					parent.replaceChild( elem, this );
5541
				}
5542
			}
5543

    
5544
		// Force callback invocation
5545
		}, ignored );
5546
	}
5547
} );
5548

    
5549
jQuery.each( {
5550
	appendTo: "append",
5551
	prependTo: "prepend",
5552
	insertBefore: "before",
5553
	insertAfter: "after",
5554
	replaceAll: "replaceWith"
5555
}, function( name, original ) {
5556
	jQuery.fn[ name ] = function( selector ) {
5557
		var elems,
5558
			ret = [],
5559
			insert = jQuery( selector ),
5560
			last = insert.length - 1,
5561
			i = 0;
5562

    
5563
		for ( ; i <= last; i++ ) {
5564
			elems = i === last ? this : this.clone( true );
5565
			jQuery( insert[ i ] )[ original ]( elems );
5566

    
5567
			// Support: QtWebKit
5568
			// .get() because push.apply(_, arraylike) throws
5569
			push.apply( ret, elems.get() );
5570
		}
5571

    
5572
		return this.pushStack( ret );
5573
	};
5574
} );
5575

    
5576

    
5577
var iframe,
5578
	elemdisplay = {
5579

    
5580
		// Support: Firefox
5581
		// We have to pre-define these values for FF (#10227)
5582
		HTML: "block",
5583
		BODY: "block"
5584
	};
5585

    
5586
/**
5587
 * Retrieve the actual display of a element
5588
 * @param {String} name nodeName of the element
5589
 * @param {Object} doc Document object
5590
 */
5591

    
5592
// Called only from within defaultDisplay
5593
function actualDisplay( name, doc ) {
5594
	var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
5595

    
5596
		display = jQuery.css( elem[ 0 ], "display" );
5597

    
5598
	// We don't have any data stored on the element,
5599
	// so use "detach" method as fast way to get rid of the element
5600
	elem.detach();
5601

    
5602
	return display;
5603
}
5604

    
5605
/**
5606
 * Try to determine the default display value of an element
5607
 * @param {String} nodeName
5608
 */
5609
function defaultDisplay( nodeName ) {
5610
	var doc = document,
5611
		display = elemdisplay[ nodeName ];
5612

    
5613
	if ( !display ) {
5614
		display = actualDisplay( nodeName, doc );
5615

    
5616
		// If the simple way fails, read from inside an iframe
5617
		if ( display === "none" || !display ) {
5618

    
5619
			// Use the already-created iframe if possible
5620
			iframe = ( iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" ) )
5621
				.appendTo( doc.documentElement );
5622

    
5623
			// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
5624
			doc = iframe[ 0 ].contentDocument;
5625

    
5626
			// Support: IE
5627
			doc.write();
5628
			doc.close();
5629

    
5630
			display = actualDisplay( nodeName, doc );
5631
			iframe.detach();
5632
		}
5633

    
5634
		// Store the correct default display
5635
		elemdisplay[ nodeName ] = display;
5636
	}
5637

    
5638
	return display;
5639
}
5640
var rmargin = ( /^margin/ );
5641

    
5642
var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
5643

    
5644
var getStyles = function( elem ) {
5645

    
5646
		// Support: IE<=11+, Firefox<=30+ (#15098, #14150)
5647
		// IE throws on elements created in popups
5648
		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
5649
		var view = elem.ownerDocument.defaultView;
5650

    
5651
		if ( !view || !view.opener ) {
5652
			view = window;
5653
		}
5654

    
5655
		return view.getComputedStyle( elem );
5656
	};
5657

    
5658
var swap = function( elem, options, callback, args ) {
5659
	var ret, name,
5660
		old = {};
5661

    
5662
	// Remember the old values, and insert the new ones
5663
	for ( name in options ) {
5664
		old[ name ] = elem.style[ name ];
5665
		elem.style[ name ] = options[ name ];
5666
	}
5667

    
5668
	ret = callback.apply( elem, args || [] );
5669

    
5670
	// Revert the old values
5671
	for ( name in options ) {
5672
		elem.style[ name ] = old[ name ];
5673
	}
5674

    
5675
	return ret;
5676
};
5677

    
5678

    
5679
var documentElement = document.documentElement;
5680

    
5681

    
5682

    
5683
( function() {
5684
	var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
5685
		container = document.createElement( "div" ),
5686
		div = document.createElement( "div" );
5687

    
5688
	// Finish early in limited (non-browser) environments
5689
	if ( !div.style ) {
5690
		return;
5691
	}
5692

    
5693
	// Support: IE9-11+
5694
	// Style of cloned element affects source element cloned (#8908)
5695
	div.style.backgroundClip = "content-box";
5696
	div.cloneNode( true ).style.backgroundClip = "";
5697
	support.clearCloneStyle = div.style.backgroundClip === "content-box";
5698

    
5699
	container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
5700
		"padding:0;margin-top:1px;position:absolute";
5701
	container.appendChild( div );
5702

    
5703
	// Executing both pixelPosition & boxSizingReliable tests require only one layout
5704
	// so they're executed at the same time to save the second computation.
5705
	function computeStyleTests() {
5706
		div.style.cssText =
5707

    
5708
			// Support: Firefox<29, Android 2.3
5709
			// Vendor-prefix box-sizing
5710
			"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;" +
5711
			"position:relative;display:block;" +
5712
			"margin:auto;border:1px;padding:1px;" +
5713
			"top:1%;width:50%";
5714
		div.innerHTML = "";
5715
		documentElement.appendChild( container );
5716

    
5717
		var divStyle = window.getComputedStyle( div );
5718
		pixelPositionVal = divStyle.top !== "1%";
5719
		reliableMarginLeftVal = divStyle.marginLeft === "2px";
5720
		boxSizingReliableVal = divStyle.width === "4px";
5721

    
5722
		// Support: Android 4.0 - 4.3 only
5723
		// Some styles come back with percentage values, even though they shouldn't
5724
		div.style.marginRight = "50%";
5725
		pixelMarginRightVal = divStyle.marginRight === "4px";
5726

    
5727
		documentElement.removeChild( container );
5728
	}
5729

    
5730
	jQuery.extend( support, {
5731
		pixelPosition: function() {
5732

    
5733
			// This test is executed only once but we still do memoizing
5734
			// since we can use the boxSizingReliable pre-computing.
5735
			// No need to check if the test was already performed, though.
5736
			computeStyleTests();
5737
			return pixelPositionVal;
5738
		},
5739
		boxSizingReliable: function() {
5740
			if ( boxSizingReliableVal == null ) {
5741
				computeStyleTests();
5742
			}
5743
			return boxSizingReliableVal;
5744
		},
5745
		pixelMarginRight: function() {
5746

    
5747
			// Support: Android 4.0-4.3
5748
			// We're checking for boxSizingReliableVal here instead of pixelMarginRightVal
5749
			// since that compresses better and they're computed together anyway.
5750
			if ( boxSizingReliableVal == null ) {
5751
				computeStyleTests();
5752
			}
5753
			return pixelMarginRightVal;
5754
		},
5755
		reliableMarginLeft: function() {
5756

    
5757
			// Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37
5758
			if ( boxSizingReliableVal == null ) {
5759
				computeStyleTests();
5760
			}
5761
			return reliableMarginLeftVal;
5762
		},
5763
		reliableMarginRight: function() {
5764

    
5765
			// Support: Android 2.3
5766
			// Check if div with explicit width and no margin-right incorrectly
5767
			// gets computed margin-right based on width of container. (#3333)
5768
			// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
5769
			// This support function is only executed once so no memoizing is needed.
5770
			var ret,
5771
				marginDiv = div.appendChild( document.createElement( "div" ) );
5772

    
5773
			// Reset CSS: box-sizing; display; margin; border; padding
5774
			marginDiv.style.cssText = div.style.cssText =
5775

    
5776
				// Support: Android 2.3
5777
				// Vendor-prefix box-sizing
5778
				"-webkit-box-sizing:content-box;box-sizing:content-box;" +
5779
				"display:block;margin:0;border:0;padding:0";
5780
			marginDiv.style.marginRight = marginDiv.style.width = "0";
5781
			div.style.width = "1px";
5782
			documentElement.appendChild( container );
5783

    
5784
			ret = !parseFloat( window.getComputedStyle( marginDiv ).marginRight );
5785

    
5786
			documentElement.removeChild( container );
5787
			div.removeChild( marginDiv );
5788

    
5789
			return ret;
5790
		}
5791
	} );
5792
} )();
5793

    
5794

    
5795
function curCSS( elem, name, computed ) {
5796
	var width, minWidth, maxWidth, ret,
5797
		style = elem.style;
5798

    
5799
	computed = computed || getStyles( elem );
5800
	ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;
5801

    
5802
	// Support: Opera 12.1x only
5803
	// Fall back to style even without computed
5804
	// computed is undefined for elems on document fragments
5805
	if ( ( ret === "" || ret === undefined ) && !jQuery.contains( elem.ownerDocument, elem ) ) {
5806
		ret = jQuery.style( elem, name );
5807
	}
5808

    
5809
	// Support: IE9
5810
	// getPropertyValue is only needed for .css('filter') (#12537)
5811
	if ( computed ) {
5812

    
5813
		// A tribute to the "awesome hack by Dean Edwards"
5814
		// Android Browser returns percentage for some values,
5815
		// but width seems to be reliably pixels.
5816
		// This is against the CSSOM draft spec:
5817
		// http://dev.w3.org/csswg/cssom/#resolved-values
5818
		if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
5819

    
5820
			// Remember the original values
5821
			width = style.width;
5822
			minWidth = style.minWidth;
5823
			maxWidth = style.maxWidth;
5824

    
5825
			// Put in the new values to get a computed value out
5826
			style.minWidth = style.maxWidth = style.width = ret;
5827
			ret = computed.width;
5828

    
5829
			// Revert the changed values
5830
			style.width = width;
5831
			style.minWidth = minWidth;
5832
			style.maxWidth = maxWidth;
5833
		}
5834
	}
5835

    
5836
	return ret !== undefined ?
5837

    
5838
		// Support: IE9-11+
5839
		// IE returns zIndex value as an integer.
5840
		ret + "" :
5841
		ret;
5842
}
5843

    
5844

    
5845
function addGetHookIf( conditionFn, hookFn ) {
5846

    
5847
	// Define the hook, we'll check on the first run if it's really needed.
5848
	return {
5849
		get: function() {
5850
			if ( conditionFn() ) {
5851

    
5852
				// Hook not needed (or it's not possible to use it due
5853
				// to missing dependency), remove it.
5854
				delete this.get;
5855
				return;
5856
			}
5857

    
5858
			// Hook needed; redefine it so that the support test is not executed again.
5859
			return ( this.get = hookFn ).apply( this, arguments );
5860
		}
5861
	};
5862
}
5863

    
5864

    
5865
var
5866

    
5867
	// Swappable if display is none or starts with table
5868
	// except "table", "table-cell", or "table-caption"
5869
	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
5870
	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
5871

    
5872
	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
5873
	cssNormalTransform = {
5874
		letterSpacing: "0",
5875
		fontWeight: "400"
5876
	},
5877

    
5878
	cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
5879
	emptyStyle = document.createElement( "div" ).style;
5880

    
5881
// Return a css property mapped to a potentially vendor prefixed property
5882
function vendorPropName( name ) {
5883

    
5884
	// Shortcut for names that are not vendor prefixed
5885
	if ( name in emptyStyle ) {
5886
		return name;
5887
	}
5888

    
5889
	// Check for vendor prefixed names
5890
	var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
5891
		i = cssPrefixes.length;
5892

    
5893
	while ( i-- ) {
5894
		name = cssPrefixes[ i ] + capName;
5895
		if ( name in emptyStyle ) {
5896
			return name;
5897
		}
5898
	}
5899
}
5900

    
5901
function setPositiveNumber( elem, value, subtract ) {
5902

    
5903
	// Any relative (+/-) values have already been
5904
	// normalized at this point
5905
	var matches = rcssNum.exec( value );
5906
	return matches ?
5907

    
5908
		// Guard against undefined "subtract", e.g., when used as in cssHooks
5909
		Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
5910
		value;
5911
}
5912

    
5913
function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
5914
	var i = extra === ( isBorderBox ? "border" : "content" ) ?
5915

    
5916
		// If we already have the right measurement, avoid augmentation
5917
		4 :
5918

    
5919
		// Otherwise initialize for horizontal or vertical properties
5920
		name === "width" ? 1 : 0,
5921

    
5922
		val = 0;
5923

    
5924
	for ( ; i < 4; i += 2 ) {
5925

    
5926
		// Both box models exclude margin, so add it if we want it
5927
		if ( extra === "margin" ) {
5928
			val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
5929
		}
5930

    
5931
		if ( isBorderBox ) {
5932

    
5933
			// border-box includes padding, so remove it if we want content
5934
			if ( extra === "content" ) {
5935
				val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
5936
			}
5937

    
5938
			// At this point, extra isn't border nor margin, so remove border
5939
			if ( extra !== "margin" ) {
5940
				val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
5941
			}
5942
		} else {
5943

    
5944
			// At this point, extra isn't content, so add padding
5945
			val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
5946

    
5947
			// At this point, extra isn't content nor padding, so add border
5948
			if ( extra !== "padding" ) {
5949
				val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
5950
			}
5951
		}
5952
	}
5953

    
5954
	return val;
5955
}
5956

    
5957
function getWidthOrHeight( elem, name, extra ) {
5958

    
5959
	// Start with offset property, which is equivalent to the border-box value
5960
	var valueIsBorderBox = true,
5961
		val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
5962
		styles = getStyles( elem ),
5963
		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
5964

    
5965
	// Some non-html elements return undefined for offsetWidth, so check for null/undefined
5966
	// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
5967
	// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
5968
	if ( val <= 0 || val == null ) {
5969

    
5970
		// Fall back to computed then uncomputed css if necessary
5971
		val = curCSS( elem, name, styles );
5972
		if ( val < 0 || val == null ) {
5973
			val = elem.style[ name ];
5974
		}
5975

    
5976
		// Computed unit is not pixels. Stop here and return.
5977
		if ( rnumnonpx.test( val ) ) {
5978
			return val;
5979
		}
5980

    
5981
		// Check for style in case a browser which returns unreliable values
5982
		// for getComputedStyle silently falls back to the reliable elem.style
5983
		valueIsBorderBox = isBorderBox &&
5984
			( support.boxSizingReliable() || val === elem.style[ name ] );
5985

    
5986
		// Normalize "", auto, and prepare for extra
5987
		val = parseFloat( val ) || 0;
5988
	}
5989

    
5990
	// Use the active box-sizing model to add/subtract irrelevant styles
5991
	return ( val +
5992
		augmentWidthOrHeight(
5993
			elem,
5994
			name,
5995
			extra || ( isBorderBox ? "border" : "content" ),
5996
			valueIsBorderBox,
5997
			styles
5998
		)
5999
	) + "px";
6000
}
6001

    
6002
function showHide( elements, show ) {
6003
	var display, elem, hidden,
6004
		values = [],
6005
		index = 0,
6006
		length = elements.length;
6007

    
6008
	for ( ; index < length; index++ ) {
6009
		elem = elements[ index ];
6010
		if ( !elem.style ) {
6011
			continue;
6012
		}
6013

    
6014
		values[ index ] = dataPriv.get( elem, "olddisplay" );
6015
		display = elem.style.display;
6016
		if ( show ) {
6017

    
6018
			// Reset the inline display of this element to learn if it is
6019
			// being hidden by cascaded rules or not
6020
			if ( !values[ index ] && display === "none" ) {
6021
				elem.style.display = "";
6022
			}
6023

    
6024
			// Set elements which have been overridden with display: none
6025
			// in a stylesheet to whatever the default browser style is
6026
			// for such an element
6027
			if ( elem.style.display === "" && isHidden( elem ) ) {
6028
				values[ index ] = dataPriv.access(
6029
					elem,
6030
					"olddisplay",
6031
					defaultDisplay( elem.nodeName )
6032
				);
6033
			}
6034
		} else {
6035
			hidden = isHidden( elem );
6036

    
6037
			if ( display !== "none" || !hidden ) {
6038
				dataPriv.set(
6039
					elem,
6040
					"olddisplay",
6041
					hidden ? display : jQuery.css( elem, "display" )
6042
				);
6043
			}
6044
		}
6045
	}
6046

    
6047
	// Set the display of most of the elements in a second loop
6048
	// to avoid the constant reflow
6049
	for ( index = 0; index < length; index++ ) {
6050
		elem = elements[ index ];
6051
		if ( !elem.style ) {
6052
			continue;
6053
		}
6054
		if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
6055
			elem.style.display = show ? values[ index ] || "" : "none";
6056
		}
6057
	}
6058

    
6059
	return elements;
6060
}
6061

    
6062
jQuery.extend( {
6063

    
6064
	// Add in style property hooks for overriding the default
6065
	// behavior of getting and setting a style property
6066
	cssHooks: {
6067
		opacity: {
6068
			get: function( elem, computed ) {
6069
				if ( computed ) {
6070

    
6071
					// We should always get a number back from opacity
6072
					var ret = curCSS( elem, "opacity" );
6073
					return ret === "" ? "1" : ret;
6074
				}
6075
			}
6076
		}
6077
	},
6078

    
6079
	// Don't automatically add "px" to these possibly-unitless properties
6080
	cssNumber: {
6081
		"animationIterationCount": true,
6082
		"columnCount": true,
6083
		"fillOpacity": true,
6084
		"flexGrow": true,
6085
		"flexShrink": true,
6086
		"fontWeight": true,
6087
		"lineHeight": true,
6088
		"opacity": true,
6089
		"order": true,
6090
		"orphans": true,
6091
		"widows": true,
6092
		"zIndex": true,
6093
		"zoom": true
6094
	},
6095

    
6096
	// Add in properties whose names you wish to fix before
6097
	// setting or getting the value
6098
	cssProps: {
6099
		"float": "cssFloat"
6100
	},
6101

    
6102
	// Get and set the style property on a DOM Node
6103
	style: function( elem, name, value, extra ) {
6104

    
6105
		// Don't set styles on text and comment nodes
6106
		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6107
			return;
6108
		}
6109

    
6110
		// Make sure that we're working with the right name
6111
		var ret, type, hooks,
6112
			origName = jQuery.camelCase( name ),
6113
			style = elem.style;
6114

    
6115
		name = jQuery.cssProps[ origName ] ||
6116
			( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
6117

    
6118
		// Gets hook for the prefixed version, then unprefixed version
6119
		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6120

    
6121
		// Check if we're setting a value
6122
		if ( value !== undefined ) {
6123
			type = typeof value;
6124

    
6125
			// Convert "+=" or "-=" to relative numbers (#7345)
6126
			if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
6127
				value = adjustCSS( elem, name, ret );
6128

    
6129
				// Fixes bug #9237
6130
				type = "number";
6131
			}
6132

    
6133
			// Make sure that null and NaN values aren't set (#7116)
6134
			if ( value == null || value !== value ) {
6135
				return;
6136
			}
6137

    
6138
			// If a number was passed in, add the unit (except for certain CSS properties)
6139
			if ( type === "number" ) {
6140
				value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
6141
			}
6142

    
6143
			// Support: IE9-11+
6144
			// background-* props affect original clone's values
6145
			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
6146
				style[ name ] = "inherit";
6147
			}
6148

    
6149
			// If a hook was provided, use that value, otherwise just set the specified value
6150
			if ( !hooks || !( "set" in hooks ) ||
6151
				( value = hooks.set( elem, value, extra ) ) !== undefined ) {
6152

    
6153
				style[ name ] = value;
6154
			}
6155

    
6156
		} else {
6157

    
6158
			// If a hook was provided get the non-computed value from there
6159
			if ( hooks && "get" in hooks &&
6160
				( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
6161

    
6162
				return ret;
6163
			}
6164

    
6165
			// Otherwise just get the value from the style object
6166
			return style[ name ];
6167
		}
6168
	},
6169

    
6170
	css: function( elem, name, extra, styles ) {
6171
		var val, num, hooks,
6172
			origName = jQuery.camelCase( name );
6173

    
6174
		// Make sure that we're working with the right name
6175
		name = jQuery.cssProps[ origName ] ||
6176
			( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
6177

    
6178
		// Try prefixed name followed by the unprefixed name
6179
		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6180

    
6181
		// If a hook was provided get the computed value from there
6182
		if ( hooks && "get" in hooks ) {
6183
			val = hooks.get( elem, true, extra );
6184
		}
6185

    
6186
		// Otherwise, if a way to get the computed value exists, use that
6187
		if ( val === undefined ) {
6188
			val = curCSS( elem, name, styles );
6189
		}
6190

    
6191
		// Convert "normal" to computed value
6192
		if ( val === "normal" && name in cssNormalTransform ) {
6193
			val = cssNormalTransform[ name ];
6194
		}
6195

    
6196
		// Make numeric if forced or a qualifier was provided and val looks numeric
6197
		if ( extra === "" || extra ) {
6198
			num = parseFloat( val );
6199
			return extra === true || isFinite( num ) ? num || 0 : val;
6200
		}
6201
		return val;
6202
	}
6203
} );
6204

    
6205
jQuery.each( [ "height", "width" ], function( i, name ) {
6206
	jQuery.cssHooks[ name ] = {
6207
		get: function( elem, computed, extra ) {
6208
			if ( computed ) {
6209

    
6210
				// Certain elements can have dimension info if we invisibly show them
6211
				// but it must have a current display style that would benefit
6212
				return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
6213
					elem.offsetWidth === 0 ?
6214
						swap( elem, cssShow, function() {
6215
							return getWidthOrHeight( elem, name, extra );
6216
						} ) :
6217
						getWidthOrHeight( elem, name, extra );
6218
			}
6219
		},
6220

    
6221
		set: function( elem, value, extra ) {
6222
			var matches,
6223
				styles = extra && getStyles( elem ),
6224
				subtract = extra && augmentWidthOrHeight(
6225
					elem,
6226
					name,
6227
					extra,
6228
					jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
6229
					styles
6230
				);
6231

    
6232
			// Convert to pixels if value adjustment is needed
6233
			if ( subtract && ( matches = rcssNum.exec( value ) ) &&
6234
				( matches[ 3 ] || "px" ) !== "px" ) {
6235

    
6236
				elem.style[ name ] = value;
6237
				value = jQuery.css( elem, name );
6238
			}
6239

    
6240
			return setPositiveNumber( elem, value, subtract );
6241
		}
6242
	};
6243
} );
6244

    
6245
jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
6246
	function( elem, computed ) {
6247
		if ( computed ) {
6248
			return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
6249
				elem.getBoundingClientRect().left -
6250
					swap( elem, { marginLeft: 0 }, function() {
6251
						return elem.getBoundingClientRect().left;
6252
					} )
6253
				) + "px";
6254
		}
6255
	}
6256
);
6257

    
6258
// Support: Android 2.3
6259
jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
6260
	function( elem, computed ) {
6261
		if ( computed ) {
6262
			return swap( elem, { "display": "inline-block" },
6263
				curCSS, [ elem, "marginRight" ] );
6264
		}
6265
	}
6266
);
6267

    
6268
// These hooks are used by animate to expand properties
6269
jQuery.each( {
6270
	margin: "",
6271
	padding: "",
6272
	border: "Width"
6273
}, function( prefix, suffix ) {
6274
	jQuery.cssHooks[ prefix + suffix ] = {
6275
		expand: function( value ) {
6276
			var i = 0,
6277
				expanded = {},
6278

    
6279
				// Assumes a single number if not a string
6280
				parts = typeof value === "string" ? value.split( " " ) : [ value ];
6281

    
6282
			for ( ; i < 4; i++ ) {
6283
				expanded[ prefix + cssExpand[ i ] + suffix ] =
6284
					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
6285
			}
6286

    
6287
			return expanded;
6288
		}
6289
	};
6290

    
6291
	if ( !rmargin.test( prefix ) ) {
6292
		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
6293
	}
6294
} );
6295

    
6296
jQuery.fn.extend( {
6297
	css: function( name, value ) {
6298
		return access( this, function( elem, name, value ) {
6299
			var styles, len,
6300
				map = {},
6301
				i = 0;
6302

    
6303
			if ( jQuery.isArray( name ) ) {
6304
				styles = getStyles( elem );
6305
				len = name.length;
6306

    
6307
				for ( ; i < len; i++ ) {
6308
					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
6309
				}
6310

    
6311
				return map;
6312
			}
6313

    
6314
			return value !== undefined ?
6315
				jQuery.style( elem, name, value ) :
6316
				jQuery.css( elem, name );
6317
		}, name, value, arguments.length > 1 );
6318
	},
6319
	show: function() {
6320
		return showHide( this, true );
6321
	},
6322
	hide: function() {
6323
		return showHide( this );
6324
	},
6325
	toggle: function( state ) {
6326
		if ( typeof state === "boolean" ) {
6327
			return state ? this.show() : this.hide();
6328
		}
6329

    
6330
		return this.each( function() {
6331
			if ( isHidden( this ) ) {
6332
				jQuery( this ).show();
6333
			} else {
6334
				jQuery( this ).hide();
6335
			}
6336
		} );
6337
	}
6338
} );
6339

    
6340

    
6341
function Tween( elem, options, prop, end, easing ) {
6342
	return new Tween.prototype.init( elem, options, prop, end, easing );
6343
}
6344
jQuery.Tween = Tween;
6345

    
6346
Tween.prototype = {
6347
	constructor: Tween,
6348
	init: function( elem, options, prop, end, easing, unit ) {
6349
		this.elem = elem;
6350
		this.prop = prop;
6351
		this.easing = easing || jQuery.easing._default;
6352
		this.options = options;
6353
		this.start = this.now = this.cur();
6354
		this.end = end;
6355
		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
6356
	},
6357
	cur: function() {
6358
		var hooks = Tween.propHooks[ this.prop ];
6359

    
6360
		return hooks && hooks.get ?
6361
			hooks.get( this ) :
6362
			Tween.propHooks._default.get( this );
6363
	},
6364
	run: function( percent ) {
6365
		var eased,
6366
			hooks = Tween.propHooks[ this.prop ];
6367

    
6368
		if ( this.options.duration ) {
6369
			this.pos = eased = jQuery.easing[ this.easing ](
6370
				percent, this.options.duration * percent, 0, 1, this.options.duration
6371
			);
6372
		} else {
6373
			this.pos = eased = percent;
6374
		}
6375
		this.now = ( this.end - this.start ) * eased + this.start;
6376

    
6377
		if ( this.options.step ) {
6378
			this.options.step.call( this.elem, this.now, this );
6379
		}
6380

    
6381
		if ( hooks && hooks.set ) {
6382
			hooks.set( this );
6383
		} else {
6384
			Tween.propHooks._default.set( this );
6385
		}
6386
		return this;
6387
	}
6388
};
6389

    
6390
Tween.prototype.init.prototype = Tween.prototype;
6391

    
6392
Tween.propHooks = {
6393
	_default: {
6394
		get: function( tween ) {
6395
			var result;
6396

    
6397
			// Use a property on the element directly when it is not a DOM element,
6398
			// or when there is no matching style property that exists.
6399
			if ( tween.elem.nodeType !== 1 ||
6400
				tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
6401
				return tween.elem[ tween.prop ];
6402
			}
6403

    
6404
			// Passing an empty string as a 3rd parameter to .css will automatically
6405
			// attempt a parseFloat and fallback to a string if the parse fails.
6406
			// Simple values such as "10px" are parsed to Float;
6407
			// complex values such as "rotate(1rad)" are returned as-is.
6408
			result = jQuery.css( tween.elem, tween.prop, "" );
6409

    
6410
			// Empty strings, null, undefined and "auto" are converted to 0.
6411
			return !result || result === "auto" ? 0 : result;
6412
		},
6413
		set: function( tween ) {
6414

    
6415
			// Use step hook for back compat.
6416
			// Use cssHook if its there.
6417
			// Use .style if available and use plain properties where available.
6418
			if ( jQuery.fx.step[ tween.prop ] ) {
6419
				jQuery.fx.step[ tween.prop ]( tween );
6420
			} else if ( tween.elem.nodeType === 1 &&
6421
				( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
6422
					jQuery.cssHooks[ tween.prop ] ) ) {
6423
				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
6424
			} else {
6425
				tween.elem[ tween.prop ] = tween.now;
6426
			}
6427
		}
6428
	}
6429
};
6430

    
6431
// Support: IE9
6432
// Panic based approach to setting things on disconnected nodes
6433
Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
6434
	set: function( tween ) {
6435
		if ( tween.elem.nodeType && tween.elem.parentNode ) {
6436
			tween.elem[ tween.prop ] = tween.now;
6437
		}
6438
	}
6439
};
6440

    
6441
jQuery.easing = {
6442
	linear: function( p ) {
6443
		return p;
6444
	},
6445
	swing: function( p ) {
6446
		return 0.5 - Math.cos( p * Math.PI ) / 2;
6447
	},
6448
	_default: "swing"
6449
};
6450

    
6451
jQuery.fx = Tween.prototype.init;
6452

    
6453
// Back Compat <1.8 extension point
6454
jQuery.fx.step = {};
6455

    
6456

    
6457

    
6458

    
6459
var
6460
	fxNow, timerId,
6461
	rfxtypes = /^(?:toggle|show|hide)$/,
6462
	rrun = /queueHooks$/;
6463

    
6464
// Animations created synchronously will run synchronously
6465
function createFxNow() {
6466
	window.setTimeout( function() {
6467
		fxNow = undefined;
6468
	} );
6469
	return ( fxNow = jQuery.now() );
6470
}
6471

    
6472
// Generate parameters to create a standard animation
6473
function genFx( type, includeWidth ) {
6474
	var which,
6475
		i = 0,
6476
		attrs = { height: type };
6477

    
6478
	// If we include width, step value is 1 to do all cssExpand values,
6479
	// otherwise step value is 2 to skip over Left and Right
6480
	includeWidth = includeWidth ? 1 : 0;
6481
	for ( ; i < 4 ; i += 2 - includeWidth ) {
6482
		which = cssExpand[ i ];
6483
		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
6484
	}
6485

    
6486
	if ( includeWidth ) {
6487
		attrs.opacity = attrs.width = type;
6488
	}
6489

    
6490
	return attrs;
6491
}
6492

    
6493
function createTween( value, prop, animation ) {
6494
	var tween,
6495
		collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
6496
		index = 0,
6497
		length = collection.length;
6498
	for ( ; index < length; index++ ) {
6499
		if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
6500

    
6501
			// We're done with this property
6502
			return tween;
6503
		}
6504
	}
6505
}
6506

    
6507
function defaultPrefilter( elem, props, opts ) {
6508
	/* jshint validthis: true */
6509
	var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
6510
		anim = this,
6511
		orig = {},
6512
		style = elem.style,
6513
		hidden = elem.nodeType && isHidden( elem ),
6514
		dataShow = dataPriv.get( elem, "fxshow" );
6515

    
6516
	// Handle queue: false promises
6517
	if ( !opts.queue ) {
6518
		hooks = jQuery._queueHooks( elem, "fx" );
6519
		if ( hooks.unqueued == null ) {
6520
			hooks.unqueued = 0;
6521
			oldfire = hooks.empty.fire;
6522
			hooks.empty.fire = function() {
6523
				if ( !hooks.unqueued ) {
6524
					oldfire();
6525
				}
6526
			};
6527
		}
6528
		hooks.unqueued++;
6529

    
6530
		anim.always( function() {
6531

    
6532
			// Ensure the complete handler is called before this completes
6533
			anim.always( function() {
6534
				hooks.unqueued--;
6535
				if ( !jQuery.queue( elem, "fx" ).length ) {
6536
					hooks.empty.fire();
6537
				}
6538
			} );
6539
		} );
6540
	}
6541

    
6542
	// Height/width overflow pass
6543
	if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
6544

    
6545
		// Make sure that nothing sneaks out
6546
		// Record all 3 overflow attributes because IE9-10 do not
6547
		// change the overflow attribute when overflowX and
6548
		// overflowY are set to the same value
6549
		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
6550

    
6551
		// Set display property to inline-block for height/width
6552
		// animations on inline elements that are having width/height animated
6553
		display = jQuery.css( elem, "display" );
6554

    
6555
		// Test default display if display is currently "none"
6556
		checkDisplay = display === "none" ?
6557
			dataPriv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
6558

    
6559
		if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
6560
			style.display = "inline-block";
6561
		}
6562
	}
6563

    
6564
	if ( opts.overflow ) {
6565
		style.overflow = "hidden";
6566
		anim.always( function() {
6567
			style.overflow = opts.overflow[ 0 ];
6568
			style.overflowX = opts.overflow[ 1 ];
6569
			style.overflowY = opts.overflow[ 2 ];
6570
		} );
6571
	}
6572

    
6573
	// show/hide pass
6574
	for ( prop in props ) {
6575
		value = props[ prop ];
6576
		if ( rfxtypes.exec( value ) ) {
6577
			delete props[ prop ];
6578
			toggle = toggle || value === "toggle";
6579
			if ( value === ( hidden ? "hide" : "show" ) ) {
6580

    
6581
				// If there is dataShow left over from a stopped hide or show
6582
				// and we are going to proceed with show, we should pretend to be hidden
6583
				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
6584
					hidden = true;
6585
				} else {
6586
					continue;
6587
				}
6588
			}
6589
			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
6590

    
6591
		// Any non-fx value stops us from restoring the original display value
6592
		} else {
6593
			display = undefined;
6594
		}
6595
	}
6596

    
6597
	if ( !jQuery.isEmptyObject( orig ) ) {
6598
		if ( dataShow ) {
6599
			if ( "hidden" in dataShow ) {
6600
				hidden = dataShow.hidden;
6601
			}
6602
		} else {
6603
			dataShow = dataPriv.access( elem, "fxshow", {} );
6604
		}
6605

    
6606
		// Store state if its toggle - enables .stop().toggle() to "reverse"
6607
		if ( toggle ) {
6608
			dataShow.hidden = !hidden;
6609
		}
6610
		if ( hidden ) {
6611
			jQuery( elem ).show();
6612
		} else {
6613
			anim.done( function() {
6614
				jQuery( elem ).hide();
6615
			} );
6616
		}
6617
		anim.done( function() {
6618
			var prop;
6619

    
6620
			dataPriv.remove( elem, "fxshow" );
6621
			for ( prop in orig ) {
6622
				jQuery.style( elem, prop, orig[ prop ] );
6623
			}
6624
		} );
6625
		for ( prop in orig ) {
6626
			tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
6627

    
6628
			if ( !( prop in dataShow ) ) {
6629
				dataShow[ prop ] = tween.start;
6630
				if ( hidden ) {
6631
					tween.end = tween.start;
6632
					tween.start = prop === "width" || prop === "height" ? 1 : 0;
6633
				}
6634
			}
6635
		}
6636

    
6637
	// If this is a noop like .hide().hide(), restore an overwritten display value
6638
	} else if ( ( display === "none" ? defaultDisplay( elem.nodeName ) : display ) === "inline" ) {
6639
		style.display = display;
6640
	}
6641
}
6642

    
6643
function propFilter( props, specialEasing ) {
6644
	var index, name, easing, value, hooks;
6645

    
6646
	// camelCase, specialEasing and expand cssHook pass
6647
	for ( index in props ) {
6648
		name = jQuery.camelCase( index );
6649
		easing = specialEasing[ name ];
6650
		value = props[ index ];
6651
		if ( jQuery.isArray( value ) ) {
6652
			easing = value[ 1 ];
6653
			value = props[ index ] = value[ 0 ];
6654
		}
6655

    
6656
		if ( index !== name ) {
6657
			props[ name ] = value;
6658
			delete props[ index ];
6659
		}
6660

    
6661
		hooks = jQuery.cssHooks[ name ];
6662
		if ( hooks && "expand" in hooks ) {
6663
			value = hooks.expand( value );
6664
			delete props[ name ];
6665

    
6666
			// Not quite $.extend, this won't overwrite existing keys.
6667
			// Reusing 'index' because we have the correct "name"
6668
			for ( index in value ) {
6669
				if ( !( index in props ) ) {
6670
					props[ index ] = value[ index ];
6671
					specialEasing[ index ] = easing;
6672
				}
6673
			}
6674
		} else {
6675
			specialEasing[ name ] = easing;
6676
		}
6677
	}
6678
}
6679

    
6680
function Animation( elem, properties, options ) {
6681
	var result,
6682
		stopped,
6683
		index = 0,
6684
		length = Animation.prefilters.length,
6685
		deferred = jQuery.Deferred().always( function() {
6686

    
6687
			// Don't match elem in the :animated selector
6688
			delete tick.elem;
6689
		} ),
6690
		tick = function() {
6691
			if ( stopped ) {
6692
				return false;
6693
			}
6694
			var currentTime = fxNow || createFxNow(),
6695
				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
6696

    
6697
				// Support: Android 2.3
6698
				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
6699
				temp = remaining / animation.duration || 0,
6700
				percent = 1 - temp,
6701
				index = 0,
6702
				length = animation.tweens.length;
6703

    
6704
			for ( ; index < length ; index++ ) {
6705
				animation.tweens[ index ].run( percent );
6706
			}
6707

    
6708
			deferred.notifyWith( elem, [ animation, percent, remaining ] );
6709

    
6710
			if ( percent < 1 && length ) {
6711
				return remaining;
6712
			} else {
6713
				deferred.resolveWith( elem, [ animation ] );
6714
				return false;
6715
			}
6716
		},
6717
		animation = deferred.promise( {
6718
			elem: elem,
6719
			props: jQuery.extend( {}, properties ),
6720
			opts: jQuery.extend( true, {
6721
				specialEasing: {},
6722
				easing: jQuery.easing._default
6723
			}, options ),
6724
			originalProperties: properties,
6725
			originalOptions: options,
6726
			startTime: fxNow || createFxNow(),
6727
			duration: options.duration,
6728
			tweens: [],
6729
			createTween: function( prop, end ) {
6730
				var tween = jQuery.Tween( elem, animation.opts, prop, end,
6731
						animation.opts.specialEasing[ prop ] || animation.opts.easing );
6732
				animation.tweens.push( tween );
6733
				return tween;
6734
			},
6735
			stop: function( gotoEnd ) {
6736
				var index = 0,
6737

    
6738
					// If we are going to the end, we want to run all the tweens
6739
					// otherwise we skip this part
6740
					length = gotoEnd ? animation.tweens.length : 0;
6741
				if ( stopped ) {
6742
					return this;
6743
				}
6744
				stopped = true;
6745
				for ( ; index < length ; index++ ) {
6746
					animation.tweens[ index ].run( 1 );
6747
				}
6748

    
6749
				// Resolve when we played the last frame; otherwise, reject
6750
				if ( gotoEnd ) {
6751
					deferred.notifyWith( elem, [ animation, 1, 0 ] );
6752
					deferred.resolveWith( elem, [ animation, gotoEnd ] );
6753
				} else {
6754
					deferred.rejectWith( elem, [ animation, gotoEnd ] );
6755
				}
6756
				return this;
6757
			}
6758
		} ),
6759
		props = animation.props;
6760

    
6761
	propFilter( props, animation.opts.specialEasing );
6762

    
6763
	for ( ; index < length ; index++ ) {
6764
		result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
6765
		if ( result ) {
6766
			if ( jQuery.isFunction( result.stop ) ) {
6767
				jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
6768
					jQuery.proxy( result.stop, result );
6769
			}
6770
			return result;
6771
		}
6772
	}
6773

    
6774
	jQuery.map( props, createTween, animation );
6775

    
6776
	if ( jQuery.isFunction( animation.opts.start ) ) {
6777
		animation.opts.start.call( elem, animation );
6778
	}
6779

    
6780
	jQuery.fx.timer(
6781
		jQuery.extend( tick, {
6782
			elem: elem,
6783
			anim: animation,
6784
			queue: animation.opts.queue
6785
		} )
6786
	);
6787

    
6788
	// attach callbacks from options
6789
	return animation.progress( animation.opts.progress )
6790
		.done( animation.opts.done, animation.opts.complete )
6791
		.fail( animation.opts.fail )
6792
		.always( animation.opts.always );
6793
}
6794

    
6795
jQuery.Animation = jQuery.extend( Animation, {
6796
	tweeners: {
6797
		"*": [ function( prop, value ) {
6798
			var tween = this.createTween( prop, value );
6799
			adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
6800
			return tween;
6801
		} ]
6802
	},
6803

    
6804
	tweener: function( props, callback ) {
6805
		if ( jQuery.isFunction( props ) ) {
6806
			callback = props;
6807
			props = [ "*" ];
6808
		} else {
6809
			props = props.match( rnotwhite );
6810
		}
6811

    
6812
		var prop,
6813
			index = 0,
6814
			length = props.length;
6815

    
6816
		for ( ; index < length ; index++ ) {
6817
			prop = props[ index ];
6818
			Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
6819
			Animation.tweeners[ prop ].unshift( callback );
6820
		}
6821
	},
6822

    
6823
	prefilters: [ defaultPrefilter ],
6824

    
6825
	prefilter: function( callback, prepend ) {
6826
		if ( prepend ) {
6827
			Animation.prefilters.unshift( callback );
6828
		} else {
6829
			Animation.prefilters.push( callback );
6830
		}
6831
	}
6832
} );
6833

    
6834
jQuery.speed = function( speed, easing, fn ) {
6835
	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
6836
		complete: fn || !fn && easing ||
6837
			jQuery.isFunction( speed ) && speed,
6838
		duration: speed,
6839
		easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
6840
	};
6841

    
6842
	opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ?
6843
		opt.duration : opt.duration in jQuery.fx.speeds ?
6844
			jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
6845

    
6846
	// Normalize opt.queue - true/undefined/null -> "fx"
6847
	if ( opt.queue == null || opt.queue === true ) {
6848
		opt.queue = "fx";
6849
	}
6850

    
6851
	// Queueing
6852
	opt.old = opt.complete;
6853

    
6854
	opt.complete = function() {
6855
		if ( jQuery.isFunction( opt.old ) ) {
6856
			opt.old.call( this );
6857
		}
6858

    
6859
		if ( opt.queue ) {
6860
			jQuery.dequeue( this, opt.queue );
6861
		}
6862
	};
6863

    
6864
	return opt;
6865
};
6866

    
6867
jQuery.fn.extend( {
6868
	fadeTo: function( speed, to, easing, callback ) {
6869

    
6870
		// Show any hidden elements after setting opacity to 0
6871
		return this.filter( isHidden ).css( "opacity", 0 ).show()
6872

    
6873
			// Animate to the value specified
6874
			.end().animate( { opacity: to }, speed, easing, callback );
6875
	},
6876
	animate: function( prop, speed, easing, callback ) {
6877
		var empty = jQuery.isEmptyObject( prop ),
6878
			optall = jQuery.speed( speed, easing, callback ),
6879
			doAnimation = function() {
6880

    
6881
				// Operate on a copy of prop so per-property easing won't be lost
6882
				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
6883

    
6884
				// Empty animations, or finishing resolves immediately
6885
				if ( empty || dataPriv.get( this, "finish" ) ) {
6886
					anim.stop( true );
6887
				}
6888
			};
6889
			doAnimation.finish = doAnimation;
6890

    
6891
		return empty || optall.queue === false ?
6892
			this.each( doAnimation ) :
6893
			this.queue( optall.queue, doAnimation );
6894
	},
6895
	stop: function( type, clearQueue, gotoEnd ) {
6896
		var stopQueue = function( hooks ) {
6897
			var stop = hooks.stop;
6898
			delete hooks.stop;
6899
			stop( gotoEnd );
6900
		};
6901

    
6902
		if ( typeof type !== "string" ) {
6903
			gotoEnd = clearQueue;
6904
			clearQueue = type;
6905
			type = undefined;
6906
		}
6907
		if ( clearQueue && type !== false ) {
6908
			this.queue( type || "fx", [] );
6909
		}
6910

    
6911
		return this.each( function() {
6912
			var dequeue = true,
6913
				index = type != null && type + "queueHooks",
6914
				timers = jQuery.timers,
6915
				data = dataPriv.get( this );
6916

    
6917
			if ( index ) {
6918
				if ( data[ index ] && data[ index ].stop ) {
6919
					stopQueue( data[ index ] );
6920
				}
6921
			} else {
6922
				for ( index in data ) {
6923
					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
6924
						stopQueue( data[ index ] );
6925
					}
6926
				}
6927
			}
6928

    
6929
			for ( index = timers.length; index--; ) {
6930
				if ( timers[ index ].elem === this &&
6931
					( type == null || timers[ index ].queue === type ) ) {
6932

    
6933
					timers[ index ].anim.stop( gotoEnd );
6934
					dequeue = false;
6935
					timers.splice( index, 1 );
6936
				}
6937
			}
6938

    
6939
			// Start the next in the queue if the last step wasn't forced.
6940
			// Timers currently will call their complete callbacks, which
6941
			// will dequeue but only if they were gotoEnd.
6942
			if ( dequeue || !gotoEnd ) {
6943
				jQuery.dequeue( this, type );
6944
			}
6945
		} );
6946
	},
6947
	finish: function( type ) {
6948
		if ( type !== false ) {
6949
			type = type || "fx";
6950
		}
6951
		return this.each( function() {
6952
			var index,
6953
				data = dataPriv.get( this ),
6954
				queue = data[ type + "queue" ],
6955
				hooks = data[ type + "queueHooks" ],
6956
				timers = jQuery.timers,
6957
				length = queue ? queue.length : 0;
6958

    
6959
			// Enable finishing flag on private data
6960
			data.finish = true;
6961

    
6962
			// Empty the queue first
6963
			jQuery.queue( this, type, [] );
6964

    
6965
			if ( hooks && hooks.stop ) {
6966
				hooks.stop.call( this, true );
6967
			}
6968

    
6969
			// Look for any active animations, and finish them
6970
			for ( index = timers.length; index--; ) {
6971
				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
6972
					timers[ index ].anim.stop( true );
6973
					timers.splice( index, 1 );
6974
				}
6975
			}
6976

    
6977
			// Look for any animations in the old queue and finish them
6978
			for ( index = 0; index < length; index++ ) {
6979
				if ( queue[ index ] && queue[ index ].finish ) {
6980
					queue[ index ].finish.call( this );
6981
				}
6982
			}
6983

    
6984
			// Turn off finishing flag
6985
			delete data.finish;
6986
		} );
6987
	}
6988
} );
6989

    
6990
jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
6991
	var cssFn = jQuery.fn[ name ];
6992
	jQuery.fn[ name ] = function( speed, easing, callback ) {
6993
		return speed == null || typeof speed === "boolean" ?
6994
			cssFn.apply( this, arguments ) :
6995
			this.animate( genFx( name, true ), speed, easing, callback );
6996
	};
6997
} );
6998

    
6999
// Generate shortcuts for custom animations
7000
jQuery.each( {
7001
	slideDown: genFx( "show" ),
7002
	slideUp: genFx( "hide" ),
7003
	slideToggle: genFx( "toggle" ),
7004
	fadeIn: { opacity: "show" },
7005
	fadeOut: { opacity: "hide" },
7006
	fadeToggle: { opacity: "toggle" }
7007
}, function( name, props ) {
7008
	jQuery.fn[ name ] = function( speed, easing, callback ) {
7009
		return this.animate( props, speed, easing, callback );
7010
	};
7011
} );
7012

    
7013
jQuery.timers = [];
7014
jQuery.fx.tick = function() {
7015
	var timer,
7016
		i = 0,
7017
		timers = jQuery.timers;
7018

    
7019
	fxNow = jQuery.now();
7020

    
7021
	for ( ; i < timers.length; i++ ) {
7022
		timer = timers[ i ];
7023

    
7024
		// Checks the timer has not already been removed
7025
		if ( !timer() && timers[ i ] === timer ) {
7026
			timers.splice( i--, 1 );
7027
		}
7028
	}
7029

    
7030
	if ( !timers.length ) {
7031
		jQuery.fx.stop();
7032
	}
7033
	fxNow = undefined;
7034
};
7035

    
7036
jQuery.fx.timer = function( timer ) {
7037
	jQuery.timers.push( timer );
7038
	if ( timer() ) {
7039
		jQuery.fx.start();
7040
	} else {
7041
		jQuery.timers.pop();
7042
	}
7043
};
7044

    
7045
jQuery.fx.interval = 13;
7046
jQuery.fx.start = function() {
7047
	if ( !timerId ) {
7048
		timerId = window.setInterval( jQuery.fx.tick, jQuery.fx.interval );
7049
	}
7050
};
7051

    
7052
jQuery.fx.stop = function() {
7053
	window.clearInterval( timerId );
7054

    
7055
	timerId = null;
7056
};
7057

    
7058
jQuery.fx.speeds = {
7059
	slow: 600,
7060
	fast: 200,
7061

    
7062
	// Default speed
7063
	_default: 400
7064
};
7065

    
7066

    
7067
// Based off of the plugin by Clint Helfers, with permission.
7068
// http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
7069
jQuery.fn.delay = function( time, type ) {
7070
	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
7071
	type = type || "fx";
7072

    
7073
	return this.queue( type, function( next, hooks ) {
7074
		var timeout = window.setTimeout( next, time );
7075
		hooks.stop = function() {
7076
			window.clearTimeout( timeout );
7077
		};
7078
	} );
7079
};
7080

    
7081

    
7082
( function() {
7083
	var input = document.createElement( "input" ),
7084
		select = document.createElement( "select" ),
7085
		opt = select.appendChild( document.createElement( "option" ) );
7086

    
7087
	input.type = "checkbox";
7088

    
7089
	// Support: iOS<=5.1, Android<=4.2+
7090
	// Default value for a checkbox should be "on"
7091
	support.checkOn = input.value !== "";
7092

    
7093
	// Support: IE<=11+
7094
	// Must access selectedIndex to make default options select
7095
	support.optSelected = opt.selected;
7096

    
7097
	// Support: Android<=2.3
7098
	// Options inside disabled selects are incorrectly marked as disabled
7099
	select.disabled = true;
7100
	support.optDisabled = !opt.disabled;
7101

    
7102
	// Support: IE<=11+
7103
	// An input loses its value after becoming a radio
7104
	input = document.createElement( "input" );
7105
	input.value = "t";
7106
	input.type = "radio";
7107
	support.radioValue = input.value === "t";
7108
} )();
7109

    
7110

    
7111
var boolHook,
7112
	attrHandle = jQuery.expr.attrHandle;
7113

    
7114
jQuery.fn.extend( {
7115
	attr: function( name, value ) {
7116
		return access( this, jQuery.attr, name, value, arguments.length > 1 );
7117
	},
7118

    
7119
	removeAttr: function( name ) {
7120
		return this.each( function() {
7121
			jQuery.removeAttr( this, name );
7122
		} );
7123
	}
7124
} );
7125

    
7126
jQuery.extend( {
7127
	attr: function( elem, name, value ) {
7128
		var ret, hooks,
7129
			nType = elem.nodeType;
7130

    
7131
		// Don't get/set attributes on text, comment and attribute nodes
7132
		if ( nType === 3 || nType === 8 || nType === 2 ) {
7133
			return;
7134
		}
7135

    
7136
		// Fallback to prop when attributes are not supported
7137
		if ( typeof elem.getAttribute === "undefined" ) {
7138
			return jQuery.prop( elem, name, value );
7139
		}
7140

    
7141
		// All attributes are lowercase
7142
		// Grab necessary hook if one is defined
7143
		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
7144
			name = name.toLowerCase();
7145
			hooks = jQuery.attrHooks[ name ] ||
7146
				( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
7147
		}
7148

    
7149
		if ( value !== undefined ) {
7150
			if ( value === null ) {
7151
				jQuery.removeAttr( elem, name );
7152
				return;
7153
			}
7154

    
7155
			if ( hooks && "set" in hooks &&
7156
				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
7157
				return ret;
7158
			}
7159

    
7160
			elem.setAttribute( name, value + "" );
7161
			return value;
7162
		}
7163

    
7164
		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
7165
			return ret;
7166
		}
7167

    
7168
		ret = jQuery.find.attr( elem, name );
7169

    
7170
		// Non-existent attributes return null, we normalize to undefined
7171
		return ret == null ? undefined : ret;
7172
	},
7173

    
7174
	attrHooks: {
7175
		type: {
7176
			set: function( elem, value ) {
7177
				if ( !support.radioValue && value === "radio" &&
7178
					jQuery.nodeName( elem, "input" ) ) {
7179
					var val = elem.value;
7180
					elem.setAttribute( "type", value );
7181
					if ( val ) {
7182
						elem.value = val;
7183
					}
7184
					return value;
7185
				}
7186
			}
7187
		}
7188
	},
7189

    
7190
	removeAttr: function( elem, value ) {
7191
		var name, propName,
7192
			i = 0,
7193
			attrNames = value && value.match( rnotwhite );
7194

    
7195
		if ( attrNames && elem.nodeType === 1 ) {
7196
			while ( ( name = attrNames[ i++ ] ) ) {
7197
				propName = jQuery.propFix[ name ] || name;
7198

    
7199
				// Boolean attributes get special treatment (#10870)
7200
				if ( jQuery.expr.match.bool.test( name ) ) {
7201

    
7202
					// Set corresponding property to false
7203
					elem[ propName ] = false;
7204
				}
7205

    
7206
				elem.removeAttribute( name );
7207
			}
7208
		}
7209
	}
7210
} );
7211

    
7212
// Hooks for boolean attributes
7213
boolHook = {
7214
	set: function( elem, value, name ) {
7215
		if ( value === false ) {
7216

    
7217
			// Remove boolean attributes when set to false
7218
			jQuery.removeAttr( elem, name );
7219
		} else {
7220
			elem.setAttribute( name, name );
7221
		}
7222
		return name;
7223
	}
7224
};
7225
jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
7226
	var getter = attrHandle[ name ] || jQuery.find.attr;
7227

    
7228
	attrHandle[ name ] = function( elem, name, isXML ) {
7229
		var ret, handle;
7230
		if ( !isXML ) {
7231

    
7232
			// Avoid an infinite loop by temporarily removing this function from the getter
7233
			handle = attrHandle[ name ];
7234
			attrHandle[ name ] = ret;
7235
			ret = getter( elem, name, isXML ) != null ?
7236
				name.toLowerCase() :
7237
				null;
7238
			attrHandle[ name ] = handle;
7239
		}
7240
		return ret;
7241
	};
7242
} );
7243

    
7244

    
7245

    
7246

    
7247
var rfocusable = /^(?:input|select|textarea|button)$/i,
7248
	rclickable = /^(?:a|area)$/i;
7249

    
7250
jQuery.fn.extend( {
7251
	prop: function( name, value ) {
7252
		return access( this, jQuery.prop, name, value, arguments.length > 1 );
7253
	},
7254

    
7255
	removeProp: function( name ) {
7256
		return this.each( function() {
7257
			delete this[ jQuery.propFix[ name ] || name ];
7258
		} );
7259
	}
7260
} );
7261

    
7262
jQuery.extend( {
7263
	prop: function( elem, name, value ) {
7264
		var ret, hooks,
7265
			nType = elem.nodeType;
7266

    
7267
		// Don't get/set properties on text, comment and attribute nodes
7268
		if ( nType === 3 || nType === 8 || nType === 2 ) {
7269
			return;
7270
		}
7271

    
7272
		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
7273

    
7274
			// Fix name and attach hooks
7275
			name = jQuery.propFix[ name ] || name;
7276
			hooks = jQuery.propHooks[ name ];
7277
		}
7278

    
7279
		if ( value !== undefined ) {
7280
			if ( hooks && "set" in hooks &&
7281
				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
7282
				return ret;
7283
			}
7284

    
7285
			return ( elem[ name ] = value );
7286
		}
7287

    
7288
		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
7289
			return ret;
7290
		}
7291

    
7292
		return elem[ name ];
7293
	},
7294

    
7295
	propHooks: {
7296
		tabIndex: {
7297
			get: function( elem ) {
7298

    
7299
				// elem.tabIndex doesn't always return the
7300
				// correct value when it hasn't been explicitly set
7301
				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
7302
				// Use proper attribute retrieval(#12072)
7303
				var tabindex = jQuery.find.attr( elem, "tabindex" );
7304

    
7305
				return tabindex ?
7306
					parseInt( tabindex, 10 ) :
7307
					rfocusable.test( elem.nodeName ) ||
7308
						rclickable.test( elem.nodeName ) && elem.href ?
7309
							0 :
7310
							-1;
7311
			}
7312
		}
7313
	},
7314

    
7315
	propFix: {
7316
		"for": "htmlFor",
7317
		"class": "className"
7318
	}
7319
} );
7320

    
7321
// Support: IE <=11 only
7322
// Accessing the selectedIndex property
7323
// forces the browser to respect setting selected
7324
// on the option
7325
// The getter ensures a default option is selected
7326
// when in an optgroup
7327
if ( !support.optSelected ) {
7328
	jQuery.propHooks.selected = {
7329
		get: function( elem ) {
7330
			var parent = elem.parentNode;
7331
			if ( parent && parent.parentNode ) {
7332
				parent.parentNode.selectedIndex;
7333
			}
7334
			return null;
7335
		},
7336
		set: function( elem ) {
7337
			var parent = elem.parentNode;
7338
			if ( parent ) {
7339
				parent.selectedIndex;
7340

    
7341
				if ( parent.parentNode ) {
7342
					parent.parentNode.selectedIndex;
7343
				}
7344
			}
7345
		}
7346
	};
7347
}
7348

    
7349
jQuery.each( [
7350
	"tabIndex",
7351
	"readOnly",
7352
	"maxLength",
7353
	"cellSpacing",
7354
	"cellPadding",
7355
	"rowSpan",
7356
	"colSpan",
7357
	"useMap",
7358
	"frameBorder",
7359
	"contentEditable"
7360
], function() {
7361
	jQuery.propFix[ this.toLowerCase() ] = this;
7362
} );
7363

    
7364

    
7365

    
7366

    
7367
var rclass = /[\t\r\n\f]/g;
7368

    
7369
function getClass( elem ) {
7370
	return elem.getAttribute && elem.getAttribute( "class" ) || "";
7371
}
7372

    
7373
jQuery.fn.extend( {
7374
	addClass: function( value ) {
7375
		var classes, elem, cur, curValue, clazz, j, finalValue,
7376
			i = 0;
7377

    
7378
		if ( jQuery.isFunction( value ) ) {
7379
			return this.each( function( j ) {
7380
				jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
7381
			} );
7382
		}
7383

    
7384
		if ( typeof value === "string" && value ) {
7385
			classes = value.match( rnotwhite ) || [];
7386

    
7387
			while ( ( elem = this[ i++ ] ) ) {
7388
				curValue = getClass( elem );
7389
				cur = elem.nodeType === 1 &&
7390
					( " " + curValue + " " ).replace( rclass, " " );
7391

    
7392
				if ( cur ) {
7393
					j = 0;
7394
					while ( ( clazz = classes[ j++ ] ) ) {
7395
						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
7396
							cur += clazz + " ";
7397
						}
7398
					}
7399

    
7400
					// Only assign if different to avoid unneeded rendering.
7401
					finalValue = jQuery.trim( cur );
7402
					if ( curValue !== finalValue ) {
7403
						elem.setAttribute( "class", finalValue );
7404
					}
7405
				}
7406
			}
7407
		}
7408

    
7409
		return this;
7410
	},
7411

    
7412
	removeClass: function( value ) {
7413
		var classes, elem, cur, curValue, clazz, j, finalValue,
7414
			i = 0;
7415

    
7416
		if ( jQuery.isFunction( value ) ) {
7417
			return this.each( function( j ) {
7418
				jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
7419
			} );
7420
		}
7421

    
7422
		if ( !arguments.length ) {
7423
			return this.attr( "class", "" );
7424
		}
7425

    
7426
		if ( typeof value === "string" && value ) {
7427
			classes = value.match( rnotwhite ) || [];
7428

    
7429
			while ( ( elem = this[ i++ ] ) ) {
7430
				curValue = getClass( elem );
7431

    
7432
				// This expression is here for better compressibility (see addClass)
7433
				cur = elem.nodeType === 1 &&
7434
					( " " + curValue + " " ).replace( rclass, " " );
7435

    
7436
				if ( cur ) {
7437
					j = 0;
7438
					while ( ( clazz = classes[ j++ ] ) ) {
7439

    
7440
						// Remove *all* instances
7441
						while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
7442
							cur = cur.replace( " " + clazz + " ", " " );
7443
						}
7444
					}
7445

    
7446
					// Only assign if different to avoid unneeded rendering.
7447
					finalValue = jQuery.trim( cur );
7448
					if ( curValue !== finalValue ) {
7449
						elem.setAttribute( "class", finalValue );
7450
					}
7451
				}
7452
			}
7453
		}
7454

    
7455
		return this;
7456
	},
7457

    
7458
	toggleClass: function( value, stateVal ) {
7459
		var type = typeof value;
7460

    
7461
		if ( typeof stateVal === "boolean" && type === "string" ) {
7462
			return stateVal ? this.addClass( value ) : this.removeClass( value );
7463
		}
7464

    
7465
		if ( jQuery.isFunction( value ) ) {
7466
			return this.each( function( i ) {
7467
				jQuery( this ).toggleClass(
7468
					value.call( this, i, getClass( this ), stateVal ),
7469
					stateVal
7470
				);
7471
			} );
7472
		}
7473

    
7474
		return this.each( function() {
7475
			var className, i, self, classNames;
7476

    
7477
			if ( type === "string" ) {
7478

    
7479
				// Toggle individual class names
7480
				i = 0;
7481
				self = jQuery( this );
7482
				classNames = value.match( rnotwhite ) || [];
7483

    
7484
				while ( ( className = classNames[ i++ ] ) ) {
7485

    
7486
					// Check each className given, space separated list
7487
					if ( self.hasClass( className ) ) {
7488
						self.removeClass( className );
7489
					} else {
7490
						self.addClass( className );
7491
					}
7492
				}
7493

    
7494
			// Toggle whole class name
7495
			} else if ( value === undefined || type === "boolean" ) {
7496
				className = getClass( this );
7497
				if ( className ) {
7498

    
7499
					// Store className if set
7500
					dataPriv.set( this, "__className__", className );
7501
				}
7502

    
7503
				// If the element has a class name or if we're passed `false`,
7504
				// then remove the whole classname (if there was one, the above saved it).
7505
				// Otherwise bring back whatever was previously saved (if anything),
7506
				// falling back to the empty string if nothing was stored.
7507
				if ( this.setAttribute ) {
7508
					this.setAttribute( "class",
7509
						className || value === false ?
7510
						"" :
7511
						dataPriv.get( this, "__className__" ) || ""
7512
					);
7513
				}
7514
			}
7515
		} );
7516
	},
7517

    
7518
	hasClass: function( selector ) {
7519
		var className, elem,
7520
			i = 0;
7521

    
7522
		className = " " + selector + " ";
7523
		while ( ( elem = this[ i++ ] ) ) {
7524
			if ( elem.nodeType === 1 &&
7525
				( " " + getClass( elem ) + " " ).replace( rclass, " " )
7526
					.indexOf( className ) > -1
7527
			) {
7528
				return true;
7529
			}
7530
		}
7531

    
7532
		return false;
7533
	}
7534
} );
7535

    
7536

    
7537

    
7538

    
7539
var rreturn = /\r/g,
7540
	rspaces = /[\x20\t\r\n\f]+/g;
7541

    
7542
jQuery.fn.extend( {
7543
	val: function( value ) {
7544
		var hooks, ret, isFunction,
7545
			elem = this[ 0 ];
7546

    
7547
		if ( !arguments.length ) {
7548
			if ( elem ) {
7549
				hooks = jQuery.valHooks[ elem.type ] ||
7550
					jQuery.valHooks[ elem.nodeName.toLowerCase() ];
7551

    
7552
				if ( hooks &&
7553
					"get" in hooks &&
7554
					( ret = hooks.get( elem, "value" ) ) !== undefined
7555
				) {
7556
					return ret;
7557
				}
7558

    
7559
				ret = elem.value;
7560

    
7561
				return typeof ret === "string" ?
7562

    
7563
					// Handle most common string cases
7564
					ret.replace( rreturn, "" ) :
7565

    
7566
					// Handle cases where value is null/undef or number
7567
					ret == null ? "" : ret;
7568
			}
7569

    
7570
			return;
7571
		}
7572

    
7573
		isFunction = jQuery.isFunction( value );
7574

    
7575
		return this.each( function( i ) {
7576
			var val;
7577

    
7578
			if ( this.nodeType !== 1 ) {
7579
				return;
7580
			}
7581

    
7582
			if ( isFunction ) {
7583
				val = value.call( this, i, jQuery( this ).val() );
7584
			} else {
7585
				val = value;
7586
			}
7587

    
7588
			// Treat null/undefined as ""; convert numbers to string
7589
			if ( val == null ) {
7590
				val = "";
7591

    
7592
			} else if ( typeof val === "number" ) {
7593
				val += "";
7594

    
7595
			} else if ( jQuery.isArray( val ) ) {
7596
				val = jQuery.map( val, function( value ) {
7597
					return value == null ? "" : value + "";
7598
				} );
7599
			}
7600

    
7601
			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
7602

    
7603
			// If set returns undefined, fall back to normal setting
7604
			if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
7605
				this.value = val;
7606
			}
7607
		} );
7608
	}
7609
} );
7610

    
7611
jQuery.extend( {
7612
	valHooks: {
7613
		option: {
7614
			get: function( elem ) {
7615

    
7616
				var val = jQuery.find.attr( elem, "value" );
7617
				return val != null ?
7618
					val :
7619

    
7620
					// Support: IE10-11+
7621
					// option.text throws exceptions (#14686, #14858)
7622
					// Strip and collapse whitespace
7623
					// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
7624
					jQuery.trim( jQuery.text( elem ) ).replace( rspaces, " " );
7625
			}
7626
		},
7627
		select: {
7628
			get: function( elem ) {
7629
				var value, option,
7630
					options = elem.options,
7631
					index = elem.selectedIndex,
7632
					one = elem.type === "select-one" || index < 0,
7633
					values = one ? null : [],
7634
					max = one ? index + 1 : options.length,
7635
					i = index < 0 ?
7636
						max :
7637
						one ? index : 0;
7638

    
7639
				// Loop through all the selected options
7640
				for ( ; i < max; i++ ) {
7641
					option = options[ i ];
7642

    
7643
					// IE8-9 doesn't update selected after form reset (#2551)
7644
					if ( ( option.selected || i === index ) &&
7645

    
7646
							// Don't return options that are disabled or in a disabled optgroup
7647
							( support.optDisabled ?
7648
								!option.disabled : option.getAttribute( "disabled" ) === null ) &&
7649
							( !option.parentNode.disabled ||
7650
								!jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
7651

    
7652
						// Get the specific value for the option
7653
						value = jQuery( option ).val();
7654

    
7655
						// We don't need an array for one selects
7656
						if ( one ) {
7657
							return value;
7658
						}
7659

    
7660
						// Multi-Selects return an array
7661
						values.push( value );
7662
					}
7663
				}
7664

    
7665
				return values;
7666
			},
7667

    
7668
			set: function( elem, value ) {
7669
				var optionSet, option,
7670
					options = elem.options,
7671
					values = jQuery.makeArray( value ),
7672
					i = options.length;
7673

    
7674
				while ( i-- ) {
7675
					option = options[ i ];
7676
					if ( option.selected =
7677
						jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
7678
					) {
7679
						optionSet = true;
7680
					}
7681
				}
7682

    
7683
				// Force browsers to behave consistently when non-matching value is set
7684
				if ( !optionSet ) {
7685
					elem.selectedIndex = -1;
7686
				}
7687
				return values;
7688
			}
7689
		}
7690
	}
7691
} );
7692

    
7693
// Radios and checkboxes getter/setter
7694
jQuery.each( [ "radio", "checkbox" ], function() {
7695
	jQuery.valHooks[ this ] = {
7696
		set: function( elem, value ) {
7697
			if ( jQuery.isArray( value ) ) {
7698
				return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
7699
			}
7700
		}
7701
	};
7702
	if ( !support.checkOn ) {
7703
		jQuery.valHooks[ this ].get = function( elem ) {
7704
			return elem.getAttribute( "value" ) === null ? "on" : elem.value;
7705
		};
7706
	}
7707
} );
7708

    
7709

    
7710

    
7711

    
7712
// Return jQuery for attributes-only inclusion
7713

    
7714

    
7715
var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;
7716

    
7717
jQuery.extend( jQuery.event, {
7718

    
7719
	trigger: function( event, data, elem, onlyHandlers ) {
7720

    
7721
		var i, cur, tmp, bubbleType, ontype, handle, special,
7722
			eventPath = [ elem || document ],
7723
			type = hasOwn.call( event, "type" ) ? event.type : event,
7724
			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
7725

    
7726
		cur = tmp = elem = elem || document;
7727

    
7728
		// Don't do events on text and comment nodes
7729
		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
7730
			return;
7731
		}
7732

    
7733
		// focus/blur morphs to focusin/out; ensure we're not firing them right now
7734
		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
7735
			return;
7736
		}
7737

    
7738
		if ( type.indexOf( "." ) > -1 ) {
7739

    
7740
			// Namespaced trigger; create a regexp to match event type in handle()
7741
			namespaces = type.split( "." );
7742
			type = namespaces.shift();
7743
			namespaces.sort();
7744
		}
7745
		ontype = type.indexOf( ":" ) < 0 && "on" + type;
7746

    
7747
		// Caller can pass in a jQuery.Event object, Object, or just an event type string
7748
		event = event[ jQuery.expando ] ?
7749
			event :
7750
			new jQuery.Event( type, typeof event === "object" && event );
7751

    
7752
		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
7753
		event.isTrigger = onlyHandlers ? 2 : 3;
7754
		event.namespace = namespaces.join( "." );
7755
		event.rnamespace = event.namespace ?
7756
			new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
7757
			null;
7758

    
7759
		// Clean up the event in case it is being reused
7760
		event.result = undefined;
7761
		if ( !event.target ) {
7762
			event.target = elem;
7763
		}
7764

    
7765
		// Clone any incoming data and prepend the event, creating the handler arg list
7766
		data = data == null ?
7767
			[ event ] :
7768
			jQuery.makeArray( data, [ event ] );
7769

    
7770
		// Allow special events to draw outside the lines
7771
		special = jQuery.event.special[ type ] || {};
7772
		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
7773
			return;
7774
		}
7775

    
7776
		// Determine event propagation path in advance, per W3C events spec (#9951)
7777
		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
7778
		if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
7779

    
7780
			bubbleType = special.delegateType || type;
7781
			if ( !rfocusMorph.test( bubbleType + type ) ) {
7782
				cur = cur.parentNode;
7783
			}
7784
			for ( ; cur; cur = cur.parentNode ) {
7785
				eventPath.push( cur );
7786
				tmp = cur;
7787
			}
7788

    
7789
			// Only add window if we got to document (e.g., not plain obj or detached DOM)
7790
			if ( tmp === ( elem.ownerDocument || document ) ) {
7791
				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
7792
			}
7793
		}
7794

    
7795
		// Fire handlers on the event path
7796
		i = 0;
7797
		while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
7798

    
7799
			event.type = i > 1 ?
7800
				bubbleType :
7801
				special.bindType || type;
7802

    
7803
			// jQuery handler
7804
			handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
7805
				dataPriv.get( cur, "handle" );
7806
			if ( handle ) {
7807
				handle.apply( cur, data );
7808
			}
7809

    
7810
			// Native handler
7811
			handle = ontype && cur[ ontype ];
7812
			if ( handle && handle.apply && acceptData( cur ) ) {
7813
				event.result = handle.apply( cur, data );
7814
				if ( event.result === false ) {
7815
					event.preventDefault();
7816
				}
7817
			}
7818
		}
7819
		event.type = type;
7820

    
7821
		// If nobody prevented the default action, do it now
7822
		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
7823

    
7824
			if ( ( !special._default ||
7825
				special._default.apply( eventPath.pop(), data ) === false ) &&
7826
				acceptData( elem ) ) {
7827

    
7828
				// Call a native DOM method on the target with the same name name as the event.
7829
				// Don't do default actions on window, that's where global variables be (#6170)
7830
				if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
7831

    
7832
					// Don't re-trigger an onFOO event when we call its FOO() method
7833
					tmp = elem[ ontype ];
7834

    
7835
					if ( tmp ) {
7836
						elem[ ontype ] = null;
7837
					}
7838

    
7839
					// Prevent re-triggering of the same event, since we already bubbled it above
7840
					jQuery.event.triggered = type;
7841
					elem[ type ]();
7842
					jQuery.event.triggered = undefined;
7843

    
7844
					if ( tmp ) {
7845
						elem[ ontype ] = tmp;
7846
					}
7847
				}
7848
			}
7849
		}
7850

    
7851
		return event.result;
7852
	},
7853

    
7854
	// Piggyback on a donor event to simulate a different one
7855
	// Used only for `focus(in | out)` events
7856
	simulate: function( type, elem, event ) {
7857
		var e = jQuery.extend(
7858
			new jQuery.Event(),
7859
			event,
7860
			{
7861
				type: type,
7862
				isSimulated: true
7863
			}
7864
		);
7865

    
7866
		jQuery.event.trigger( e, null, elem );
7867
	}
7868

    
7869
} );
7870

    
7871
jQuery.fn.extend( {
7872

    
7873
	trigger: function( type, data ) {
7874
		return this.each( function() {
7875
			jQuery.event.trigger( type, data, this );
7876
		} );
7877
	},
7878
	triggerHandler: function( type, data ) {
7879
		var elem = this[ 0 ];
7880
		if ( elem ) {
7881
			return jQuery.event.trigger( type, data, elem, true );
7882
		}
7883
	}
7884
} );
7885

    
7886

    
7887
jQuery.each( ( "blur focus focusin focusout load resize scroll unload click dblclick " +
7888
	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
7889
	"change select submit keydown keypress keyup error contextmenu" ).split( " " ),
7890
	function( i, name ) {
7891

    
7892
	// Handle event binding
7893
	jQuery.fn[ name ] = function( data, fn ) {
7894
		return arguments.length > 0 ?
7895
			this.on( name, null, data, fn ) :
7896
			this.trigger( name );
7897
	};
7898
} );
7899

    
7900
jQuery.fn.extend( {
7901
	hover: function( fnOver, fnOut ) {
7902
		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
7903
	}
7904
} );
7905

    
7906

    
7907

    
7908

    
7909
support.focusin = "onfocusin" in window;
7910

    
7911

    
7912
// Support: Firefox
7913
// Firefox doesn't have focus(in | out) events
7914
// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
7915
//
7916
// Support: Chrome, Safari
7917
// focus(in | out) events fire after focus & blur events,
7918
// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
7919
// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857
7920
if ( !support.focusin ) {
7921
	jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
7922

    
7923
		// Attach a single capturing handler on the document while someone wants focusin/focusout
7924
		var handler = function( event ) {
7925
			jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
7926
		};
7927

    
7928
		jQuery.event.special[ fix ] = {
7929
			setup: function() {
7930
				var doc = this.ownerDocument || this,
7931
					attaches = dataPriv.access( doc, fix );
7932

    
7933
				if ( !attaches ) {
7934
					doc.addEventListener( orig, handler, true );
7935
				}
7936
				dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
7937
			},
7938
			teardown: function() {
7939
				var doc = this.ownerDocument || this,
7940
					attaches = dataPriv.access( doc, fix ) - 1;
7941

    
7942
				if ( !attaches ) {
7943
					doc.removeEventListener( orig, handler, true );
7944
					dataPriv.remove( doc, fix );
7945

    
7946
				} else {
7947
					dataPriv.access( doc, fix, attaches );
7948
				}
7949
			}
7950
		};
7951
	} );
7952
}
7953
var location = window.location;
7954

    
7955
var nonce = jQuery.now();
7956

    
7957
var rquery = ( /\?/ );
7958

    
7959

    
7960

    
7961
// Support: Android 2.3
7962
// Workaround failure to string-cast null input
7963
jQuery.parseJSON = function( data ) {
7964
	return JSON.parse( data + "" );
7965
};
7966

    
7967

    
7968
// Cross-browser xml parsing
7969
jQuery.parseXML = function( data ) {
7970
	var xml;
7971
	if ( !data || typeof data !== "string" ) {
7972
		return null;
7973
	}
7974

    
7975
	// Support: IE9
7976
	try {
7977
		xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
7978
	} catch ( e ) {
7979
		xml = undefined;
7980
	}
7981

    
7982
	if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
7983
		jQuery.error( "Invalid XML: " + data );
7984
	}
7985
	return xml;
7986
};
7987

    
7988

    
7989
var
7990
	rhash = /#.*$/,
7991
	rts = /([?&])_=[^&]*/,
7992
	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
7993

    
7994
	// #7653, #8125, #8152: local protocol detection
7995
	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
7996
	rnoContent = /^(?:GET|HEAD)$/,
7997
	rprotocol = /^\/\//,
7998

    
7999
	/* Prefilters
8000
	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
8001
	 * 2) These are called:
8002
	 *    - BEFORE asking for a transport
8003
	 *    - AFTER param serialization (s.data is a string if s.processData is true)
8004
	 * 3) key is the dataType
8005
	 * 4) the catchall symbol "*" can be used
8006
	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
8007
	 */
8008
	prefilters = {},
8009

    
8010
	/* Transports bindings
8011
	 * 1) key is the dataType
8012
	 * 2) the catchall symbol "*" can be used
8013
	 * 3) selection will start with transport dataType and THEN go to "*" if needed
8014
	 */
8015
	transports = {},
8016

    
8017
	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
8018
	allTypes = "*/".concat( "*" ),
8019

    
8020
	// Anchor tag for parsing the document origin
8021
	originAnchor = document.createElement( "a" );
8022
	originAnchor.href = location.href;
8023

    
8024
// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
8025
function addToPrefiltersOrTransports( structure ) {
8026

    
8027
	// dataTypeExpression is optional and defaults to "*"
8028
	return function( dataTypeExpression, func ) {
8029

    
8030
		if ( typeof dataTypeExpression !== "string" ) {
8031
			func = dataTypeExpression;
8032
			dataTypeExpression = "*";
8033
		}
8034

    
8035
		var dataType,
8036
			i = 0,
8037
			dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
8038

    
8039
		if ( jQuery.isFunction( func ) ) {
8040

    
8041
			// For each dataType in the dataTypeExpression
8042
			while ( ( dataType = dataTypes[ i++ ] ) ) {
8043

    
8044
				// Prepend if requested
8045
				if ( dataType[ 0 ] === "+" ) {
8046
					dataType = dataType.slice( 1 ) || "*";
8047
					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
8048

    
8049
				// Otherwise append
8050
				} else {
8051
					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
8052
				}
8053
			}
8054
		}
8055
	};
8056
}
8057

    
8058
// Base inspection function for prefilters and transports
8059
function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
8060

    
8061
	var inspected = {},
8062
		seekingTransport = ( structure === transports );
8063

    
8064
	function inspect( dataType ) {
8065
		var selected;
8066
		inspected[ dataType ] = true;
8067
		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
8068
			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
8069
			if ( typeof dataTypeOrTransport === "string" &&
8070
				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
8071

    
8072
				options.dataTypes.unshift( dataTypeOrTransport );
8073
				inspect( dataTypeOrTransport );
8074
				return false;
8075
			} else if ( seekingTransport ) {
8076
				return !( selected = dataTypeOrTransport );
8077
			}
8078
		} );
8079
		return selected;
8080
	}
8081

    
8082
	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
8083
}
8084

    
8085
// A special extend for ajax options
8086
// that takes "flat" options (not to be deep extended)
8087
// Fixes #9887
8088
function ajaxExtend( target, src ) {
8089
	var key, deep,
8090
		flatOptions = jQuery.ajaxSettings.flatOptions || {};
8091

    
8092
	for ( key in src ) {
8093
		if ( src[ key ] !== undefined ) {
8094
			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
8095
		}
8096
	}
8097
	if ( deep ) {
8098
		jQuery.extend( true, target, deep );
8099
	}
8100

    
8101
	return target;
8102
}
8103

    
8104
/* Handles responses to an ajax request:
8105
 * - finds the right dataType (mediates between content-type and expected dataType)
8106
 * - returns the corresponding response
8107
 */
8108
function ajaxHandleResponses( s, jqXHR, responses ) {
8109

    
8110
	var ct, type, finalDataType, firstDataType,
8111
		contents = s.contents,
8112
		dataTypes = s.dataTypes;
8113

    
8114
	// Remove auto dataType and get content-type in the process
8115
	while ( dataTypes[ 0 ] === "*" ) {
8116
		dataTypes.shift();
8117
		if ( ct === undefined ) {
8118
			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
8119
		}
8120
	}
8121

    
8122
	// Check if we're dealing with a known content-type
8123
	if ( ct ) {
8124
		for ( type in contents ) {
8125
			if ( contents[ type ] && contents[ type ].test( ct ) ) {
8126
				dataTypes.unshift( type );
8127
				break;
8128
			}
8129
		}
8130
	}
8131

    
8132
	// Check to see if we have a response for the expected dataType
8133
	if ( dataTypes[ 0 ] in responses ) {
8134
		finalDataType = dataTypes[ 0 ];
8135
	} else {
8136

    
8137
		// Try convertible dataTypes
8138
		for ( type in responses ) {
8139
			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
8140
				finalDataType = type;
8141
				break;
8142
			}
8143
			if ( !firstDataType ) {
8144
				firstDataType = type;
8145
			}
8146
		}
8147

    
8148
		// Or just use first one
8149
		finalDataType = finalDataType || firstDataType;
8150
	}
8151

    
8152
	// If we found a dataType
8153
	// We add the dataType to the list if needed
8154
	// and return the corresponding response
8155
	if ( finalDataType ) {
8156
		if ( finalDataType !== dataTypes[ 0 ] ) {
8157
			dataTypes.unshift( finalDataType );
8158
		}
8159
		return responses[ finalDataType ];
8160
	}
8161
}
8162

    
8163
/* Chain conversions given the request and the original response
8164
 * Also sets the responseXXX fields on the jqXHR instance
8165
 */
8166
function ajaxConvert( s, response, jqXHR, isSuccess ) {
8167
	var conv2, current, conv, tmp, prev,
8168
		converters = {},
8169

    
8170
		// Work with a copy of dataTypes in case we need to modify it for conversion
8171
		dataTypes = s.dataTypes.slice();
8172

    
8173
	// Create converters map with lowercased keys
8174
	if ( dataTypes[ 1 ] ) {
8175
		for ( conv in s.converters ) {
8176
			converters[ conv.toLowerCase() ] = s.converters[ conv ];
8177
		}
8178
	}
8179

    
8180
	current = dataTypes.shift();
8181

    
8182
	// Convert to each sequential dataType
8183
	while ( current ) {
8184

    
8185
		if ( s.responseFields[ current ] ) {
8186
			jqXHR[ s.responseFields[ current ] ] = response;
8187
		}
8188

    
8189
		// Apply the dataFilter if provided
8190
		if ( !prev && isSuccess && s.dataFilter ) {
8191
			response = s.dataFilter( response, s.dataType );
8192
		}
8193

    
8194
		prev = current;
8195
		current = dataTypes.shift();
8196

    
8197
		if ( current ) {
8198

    
8199
		// There's only work to do if current dataType is non-auto
8200
			if ( current === "*" ) {
8201

    
8202
				current = prev;
8203

    
8204
			// Convert response if prev dataType is non-auto and differs from current
8205
			} else 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

    
8223
								// Condense equivalence converters
8224
								if ( conv === true ) {
8225
									conv = converters[ conv2 ];
8226

    
8227
								// Otherwise, insert the intermediate dataType
8228
								} else if ( converters[ conv2 ] !== true ) {
8229
									current = tmp[ 0 ];
8230
									dataTypes.unshift( tmp[ 1 ] );
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 {
8249
								state: "parsererror",
8250
								error: conv ? e : "No conversion from " + prev + " to " + current
8251
							};
8252
						}
8253
					}
8254
				}
8255
			}
8256
		}
8257
	}
8258

    
8259
	return { state: "success", data: response };
8260
}
8261

    
8262
jQuery.extend( {
8263

    
8264
	// Counter for holding the number of active queries
8265
	active: 0,
8266

    
8267
	// Last-Modified header cache for next request
8268
	lastModified: {},
8269
	etag: {},
8270

    
8271
	ajaxSettings: {
8272
		url: location.href,
8273
		type: "GET",
8274
		isLocal: rlocalProtocol.test( location.protocol ),
8275
		global: true,
8276
		processData: true,
8277
		async: true,
8278
		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
8279
		/*
8280
		timeout: 0,
8281
		data: null,
8282
		dataType: null,
8283
		username: null,
8284
		password: null,
8285
		cache: null,
8286
		throws: false,
8287
		traditional: false,
8288
		headers: {},
8289
		*/
8290

    
8291
		accepts: {
8292
			"*": allTypes,
8293
			text: "text/plain",
8294
			html: "text/html",
8295
			xml: "application/xml, text/xml",
8296
			json: "application/json, text/javascript"
8297
		},
8298

    
8299
		contents: {
8300
			xml: /\bxml\b/,
8301
			html: /\bhtml/,
8302
			json: /\bjson\b/
8303
		},
8304

    
8305
		responseFields: {
8306
			xml: "responseXML",
8307
			text: "responseText",
8308
			json: "responseJSON"
8309
		},
8310

    
8311
		// Data converters
8312
		// Keys separate source (or catchall "*") and destination types with a single space
8313
		converters: {
8314

    
8315
			// Convert anything to text
8316
			"* text": String,
8317

    
8318
			// Text to html (true = no transformation)
8319
			"text html": true,
8320

    
8321
			// Evaluate text as a json expression
8322
			"text json": jQuery.parseJSON,
8323

    
8324
			// Parse text as xml
8325
			"text xml": jQuery.parseXML
8326
		},
8327

    
8328
		// For options that shouldn't be deep extended:
8329
		// you can add your own custom options here if
8330
		// and when you create one that shouldn't be
8331
		// deep extended (see ajaxExtend)
8332
		flatOptions: {
8333
			url: true,
8334
			context: true
8335
		}
8336
	},
8337

    
8338
	// Creates a full fledged settings object into target
8339
	// with both ajaxSettings and settings fields.
8340
	// If target is omitted, writes into ajaxSettings.
8341
	ajaxSetup: function( target, settings ) {
8342
		return settings ?
8343

    
8344
			// Building a settings object
8345
			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
8346

    
8347
			// Extending ajaxSettings
8348
			ajaxExtend( jQuery.ajaxSettings, target );
8349
	},
8350

    
8351
	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
8352
	ajaxTransport: addToPrefiltersOrTransports( transports ),
8353

    
8354
	// Main method
8355
	ajax: function( url, options ) {
8356

    
8357
		// If url is an object, simulate pre-1.5 signature
8358
		if ( typeof url === "object" ) {
8359
			options = url;
8360
			url = undefined;
8361
		}
8362

    
8363
		// Force options to be an object
8364
		options = options || {};
8365

    
8366
		var transport,
8367

    
8368
			// URL without anti-cache param
8369
			cacheURL,
8370

    
8371
			// Response headers
8372
			responseHeadersString,
8373
			responseHeaders,
8374

    
8375
			// timeout handle
8376
			timeoutTimer,
8377

    
8378
			// Url cleanup var
8379
			urlAnchor,
8380

    
8381
			// To know if global events are to be dispatched
8382
			fireGlobals,
8383

    
8384
			// Loop variable
8385
			i,
8386

    
8387
			// Create the final options object
8388
			s = jQuery.ajaxSetup( {}, options ),
8389

    
8390
			// Callbacks context
8391
			callbackContext = s.context || s,
8392

    
8393
			// Context for global events is callbackContext if it is a DOM node or jQuery collection
8394
			globalEventContext = s.context &&
8395
				( callbackContext.nodeType || callbackContext.jquery ) ?
8396
					jQuery( callbackContext ) :
8397
					jQuery.event,
8398

    
8399
			// Deferreds
8400
			deferred = jQuery.Deferred(),
8401
			completeDeferred = jQuery.Callbacks( "once memory" ),
8402

    
8403
			// Status-dependent callbacks
8404
			statusCode = s.statusCode || {},
8405

    
8406
			// Headers (they are sent all at once)
8407
			requestHeaders = {},
8408
			requestHeadersNames = {},
8409

    
8410
			// The jqXHR state
8411
			state = 0,
8412

    
8413
			// Default abort message
8414
			strAbort = "canceled",
8415

    
8416
			// Fake xhr
8417
			jqXHR = {
8418
				readyState: 0,
8419

    
8420
				// Builds headers hashtable if needed
8421
				getResponseHeader: function( key ) {
8422
					var match;
8423
					if ( state === 2 ) {
8424
						if ( !responseHeaders ) {
8425
							responseHeaders = {};
8426
							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
8427
								responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
8428
							}
8429
						}
8430
						match = responseHeaders[ key.toLowerCase() ];
8431
					}
8432
					return match == null ? null : match;
8433
				},
8434

    
8435
				// Raw string
8436
				getAllResponseHeaders: function() {
8437
					return state === 2 ? responseHeadersString : null;
8438
				},
8439

    
8440
				// Caches the header
8441
				setRequestHeader: function( name, value ) {
8442
					var lname = name.toLowerCase();
8443
					if ( !state ) {
8444
						name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
8445
						requestHeaders[ name ] = value;
8446
					}
8447
					return this;
8448
				},
8449

    
8450
				// Overrides response content-type header
8451
				overrideMimeType: function( type ) {
8452
					if ( !state ) {
8453
						s.mimeType = type;
8454
					}
8455
					return this;
8456
				},
8457

    
8458
				// Status-dependent callbacks
8459
				statusCode: function( map ) {
8460
					var code;
8461
					if ( map ) {
8462
						if ( state < 2 ) {
8463
							for ( code in map ) {
8464

    
8465
								// Lazy-add the new callback in a way that preserves old ones
8466
								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
8467
							}
8468
						} else {
8469

    
8470
							// Execute the appropriate callbacks
8471
							jqXHR.always( map[ jqXHR.status ] );
8472
						}
8473
					}
8474
					return this;
8475
				},
8476

    
8477
				// Cancel the request
8478
				abort: function( statusText ) {
8479
					var finalText = statusText || strAbort;
8480
					if ( transport ) {
8481
						transport.abort( finalText );
8482
					}
8483
					done( 0, finalText );
8484
					return this;
8485
				}
8486
			};
8487

    
8488
		// Attach deferreds
8489
		deferred.promise( jqXHR ).complete = completeDeferred.add;
8490
		jqXHR.success = jqXHR.done;
8491
		jqXHR.error = jqXHR.fail;
8492

    
8493
		// Remove hash character (#7531: and string promotion)
8494
		// Add protocol if not provided (prefilters might expect it)
8495
		// Handle falsy url in the settings object (#10093: consistency with old signature)
8496
		// We also use the url parameter if available
8497
		s.url = ( ( url || s.url || location.href ) + "" ).replace( rhash, "" )
8498
			.replace( rprotocol, location.protocol + "//" );
8499

    
8500
		// Alias method option to type as per ticket #12004
8501
		s.type = options.method || options.type || s.method || s.type;
8502

    
8503
		// Extract dataTypes list
8504
		s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
8505

    
8506
		// A cross-domain request is in order when the origin doesn't match the current origin.
8507
		if ( s.crossDomain == null ) {
8508
			urlAnchor = document.createElement( "a" );
8509

    
8510
			// Support: IE8-11+
8511
			// IE throws exception if url is malformed, e.g. http://example.com:80x/
8512
			try {
8513
				urlAnchor.href = s.url;
8514

    
8515
				// Support: IE8-11+
8516
				// Anchor's host property isn't correctly set when s.url is relative
8517
				urlAnchor.href = urlAnchor.href;
8518
				s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
8519
					urlAnchor.protocol + "//" + urlAnchor.host;
8520
			} catch ( e ) {
8521

    
8522
				// If there is an error parsing the URL, assume it is crossDomain,
8523
				// it can be rejected by the transport if it is invalid
8524
				s.crossDomain = true;
8525
			}
8526
		}
8527

    
8528
		// Convert data if not already a string
8529
		if ( s.data && s.processData && typeof s.data !== "string" ) {
8530
			s.data = jQuery.param( s.data, s.traditional );
8531
		}
8532

    
8533
		// Apply prefilters
8534
		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
8535

    
8536
		// If request was aborted inside a prefilter, stop there
8537
		if ( state === 2 ) {
8538
			return jqXHR;
8539
		}
8540

    
8541
		// We can fire global events as of now if asked to
8542
		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
8543
		fireGlobals = jQuery.event && s.global;
8544

    
8545
		// Watch for a new set of requests
8546
		if ( fireGlobals && jQuery.active++ === 0 ) {
8547
			jQuery.event.trigger( "ajaxStart" );
8548
		}
8549

    
8550
		// Uppercase the type
8551
		s.type = s.type.toUpperCase();
8552

    
8553
		// Determine if request has content
8554
		s.hasContent = !rnoContent.test( s.type );
8555

    
8556
		// Save the URL in case we're toying with the If-Modified-Since
8557
		// and/or If-None-Match header later on
8558
		cacheURL = s.url;
8559

    
8560
		// More options handling for requests with no content
8561
		if ( !s.hasContent ) {
8562

    
8563
			// If data is available, append data to url
8564
			if ( s.data ) {
8565
				cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
8566

    
8567
				// #9682: remove data so that it's not used in an eventual retry
8568
				delete s.data;
8569
			}
8570

    
8571
			// Add anti-cache in url if needed
8572
			if ( s.cache === false ) {
8573
				s.url = rts.test( cacheURL ) ?
8574

    
8575
					// If there is already a '_' parameter, set its value
8576
					cacheURL.replace( rts, "$1_=" + nonce++ ) :
8577

    
8578
					// Otherwise add one to the end
8579
					cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
8580
			}
8581
		}
8582

    
8583
		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
8584
		if ( s.ifModified ) {
8585
			if ( jQuery.lastModified[ cacheURL ] ) {
8586
				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
8587
			}
8588
			if ( jQuery.etag[ cacheURL ] ) {
8589
				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
8590
			}
8591
		}
8592

    
8593
		// Set the correct header, if data is being sent
8594
		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
8595
			jqXHR.setRequestHeader( "Content-Type", s.contentType );
8596
		}
8597

    
8598
		// Set the Accepts header for the server, depending on the dataType
8599
		jqXHR.setRequestHeader(
8600
			"Accept",
8601
			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
8602
				s.accepts[ s.dataTypes[ 0 ] ] +
8603
					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
8604
				s.accepts[ "*" ]
8605
		);
8606

    
8607
		// Check for headers option
8608
		for ( i in s.headers ) {
8609
			jqXHR.setRequestHeader( i, s.headers[ i ] );
8610
		}
8611

    
8612
		// Allow custom headers/mimetypes and early abort
8613
		if ( s.beforeSend &&
8614
			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
8615

    
8616
			// Abort if not done already and return
8617
			return jqXHR.abort();
8618
		}
8619

    
8620
		// Aborting is no longer a cancellation
8621
		strAbort = "abort";
8622

    
8623
		// Install callbacks on deferreds
8624
		for ( i in { success: 1, error: 1, complete: 1 } ) {
8625
			jqXHR[ i ]( s[ i ] );
8626
		}
8627

    
8628
		// Get transport
8629
		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
8630

    
8631
		// If no transport, we auto-abort
8632
		if ( !transport ) {
8633
			done( -1, "No Transport" );
8634
		} else {
8635
			jqXHR.readyState = 1;
8636

    
8637
			// Send global event
8638
			if ( fireGlobals ) {
8639
				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
8640
			}
8641

    
8642
			// If request was aborted inside ajaxSend, stop there
8643
			if ( state === 2 ) {
8644
				return jqXHR;
8645
			}
8646

    
8647
			// Timeout
8648
			if ( s.async && s.timeout > 0 ) {
8649
				timeoutTimer = window.setTimeout( function() {
8650
					jqXHR.abort( "timeout" );
8651
				}, s.timeout );
8652
			}
8653

    
8654
			try {
8655
				state = 1;
8656
				transport.send( requestHeaders, done );
8657
			} catch ( e ) {
8658

    
8659
				// Propagate exception as error if not done
8660
				if ( state < 2 ) {
8661
					done( -1, e );
8662

    
8663
				// Simply rethrow otherwise
8664
				} else {
8665
					throw e;
8666
				}
8667
			}
8668
		}
8669

    
8670
		// Callback for when everything is done
8671
		function done( status, nativeStatusText, responses, headers ) {
8672
			var isSuccess, success, error, response, modified,
8673
				statusText = nativeStatusText;
8674

    
8675
			// Called once
8676
			if ( state === 2 ) {
8677
				return;
8678
			}
8679

    
8680
			// State is "done" now
8681
			state = 2;
8682

    
8683
			// Clear timeout if it exists
8684
			if ( timeoutTimer ) {
8685
				window.clearTimeout( timeoutTimer );
8686
			}
8687

    
8688
			// Dereference transport for early garbage collection
8689
			// (no matter how long the jqXHR object will be used)
8690
			transport = undefined;
8691

    
8692
			// Cache response headers
8693
			responseHeadersString = headers || "";
8694

    
8695
			// Set readyState
8696
			jqXHR.readyState = status > 0 ? 4 : 0;
8697

    
8698
			// Determine if successful
8699
			isSuccess = status >= 200 && status < 300 || status === 304;
8700

    
8701
			// Get response data
8702
			if ( responses ) {
8703
				response = ajaxHandleResponses( s, jqXHR, responses );
8704
			}
8705

    
8706
			// Convert no matter what (that way responseXXX fields are always set)
8707
			response = ajaxConvert( s, response, jqXHR, isSuccess );
8708

    
8709
			// If successful, handle type chaining
8710
			if ( isSuccess ) {
8711

    
8712
				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
8713
				if ( s.ifModified ) {
8714
					modified = jqXHR.getResponseHeader( "Last-Modified" );
8715
					if ( modified ) {
8716
						jQuery.lastModified[ cacheURL ] = modified;
8717
					}
8718
					modified = jqXHR.getResponseHeader( "etag" );
8719
					if ( modified ) {
8720
						jQuery.etag[ cacheURL ] = modified;
8721
					}
8722
				}
8723

    
8724
				// if no content
8725
				if ( status === 204 || s.type === "HEAD" ) {
8726
					statusText = "nocontent";
8727

    
8728
				// if not modified
8729
				} else if ( status === 304 ) {
8730
					statusText = "notmodified";
8731

    
8732
				// If we have data, let's convert it
8733
				} else {
8734
					statusText = response.state;
8735
					success = response.data;
8736
					error = response.error;
8737
					isSuccess = !error;
8738
				}
8739
			} else {
8740

    
8741
				// Extract error from statusText and normalize for non-aborts
8742
				error = statusText;
8743
				if ( status || !statusText ) {
8744
					statusText = "error";
8745
					if ( status < 0 ) {
8746
						status = 0;
8747
					}
8748
				}
8749
			}
8750

    
8751
			// Set data for the fake xhr object
8752
			jqXHR.status = status;
8753
			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
8754

    
8755
			// Success/Error
8756
			if ( isSuccess ) {
8757
				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
8758
			} else {
8759
				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
8760
			}
8761

    
8762
			// Status-dependent callbacks
8763
			jqXHR.statusCode( statusCode );
8764
			statusCode = undefined;
8765

    
8766
			if ( fireGlobals ) {
8767
				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
8768
					[ jqXHR, s, isSuccess ? success : error ] );
8769
			}
8770

    
8771
			// Complete
8772
			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
8773

    
8774
			if ( fireGlobals ) {
8775
				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
8776

    
8777
				// Handle the global AJAX counter
8778
				if ( !( --jQuery.active ) ) {
8779
					jQuery.event.trigger( "ajaxStop" );
8780
				}
8781
			}
8782
		}
8783

    
8784
		return jqXHR;
8785
	},
8786

    
8787
	getJSON: function( url, data, callback ) {
8788
		return jQuery.get( url, data, callback, "json" );
8789
	},
8790

    
8791
	getScript: function( url, callback ) {
8792
		return jQuery.get( url, undefined, callback, "script" );
8793
	}
8794
} );
8795

    
8796
jQuery.each( [ "get", "post" ], function( i, method ) {
8797
	jQuery[ method ] = function( url, data, callback, type ) {
8798

    
8799
		// Shift arguments if data argument was omitted
8800
		if ( jQuery.isFunction( data ) ) {
8801
			type = type || callback;
8802
			callback = data;
8803
			data = undefined;
8804
		}
8805

    
8806
		// The url can be an options object (which then must have .url)
8807
		return jQuery.ajax( jQuery.extend( {
8808
			url: url,
8809
			type: method,
8810
			dataType: type,
8811
			data: data,
8812
			success: callback
8813
		}, jQuery.isPlainObject( url ) && url ) );
8814
	};
8815
} );
8816

    
8817

    
8818
jQuery._evalUrl = function( url ) {
8819
	return jQuery.ajax( {
8820
		url: url,
8821

    
8822
		// Make this explicit, since user can override this through ajaxSetup (#11264)
8823
		type: "GET",
8824
		dataType: "script",
8825
		async: false,
8826
		global: false,
8827
		"throws": true
8828
	} );
8829
};
8830

    
8831

    
8832
jQuery.fn.extend( {
8833
	wrapAll: function( html ) {
8834
		var wrap;
8835

    
8836
		if ( jQuery.isFunction( html ) ) {
8837
			return this.each( function( i ) {
8838
				jQuery( this ).wrapAll( html.call( this, i ) );
8839
			} );
8840
		}
8841

    
8842
		if ( this[ 0 ] ) {
8843

    
8844
			// The elements to wrap the target around
8845
			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
8846

    
8847
			if ( this[ 0 ].parentNode ) {
8848
				wrap.insertBefore( this[ 0 ] );
8849
			}
8850

    
8851
			wrap.map( function() {
8852
				var elem = this;
8853

    
8854
				while ( elem.firstElementChild ) {
8855
					elem = elem.firstElementChild;
8856
				}
8857

    
8858
				return elem;
8859
			} ).append( this );
8860
		}
8861

    
8862
		return this;
8863
	},
8864

    
8865
	wrapInner: function( html ) {
8866
		if ( jQuery.isFunction( html ) ) {
8867
			return this.each( function( i ) {
8868
				jQuery( this ).wrapInner( html.call( this, i ) );
8869
			} );
8870
		}
8871

    
8872
		return this.each( function() {
8873
			var self = jQuery( this ),
8874
				contents = self.contents();
8875

    
8876
			if ( contents.length ) {
8877
				contents.wrapAll( html );
8878

    
8879
			} else {
8880
				self.append( html );
8881
			}
8882
		} );
8883
	},
8884

    
8885
	wrap: function( html ) {
8886
		var isFunction = jQuery.isFunction( html );
8887

    
8888
		return this.each( function( i ) {
8889
			jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
8890
		} );
8891
	},
8892

    
8893
	unwrap: function() {
8894
		return this.parent().each( function() {
8895
			if ( !jQuery.nodeName( this, "body" ) ) {
8896
				jQuery( this ).replaceWith( this.childNodes );
8897
			}
8898
		} ).end();
8899
	}
8900
} );
8901

    
8902

    
8903
jQuery.expr.filters.hidden = function( elem ) {
8904
	return !jQuery.expr.filters.visible( elem );
8905
};
8906
jQuery.expr.filters.visible = function( elem ) {
8907

    
8908
	// Support: Opera <= 12.12
8909
	// Opera reports offsetWidths and offsetHeights less than zero on some elements
8910
	// Use OR instead of AND as the element is not visible if either is true
8911
	// See tickets #10406 and #13132
8912
	return elem.offsetWidth > 0 || elem.offsetHeight > 0 || elem.getClientRects().length > 0;
8913
};
8914

    
8915

    
8916

    
8917

    
8918
var r20 = /%20/g,
8919
	rbracket = /\[\]$/,
8920
	rCRLF = /\r?\n/g,
8921
	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
8922
	rsubmittable = /^(?:input|select|textarea|keygen)/i;
8923

    
8924
function buildParams( prefix, obj, traditional, add ) {
8925
	var name;
8926

    
8927
	if ( jQuery.isArray( obj ) ) {
8928

    
8929
		// Serialize array item.
8930
		jQuery.each( obj, function( i, v ) {
8931
			if ( traditional || rbracket.test( prefix ) ) {
8932

    
8933
				// Treat each array item as a scalar.
8934
				add( prefix, v );
8935

    
8936
			} else {
8937

    
8938
				// Item is non-scalar (array or object), encode its numeric index.
8939
				buildParams(
8940
					prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
8941
					v,
8942
					traditional,
8943
					add
8944
				);
8945
			}
8946
		} );
8947

    
8948
	} else if ( !traditional && jQuery.type( obj ) === "object" ) {
8949

    
8950
		// Serialize object item.
8951
		for ( name in obj ) {
8952
			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
8953
		}
8954

    
8955
	} else {
8956

    
8957
		// Serialize scalar item.
8958
		add( prefix, obj );
8959
	}
8960
}
8961

    
8962
// Serialize an array of form elements or a set of
8963
// key/values into a query string
8964
jQuery.param = function( a, traditional ) {
8965
	var prefix,
8966
		s = [],
8967
		add = function( key, value ) {
8968

    
8969
			// If value is a function, invoke it and return its value
8970
			value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
8971
			s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
8972
		};
8973

    
8974
	// Set traditional to true for jQuery <= 1.3.2 behavior.
8975
	if ( traditional === undefined ) {
8976
		traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
8977
	}
8978

    
8979
	// If an array was passed in, assume that it is an array of form elements.
8980
	if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
8981

    
8982
		// Serialize the form elements
8983
		jQuery.each( a, function() {
8984
			add( this.name, this.value );
8985
		} );
8986

    
8987
	} else {
8988

    
8989
		// If traditional, encode the "old" way (the way 1.3.2 or older
8990
		// did it), otherwise encode params recursively.
8991
		for ( prefix in a ) {
8992
			buildParams( prefix, a[ prefix ], traditional, add );
8993
		}
8994
	}
8995

    
8996
	// Return the resulting serialization
8997
	return s.join( "&" ).replace( r20, "+" );
8998
};
8999

    
9000
jQuery.fn.extend( {
9001
	serialize: function() {
9002
		return jQuery.param( this.serializeArray() );
9003
	},
9004
	serializeArray: function() {
9005
		return this.map( function() {
9006

    
9007
			// Can add propHook for "elements" to filter or add form elements
9008
			var elements = jQuery.prop( this, "elements" );
9009
			return elements ? jQuery.makeArray( elements ) : this;
9010
		} )
9011
		.filter( function() {
9012
			var type = this.type;
9013

    
9014
			// Use .is( ":disabled" ) so that fieldset[disabled] works
9015
			return this.name && !jQuery( this ).is( ":disabled" ) &&
9016
				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
9017
				( this.checked || !rcheckableType.test( type ) );
9018
		} )
9019
		.map( function( i, elem ) {
9020
			var val = jQuery( this ).val();
9021

    
9022
			return val == null ?
9023
				null :
9024
				jQuery.isArray( val ) ?
9025
					jQuery.map( val, function( val ) {
9026
						return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
9027
					} ) :
9028
					{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
9029
		} ).get();
9030
	}
9031
} );
9032

    
9033

    
9034
jQuery.ajaxSettings.xhr = function() {
9035
	try {
9036
		return new window.XMLHttpRequest();
9037
	} catch ( e ) {}
9038
};
9039

    
9040
var xhrSuccessStatus = {
9041

    
9042
		// File protocol always yields status code 0, assume 200
9043
		0: 200,
9044

    
9045
		// Support: IE9
9046
		// #1450: sometimes IE returns 1223 when it should be 204
9047
		1223: 204
9048
	},
9049
	xhrSupported = jQuery.ajaxSettings.xhr();
9050

    
9051
support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
9052
support.ajax = xhrSupported = !!xhrSupported;
9053

    
9054
jQuery.ajaxTransport( function( options ) {
9055
	var callback, errorCallback;
9056

    
9057
	// Cross domain only allowed if supported through XMLHttpRequest
9058
	if ( support.cors || xhrSupported && !options.crossDomain ) {
9059
		return {
9060
			send: function( headers, complete ) {
9061
				var i,
9062
					xhr = options.xhr();
9063

    
9064
				xhr.open(
9065
					options.type,
9066
					options.url,
9067
					options.async,
9068
					options.username,
9069
					options.password
9070
				);
9071

    
9072
				// Apply custom fields if provided
9073
				if ( options.xhrFields ) {
9074
					for ( i in options.xhrFields ) {
9075
						xhr[ i ] = options.xhrFields[ i ];
9076
					}
9077
				}
9078

    
9079
				// Override mime type if needed
9080
				if ( options.mimeType && xhr.overrideMimeType ) {
9081
					xhr.overrideMimeType( options.mimeType );
9082
				}
9083

    
9084
				// X-Requested-With header
9085
				// For cross-domain requests, seeing as conditions for a preflight are
9086
				// akin to a jigsaw puzzle, we simply never set it to be sure.
9087
				// (it can always be set on a per-request basis or even using ajaxSetup)
9088
				// For same-domain requests, won't change header if already provided.
9089
				if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
9090
					headers[ "X-Requested-With" ] = "XMLHttpRequest";
9091
				}
9092

    
9093
				// Set headers
9094
				for ( i in headers ) {
9095
					xhr.setRequestHeader( i, headers[ i ] );
9096
				}
9097

    
9098
				// Callback
9099
				callback = function( type ) {
9100
					return function() {
9101
						if ( callback ) {
9102
							callback = errorCallback = xhr.onload =
9103
								xhr.onerror = xhr.onabort = xhr.onreadystatechange = null;
9104

    
9105
							if ( type === "abort" ) {
9106
								xhr.abort();
9107
							} else if ( type === "error" ) {
9108

    
9109
								// Support: IE9
9110
								// On a manual native abort, IE9 throws
9111
								// errors on any property access that is not readyState
9112
								if ( typeof xhr.status !== "number" ) {
9113
									complete( 0, "error" );
9114
								} else {
9115
									complete(
9116

    
9117
										// File: protocol always yields status 0; see #8605, #14207
9118
										xhr.status,
9119
										xhr.statusText
9120
									);
9121
								}
9122
							} else {
9123
								complete(
9124
									xhrSuccessStatus[ xhr.status ] || xhr.status,
9125
									xhr.statusText,
9126

    
9127
									// Support: IE9 only
9128
									// IE9 has no XHR2 but throws on binary (trac-11426)
9129
									// For XHR2 non-text, let the caller handle it (gh-2498)
9130
									( xhr.responseType || "text" ) !== "text"  ||
9131
									typeof xhr.responseText !== "string" ?
9132
										{ binary: xhr.response } :
9133
										{ text: xhr.responseText },
9134
									xhr.getAllResponseHeaders()
9135
								);
9136
							}
9137
						}
9138
					};
9139
				};
9140

    
9141
				// Listen to events
9142
				xhr.onload = callback();
9143
				errorCallback = xhr.onerror = callback( "error" );
9144

    
9145
				// Support: IE9
9146
				// Use onreadystatechange to replace onabort
9147
				// to handle uncaught aborts
9148
				if ( xhr.onabort !== undefined ) {
9149
					xhr.onabort = errorCallback;
9150
				} else {
9151
					xhr.onreadystatechange = function() {
9152

    
9153
						// Check readyState before timeout as it changes
9154
						if ( xhr.readyState === 4 ) {
9155

    
9156
							// Allow onerror to be called first,
9157
							// but that will not handle a native abort
9158
							// Also, save errorCallback to a variable
9159
							// as xhr.onerror cannot be accessed
9160
							window.setTimeout( function() {
9161
								if ( callback ) {
9162
									errorCallback();
9163
								}
9164
							} );
9165
						}
9166
					};
9167
				}
9168

    
9169
				// Create the abort callback
9170
				callback = callback( "abort" );
9171

    
9172
				try {
9173

    
9174
					// Do send the request (this may raise an exception)
9175
					xhr.send( options.hasContent && options.data || null );
9176
				} catch ( e ) {
9177

    
9178
					// #14683: Only rethrow if this hasn't been notified as an error yet
9179
					if ( callback ) {
9180
						throw e;
9181
					}
9182
				}
9183
			},
9184

    
9185
			abort: function() {
9186
				if ( callback ) {
9187
					callback();
9188
				}
9189
			}
9190
		};
9191
	}
9192
} );
9193

    
9194

    
9195

    
9196

    
9197
// Install script dataType
9198
jQuery.ajaxSetup( {
9199
	accepts: {
9200
		script: "text/javascript, application/javascript, " +
9201
			"application/ecmascript, application/x-ecmascript"
9202
	},
9203
	contents: {
9204
		script: /\b(?:java|ecma)script\b/
9205
	},
9206
	converters: {
9207
		"text script": function( text ) {
9208
			jQuery.globalEval( text );
9209
			return text;
9210
		}
9211
	}
9212
} );
9213

    
9214
// Handle cache's special case and crossDomain
9215
jQuery.ajaxPrefilter( "script", function( s ) {
9216
	if ( s.cache === undefined ) {
9217
		s.cache = false;
9218
	}
9219
	if ( s.crossDomain ) {
9220
		s.type = "GET";
9221
	}
9222
} );
9223

    
9224
// Bind script tag hack transport
9225
jQuery.ajaxTransport( "script", function( s ) {
9226

    
9227
	// This transport only deals with cross domain requests
9228
	if ( s.crossDomain ) {
9229
		var script, callback;
9230
		return {
9231
			send: function( _, complete ) {
9232
				script = jQuery( "<script>" ).prop( {
9233
					charset: s.scriptCharset,
9234
					src: s.url
9235
				} ).on(
9236
					"load error",
9237
					callback = function( evt ) {
9238
						script.remove();
9239
						callback = null;
9240
						if ( evt ) {
9241
							complete( evt.type === "error" ? 404 : 200, evt.type );
9242
						}
9243
					}
9244
				);
9245

    
9246
				// Use native DOM manipulation to avoid our domManip AJAX trickery
9247
				document.head.appendChild( script[ 0 ] );
9248
			},
9249
			abort: function() {
9250
				if ( callback ) {
9251
					callback();
9252
				}
9253
			}
9254
		};
9255
	}
9256
} );
9257

    
9258

    
9259

    
9260

    
9261
var oldCallbacks = [],
9262
	rjsonp = /(=)\?(?=&|$)|\?\?/;
9263

    
9264
// Default jsonp settings
9265
jQuery.ajaxSetup( {
9266
	jsonp: "callback",
9267
	jsonpCallback: function() {
9268
		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
9269
		this[ callback ] = true;
9270
		return callback;
9271
	}
9272
} );
9273

    
9274
// Detect, normalize options and install callbacks for jsonp requests
9275
jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
9276

    
9277
	var callbackName, overwritten, responseContainer,
9278
		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
9279
			"url" :
9280
			typeof s.data === "string" &&
9281
				( s.contentType || "" )
9282
					.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
9283
				rjsonp.test( s.data ) && "data"
9284
		);
9285

    
9286
	// Handle iff the expected data type is "jsonp" or we have a parameter to set
9287
	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
9288

    
9289
		// Get callback name, remembering preexisting value associated with it
9290
		callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
9291
			s.jsonpCallback() :
9292
			s.jsonpCallback;
9293

    
9294
		// Insert callback into url or form data
9295
		if ( jsonProp ) {
9296
			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
9297
		} else if ( s.jsonp !== false ) {
9298
			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
9299
		}
9300

    
9301
		// Use data converter to retrieve json after script execution
9302
		s.converters[ "script json" ] = function() {
9303
			if ( !responseContainer ) {
9304
				jQuery.error( callbackName + " was not called" );
9305
			}
9306
			return responseContainer[ 0 ];
9307
		};
9308

    
9309
		// Force json dataType
9310
		s.dataTypes[ 0 ] = "json";
9311

    
9312
		// Install callback
9313
		overwritten = window[ callbackName ];
9314
		window[ callbackName ] = function() {
9315
			responseContainer = arguments;
9316
		};
9317

    
9318
		// Clean-up function (fires after converters)
9319
		jqXHR.always( function() {
9320

    
9321
			// If previous value didn't exist - remove it
9322
			if ( overwritten === undefined ) {
9323
				jQuery( window ).removeProp( callbackName );
9324

    
9325
			// Otherwise restore preexisting value
9326
			} else {
9327
				window[ callbackName ] = overwritten;
9328
			}
9329

    
9330
			// Save back as free
9331
			if ( s[ callbackName ] ) {
9332

    
9333
				// Make sure that re-using the options doesn't screw things around
9334
				s.jsonpCallback = originalSettings.jsonpCallback;
9335

    
9336
				// Save the callback name for future use
9337
				oldCallbacks.push( callbackName );
9338
			}
9339

    
9340
			// Call if it was a function and we have a response
9341
			if ( responseContainer && jQuery.isFunction( overwritten ) ) {
9342
				overwritten( responseContainer[ 0 ] );
9343
			}
9344

    
9345
			responseContainer = overwritten = undefined;
9346
		} );
9347

    
9348
		// Delegate to script
9349
		return "script";
9350
	}
9351
} );
9352

    
9353

    
9354

    
9355

    
9356
// Argument "data" should be string of html
9357
// context (optional): If specified, the fragment will be created in this context,
9358
// defaults to document
9359
// keepScripts (optional): If true, will include scripts passed in the html string
9360
jQuery.parseHTML = function( data, context, keepScripts ) {
9361
	if ( !data || typeof data !== "string" ) {
9362
		return null;
9363
	}
9364
	if ( typeof context === "boolean" ) {
9365
		keepScripts = context;
9366
		context = false;
9367
	}
9368
	context = context || document;
9369

    
9370
	var parsed = rsingleTag.exec( data ),
9371
		scripts = !keepScripts && [];
9372

    
9373
	// Single tag
9374
	if ( parsed ) {
9375
		return [ context.createElement( parsed[ 1 ] ) ];
9376
	}
9377

    
9378
	parsed = buildFragment( [ data ], context, scripts );
9379

    
9380
	if ( scripts && scripts.length ) {
9381
		jQuery( scripts ).remove();
9382
	}
9383

    
9384
	return jQuery.merge( [], parsed.childNodes );
9385
};
9386

    
9387

    
9388
// Keep a copy of the old load method
9389
var _load = jQuery.fn.load;
9390

    
9391
/**
9392
 * Load a url into a page
9393
 */
9394
jQuery.fn.load = function( url, params, callback ) {
9395
	if ( typeof url !== "string" && _load ) {
9396
		return _load.apply( this, arguments );
9397
	}
9398

    
9399
	var selector, type, response,
9400
		self = this,
9401
		off = url.indexOf( " " );
9402

    
9403
	if ( off > -1 ) {
9404
		selector = jQuery.trim( url.slice( off ) );
9405
		url = url.slice( 0, off );
9406
	}
9407

    
9408
	// If it's a function
9409
	if ( jQuery.isFunction( params ) ) {
9410

    
9411
		// We assume that it's the callback
9412
		callback = params;
9413
		params = undefined;
9414

    
9415
	// Otherwise, build a param string
9416
	} else if ( params && typeof params === "object" ) {
9417
		type = "POST";
9418
	}
9419

    
9420
	// If we have elements to modify, make the request
9421
	if ( self.length > 0 ) {
9422
		jQuery.ajax( {
9423
			url: url,
9424

    
9425
			// If "type" variable is undefined, then "GET" method will be used.
9426
			// Make value of this field explicit since
9427
			// user can override it through ajaxSetup method
9428
			type: type || "GET",
9429
			dataType: "html",
9430
			data: params
9431
		} ).done( function( responseText ) {
9432

    
9433
			// Save response for use in complete callback
9434
			response = arguments;
9435

    
9436
			self.html( selector ?
9437

    
9438
				// If a selector was specified, locate the right elements in a dummy div
9439
				// Exclude scripts to avoid IE 'Permission Denied' errors
9440
				jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
9441

    
9442
				// Otherwise use the full result
9443
				responseText );
9444

    
9445
		// If the request succeeds, this function gets "data", "status", "jqXHR"
9446
		// but they are ignored because response was set above.
9447
		// If it fails, this function gets "jqXHR", "status", "error"
9448
		} ).always( callback && function( jqXHR, status ) {
9449
			self.each( function() {
9450
				callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
9451
			} );
9452
		} );
9453
	}
9454

    
9455
	return this;
9456
};
9457

    
9458

    
9459

    
9460

    
9461
// Attach a bunch of functions for handling common AJAX events
9462
jQuery.each( [
9463
	"ajaxStart",
9464
	"ajaxStop",
9465
	"ajaxComplete",
9466
	"ajaxError",
9467
	"ajaxSuccess",
9468
	"ajaxSend"
9469
], function( i, type ) {
9470
	jQuery.fn[ type ] = function( fn ) {
9471
		return this.on( type, fn );
9472
	};
9473
} );
9474

    
9475

    
9476

    
9477

    
9478
jQuery.expr.filters.animated = function( elem ) {
9479
	return jQuery.grep( jQuery.timers, function( fn ) {
9480
		return elem === fn.elem;
9481
	} ).length;
9482
};
9483

    
9484

    
9485

    
9486

    
9487
/**
9488
 * Gets a window from an element
9489
 */
9490
function getWindow( elem ) {
9491
	return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
9492
}
9493

    
9494
jQuery.offset = {
9495
	setOffset: function( elem, options, i ) {
9496
		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
9497
			position = jQuery.css( elem, "position" ),
9498
			curElem = jQuery( elem ),
9499
			props = {};
9500

    
9501
		// Set position first, in-case top/left are set even on static elem
9502
		if ( position === "static" ) {
9503
			elem.style.position = "relative";
9504
		}
9505

    
9506
		curOffset = curElem.offset();
9507
		curCSSTop = jQuery.css( elem, "top" );
9508
		curCSSLeft = jQuery.css( elem, "left" );
9509
		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
9510
			( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
9511

    
9512
		// Need to be able to calculate position if either
9513
		// top or left is auto and position is either absolute or fixed
9514
		if ( calculatePosition ) {
9515
			curPosition = curElem.position();
9516
			curTop = curPosition.top;
9517
			curLeft = curPosition.left;
9518

    
9519
		} else {
9520
			curTop = parseFloat( curCSSTop ) || 0;
9521
			curLeft = parseFloat( curCSSLeft ) || 0;
9522
		}
9523

    
9524
		if ( jQuery.isFunction( options ) ) {
9525

    
9526
			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
9527
			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
9528
		}
9529

    
9530
		if ( options.top != null ) {
9531
			props.top = ( options.top - curOffset.top ) + curTop;
9532
		}
9533
		if ( options.left != null ) {
9534
			props.left = ( options.left - curOffset.left ) + curLeft;
9535
		}
9536

    
9537
		if ( "using" in options ) {
9538
			options.using.call( elem, props );
9539

    
9540
		} else {
9541
			curElem.css( props );
9542
		}
9543
	}
9544
};
9545

    
9546
jQuery.fn.extend( {
9547
	offset: function( options ) {
9548
		if ( arguments.length ) {
9549
			return options === undefined ?
9550
				this :
9551
				this.each( function( i ) {
9552
					jQuery.offset.setOffset( this, options, i );
9553
				} );
9554
		}
9555

    
9556
		var docElem, win,
9557
			elem = this[ 0 ],
9558
			box = { top: 0, left: 0 },
9559
			doc = elem && elem.ownerDocument;
9560

    
9561
		if ( !doc ) {
9562
			return;
9563
		}
9564

    
9565
		docElem = doc.documentElement;
9566

    
9567
		// Make sure it's not a disconnected DOM node
9568
		if ( !jQuery.contains( docElem, elem ) ) {
9569
			return box;
9570
		}
9571

    
9572
		box = elem.getBoundingClientRect();
9573
		win = getWindow( doc );
9574
		return {
9575
			top: box.top + win.pageYOffset - docElem.clientTop,
9576
			left: box.left + win.pageXOffset - docElem.clientLeft
9577
		};
9578
	},
9579

    
9580
	position: function() {
9581
		if ( !this[ 0 ] ) {
9582
			return;
9583
		}
9584

    
9585
		var offsetParent, offset,
9586
			elem = this[ 0 ],
9587
			parentOffset = { top: 0, left: 0 };
9588

    
9589
		// Fixed elements are offset from window (parentOffset = {top:0, left: 0},
9590
		// because it is its only offset parent
9591
		if ( jQuery.css( elem, "position" ) === "fixed" ) {
9592

    
9593
			// Assume getBoundingClientRect is there when computed position is fixed
9594
			offset = elem.getBoundingClientRect();
9595

    
9596
		} else {
9597

    
9598
			// Get *real* offsetParent
9599
			offsetParent = this.offsetParent();
9600

    
9601
			// Get correct offsets
9602
			offset = this.offset();
9603
			if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
9604
				parentOffset = offsetParent.offset();
9605
			}
9606

    
9607
			// Add offsetParent borders
9608
			parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
9609
			parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
9610
		}
9611

    
9612
		// Subtract parent offsets and element margins
9613
		return {
9614
			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
9615
			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
9616
		};
9617
	},
9618

    
9619
	// This method will return documentElement in the following cases:
9620
	// 1) For the element inside the iframe without offsetParent, this method will return
9621
	//    documentElement of the parent window
9622
	// 2) For the hidden or detached element
9623
	// 3) For body or html element, i.e. in case of the html node - it will return itself
9624
	//
9625
	// but those exceptions were never presented as a real life use-cases
9626
	// and might be considered as more preferable results.
9627
	//
9628
	// This logic, however, is not guaranteed and can change at any point in the future
9629
	offsetParent: function() {
9630
		return this.map( function() {
9631
			var offsetParent = this.offsetParent;
9632

    
9633
			while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
9634
				offsetParent = offsetParent.offsetParent;
9635
			}
9636

    
9637
			return offsetParent || documentElement;
9638
		} );
9639
	}
9640
} );
9641

    
9642
// Create scrollLeft and scrollTop methods
9643
jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
9644
	var top = "pageYOffset" === prop;
9645

    
9646
	jQuery.fn[ method ] = function( val ) {
9647
		return access( this, function( elem, method, val ) {
9648
			var win = getWindow( elem );
9649

    
9650
			if ( val === undefined ) {
9651
				return win ? win[ prop ] : elem[ method ];
9652
			}
9653

    
9654
			if ( win ) {
9655
				win.scrollTo(
9656
					!top ? val : win.pageXOffset,
9657
					top ? val : win.pageYOffset
9658
				);
9659

    
9660
			} else {
9661
				elem[ method ] = val;
9662
			}
9663
		}, method, val, arguments.length );
9664
	};
9665
} );
9666

    
9667
// Support: Safari<7-8+, Chrome<37-44+
9668
// Add the top/left cssHooks using jQuery.fn.position
9669
// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
9670
// Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280
9671
// getComputedStyle returns percent when specified for top/left/bottom/right;
9672
// rather than make the css module depend on the offset module, just check for it here
9673
jQuery.each( [ "top", "left" ], function( i, prop ) {
9674
	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
9675
		function( elem, computed ) {
9676
			if ( computed ) {
9677
				computed = curCSS( elem, prop );
9678

    
9679
				// If curCSS returns percentage, fallback to offset
9680
				return rnumnonpx.test( computed ) ?
9681
					jQuery( elem ).position()[ prop ] + "px" :
9682
					computed;
9683
			}
9684
		}
9685
	);
9686
} );
9687

    
9688

    
9689
// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
9690
jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
9691
	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
9692
		function( defaultExtra, funcName ) {
9693

    
9694
		// Margin is only for outerHeight, outerWidth
9695
		jQuery.fn[ funcName ] = function( margin, value ) {
9696
			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
9697
				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
9698

    
9699
			return access( this, function( elem, type, value ) {
9700
				var doc;
9701

    
9702
				if ( jQuery.isWindow( elem ) ) {
9703

    
9704
					// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
9705
					// isn't a whole lot we can do. See pull request at this URL for discussion:
9706
					// https://github.com/jquery/jquery/pull/764
9707
					return elem.document.documentElement[ "client" + name ];
9708
				}
9709

    
9710
				// Get document width or height
9711
				if ( elem.nodeType === 9 ) {
9712
					doc = elem.documentElement;
9713

    
9714
					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
9715
					// whichever is greatest
9716
					return Math.max(
9717
						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
9718
						elem.body[ "offset" + name ], doc[ "offset" + name ],
9719
						doc[ "client" + name ]
9720
					);
9721
				}
9722

    
9723
				return value === undefined ?
9724

    
9725
					// Get width or height on the element, requesting but not forcing parseFloat
9726
					jQuery.css( elem, type, extra ) :
9727

    
9728
					// Set width or height on the element
9729
					jQuery.style( elem, type, value, extra );
9730
			}, type, chainable ? margin : undefined, chainable, null );
9731
		};
9732
	} );
9733
} );
9734

    
9735

    
9736
jQuery.fn.extend( {
9737

    
9738
	bind: function( types, data, fn ) {
9739
		return this.on( types, null, data, fn );
9740
	},
9741
	unbind: function( types, fn ) {
9742
		return this.off( types, null, fn );
9743
	},
9744

    
9745
	delegate: function( selector, types, data, fn ) {
9746
		return this.on( types, selector, data, fn );
9747
	},
9748
	undelegate: function( selector, types, fn ) {
9749

    
9750
		// ( namespace ) or ( selector, types [, fn] )
9751
		return arguments.length === 1 ?
9752
			this.off( selector, "**" ) :
9753
			this.off( types, selector || "**", fn );
9754
	},
9755
	size: function() {
9756
		return this.length;
9757
	}
9758
} );
9759

    
9760
jQuery.fn.andSelf = jQuery.fn.addBack;
9761

    
9762

    
9763

    
9764

    
9765
// Register as a named AMD module, since jQuery can be concatenated with other
9766
// files that may use define, but not via a proper concatenation script that
9767
// understands anonymous AMD modules. A named AMD is safest and most robust
9768
// way to register. Lowercase jquery is used because AMD module names are
9769
// derived from file names, and jQuery is normally delivered in a lowercase
9770
// file name. Do this after creating the global so that if an AMD module wants
9771
// to call noConflict to hide this version of jQuery, it will work.
9772

    
9773
// Note that for maximum portability, libraries that are not jQuery should
9774
// declare themselves as anonymous modules, and avoid setting a global if an
9775
// AMD loader is present. jQuery is a special case. For more information, see
9776
// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
9777

    
9778
if ( typeof define === "function" && define.amd ) {
9779
	define( "jquery", [], function() {
9780
		return jQuery;
9781
	} );
9782
}
9783

    
9784

    
9785

    
9786
var
9787

    
9788
	// Map over jQuery in case of overwrite
9789
	_jQuery = window.jQuery,
9790

    
9791
	// Map over the $ in case of overwrite
9792
	_$ = window.$;
9793

    
9794
jQuery.noConflict = function( deep ) {
9795
	if ( window.$ === jQuery ) {
9796
		window.$ = _$;
9797
	}
9798

    
9799
	if ( deep && window.jQuery === jQuery ) {
9800
		window.jQuery = _jQuery;
9801
	}
9802

    
9803
	return jQuery;
9804
};
9805

    
9806
// Expose jQuery and $ identifiers, even in AMD
9807
// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
9808
// and CommonJS for browser emulators (#13566)
9809
if ( !noGlobal ) {
9810
	window.jQuery = window.$ = jQuery;
9811
}
9812

    
9813
return jQuery;
9814
}));
9815

    
9816
;(function () {
9817
	'use strict';
9818

    
9819
	/**
9820
	 * @preserve FastClick: polyfill to remove click delays on browsers with touch UIs.
9821
	 *
9822
	 * @codingstandard ftlabs-jsv2
9823
	 * @copyright The Financial Times Limited [All Rights Reserved]
9824
	 * @license MIT License (see LICENSE.txt)
9825
	 */
9826

    
9827
	/*jslint browser:true, node:true*/
9828
	/*global define, Event, Node*/
9829

    
9830

    
9831
	/**
9832
	 * Instantiate fast-clicking listeners on the specified layer.
9833
	 *
9834
	 * @constructor
9835
	 * @param {Element} layer The layer to listen on
9836
	 * @param {Object} [options={}] The options to override the defaults
9837
	 */
9838
	function FastClick(layer, options) {
9839
		var oldOnClick;
9840

    
9841
		options = options || {};
9842

    
9843
		/**
9844
		 * Whether a click is currently being tracked.
9845
		 *
9846
		 * @type boolean
9847
		 */
9848
		this.trackingClick = false;
9849

    
9850

    
9851
		/**
9852
		 * Timestamp for when click tracking started.
9853
		 *
9854
		 * @type number
9855
		 */
9856
		this.trackingClickStart = 0;
9857

    
9858

    
9859
		/**
9860
		 * The element being tracked for a click.
9861
		 *
9862
		 * @type EventTarget
9863
		 */
9864
		this.targetElement = null;
9865

    
9866

    
9867
		/**
9868
		 * X-coordinate of touch start event.
9869
		 *
9870
		 * @type number
9871
		 */
9872
		this.touchStartX = 0;
9873

    
9874

    
9875
		/**
9876
		 * Y-coordinate of touch start event.
9877
		 *
9878
		 * @type number
9879
		 */
9880
		this.touchStartY = 0;
9881

    
9882

    
9883
		/**
9884
		 * ID of the last touch, retrieved from Touch.identifier.
9885
		 *
9886
		 * @type number
9887
		 */
9888
		this.lastTouchIdentifier = 0;
9889

    
9890

    
9891
		/**
9892
		 * Touchmove boundary, beyond which a click will be cancelled.
9893
		 *
9894
		 * @type number
9895
		 */
9896
		this.touchBoundary = options.touchBoundary || 10;
9897

    
9898

    
9899
		/**
9900
		 * The FastClick layer.
9901
		 *
9902
		 * @type Element
9903
		 */
9904
		this.layer = layer;
9905

    
9906
		/**
9907
		 * The minimum time between tap(touchstart and touchend) events
9908
		 *
9909
		 * @type number
9910
		 */
9911
		this.tapDelay = options.tapDelay || 200;
9912

    
9913
		/**
9914
		 * The maximum time for a tap
9915
		 *
9916
		 * @type number
9917
		 */
9918
		this.tapTimeout = options.tapTimeout || 700;
9919

    
9920
		if (FastClick.notNeeded(layer)) {
9921
			return;
9922
		}
9923

    
9924
		// Some old versions of Android don't have Function.prototype.bind
9925
		function bind(method, context) {
9926
			return function() { return method.apply(context, arguments); };
9927
		}
9928

    
9929

    
9930
		var methods = ['onMouse', 'onClick', 'onTouchStart', 'onTouchMove', 'onTouchEnd', 'onTouchCancel'];
9931
		var context = this;
9932
		for (var i = 0, l = methods.length; i < l; i++) {
9933
			context[methods[i]] = bind(context[methods[i]], context);
9934
		}
9935

    
9936
		// Set up event handlers as required
9937
		if (deviceIsAndroid) {
9938
			layer.addEventListener('mouseover', this.onMouse, true);
9939
			layer.addEventListener('mousedown', this.onMouse, true);
9940
			layer.addEventListener('mouseup', this.onMouse, true);
9941
		}
9942

    
9943
		layer.addEventListener('click', this.onClick, true);
9944
		layer.addEventListener('touchstart', this.onTouchStart, false);
9945
		layer.addEventListener('touchmove', this.onTouchMove, false);
9946
		layer.addEventListener('touchend', this.onTouchEnd, false);
9947
		layer.addEventListener('touchcancel', this.onTouchCancel, false);
9948

    
9949
		// Hack is required for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2)
9950
		// which is how FastClick normally stops click events bubbling to callbacks registered on the FastClick
9951
		// layer when they are cancelled.
9952
		if (!Event.prototype.stopImmediatePropagation) {
9953
			layer.removeEventListener = function(type, callback, capture) {
9954
				var rmv = Node.prototype.removeEventListener;
9955
				if (type === 'click') {
9956
					rmv.call(layer, type, callback.hijacked || callback, capture);
9957
				} else {
9958
					rmv.call(layer, type, callback, capture);
9959
				}
9960
			};
9961

    
9962
			layer.addEventListener = function(type, callback, capture) {
9963
				var adv = Node.prototype.addEventListener;
9964
				if (type === 'click') {
9965
					adv.call(layer, type, callback.hijacked || (callback.hijacked = function(event) {
9966
						if (!event.propagationStopped) {
9967
							callback(event);
9968
						}
9969
					}), capture);
9970
				} else {
9971
					adv.call(layer, type, callback, capture);
9972
				}
9973
			};
9974
		}
9975

    
9976
		// If a handler is already declared in the element's onclick attribute, it will be fired before
9977
		// FastClick's onClick handler. Fix this by pulling out the user-defined handler function and
9978
		// adding it as listener.
9979
		if (typeof layer.onclick === 'function') {
9980

    
9981
			// Android browser on at least 3.2 requires a new reference to the function in layer.onclick
9982
			// - the old one won't work if passed to addEventListener directly.
9983
			oldOnClick = layer.onclick;
9984
			layer.addEventListener('click', function(event) {
9985
				oldOnClick(event);
9986
			}, false);
9987
			layer.onclick = null;
9988
		}
9989
	}
9990

    
9991
	/**
9992
	* Windows Phone 8.1 fakes user agent string to look like Android and iPhone.
9993
	*
9994
	* @type boolean
9995
	*/
9996
	var deviceIsWindowsPhone = navigator.userAgent.indexOf("Windows Phone") >= 0;
9997

    
9998
	/**
9999
	 * Android requires exceptions.
10000
	 *
10001
	 * @type boolean
10002
	 */
10003
	var deviceIsAndroid = navigator.userAgent.indexOf('Android') > 0 && !deviceIsWindowsPhone;
10004

    
10005

    
10006
	/**
10007
	 * iOS requires exceptions.
10008
	 *
10009
	 * @type boolean
10010
	 */
10011
	var deviceIsIOS = /iP(ad|hone|od)/.test(navigator.userAgent) && !deviceIsWindowsPhone;
10012

    
10013

    
10014
	/**
10015
	 * iOS 4 requires an exception for select elements.
10016
	 *
10017
	 * @type boolean
10018
	 */
10019
	var deviceIsIOS4 = deviceIsIOS && (/OS 4_\d(_\d)?/).test(navigator.userAgent);
10020

    
10021

    
10022
	/**
10023
	 * iOS 6.0-7.* requires the target element to be manually derived
10024
	 *
10025
	 * @type boolean
10026
	 */
10027
	var deviceIsIOSWithBadTarget = deviceIsIOS && (/OS [6-7]_\d/).test(navigator.userAgent);
10028

    
10029
	/**
10030
	 * BlackBerry requires exceptions.
10031
	 *
10032
	 * @type boolean
10033
	 */
10034
	var deviceIsBlackBerry10 = navigator.userAgent.indexOf('BB10') > 0;
10035

    
10036
	/**
10037
	 * Determine whether a given element requires a native click.
10038
	 *
10039
	 * @param {EventTarget|Element} target Target DOM element
10040
	 * @returns {boolean} Returns true if the element needs a native click
10041
	 */
10042
	FastClick.prototype.needsClick = function(target) {
10043
		switch (target.nodeName.toLowerCase()) {
10044

    
10045
		// Don't send a synthetic click to disabled inputs (issue #62)
10046
		case 'button':
10047
		case 'select':
10048
		case 'textarea':
10049
			if (target.disabled) {
10050
				return true;
10051
			}
10052

    
10053
			break;
10054
		case 'input':
10055

    
10056
			// File inputs need real clicks on iOS 6 due to a browser bug (issue #68)
10057
			if ((deviceIsIOS && target.type === 'file') || target.disabled) {
10058
				return true;
10059
			}
10060

    
10061
			break;
10062
		case 'label':
10063
		case 'iframe': // iOS8 homescreen apps can prevent events bubbling into frames
10064
		case 'video':
10065
			return true;
10066
		}
10067

    
10068
		return (/\bneedsclick\b/).test(target.className);
10069
	};
10070

    
10071

    
10072
	/**
10073
	 * Determine whether a given element requires a call to focus to simulate click into element.
10074
	 *
10075
	 * @param {EventTarget|Element} target Target DOM element
10076
	 * @returns {boolean} Returns true if the element requires a call to focus to simulate native click.
10077
	 */
10078
	FastClick.prototype.needsFocus = function(target) {
10079
		switch (target.nodeName.toLowerCase()) {
10080
		case 'textarea':
10081
			return true;
10082
		case 'select':
10083
			return !deviceIsAndroid;
10084
		case 'input':
10085
			switch (target.type) {
10086
			case 'button':
10087
			case 'checkbox':
10088
			case 'file':
10089
			case 'image':
10090
			case 'radio':
10091
			case 'submit':
10092
				return false;
10093
			}
10094

    
10095
			// No point in attempting to focus disabled inputs
10096
			return !target.disabled && !target.readOnly;
10097
		default:
10098
			return (/\bneedsfocus\b/).test(target.className);
10099
		}
10100
	};
10101

    
10102

    
10103
	/**
10104
	 * Send a click event to the specified element.
10105
	 *
10106
	 * @param {EventTarget|Element} targetElement
10107
	 * @param {Event} event
10108
	 */
10109
	FastClick.prototype.sendClick = function(targetElement, event) {
10110
		var clickEvent, touch;
10111

    
10112
		// On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect (#24)
10113
		if (document.activeElement && document.activeElement !== targetElement) {
10114
			document.activeElement.blur();
10115
		}
10116

    
10117
		touch = event.changedTouches[0];
10118

    
10119
		// Synthesise a click event, with an extra attribute so it can be tracked
10120
		clickEvent = document.createEvent('MouseEvents');
10121
		clickEvent.initMouseEvent(this.determineEventType(targetElement), true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
10122
		clickEvent.forwardedTouchEvent = true;
10123
		targetElement.dispatchEvent(clickEvent);
10124
	};
10125

    
10126
	FastClick.prototype.determineEventType = function(targetElement) {
10127

    
10128
		//Issue #159: Android Chrome Select Box does not open with a synthetic click event
10129
		if (deviceIsAndroid && targetElement.tagName.toLowerCase() === 'select') {
10130
			return 'mousedown';
10131
		}
10132

    
10133
		return 'click';
10134
	};
10135

    
10136

    
10137
	/**
10138
	 * @param {EventTarget|Element} targetElement
10139
	 */
10140
	FastClick.prototype.focus = function(targetElement) {
10141
		var length;
10142

    
10143
		// Issue #160: on iOS 7, some input elements (e.g. date datetime month) throw a vague TypeError on setSelectionRange. These elements don't have an integer value for the selectionStart and selectionEnd properties, but unfortunately that can't be used for detection because accessing the properties also throws a TypeError. Just check the type instead. Filed as Apple bug #15122724.
10144
		if (deviceIsIOS && targetElement.setSelectionRange && targetElement.type.indexOf('date') !== 0 && targetElement.type !== 'time' && targetElement.type !== 'month') {
10145
			length = targetElement.value.length;
10146
			targetElement.setSelectionRange(length, length);
10147
		} else {
10148
			targetElement.focus();
10149
		}
10150
	};
10151

    
10152

    
10153
	/**
10154
	 * Check whether the given target element is a child of a scrollable layer and if so, set a flag on it.
10155
	 *
10156
	 * @param {EventTarget|Element} targetElement
10157
	 */
10158
	FastClick.prototype.updateScrollParent = function(targetElement) {
10159
		var scrollParent, parentElement;
10160

    
10161
		scrollParent = targetElement.fastClickScrollParent;
10162

    
10163
		// Attempt to discover whether the target element is contained within a scrollable layer. Re-check if the
10164
		// target element was moved to another parent.
10165
		if (!scrollParent || !scrollParent.contains(targetElement)) {
10166
			parentElement = targetElement;
10167
			do {
10168
				if (parentElement.scrollHeight > parentElement.offsetHeight) {
10169
					scrollParent = parentElement;
10170
					targetElement.fastClickScrollParent = parentElement;
10171
					break;
10172
				}
10173

    
10174
				parentElement = parentElement.parentElement;
10175
			} while (parentElement);
10176
		}
10177

    
10178
		// Always update the scroll top tracker if possible.
10179
		if (scrollParent) {
10180
			scrollParent.fastClickLastScrollTop = scrollParent.scrollTop;
10181
		}
10182
	};
10183

    
10184

    
10185
	/**
10186
	 * @param {EventTarget} targetElement
10187
	 * @returns {Element|EventTarget}
10188
	 */
10189
	FastClick.prototype.getTargetElementFromEventTarget = function(eventTarget) {
10190

    
10191
		// On some older browsers (notably Safari on iOS 4.1 - see issue #56) the event target may be a text node.
10192
		if (eventTarget.nodeType === Node.TEXT_NODE) {
10193
			return eventTarget.parentNode;
10194
		}
10195

    
10196
		return eventTarget;
10197
	};
10198

    
10199

    
10200
	/**
10201
	 * On touch start, record the position and scroll offset.
10202
	 *
10203
	 * @param {Event} event
10204
	 * @returns {boolean}
10205
	 */
10206
	FastClick.prototype.onTouchStart = function(event) {
10207
		var targetElement, touch, selection;
10208

    
10209
		// Ignore multiple touches, otherwise pinch-to-zoom is prevented if both fingers are on the FastClick element (issue #111).
10210
		if (event.targetTouches.length > 1) {
10211
			return true;
10212
		}
10213

    
10214
		targetElement = this.getTargetElementFromEventTarget(event.target);
10215
		touch = event.targetTouches[0];
10216

    
10217
		if (deviceIsIOS) {
10218

    
10219
			// Only trusted events will deselect text on iOS (issue #49)
10220
			selection = window.getSelection();
10221
			if (selection.rangeCount && !selection.isCollapsed) {
10222
				return true;
10223
			}
10224

    
10225
			if (!deviceIsIOS4) {
10226

    
10227
				// Weird things happen on iOS when an alert or confirm dialog is opened from a click event callback (issue #23):
10228
				// when the user next taps anywhere else on the page, new touchstart and touchend events are dispatched
10229
				// with the same identifier as the touch event that previously triggered the click that triggered the alert.
10230
				// Sadly, there is an issue on iOS 4 that causes some normal touch events to have the same identifier as an
10231
				// immediately preceeding touch event (issue #52), so this fix is unavailable on that platform.
10232
				// Issue 120: touch.identifier is 0 when Chrome dev tools 'Emulate touch events' is set with an iOS device UA string,
10233
				// which causes all touch events to be ignored. As this block only applies to iOS, and iOS identifiers are always long,
10234
				// random integers, it's safe to to continue if the identifier is 0 here.
10235
				if (touch.identifier && touch.identifier === this.lastTouchIdentifier) {
10236
					event.preventDefault();
10237
					return false;
10238
				}
10239

    
10240
				this.lastTouchIdentifier = touch.identifier;
10241

    
10242
				// If the target element is a child of a scrollable layer (using -webkit-overflow-scrolling: touch) and:
10243
				// 1) the user does a fling scroll on the scrollable layer
10244
				// 2) the user stops the fling scroll with another tap
10245
				// then the event.target of the last 'touchend' event will be the element that was under the user's finger
10246
				// when the fling scroll was started, causing FastClick to send a click event to that layer - unless a check
10247
				// is made to ensure that a parent layer was not scrolled before sending a synthetic click (issue #42).
10248
				this.updateScrollParent(targetElement);
10249
			}
10250
		}
10251

    
10252
		this.trackingClick = true;
10253
		this.trackingClickStart = event.timeStamp;
10254
		this.targetElement = targetElement;
10255

    
10256
		this.touchStartX = touch.pageX;
10257
		this.touchStartY = touch.pageY;
10258

    
10259
		// Prevent phantom clicks on fast double-tap (issue #36)
10260
		if ((event.timeStamp - this.lastClickTime) < this.tapDelay) {
10261
			event.preventDefault();
10262
		}
10263

    
10264
		return true;
10265
	};
10266

    
10267

    
10268
	/**
10269
	 * Based on a touchmove event object, check whether the touch has moved past a boundary since it started.
10270
	 *
10271
	 * @param {Event} event
10272
	 * @returns {boolean}
10273
	 */
10274
	FastClick.prototype.touchHasMoved = function(event) {
10275
		var touch = event.changedTouches[0], boundary = this.touchBoundary;
10276

    
10277
		if (Math.abs(touch.pageX - this.touchStartX) > boundary || Math.abs(touch.pageY - this.touchStartY) > boundary) {
10278
			return true;
10279
		}
10280

    
10281
		return false;
10282
	};
10283

    
10284

    
10285
	/**
10286
	 * Update the last position.
10287
	 *
10288
	 * @param {Event} event
10289
	 * @returns {boolean}
10290
	 */
10291
	FastClick.prototype.onTouchMove = function(event) {
10292
		if (!this.trackingClick) {
10293
			return true;
10294
		}
10295

    
10296
		// If the touch has moved, cancel the click tracking
10297
		if (this.targetElement !== this.getTargetElementFromEventTarget(event.target) || this.touchHasMoved(event)) {
10298
			this.trackingClick = false;
10299
			this.targetElement = null;
10300
		}
10301

    
10302
		return true;
10303
	};
10304

    
10305

    
10306
	/**
10307
	 * Attempt to find the labelled control for the given label element.
10308
	 *
10309
	 * @param {EventTarget|HTMLLabelElement} labelElement
10310
	 * @returns {Element|null}
10311
	 */
10312
	FastClick.prototype.findControl = function(labelElement) {
10313

    
10314
		// Fast path for newer browsers supporting the HTML5 control attribute
10315
		if (labelElement.control !== undefined) {
10316
			return labelElement.control;
10317
		}
10318

    
10319
		// All browsers under test that support touch events also support the HTML5 htmlFor attribute
10320
		if (labelElement.htmlFor) {
10321
			return document.getElementById(labelElement.htmlFor);
10322
		}
10323

    
10324
		// If no for attribute exists, attempt to retrieve the first labellable descendant element
10325
		// the list of which is defined here: http://www.w3.org/TR/html5/forms.html#category-label
10326
		return labelElement.querySelector('button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea');
10327
	};
10328

    
10329

    
10330
	/**
10331
	 * On touch end, determine whether to send a click event at once.
10332
	 *
10333
	 * @param {Event} event
10334
	 * @returns {boolean}
10335
	 */
10336
	FastClick.prototype.onTouchEnd = function(event) {
10337
		var forElement, trackingClickStart, targetTagName, scrollParent, touch, targetElement = this.targetElement;
10338

    
10339
		if (!this.trackingClick) {
10340
			return true;
10341
		}
10342

    
10343
		// Prevent phantom clicks on fast double-tap (issue #36)
10344
		if ((event.timeStamp - this.lastClickTime) < this.tapDelay) {
10345
			this.cancelNextClick = true;
10346
			return true;
10347
		}
10348

    
10349
		if ((event.timeStamp - this.trackingClickStart) > this.tapTimeout) {
10350
			return true;
10351
		}
10352

    
10353
		// Reset to prevent wrong click cancel on input (issue #156).
10354
		this.cancelNextClick = false;
10355

    
10356
		this.lastClickTime = event.timeStamp;
10357

    
10358
		trackingClickStart = this.trackingClickStart;
10359
		this.trackingClick = false;
10360
		this.trackingClickStart = 0;
10361

    
10362
		// On some iOS devices, the targetElement supplied with the event is invalid if the layer
10363
		// is performing a transition or scroll, and has to be re-detected manually. Note that
10364
		// for this to function correctly, it must be called *after* the event target is checked!
10365
		// See issue #57; also filed as rdar://13048589 .
10366
		if (deviceIsIOSWithBadTarget) {
10367
			touch = event.changedTouches[0];
10368

    
10369
			// In certain cases arguments of elementFromPoint can be negative, so prevent setting targetElement to null
10370
			targetElement = document.elementFromPoint(touch.pageX - window.pageXOffset, touch.pageY - window.pageYOffset) || targetElement;
10371
			targetElement.fastClickScrollParent = this.targetElement.fastClickScrollParent;
10372
		}
10373

    
10374
		targetTagName = targetElement.tagName.toLowerCase();
10375
		if (targetTagName === 'label') {
10376
			forElement = this.findControl(targetElement);
10377
			if (forElement) {
10378
				this.focus(targetElement);
10379
				if (deviceIsAndroid) {
10380
					return false;
10381
				}
10382

    
10383
				targetElement = forElement;
10384
			}
10385
		} else if (this.needsFocus(targetElement)) {
10386

    
10387
			// Case 1: If the touch started a while ago (best guess is 100ms based on tests for issue #36) then focus will be triggered anyway. Return early and unset the target element reference so that the subsequent click will be allowed through.
10388
			// Case 2: Without this exception for input elements tapped when the document is contained in an iframe, then any inputted text won't be visible even though the value attribute is updated as the user types (issue #37).
10389
			if ((event.timeStamp - trackingClickStart) > 100 || (deviceIsIOS && window.top !== window && targetTagName === 'input')) {
10390
				this.targetElement = null;
10391
				return false;
10392
			}
10393

    
10394
			this.focus(targetElement);
10395
			this.sendClick(targetElement, event);
10396

    
10397
			// Select elements need the event to go through on iOS 4, otherwise the selector menu won't open.
10398
			// Also this breaks opening selects when VoiceOver is active on iOS6, iOS7 (and possibly others)
10399
			if (!deviceIsIOS || targetTagName !== 'select') {
10400
				this.targetElement = null;
10401
				event.preventDefault();
10402
			}
10403

    
10404
			return false;
10405
		}
10406

    
10407
		if (deviceIsIOS && !deviceIsIOS4) {
10408

    
10409
			// Don't send a synthetic click event if the target element is contained within a parent layer that was scrolled
10410
			// and this tap is being used to stop the scrolling (usually initiated by a fling - issue #42).
10411
			scrollParent = targetElement.fastClickScrollParent;
10412
			if (scrollParent && scrollParent.fastClickLastScrollTop !== scrollParent.scrollTop) {
10413
				return true;
10414
			}
10415
		}
10416

    
10417
		// Prevent the actual click from going though - unless the target node is marked as requiring
10418
		// real clicks or if it is in the whitelist in which case only non-programmatic clicks are permitted.
10419
		if (!this.needsClick(targetElement)) {
10420
			event.preventDefault();
10421
			this.sendClick(targetElement, event);
10422
		}
10423

    
10424
		return false;
10425
	};
10426

    
10427

    
10428
	/**
10429
	 * On touch cancel, stop tracking the click.
10430
	 *
10431
	 * @returns {void}
10432
	 */
10433
	FastClick.prototype.onTouchCancel = function() {
10434
		this.trackingClick = false;
10435
		this.targetElement = null;
10436
	};
10437

    
10438

    
10439
	/**
10440
	 * Determine mouse events which should be permitted.
10441
	 *
10442
	 * @param {Event} event
10443
	 * @returns {boolean}
10444
	 */
10445
	FastClick.prototype.onMouse = function(event) {
10446

    
10447
		// If a target element was never set (because a touch event was never fired) allow the event
10448
		if (!this.targetElement) {
10449
			return true;
10450
		}
10451

    
10452
		if (event.forwardedTouchEvent) {
10453
			return true;
10454
		}
10455

    
10456
		// Programmatically generated events targeting a specific element should be permitted
10457
		if (!event.cancelable) {
10458
			return true;
10459
		}
10460

    
10461
		// Derive and check the target element to see whether the mouse event needs to be permitted;
10462
		// unless explicitly enabled, prevent non-touch click events from triggering actions,
10463
		// to prevent ghost/doubleclicks.
10464
		if (!this.needsClick(this.targetElement) || this.cancelNextClick) {
10465

    
10466
			// Prevent any user-added listeners declared on FastClick element from being fired.
10467
			if (event.stopImmediatePropagation) {
10468
				event.stopImmediatePropagation();
10469
			} else {
10470

    
10471
				// Part of the hack for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2)
10472
				event.propagationStopped = true;
10473
			}
10474

    
10475
			// Cancel the event
10476
			event.stopPropagation();
10477
			event.preventDefault();
10478

    
10479
			return false;
10480
		}
10481

    
10482
		// If the mouse event is permitted, return true for the action to go through.
10483
		return true;
10484
	};
10485

    
10486

    
10487
	/**
10488
	 * On actual clicks, determine whether this is a touch-generated click, a click action occurring
10489
	 * naturally after a delay after a touch (which needs to be cancelled to avoid duplication), or
10490
	 * an actual click which should be permitted.
10491
	 *
10492
	 * @param {Event} event
10493
	 * @returns {boolean}
10494
	 */
10495
	FastClick.prototype.onClick = function(event) {
10496
		var permitted;
10497

    
10498
		// It's possible for another FastClick-like library delivered with third-party code to fire a click event before FastClick does (issue #44). In that case, set the click-tracking flag back to false and return early. This will cause onTouchEnd to return early.
10499
		if (this.trackingClick) {
10500
			this.targetElement = null;
10501
			this.trackingClick = false;
10502
			return true;
10503
		}
10504

    
10505
		// Very odd behaviour on iOS (issue #18): if a submit element is present inside a form and the user hits enter in the iOS simulator or clicks the Go button on the pop-up OS keyboard the a kind of 'fake' click event will be triggered with the submit-type input element as the target.
10506
		if (event.target.type === 'submit' && event.detail === 0) {
10507
			return true;
10508
		}
10509

    
10510
		permitted = this.onMouse(event);
10511

    
10512
		// Only unset targetElement if the click is not permitted. This will ensure that the check for !targetElement in onMouse fails and the browser's click doesn't go through.
10513
		if (!permitted) {
10514
			this.targetElement = null;
10515
		}
10516

    
10517
		// If clicks are permitted, return true for the action to go through.
10518
		return permitted;
10519
	};
10520

    
10521

    
10522
	/**
10523
	 * Remove all FastClick's event listeners.
10524
	 *
10525
	 * @returns {void}
10526
	 */
10527
	FastClick.prototype.destroy = function() {
10528
		var layer = this.layer;
10529

    
10530
		if (deviceIsAndroid) {
10531
			layer.removeEventListener('mouseover', this.onMouse, true);
10532
			layer.removeEventListener('mousedown', this.onMouse, true);
10533
			layer.removeEventListener('mouseup', this.onMouse, true);
10534
		}
10535

    
10536
		layer.removeEventListener('click', this.onClick, true);
10537
		layer.removeEventListener('touchstart', this.onTouchStart, false);
10538
		layer.removeEventListener('touchmove', this.onTouchMove, false);
10539
		layer.removeEventListener('touchend', this.onTouchEnd, false);
10540
		layer.removeEventListener('touchcancel', this.onTouchCancel, false);
10541
	};
10542

    
10543

    
10544
	/**
10545
	 * Check whether FastClick is needed.
10546
	 *
10547
	 * @param {Element} layer The layer to listen on
10548
	 */
10549
	FastClick.notNeeded = function(layer) {
10550
		var metaViewport;
10551
		var chromeVersion;
10552
		var blackberryVersion;
10553
		var firefoxVersion;
10554

    
10555
		// Devices that don't support touch don't need FastClick
10556
		if (typeof window.ontouchstart === 'undefined') {
10557
			return true;
10558
		}
10559

    
10560
		// Chrome version - zero for other browsers
10561
		chromeVersion = +(/Chrome\/([0-9]+)/.exec(navigator.userAgent) || [,0])[1];
10562

    
10563
		if (chromeVersion) {
10564

    
10565
			if (deviceIsAndroid) {
10566
				metaViewport = document.querySelector('meta[name=viewport]');
10567

    
10568
				if (metaViewport) {
10569
					// Chrome on Android with user-scalable="no" doesn't need FastClick (issue #89)
10570
					if (metaViewport.content.indexOf('user-scalable=no') !== -1) {
10571
						return true;
10572
					}
10573
					// Chrome 32 and above with width=device-width or less don't need FastClick
10574
					if (chromeVersion > 31 && document.documentElement.scrollWidth <= window.outerWidth) {
10575
						return true;
10576
					}
10577
				}
10578

    
10579
			// Chrome desktop doesn't need FastClick (issue #15)
10580
			} else {
10581
				return true;
10582
			}
10583
		}
10584

    
10585
		if (deviceIsBlackBerry10) {
10586
			blackberryVersion = navigator.userAgent.match(/Version\/([0-9]*)\.([0-9]*)/);
10587

    
10588
			// BlackBerry 10.3+ does not require Fastclick library.
10589
			// https://github.com/ftlabs/fastclick/issues/251
10590
			if (blackberryVersion[1] >= 10 && blackberryVersion[2] >= 3) {
10591
				metaViewport = document.querySelector('meta[name=viewport]');
10592

    
10593
				if (metaViewport) {
10594
					// user-scalable=no eliminates click delay.
10595
					if (metaViewport.content.indexOf('user-scalable=no') !== -1) {
10596
						return true;
10597
					}
10598
					// width=device-width (or less than device-width) eliminates click delay.
10599
					if (document.documentElement.scrollWidth <= window.outerWidth) {
10600
						return true;
10601
					}
10602
				}
10603
			}
10604
		}
10605

    
10606
		// IE10 with -ms-touch-action: none or manipulation, which disables double-tap-to-zoom (issue #97)
10607
		if (layer.style.msTouchAction === 'none' || layer.style.touchAction === 'manipulation') {
10608
			return true;
10609
		}
10610

    
10611
		// Firefox version - zero for other browsers
10612
		firefoxVersion = +(/Firefox\/([0-9]+)/.exec(navigator.userAgent) || [,0])[1];
10613

    
10614
		if (firefoxVersion >= 27) {
10615
			// Firefox 27+ does not have tap delay if the content is not zoomable - https://bugzilla.mozilla.org/show_bug.cgi?id=922896
10616

    
10617
			metaViewport = document.querySelector('meta[name=viewport]');
10618
			if (metaViewport && (metaViewport.content.indexOf('user-scalable=no') !== -1 || document.documentElement.scrollWidth <= window.outerWidth)) {
10619
				return true;
10620
			}
10621
		}
10622

    
10623
		// IE11: prefixed -ms-touch-action is no longer supported and it's recomended to use non-prefixed version
10624
		// http://msdn.microsoft.com/en-us/library/windows/apps/Hh767313.aspx
10625
		if (layer.style.touchAction === 'none' || layer.style.touchAction === 'manipulation') {
10626
			return true;
10627
		}
10628

    
10629
		return false;
10630
	};
10631

    
10632

    
10633
	/**
10634
	 * Factory method for creating a FastClick object
10635
	 *
10636
	 * @param {Element} layer The layer to listen on
10637
	 * @param {Object} [options={}] The options to override the defaults
10638
	 */
10639
	FastClick.attach = function(layer, options) {
10640
		return new FastClick(layer, options);
10641
	};
10642

    
10643

    
10644
	if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {
10645

    
10646
		// AMD. Register as an anonymous module.
10647
		define(function() {
10648
			return FastClick;
10649
		});
10650
	} else if (typeof module !== 'undefined' && module.exports) {
10651
		module.exports = FastClick.attach;
10652
		module.exports.FastClick = FastClick;
10653
	} else {
10654
		window.FastClick = FastClick;
10655
	}
10656
}());
10657

    
10658
/*!
10659
 * Bez v1.0.10-g5ae0136
10660
 * http://github.com/rdallasgray/bez
10661
 * 
10662
 * A plugin to convert CSS3 cubic-bezier co-ordinates to jQuery-compatible easing functions
10663
 * 
10664
 * With thanks to Nikolay Nemshilov for clarification on the cubic-bezier maths
10665
 * See http://st-on-it.blogspot.com/2011/05/calculating-cubic-bezier-function.html
10666
 * 
10667
 * Copyright 2011 Robert Dallas Gray. All rights reserved.
10668
 * Provided under the FreeBSD license: https://github.com/rdallasgray/bez/blob/master/LICENSE.txt
10669
*/jQuery.extend({bez:function(a){var b="bez_"+jQuery.makeArray(arguments).join("_").replace(".","p");if(typeof jQuery.easing[b]!="function"){var c=function(a,b){var c=[null,null],d=[null,null],e=[null,null],f=function(f,g){return e[g]=3*a[g],d[g]=3*(b[g]-a[g])-e[g],c[g]=1-e[g]-d[g],f*(e[g]+f*(d[g]+f*c[g]))},g=function(a){return e[0]+a*(2*d[0]+3*c[0]*a)},h=function(a){var b=a,c=0,d;while(++c<14){d=f(b,0)-a;if(Math.abs(d)<.001)break;b-=d/g(b)}return b};return function(a){return f(h(a),1)}};jQuery.easing[b]=function(b,d,e,f,g){return f*c([a[0],a[1]],[a[2],a[3]])(d/g)+e}}return b}});
10670

    
10671
/*
10672
 * jQuery One Page Nav Plugin
10673
 * http://github.com/davist11/jQuery-One-Page-Nav
10674
 *
10675
 * Copyright (c) 2010 Trevor Davis (http://trevordavis.net)
10676
 * Dual licensed under the MIT and GPL licenses.
10677
 * Uses the same license as jQuery, see:
10678
 * http://jquery.org/license
10679
 *
10680
 * @version 3.0.0
10681
 *
10682
 * Example usage:
10683
 * $('#nav').onePageNav({
10684
 *   currentClass: 'current',
10685
 *   changeHash: false,
10686
 *   scrollSpeed: 750
10687
 * });
10688
 */
10689

    
10690
;(function($, window, document, undefined){
10691

    
10692
    // our plugin constructor
10693
    var OnePageNav = function(elem, options){
10694
        this.elem = elem;
10695
        this.$elem = $(elem);
10696
        this.options = options;
10697
        this.metadata = this.$elem.data('plugin-options');
10698
        this.$win = $(window);
10699
        this.sections = {};
10700
        this.didScroll = false;
10701
        this.$doc = $(document);
10702
        this.docHeight = this.$doc.height();
10703
    };
10704

    
10705
    // the plugin prototype
10706
    OnePageNav.prototype = {
10707
        defaults: {
10708
            navItems: 'a',
10709
            currentClass: 'current',
10710
            changeHash: false,
10711
            easing: 'swing',
10712
            filter: '',
10713
            scrollOffset: 0,
10714
            scrollSpeed: 750,
10715
            scrollThreshold: 0.5,
10716
            begin: false,
10717
            end: false,
10718
            scrollChange: false
10719
        },
10720

    
10721
        init: function() {
10722
            // Introduce defaults that can be extended either
10723
            // globally or using an object literal.
10724
            this.config = $.extend({}, this.defaults, this.options, this.metadata);
10725

    
10726
            this.$nav = this.$elem.find(this.config.navItems);
10727

    
10728
            //Filter any links out of the nav
10729
            if(this.config.filter !== '') {
10730
                this.$nav = this.$nav.filter(this.config.filter);
10731
            }
10732

    
10733
            //Handle clicks on the nav
10734
            this.$nav.on('click.onePageNav', $.proxy(this.handleClick, this));
10735

    
10736
            //Get the section positions
10737
            this.getPositions();
10738

    
10739
            //Handle scroll changes
10740
            this.bindInterval();
10741

    
10742
            //Update the positions on resize too
10743
            this.$win.on('resize.onePageNav', $.proxy(this.getPositions, this));
10744

    
10745
            return this;
10746
        },
10747

    
10748
        adjustNav: function(self, $parent) {
10749
            self.$elem.find('.' + self.config.currentClass).removeClass(self.config.currentClass);
10750
            $parent.addClass(self.config.currentClass);
10751
        },
10752

    
10753
        bindInterval: function() {
10754
            var self = this;
10755
            var docHeight;
10756

    
10757
            self.$win.on('scroll.onePageNav', function() {
10758
                self.didScroll = true;
10759
            });
10760

    
10761
            self.t = setInterval(function() {
10762
                docHeight = self.$doc.height();
10763

    
10764
                //If it was scrolled
10765
                if(self.didScroll) {
10766
                    self.didScroll = false;
10767
                    self.scrollChange();
10768
                }
10769

    
10770
                //If the document height changes
10771
                if(docHeight !== self.docHeight) {
10772
                    self.docHeight = docHeight;
10773
                    self.getPositions();
10774
                }
10775
            }, 250);
10776
        },
10777

    
10778
        getHash: function($link) {
10779
            return $link.attr('href').split('#')[1];
10780
        },
10781

    
10782
        getPositions: function() {
10783
            var self = this;
10784
            var linkHref;
10785
            var topPos;
10786
            var $target;
10787

    
10788
            self.$nav.each(function() {
10789
                linkHref = self.getHash($(this));
10790
                $target = $('#' + linkHref);
10791

    
10792
                if($target.length) {
10793
                    topPos = $target.offset().top;
10794
                    self.sections[linkHref] = Math.round(topPos);
10795
                }
10796
            });
10797
        },
10798

    
10799
        getSection: function(windowPos) {
10800
            var returnValue = null;
10801
            var windowHeight = Math.round(this.$win.height() * this.config.scrollThreshold);
10802

    
10803
            // Sort Sections by Position
10804
            this.sections = this.sortSectionsByPosition(this.sections);
10805

    
10806
            for(var section in this.sections) {
10807
                if((this.sections[section] - windowHeight) < windowPos) {
10808
                    returnValue = section;
10809
                }
10810
            }
10811

    
10812
            return returnValue;
10813
        },
10814

    
10815
        /**
10816
         * Sort Sections by its position value
10817
         * based on http://am.aurlien.net/post/1221493460/sorting-javascript-objects
10818
         * @param  {Object} obj		Object to sort
10819
         * @return {Object}         sorted Object
10820
         */
10821
        sortSectionsByPosition: function (obj) {
10822
            var tempArray = [];
10823
            var tempObj = {};
10824

    
10825
            // Transform Object in Array
10826
            for (var key in obj) {
10827
                if (obj.hasOwnProperty(key)) {
10828
                    tempArray.push(key);
10829
                }
10830
            }
10831

    
10832
            tempArray.sort(function(a,b) {
10833
                var x = obj[a];
10834
                var y = obj[b];
10835

    
10836
                return ((x < y) ? -1 : ((x > y) ? 1 : 0));
10837
            });
10838

    
10839
            // Transform sorted tempArray back into Object
10840
            for (var i=0; i<tempArray.length; i++) {
10841
                tempObj[tempArray[i]] = obj[tempArray[i]];
10842
            }
10843

    
10844
            return tempObj;
10845
        },
10846

    
10847
        handleClick: function(e) {
10848
            var self = this;
10849
            var $link = $(e.currentTarget);
10850
            var $parent = $link.parent();
10851
            var newLoc = '#' + self.getHash($link);
10852

    
10853
            if(!$parent.hasClass(self.config.currentClass)) {
10854
                //Start callback
10855
                if(self.config.begin) {
10856
                    self.config.begin();
10857
                }
10858

    
10859
                //Change the highlighted nav item
10860
                self.adjustNav(self, $parent);
10861

    
10862
                //Removing the auto-adjust on scroll
10863
                self.unbindInterval();
10864

    
10865
                //Scroll to the correct position
10866
                self.scrollTo(newLoc, function() {
10867
                    //Do we need to change the hash?
10868
                    if(self.config.changeHash) {
10869
                        window.location.hash = newLoc;
10870
                    }
10871

    
10872
                    //Add the auto-adjust on scroll back in
10873
                    self.bindInterval();
10874

    
10875
                    //End callback
10876
                    if(self.config.end) {
10877
                        self.config.end();
10878
                    }
10879
                });
10880
            }
10881

    
10882
            e.preventDefault();
10883
        },
10884

    
10885
        scrollChange: function() {
10886
            var windowTop = this.$win.scrollTop();
10887
            var position = this.getSection(windowTop);
10888
            var $parent;
10889

    
10890
            //If the position is set
10891
            if(position !== null) {
10892
                $parent = this.$elem.find('a[href$="#' + position + '"]').parent();
10893

    
10894
                //If it's not already the current section
10895
                if(!$parent.hasClass(this.config.currentClass)) {
10896
                    //Change the highlighted nav item
10897
                    this.adjustNav(this, $parent);
10898

    
10899
                    //If there is a scrollChange callback
10900
                    if(this.config.scrollChange) {
10901
                        this.config.scrollChange($parent);
10902
                    }
10903
                }
10904
            }
10905
        },
10906

    
10907
        scrollTo: function(target, callback) {
10908
            var offset = $(target).offset().top;
10909
            $('html, body').animate({
10910
                scrollTop: offset + this.config.scrollOffset
10911
            }, this.config.scrollSpeed, this.config.easing, callback);
10912
        },
10913

    
10914
        unbindInterval: function() {
10915
            clearInterval(this.t);
10916
            this.$win.unbind('scroll.onePageNav');
10917
        }
10918
    };
10919

    
10920
    OnePageNav.defaults = OnePageNav.prototype.defaults;
10921

    
10922
    $.fn.onePageNav = function(options) {
10923
        return this.each(function() {
10924
            new OnePageNav(this, options).init();
10925
        });
10926
    };
10927

    
10928
})( jQuery, window , document );
(3-3/6)