PageSourceSearch

https://www.beechnut.com/wp-content/themes/beechnut/library/js/_plugins.js

js beechnut.com collected 2026-09-25 18:52:56 UTC 487,665 bytes, 17,030 lines download raw bytes

vendor: 40,583 bytes, lines 1-1506
1/*!
2 * jQuery JavaScript Library v2.1.4
3 * http://jquery.com/
4 *
5 * Includes Sizzle.js
6 * http://sizzlejs.com/
7 *
8 * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
9 * Released under the MIT license
10 * http://jquery.org/license
11 *
12 * Date: 2015-04-28T16:01Z
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//
45
46var arr = [];
47
48var slice = arr.slice;
49
50var concat = arr.concat;
51
52var push = arr.push;
53
54var indexOf = arr.indexOf;
55
56var class2type = {};
57
58var toString = class2type.toString;
59
60var hasOwn = class2type.hasOwnProperty;
61
62var support = {};
63
64
65
66var
67	// Use the correct document accordingly with window argument (sandbox)
68	document = window.document,
69
70	version = "2.1.4",
71
72	// Define a local copy of jQuery
73	jQuery = function( selector, context ) {
74		// The jQuery object is actually just the init constructor 'enhanced'
75		// Need init if jQuery is called (just allow error to be thrown if not included)
76		return new jQuery.fn.init( selector, context );
77	},
78
79	// Support: Android<4.1
80	// Make sure we trim BOM and NBSP
81	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
82
83	// Matches dashed string for camelizing
84	rmsPrefix = /^-ms-/,
85	rdashAlpha = /-([\da-z])/gi,
86
87	// Used by jQuery.camelCase as callback to replace()
88	fcamelCase = function( all, letter ) {
89		return letter.toUpperCase();
90	};
91
92jQuery.fn = jQuery.prototype = {
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	// (You can seed the arguments with an array of args, but this is
137	// only used internally.)
138	each: function( callback, args ) {
139		return jQuery.each( this, callback, args );
140	},
141
142	map: function( callback ) {
143		return this.pushStack( jQuery.map(this, function( elem, i ) {
144			return callback.call( elem, i, elem );
145		}));
146	},
147
148	slice: function() {
149		return this.pushStack( slice.apply( this, arguments ) );
150	},
151
152	first: function() {
153		return this.eq( 0 );
154	},
155
156	last: function() {
157		return this.eq( -1 );
158	},
159
160	eq: function( i ) {
161		var len = this.length,
162			j = +i + ( i < 0 ? len : 0 );
163		return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
164	},
165
166	end: function() {
167		return this.prevObject || this.constructor(null);
168	},
169
170	// For internal use only.
171	// Behaves like an Array's method, not like a jQuery method.
172	push: push,
173	sort: arr.sort,
174	splice: arr.splice
175};
176
177jQuery.extend = jQuery.fn.extend = function() {
178	var options, name, src, copy, copyIsArray, clone,
179		target = arguments[0] || {},
180		i = 1,
181		length = arguments.length,
182		deep = false;
183
184	// Handle a deep copy situation
185	if ( typeof target === "boolean" ) {
186		deep = target;
187
188		// Skip the boolean and the target
189		target = arguments[ i ] || {};
190		i++;
191	}
192
193	// Handle case when target is a string or something (possible in deep copy)
194	if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
195		target = {};
196	}
197
198	// Extend jQuery itself if only one argument is passed
199	if ( i === length ) {
200		target = this;
201		i--;
202	}
203
204	for ( ; i < length; i++ ) {
205		// Only deal with non-null/undefined values
206		if ( (options = arguments[ i ]) != null ) {
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) || (copyIsArray = jQuery.isArray(copy)) ) ) {
219					if ( copyIsArray ) {
220						copyIsArray = false;
221						clone = src && jQuery.isArray(src) ? src : [];
222
223					} else {
224						clone = src && jQuery.isPlainObject(src) ? src : {};
225					}
226
227					// Never move original objects, clone them
228					target[ name ] = jQuery.extend( deep, clone, copy );
229
230				// Don't bring in undefined values
231				} else if ( copy !== undefined ) {
232					target[ name ] = copy;
233				}
234			}
235		}
236	}
237
238	// Return the modified object
239	return target;
240};
241
242jQuery.extend({
243	// Unique for each copy of jQuery on the page
244	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
245
246	// Assume jQuery is ready without the ready module
247	isReady: true,
248
249	error: function( msg ) {
250		throw new Error( msg );
251	},
252
253	noop: function() {},
254
255	isFunction: function( obj ) {
256		return jQuery.type(obj) === "function";
257	},
258
259	isArray: Array.isArray,
260
261	isWindow: function( obj ) {
262		return obj != null && obj === obj.window;
263	},
264
265	isNumeric: function( obj ) {
266		// parseFloat NaNs numeric-cast false positives (null|true|false|"")
267		// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
268		// subtraction forces infinities to NaN
269		// adding 1 corrects loss of precision from parseFloat (#15100)
270		return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;
271	},
272
273	isPlainObject: function( obj ) {
274		// Not plain objects:
275		// - Any object or value whose internal [[Class]] property is not "[object Object]"
276		// - DOM nodes
277		// - window
278		if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
279			return false;
280		}
281
282		if ( obj.constructor &&
283				!hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
284			return false;
285		}
286
287		// If the function hasn't returned already, we're confident that
288		// |obj| is a plain object, created by {} or constructed with new Object
289		return true;
290	},
291
292	isEmptyObject: function( obj ) {
293		var name;
294		for ( name in obj ) {
295			return false;
296		}
297		return true;
298	},
299
300	type: function( obj ) {
301		if ( obj == null ) {
302			return obj + "";
303		}
304		// Support: Android<4.0, iOS<6 (functionish RegExp)
305		return typeof obj === "object" || typeof obj === "function" ?
306			class2type[ toString.call(obj) ] || "object" :
307			typeof obj;
308	},
309
310	// Evaluates a script in a global context
311	globalEval: function( code ) {
312		var script,
313			indirect = eval;
314
315		code = jQuery.trim( code );
316
317		if ( code ) {
318			// If the code includes a valid, prologue position
319			// strict mode pragma, execute code by injecting a
320			// script tag into the document.
321			if ( code.indexOf("use strict") === 1 ) {
322				script = document.createElement("script");
323				script.text = code;
324				document.head.appendChild( script ).parentNode.removeChild( script );
325			} else {
326			// Otherwise, avoid the DOM node creation, insertion
327			// and removal by using an indirect global eval
328				indirect( code );
329			}
330		}
331	},
332
333	// Convert dashed to camelCase; used by the css and data modules
334	// Support: IE9-11+
335	// Microsoft forgot to hump their vendor prefix (#9572)
336	camelCase: function( string ) {
337		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
338	},
339
340	nodeName: function( elem, name ) {
341		return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
342	},
343
344	// args is for internal usage only
345	each: function( obj, callback, args ) {
346		var value,
347			i = 0,
348			length = obj.length,
349			isArray = isArraylike( obj );
350
351		if ( args ) {
352			if ( isArray ) {
353				for ( ; i < length; i++ ) {
354					value = callback.apply( obj[ i ], args );
355
356					if ( value === false ) {
357						break;
358					}
359				}
360			} else {
361				for ( i in obj ) {
362					value = callback.apply( obj[ i ], args );
363
364					if ( value === false ) {
365						break;
366					}
367				}
368			}
369
370		// A special, fast, case for the most common use of each
371		} else {
372			if ( isArray ) {
373				for ( ; i < length; i++ ) {
374					value = callback.call( obj[ i ], i, obj[ i ] );
375
376					if ( value === false ) {
377						break;
378					}
379				}
380			} else {
381				for ( i in obj ) {
382					value = callback.call( obj[ i ], i, obj[ i ] );
383
384					if ( value === false ) {
385						break;
386					}
387				}
388			}
389		}
390
391		return obj;
392	},
393
394	// Support: Android<4.1
395	trim: function( text ) {
396		return text == null ?
397			"" :
398			( text + "" ).replace( rtrim, "" );
399	},
400
401	// results is for internal usage only
402	makeArray: function( arr, results ) {
403		var ret = results || [];
404
405		if ( arr != null ) {
406			if ( isArraylike( Object(arr) ) ) {
407				jQuery.merge( ret,
408					typeof arr === "string" ?
409					[ arr ] : arr
410				);
411			} else {
412				push.call( ret, arr );
413			}
414		}
415
416		return ret;
417	},
418
419	inArray: function( elem, arr, i ) {
420		return arr == null ? -1 : indexOf.call( arr, elem, i );
421	},
422
423	merge: function( first, second ) {
424		var len = +second.length,
425			j = 0,
426			i = first.length;
427
428		for ( ; j < len; j++ ) {
429			first[ i++ ] = second[ j ];
430		}
431
432		first.length = i;
433
434		return first;
435	},
436
437	grep: function( elems, callback, invert ) {
438		var callbackInverse,
439			matches = [],
440			i = 0,
441			length = elems.length,
442			callbackExpect = !invert;
443
444		// Go through the array, only saving the items
445		// that pass the validator function
446		for ( ; i < length; i++ ) {
447			callbackInverse = !callback( elems[ i ], i );
448			if ( callbackInverse !== callbackExpect ) {
449				matches.push( elems[ i ] );
450			}
451		}
452
453		return matches;
454	},
455
456	// arg is for internal usage only
457	map: function( elems, callback, arg ) {
458		var value,
459			i = 0,
460			length = elems.length,
461			isArray = isArraylike( elems ),
462			ret = [];
463
464		// Go through the array, translating each of the items to their new values
465		if ( isArray ) {
466			for ( ; i < length; i++ ) {
467				value = callback( elems[ i ], i, arg );
468
469				if ( value != null ) {
470					ret.push( value );
471				}
472			}
473
474		// Go through every key on the object,
475		} else {
476			for ( i in elems ) {
477				value = callback( elems[ i ], i, arg );
478
479				if ( value != null ) {
480					ret.push( value );
481				}
482			}
483		}
484
485		// Flatten any nested arrays
486		return concat.apply( [], ret );
487	},
488
489	// A global GUID counter for objects
490	guid: 1,
491
492	// Bind a function to a context, optionally partially applying any
493	// arguments.
494	proxy: function( fn, context ) {
495		var tmp, args, proxy;
496
497		if ( typeof context === "string" ) {
498			tmp = fn[ context ];
499			context = fn;
500			fn = tmp;
501		}
502
503		// Quick check to determine if target is callable, in the spec
504		// this throws a TypeError, but we will just return undefined.
505		if ( !jQuery.isFunction( fn ) ) {
506			return undefined;
507		}
508
509		// Simulated bind
510		args = slice.call( arguments, 2 );
511		proxy = function() {
512			return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
513		};
514
515		// Set the guid of unique handler to the same of original handler, so it can be removed
516		proxy.guid = fn.guid = fn.guid || jQuery.guid++;
517
518		return proxy;
519	},
520
521	now: Date.now,
522
523	// jQuery.support is not used in Core but other projects attach their
524	// properties to it so it needs to exist.
525	support: support
526});
527
528// Populate the class2type map
529jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
530	class2type[ "[object " + name + "]" ] = name.toLowerCase();
531});
532
533function isArraylike( obj ) {
534
535	// Support: iOS 8.2 (not reproducible in simulator)
536	// `in` check used to prevent JIT error (gh-2145)
537	// hasOwn isn't used here due to false negatives
538	// regarding Nodelist length in IE
539	var length = "length" in obj && obj.length,
540		type = jQuery.type( obj );
541
542	if ( type === "function" || jQuery.isWindow( obj ) ) {
543		return false;
544	}
545
546	if ( obj.nodeType === 1 && length ) {
547		return true;
548	}
549
550	return type === "array" || length === 0 ||
551		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
552}
553var Sizzle =
554/*!
555 * Sizzle CSS Selector Engine v2.2.0-pre
556 * http://sizzlejs.com/
557 *
558 * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors
559 * Released under the MIT license
560 * http://jquery.org/license
561 *
562 * Date: 2014-12-16
563 */
564(function( window ) {
565
566var i,
567	support,
568	Expr,
569	getText,
570	isXML,
571	tokenize,
572	compile,
573	select,
574	outermostContext,
575	sortInput,
576	hasDuplicate,
577
578	// Local document vars
579	setDocument,
580	document,
581	docElem,
582	documentIsHTML,
583	rbuggyQSA,
584	rbuggyMatches,
585	matches,
586	contains,
587
588	// Instance-specific data
589	expando = "sizzle" + 1 * new Date(),
590	preferredDoc = window.document,
591	dirruns = 0,
592	done = 0,
593	classCache = createCache(),
594	tokenCache = createCache(),
595	compilerCache = createCache(),
596	sortOrder = function( a, b ) {
597		if ( a === b ) {
598			hasDuplicate = true;
599		}
600		return 0;
601	},
602
603	// General-purpose constants
604	MAX_NEGATIVE = 1 << 31,
605
606	// Instance methods
607	hasOwn = ({}).hasOwnProperty,
608	arr = [],
609	pop = arr.pop,
610	push_native = arr.push,
611	push = arr.push,
612	slice = arr.slice,
613	// Use a stripped-down indexOf as it's faster than native
614	// http://jsperf.com/thor-indexof-vs-for/5
615	indexOf = function( list, elem ) {
616		var i = 0,
617			len = list.length;
618		for ( ; i < len; i++ ) {
619			if ( list[i] === elem ) {
620				return i;
621			}
622		}
623		return -1;
624	},
625
626	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
627
628	// Regular expressions
629
630	// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
631	whitespace = "[\\x20\\t\\r\\n\\f]",
632	// http://www.w3.org/TR/css3-syntax/#characters
633	characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
634
635	// Loosely modeled on CSS identifier characters
636	// An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
637	// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
638	identifier = characterEncoding.replace( "w", "w#" ),
639
640	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
641	attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace +
642		// Operator (capture 2)
643		"*([*^$|!~]?=)" + whitespace +
644		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
645		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
646		"*\\]",
647
648	pseudos = ":(" + characterEncoding + ")(?:\\((" +
649		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
650		// 1. quoted (capture 3; capture 4 or capture 5)
651		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
652		// 2. simple (capture 6)
653		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
654		// 3. anything else (capture 2)
655		".*" +
656		")\\)|)",
657
658	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
659	rwhitespace = new RegExp( whitespace + "+", "g" ),
660	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
661
662	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
663	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
664
665	rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
666
667	rpseudo = new RegExp( pseudos ),
668	ridentifier = new RegExp( "^" + identifier + "$" ),
669
670	matchExpr = {
671		"ID": new RegExp( "^#(" + characterEncoding + ")" ),
672		"CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
673		"TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
674		"ATTR": new RegExp( "^" + attributes ),
675		"PSEUDO": new RegExp( "^" + pseudos ),
676		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
677			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
678			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
679		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
680		// For use in libraries implementing .is()
681		// We use this for POS matching in `select`
682		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
683			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
684	},
685
686	rinputs = /^(?:input|select|textarea|button)$/i,
687	rheader = /^h\d$/i,
688
689	rnative = /^[^{]+\{\s*\[native \w/,
690
691	// Easily-parseable/retrievable ID or TAG or CLASS selectors
692	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
693
694	rsibling = /[+~]/,
695	rescape = /'|\\/g,
696
697	// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
698	runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
699	funescape = function( _, escaped, escapedWhitespace ) {
700		var high = "0x" + escaped - 0x10000;
701		// NaN means non-codepoint
702		// Support: Firefox<24
703		// Workaround erroneous numeric interpretation of +"0x"
704		return high !== high || escapedWhitespace ?
705			escaped :
706			high < 0 ?
707				// BMP codepoint
708				String.fromCharCode( high + 0x10000 ) :
709				// Supplemental Plane codepoint (surrogate pair)
710				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
711	},
712
713	// Used for iframes
714	// See setDocument()
715	// Removing the function wrapper causes a "Permission Denied"
716	// error in IE
717	unloadHandler = function() {
718		setDocument();
719	};
720
721// Optimize for push.apply( _, NodeList )
722try {
723	push.apply(
724		(arr = slice.call( preferredDoc.childNodes )),
725		preferredDoc.childNodes
726	);
727	// Support: Android<4.0
728	// Detect silently failing push.apply
729	arr[ preferredDoc.childNodes.length ].nodeType;
730} catch ( e ) {
731	push = { apply: arr.length ?
732
733		// Leverage slice if possible
734		function( target, els ) {
735			push_native.apply( target, slice.call(els) );
736		} :
737
738		// Support: IE<9
739		// Otherwise append directly
740		function( target, els ) {
741			var j = target.length,
742				i = 0;
743			// Can't trust NodeList.length
744			while ( (target[j++] = els[i++]) ) {}
745			target.length = j - 1;
746		}
747	};
748}
749
750function Sizzle( selector, context, results, seed ) {
751	var match, elem, m, nodeType,
752		// QSA vars
753		i, groups, old, nid, newContext, newSelector;
754
755	if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
756		setDocument( context );
757	}
758
759	context = context || document;
760	results = results || [];
761	nodeType = context.nodeType;
762
763	if ( typeof selector !== "string" || !selector ||
764		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
765
766		return results;
767	}
768
769	if ( !seed && documentIsHTML ) {
770
771		// Try to shortcut find operations when possible (e.g., not under DocumentFragment)
772		if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
773			// Speed-up: Sizzle("#ID")
774			if ( (m = match[1]) ) {
775				if ( nodeType === 9 ) {
776					elem = context.getElementById( m );
777					// Check parentNode to catch when Blackberry 4.6 returns
778					// nodes that are no longer in the document (jQuery #6963)
779					if ( elem && elem.parentNode ) {
780						// Handle the case where IE, Opera, and Webkit return items
781						// by name instead of ID
782						if ( elem.id === m ) {
783							results.push( elem );
784							return results;
785						}
786					} else {
787						return results;
788					}
789				} else {
790					// Context is not a document
791					if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
792						contains( context, elem ) && elem.id === m ) {
793						results.push( elem );
794						return results;
795					}
796				}
797
798			// Speed-up: Sizzle("TAG")
799			} else if ( match[2] ) {
800				push.apply( results, context.getElementsByTagName( selector ) );
801				return results;
802
803			// Speed-up: Sizzle(".CLASS")
804			} else if ( (m = match[3]) && support.getElementsByClassName ) {
805				push.apply( results, context.getElementsByClassName( m ) );
806				return results;
807			}
808		}
809
810		// QSA path
811		if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
812			nid = old = expando;
813			newContext = context;
814			newSelector = nodeType !== 1 && selector;
815
816			// qSA works strangely on Element-rooted queries
817			// We can work around this by specifying an extra ID on the root
818			// and working up from there (Thanks to Andrew Dupont for the technique)
819			// IE 8 doesn't work on object elements
820			if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
821				groups = tokenize( selector );
822
823				if ( (old = context.getAttribute("id")) ) {
824					nid = old.replace( rescape, "\\$&" );
825				} else {
826					context.setAttribute( "id", nid );
827				}
828				nid = "[id='" + nid + "'] ";
829
830				i = groups.length;
831				while ( i-- ) {
832					groups[i] = nid + toSelector( groups[i] );
833				}
834				newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
835				newSelector = groups.join(",");
836			}
837
838			if ( newSelector ) {
839				try {
840					push.apply( results,
841						newContext.querySelectorAll( newSelector )
842					);
843					return results;
844				} catch(qsaError) {
845				} finally {
846					if ( !old ) {
847						context.removeAttribute("id");
848					}
849				}
850			}
851		}
852	}
853
854	// All others
855	return select( selector.replace( rtrim, "$1" ), context, results, seed );
856}
857
858/**
859 * Create key-value caches of limited size
860 * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
861 *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
862 *	deleting the oldest entry
863 */
864function createCache() {
865	var keys = [];
866
867	function cache( key, value ) {
868		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
869		if ( keys.push( key + " " ) > Expr.cacheLength ) {
870			// Only keep the most recent entries
871			delete cache[ keys.shift() ];
872		}
873		return (cache[ key + " " ] = value);
874	}
875	return cache;
876}
877
878/**
879 * Mark a function for special use by Sizzle
880 * @param {Function} fn The function to mark
881 */
882function markFunction( fn ) {
883	fn[ expando ] = true;
884	return fn;
885}
886
887/**
888 * Support testing using an element
889 * @param {Function} fn Passed the created div and expects a boolean result
890 */
891function assert( fn ) {
892	var div = document.createElement("div");
893
894	try {
895		return !!fn( div );
896	} catch (e) {
897		return false;
898	} finally {
899		// Remove from its parent by default
900		if ( div.parentNode ) {
901			div.parentNode.removeChild( div );
902		}
903		// release memory in IE
904		div = null;
905	}
906}
907
908/**
909 * Adds the same handler for all of the specified attrs
910 * @param {String} attrs Pipe-separated list of attributes
911 * @param {Function} handler The method that will be applied
912 */
913function addHandle( attrs, handler ) {
914	var arr = attrs.split("|"),
915		i = attrs.length;
916
917	while ( i-- ) {
918		Expr.attrHandle[ arr[i] ] = handler;
919	}
920}
921
922/**
923 * Checks document order of two siblings
924 * @param {Element} a
925 * @param {Element} b
926 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
927 */
928function siblingCheck( a, b ) {
929	var cur = b && a,
930		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
931			( ~b.sourceIndex || MAX_NEGATIVE ) -
932			( ~a.sourceIndex || MAX_NEGATIVE );
933
934	// Use IE sourceIndex if available on both nodes
935	if ( diff ) {
936		return diff;
937	}
938
939	// Check if b follows a
940	if ( cur ) {
941		while ( (cur = cur.nextSibling) ) {
942			if ( cur === b ) {
943				return -1;
944			}
945		}
946	}
947
948	return a ? 1 : -1;
949}
950
951/**
952 * Returns a function to use in pseudos for input types
953 * @param {String} type
954 */
955function createInputPseudo( type ) {
956	return function( elem ) {
957		var name = elem.nodeName.toLowerCase();
958		return name === "input" && elem.type === type;
959	};
960}
961
962/**
963 * Returns a function to use in pseudos for buttons
964 * @param {String} type
965 */
966function createButtonPseudo( type ) {
967	return function( elem ) {
968		var name = elem.nodeName.toLowerCase();
969		return (name === "input" || name === "button") && elem.type === type;
970	};
971}
972
973/**
974 * Returns a function to use in pseudos for positionals
975 * @param {Function} fn
976 */
977function createPositionalPseudo( fn ) {
978	return markFunction(function( argument ) {
979		argument = +argument;
980		return markFunction(function( seed, matches ) {
981			var j,
982				matchIndexes = fn( [], seed.length, argument ),
983				i = matchIndexes.length;
984
985			// Match elements found at the specified indexes
986			while ( i-- ) {
987				if ( seed[ (j = matchIndexes[i]) ] ) {
988					seed[j] = !(matches[j] = seed[j]);
989				}
990			}
991		});
992	});
993}
994
995/**
996 * Checks a node for validity as a Sizzle context
997 * @param {Element|Object=} context
998 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
999 */
1000function testContext( context ) {
1001	return context && typeof context.getElementsByTagName !== "undefined" && context;
1002}
1003
1004// Expose support vars for convenience
1005support = Sizzle.support = {};
1006
1007/**
1008 * Detects XML nodes
1009 * @param {Element|Object} elem An element or a document
1010 * @returns {Boolean} True iff elem is a non-HTML XML node
1011 */
1012isXML = Sizzle.isXML = function( elem ) {
1013	// documentElement is verified for cases where it doesn't yet exist
1014	// (such as loading iframes in IE - #4833)
1015	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1016	return documentElement ? documentElement.nodeName !== "HTML" : false;
1017};
1018
1019/**
1020 * Sets document-related variables once based on the current document
1021 * @param {Element|Object} [doc] An element or document object to use to set the document
1022 * @returns {Object} Returns the current document
1023 */
1024setDocument = Sizzle.setDocument = function( node ) {
1025	var hasCompare, parent,
1026		doc = node ? node.ownerDocument || node : preferredDoc;
1027
1028	// If no document and documentElement is available, return
1029	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
1030		return document;
1031	}
1032
1033	// Set our document
1034	document = doc;
1035	docElem = doc.documentElement;
1036	parent = doc.defaultView;
1037
1038	// Support: IE>8
1039	// If iframe document is assigned to "document" variable and if iframe has been reloaded,
1040	// IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
1041	// IE6-8 do not support the defaultView property so parent will be undefined
1042	if ( parent && parent !== parent.top ) {
1043		// IE11 does not have attachEvent, so all must suffer
1044		if ( parent.addEventListener ) {
1045			parent.addEventListener( "unload", unloadHandler, false );
1046		} else if ( parent.attachEvent ) {
1047			parent.attachEvent( "onunload", unloadHandler );
1048		}
1049	}
1050
1051	/* Support tests
1052	---------------------------------------------------------------------- */
1053	documentIsHTML = !isXML( doc );
1054
1055	/* Attributes
1056	---------------------------------------------------------------------- */
1057
1058	// Support: IE<8
1059	// Verify that getAttribute really returns attributes and not properties
1060	// (excepting IE8 booleans)
1061	support.attributes = assert(function( div ) {
1062		div.className = "i";
1063		return !div.getAttribute("className");
1064	});
1065
1066	/* getElement(s)By*
1067	---------------------------------------------------------------------- */
1068
1069	// Check if getElementsByTagName("*") returns only elements
1070	support.getElementsByTagName = assert(function( div ) {
1071		div.appendChild( doc.createComment("") );
1072		return !div.getElementsByTagName("*").length;
1073	});
1074
1075	// Support: IE<9
1076	support.getElementsByClassName = rnative.test( doc.getElementsByClassName );
1077
1078	// Support: IE<10
1079	// Check if getElementById returns elements by name
1080	// The broken getElementById methods don't pick up programatically-set names,
1081	// so use a roundabout getElementsByName test
1082	support.getById = assert(function( div ) {
1083		docElem.appendChild( div ).id = expando;
1084		return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
1085	});
1086
1087	// ID find and filter
1088	if ( support.getById ) {
1089		Expr.find["ID"] = function( id, context ) {
1090			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1091				var m = context.getElementById( id );
1092				// Check parentNode to catch when Blackberry 4.6 returns
1093				// nodes that are no longer in the document #6963
1094				return m && m.parentNode ? [ m ] : [];
1095			}
1096		};
1097		Expr.filter["ID"] = function( id ) {
1098			var attrId = id.replace( runescape, funescape );
1099			return function( elem ) {
1100				return elem.getAttribute("id") === attrId;
1101			};
1102		};
1103	} else {
1104		// Support: IE6/7
1105		// getElementById is not reliable as a find shortcut
1106		delete Expr.find["ID"];
1107
1108		Expr.filter["ID"] =  function( id ) {
1109			var attrId = id.replace( runescape, funescape );
1110			return function( elem ) {
1111				var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
1112				return node && node.value === attrId;
1113			};
1114		};
1115	}
1116
1117	// Tag
1118	Expr.find["TAG"] = support.getElementsByTagName ?
1119		function( tag, context ) {
1120			if ( typeof context.getElementsByTagName !== "undefined" ) {
1121				return context.getElementsByTagName( tag );
1122
1123			// DocumentFragment nodes don't have gEBTN
1124			} else if ( support.qsa ) {
1125				return context.querySelectorAll( tag );
1126			}
1127		} :
1128
1129		function( tag, context ) {
1130			var elem,
1131				tmp = [],
1132				i = 0,
1133				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
1134				results = context.getElementsByTagName( tag );
1135
1136			// Filter out possible comments
1137			if ( tag === "*" ) {
1138				while ( (elem = results[i++]) ) {
1139					if ( elem.nodeType === 1 ) {
1140						tmp.push( elem );
1141					}
1142				}
1143
1144				return tmp;
1145			}
1146			return results;
1147		};
1148
1149	// Class
1150	Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
1151		if ( documentIsHTML ) {
1152			return context.getElementsByClassName( className );
1153		}
1154	};
1155
1156	/* QSA/matchesSelector
1157	---------------------------------------------------------------------- */
1158
1159	// QSA and matchesSelector support
1160
1161	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1162	rbuggyMatches = [];
1163
1164	// qSa(:focus) reports false when true (Chrome 21)
1165	// We allow this because of a bug in IE8/9 that throws an error
1166	// whenever `document.activeElement` is accessed on an iframe
1167	// So, we allow :focus to pass through QSA all the time to avoid the IE error
1168	// See http://bugs.jquery.com/ticket/13378
1169	rbuggyQSA = [];
1170
1171	if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
1172		// Build QSA regex
1173		// Regex strategy adopted from Diego Perini
1174		assert(function( div ) {
1175			// Select is set to empty string on purpose
1176			// This is to test IE's treatment of not explicitly
1177			// setting a boolean content attribute,
1178			// since its presence should be enough
1179			// http://bugs.jquery.com/ticket/12359
1180			docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
1181				"<select id='" + expando + "-\f]' msallowcapture=''>" +
1182				"<option selected=''></option></select>";
1183
1184			// Support: IE8, Opera 11-12.16
1185			// Nothing should be selected when empty strings follow ^= or $= or *=
1186			// The test attribute must be unknown in Opera but "safe" for WinRT
1187			// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1188			if ( div.querySelectorAll("[msallowcapture^='']").length ) {
1189				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1190			}
1191
1192			// Support: IE8
1193			// Boolean attributes and "value" are not treated correctly
1194			if ( !div.querySelectorAll("[selected]").length ) {
1195				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1196			}
1197
1198			// Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+
1199			if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
1200				rbuggyQSA.push("~=");
1201			}
1202
1203			// Webkit/Opera - :checked should return selected option elements
1204			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1205			// IE8 throws error here and will not see later tests
1206			if ( !div.querySelectorAll(":checked").length ) {
1207				rbuggyQSA.push(":checked");
1208			}
1209
1210			// Support: Safari 8+, iOS 8+
1211			// https://bugs.webkit.org/show_bug.cgi?id=136851
1212			// In-page `selector#id sibing-combinator selector` fails
1213			if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
1214				rbuggyQSA.push(".#.+[+~]");
1215			}
1216		});
1217
1218		assert(function( div ) {
1219			// Support: Windows 8 Native Apps
1220			// The type and name attributes are restricted during .innerHTML assignment
1221			var input = doc.createElement("input");
1222			input.setAttribute( "type", "hidden" );
1223			div.appendChild( input ).setAttribute( "name", "D" );
1224
1225			// Support: IE8
1226			// Enforce case-sensitivity of name attribute
1227			if ( div.querySelectorAll("[name=d]").length ) {
1228				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1229			}
1230
1231			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1232			// IE8 throws error here and will not see later tests
1233			if ( !div.querySelectorAll(":enabled").length ) {
1234				rbuggyQSA.push( ":enabled", ":disabled" );
1235			}
1236
1237			// Opera 10-11 does not throw on post-comma invalid pseudos
1238			div.querySelectorAll("*,:x");
1239			rbuggyQSA.push(",.*:");
1240		});
1241	}
1242
1243	if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
1244		docElem.webkitMatchesSelector ||
1245		docElem.mozMatchesSelector ||
1246		docElem.oMatchesSelector ||
1247		docElem.msMatchesSelector) )) ) {
1248
1249		assert(function( div ) {
1250			// Check to see if it's possible to do matchesSelector
1251			// on a disconnected node (IE 9)
1252			support.disconnectedMatch = matches.call( div, "div" );
1253
1254			// This should fail with an exception
1255			// Gecko does not error, returns false instead
1256			matches.call( div, "[s!='']:x" );
1257			rbuggyMatches.push( "!=", pseudos );
1258		});
1259	}
1260
1261	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
1262	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
1263
1264	/* Contains
1265	---------------------------------------------------------------------- */
1266	hasCompare = rnative.test( docElem.compareDocumentPosition );
1267
1268	// Element contains another
1269	// Purposefully does not implement inclusive descendent
1270	// As in, an element does not contain itself
1271	contains = hasCompare || rnative.test( docElem.contains ) ?
1272		function( a, b ) {
1273			var adown = a.nodeType === 9 ? a.documentElement : a,
1274				bup = b && b.parentNode;
1275			return a === bup || !!( bup && bup.nodeType === 1 && (
1276				adown.contains ?
1277					adown.contains( bup ) :
1278					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1279			));
1280		} :
1281		function( a, b ) {
1282			if ( b ) {
1283				while ( (b = b.parentNode) ) {
1284					if ( b === a ) {
1285						return true;
1286					}
1287				}
1288			}
1289			return false;
1290		};
1291
1292	/* Sorting
1293	---------------------------------------------------------------------- */
1294
1295	// Document order sorting
1296	sortOrder = hasCompare ?
1297	function( a, b ) {
1298
1299		// Flag for duplicate removal
1300		if ( a === b ) {
1301			hasDuplicate = true;
1302			return 0;
1303		}
1304
1305		// Sort on method existence if only one input has compareDocumentPosition
1306		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1307		if ( compare ) {
1308			return compare;
1309		}
1310
1311		// Calculate position if both inputs belong to the same document
1312		compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
1313			a.compareDocumentPosition( b ) :
1314
1315			// Otherwise we know they are disconnected
1316			1;
1317
1318		// Disconnected nodes
1319		if ( compare & 1 ||
1320			(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
1321
1322			// Choose the first element that is related to our preferred document
1323			if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
1324				return -1;
1325			}
1326			if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
1327				return 1;
1328			}
1329
1330			// Maintain original order
1331			return sortInput ?
1332				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1333				0;
1334		}
1335
1336		return compare & 4 ? -1 : 1;
1337	} :
1338	function( a, b ) {
1339		// Exit early if the nodes are identical
1340		if ( a === b ) {
1341			hasDuplicate = true;
1342			return 0;
1343		}
1344
1345		var cur,
1346			i = 0,
1347			aup = a.parentNode,
1348			bup = b.parentNode,
1349			ap = [ a ],
1350			bp = [ b ];
1351
1352		// Parentless nodes are either documents or disconnected
1353		if ( !aup || !bup ) {
1354			return a === doc ? -1 :
1355				b === doc ? 1 :
1356				aup ? -1 :
1357				bup ? 1 :
1358				sortInput ?
1359				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1360				0;
1361
1362		// If the nodes are siblings, we can do a quick check
1363		} else if ( aup === bup ) {
1364			return siblingCheck( a, b );
1365		}
1366
1367		// Otherwise we need full lists of their ancestors for comparison
1368		cur = a;
1369		while ( (cur = cur.parentNode) ) {
1370			ap.unshift( cur );
1371		}
1372		cur = b;
1373		while ( (cur = cur.parentNode) ) {
1374			bp.unshift( cur );
1375		}
1376
1377		// Walk down the tree looking for a discrepancy
1378		while ( ap[i] === bp[i] ) {
1379			i++;
1380		}
1381
1382		return i ?
1383			// Do a sibling check if the nodes have a common ancestor
1384			siblingCheck( ap[i], bp[i] ) :
1385
1386			// Otherwise nodes in our document sort first
1387			ap[i] === preferredDoc ? -1 :
1388			bp[i] === preferredDoc ? 1 :
1389			0;
1390	};
1391
1392	return doc;
1393};
1394
1395Sizzle.matches = function( expr, elements ) {
1396	return Sizzle( expr, null, null, elements );
1397};
1398
1399Sizzle.matchesSelector = function( elem, expr ) {
1400	// Set document vars if needed
1401	if ( ( elem.ownerDocument || elem ) !== document ) {
1402		setDocument( elem );
1403	}
1404
1405	// Make sure that attribute selectors are quoted
1406	expr = expr.replace( rattributeQuotes, "='$1']" );
1407
1408	if ( support.matchesSelector && documentIsHTML &&
1409		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1410		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
1411
1412		try {
1413			var ret = matches.call( elem, expr );
1414
1415			// IE 9's matchesSelector returns false on disconnected nodes
1416			if ( ret || support.disconnectedMatch ||
1417					// As well, disconnected nodes are said to be in a document
1418					// fragment in IE 9
1419					elem.document && elem.document.nodeType !== 11 ) {
1420				return ret;
1421			}
1422		} catch (e) {}
1423	}
1424
1425	return Sizzle( expr, document, null, [ elem ] ).length > 0;
1426};
1427
1428Sizzle.contains = function( context, elem ) {
1429	// Set document vars if needed
1430	if ( ( context.ownerDocument || context ) !== document ) {
1431		setDocument( context );
1432	}
1433	return contains( context, elem );
1434};
1435
1436Sizzle.attr = function( elem, name ) {
1437	// Set document vars if needed
1438	if ( ( elem.ownerDocument || elem ) !== document ) {
1439		setDocument( elem );
1440	}
1441
1442	var fn = Expr.attrHandle[ name.toLowerCase() ],
1443		// Don't get fooled by Object.prototype properties (jQuery #13807)
1444		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1445			fn( elem, name, !documentIsHTML ) :
1446			undefined;
1447
1448	return val !== undefined ?
1449		val :
1450		support.attributes || !documentIsHTML ?
1451			elem.getAttribute( name ) :
1452			(val = elem.getAttributeNode(name)) && val.specified ?
1453				val.value :
1454				null;
1455};
1456
1457Sizzle.error = function( msg ) {
1458	throw new Error( "Syntax error, unrecognized expression: " + msg );
1459};
1460
1461/**
1462 * Document sorting and removing duplicates
1463 * @param {ArrayLike} results
1464 */
1465Sizzle.uniqueSort = function( results ) {
1466	var elem,
1467		duplicates = [],
1468		j = 0,
1469		i = 0;
1470
1471	// Unless we *know* we can detect duplicates, assume their presence
1472	hasDuplicate = !support.detectDuplicates;
1473	sortInput = !support.sortStable && results.slice( 0 );
1474	results.sort( sortOrder );
1475
1476	if ( hasDuplicate ) {
1477		while ( (elem = results[i++]) ) {
1478			if ( elem === results[ i ] ) {
1479				j = duplicates.push( i );
1480			}
1481		}
1482		while ( j-- ) {
1483			results.splice( duplicates[ j ], 1 );
1484		}
1485	}
1486
1487	// Clear input after sorting to release objects
1488	// See https://github.com/jquery/sizzle/pull/225
1489	sortInput = null;
1490
1491	return results;
1492};
1493
1494/**
1495 * Utility function for retrieving the text value of an array of DOM nodes
1496 * @param {Array|Element} elem
1497 */
1498getText = Sizzle.getText = function( elem ) {
1499	var node,
1500		ret = "",
1501		i = 0,
1502		nodeType = elem.nodeType;
1503
1504	if ( !nodeType ) {
1505		// If no nodeType, this is expected to be an array
1506		while ( (node = elem[i++]) ) {
vendor: 4,161 bytes, lines 1507-1659
1507			// Do not traverse comment nodes
1508			ret += getText( node );
1509		}
1510	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1511		// Use textContent for elements
1512		// innerText usage removed for consistency of new lines (jQuery #11153)
1513		if ( typeof elem.textContent === "string" ) {
1514			return elem.textContent;
1515		} else {
1516			// Traverse its children
1517			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1518				ret += getText( elem );
1519			}
1520		}
1521	} else if ( nodeType === 3 || nodeType === 4 ) {
1522		return elem.nodeValue;
1523	}
1524	// Do not include comment or processing instruction nodes
1525
1526	return ret;
1527};
1528
1529Expr = Sizzle.selectors = {
1530
1531	// Can be adjusted by the user
1532	cacheLength: 50,
1533
1534	createPseudo: markFunction,
1535
1536	match: matchExpr,
1537
1538	attrHandle: {},
1539
1540	find: {},
1541
1542	relative: {
1543		">": { dir: "parentNode", first: true },
1544		" ": { dir: "parentNode" },
1545		"+": { dir: "previousSibling", first: true },
1546		"~": { dir: "previousSibling" }
1547	},
1548
1549	preFilter: {
1550		"ATTR": function( match ) {
1551			match[1] = match[1].replace( runescape, funescape );
1552
1553			// Move the given value to match[3] whether quoted or unquoted
1554			match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
1555
1556			if ( match[2] === "~=" ) {
1557				match[3] = " " + match[3] + " ";
1558			}
1559
1560			return match.slice( 0, 4 );
1561		},
1562
1563		"CHILD": function( match ) {
1564			/* matches from matchExpr["CHILD"]
1565				1 type (only|nth|...)
1566				2 what (child|of-type)
1567				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1568				4 xn-component of xn+y argument ([+-]?\d*n|)
1569				5 sign of xn-component
1570				6 x of xn-component
1571				7 sign of y-component
1572				8 y of y-component
1573			*/
1574			match[1] = match[1].toLowerCase();
1575
1576			if ( match[1].slice( 0, 3 ) === "nth" ) {
1577				// nth-* requires argument
1578				if ( !match[3] ) {
1579					Sizzle.error( match[0] );
1580				}
1581
1582				// numeric x and y parameters for Expr.filter.CHILD
1583				// remember that false/true cast respectively to 0/1
1584				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
1585				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
1586
1587			// other types prohibit arguments
1588			} else if ( match[3] ) {
1589				Sizzle.error( match[0] );
1590			}
1591
1592			return match;
1593		},
1594
1595		"PSEUDO": function( match ) {
1596			var excess,
1597				unquoted = !match[6] && match[2];
1598
1599			if ( matchExpr["CHILD"].test( match[0] ) ) {
1600				return null;
1601			}
1602
1603			// Accept quoted arguments as-is
1604			if ( match[3] ) {
1605				match[2] = match[4] || match[5] || "";
1606
1607			// Strip excess characters from unquoted arguments
1608			} else if ( unquoted && rpseudo.test( unquoted ) &&
1609				// Get excess from tokenize (recursively)
1610				(excess = tokenize( unquoted, true )) &&
1611				// advance to the next closing parenthesis
1612				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
1613
1614				// excess is a negative index
1615				match[0] = match[0].slice( 0, excess );
1616				match[2] = unquoted.slice( 0, excess );
1617			}
1618
1619			// Return only captures needed by the pseudo filter method (type and argument)
1620			return match.slice( 0, 3 );
1621		}
1622	},
1623
1624	filter: {
1625
1626		"TAG": function( nodeNameSelector ) {
1627			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1628			return nodeNameSelector === "*" ?
1629				function() { return true; } :
1630				function( elem ) {
1631					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1632				};
1633		},
1634
1635		"CLASS": function( className ) {
1636			var pattern = classCache[ className + " " ];
1637
1638			return pattern ||
1639				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
1640				classCache( className, function( elem ) {
1641					return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
1642				});
1643		},
1644
1645		"ATTR": function( name, operator, check ) {
1646			return function( elem ) {
1647				var result = Sizzle.attr( elem, name );
1648
1649				if ( result == null ) {
1650					return operator === "!=";
1651				}
1652				if ( !operator ) {
1653					return true;
1654				}
1655
1656				result += "";
1657
1658				return operator === "=" ? result === check :
1659					operator === "!=" ? result !== check :
vendor: 6,854 bytes, lines 1660-1865
1660					operator === "^=" ? check && result.indexOf( check ) === 0 :
1661					operator === "*=" ? check && result.indexOf( check ) > -1 :
1662					operator === "$=" ? check && result.slice( -check.length ) === check :
1663					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
1664					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1665					false;
1666			};
1667		},
1668
1669		"CHILD": function( type, what, argument, first, last ) {
1670			var simple = type.slice( 0, 3 ) !== "nth",
1671				forward = type.slice( -4 ) !== "last",
1672				ofType = what === "of-type";
1673
1674			return first === 1 && last === 0 ?
1675
1676				// Shortcut for :nth-*(n)
1677				function( elem ) {
1678					return !!elem.parentNode;
1679				} :
1680
1681				function( elem, context, xml ) {
1682					var cache, outerCache, node, diff, nodeIndex, start,
1683						dir = simple !== forward ? "nextSibling" : "previousSibling",
1684						parent = elem.parentNode,
1685						name = ofType && elem.nodeName.toLowerCase(),
1686						useCache = !xml && !ofType;
1687
1688					if ( parent ) {
1689
1690						// :(first|last|only)-(child|of-type)
1691						if ( simple ) {
1692							while ( dir ) {
1693								node = elem;
1694								while ( (node = node[ dir ]) ) {
1695									if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
1696										return false;
1697									}
1698								}
1699								// Reverse direction for :only-* (if we haven't yet done so)
1700								start = dir = type === "only" && !start && "nextSibling";
1701							}
1702							return true;
1703						}
1704
1705						start = [ forward ? parent.firstChild : parent.lastChild ];
1706
1707						// non-xml :nth-child(...) stores cache data on `parent`
1708						if ( forward && useCache ) {
1709							// Seek `elem` from a previously-cached index
1710							outerCache = parent[ expando ] || (parent[ expando ] = {});
1711							cache = outerCache[ type ] || [];
1712							nodeIndex = cache[0] === dirruns && cache[1];
1713							diff = cache[0] === dirruns && cache[2];
1714							node = nodeIndex && parent.childNodes[ nodeIndex ];
1715
1716							while ( (node = ++nodeIndex && node && node[ dir ] ||
1717
1718								// Fallback to seeking `elem` from the start
1719								(diff = nodeIndex = 0) || start.pop()) ) {
1720
1721								// When found, cache indexes on `parent` and break
1722								if ( node.nodeType === 1 && ++diff && node === elem ) {
1723									outerCache[ type ] = [ dirruns, nodeIndex, diff ];
1724									break;
1725								}
1726							}
1727
1728						// Use previously-cached element index if available
1729						} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
1730							diff = cache[1];
1731
1732						// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
1733						} else {
1734							// Use the same loop as above to seek `elem` from the start
1735							while ( (node = ++nodeIndex && node && node[ dir ] ||
1736								(diff = nodeIndex = 0) || start.pop()) ) {
1737
1738								if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
1739									// Cache the index of each encountered element
1740									if ( useCache ) {
1741										(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
1742									}
1743
1744									if ( node === elem ) {
1745										break;
1746									}
1747								}
1748							}
1749						}
1750
1751						// Incorporate the offset, then check against cycle size
1752						diff -= last;
1753						return diff === first || ( diff % first === 0 && diff / first >= 0 );
1754					}
1755				};
1756		},
1757
1758		"PSEUDO": function( pseudo, argument ) {
1759			// pseudo-class names are case-insensitive
1760			// http://www.w3.org/TR/selectors/#pseudo-classes
1761			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1762			// Remember that setFilters inherits from pseudos
1763			var args,
1764				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
1765					Sizzle.error( "unsupported pseudo: " + pseudo );
1766
1767			// The user may use createPseudo to indicate that
1768			// arguments are needed to create the filter function
1769			// just as Sizzle does
1770			if ( fn[ expando ] ) {
1771				return fn( argument );
1772			}
1773
1774			// But maintain support for old signatures
1775			if ( fn.length > 1 ) {
1776				args = [ pseudo, pseudo, "", argument ];
1777				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
1778					markFunction(function( seed, matches ) {
1779						var idx,
1780							matched = fn( seed, argument ),
1781							i = matched.length;
1782						while ( i-- ) {
1783							idx = indexOf( seed, matched[i] );
1784							seed[ idx ] = !( matches[ idx ] = matched[i] );
1785						}
1786					}) :
1787					function( elem ) {
1788						return fn( elem, 0, args );
1789					};
1790			}
1791
1792			return fn;
1793		}
1794	},
1795
1796	pseudos: {
1797		// Potentially complex pseudos
1798		"not": markFunction(function( selector ) {
1799			// Trim the selector passed to compile
1800			// to avoid treating leading and trailing
1801			// spaces as combinators
1802			var input = [],
1803				results = [],
1804				matcher = compile( selector.replace( rtrim, "$1" ) );
1805
1806			return matcher[ expando ] ?
1807				markFunction(function( seed, matches, context, xml ) {
1808					var elem,
1809						unmatched = matcher( seed, null, xml, [] ),
1810						i = seed.length;
1811
1812					// Match elements unmatched by `matcher`
1813					while ( i-- ) {
1814						if ( (elem = unmatched[i]) ) {
1815							seed[i] = !(matches[i] = elem);
1816						}
1817					}
1818				}) :
1819				function( elem, context, xml ) {
1820					input[0] = elem;
1821					matcher( input, null, xml, results );
1822					// Don't keep the element (issue #299)
1823					input[0] = null;
1824					return !results.pop();
1825				};
1826		}),
1827
1828		"has": markFunction(function( selector ) {
1829			return function( elem ) {
1830				return Sizzle( selector, elem ).length > 0;
1831			};
1832		}),
1833
1834		"contains": markFunction(function( text ) {
1835			text = text.replace( runescape, funescape );
1836			return function( elem ) {
1837				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
1838			};
1839		}),
1840
1841		// "Whether an element is represented by a :lang() selector
1842		// is based solely on the element's language value
1843		// being equal to the identifier C,
1844		// or beginning with the identifier C immediately followed by "-".
1845		// The matching of C against the element's language value is performed case-insensitively.
1846		// The identifier C does not have to be a valid language name."
1847		// http://www.w3.org/TR/selectors/#lang-pseudo
1848		"lang": markFunction( function( lang ) {
1849			// lang value must be a valid identifier
1850			if ( !ridentifier.test(lang || "") ) {
1851				Sizzle.error( "unsupported lang: " + lang );
1852			}
1853			lang = lang.replace( runescape, funescape ).toLowerCase();
1854			return function( elem ) {
1855				var elemLang;
1856				do {
1857					if ( (elemLang = documentIsHTML ?
1858						elem.lang :
1859						elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
1860
1861						elemLang = elemLang.toLowerCase();
1862						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
1863					}
1864				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
1865				return false;
vendor: 4,543 bytes, lines 1866-2037
1866			};
1867		}),
1868
1869		// Miscellaneous
1870		"target": function( elem ) {
1871			var hash = window.location && window.location.hash;
1872			return hash && hash.slice( 1 ) === elem.id;
1873		},
1874
1875		"root": function( elem ) {
1876			return elem === docElem;
1877		},
1878
1879		"focus": function( elem ) {
1880			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
1881		},
1882
1883		// Boolean properties
1884		"enabled": function( elem ) {
1885			return elem.disabled === false;
1886		},
1887
1888		"disabled": function( elem ) {
1889			return elem.disabled === true;
1890		},
1891
1892		"checked": function( elem ) {
1893			// In CSS3, :checked should return both checked and selected elements
1894			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1895			var nodeName = elem.nodeName.toLowerCase();
1896			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
1897		},
1898
1899		"selected": function( elem ) {
1900			// Accessing this property makes selected-by-default
1901			// options in Safari work properly
1902			if ( elem.parentNode ) {
1903				elem.parentNode.selectedIndex;
1904			}
1905
1906			return elem.selected === true;
1907		},
1908
1909		// Contents
1910		"empty": function( elem ) {
1911			// http://www.w3.org/TR/selectors/#empty-pseudo
1912			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
1913			//   but not by others (comment: 8; processing instruction: 7; etc.)
1914			// nodeType < 6 works because attributes (2) do not appear as children
1915			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1916				if ( elem.nodeType < 6 ) {
1917					return false;
1918				}
1919			}
1920			return true;
1921		},
1922
1923		"parent": function( elem ) {
1924			return !Expr.pseudos["empty"]( elem );
1925		},
1926
1927		// Element/input types
1928		"header": function( elem ) {
1929			return rheader.test( elem.nodeName );
1930		},
1931
1932		"input": function( elem ) {
1933			return rinputs.test( elem.nodeName );
1934		},
1935
1936		"button": function( elem ) {
1937			var name = elem.nodeName.toLowerCase();
1938			return name === "input" && elem.type === "button" || name === "button";
1939		},
1940
1941		"text": function( elem ) {
1942			var attr;
1943			return elem.nodeName.toLowerCase() === "input" &&
1944				elem.type === "text" &&
1945
1946				// Support: IE<8
1947				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
1948				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
1949		},
1950
1951		// Position-in-collection
1952		"first": createPositionalPseudo(function() {
1953			return [ 0 ];
1954		}),
1955
1956		"last": createPositionalPseudo(function( matchIndexes, length ) {
1957			return [ length - 1 ];
1958		}),
1959
1960		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
1961			return [ argument < 0 ? argument + length : argument ];
1962		}),
1963
1964		"even": createPositionalPseudo(function( matchIndexes, length ) {
1965			var i = 0;
1966			for ( ; i < length; i += 2 ) {
1967				matchIndexes.push( i );
1968			}
1969			return matchIndexes;
1970		}),
1971
1972		"odd": createPositionalPseudo(function( matchIndexes, length ) {
1973			var i = 1;
1974			for ( ; i < length; i += 2 ) {
1975				matchIndexes.push( i );
1976			}
1977			return matchIndexes;
1978		}),
1979
1980		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
1981			var i = argument < 0 ? argument + length : argument;
1982			for ( ; --i >= 0; ) {
1983				matchIndexes.push( i );
1984			}
1985			return matchIndexes;
1986		}),
1987
1988		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
1989			var i = argument < 0 ? argument + length : argument;
1990			for ( ; ++i < length; ) {
1991				matchIndexes.push( i );
1992			}
1993			return matchIndexes;
1994		})
1995	}
1996};
1997
1998Expr.pseudos["nth"] = Expr.pseudos["eq"];
1999
2000// Add button/input type pseudos
2001for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2002	Expr.pseudos[ i ] = createInputPseudo( i );
2003}
2004for ( i in { submit: true, reset: true } ) {
2005	Expr.pseudos[ i ] = createButtonPseudo( i );
2006}
2007
2008// Easy API for creating new setFilters
2009function setFilters() {}
2010setFilters.prototype = Expr.filters = Expr.pseudos;
2011Expr.setFilters = new setFilters();
2012
2013tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
2014	var matched, match, tokens, type,
2015		soFar, groups, preFilters,
2016		cached = tokenCache[ selector + " " ];
2017
2018	if ( cached ) {
2019		return parseOnly ? 0 : cached.slice( 0 );
2020	}
2021
2022	soFar = selector;
2023	groups = [];
2024	preFilters = Expr.preFilter;
2025
2026	while ( soFar ) {
2027
2028		// Comma and first run
2029		if ( !matched || (match = rcomma.exec( soFar )) ) {
2030			if ( match ) {
2031				// Don't consume trailing commas as valid
2032				soFar = soFar.slice( match[0].length ) || soFar;
2033			}
2034			groups.push( (tokens = []) );
2035		}
2036
2037		matched = false;
vendor: 171,208 bytes, lines 2038-8457
2038
2039		// Combinators
2040		if ( (match = rcombinators.exec( soFar )) ) {
2041			matched = match.shift();
2042			tokens.push({
2043				value: matched,
2044				// Cast descendant combinators to space
2045				type: match[0].replace( rtrim, " " )
2046			});
2047			soFar = soFar.slice( matched.length );
2048		}
2049
2050		// Filters
2051		for ( type in Expr.filter ) {
2052			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
2053				(match = preFilters[ type ]( match ))) ) {
2054				matched = match.shift();
2055				tokens.push({
2056					value: matched,
2057					type: type,
2058					matches: match
2059				});
2060				soFar = soFar.slice( matched.length );
2061			}
2062		}
2063
2064		if ( !matched ) {
2065			break;
2066		}
2067	}
2068
2069	// Return the length of the invalid excess
2070	// if we're just parsing
2071	// Otherwise, throw an error or return tokens
2072	return parseOnly ?
2073		soFar.length :
2074		soFar ?
2075			Sizzle.error( selector ) :
2076			// Cache the tokens
2077			tokenCache( selector, groups ).slice( 0 );
2078};
2079
2080function toSelector( tokens ) {
2081	var i = 0,
2082		len = tokens.length,
2083		selector = "";
2084	for ( ; i < len; i++ ) {
2085		selector += tokens[i].value;
2086	}
2087	return selector;
2088}
2089
2090function addCombinator( matcher, combinator, base ) {
2091	var dir = combinator.dir,
2092		checkNonElements = base && dir === "parentNode",
2093		doneName = done++;
2094
2095	return combinator.first ?
2096		// Check against closest ancestor/preceding element
2097		function( elem, context, xml ) {
2098			while ( (elem = elem[ dir ]) ) {
2099				if ( elem.nodeType === 1 || checkNonElements ) {
2100					return matcher( elem, context, xml );
2101				}
2102			}
2103		} :
2104
2105		// Check against all ancestor/preceding elements
2106		function( elem, context, xml ) {
2107			var oldCache, outerCache,
2108				newCache = [ dirruns, doneName ];
2109
2110			// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
2111			if ( xml ) {
2112				while ( (elem = elem[ dir ]) ) {
2113					if ( elem.nodeType === 1 || checkNonElements ) {
2114						if ( matcher( elem, context, xml ) ) {
2115							return true;
2116						}
2117					}
2118				}
2119			} else {
2120				while ( (elem = elem[ dir ]) ) {
2121					if ( elem.nodeType === 1 || checkNonElements ) {
2122						outerCache = elem[ expando ] || (elem[ expando ] = {});
2123						if ( (oldCache = outerCache[ dir ]) &&
2124							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2125
2126							// Assign to newCache so results back-propagate to previous elements
2127							return (newCache[ 2 ] = oldCache[ 2 ]);
2128						} else {
2129							// Reuse newcache so results back-propagate to previous elements
2130							outerCache[ dir ] = newCache;
2131
2132							// A match means we're done; a fail means we have to keep checking
2133							if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
2134								return true;
2135							}
2136						}
2137					}
2138				}
2139			}
2140		};
2141}
2142
2143function elementMatcher( matchers ) {
2144	return matchers.length > 1 ?
2145		function( elem, context, xml ) {
2146			var i = matchers.length;
2147			while ( i-- ) {
2148				if ( !matchers[i]( elem, context, xml ) ) {
2149					return false;
2150				}
2151			}
2152			return true;
2153		} :
2154		matchers[0];
2155}
2156
2157function multipleContexts( selector, contexts, results ) {
2158	var i = 0,
2159		len = contexts.length;
2160	for ( ; i < len; i++ ) {
2161		Sizzle( selector, contexts[i], results );
2162	}
2163	return results;
2164}
2165
2166function condense( unmatched, map, filter, context, xml ) {
2167	var elem,
2168		newUnmatched = [],
2169		i = 0,
2170		len = unmatched.length,
2171		mapped = map != null;
2172
2173	for ( ; i < len; i++ ) {
2174		if ( (elem = unmatched[i]) ) {
2175			if ( !filter || filter( elem, context, xml ) ) {
2176				newUnmatched.push( elem );
2177				if ( mapped ) {
2178					map.push( i );
2179				}
2180			}
2181		}
2182	}
2183
2184	return newUnmatched;
2185}
2186
2187function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2188	if ( postFilter && !postFilter[ expando ] ) {
2189		postFilter = setMatcher( postFilter );
2190	}
2191	if ( postFinder && !postFinder[ expando ] ) {
2192		postFinder = setMatcher( postFinder, postSelector );
2193	}
2194	return markFunction(function( seed, results, context, xml ) {
2195		var temp, i, elem,
2196			preMap = [],
2197			postMap = [],
2198			preexisting = results.length,
2199
2200			// Get initial elements from seed or context
2201			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
2202
2203			// Prefilter to get matcher input, preserving a map for seed-results synchronization
2204			matcherIn = preFilter && ( seed || !selector ) ?
2205				condense( elems, preMap, preFilter, context, xml ) :
2206				elems,
2207
2208			matcherOut = matcher ?
2209				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2210				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2211
2212					// ...intermediate processing is necessary
2213					[] :
2214
2215					// ...otherwise use results directly
2216					results :
2217				matcherIn;
2218
2219		// Find primary matches
2220		if ( matcher ) {
2221			matcher( matcherIn, matcherOut, context, xml );
2222		}
2223
2224		// Apply postFilter
2225		if ( postFilter ) {
2226			temp = condense( matcherOut, postMap );
2227			postFilter( temp, [], context, xml );
2228
2229			// Un-match failing elements by moving them back to matcherIn
2230			i = temp.length;
2231			while ( i-- ) {
2232				if ( (elem = temp[i]) ) {
2233					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
2234				}
2235			}
2236		}
2237
2238		if ( seed ) {
2239			if ( postFinder || preFilter ) {
2240				if ( postFinder ) {
2241					// Get the final matcherOut by condensing this intermediate into postFinder contexts
2242					temp = [];
2243					i = matcherOut.length;
2244					while ( i-- ) {
2245						if ( (elem = matcherOut[i]) ) {
2246							// Restore matcherIn since elem is not yet a final match
2247							temp.push( (matcherIn[i] = elem) );
2248						}
2249					}
2250					postFinder( null, (matcherOut = []), temp, xml );
2251				}
2252
2253				// Move matched elements from seed to results to keep them synchronized
2254				i = matcherOut.length;
2255				while ( i-- ) {
2256					if ( (elem = matcherOut[i]) &&
2257						(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
2258
2259						seed[temp] = !(results[temp] = elem);
2260					}
2261				}
2262			}
2263
2264		// Add elements to results, through postFinder if defined
2265		} else {
2266			matcherOut = condense(
2267				matcherOut === results ?
2268					matcherOut.splice( preexisting, matcherOut.length ) :
2269					matcherOut
2270			);
2271			if ( postFinder ) {
2272				postFinder( null, results, matcherOut, xml );
2273			} else {
2274				push.apply( results, matcherOut );
2275			}
2276		}
2277	});
2278}
2279
2280function matcherFromTokens( tokens ) {
2281	var checkContext, matcher, j,
2282		len = tokens.length,
2283		leadingRelative = Expr.relative[ tokens[0].type ],
2284		implicitRelative = leadingRelative || Expr.relative[" "],
2285		i = leadingRelative ? 1 : 0,
2286
2287		// The foundational matcher ensures that elements are reachable from top-level context(s)
2288		matchContext = addCombinator( function( elem ) {
2289			return elem === checkContext;
2290		}, implicitRelative, true ),
2291		matchAnyContext = addCombinator( function( elem ) {
2292			return indexOf( checkContext, elem ) > -1;
2293		}, implicitRelative, true ),
2294		matchers = [ function( elem, context, xml ) {
2295			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2296				(checkContext = context).nodeType ?
2297					matchContext( elem, context, xml ) :
2298					matchAnyContext( elem, context, xml ) );
2299			// Avoid hanging onto element (issue #299)
2300			checkContext = null;
2301			return ret;
2302		} ];
2303
2304	for ( ; i < len; i++ ) {
2305		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
2306			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
2307		} else {
2308			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
2309
2310			// Return special upon seeing a positional matcher
2311			if ( matcher[ expando ] ) {
2312				// Find the next relative operator (if any) for proper handling
2313				j = ++i;
2314				for ( ; j < len; j++ ) {
2315					if ( Expr.relative[ tokens[j].type ] ) {
2316						break;
2317					}
2318				}
2319				return setMatcher(
2320					i > 1 && elementMatcher( matchers ),
2321					i > 1 && toSelector(
2322						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
2323						tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
2324					).replace( rtrim, "$1" ),
2325					matcher,
2326					i < j && matcherFromTokens( tokens.slice( i, j ) ),
2327					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
2328					j < len && toSelector( tokens )
2329				);
2330			}
2331			matchers.push( matcher );
2332		}
2333	}
2334
2335	return elementMatcher( matchers );
2336}
2337
2338function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2339	var bySet = setMatchers.length > 0,
2340		byElement = elementMatchers.length > 0,
2341		superMatcher = function( seed, context, xml, results, outermost ) {
2342			var elem, j, matcher,
2343				matchedCount = 0,
2344				i = "0",
2345				unmatched = seed && [],
2346				setMatched = [],
2347				contextBackup = outermostContext,
2348				// We must always have either seed elements or outermost context
2349				elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
2350				// Use integer dirruns iff this is the outermost matcher
2351				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
2352				len = elems.length;
2353
2354			if ( outermost ) {
2355				outermostContext = context !== document && context;
2356			}
2357
2358			// Add elements passing elementMatchers directly to results
2359			// Keep `i` a string if there are no elements so `matchedCount` will be "00" below
2360			// Support: IE<9, Safari
2361			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2362			for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
2363				if ( byElement && elem ) {
2364					j = 0;
2365					while ( (matcher = elementMatchers[j++]) ) {
2366						if ( matcher( elem, context, xml ) ) {
2367							results.push( elem );
2368							break;
2369						}
2370					}
2371					if ( outermost ) {
2372						dirruns = dirrunsUnique;
2373					}
2374				}
2375
2376				// Track unmatched elements for set filters
2377				if ( bySet ) {
2378					// They will have gone through all possible matchers
2379					if ( (elem = !matcher && elem) ) {
2380						matchedCount--;
2381					}
2382
2383					// Lengthen the array for every element, matched or not
2384					if ( seed ) {
2385						unmatched.push( elem );
2386					}
2387				}
2388			}
2389
2390			// Apply set filters to unmatched elements
2391			matchedCount += i;
2392			if ( bySet && i !== matchedCount ) {
2393				j = 0;
2394				while ( (matcher = setMatchers[j++]) ) {
2395					matcher( unmatched, setMatched, context, xml );
2396				}
2397
2398				if ( seed ) {
2399					// Reintegrate element matches to eliminate the need for sorting
2400					if ( matchedCount > 0 ) {
2401						while ( i-- ) {
2402							if ( !(unmatched[i] || setMatched[i]) ) {
2403								setMatched[i] = pop.call( results );
2404							}
2405						}
2406					}
2407
2408					// Discard index placeholder values to get only actual matches
2409					setMatched = condense( setMatched );
2410				}
2411
2412				// Add matches to results
2413				push.apply( results, setMatched );
2414
2415				// Seedless set matches succeeding multiple successful matchers stipulate sorting
2416				if ( outermost && !seed && setMatched.length > 0 &&
2417					( matchedCount + setMatchers.length ) > 1 ) {
2418
2419					Sizzle.uniqueSort( results );
2420				}
2421			}
2422
2423			// Override manipulation of globals by nested matchers
2424			if ( outermost ) {
2425				dirruns = dirrunsUnique;
2426				outermostContext = contextBackup;
2427			}
2428
2429			return unmatched;
2430		};
2431
2432	return bySet ?
2433		markFunction( superMatcher ) :
2434		superMatcher;
2435}
2436
2437compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
2438	var i,
2439		setMatchers = [],
2440		elementMatchers = [],
2441		cached = compilerCache[ selector + " " ];
2442
2443	if ( !cached ) {
2444		// Generate a function of recursive functions that can be used to check each element
2445		if ( !match ) {
2446			match = tokenize( selector );
2447		}
2448		i = match.length;
2449		while ( i-- ) {
2450			cached = matcherFromTokens( match[i] );
2451			if ( cached[ expando ] ) {
2452				setMatchers.push( cached );
2453			} else {
2454				elementMatchers.push( cached );
2455			}
2456		}
2457
2458		// Cache the compiled function
2459		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
2460
2461		// Save selector and tokenization
2462		cached.selector = selector;
2463	}
2464	return cached;
2465};
2466
2467/**
2468 * A low-level selection function that works with Sizzle's compiled
2469 *  selector functions
2470 * @param {String|Function} selector A selector or a pre-compiled
2471 *  selector function built with Sizzle.compile
2472 * @param {Element} context
2473 * @param {Array} [results]
2474 * @param {Array} [seed] A set of elements to match against
2475 */
2476select = Sizzle.select = function( selector, context, results, seed ) {
2477	var i, tokens, token, type, find,
2478		compiled = typeof selector === "function" && selector,
2479		match = !seed && tokenize( (selector = compiled.selector || selector) );
2480
2481	results = results || [];
2482
2483	// Try to minimize operations if there is no seed and only one group
2484	if ( match.length === 1 ) {
2485
2486		// Take a shortcut and set the context if the root selector is an ID
2487		tokens = match[0] = match[0].slice( 0 );
2488		if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
2489				support.getById && context.nodeType === 9 && documentIsHTML &&
2490				Expr.relative[ tokens[1].type ] ) {
2491
2492			context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
2493			if ( !context ) {
2494				return results;
2495
2496			// Precompiled matchers will still verify ancestry, so step up a level
2497			} else if ( compiled ) {
2498				context = context.parentNode;
2499			}
2500
2501			selector = selector.slice( tokens.shift().value.length );
2502		}
2503
2504		// Fetch a seed set for right-to-left matching
2505		i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
2506		while ( i-- ) {
2507			token = tokens[i];
2508
2509			// Abort if we hit a combinator
2510			if ( Expr.relative[ (type = token.type) ] ) {
2511				break;
2512			}
2513			if ( (find = Expr.find[ type ]) ) {
2514				// Search, expanding context for leading sibling combinators
2515				if ( (seed = find(
2516					token.matches[0].replace( runescape, funescape ),
2517					rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
2518				)) ) {
2519
2520					// If seed is empty or no tokens remain, we can return early
2521					tokens.splice( i, 1 );
2522					selector = seed.length && toSelector( tokens );
2523					if ( !selector ) {
2524						push.apply( results, seed );
2525						return results;
2526					}
2527
2528					break;
2529				}
2530			}
2531		}
2532	}
2533
2534	// Compile and execute a filtering function if one is not provided
2535	// Provide `match` to avoid retokenization if we modified the selector above
2536	( compiled || compile( selector, match ) )(
2537		seed,
2538		context,
2539		!documentIsHTML,
2540		results,
2541		rsibling.test( selector ) && testContext( context.parentNode ) || context
2542	);
2543	return results;
2544};
2545
2546// One-time assignments
2547
2548// Sort stability
2549support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
2550
2551// Support: Chrome 14-35+
2552// Always assume duplicates if they aren't passed to the comparison function
2553support.detectDuplicates = !!hasDuplicate;
2554
2555// Initialize against the default document
2556setDocument();
2557
2558// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2559// Detached nodes confoundingly follow *each other*
2560support.sortDetached = assert(function( div1 ) {
2561	// Should return 1, but returns 4 (following)
2562	return div1.compareDocumentPosition( document.createElement("div") ) & 1;
2563});
2564
2565// Support: IE<8
2566// Prevent attribute/property "interpolation"
2567// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2568if ( !assert(function( div ) {
2569	div.innerHTML = "<a href='#'></a>";
2570	return div.firstChild.getAttribute("href") === "#" ;
2571}) ) {
2572	addHandle( "type|href|height|width", function( elem, name, isXML ) {
2573		if ( !isXML ) {
2574			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
2575		}
2576	});
2577}
2578
2579// Support: IE<9
2580// Use defaultValue in place of getAttribute("value")
2581if ( !support.attributes || !assert(function( div ) {
2582	div.innerHTML = "<input/>";
2583	div.firstChild.setAttribute( "value", "" );
2584	return div.firstChild.getAttribute( "value" ) === "";
2585}) ) {
2586	addHandle( "value", function( elem, name, isXML ) {
2587		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
2588			return elem.defaultValue;
2589		}
2590	});
2591}
2592
2593// Support: IE<9
2594// Use getAttributeNode to fetch booleans when getAttribute lies
2595if ( !assert(function( div ) {
2596	return div.getAttribute("disabled") == null;
2597}) ) {
2598	addHandle( booleans, function( elem, name, isXML ) {
2599		var val;
2600		if ( !isXML ) {
2601			return elem[ name ] === true ? name.toLowerCase() :
2602					(val = elem.getAttributeNode( name )) && val.specified ?
2603					val.value :
2604				null;
2605		}
2606	});
2607}
2608
2609return Sizzle;
2610
2611})( window );
2612
2613
2614
2615jQuery.find = Sizzle;
2616jQuery.expr = Sizzle.selectors;
2617jQuery.expr[":"] = jQuery.expr.pseudos;
2618jQuery.unique = Sizzle.uniqueSort;
2619jQuery.text = Sizzle.getText;
2620jQuery.isXMLDoc = Sizzle.isXML;
2621jQuery.contains = Sizzle.contains;
2622
2623
2624
2625var rneedsContext = jQuery.expr.match.needsContext;
2626
2627var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/);
2628
2629
2630
2631var risSimple = /^.[^:#\[\.,]*$/;
2632
2633// Implement the identical functionality for filter and not
2634function winnow( elements, qualifier, not ) {
2635	if ( jQuery.isFunction( qualifier ) ) {
2636		return jQuery.grep( elements, function( elem, i ) {
2637			/* jshint -W018 */
2638			return !!qualifier.call( elem, i, elem ) !== not;
2639		});
2640
2641	}
2642
2643	if ( qualifier.nodeType ) {
2644		return jQuery.grep( elements, function( elem ) {
2645			return ( elem === qualifier ) !== not;
2646		});
2647
2648	}
2649
2650	if ( typeof qualifier === "string" ) {
2651		if ( risSimple.test( qualifier ) ) {
2652			return jQuery.filter( qualifier, elements, not );
2653		}
2654
2655		qualifier = jQuery.filter( qualifier, elements );
2656	}
2657
2658	return jQuery.grep( elements, function( elem ) {
2659		return ( indexOf.call( qualifier, elem ) >= 0 ) !== not;
2660	});
2661}
2662
2663jQuery.filter = function( expr, elems, not ) {
2664	var elem = elems[ 0 ];
2665
2666	if ( not ) {
2667		expr = ":not(" + expr + ")";
2668	}
2669
2670	return elems.length === 1 && elem.nodeType === 1 ?
2671		jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
2672		jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
2673			return elem.nodeType === 1;
2674		}));
2675};
2676
2677jQuery.fn.extend({
2678	find: function( selector ) {
2679		var i,
2680			len = this.length,
2681			ret = [],
2682			self = this;
2683
2684		if ( typeof selector !== "string" ) {
2685			return this.pushStack( jQuery( selector ).filter(function() {
2686				for ( i = 0; i < len; i++ ) {
2687					if ( jQuery.contains( self[ i ], this ) ) {
2688						return true;
2689					}
2690				}
2691			}) );
2692		}
2693
2694		for ( i = 0; i < len; i++ ) {
2695			jQuery.find( selector, self[ i ], ret );
2696		}
2697
2698		// Needed because $( selector, context ) becomes $( context ).find( selector )
2699		ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
2700		ret.selector = this.selector ? this.selector + " " + selector : selector;
2701		return ret;
2702	},
2703	filter: function( selector ) {
2704		return this.pushStack( winnow(this, selector || [], false) );
2705	},
2706	not: function( selector ) {
2707		return this.pushStack( winnow(this, selector || [], true) );
2708	},
2709	is: function( selector ) {
2710		return !!winnow(
2711			this,
2712
2713			// If this is a positional/relative selector, check membership in the returned set
2714			// so $("p:first").is("p:last") won't return true for a doc with two "p".
2715			typeof selector === "string" && rneedsContext.test( selector ) ?
2716				jQuery( selector ) :
2717				selector || [],
2718			false
2719		).length;
2720	}
2721});
2722
2723
2724// Initialize a jQuery object
2725
2726
2727// A central reference to the root jQuery(document)
2728var rootjQuery,
2729
2730	// A simple way to check for HTML strings
2731	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
2732	// Strict HTML recognition (#11290: must start with <)
2733	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
2734
2735	init = jQuery.fn.init = function( selector, context ) {
2736		var match, elem;
2737
2738		// HANDLE: $(""), $(null), $(undefined), $(false)
2739		if ( !selector ) {
2740			return this;
2741		}
2742
2743		// Handle HTML strings
2744		if ( typeof selector === "string" ) {
2745			if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) {
2746				// Assume that strings that start and end with <> are HTML and skip the regex check
2747				match = [ null, selector, null ];
2748
2749			} else {
2750				match = rquickExpr.exec( selector );
2751			}
2752
2753			// Match html or make sure no context is specified for #id
2754			if ( match && (match[1] || !context) ) {
2755
2756				// HANDLE: $(html) -> $(array)
2757				if ( match[1] ) {
2758					context = context instanceof jQuery ? context[0] : context;
2759
2760					// Option to run scripts is true for back-compat
2761					// Intentionally let the error be thrown if parseHTML is not present
2762					jQuery.merge( this, jQuery.parseHTML(
2763						match[1],
2764						context && context.nodeType ? context.ownerDocument || context : document,
2765						true
2766					) );
2767
2768					// HANDLE: $(html, props)
2769					if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
2770						for ( match in context ) {
2771							// Properties of context are called as methods if possible
2772							if ( jQuery.isFunction( this[ match ] ) ) {
2773								this[ match ]( context[ match ] );
2774
2775							// ...and otherwise set as attributes
2776							} else {
2777								this.attr( match, context[ match ] );
2778							}
2779						}
2780					}
2781
2782					return this;
2783
2784				// HANDLE: $(#id)
2785				} else {
2786					elem = document.getElementById( match[2] );
2787
2788					// Support: Blackberry 4.6
2789					// gEBID returns nodes no longer in the document (#6963)
2790					if ( elem && elem.parentNode ) {
2791						// Inject the element directly into the jQuery object
2792						this.length = 1;
2793						this[0] = elem;
2794					}
2795
2796					this.context = document;
2797					this.selector = selector;
2798					return this;
2799				}
2800
2801			// HANDLE: $(expr, $(...))
2802			} else if ( !context || context.jquery ) {
2803				return ( context || rootjQuery ).find( selector );
2804
2805			// HANDLE: $(expr, context)
2806			// (which is just equivalent to: $(context).find(expr)
2807			} else {
2808				return this.constructor( context ).find( selector );
2809			}
2810
2811		// HANDLE: $(DOMElement)
2812		} else if ( selector.nodeType ) {
2813			this.context = this[0] = selector;
2814			this.length = 1;
2815			return this;
2816
2817		// HANDLE: $(function)
2818		// Shortcut for document ready
2819		} else if ( jQuery.isFunction( selector ) ) {
2820			return typeof rootjQuery.ready !== "undefined" ?
2821				rootjQuery.ready( selector ) :
2822				// Execute immediately if ready is not present
2823				selector( jQuery );
2824		}
2825
2826		if ( selector.selector !== undefined ) {
2827			this.selector = selector.selector;
2828			this.context = selector.context;
2829		}
2830
2831		return jQuery.makeArray( selector, this );
2832	};
2833
2834// Give the init function the jQuery prototype for later instantiation
2835init.prototype = jQuery.fn;
2836
2837// Initialize central reference
2838rootjQuery = jQuery( document );
2839
2840
2841var rparentsprev = /^(?:parents|prev(?:Until|All))/,
2842	// Methods guaranteed to produce a unique set when starting from a unique set
2843	guaranteedUnique = {
2844		children: true,
2845		contents: true,
2846		next: true,
2847		prev: true
2848	};
2849
2850jQuery.extend({
2851	dir: function( elem, dir, until ) {
2852		var matched = [],
2853			truncate = until !== undefined;
2854
2855		while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) {
2856			if ( elem.nodeType === 1 ) {
2857				if ( truncate && jQuery( elem ).is( until ) ) {
2858					break;
2859				}
2860				matched.push( elem );
2861			}
2862		}
2863		return matched;
2864	},
2865
2866	sibling: function( n, elem ) {
2867		var matched = [];
2868
2869		for ( ; n; n = n.nextSibling ) {
2870			if ( n.nodeType === 1 && n !== elem ) {
2871				matched.push( n );
2872			}
2873		}
2874
2875		return matched;
2876	}
2877});
2878
2879jQuery.fn.extend({
2880	has: function( target ) {
2881		var targets = jQuery( target, this ),
2882			l = targets.length;
2883
2884		return this.filter(function() {
2885			var i = 0;
2886			for ( ; i < l; i++ ) {
2887				if ( jQuery.contains( this, targets[i] ) ) {
2888					return true;
2889				}
2890			}
2891		});
2892	},
2893
2894	closest: function( selectors, context ) {
2895		var cur,
2896			i = 0,
2897			l = this.length,
2898			matched = [],
2899			pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
2900				jQuery( selectors, context || this.context ) :
2901				0;
2902
2903		for ( ; i < l; i++ ) {
2904			for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
2905				// Always skip document fragments
2906				if ( cur.nodeType < 11 && (pos ?
2907					pos.index(cur) > -1 :
2908
2909					// Don't pass non-elements to Sizzle
2910					cur.nodeType === 1 &&
2911						jQuery.find.matchesSelector(cur, selectors)) ) {
2912
2913					matched.push( cur );
2914					break;
2915				}
2916			}
2917		}
2918
2919		return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
2920	},
2921
2922	// Determine the position of an element within the set
2923	index: function( elem ) {
2924
2925		// No argument, return index in parent
2926		if ( !elem ) {
2927			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
2928		}
2929
2930		// Index in selector
2931		if ( typeof elem === "string" ) {
2932			return indexOf.call( jQuery( elem ), this[ 0 ] );
2933		}
2934
2935		// Locate the position of the desired element
2936		return indexOf.call( this,
2937
2938			// If it receives a jQuery object, the first element is used
2939			elem.jquery ? elem[ 0 ] : elem
2940		);
2941	},
2942
2943	add: function( selector, context ) {
2944		return this.pushStack(
2945			jQuery.unique(
2946				jQuery.merge( this.get(), jQuery( selector, context ) )
2947			)
2948		);
2949	},
2950
2951	addBack: function( selector ) {
2952		return this.add( selector == null ?
2953			this.prevObject : this.prevObject.filter(selector)
2954		);
2955	}
2956});
2957
2958function sibling( cur, dir ) {
2959	while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {}
2960	return cur;
2961}
2962
2963jQuery.each({
2964	parent: function( elem ) {
2965		var parent = elem.parentNode;
2966		return parent && parent.nodeType !== 11 ? parent : null;
2967	},
2968	parents: function( elem ) {
2969		return jQuery.dir( elem, "parentNode" );
2970	},
2971	parentsUntil: function( elem, i, until ) {
2972		return jQuery.dir( elem, "parentNode", until );
2973	},
2974	next: function( elem ) {
2975		return sibling( elem, "nextSibling" );
2976	},
2977	prev: function( elem ) {
2978		return sibling( elem, "previousSibling" );
2979	},
2980	nextAll: function( elem ) {
2981		return jQuery.dir( elem, "nextSibling" );
2982	},
2983	prevAll: function( elem ) {
2984		return jQuery.dir( elem, "previousSibling" );
2985	},
2986	nextUntil: function( elem, i, until ) {
2987		return jQuery.dir( elem, "nextSibling", until );
2988	},
2989	prevUntil: function( elem, i, until ) {
2990		return jQuery.dir( elem, "previousSibling", until );
2991	},
2992	siblings: function( elem ) {
2993		return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
2994	},
2995	children: function( elem ) {
2996		return jQuery.sibling( elem.firstChild );
2997	},
2998	contents: function( elem ) {
2999		return elem.contentDocument || jQuery.merge( [], elem.childNodes );
3000	}
3001}, function( name, fn ) {
3002	jQuery.fn[ name ] = function( until, selector ) {
3003		var matched = jQuery.map( this, fn, until );
3004
3005		if ( name.slice( -5 ) !== "Until" ) {
3006			selector = until;
3007		}
3008
3009		if ( selector && typeof selector === "string" ) {
3010			matched = jQuery.filter( selector, matched );
3011		}
3012
3013		if ( this.length > 1 ) {
3014			// Remove duplicates
3015			if ( !guaranteedUnique[ name ] ) {
3016				jQuery.unique( matched );
3017			}
3018
3019			// Reverse order for parents* and prev-derivatives
3020			if ( rparentsprev.test( name ) ) {
3021				matched.reverse();
3022			}
3023		}
3024
3025		return this.pushStack( matched );
3026	};
3027});
3028var rnotwhite = (/\S+/g);
3029
3030
3031
3032// String to Object options format cache
3033var optionsCache = {};
3034
3035// Convert String-formatted options into Object-formatted ones and store in cache
3036function createOptions( options ) {
3037	var object = optionsCache[ options ] = {};
3038	jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
3039		object[ flag ] = true;
3040	});
3041	return object;
3042}
3043
3044/*
3045 * Create a callback list using the following parameters:
3046 *
3047 *	options: an optional list of space-separated options that will change how
3048 *			the callback list behaves or a more traditional option object
3049 *
3050 * By default a callback list will act like an event callback list and can be
3051 * "fired" multiple times.
3052 *
3053 * Possible options:
3054 *
3055 *	once:			will ensure the callback list can only be fired once (like a Deferred)
3056 *
3057 *	memory:			will keep track of previous values and will call any callback added
3058 *					after the list has been fired right away with the latest "memorized"
3059 *					values (like a Deferred)
3060 *
3061 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
3062 *
3063 *	stopOnFalse:	interrupt callings when a callback returns false
3064 *
3065 */
3066jQuery.Callbacks = function( options ) {
3067
3068	// Convert options from String-formatted to Object-formatted if needed
3069	// (we check in cache first)
3070	options = typeof options === "string" ?
3071		( optionsCache[ options ] || createOptions( options ) ) :
3072		jQuery.extend( {}, options );
3073
3074	var // Last fire value (for non-forgettable lists)
3075		memory,
3076		// Flag to know if list was already fired
3077		fired,
3078		// Flag to know if list is currently firing
3079		firing,
3080		// First callback to fire (used internally by add and fireWith)
3081		firingStart,
3082		// End of the loop when firing
3083		firingLength,
3084		// Index of currently firing callback (modified by remove if needed)
3085		firingIndex,
3086		// Actual callback list
3087		list = [],
3088		// Stack of fire calls for repeatable lists
3089		stack = !options.once && [],
3090		// Fire callbacks
3091		fire = function( data ) {
3092			memory = options.memory && data;
3093			fired = true;
3094			firingIndex = firingStart || 0;
3095			firingStart = 0;
3096			firingLength = list.length;
3097			firing = true;
3098			for ( ; list && firingIndex < firingLength; firingIndex++ ) {
3099				if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
3100					memory = false; // To prevent further calls using add
3101					break;
3102				}
3103			}
3104			firing = false;
3105			if ( list ) {
3106				if ( stack ) {
3107					if ( stack.length ) {
3108						fire( stack.shift() );
3109					}
3110				} else if ( memory ) {
3111					list = [];
3112				} else {
3113					self.disable();
3114				}
3115			}
3116		},
3117		// Actual Callbacks object
3118		self = {
3119			// Add a callback or a collection of callbacks to the list
3120			add: function() {
3121				if ( list ) {
3122					// First, we save the current length
3123					var start = list.length;
3124					(function add( args ) {
3125						jQuery.each( args, function( _, arg ) {
3126							var type = jQuery.type( arg );
3127							if ( type === "function" ) {
3128								if ( !options.unique || !self.has( arg ) ) {
3129									list.push( arg );
3130								}
3131							} else if ( arg && arg.length && type !== "string" ) {
3132								// Inspect recursively
3133								add( arg );
3134							}
3135						});
3136					})( arguments );
3137					// Do we need to add the callbacks to the
3138					// current firing batch?
3139					if ( firing ) {
3140						firingLength = list.length;
3141					// With memory, if we're not firing then
3142					// we should call right away
3143					} else if ( memory ) {
3144						firingStart = start;
3145						fire( memory );
3146					}
3147				}
3148				return this;
3149			},
3150			// Remove a callback from the list
3151			remove: function() {
3152				if ( list ) {
3153					jQuery.each( arguments, function( _, arg ) {
3154						var index;
3155						while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3156							list.splice( index, 1 );
3157							// Handle firing indexes
3158							if ( firing ) {
3159								if ( index <= firingLength ) {
3160									firingLength--;
3161								}
3162								if ( index <= firingIndex ) {
3163									firingIndex--;
3164								}
3165							}
3166						}
3167					});
3168				}
3169				return this;
3170			},
3171			// Check if a given callback is in the list.
3172			// If no argument is given, return whether or not list has callbacks attached.
3173			has: function( fn ) {
3174				return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
3175			},
3176			// Remove all callbacks from the list
3177			empty: function() {
3178				list = [];
3179				firingLength = 0;
3180				return this;
3181			},
3182			// Have the list do nothing anymore
3183			disable: function() {
3184				list = stack = memory = undefined;
3185				return this;
3186			},
3187			// Is it disabled?
3188			disabled: function() {
3189				return !list;
3190			},
3191			// Lock the list in its current state
3192			lock: function() {
3193				stack = undefined;
3194				if ( !memory ) {
3195					self.disable();
3196				}
3197				return this;
3198			},
3199			// Is it locked?
3200			locked: function() {
3201				return !stack;
3202			},
3203			// Call all callbacks with the given context and arguments
3204			fireWith: function( context, args ) {
3205				if ( list && ( !fired || stack ) ) {
3206					args = args || [];
3207					args = [ context, args.slice ? args.slice() : args ];
3208					if ( firing ) {
3209						stack.push( args );
3210					} else {
3211						fire( args );
3212					}
3213				}
3214				return this;
3215			},
3216			// Call all the callbacks with the given arguments
3217			fire: function() {
3218				self.fireWith( this, arguments );
3219				return this;
3220			},
3221			// To know if the callbacks have already been called at least once
3222			fired: function() {
3223				return !!fired;
3224			}
3225		};
3226
3227	return self;
3228};
3229
3230
3231jQuery.extend({
3232
3233	Deferred: function( func ) {
3234		var tuples = [
3235				// action, add listener, listener list, final state
3236				[ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
3237				[ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
3238				[ "notify", "progress", jQuery.Callbacks("memory") ]
3239			],
3240			state = "pending",
3241			promise = {
3242				state: function() {
3243					return state;
3244				},
3245				always: function() {
3246					deferred.done( arguments ).fail( arguments );
3247					return this;
3248				},
3249				then: function( /* fnDone, fnFail, fnProgress */ ) {
3250					var fns = arguments;
3251					return jQuery.Deferred(function( newDefer ) {
3252						jQuery.each( tuples, function( i, tuple ) {
3253							var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
3254							// deferred[ done | fail | progress ] for forwarding actions to newDefer
3255							deferred[ tuple[1] ](function() {
3256								var returned = fn && fn.apply( this, arguments );
3257								if ( returned && jQuery.isFunction( returned.promise ) ) {
3258									returned.promise()
3259										.done( newDefer.resolve )
3260										.fail( newDefer.reject )
3261										.progress( newDefer.notify );
3262								} else {
3263									newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
3264								}
3265							});
3266						});
3267						fns = null;
3268					}).promise();
3269				},
3270				// Get a promise for this deferred
3271				// If obj is provided, the promise aspect is added to the object
3272				promise: function( obj ) {
3273					return obj != null ? jQuery.extend( obj, promise ) : promise;
3274				}
3275			},
3276			deferred = {};
3277
3278		// Keep pipe for back-compat
3279		promise.pipe = promise.then;
3280
3281		// Add list-specific methods
3282		jQuery.each( tuples, function( i, tuple ) {
3283			var list = tuple[ 2 ],
3284				stateString = tuple[ 3 ];
3285
3286			// promise[ done | fail | progress ] = list.add
3287			promise[ tuple[1] ] = list.add;
3288
3289			// Handle state
3290			if ( stateString ) {
3291				list.add(function() {
3292					// state = [ resolved | rejected ]
3293					state = stateString;
3294
3295				// [ reject_list | resolve_list ].disable; progress_list.lock
3296				}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
3297			}
3298
3299			// deferred[ resolve | reject | notify ]
3300			deferred[ tuple[0] ] = function() {
3301				deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
3302				return this;
3303			};
3304			deferred[ tuple[0] + "With" ] = list.fireWith;
3305		});
3306
3307		// Make the deferred a promise
3308		promise.promise( deferred );
3309
3310		// Call given func if any
3311		if ( func ) {
3312			func.call( deferred, deferred );
3313		}
3314
3315		// All done!
3316		return deferred;
3317	},
3318
3319	// Deferred helper
3320	when: function( subordinate /* , ..., subordinateN */ ) {
3321		var i = 0,
3322			resolveValues = slice.call( arguments ),
3323			length = resolveValues.length,
3324
3325			// the count of uncompleted subordinates
3326			remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
3327
3328			// the master Deferred. If resolveValues consist of only a single Deferred, just use that.
3329			deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
3330
3331			// Update function for both resolve and progress values
3332			updateFunc = function( i, contexts, values ) {
3333				return function( value ) {
3334					contexts[ i ] = this;
3335					values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
3336					if ( values === progressValues ) {
3337						deferred.notifyWith( contexts, values );
3338					} else if ( !( --remaining ) ) {
3339						deferred.resolveWith( contexts, values );
3340					}
3341				};
3342			},
3343
3344			progressValues, progressContexts, resolveContexts;
3345
3346		// Add listeners to Deferred subordinates; treat others as resolved
3347		if ( length > 1 ) {
3348			progressValues = new Array( length );
3349			progressContexts = new Array( length );
3350			resolveContexts = new Array( length );
3351			for ( ; i < length; i++ ) {
3352				if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
3353					resolveValues[ i ].promise()
3354						.done( updateFunc( i, resolveContexts, resolveValues ) )
3355						.fail( deferred.reject )
3356						.progress( updateFunc( i, progressContexts, progressValues ) );
3357				} else {
3358					--remaining;
3359				}
3360			}
3361		}
3362
3363		// If we're not waiting on anything, resolve the master
3364		if ( !remaining ) {
3365			deferred.resolveWith( resolveContexts, resolveValues );
3366		}
3367
3368		return deferred.promise();
3369	}
3370});
3371
3372
3373// The deferred used on DOM ready
3374var readyList;
3375
3376jQuery.fn.ready = function( fn ) {
3377	// Add the callback
3378	jQuery.ready.promise().done( fn );
3379
3380	return this;
3381};
3382
3383jQuery.extend({
3384	// Is the DOM ready to be used? Set to true once it occurs.
3385	isReady: false,
3386
3387	// A counter to track how many items to wait for before
3388	// the ready event fires. See #6781
3389	readyWait: 1,
3390
3391	// Hold (or release) the ready event
3392	holdReady: function( hold ) {
3393		if ( hold ) {
3394			jQuery.readyWait++;
3395		} else {
3396			jQuery.ready( true );
3397		}
3398	},
3399
3400	// Handle when the DOM is ready
3401	ready: function( wait ) {
3402
3403		// Abort if there are pending holds or we're already ready
3404		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
3405			return;
3406		}
3407
3408		// Remember that the DOM is ready
3409		jQuery.isReady = true;
3410
3411		// If a normal DOM Ready event fired, decrement, and wait if need be
3412		if ( wait !== true && --jQuery.readyWait > 0 ) {
3413			return;
3414		}
3415
3416		// If there are functions bound, to execute
3417		readyList.resolveWith( document, [ jQuery ] );
3418
3419		// Trigger any bound ready events
3420		if ( jQuery.fn.triggerHandler ) {
3421			jQuery( document ).triggerHandler( "ready" );
3422			jQuery( document ).off( "ready" );
3423		}
3424	}
3425});
3426
3427/**
3428 * The ready event handler and self cleanup method
3429 */
3430function completed() {
3431	document.removeEventListener( "DOMContentLoaded", completed, false );
3432	window.removeEventListener( "load", completed, false );
3433	jQuery.ready();
3434}
3435
3436jQuery.ready.promise = function( obj ) {
3437	if ( !readyList ) {
3438
3439		readyList = jQuery.Deferred();
3440
3441		// Catch cases where $(document).ready() is called after the browser event has already occurred.
3442		// We once tried to use readyState "interactive" here, but it caused issues like the one
3443		// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
3444		if ( document.readyState === "complete" ) {
3445			// Handle it asynchronously to allow scripts the opportunity to delay ready
3446			setTimeout( jQuery.ready );
3447
3448		} else {
3449
3450			// Use the handy event callback
3451			document.addEventListener( "DOMContentLoaded", completed, false );
3452
3453			// A fallback to window.onload, that will always work
3454			window.addEventListener( "load", completed, false );
3455		}
3456	}
3457	return readyList.promise( obj );
3458};
3459
3460// Kick off the DOM ready check even if the user does not
3461jQuery.ready.promise();
3462
3463
3464
3465
3466// Multifunctional method to get and set values of a collection
3467// The value/s can optionally be executed if it's a function
3468var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
3469	var i = 0,
3470		len = elems.length,
3471		bulk = key == null;
3472
3473	// Sets many values
3474	if ( jQuery.type( key ) === "object" ) {
3475		chainable = true;
3476		for ( i in key ) {
3477			jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
3478		}
3479
3480	// Sets one value
3481	} else if ( value !== undefined ) {
3482		chainable = true;
3483
3484		if ( !jQuery.isFunction( value ) ) {
3485			raw = true;
3486		}
3487
3488		if ( bulk ) {
3489			// Bulk operations run against the entire set
3490			if ( raw ) {
3491				fn.call( elems, value );
3492				fn = null;
3493
3494			// ...except when executing function values
3495			} else {
3496				bulk = fn;
3497				fn = function( elem, key, value ) {
3498					return bulk.call( jQuery( elem ), value );
3499				};
3500			}
3501		}
3502
3503		if ( fn ) {
3504			for ( ; i < len; i++ ) {
3505				fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
3506			}
3507		}
3508	}
3509
3510	return chainable ?
3511		elems :
3512
3513		// Gets
3514		bulk ?
3515			fn.call( elems ) :
3516			len ? fn( elems[0], key ) : emptyGet;
3517};
3518
3519
3520/**
3521 * Determines whether an object can have data
3522 */
3523jQuery.acceptData = function( owner ) {
3524	// Accepts only:
3525	//  - Node
3526	//    - Node.ELEMENT_NODE
3527	//    - Node.DOCUMENT_NODE
3528	//  - Object
3529	//    - Any
3530	/* jshint -W018 */
3531	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
3532};
3533
3534
3535function Data() {
3536	// Support: Android<4,
3537	// Old WebKit does not have Object.preventExtensions/freeze method,
3538	// return new empty object instead with no [[set]] accessor
3539	Object.defineProperty( this.cache = {}, 0, {
3540		get: function() {
3541			return {};
3542		}
3543	});
3544
3545	this.expando = jQuery.expando + Data.uid++;
3546}
3547
3548Data.uid = 1;
3549Data.accepts = jQuery.acceptData;
3550
3551Data.prototype = {
3552	key: function( owner ) {
3553		// We can accept data for non-element nodes in modern browsers,
3554		// but we should not, see #8335.
3555		// Always return the key for a frozen object.
3556		if ( !Data.accepts( owner ) ) {
3557			return 0;
3558		}
3559
3560		var descriptor = {},
3561			// Check if the owner object already has a cache key
3562			unlock = owner[ this.expando ];
3563
3564		// If not, create one
3565		if ( !unlock ) {
3566			unlock = Data.uid++;
3567
3568			// Secure it in a non-enumerable, non-writable property
3569			try {
3570				descriptor[ this.expando ] = { value: unlock };
3571				Object.defineProperties( owner, descriptor );
3572
3573			// Support: Android<4
3574			// Fallback to a less secure definition
3575			} catch ( e ) {
3576				descriptor[ this.expando ] = unlock;
3577				jQuery.extend( owner, descriptor );
3578			}
3579		}
3580
3581		// Ensure the cache object
3582		if ( !this.cache[ unlock ] ) {
3583			this.cache[ unlock ] = {};
3584		}
3585
3586		return unlock;
3587	},
3588	set: function( owner, data, value ) {
3589		var prop,
3590			// There may be an unlock assigned to this node,
3591			// if there is no entry for this "owner", create one inline
3592			// and set the unlock as though an owner entry had always existed
3593			unlock = this.key( owner ),
3594			cache = this.cache[ unlock ];
3595
3596		// Handle: [ owner, key, value ] args
3597		if ( typeof data === "string" ) {
3598			cache[ data ] = value;
3599
3600		// Handle: [ owner, { properties } ] args
3601		} else {
3602			// Fresh assignments by object are shallow copied
3603			if ( jQuery.isEmptyObject( cache ) ) {
3604				jQuery.extend( this.cache[ unlock ], data );
3605			// Otherwise, copy the properties one-by-one to the cache object
3606			} else {
3607				for ( prop in data ) {
3608					cache[ prop ] = data[ prop ];
3609				}
3610			}
3611		}
3612		return cache;
3613	},
3614	get: function( owner, key ) {
3615		// Either a valid cache is found, or will be created.
3616		// New caches will be created and the unlock returned,
3617		// allowing direct access to the newly created
3618		// empty data object. A valid owner object must be provided.
3619		var cache = this.cache[ this.key( owner ) ];
3620
3621		return key === undefined ?
3622			cache : cache[ key ];
3623	},
3624	access: function( owner, key, value ) {
3625		var stored;
3626		// In cases where either:
3627		//
3628		//   1. No key was specified
3629		//   2. A string key was specified, but no value provided
3630		//
3631		// Take the "read" path and allow the get method to determine
3632		// which value to return, respectively either:
3633		//
3634		//   1. The entire cache object
3635		//   2. The data stored at the key
3636		//
3637		if ( key === undefined ||
3638				((key && typeof key === "string") && value === undefined) ) {
3639
3640			stored = this.get( owner, key );
3641
3642			return stored !== undefined ?
3643				stored : this.get( owner, jQuery.camelCase(key) );
3644		}
3645
3646		// [*]When the key is not a string, or both a key and value
3647		// are specified, set or extend (existing objects) with either:
3648		//
3649		//   1. An object of properties
3650		//   2. A key and value
3651		//
3652		this.set( owner, key, value );
3653
3654		// Since the "set" path can have two possible entry points
3655		// return the expected data based on which path was taken[*]
3656		return value !== undefined ? value : key;
3657	},
3658	remove: function( owner, key ) {
3659		var i, name, camel,
3660			unlock = this.key( owner ),
3661			cache = this.cache[ unlock ];
3662
3663		if ( key === undefined ) {
3664			this.cache[ unlock ] = {};
3665
3666		} else {
3667			// Support array or space separated string of keys
3668			if ( jQuery.isArray( key ) ) {
3669				// If "name" is an array of keys...
3670				// When data is initially created, via ("key", "val") signature,
3671				// keys will be converted to camelCase.
3672				// Since there is no way to tell _how_ a key was added, remove
3673				// both plain key and camelCase key. #12786
3674				// This will only penalize the array argument path.
3675				name = key.concat( key.map( jQuery.camelCase ) );
3676			} else {
3677				camel = jQuery.camelCase( key );
3678				// Try the string as a key before any manipulation
3679				if ( key in cache ) {
3680					name = [ key, camel ];
3681				} else {
3682					// If a key with the spaces exists, use it.
3683					// Otherwise, create an array by matching non-whitespace
3684					name = camel;
3685					name = name in cache ?
3686						[ name ] : ( name.match( rnotwhite ) || [] );
3687				}
3688			}
3689
3690			i = name.length;
3691			while ( i-- ) {
3692				delete cache[ name[ i ] ];
3693			}
3694		}
3695	},
3696	hasData: function( owner ) {
3697		return !jQuery.isEmptyObject(
3698			this.cache[ owner[ this.expando ] ] || {}
3699		);
3700	},
3701	discard: function( owner ) {
3702		if ( owner[ this.expando ] ) {
3703			delete this.cache[ owner[ this.expando ] ];
3704		}
3705	}
3706};
3707var data_priv = new Data();
3708
3709var data_user = new Data();
3710
3711
3712
3713//	Implementation Summary
3714//
3715//	1. Enforce API surface and semantic compatibility with 1.9.x branch
3716//	2. Improve the module's maintainability by reducing the storage
3717//		paths to a single mechanism.
3718//	3. Use the same single mechanism to support "private" and "user" data.
3719//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
3720//	5. Avoid exposing implementation details on user objects (eg. expando properties)
3721//	6. Provide a clear path for implementation upgrade to WeakMap in 2014
3722
3723var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
3724	rmultiDash = /([A-Z])/g;
3725
3726function dataAttr( elem, key, data ) {
3727	var name;
3728
3729	// If nothing was found internally, try to fetch any
3730	// data from the HTML5 data-* attribute
3731	if ( data === undefined && elem.nodeType === 1 ) {
3732		name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
3733		data = elem.getAttribute( name );
3734
3735		if ( typeof data === "string" ) {
3736			try {
3737				data = data === "true" ? true :
3738					data === "false" ? false :
3739					data === "null" ? null :
3740					// Only convert to a number if it doesn't change the string
3741					+data + "" === data ? +data :
3742					rbrace.test( data ) ? jQuery.parseJSON( data ) :
3743					data;
3744			} catch( e ) {}
3745
3746			// Make sure we set the data so it isn't changed later
3747			data_user.set( elem, key, data );
3748		} else {
3749			data = undefined;
3750		}
3751	}
3752	return data;
3753}
3754
3755jQuery.extend({
3756	hasData: function( elem ) {
3757		return data_user.hasData( elem ) || data_priv.hasData( elem );
3758	},
3759
3760	data: function( elem, name, data ) {
3761		return data_user.access( elem, name, data );
3762	},
3763
3764	removeData: function( elem, name ) {
3765		data_user.remove( elem, name );
3766	},
3767
3768	// TODO: Now that all calls to _data and _removeData have been replaced
3769	// with direct calls to data_priv methods, these can be deprecated.
3770	_data: function( elem, name, data ) {
3771		return data_priv.access( elem, name, data );
3772	},
3773
3774	_removeData: function( elem, name ) {
3775		data_priv.remove( elem, name );
3776	}
3777});
3778
3779jQuery.fn.extend({
3780	data: function( key, value ) {
3781		var i, name, data,
3782			elem = this[ 0 ],
3783			attrs = elem && elem.attributes;
3784
3785		// Gets all values
3786		if ( key === undefined ) {
3787			if ( this.length ) {
3788				data = data_user.get( elem );
3789
3790				if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) {
3791					i = attrs.length;
3792					while ( i-- ) {
3793
3794						// Support: IE11+
3795						// The attrs elements can be null (#14894)
3796						if ( attrs[ i ] ) {
3797							name = attrs[ i ].name;
3798							if ( name.indexOf( "data-" ) === 0 ) {
3799								name = jQuery.camelCase( name.slice(5) );
3800								dataAttr( elem, name, data[ name ] );
3801							}
3802						}
3803					}
3804					data_priv.set( elem, "hasDataAttrs", true );
3805				}
3806			}
3807
3808			return data;
3809		}
3810
3811		// Sets multiple values
3812		if ( typeof key === "object" ) {
3813			return this.each(function() {
3814				data_user.set( this, key );
3815			});
3816		}
3817
3818		return access( this, function( value ) {
3819			var data,
3820				camelKey = jQuery.camelCase( key );
3821
3822			// The calling jQuery object (element matches) is not empty
3823			// (and therefore has an element appears at this[ 0 ]) and the
3824			// `value` parameter was not undefined. An empty jQuery object
3825			// will result in `undefined` for elem = this[ 0 ] which will
3826			// throw an exception if an attempt to read a data cache is made.
3827			if ( elem && value === undefined ) {
3828				// Attempt to get data from the cache
3829				// with the key as-is
3830				data = data_user.get( elem, key );
3831				if ( data !== undefined ) {
3832					return data;
3833				}
3834
3835				// Attempt to get data from the cache
3836				// with the key camelized
3837				data = data_user.get( elem, camelKey );
3838				if ( data !== undefined ) {
3839					return data;
3840				}
3841
3842				// Attempt to "discover" the data in
3843				// HTML5 custom data-* attrs
3844				data = dataAttr( elem, camelKey, undefined );
3845				if ( data !== undefined ) {
3846					return data;
3847				}
3848
3849				// We tried really hard, but the data doesn't exist.
3850				return;
3851			}
3852
3853			// Set the data...
3854			this.each(function() {
3855				// First, attempt to store a copy or reference of any
3856				// data that might've been store with a camelCased key.
3857				var data = data_user.get( this, camelKey );
3858
3859				// For HTML5 data-* attribute interop, we have to
3860				// store property names with dashes in a camelCase form.
3861				// This might not apply to all properties...*
3862				data_user.set( this, camelKey, value );
3863
3864				// *... In the case of properties that might _actually_
3865				// have dashes, we need to also store a copy of that
3866				// unchanged property.
3867				if ( key.indexOf("-") !== -1 && data !== undefined ) {
3868					data_user.set( this, key, value );
3869				}
3870			});
3871		}, null, value, arguments.length > 1, null, true );
3872	},
3873
3874	removeData: function( key ) {
3875		return this.each(function() {
3876			data_user.remove( this, key );
3877		});
3878	}
3879});
3880
3881
3882jQuery.extend({
3883	queue: function( elem, type, data ) {
3884		var queue;
3885
3886		if ( elem ) {
3887			type = ( type || "fx" ) + "queue";
3888			queue = data_priv.get( elem, type );
3889
3890			// Speed up dequeue by getting out quickly if this is just a lookup
3891			if ( data ) {
3892				if ( !queue || jQuery.isArray( data ) ) {
3893					queue = data_priv.access( elem, type, jQuery.makeArray(data) );
3894				} else {
3895					queue.push( data );
3896				}
3897			}
3898			return queue || [];
3899		}
3900	},
3901
3902	dequeue: function( elem, type ) {
3903		type = type || "fx";
3904
3905		var queue = jQuery.queue( elem, type ),
3906			startLength = queue.length,
3907			fn = queue.shift(),
3908			hooks = jQuery._queueHooks( elem, type ),
3909			next = function() {
3910				jQuery.dequeue( elem, type );
3911			};
3912
3913		// If the fx queue is dequeued, always remove the progress sentinel
3914		if ( fn === "inprogress" ) {
3915			fn = queue.shift();
3916			startLength--;
3917		}
3918
3919		if ( fn ) {
3920
3921			// Add a progress sentinel to prevent the fx queue from being
3922			// automatically dequeued
3923			if ( type === "fx" ) {
3924				queue.unshift( "inprogress" );
3925			}
3926
3927			// Clear up the last queue stop function
3928			delete hooks.stop;
3929			fn.call( elem, next, hooks );
3930		}
3931
3932		if ( !startLength && hooks ) {
3933			hooks.empty.fire();
3934		}
3935	},
3936
3937	// Not public - generate a queueHooks object, or return the current one
3938	_queueHooks: function( elem, type ) {
3939		var key = type + "queueHooks";
3940		return data_priv.get( elem, key ) || data_priv.access( elem, key, {
3941			empty: jQuery.Callbacks("once memory").add(function() {
3942				data_priv.remove( elem, [ type + "queue", key ] );
3943			})
3944		});
3945	}
3946});
3947
3948jQuery.fn.extend({
3949	queue: function( type, data ) {
3950		var setter = 2;
3951
3952		if ( typeof type !== "string" ) {
3953			data = type;
3954			type = "fx";
3955			setter--;
3956		}
3957
3958		if ( arguments.length < setter ) {
3959			return jQuery.queue( this[0], type );
3960		}
3961
3962		return data === undefined ?
3963			this :
3964			this.each(function() {
3965				var queue = jQuery.queue( this, type, data );
3966
3967				// Ensure a hooks for this queue
3968				jQuery._queueHooks( this, type );
3969
3970				if ( type === "fx" && queue[0] !== "inprogress" ) {
3971					jQuery.dequeue( this, type );
3972				}
3973			});
3974	},
3975	dequeue: function( type ) {
3976		return this.each(function() {
3977			jQuery.dequeue( this, type );
3978		});
3979	},
3980	clearQueue: function( type ) {
3981		return this.queue( type || "fx", [] );
3982	},
3983	// Get a promise resolved when queues of a certain type
3984	// are emptied (fx is the type by default)
3985	promise: function( type, obj ) {
3986		var tmp,
3987			count = 1,
3988			defer = jQuery.Deferred(),
3989			elements = this,
3990			i = this.length,
3991			resolve = function() {
3992				if ( !( --count ) ) {
3993					defer.resolveWith( elements, [ elements ] );
3994				}
3995			};
3996
3997		if ( typeof type !== "string" ) {
3998			obj = type;
3999			type = undefined;
4000		}
4001		type = type || "fx";
4002
4003		while ( i-- ) {
4004			tmp = data_priv.get( elements[ i ], type + "queueHooks" );
4005			if ( tmp && tmp.empty ) {
4006				count++;
4007				tmp.empty.add( resolve );
4008			}
4009		}
4010		resolve();
4011		return defer.promise( obj );
4012	}
4013});
4014var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;
4015
4016var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
4017
4018var isHidden = function( elem, el ) {
4019		// isHidden might be called from jQuery#filter function;
4020		// in that case, element will be second argument
4021		elem = el || elem;
4022		return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
4023	};
4024
4025var rcheckableType = (/^(?:checkbox|radio)$/i);
4026
4027
4028
4029(function() {
4030	var fragment = document.createDocumentFragment(),
4031		div = fragment.appendChild( document.createElement( "div" ) ),
4032		input = document.createElement( "input" );
4033
4034	// Support: Safari<=5.1
4035	// Check state lost if the name is set (#11217)
4036	// Support: Windows Web Apps (WWA)
4037	// `name` and `type` must use .setAttribute for WWA (#14901)
4038	input.setAttribute( "type", "radio" );
4039	input.setAttribute( "checked", "checked" );
4040	input.setAttribute( "name", "t" );
4041
4042	div.appendChild( input );
4043
4044	// Support: Safari<=5.1, Android<4.2
4045	// Older WebKit doesn't clone checked state correctly in fragments
4046	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
4047
4048	// Support: IE<=11+
4049	// Make sure textarea (and checkbox) defaultValue is properly cloned
4050	div.innerHTML = "<textarea>x</textarea>";
4051	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
4052})();
4053var strundefined = typeof undefined;
4054
4055
4056
4057support.focusinBubbles = "onfocusin" in window;
4058
4059
4060var
4061	rkeyEvent = /^key/,
4062	rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,
4063	rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
4064	rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
4065
4066function returnTrue() {
4067	return true;
4068}
4069
4070function returnFalse() {
4071	return false;
4072}
4073
4074function safeActiveElement() {
4075	try {
4076		return document.activeElement;
4077	} catch ( err ) { }
4078}
4079
4080/*
4081 * Helper functions for managing events -- not part of the public interface.
4082 * Props to Dean Edwards' addEvent library for many of the ideas.
4083 */
4084jQuery.event = {
4085
4086	global: {},
4087
4088	add: function( elem, types, handler, data, selector ) {
4089
4090		var handleObjIn, eventHandle, tmp,
4091			events, t, handleObj,
4092			special, handlers, type, namespaces, origType,
4093			elemData = data_priv.get( elem );
4094
4095		// Don't attach events to noData or text/comment nodes (but allow plain objects)
4096		if ( !elemData ) {
4097			return;
4098		}
4099
4100		// Caller can pass in an object of custom data in lieu of the handler
4101		if ( handler.handler ) {
4102			handleObjIn = handler;
4103			handler = handleObjIn.handler;
4104			selector = handleObjIn.selector;
4105		}
4106
4107		// Make sure that the handler has a unique ID, used to find/remove it later
4108		if ( !handler.guid ) {
4109			handler.guid = jQuery.guid++;
4110		}
4111
4112		// Init the element's event structure and main handler, if this is the first
4113		if ( !(events = elemData.events) ) {
4114			events = elemData.events = {};
4115		}
4116		if ( !(eventHandle = elemData.handle) ) {
4117			eventHandle = elemData.handle = function( e ) {
4118				// Discard the second event of a jQuery.event.trigger() and
4119				// when an event is called after a page has unloaded
4120				return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ?
4121					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
4122			};
4123		}
4124
4125		// Handle multiple events separated by a space
4126		types = ( types || "" ).match( rnotwhite ) || [ "" ];
4127		t = types.length;
4128		while ( t-- ) {
4129			tmp = rtypenamespace.exec( types[t] ) || [];
4130			type = origType = tmp[1];
4131			namespaces = ( tmp[2] || "" ).split( "." ).sort();
4132
4133			// There *must* be a type, no attaching namespace-only handlers
4134			if ( !type ) {
4135				continue;
4136			}
4137
4138			// If event changes its type, use the special event handlers for the changed type
4139			special = jQuery.event.special[ type ] || {};
4140
4141			// If selector defined, determine special event api type, otherwise given type
4142			type = ( selector ? special.delegateType : special.bindType ) || type;
4143
4144			// Update special based on newly reset type
4145			special = jQuery.event.special[ type ] || {};
4146
4147			// handleObj is passed to all event handlers
4148			handleObj = jQuery.extend({
4149				type: type,
4150				origType: origType,
4151				data: data,
4152				handler: handler,
4153				guid: handler.guid,
4154				selector: selector,
4155				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
4156				namespace: namespaces.join(".")
4157			}, handleObjIn );
4158
4159			// Init the event handler queue if we're the first
4160			if ( !(handlers = events[ type ]) ) {
4161				handlers = events[ type ] = [];
4162				handlers.delegateCount = 0;
4163
4164				// Only use addEventListener if the special events handler returns false
4165				if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
4166					if ( elem.addEventListener ) {
4167						elem.addEventListener( type, eventHandle, false );
4168					}
4169				}
4170			}
4171
4172			if ( special.add ) {
4173				special.add.call( elem, handleObj );
4174
4175				if ( !handleObj.handler.guid ) {
4176					handleObj.handler.guid = handler.guid;
4177				}
4178			}
4179
4180			// Add to the element's handler list, delegates in front
4181			if ( selector ) {
4182				handlers.splice( handlers.delegateCount++, 0, handleObj );
4183			} else {
4184				handlers.push( handleObj );
4185			}
4186
4187			// Keep track of which events have ever been used, for event optimization
4188			jQuery.event.global[ type ] = true;
4189		}
4190
4191	},
4192
4193	// Detach an event or set of events from an element
4194	remove: function( elem, types, handler, selector, mappedTypes ) {
4195
4196		var j, origCount, tmp,
4197			events, t, handleObj,
4198			special, handlers, type, namespaces, origType,
4199			elemData = data_priv.hasData( elem ) && data_priv.get( elem );
4200
4201		if ( !elemData || !(events = elemData.events) ) {
4202			return;
4203		}
4204
4205		// Once for each type.namespace in types; type may be omitted
4206		types = ( types || "" ).match( rnotwhite ) || [ "" ];
4207		t = types.length;
4208		while ( t-- ) {
4209			tmp = rtypenamespace.exec( types[t] ) || [];
4210			type = origType = tmp[1];
4211			namespaces = ( tmp[2] || "" ).split( "." ).sort();
4212
4213			// Unbind all events (on this namespace, if provided) for the element
4214			if ( !type ) {
4215				for ( type in events ) {
4216					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
4217				}
4218				continue;
4219			}
4220
4221			special = jQuery.event.special[ type ] || {};
4222			type = ( selector ? special.delegateType : special.bindType ) || type;
4223			handlers = events[ type ] || [];
4224			tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
4225
4226			// Remove matching events
4227			origCount = j = handlers.length;
4228			while ( j-- ) {
4229				handleObj = handlers[ j ];
4230
4231				if ( ( mappedTypes || origType === handleObj.origType ) &&
4232					( !handler || handler.guid === handleObj.guid ) &&
4233					( !tmp || tmp.test( handleObj.namespace ) ) &&
4234					( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
4235					handlers.splice( j, 1 );
4236
4237					if ( handleObj.selector ) {
4238						handlers.delegateCount--;
4239					}
4240					if ( special.remove ) {
4241						special.remove.call( elem, handleObj );
4242					}
4243				}
4244			}
4245
4246			// Remove generic event handler if we removed something and no more handlers exist
4247			// (avoids potential for endless recursion during removal of special event handlers)
4248			if ( origCount && !handlers.length ) {
4249				if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
4250					jQuery.removeEvent( elem, type, elemData.handle );
4251				}
4252
4253				delete events[ type ];
4254			}
4255		}
4256
4257		// Remove the expando if it's no longer used
4258		if ( jQuery.isEmptyObject( events ) ) {
4259			delete elemData.handle;
4260			data_priv.remove( elem, "events" );
4261		}
4262	},
4263
4264	trigger: function( event, data, elem, onlyHandlers ) {
4265
4266		var i, cur, tmp, bubbleType, ontype, handle, special,
4267			eventPath = [ elem || document ],
4268			type = hasOwn.call( event, "type" ) ? event.type : event,
4269			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
4270
4271		cur = tmp = elem = elem || document;
4272
4273		// Don't do events on text and comment nodes
4274		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
4275			return;
4276		}
4277
4278		// focus/blur morphs to focusin/out; ensure we're not firing them right now
4279		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
4280			return;
4281		}
4282
4283		if ( type.indexOf(".") >= 0 ) {
4284			// Namespaced trigger; create a regexp to match event type in handle()
4285			namespaces = type.split(".");
4286			type = namespaces.shift();
4287			namespaces.sort();
4288		}
4289		ontype = type.indexOf(":") < 0 && "on" + type;
4290
4291		// Caller can pass in a jQuery.Event object, Object, or just an event type string
4292		event = event[ jQuery.expando ] ?
4293			event :
4294			new jQuery.Event( type, typeof event === "object" && event );
4295
4296		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
4297		event.isTrigger = onlyHandlers ? 2 : 3;
4298		event.namespace = namespaces.join(".");
4299		event.namespace_re = event.namespace ?
4300			new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
4301			null;
4302
4303		// Clean up the event in case it is being reused
4304		event.result = undefined;
4305		if ( !event.target ) {
4306			event.target = elem;
4307		}
4308
4309		// Clone any incoming data and prepend the event, creating the handler arg list
4310		data = data == null ?
4311			[ event ] :
4312			jQuery.makeArray( data, [ event ] );
4313
4314		// Allow special events to draw outside the lines
4315		special = jQuery.event.special[ type ] || {};
4316		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
4317			return;
4318		}
4319
4320		// Determine event propagation path in advance, per W3C events spec (#9951)
4321		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
4322		if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
4323
4324			bubbleType = special.delegateType || type;
4325			if ( !rfocusMorph.test( bubbleType + type ) ) {
4326				cur = cur.parentNode;
4327			}
4328			for ( ; cur; cur = cur.parentNode ) {
4329				eventPath.push( cur );
4330				tmp = cur;
4331			}
4332
4333			// Only add window if we got to document (e.g., not plain obj or detached DOM)
4334			if ( tmp === (elem.ownerDocument || document) ) {
4335				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
4336			}
4337		}
4338
4339		// Fire handlers on the event path
4340		i = 0;
4341		while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
4342
4343			event.type = i > 1 ?
4344				bubbleType :
4345				special.bindType || type;
4346
4347			// jQuery handler
4348			handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" );
4349			if ( handle ) {
4350				handle.apply( cur, data );
4351			}
4352
4353			// Native handler
4354			handle = ontype && cur[ ontype ];
4355			if ( handle && handle.apply && jQuery.acceptData( cur ) ) {
4356				event.result = handle.apply( cur, data );
4357				if ( event.result === false ) {
4358					event.preventDefault();
4359				}
4360			}
4361		}
4362		event.type = type;
4363
4364		// If nobody prevented the default action, do it now
4365		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
4366
4367			if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
4368				jQuery.acceptData( elem ) ) {
4369
4370				// Call a native DOM method on the target with the same name name as the event.
4371				// Don't do default actions on window, that's where global variables be (#6170)
4372				if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
4373
4374					// Don't re-trigger an onFOO event when we call its FOO() method
4375					tmp = elem[ ontype ];
4376
4377					if ( tmp ) {
4378						elem[ ontype ] = null;
4379					}
4380
4381					// Prevent re-triggering of the same event, since we already bubbled it above
4382					jQuery.event.triggered = type;
4383					elem[ type ]();
4384					jQuery.event.triggered = undefined;
4385
4386					if ( tmp ) {
4387						elem[ ontype ] = tmp;
4388					}
4389				}
4390			}
4391		}
4392
4393		return event.result;
4394	},
4395
4396	dispatch: function( event ) {
4397
4398		// Make a writable jQuery.Event from the native event object
4399		event = jQuery.event.fix( event );
4400
4401		var i, j, ret, matched, handleObj,
4402			handlerQueue = [],
4403			args = slice.call( arguments ),
4404			handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [],
4405			special = jQuery.event.special[ event.type ] || {};
4406
4407		// Use the fix-ed jQuery.Event rather than the (read-only) native event
4408		args[0] = event;
4409		event.delegateTarget = this;
4410
4411		// Call the preDispatch hook for the mapped type, and let it bail if desired
4412		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
4413			return;
4414		}
4415
4416		// Determine handlers
4417		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
4418
4419		// Run delegates first; they may want to stop propagation beneath us
4420		i = 0;
4421		while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
4422			event.currentTarget = matched.elem;
4423
4424			j = 0;
4425			while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
4426
4427				// Triggered event must either 1) have no namespace, or 2) have namespace(s)
4428				// a subset or equal to those in the bound event (both can have no namespace).
4429				if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
4430
4431					event.handleObj = handleObj;
4432					event.data = handleObj.data;
4433
4434					ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
4435							.apply( matched.elem, args );
4436
4437					if ( ret !== undefined ) {
4438						if ( (event.result = ret) === false ) {
4439							event.preventDefault();
4440							event.stopPropagation();
4441						}
4442					}
4443				}
4444			}
4445		}
4446
4447		// Call the postDispatch hook for the mapped type
4448		if ( special.postDispatch ) {
4449			special.postDispatch.call( this, event );
4450		}
4451
4452		return event.result;
4453	},
4454
4455	handlers: function( event, handlers ) {
4456		var i, matches, sel, handleObj,
4457			handlerQueue = [],
4458			delegateCount = handlers.delegateCount,
4459			cur = event.target;
4460
4461		// Find delegate handlers
4462		// Black-hole SVG <use> instance trees (#13180)
4463		// Avoid non-left-click bubbling in Firefox (#3861)
4464		if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
4465
4466			for ( ; cur !== this; cur = cur.parentNode || this ) {
4467
4468				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
4469				if ( cur.disabled !== true || event.type !== "click" ) {
4470					matches = [];
4471					for ( i = 0; i < delegateCount; i++ ) {
4472						handleObj = handlers[ i ];
4473
4474						// Don't conflict with Object.prototype properties (#13203)
4475						sel = handleObj.selector + " ";
4476
4477						if ( matches[ sel ] === undefined ) {
4478							matches[ sel ] = handleObj.needsContext ?
4479								jQuery( sel, this ).index( cur ) >= 0 :
4480								jQuery.find( sel, this, null, [ cur ] ).length;
4481						}
4482						if ( matches[ sel ] ) {
4483							matches.push( handleObj );
4484						}
4485					}
4486					if ( matches.length ) {
4487						handlerQueue.push({ elem: cur, handlers: matches });
4488					}
4489				}
4490			}
4491		}
4492
4493		// Add the remaining (directly-bound) handlers
4494		if ( delegateCount < handlers.length ) {
4495			handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
4496		}
4497
4498		return handlerQueue;
4499	},
4500
4501	// Includes some event props shared by KeyEvent and MouseEvent
4502	props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
4503
4504	fixHooks: {},
4505
4506	keyHooks: {
4507		props: "char charCode key keyCode".split(" "),
4508		filter: function( event, original ) {
4509
4510			// Add which for key events
4511			if ( event.which == null ) {
4512				event.which = original.charCode != null ? original.charCode : original.keyCode;
4513			}
4514
4515			return event;
4516		}
4517	},
4518
4519	mouseHooks: {
4520		props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
4521		filter: function( event, original ) {
4522			var eventDoc, doc, body,
4523				button = original.button;
4524
4525			// Calculate pageX/Y if missing and clientX/Y available
4526			if ( event.pageX == null && original.clientX != null ) {
4527				eventDoc = event.target.ownerDocument || document;
4528				doc = eventDoc.documentElement;
4529				body = eventDoc.body;
4530
4531				event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
4532				event.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );
4533			}
4534
4535			// Add which for click: 1 === left; 2 === middle; 3 === right
4536			// Note: button is not normalized, so don't use it
4537			if ( !event.which && button !== undefined ) {
4538				event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
4539			}
4540
4541			return event;
4542		}
4543	},
4544
4545	fix: function( event ) {
4546		if ( event[ jQuery.expando ] ) {
4547			return event;
4548		}
4549
4550		// Create a writable copy of the event object and normalize some properties
4551		var i, prop, copy,
4552			type = event.type,
4553			originalEvent = event,
4554			fixHook = this.fixHooks[ type ];
4555
4556		if ( !fixHook ) {
4557			this.fixHooks[ type ] = fixHook =
4558				rmouseEvent.test( type ) ? this.mouseHooks :
4559				rkeyEvent.test( type ) ? this.keyHooks :
4560				{};
4561		}
4562		copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
4563
4564		event = new jQuery.Event( originalEvent );
4565
4566		i = copy.length;
4567		while ( i-- ) {
4568			prop = copy[ i ];
4569			event[ prop ] = originalEvent[ prop ];
4570		}
4571
4572		// Support: Cordova 2.5 (WebKit) (#13255)
4573		// All events should have a target; Cordova deviceready doesn't
4574		if ( !event.target ) {
4575			event.target = document;
4576		}
4577
4578		// Support: Safari 6.0+, Chrome<28
4579		// Target should not be a text node (#504, #13143)
4580		if ( event.target.nodeType === 3 ) {
4581			event.target = event.target.parentNode;
4582		}
4583
4584		return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
4585	},
4586
4587	special: {
4588		load: {
4589			// Prevent triggered image.load events from bubbling to window.load
4590			noBubble: true
4591		},
4592		focus: {
4593			// Fire native event if possible so blur/focus sequence is correct
4594			trigger: function() {
4595				if ( this !== safeActiveElement() && this.focus ) {
4596					this.focus();
4597					return false;
4598				}
4599			},
4600			delegateType: "focusin"
4601		},
4602		blur: {
4603			trigger: function() {
4604				if ( this === safeActiveElement() && this.blur ) {
4605					this.blur();
4606					return false;
4607				}
4608			},
4609			delegateType: "focusout"
4610		},
4611		click: {
4612			// For checkbox, fire native event so checked state will be right
4613			trigger: function() {
4614				if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
4615					this.click();
4616					return false;
4617				}
4618			},
4619
4620			// For cross-browser consistency, don't fire native .click() on links
4621			_default: function( event ) {
4622				return jQuery.nodeName( event.target, "a" );
4623			}
4624		},
4625
4626		beforeunload: {
4627			postDispatch: function( event ) {
4628
4629				// Support: Firefox 20+
4630				// Firefox doesn't alert if the returnValue field is not set.
4631				if ( event.result !== undefined && event.originalEvent ) {
4632					event.originalEvent.returnValue = event.result;
4633				}
4634			}
4635		}
4636	},
4637
4638	simulate: function( type, elem, event, bubble ) {
4639		// Piggyback on a donor event to simulate a different one.
4640		// Fake originalEvent to avoid donor's stopPropagation, but if the
4641		// simulated event prevents default then we do the same on the donor.
4642		var e = jQuery.extend(
4643			new jQuery.Event(),
4644			event,
4645			{
4646				type: type,
4647				isSimulated: true,
4648				originalEvent: {}
4649			}
4650		);
4651		if ( bubble ) {
4652			jQuery.event.trigger( e, null, elem );
4653		} else {
4654			jQuery.event.dispatch.call( elem, e );
4655		}
4656		if ( e.isDefaultPrevented() ) {
4657			event.preventDefault();
4658		}
4659	}
4660};
4661
4662jQuery.removeEvent = function( elem, type, handle ) {
4663	if ( elem.removeEventListener ) {
4664		elem.removeEventListener( type, handle, false );
4665	}
4666};
4667
4668jQuery.Event = function( src, props ) {
4669	// Allow instantiation without the 'new' keyword
4670	if ( !(this instanceof jQuery.Event) ) {
4671		return new jQuery.Event( src, props );
4672	}
4673
4674	// Event object
4675	if ( src && src.type ) {
4676		this.originalEvent = src;
4677		this.type = src.type;
4678
4679		// Events bubbling up the document may have been marked as prevented
4680		// by a handler lower down the tree; reflect the correct value.
4681		this.isDefaultPrevented = src.defaultPrevented ||
4682				src.defaultPrevented === undefined &&
4683				// Support: Android<4.0
4684				src.returnValue === false ?
4685			returnTrue :
4686			returnFalse;
4687
4688	// Event type
4689	} else {
4690		this.type = src;
4691	}
4692
4693	// Put explicitly provided properties onto the event object
4694	if ( props ) {
4695		jQuery.extend( this, props );
4696	}
4697
4698	// Create a timestamp if incoming event doesn't have one
4699	this.timeStamp = src && src.timeStamp || jQuery.now();
4700
4701	// Mark it as fixed
4702	this[ jQuery.expando ] = true;
4703};
4704
4705// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
4706// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
4707jQuery.Event.prototype = {
4708	isDefaultPrevented: returnFalse,
4709	isPropagationStopped: returnFalse,
4710	isImmediatePropagationStopped: returnFalse,
4711
4712	preventDefault: function() {
4713		var e = this.originalEvent;
4714
4715		this.isDefaultPrevented = returnTrue;
4716
4717		if ( e && e.preventDefault ) {
4718			e.preventDefault();
4719		}
4720	},
4721	stopPropagation: function() {
4722		var e = this.originalEvent;
4723
4724		this.isPropagationStopped = returnTrue;
4725
4726		if ( e && e.stopPropagation ) {
4727			e.stopPropagation();
4728		}
4729	},
4730	stopImmediatePropagation: function() {
4731		var e = this.originalEvent;
4732
4733		this.isImmediatePropagationStopped = returnTrue;
4734
4735		if ( e && e.stopImmediatePropagation ) {
4736			e.stopImmediatePropagation();
4737		}
4738
4739		this.stopPropagation();
4740	}
4741};
4742
4743// Create mouseenter/leave events using mouseover/out and event-time checks
4744// Support: Chrome 15+
4745jQuery.each({
4746	mouseenter: "mouseover",
4747	mouseleave: "mouseout",
4748	pointerenter: "pointerover",
4749	pointerleave: "pointerout"
4750}, function( orig, fix ) {
4751	jQuery.event.special[ orig ] = {
4752		delegateType: fix,
4753		bindType: fix,
4754
4755		handle: function( event ) {
4756			var ret,
4757				target = this,
4758				related = event.relatedTarget,
4759				handleObj = event.handleObj;
4760
4761			// For mousenter/leave call the handler if related is outside the target.
4762			// NB: No relatedTarget if the mouse left/entered the browser window
4763			if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
4764				event.type = handleObj.origType;
4765				ret = handleObj.handler.apply( this, arguments );
4766				event.type = fix;
4767			}
4768			return ret;
4769		}
4770	};
4771});
4772
4773// Support: Firefox, Chrome, Safari
4774// Create "bubbling" focus and blur events
4775if ( !support.focusinBubbles ) {
4776	jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
4777
4778		// Attach a single capturing handler on the document while someone wants focusin/focusout
4779		var handler = function( event ) {
4780				jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
4781			};
4782
4783		jQuery.event.special[ fix ] = {
4784			setup: function() {
4785				var doc = this.ownerDocument || this,
4786					attaches = data_priv.access( doc, fix );
4787
4788				if ( !attaches ) {
4789					doc.addEventListener( orig, handler, true );
4790				}
4791				data_priv.access( doc, fix, ( attaches || 0 ) + 1 );
4792			},
4793			teardown: function() {
4794				var doc = this.ownerDocument || this,
4795					attaches = data_priv.access( doc, fix ) - 1;
4796
4797				if ( !attaches ) {
4798					doc.removeEventListener( orig, handler, true );
4799					data_priv.remove( doc, fix );
4800
4801				} else {
4802					data_priv.access( doc, fix, attaches );
4803				}
4804			}
4805		};
4806	});
4807}
4808
4809jQuery.fn.extend({
4810
4811	on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
4812		var origFn, type;
4813
4814		// Types can be a map of types/handlers
4815		if ( typeof types === "object" ) {
4816			// ( types-Object, selector, data )
4817			if ( typeof selector !== "string" ) {
4818				// ( types-Object, data )
4819				data = data || selector;
4820				selector = undefined;
4821			}
4822			for ( type in types ) {
4823				this.on( type, selector, data, types[ type ], one );
4824			}
4825			return this;
4826		}
4827
4828		if ( data == null && fn == null ) {
4829			// ( types, fn )
4830			fn = selector;
4831			data = selector = undefined;
4832		} else if ( fn == null ) {
4833			if ( typeof selector === "string" ) {
4834				// ( types, selector, fn )
4835				fn = data;
4836				data = undefined;
4837			} else {
4838				// ( types, data, fn )
4839				fn = data;
4840				data = selector;
4841				selector = undefined;
4842			}
4843		}
4844		if ( fn === false ) {
4845			fn = returnFalse;
4846		} else if ( !fn ) {
4847			return this;
4848		}
4849
4850		if ( one === 1 ) {
4851			origFn = fn;
4852			fn = function( event ) {
4853				// Can use an empty set, since event contains the info
4854				jQuery().off( event );
4855				return origFn.apply( this, arguments );
4856			};
4857			// Use same guid so caller can remove using origFn
4858			fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
4859		}
4860		return this.each( function() {
4861			jQuery.event.add( this, types, fn, data, selector );
4862		});
4863	},
4864	one: function( types, selector, data, fn ) {
4865		return this.on( types, selector, data, fn, 1 );
4866	},
4867	off: function( types, selector, fn ) {
4868		var handleObj, type;
4869		if ( types && types.preventDefault && types.handleObj ) {
4870			// ( event )  dispatched jQuery.Event
4871			handleObj = types.handleObj;
4872			jQuery( types.delegateTarget ).off(
4873				handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
4874				handleObj.selector,
4875				handleObj.handler
4876			);
4877			return this;
4878		}
4879		if ( typeof types === "object" ) {
4880			// ( types-object [, selector] )
4881			for ( type in types ) {
4882				this.off( type, selector, types[ type ] );
4883			}
4884			return this;
4885		}
4886		if ( selector === false || typeof selector === "function" ) {
4887			// ( types [, fn] )
4888			fn = selector;
4889			selector = undefined;
4890		}
4891		if ( fn === false ) {
4892			fn = returnFalse;
4893		}
4894		return this.each(function() {
4895			jQuery.event.remove( this, types, fn, selector );
4896		});
4897	},
4898
4899	trigger: function( type, data ) {
4900		return this.each(function() {
4901			jQuery.event.trigger( type, data, this );
4902		});
4903	},
4904	triggerHandler: function( type, data ) {
4905		var elem = this[0];
4906		if ( elem ) {
4907			return jQuery.event.trigger( type, data, elem, true );
4908		}
4909	}
4910});
4911
4912
4913var
4914	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
4915	rtagName = /<([\w:]+)/,
4916	rhtml = /<|&#?\w+;/,
4917	rnoInnerhtml = /<(?:script|style|link)/i,
4918	// checked="checked" or checked
4919	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
4920	rscriptType = /^$|\/(?:java|ecma)script/i,
4921	rscriptTypeMasked = /^true\/(.*)/,
4922	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
4923
4924	// We have to close these tags to support XHTML (#13200)
4925	wrapMap = {
4926
4927		// Support: IE9
4928		option: [ 1, "<select multiple='multiple'>", "</select>" ],
4929
4930		thead: [ 1, "<table>", "</table>" ],
4931		col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
4932		tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4933		td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4934
4935		_default: [ 0, "", "" ]
4936	};
4937
4938// Support: IE9
4939wrapMap.optgroup = wrapMap.option;
4940
4941wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4942wrapMap.th = wrapMap.td;
4943
4944// Support: 1.x compatibility
4945// Manipulating tables requires a tbody
4946function manipulationTarget( elem, content ) {
4947	return jQuery.nodeName( elem, "table" ) &&
4948		jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
4949
4950		elem.getElementsByTagName("tbody")[0] ||
4951			elem.appendChild( elem.ownerDocument.createElement("tbody") ) :
4952		elem;
4953}
4954
4955// Replace/restore the type attribute of script elements for safe DOM manipulation
4956function disableScript( elem ) {
4957	elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type;
4958	return elem;
4959}
4960function restoreScript( elem ) {
4961	var match = rscriptTypeMasked.exec( elem.type );
4962
4963	if ( match ) {
4964		elem.type = match[ 1 ];
4965	} else {
4966		elem.removeAttribute("type");
4967	}
4968
4969	return elem;
4970}
4971
4972// Mark scripts as having already been evaluated
4973function setGlobalEval( elems, refElements ) {
4974	var i = 0,
4975		l = elems.length;
4976
4977	for ( ; i < l; i++ ) {
4978		data_priv.set(
4979			elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" )
4980		);
4981	}
4982}
4983
4984function cloneCopyEvent( src, dest ) {
4985	var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
4986
4987	if ( dest.nodeType !== 1 ) {
4988		return;
4989	}
4990
4991	// 1. Copy private data: events, handlers, etc.
4992	if ( data_priv.hasData( src ) ) {
4993		pdataOld = data_priv.access( src );
4994		pdataCur = data_priv.set( dest, pdataOld );
4995		events = pdataOld.events;
4996
4997		if ( events ) {
4998			delete pdataCur.handle;
4999			pdataCur.events = {};
5000
5001			for ( type in events ) {
5002				for ( i = 0, l = events[ type ].length; i < l; i++ ) {
5003					jQuery.event.add( dest, type, events[ type ][ i ] );
5004				}
5005			}
5006		}
5007	}
5008
5009	// 2. Copy user data
5010	if ( data_user.hasData( src ) ) {
5011		udataOld = data_user.access( src );
5012		udataCur = jQuery.extend( {}, udataOld );
5013
5014		data_user.set( dest, udataCur );
5015	}
5016}
5017
5018function getAll( context, tag ) {
5019	var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) :
5020			context.querySelectorAll ? context.querySelectorAll( tag || "*" ) :
5021			[];
5022
5023	return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
5024		jQuery.merge( [ context ], ret ) :
5025		ret;
5026}
5027
5028// Fix IE bugs, see support tests
5029function fixInput( src, dest ) {
5030	var nodeName = dest.nodeName.toLowerCase();
5031
5032	// Fails to persist the checked state of a cloned checkbox or radio button.
5033	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
5034		dest.checked = src.checked;
5035
5036	// Fails to return the selected option to the default selected state when cloning options
5037	} else if ( nodeName === "input" || nodeName === "textarea" ) {
5038		dest.defaultValue = src.defaultValue;
5039	}
5040}
5041
5042jQuery.extend({
5043	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
5044		var i, l, srcElements, destElements,
5045			clone = elem.cloneNode( true ),
5046			inPage = jQuery.contains( elem.ownerDocument, elem );
5047
5048		// Fix IE cloning issues
5049		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
5050				!jQuery.isXMLDoc( elem ) ) {
5051
5052			// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
5053			destElements = getAll( clone );
5054			srcElements = getAll( elem );
5055
5056			for ( i = 0, l = srcElements.length; i < l; i++ ) {
5057				fixInput( srcElements[ i ], destElements[ i ] );
5058			}
5059		}
5060
5061		// Copy the events from the original to the clone
5062		if ( dataAndEvents ) {
5063			if ( deepDataAndEvents ) {
5064				srcElements = srcElements || getAll( elem );
5065				destElements = destElements || getAll( clone );
5066
5067				for ( i = 0, l = srcElements.length; i < l; i++ ) {
5068					cloneCopyEvent( srcElements[ i ], destElements[ i ] );
5069				}
5070			} else {
5071				cloneCopyEvent( elem, clone );
5072			}
5073		}
5074
5075		// Preserve script evaluation history
5076		destElements = getAll( clone, "script" );
5077		if ( destElements.length > 0 ) {
5078			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
5079		}
5080
5081		// Return the cloned set
5082		return clone;
5083	},
5084
5085	buildFragment: function( elems, context, scripts, selection ) {
5086		var elem, tmp, tag, wrap, contains, j,
5087			fragment = context.createDocumentFragment(),
5088			nodes = [],
5089			i = 0,
5090			l = elems.length;
5091
5092		for ( ; i < l; i++ ) {
5093			elem = elems[ i ];
5094
5095			if ( elem || elem === 0 ) {
5096
5097				// Add nodes directly
5098				if ( jQuery.type( elem ) === "object" ) {
5099					// Support: QtWebKit, PhantomJS
5100					// push.apply(_, arraylike) throws on ancient WebKit
5101					jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
5102
5103				// Convert non-html into a text node
5104				} else if ( !rhtml.test( elem ) ) {
5105					nodes.push( context.createTextNode( elem ) );
5106
5107				// Convert html into DOM nodes
5108				} else {
5109					tmp = tmp || fragment.appendChild( context.createElement("div") );
5110
5111					// Deserialize a standard representation
5112					tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
5113					wrap = wrapMap[ tag ] || wrapMap._default;
5114					tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[ 2 ];
5115
5116					// Descend through wrappers to the right content
5117					j = wrap[ 0 ];
5118					while ( j-- ) {
5119						tmp = tmp.lastChild;
5120					}
5121
5122					// Support: QtWebKit, PhantomJS
5123					// push.apply(_, arraylike) throws on ancient WebKit
5124					jQuery.merge( nodes, tmp.childNodes );
5125
5126					// Remember the top-level container
5127					tmp = fragment.firstChild;
5128
5129					// Ensure the created nodes are orphaned (#12392)
5130					tmp.textContent = "";
5131				}
5132			}
5133		}
5134
5135		// Remove wrapper from fragment
5136		fragment.textContent = "";
5137
5138		i = 0;
5139		while ( (elem = nodes[ i++ ]) ) {
5140
5141			// #4087 - If origin and destination elements are the same, and this is
5142			// that element, do not do anything
5143			if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
5144				continue;
5145			}
5146
5147			contains = jQuery.contains( elem.ownerDocument, elem );
5148
5149			// Append to fragment
5150			tmp = getAll( fragment.appendChild( elem ), "script" );
5151
5152			// Preserve script evaluation history
5153			if ( contains ) {
5154				setGlobalEval( tmp );
5155			}
5156
5157			// Capture executables
5158			if ( scripts ) {
5159				j = 0;
5160				while ( (elem = tmp[ j++ ]) ) {
5161					if ( rscriptType.test( elem.type || "" ) ) {
5162						scripts.push( elem );
5163					}
5164				}
5165			}
5166		}
5167
5168		return fragment;
5169	},
5170
5171	cleanData: function( elems ) {
5172		var data, elem, type, key,
5173			special = jQuery.event.special,
5174			i = 0;
5175
5176		for ( ; (elem = elems[ i ]) !== undefined; i++ ) {
5177			if ( jQuery.acceptData( elem ) ) {
5178				key = elem[ data_priv.expando ];
5179
5180				if ( key && (data = data_priv.cache[ key ]) ) {
5181					if ( data.events ) {
5182						for ( type in data.events ) {
5183							if ( special[ type ] ) {
5184								jQuery.event.remove( elem, type );
5185
5186							// This is a shortcut to avoid jQuery.event.remove's overhead
5187							} else {
5188								jQuery.removeEvent( elem, type, data.handle );
5189							}
5190						}
5191					}
5192					if ( data_priv.cache[ key ] ) {
5193						// Discard any remaining `private` data
5194						delete data_priv.cache[ key ];
5195					}
5196				}
5197			}
5198			// Discard any remaining `user` data
5199			delete data_user.cache[ elem[ data_user.expando ] ];
5200		}
5201	}
5202});
5203
5204jQuery.fn.extend({
5205	text: function( value ) {
5206		return access( this, function( value ) {
5207			return value === undefined ?
5208				jQuery.text( this ) :
5209				this.empty().each(function() {
5210					if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5211						this.textContent = value;
5212					}
5213				});
5214		}, null, value, arguments.length );
5215	},
5216
5217	append: function() {
5218		return this.domManip( arguments, function( elem ) {
5219			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5220				var target = manipulationTarget( this, elem );
5221				target.appendChild( elem );
5222			}
5223		});
5224	},
5225
5226	prepend: function() {
5227		return this.domManip( arguments, function( elem ) {
5228			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5229				var target = manipulationTarget( this, elem );
5230				target.insertBefore( elem, target.firstChild );
5231			}
5232		});
5233	},
5234
5235	before: function() {
5236		return this.domManip( arguments, function( elem ) {
5237			if ( this.parentNode ) {
5238				this.parentNode.insertBefore( elem, this );
5239			}
5240		});
5241	},
5242
5243	after: function() {
5244		return this.domManip( arguments, function( elem ) {
5245			if ( this.parentNode ) {
5246				this.parentNode.insertBefore( elem, this.nextSibling );
5247			}
5248		});
5249	},
5250
5251	remove: function( selector, keepData /* Internal Use Only */ ) {
5252		var elem,
5253			elems = selector ? jQuery.filter( selector, this ) : this,
5254			i = 0;
5255
5256		for ( ; (elem = elems[i]) != null; i++ ) {
5257			if ( !keepData && elem.nodeType === 1 ) {
5258				jQuery.cleanData( getAll( elem ) );
5259			}
5260
5261			if ( elem.parentNode ) {
5262				if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
5263					setGlobalEval( getAll( elem, "script" ) );
5264				}
5265				elem.parentNode.removeChild( elem );
5266			}
5267		}
5268
5269		return this;
5270	},
5271
5272	empty: function() {
5273		var elem,
5274			i = 0;
5275
5276		for ( ; (elem = this[i]) != null; i++ ) {
5277			if ( elem.nodeType === 1 ) {
5278
5279				// Prevent memory leaks
5280				jQuery.cleanData( getAll( elem, false ) );
5281
5282				// Remove any remaining nodes
5283				elem.textContent = "";
5284			}
5285		}
5286
5287		return this;
5288	},
5289
5290	clone: function( dataAndEvents, deepDataAndEvents ) {
5291		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5292		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5293
5294		return this.map(function() {
5295			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5296		});
5297	},
5298
5299	html: function( value ) {
5300		return access( this, function( value ) {
5301			var elem = this[ 0 ] || {},
5302				i = 0,
5303				l = this.length;
5304
5305			if ( value === undefined && elem.nodeType === 1 ) {
5306				return elem.innerHTML;
5307			}
5308
5309			// See if we can take a shortcut and just use innerHTML
5310			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
5311				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
5312
5313				value = value.replace( rxhtmlTag, "<$1></$2>" );
5314
5315				try {
5316					for ( ; i < l; i++ ) {
5317						elem = this[ i ] || {};
5318
5319						// Remove element nodes and prevent memory leaks
5320						if ( elem.nodeType === 1 ) {
5321							jQuery.cleanData( getAll( elem, false ) );
5322							elem.innerHTML = value;
5323						}
5324					}
5325
5326					elem = 0;
5327
5328				// If using innerHTML throws an exception, use the fallback method
5329				} catch( e ) {}
5330			}
5331
5332			if ( elem ) {
5333				this.empty().append( value );
5334			}
5335		}, null, value, arguments.length );
5336	},
5337
5338	replaceWith: function() {
5339		var arg = arguments[ 0 ];
5340
5341		// Make the changes, replacing each context element with the new content
5342		this.domManip( arguments, function( elem ) {
5343			arg = this.parentNode;
5344
5345			jQuery.cleanData( getAll( this ) );
5346
5347			if ( arg ) {
5348				arg.replaceChild( elem, this );
5349			}
5350		});
5351
5352		// Force removal if there was no new content (e.g., from empty arguments)
5353		return arg && (arg.length || arg.nodeType) ? this : this.remove();
5354	},
5355
5356	detach: function( selector ) {
5357		return this.remove( selector, true );
5358	},
5359
5360	domManip: function( args, callback ) {
5361
5362		// Flatten any nested arrays
5363		args = concat.apply( [], args );
5364
5365		var fragment, first, scripts, hasScripts, node, doc,
5366			i = 0,
5367			l = this.length,
5368			set = this,
5369			iNoClone = l - 1,
5370			value = args[ 0 ],
5371			isFunction = jQuery.isFunction( value );
5372
5373		// We can't cloneNode fragments that contain checked, in WebKit
5374		if ( isFunction ||
5375				( l > 1 && typeof value === "string" &&
5376					!support.checkClone && rchecked.test( value ) ) ) {
5377			return this.each(function( index ) {
5378				var self = set.eq( index );
5379				if ( isFunction ) {
5380					args[ 0 ] = value.call( this, index, self.html() );
5381				}
5382				self.domManip( args, callback );
5383			});
5384		}
5385
5386		if ( l ) {
5387			fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );
5388			first = fragment.firstChild;
5389
5390			if ( fragment.childNodes.length === 1 ) {
5391				fragment = first;
5392			}
5393
5394			if ( first ) {
5395				scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
5396				hasScripts = scripts.length;
5397
5398				// Use the original fragment for the last item instead of the first because it can end up
5399				// being emptied incorrectly in certain situations (#8070).
5400				for ( ; i < l; i++ ) {
5401					node = fragment;
5402
5403					if ( i !== iNoClone ) {
5404						node = jQuery.clone( node, true, true );
5405
5406						// Keep references to cloned scripts for later restoration
5407						if ( hasScripts ) {
5408							// Support: QtWebKit
5409							// jQuery.merge because push.apply(_, arraylike) throws
5410							jQuery.merge( scripts, getAll( node, "script" ) );
5411						}
5412					}
5413
5414					callback.call( this[ i ], node, i );
5415				}
5416
5417				if ( hasScripts ) {
5418					doc = scripts[ scripts.length - 1 ].ownerDocument;
5419
5420					// Reenable scripts
5421					jQuery.map( scripts, restoreScript );
5422
5423					// Evaluate executable scripts on first document insertion
5424					for ( i = 0; i < hasScripts; i++ ) {
5425						node = scripts[ i ];
5426						if ( rscriptType.test( node.type || "" ) &&
5427							!data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
5428
5429							if ( node.src ) {
5430								// Optional AJAX dependency, but won't run scripts if not present
5431								if ( jQuery._evalUrl ) {
5432									jQuery._evalUrl( node.src );
5433								}
5434							} else {
5435								jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) );
5436							}
5437						}
5438					}
5439				}
5440			}
5441		}
5442
5443		return this;
5444	}
5445});
5446
5447jQuery.each({
5448	appendTo: "append",
5449	prependTo: "prepend",
5450	insertBefore: "before",
5451	insertAfter: "after",
5452	replaceAll: "replaceWith"
5453}, function( name, original ) {
5454	jQuery.fn[ name ] = function( selector ) {
5455		var elems,
5456			ret = [],
5457			insert = jQuery( selector ),
5458			last = insert.length - 1,
5459			i = 0;
5460
5461		for ( ; i <= last; i++ ) {
5462			elems = i === last ? this : this.clone( true );
5463			jQuery( insert[ i ] )[ original ]( elems );
5464
5465			// Support: QtWebKit
5466			// .get() because push.apply(_, arraylike) throws
5467			push.apply( ret, elems.get() );
5468		}
5469
5470		return this.pushStack( ret );
5471	};
5472});
5473
5474
5475var iframe,
5476	elemdisplay = {};
5477
5478/**
5479 * Retrieve the actual display of a element
5480 * @param {String} name nodeName of the element
5481 * @param {Object} doc Document object
5482 */
5483// Called only from within defaultDisplay
5484function actualDisplay( name, doc ) {
5485	var style,
5486		elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
5487
5488		// getDefaultComputedStyle might be reliably used only on attached element
5489		display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?
5490
5491			// Use of this method is a temporary fix (more like optimization) until something better comes along,
5492			// since it was removed from specification and supported only in FF
5493			style.display : jQuery.css( elem[ 0 ], "display" );
5494
5495	// We don't have any data stored on the element,
5496	// so use "detach" method as fast way to get rid of the element
5497	elem.detach();
5498
5499	return display;
5500}
5501
5502/**
5503 * Try to determine the default display value of an element
5504 * @param {String} nodeName
5505 */
5506function defaultDisplay( nodeName ) {
5507	var doc = document,
5508		display = elemdisplay[ nodeName ];
5509
5510	if ( !display ) {
5511		display = actualDisplay( nodeName, doc );
5512
5513		// If the simple way fails, read from inside an iframe
5514		if ( display === "none" || !display ) {
5515
5516			// Use the already-created iframe if possible
5517			iframe = (iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" )).appendTo( doc.documentElement );
5518
5519			// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
5520			doc = iframe[ 0 ].contentDocument;
5521
5522			// Support: IE
5523			doc.write();
5524			doc.close();
5525
5526			display = actualDisplay( nodeName, doc );
5527			iframe.detach();
5528		}
5529
5530		// Store the correct default display
5531		elemdisplay[ nodeName ] = display;
5532	}
5533
5534	return display;
5535}
5536var rmargin = (/^margin/);
5537
5538var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
5539
5540var getStyles = function( elem ) {
5541		// Support: IE<=11+, Firefox<=30+ (#15098, #14150)
5542		// IE throws on elements created in popups
5543		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
5544		if ( elem.ownerDocument.defaultView.opener ) {
5545			return elem.ownerDocument.defaultView.getComputedStyle( elem, null );
5546		}
5547
5548		return window.getComputedStyle( elem, null );
5549	};
5550
5551
5552
5553function curCSS( elem, name, computed ) {
5554	var width, minWidth, maxWidth, ret,
5555		style = elem.style;
5556
5557	computed = computed || getStyles( elem );
5558
5559	// Support: IE9
5560	// getPropertyValue is only needed for .css('filter') (#12537)
5561	if ( computed ) {
5562		ret = computed.getPropertyValue( name ) || computed[ name ];
5563	}
5564
5565	if ( computed ) {
5566
5567		if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
5568			ret = jQuery.style( elem, name );
5569		}
5570
5571		// Support: iOS < 6
5572		// A tribute to the "awesome hack by Dean Edwards"
5573		// iOS < 6 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
5574		// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
5575		if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
5576
5577			// Remember the original values
5578			width = style.width;
5579			minWidth = style.minWidth;
5580			maxWidth = style.maxWidth;
5581
5582			// Put in the new values to get a computed value out
5583			style.minWidth = style.maxWidth = style.width = ret;
5584			ret = computed.width;
5585
5586			// Revert the changed values
5587			style.width = width;
5588			style.minWidth = minWidth;
5589			style.maxWidth = maxWidth;
5590		}
5591	}
5592
5593	return ret !== undefined ?
5594		// Support: IE
5595		// IE returns zIndex value as an integer.
5596		ret + "" :
5597		ret;
5598}
5599
5600
5601function addGetHookIf( conditionFn, hookFn ) {
5602	// Define the hook, we'll check on the first run if it's really needed.
5603	return {
5604		get: function() {
5605			if ( conditionFn() ) {
5606				// Hook not needed (or it's not possible to use it due
5607				// to missing dependency), remove it.
5608				delete this.get;
5609				return;
5610			}
5611
5612			// Hook needed; redefine it so that the support test is not executed again.
5613			return (this.get = hookFn).apply( this, arguments );
5614		}
5615	};
5616}
5617
5618
5619(function() {
5620	var pixelPositionVal, boxSizingReliableVal,
5621		docElem = document.documentElement,
5622		container = document.createElement( "div" ),
5623		div = document.createElement( "div" );
5624
5625	if ( !div.style ) {
5626		return;
5627	}
5628
5629	// Support: IE9-11+
5630	// Style of cloned element affects source element cloned (#8908)
5631	div.style.backgroundClip = "content-box";
5632	div.cloneNode( true ).style.backgroundClip = "";
5633	support.clearCloneStyle = div.style.backgroundClip === "content-box";
5634
5635	container.style.cssText = "border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;" +
5636		"position:absolute";
5637	container.appendChild( div );
5638
5639	// Executing both pixelPosition & boxSizingReliable tests require only one layout
5640	// so they're executed at the same time to save the second computation.
5641	function computePixelPositionAndBoxSizingReliable() {
5642		div.style.cssText =
5643			// Support: Firefox<29, Android 2.3
5644			// Vendor-prefix box-sizing
5645			"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;" +
5646			"box-sizing:border-box;display:block;margin-top:1%;top:1%;" +
5647			"border:1px;padding:1px;width:4px;position:absolute";
5648		div.innerHTML = "";
5649		docElem.appendChild( container );
5650
5651		var divStyle = window.getComputedStyle( div, null );
5652		pixelPositionVal = divStyle.top !== "1%";
5653		boxSizingReliableVal = divStyle.width === "4px";
5654
5655		docElem.removeChild( container );
5656	}
5657
5658	// Support: node.js jsdom
5659	// Don't assume that getComputedStyle is a property of the global object
5660	if ( window.getComputedStyle ) {
5661		jQuery.extend( support, {
5662			pixelPosition: function() {
5663
5664				// This test is executed only once but we still do memoizing
5665				// since we can use the boxSizingReliable pre-computing.
5666				// No need to check if the test was already performed, though.
5667				computePixelPositionAndBoxSizingReliable();
5668				return pixelPositionVal;
5669			},
5670			boxSizingReliable: function() {
5671				if ( boxSizingReliableVal == null ) {
5672					computePixelPositionAndBoxSizingReliable();
5673				}
5674				return boxSizingReliableVal;
5675			},
5676			reliableMarginRight: function() {
5677
5678				// Support: Android 2.3
5679				// Check if div with explicit width and no margin-right incorrectly
5680				// gets computed margin-right based on width of container. (#3333)
5681				// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
5682				// This support function is only executed once so no memoizing is needed.
5683				var ret,
5684					marginDiv = div.appendChild( document.createElement( "div" ) );
5685
5686				// Reset CSS: box-sizing; display; margin; border; padding
5687				marginDiv.style.cssText = div.style.cssText =
5688					// Support: Firefox<29, Android 2.3
5689					// Vendor-prefix box-sizing
5690					"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
5691					"box-sizing:content-box;display:block;margin:0;border:0;padding:0";
5692				marginDiv.style.marginRight = marginDiv.style.width = "0";
5693				div.style.width = "1px";
5694				docElem.appendChild( container );
5695
5696				ret = !parseFloat( window.getComputedStyle( marginDiv, null ).marginRight );
5697
5698				docElem.removeChild( container );
5699				div.removeChild( marginDiv );
5700
5701				return ret;
5702			}
5703		});
5704	}
5705})();
5706
5707
5708// A method for quickly swapping in/out CSS properties to get correct calculations.
5709jQuery.swap = function( elem, options, callback, args ) {
5710	var ret, name,
5711		old = {};
5712
5713	// Remember the old values, and insert the new ones
5714	for ( name in options ) {
5715		old[ name ] = elem.style[ name ];
5716		elem.style[ name ] = options[ name ];
5717	}
5718
5719	ret = callback.apply( elem, args || [] );
5720
5721	// Revert the old values
5722	for ( name in options ) {
5723		elem.style[ name ] = old[ name ];
5724	}
5725
5726	return ret;
5727};
5728
5729
5730var
5731	// Swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
5732	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
5733	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
5734	rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
5735	rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ),
5736
5737	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
5738	cssNormalTransform = {
5739		letterSpacing: "0",
5740		fontWeight: "400"
5741	},
5742
5743	cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
5744
5745// Return a css property mapped to a potentially vendor prefixed property
5746function vendorPropName( style, name ) {
5747
5748	// Shortcut for names that are not vendor prefixed
5749	if ( name in style ) {
5750		return name;
5751	}
5752
5753	// Check for vendor prefixed names
5754	var capName = name[0].toUpperCase() + name.slice(1),
5755		origName = name,
5756		i = cssPrefixes.length;
5757
5758	while ( i-- ) {
5759		name = cssPrefixes[ i ] + capName;
5760		if ( name in style ) {
5761			return name;
5762		}
5763	}
5764
5765	return origName;
5766}
5767
5768function setPositiveNumber( elem, value, subtract ) {
5769	var matches = rnumsplit.exec( value );
5770	return matches ?
5771		// Guard against undefined "subtract", e.g., when used as in cssHooks
5772		Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
5773		value;
5774}
5775
5776function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
5777	var i = extra === ( isBorderBox ? "border" : "content" ) ?
5778		// If we already have the right measurement, avoid augmentation
5779		4 :
5780		// Otherwise initialize for horizontal or vertical properties
5781		name === "width" ? 1 : 0,
5782
5783		val = 0;
5784
5785	for ( ; i < 4; i += 2 ) {
5786		// Both box models exclude margin, so add it if we want it
5787		if ( extra === "margin" ) {
5788			val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
5789		}
5790
5791		if ( isBorderBox ) {
5792			// border-box includes padding, so remove it if we want content
5793			if ( extra === "content" ) {
5794				val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
5795			}
5796
5797			// At this point, extra isn't border nor margin, so remove border
5798			if ( extra !== "margin" ) {
5799				val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
5800			}
5801		} else {
5802			// At this point, extra isn't content, so add padding
5803			val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
5804
5805			// At this point, extra isn't content nor padding, so add border
5806			if ( extra !== "padding" ) {
5807				val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
5808			}
5809		}
5810	}
5811
5812	return val;
5813}
5814
5815function getWidthOrHeight( elem, name, extra ) {
5816
5817	// Start with offset property, which is equivalent to the border-box value
5818	var valueIsBorderBox = true,
5819		val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
5820		styles = getStyles( elem ),
5821		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
5822
5823	// Some non-html elements return undefined for offsetWidth, so check for null/undefined
5824	// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
5825	// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
5826	if ( val <= 0 || val == null ) {
5827		// Fall back to computed then uncomputed css if necessary
5828		val = curCSS( elem, name, styles );
5829		if ( val < 0 || val == null ) {
5830			val = elem.style[ name ];
5831		}
5832
5833		// Computed unit is not pixels. Stop here and return.
5834		if ( rnumnonpx.test(val) ) {
5835			return val;
5836		}
5837
5838		// Check for style in case a browser which returns unreliable values
5839		// for getComputedStyle silently falls back to the reliable elem.style
5840		valueIsBorderBox = isBorderBox &&
5841			( support.boxSizingReliable() || val === elem.style[ name ] );
5842
5843		// Normalize "", auto, and prepare for extra
5844		val = parseFloat( val ) || 0;
5845	}
5846
5847	// Use the active box-sizing model to add/subtract irrelevant styles
5848	return ( val +
5849		augmentWidthOrHeight(
5850			elem,
5851			name,
5852			extra || ( isBorderBox ? "border" : "content" ),
5853			valueIsBorderBox,
5854			styles
5855		)
5856	) + "px";
5857}
5858
5859function showHide( elements, show ) {
5860	var display, elem, hidden,
5861		values = [],
5862		index = 0,
5863		length = elements.length;
5864
5865	for ( ; index < length; index++ ) {
5866		elem = elements[ index ];
5867		if ( !elem.style ) {
5868			continue;
5869		}
5870
5871		values[ index ] = data_priv.get( elem, "olddisplay" );
5872		display = elem.style.display;
5873		if ( show ) {
5874			// Reset the inline display of this element to learn if it is
5875			// being hidden by cascaded rules or not
5876			if ( !values[ index ] && display === "none" ) {
5877				elem.style.display = "";
5878			}
5879
5880			// Set elements which have been overridden with display: none
5881			// in a stylesheet to whatever the default browser style is
5882			// for such an element
5883			if ( elem.style.display === "" && isHidden( elem ) ) {
5884				values[ index ] = data_priv.access( elem, "olddisplay", defaultDisplay(elem.nodeName) );
5885			}
5886		} else {
5887			hidden = isHidden( elem );
5888
5889			if ( display !== "none" || !hidden ) {
5890				data_priv.set( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
5891			}
5892		}
5893	}
5894
5895	// Set the display of most of the elements in a second loop
5896	// to avoid the constant reflow
5897	for ( index = 0; index < length; index++ ) {
5898		elem = elements[ index ];
5899		if ( !elem.style ) {
5900			continue;
5901		}
5902		if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
5903			elem.style.display = show ? values[ index ] || "" : "none";
5904		}
5905	}
5906
5907	return elements;
5908}
5909
5910jQuery.extend({
5911
5912	// Add in style property hooks for overriding the default
5913	// behavior of getting and setting a style property
5914	cssHooks: {
5915		opacity: {
5916			get: function( elem, computed ) {
5917				if ( computed ) {
5918
5919					// We should always get a number back from opacity
5920					var ret = curCSS( elem, "opacity" );
5921					return ret === "" ? "1" : ret;
5922				}
5923			}
5924		}
5925	},
5926
5927	// Don't automatically add "px" to these possibly-unitless properties
5928	cssNumber: {
5929		"columnCount": true,
5930		"fillOpacity": true,
5931		"flexGrow": true,
5932		"flexShrink": true,
5933		"fontWeight": true,
5934		"lineHeight": true,
5935		"opacity": true,
5936		"order": true,
5937		"orphans": true,
5938		"widows": true,
5939		"zIndex": true,
5940		"zoom": true
5941	},
5942
5943	// Add in properties whose names you wish to fix before
5944	// setting or getting the value
5945	cssProps: {
5946		"float": "cssFloat"
5947	},
5948
5949	// Get and set the style property on a DOM Node
5950	style: function( elem, name, value, extra ) {
5951
5952		// Don't set styles on text and comment nodes
5953		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
5954			return;
5955		}
5956
5957		// Make sure that we're working with the right name
5958		var ret, type, hooks,
5959			origName = jQuery.camelCase( name ),
5960			style = elem.style;
5961
5962		name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
5963
5964		// Gets hook for the prefixed version, then unprefixed version
5965		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
5966
5967		// Check if we're setting a value
5968		if ( value !== undefined ) {
5969			type = typeof value;
5970
5971			// Convert "+=" or "-=" to relative numbers (#7345)
5972			if ( type === "string" && (ret = rrelNum.exec( value )) ) {
5973				value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
5974				// Fixes bug #9237
5975				type = "number";
5976			}
5977
5978			// Make sure that null and NaN values aren't set (#7116)
5979			if ( value == null || value !== value ) {
5980				return;
5981			}
5982
5983			// If a number, add 'px' to the (except for certain CSS properties)
5984			if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
5985				value += "px";
5986			}
5987
5988			// Support: IE9-11+
5989			// background-* props affect original clone's values
5990			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
5991				style[ name ] = "inherit";
5992			}
5993
5994			// If a hook was provided, use that value, otherwise just set the specified value
5995			if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
5996				style[ name ] = value;
5997			}
5998
5999		} else {
6000			// If a hook was provided get the non-computed value from there
6001			if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6002				return ret;
6003			}
6004
6005			// Otherwise just get the value from the style object
6006			return style[ name ];
6007		}
6008	},
6009
6010	css: function( elem, name, extra, styles ) {
6011		var val, num, hooks,
6012			origName = jQuery.camelCase( name );
6013
6014		// Make sure that we're working with the right name
6015		name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
6016
6017		// Try prefixed name followed by the unprefixed name
6018		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6019
6020		// If a hook was provided get the computed value from there
6021		if ( hooks && "get" in hooks ) {
6022			val = hooks.get( elem, true, extra );
6023		}
6024
6025		// Otherwise, if a way to get the computed value exists, use that
6026		if ( val === undefined ) {
6027			val = curCSS( elem, name, styles );
6028		}
6029
6030		// Convert "normal" to computed value
6031		if ( val === "normal" && name in cssNormalTransform ) {
6032			val = cssNormalTransform[ name ];
6033		}
6034
6035		// Make numeric if forced or a qualifier was provided and val looks numeric
6036		if ( extra === "" || extra ) {
6037			num = parseFloat( val );
6038			return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
6039		}
6040		return val;
6041	}
6042});
6043
6044jQuery.each([ "height", "width" ], function( i, name ) {
6045	jQuery.cssHooks[ name ] = {
6046		get: function( elem, computed, extra ) {
6047			if ( computed ) {
6048
6049				// Certain elements can have dimension info if we invisibly show them
6050				// but it must have a current display style that would benefit
6051				return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ?
6052					jQuery.swap( elem, cssShow, function() {
6053						return getWidthOrHeight( elem, name, extra );
6054					}) :
6055					getWidthOrHeight( elem, name, extra );
6056			}
6057		},
6058
6059		set: function( elem, value, extra ) {
6060			var styles = extra && getStyles( elem );
6061			return setPositiveNumber( elem, value, extra ?
6062				augmentWidthOrHeight(
6063					elem,
6064					name,
6065					extra,
6066					jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
6067					styles
6068				) : 0
6069			);
6070		}
6071	};
6072});
6073
6074// Support: Android 2.3
6075jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
6076	function( elem, computed ) {
6077		if ( computed ) {
6078			return jQuery.swap( elem, { "display": "inline-block" },
6079				curCSS, [ elem, "marginRight" ] );
6080		}
6081	}
6082);
6083
6084// These hooks are used by animate to expand properties
6085jQuery.each({
6086	margin: "",
6087	padding: "",
6088	border: "Width"
6089}, function( prefix, suffix ) {
6090	jQuery.cssHooks[ prefix + suffix ] = {
6091		expand: function( value ) {
6092			var i = 0,
6093				expanded = {},
6094
6095				// Assumes a single number if not a string
6096				parts = typeof value === "string" ? value.split(" ") : [ value ];
6097
6098			for ( ; i < 4; i++ ) {
6099				expanded[ prefix + cssExpand[ i ] + suffix ] =
6100					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
6101			}
6102
6103			return expanded;
6104		}
6105	};
6106
6107	if ( !rmargin.test( prefix ) ) {
6108		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
6109	}
6110});
6111
6112jQuery.fn.extend({
6113	css: function( name, value ) {
6114		return access( this, function( elem, name, value ) {
6115			var styles, len,
6116				map = {},
6117				i = 0;
6118
6119			if ( jQuery.isArray( name ) ) {
6120				styles = getStyles( elem );
6121				len = name.length;
6122
6123				for ( ; i < len; i++ ) {
6124					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
6125				}
6126
6127				return map;
6128			}
6129
6130			return value !== undefined ?
6131				jQuery.style( elem, name, value ) :
6132				jQuery.css( elem, name );
6133		}, name, value, arguments.length > 1 );
6134	},
6135	show: function() {
6136		return showHide( this, true );
6137	},
6138	hide: function() {
6139		return showHide( this );
6140	},
6141	toggle: function( state ) {
6142		if ( typeof state === "boolean" ) {
6143			return state ? this.show() : this.hide();
6144		}
6145
6146		return this.each(function() {
6147			if ( isHidden( this ) ) {
6148				jQuery( this ).show();
6149			} else {
6150				jQuery( this ).hide();
6151			}
6152		});
6153	}
6154});
6155
6156
6157function Tween( elem, options, prop, end, easing ) {
6158	return new Tween.prototype.init( elem, options, prop, end, easing );
6159}
6160jQuery.Tween = Tween;
6161
6162Tween.prototype = {
6163	constructor: Tween,
6164	init: function( elem, options, prop, end, easing, unit ) {
6165		this.elem = elem;
6166		this.prop = prop;
6167		this.easing = easing || "swing";
6168		this.options = options;
6169		this.start = this.now = this.cur();
6170		this.end = end;
6171		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
6172	},
6173	cur: function() {
6174		var hooks = Tween.propHooks[ this.prop ];
6175
6176		return hooks && hooks.get ?
6177			hooks.get( this ) :
6178			Tween.propHooks._default.get( this );
6179	},
6180	run: function( percent ) {
6181		var eased,
6182			hooks = Tween.propHooks[ this.prop ];
6183
6184		if ( this.options.duration ) {
6185			this.pos = eased = jQuery.easing[ this.easing ](
6186				percent, this.options.duration * percent, 0, 1, this.options.duration
6187			);
6188		} else {
6189			this.pos = eased = percent;
6190		}
6191		this.now = ( this.end - this.start ) * eased + this.start;
6192
6193		if ( this.options.step ) {
6194			this.options.step.call( this.elem, this.now, this );
6195		}
6196
6197		if ( hooks && hooks.set ) {
6198			hooks.set( this );
6199		} else {
6200			Tween.propHooks._default.set( this );
6201		}
6202		return this;
6203	}
6204};
6205
6206Tween.prototype.init.prototype = Tween.prototype;
6207
6208Tween.propHooks = {
6209	_default: {
6210		get: function( tween ) {
6211			var result;
6212
6213			if ( tween.elem[ tween.prop ] != null &&
6214				(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
6215				return tween.elem[ tween.prop ];
6216			}
6217
6218			// Passing an empty string as a 3rd parameter to .css will automatically
6219			// attempt a parseFloat and fallback to a string if the parse fails.
6220			// Simple values such as "10px" are parsed to Float;
6221			// complex values such as "rotate(1rad)" are returned as-is.
6222			result = jQuery.css( tween.elem, tween.prop, "" );
6223			// Empty strings, null, undefined and "auto" are converted to 0.
6224			return !result || result === "auto" ? 0 : result;
6225		},
6226		set: function( tween ) {
6227			// Use step hook for back compat.
6228			// Use cssHook if its there.
6229			// Use .style if available and use plain properties where available.
6230			if ( jQuery.fx.step[ tween.prop ] ) {
6231				jQuery.fx.step[ tween.prop ]( tween );
6232			} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
6233				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
6234			} else {
6235				tween.elem[ tween.prop ] = tween.now;
6236			}
6237		}
6238	}
6239};
6240
6241// Support: IE9
6242// Panic based approach to setting things on disconnected nodes
6243Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
6244	set: function( tween ) {
6245		if ( tween.elem.nodeType && tween.elem.parentNode ) {
6246			tween.elem[ tween.prop ] = tween.now;
6247		}
6248	}
6249};
6250
6251jQuery.easing = {
6252	linear: function( p ) {
6253		return p;
6254	},
6255	swing: function( p ) {
6256		return 0.5 - Math.cos( p * Math.PI ) / 2;
6257	}
6258};
6259
6260jQuery.fx = Tween.prototype.init;
6261
6262// Back Compat <1.8 extension point
6263jQuery.fx.step = {};
6264
6265
6266
6267
6268var
6269	fxNow, timerId,
6270	rfxtypes = /^(?:toggle|show|hide)$/,
6271	rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ),
6272	rrun = /queueHooks$/,
6273	animationPrefilters = [ defaultPrefilter ],
6274	tweeners = {
6275		"*": [ function( prop, value ) {
6276			var tween = this.createTween( prop, value ),
6277				target = tween.cur(),
6278				parts = rfxnum.exec( value ),
6279				unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
6280
6281				// Starting value computation is required for potential unit mismatches
6282				start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
6283					rfxnum.exec( jQuery.css( tween.elem, prop ) ),
6284				scale = 1,
6285				maxIterations = 20;
6286
6287			if ( start && start[ 3 ] !== unit ) {
6288				// Trust units reported by jQuery.css
6289				unit = unit || start[ 3 ];
6290
6291				// Make sure we update the tween properties later on
6292				parts = parts || [];
6293
6294				// Iteratively approximate from a nonzero starting point
6295				start = +target || 1;
6296
6297				do {
6298					// If previous iteration zeroed out, double until we get *something*.
6299					// Use string for doubling so we don't accidentally see scale as unchanged below
6300					scale = scale || ".5";
6301
6302					// Adjust and apply
6303					start = start / scale;
6304					jQuery.style( tween.elem, prop, start + unit );
6305
6306				// Update scale, tolerating zero or NaN from tween.cur(),
6307				// break the loop if scale is unchanged or perfect, or if we've just had enough
6308				} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
6309			}
6310
6311			// Update tween properties
6312			if ( parts ) {
6313				start = tween.start = +start || +target || 0;
6314				tween.unit = unit;
6315				// If a +=/-= token was provided, we're doing a relative animation
6316				tween.end = parts[ 1 ] ?
6317					start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
6318					+parts[ 2 ];
6319			}
6320
6321			return tween;
6322		} ]
6323	};
6324
6325// Animations created synchronously will run synchronously
6326function createFxNow() {
6327	setTimeout(function() {
6328		fxNow = undefined;
6329	});
6330	return ( fxNow = jQuery.now() );
6331}
6332
6333// Generate parameters to create a standard animation
6334function genFx( type, includeWidth ) {
6335	var which,
6336		i = 0,
6337		attrs = { height: type };
6338
6339	// If we include width, step value is 1 to do all cssExpand values,
6340	// otherwise step value is 2 to skip over Left and Right
6341	includeWidth = includeWidth ? 1 : 0;
6342	for ( ; i < 4 ; i += 2 - includeWidth ) {
6343		which = cssExpand[ i ];
6344		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
6345	}
6346
6347	if ( includeWidth ) {
6348		attrs.opacity = attrs.width = type;
6349	}
6350
6351	return attrs;
6352}
6353
6354function createTween( value, prop, animation ) {
6355	var tween,
6356		collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
6357		index = 0,
6358		length = collection.length;
6359	for ( ; index < length; index++ ) {
6360		if ( (tween = collection[ index ].call( animation, prop, value )) ) {
6361
6362			// We're done with this property
6363			return tween;
6364		}
6365	}
6366}
6367
6368function defaultPrefilter( elem, props, opts ) {
6369	/* jshint validthis: true */
6370	var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
6371		anim = this,
6372		orig = {},
6373		style = elem.style,
6374		hidden = elem.nodeType && isHidden( elem ),
6375		dataShow = data_priv.get( elem, "fxshow" );
6376
6377	// Handle queue: false promises
6378	if ( !opts.queue ) {
6379		hooks = jQuery._queueHooks( elem, "fx" );
6380		if ( hooks.unqueued == null ) {
6381			hooks.unqueued = 0;
6382			oldfire = hooks.empty.fire;
6383			hooks.empty.fire = function() {
6384				if ( !hooks.unqueued ) {
6385					oldfire();
6386				}
6387			};
6388		}
6389		hooks.unqueued++;
6390
6391		anim.always(function() {
6392			// Ensure the complete handler is called before this completes
6393			anim.always(function() {
6394				hooks.unqueued--;
6395				if ( !jQuery.queue( elem, "fx" ).length ) {
6396					hooks.empty.fire();
6397				}
6398			});
6399		});
6400	}
6401
6402	// Height/width overflow pass
6403	if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
6404		// Make sure that nothing sneaks out
6405		// Record all 3 overflow attributes because IE9-10 do not
6406		// change the overflow attribute when overflowX and
6407		// overflowY are set to the same value
6408		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
6409
6410		// Set display property to inline-block for height/width
6411		// animations on inline elements that are having width/height animated
6412		display = jQuery.css( elem, "display" );
6413
6414		// Test default display if display is currently "none"
6415		checkDisplay = display === "none" ?
6416			data_priv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
6417
6418		if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
6419			style.display = "inline-block";
6420		}
6421	}
6422
6423	if ( opts.overflow ) {
6424		style.overflow = "hidden";
6425		anim.always(function() {
6426			style.overflow = opts.overflow[ 0 ];
6427			style.overflowX = opts.overflow[ 1 ];
6428			style.overflowY = opts.overflow[ 2 ];
6429		});
6430	}
6431
6432	// show/hide pass
6433	for ( prop in props ) {
6434		value = props[ prop ];
6435		if ( rfxtypes.exec( value ) ) {
6436			delete props[ prop ];
6437			toggle = toggle || value === "toggle";
6438			if ( value === ( hidden ? "hide" : "show" ) ) {
6439
6440				// If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden
6441				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
6442					hidden = true;
6443				} else {
6444					continue;
6445				}
6446			}
6447			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
6448
6449		// Any non-fx value stops us from restoring the original display value
6450		} else {
6451			display = undefined;
6452		}
6453	}
6454
6455	if ( !jQuery.isEmptyObject( orig ) ) {
6456		if ( dataShow ) {
6457			if ( "hidden" in dataShow ) {
6458				hidden = dataShow.hidden;
6459			}
6460		} else {
6461			dataShow = data_priv.access( elem, "fxshow", {} );
6462		}
6463
6464		// Store state if its toggle - enables .stop().toggle() to "reverse"
6465		if ( toggle ) {
6466			dataShow.hidden = !hidden;
6467		}
6468		if ( hidden ) {
6469			jQuery( elem ).show();
6470		} else {
6471			anim.done(function() {
6472				jQuery( elem ).hide();
6473			});
6474		}
6475		anim.done(function() {
6476			var prop;
6477
6478			data_priv.remove( elem, "fxshow" );
6479			for ( prop in orig ) {
6480				jQuery.style( elem, prop, orig[ prop ] );
6481			}
6482		});
6483		for ( prop in orig ) {
6484			tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
6485
6486			if ( !( prop in dataShow ) ) {
6487				dataShow[ prop ] = tween.start;
6488				if ( hidden ) {
6489					tween.end = tween.start;
6490					tween.start = prop === "width" || prop === "height" ? 1 : 0;
6491				}
6492			}
6493		}
6494
6495	// If this is a noop like .hide().hide(), restore an overwritten display value
6496	} else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) {
6497		style.display = display;
6498	}
6499}
6500
6501function propFilter( props, specialEasing ) {
6502	var index, name, easing, value, hooks;
6503
6504	// camelCase, specialEasing and expand cssHook pass
6505	for ( index in props ) {
6506		name = jQuery.camelCase( index );
6507		easing = specialEasing[ name ];
6508		value = props[ index ];
6509		if ( jQuery.isArray( value ) ) {
6510			easing = value[ 1 ];
6511			value = props[ index ] = value[ 0 ];
6512		}
6513
6514		if ( index !== name ) {
6515			props[ name ] = value;
6516			delete props[ index ];
6517		}
6518
6519		hooks = jQuery.cssHooks[ name ];
6520		if ( hooks && "expand" in hooks ) {
6521			value = hooks.expand( value );
6522			delete props[ name ];
6523
6524			// Not quite $.extend, this won't overwrite existing keys.
6525			// Reusing 'index' because we have the correct "name"
6526			for ( index in value ) {
6527				if ( !( index in props ) ) {
6528					props[ index ] = value[ index ];
6529					specialEasing[ index ] = easing;
6530				}
6531			}
6532		} else {
6533			specialEasing[ name ] = easing;
6534		}
6535	}
6536}
6537
6538function Animation( elem, properties, options ) {
6539	var result,
6540		stopped,
6541		index = 0,
6542		length = animationPrefilters.length,
6543		deferred = jQuery.Deferred().always( function() {
6544			// Don't match elem in the :animated selector
6545			delete tick.elem;
6546		}),
6547		tick = function() {
6548			if ( stopped ) {
6549				return false;
6550			}
6551			var currentTime = fxNow || createFxNow(),
6552				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
6553				// Support: Android 2.3
6554				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
6555				temp = remaining / animation.duration || 0,
6556				percent = 1 - temp,
6557				index = 0,
6558				length = animation.tweens.length;
6559
6560			for ( ; index < length ; index++ ) {
6561				animation.tweens[ index ].run( percent );
6562			}
6563
6564			deferred.notifyWith( elem, [ animation, percent, remaining ]);
6565
6566			if ( percent < 1 && length ) {
6567				return remaining;
6568			} else {
6569				deferred.resolveWith( elem, [ animation ] );
6570				return false;
6571			}
6572		},
6573		animation = deferred.promise({
6574			elem: elem,
6575			props: jQuery.extend( {}, properties ),
6576			opts: jQuery.extend( true, { specialEasing: {} }, options ),
6577			originalProperties: properties,
6578			originalOptions: options,
6579			startTime: fxNow || createFxNow(),
6580			duration: options.duration,
6581			tweens: [],
6582			createTween: function( prop, end ) {
6583				var tween = jQuery.Tween( elem, animation.opts, prop, end,
6584						animation.opts.specialEasing[ prop ] || animation.opts.easing );
6585				animation.tweens.push( tween );
6586				return tween;
6587			},
6588			stop: function( gotoEnd ) {
6589				var index = 0,
6590					// If we are going to the end, we want to run all the tweens
6591					// otherwise we skip this part
6592					length = gotoEnd ? animation.tweens.length : 0;
6593				if ( stopped ) {
6594					return this;
6595				}
6596				stopped = true;
6597				for ( ; index < length ; index++ ) {
6598					animation.tweens[ index ].run( 1 );
6599				}
6600
6601				// Resolve when we played the last frame; otherwise, reject
6602				if ( gotoEnd ) {
6603					deferred.resolveWith( elem, [ animation, gotoEnd ] );
6604				} else {
6605					deferred.rejectWith( elem, [ animation, gotoEnd ] );
6606				}
6607				return this;
6608			}
6609		}),
6610		props = animation.props;
6611
6612	propFilter( props, animation.opts.specialEasing );
6613
6614	for ( ; index < length ; index++ ) {
6615		result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
6616		if ( result ) {
6617			return result;
6618		}
6619	}
6620
6621	jQuery.map( props, createTween, animation );
6622
6623	if ( jQuery.isFunction( animation.opts.start ) ) {
6624		animation.opts.start.call( elem, animation );
6625	}
6626
6627	jQuery.fx.timer(
6628		jQuery.extend( tick, {
6629			elem: elem,
6630			anim: animation,
6631			queue: animation.opts.queue
6632		})
6633	);
6634
6635	// attach callbacks from options
6636	return animation.progress( animation.opts.progress )
6637		.done( animation.opts.done, animation.opts.complete )
6638		.fail( animation.opts.fail )
6639		.always( animation.opts.always );
6640}
6641
6642jQuery.Animation = jQuery.extend( Animation, {
6643
6644	tweener: function( props, callback ) {
6645		if ( jQuery.isFunction( props ) ) {
6646			callback = props;
6647			props = [ "*" ];
6648		} else {
6649			props = props.split(" ");
6650		}
6651
6652		var prop,
6653			index = 0,
6654			length = props.length;
6655
6656		for ( ; index < length ; index++ ) {
6657			prop = props[ index ];
6658			tweeners[ prop ] = tweeners[ prop ] || [];
6659			tweeners[ prop ].unshift( callback );
6660		}
6661	},
6662
6663	prefilter: function( callback, prepend ) {
6664		if ( prepend ) {
6665			animationPrefilters.unshift( callback );
6666		} else {
6667			animationPrefilters.push( callback );
6668		}
6669	}
6670});
6671
6672jQuery.speed = function( speed, easing, fn ) {
6673	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
6674		complete: fn || !fn && easing ||
6675			jQuery.isFunction( speed ) && speed,
6676		duration: speed,
6677		easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
6678	};
6679
6680	opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
6681		opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
6682
6683	// Normalize opt.queue - true/undefined/null -> "fx"
6684	if ( opt.queue == null || opt.queue === true ) {
6685		opt.queue = "fx";
6686	}
6687
6688	// Queueing
6689	opt.old = opt.complete;
6690
6691	opt.complete = function() {
6692		if ( jQuery.isFunction( opt.old ) ) {
6693			opt.old.call( this );
6694		}
6695
6696		if ( opt.queue ) {
6697			jQuery.dequeue( this, opt.queue );
6698		}
6699	};
6700
6701	return opt;
6702};
6703
6704jQuery.fn.extend({
6705	fadeTo: function( speed, to, easing, callback ) {
6706
6707		// Show any hidden elements after setting opacity to 0
6708		return this.filter( isHidden ).css( "opacity", 0 ).show()
6709
6710			// Animate to the value specified
6711			.end().animate({ opacity: to }, speed, easing, callback );
6712	},
6713	animate: function( prop, speed, easing, callback ) {
6714		var empty = jQuery.isEmptyObject( prop ),
6715			optall = jQuery.speed( speed, easing, callback ),
6716			doAnimation = function() {
6717				// Operate on a copy of prop so per-property easing won't be lost
6718				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
6719
6720				// Empty animations, or finishing resolves immediately
6721				if ( empty || data_priv.get( this, "finish" ) ) {
6722					anim.stop( true );
6723				}
6724			};
6725			doAnimation.finish = doAnimation;
6726
6727		return empty || optall.queue === false ?
6728			this.each( doAnimation ) :
6729			this.queue( optall.queue, doAnimation );
6730	},
6731	stop: function( type, clearQueue, gotoEnd ) {
6732		var stopQueue = function( hooks ) {
6733			var stop = hooks.stop;
6734			delete hooks.stop;
6735			stop( gotoEnd );
6736		};
6737
6738		if ( typeof type !== "string" ) {
6739			gotoEnd = clearQueue;
6740			clearQueue = type;
6741			type = undefined;
6742		}
6743		if ( clearQueue && type !== false ) {
6744			this.queue( type || "fx", [] );
6745		}
6746
6747		return this.each(function() {
6748			var dequeue = true,
6749				index = type != null && type + "queueHooks",
6750				timers = jQuery.timers,
6751				data = data_priv.get( this );
6752
6753			if ( index ) {
6754				if ( data[ index ] && data[ index ].stop ) {
6755					stopQueue( data[ index ] );
6756				}
6757			} else {
6758				for ( index in data ) {
6759					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
6760						stopQueue( data[ index ] );
6761					}
6762				}
6763			}
6764
6765			for ( index = timers.length; index--; ) {
6766				if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
6767					timers[ index ].anim.stop( gotoEnd );
6768					dequeue = false;
6769					timers.splice( index, 1 );
6770				}
6771			}
6772
6773			// Start the next in the queue if the last step wasn't forced.
6774			// Timers currently will call their complete callbacks, which
6775			// will dequeue but only if they were gotoEnd.
6776			if ( dequeue || !gotoEnd ) {
6777				jQuery.dequeue( this, type );
6778			}
6779		});
6780	},
6781	finish: function( type ) {
6782		if ( type !== false ) {
6783			type = type || "fx";
6784		}
6785		return this.each(function() {
6786			var index,
6787				data = data_priv.get( this ),
6788				queue = data[ type + "queue" ],
6789				hooks = data[ type + "queueHooks" ],
6790				timers = jQuery.timers,
6791				length = queue ? queue.length : 0;
6792
6793			// Enable finishing flag on private data
6794			data.finish = true;
6795
6796			// Empty the queue first
6797			jQuery.queue( this, type, [] );
6798
6799			if ( hooks && hooks.stop ) {
6800				hooks.stop.call( this, true );
6801			}
6802
6803			// Look for any active animations, and finish them
6804			for ( index = timers.length; index--; ) {
6805				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
6806					timers[ index ].anim.stop( true );
6807					timers.splice( index, 1 );
6808				}
6809			}
6810
6811			// Look for any animations in the old queue and finish them
6812			for ( index = 0; index < length; index++ ) {
6813				if ( queue[ index ] && queue[ index ].finish ) {
6814					queue[ index ].finish.call( this );
6815				}
6816			}
6817
6818			// Turn off finishing flag
6819			delete data.finish;
6820		});
6821	}
6822});
6823
6824jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
6825	var cssFn = jQuery.fn[ name ];
6826	jQuery.fn[ name ] = function( speed, easing, callback ) {
6827		return speed == null || typeof speed === "boolean" ?
6828			cssFn.apply( this, arguments ) :
6829			this.animate( genFx( name, true ), speed, easing, callback );
6830	};
6831});
6832
6833// Generate shortcuts for custom animations
6834jQuery.each({
6835	slideDown: genFx("show"),
6836	slideUp: genFx("hide"),
6837	slideToggle: genFx("toggle"),
6838	fadeIn: { opacity: "show" },
6839	fadeOut: { opacity: "hide" },
6840	fadeToggle: { opacity: "toggle" }
6841}, function( name, props ) {
6842	jQuery.fn[ name ] = function( speed, easing, callback ) {
6843		return this.animate( props, speed, easing, callback );
6844	};
6845});
6846
6847jQuery.timers = [];
6848jQuery.fx.tick = function() {
6849	var timer,
6850		i = 0,
6851		timers = jQuery.timers;
6852
6853	fxNow = jQuery.now();
6854
6855	for ( ; i < timers.length; i++ ) {
6856		timer = timers[ i ];
6857		// Checks the timer has not already been removed
6858		if ( !timer() && timers[ i ] === timer ) {
6859			timers.splice( i--, 1 );
6860		}
6861	}
6862
6863	if ( !timers.length ) {
6864		jQuery.fx.stop();
6865	}
6866	fxNow = undefined;
6867};
6868
6869jQuery.fx.timer = function( timer ) {
6870	jQuery.timers.push( timer );
6871	if ( timer() ) {
6872		jQuery.fx.start();
6873	} else {
6874		jQuery.timers.pop();
6875	}
6876};
6877
6878jQuery.fx.interval = 13;
6879
6880jQuery.fx.start = function() {
6881	if ( !timerId ) {
6882		timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
6883	}
6884};
6885
6886jQuery.fx.stop = function() {
6887	clearInterval( timerId );
6888	timerId = null;
6889};
6890
6891jQuery.fx.speeds = {
6892	slow: 600,
6893	fast: 200,
6894	// Default speed
6895	_default: 400
6896};
6897
6898
6899// Based off of the plugin by Clint Helfers, with permission.
6900// http://blindsignals.com/index.php/2009/07/jquery-delay/
6901jQuery.fn.delay = function( time, type ) {
6902	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
6903	type = type || "fx";
6904
6905	return this.queue( type, function( next, hooks ) {
6906		var timeout = setTimeout( next, time );
6907		hooks.stop = function() {
6908			clearTimeout( timeout );
6909		};
6910	});
6911};
6912
6913
6914(function() {
6915	var input = document.createElement( "input" ),
6916		select = document.createElement( "select" ),
6917		opt = select.appendChild( document.createElement( "option" ) );
6918
6919	input.type = "checkbox";
6920
6921	// Support: iOS<=5.1, Android<=4.2+
6922	// Default value for a checkbox should be "on"
6923	support.checkOn = input.value !== "";
6924
6925	// Support: IE<=11+
6926	// Must access selectedIndex to make default options select
6927	support.optSelected = opt.selected;
6928
6929	// Support: Android<=2.3
6930	// Options inside disabled selects are incorrectly marked as disabled
6931	select.disabled = true;
6932	support.optDisabled = !opt.disabled;
6933
6934	// Support: IE<=11+
6935	// An input loses its value after becoming a radio
6936	input = document.createElement( "input" );
6937	input.value = "t";
6938	input.type = "radio";
6939	support.radioValue = input.value === "t";
6940})();
6941
6942
6943var nodeHook, boolHook,
6944	attrHandle = jQuery.expr.attrHandle;
6945
6946jQuery.fn.extend({
6947	attr: function( name, value ) {
6948		return access( this, jQuery.attr, name, value, arguments.length > 1 );
6949	},
6950
6951	removeAttr: function( name ) {
6952		return this.each(function() {
6953			jQuery.removeAttr( this, name );
6954		});
6955	}
6956});
6957
6958jQuery.extend({
6959	attr: function( elem, name, value ) {
6960		var hooks, ret,
6961			nType = elem.nodeType;
6962
6963		// don't get/set attributes on text, comment and attribute nodes
6964		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
6965			return;
6966		}
6967
6968		// Fallback to prop when attributes are not supported
6969		if ( typeof elem.getAttribute === strundefined ) {
6970			return jQuery.prop( elem, name, value );
6971		}
6972
6973		// All attributes are lowercase
6974		// Grab necessary hook if one is defined
6975		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
6976			name = name.toLowerCase();
6977			hooks = jQuery.attrHooks[ name ] ||
6978				( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
6979		}
6980
6981		if ( value !== undefined ) {
6982
6983			if ( value === null ) {
6984				jQuery.removeAttr( elem, name );
6985
6986			} else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
6987				return ret;
6988
6989			} else {
6990				elem.setAttribute( name, value + "" );
6991				return value;
6992			}
6993
6994		} else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
6995			return ret;
6996
6997		} else {
6998			ret = jQuery.find.attr( elem, name );
6999
7000			// Non-existent attributes return null, we normalize to undefined
7001			return ret == null ?
7002				undefined :
7003				ret;
7004		}
7005	},
7006
7007	removeAttr: function( elem, value ) {
7008		var name, propName,
7009			i = 0,
7010			attrNames = value && value.match( rnotwhite );
7011
7012		if ( attrNames && elem.nodeType === 1 ) {
7013			while ( (name = attrNames[i++]) ) {
7014				propName = jQuery.propFix[ name ] || name;
7015
7016				// Boolean attributes get special treatment (#10870)
7017				if ( jQuery.expr.match.bool.test( name ) ) {
7018					// Set corresponding property to false
7019					elem[ propName ] = false;
7020				}
7021
7022				elem.removeAttribute( name );
7023			}
7024		}
7025	},
7026
7027	attrHooks: {
7028		type: {
7029			set: function( elem, value ) {
7030				if ( !support.radioValue && value === "radio" &&
7031					jQuery.nodeName( elem, "input" ) ) {
7032					var val = elem.value;
7033					elem.setAttribute( "type", value );
7034					if ( val ) {
7035						elem.value = val;
7036					}
7037					return value;
7038				}
7039			}
7040		}
7041	}
7042});
7043
7044// Hooks for boolean attributes
7045boolHook = {
7046	set: function( elem, value, name ) {
7047		if ( value === false ) {
7048			// Remove boolean attributes when set to false
7049			jQuery.removeAttr( elem, name );
7050		} else {
7051			elem.setAttribute( name, name );
7052		}
7053		return name;
7054	}
7055};
7056jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
7057	var getter = attrHandle[ name ] || jQuery.find.attr;
7058
7059	attrHandle[ name ] = function( elem, name, isXML ) {
7060		var ret, handle;
7061		if ( !isXML ) {
7062			// Avoid an infinite loop by temporarily removing this function from the getter
7063			handle = attrHandle[ name ];
7064			attrHandle[ name ] = ret;
7065			ret = getter( elem, name, isXML ) != null ?
7066				name.toLowerCase() :
7067				null;
7068			attrHandle[ name ] = handle;
7069		}
7070		return ret;
7071	};
7072});
7073
7074
7075
7076
7077var rfocusable = /^(?:input|select|textarea|button)$/i;
7078
7079jQuery.fn.extend({
7080	prop: function( name, value ) {
7081		return access( this, jQuery.prop, name, value, arguments.length > 1 );
7082	},
7083
7084	removeProp: function( name ) {
7085		return this.each(function() {
7086			delete this[ jQuery.propFix[ name ] || name ];
7087		});
7088	}
7089});
7090
7091jQuery.extend({
7092	propFix: {
7093		"for": "htmlFor",
7094		"class": "className"
7095	},
7096
7097	prop: function( elem, name, value ) {
7098		var ret, hooks, notxml,
7099			nType = elem.nodeType;
7100
7101		// Don't get/set properties on text, comment and attribute nodes
7102		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
7103			return;
7104		}
7105
7106		notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
7107
7108		if ( notxml ) {
7109			// Fix name and attach hooks
7110			name = jQuery.propFix[ name ] || name;
7111			hooks = jQuery.propHooks[ name ];
7112		}
7113
7114		if ( value !== undefined ) {
7115			return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
7116				ret :
7117				( elem[ name ] = value );
7118
7119		} else {
7120			return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
7121				ret :
7122				elem[ name ];
7123		}
7124	},
7125
7126	propHooks: {
7127		tabIndex: {
7128			get: function( elem ) {
7129				return elem.hasAttribute( "tabindex" ) || rfocusable.test( elem.nodeName ) || elem.href ?
7130					elem.tabIndex :
7131					-1;
7132			}
7133		}
7134	}
7135});
7136
7137if ( !support.optSelected ) {
7138	jQuery.propHooks.selected = {
7139		get: function( elem ) {
7140			var parent = elem.parentNode;
7141			if ( parent && parent.parentNode ) {
7142				parent.parentNode.selectedIndex;
7143			}
7144			return null;
7145		}
7146	};
7147}
7148
7149jQuery.each([
7150	"tabIndex",
7151	"readOnly",
7152	"maxLength",
7153	"cellSpacing",
7154	"cellPadding",
7155	"rowSpan",
7156	"colSpan",
7157	"useMap",
7158	"frameBorder",
7159	"contentEditable"
7160], function() {
7161	jQuery.propFix[ this.toLowerCase() ] = this;
7162});
7163
7164
7165
7166
7167var rclass = /[\t\r\n\f]/g;
7168
7169jQuery.fn.extend({
7170	addClass: function( value ) {
7171		var classes, elem, cur, clazz, j, finalValue,
7172			proceed = typeof value === "string" && value,
7173			i = 0,
7174			len = this.length;
7175
7176		if ( jQuery.isFunction( value ) ) {
7177			return this.each(function( j ) {
7178				jQuery( this ).addClass( value.call( this, j, this.className ) );
7179			});
7180		}
7181
7182		if ( proceed ) {
7183			// The disjunction here is for better compressibility (see removeClass)
7184			classes = ( value || "" ).match( rnotwhite ) || [];
7185
7186			for ( ; i < len; i++ ) {
7187				elem = this[ i ];
7188				cur = elem.nodeType === 1 && ( elem.className ?
7189					( " " + elem.className + " " ).replace( rclass, " " ) :
7190					" "
7191				);
7192
7193				if ( cur ) {
7194					j = 0;
7195					while ( (clazz = classes[j++]) ) {
7196						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
7197							cur += clazz + " ";
7198						}
7199					}
7200
7201					// only assign if different to avoid unneeded rendering.
7202					finalValue = jQuery.trim( cur );
7203					if ( elem.className !== finalValue ) {
7204						elem.className = finalValue;
7205					}
7206				}
7207			}
7208		}
7209
7210		return this;
7211	},
7212
7213	removeClass: function( value ) {
7214		var classes, elem, cur, clazz, j, finalValue,
7215			proceed = arguments.length === 0 || typeof value === "string" && value,
7216			i = 0,
7217			len = this.length;
7218
7219		if ( jQuery.isFunction( value ) ) {
7220			return this.each(function( j ) {
7221				jQuery( this ).removeClass( value.call( this, j, this.className ) );
7222			});
7223		}
7224		if ( proceed ) {
7225			classes = ( value || "" ).match( rnotwhite ) || [];
7226
7227			for ( ; i < len; i++ ) {
7228				elem = this[ i ];
7229				// This expression is here for better compressibility (see addClass)
7230				cur = elem.nodeType === 1 && ( elem.className ?
7231					( " " + elem.className + " " ).replace( rclass, " " ) :
7232					""
7233				);
7234
7235				if ( cur ) {
7236					j = 0;
7237					while ( (clazz = classes[j++]) ) {
7238						// Remove *all* instances
7239						while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
7240							cur = cur.replace( " " + clazz + " ", " " );
7241						}
7242					}
7243
7244					// Only assign if different to avoid unneeded rendering.
7245					finalValue = value ? jQuery.trim( cur ) : "";
7246					if ( elem.className !== finalValue ) {
7247						elem.className = finalValue;
7248					}
7249				}
7250			}
7251		}
7252
7253		return this;
7254	},
7255
7256	toggleClass: function( value, stateVal ) {
7257		var type = typeof value;
7258
7259		if ( typeof stateVal === "boolean" && type === "string" ) {
7260			return stateVal ? this.addClass( value ) : this.removeClass( value );
7261		}
7262
7263		if ( jQuery.isFunction( value ) ) {
7264			return this.each(function( i ) {
7265				jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
7266			});
7267		}
7268
7269		return this.each(function() {
7270			if ( type === "string" ) {
7271				// Toggle individual class names
7272				var className,
7273					i = 0,
7274					self = jQuery( this ),
7275					classNames = value.match( rnotwhite ) || [];
7276
7277				while ( (className = classNames[ i++ ]) ) {
7278					// Check each className given, space separated list
7279					if ( self.hasClass( className ) ) {
7280						self.removeClass( className );
7281					} else {
7282						self.addClass( className );
7283					}
7284				}
7285
7286			// Toggle whole class name
7287			} else if ( type === strundefined || type === "boolean" ) {
7288				if ( this.className ) {
7289					// store className if set
7290					data_priv.set( this, "__className__", this.className );
7291				}
7292
7293				// If the element has a class name or if we're passed `false`,
7294				// then remove the whole classname (if there was one, the above saved it).
7295				// Otherwise bring back whatever was previously saved (if anything),
7296				// falling back to the empty string if nothing was stored.
7297				this.className = this.className || value === false ? "" : data_priv.get( this, "__className__" ) || "";
7298			}
7299		});
7300	},
7301
7302	hasClass: function( selector ) {
7303		var className = " " + selector + " ",
7304			i = 0,
7305			l = this.length;
7306		for ( ; i < l; i++ ) {
7307			if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
7308				return true;
7309			}
7310		}
7311
7312		return false;
7313	}
7314});
7315
7316
7317
7318
7319var rreturn = /\r/g;
7320
7321jQuery.fn.extend({
7322	val: function( value ) {
7323		var hooks, ret, isFunction,
7324			elem = this[0];
7325
7326		if ( !arguments.length ) {
7327			if ( elem ) {
7328				hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
7329
7330				if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
7331					return ret;
7332				}
7333
7334				ret = elem.value;
7335
7336				return typeof ret === "string" ?
7337					// Handle most common string cases
7338					ret.replace(rreturn, "") :
7339					// Handle cases where value is null/undef or number
7340					ret == null ? "" : ret;
7341			}
7342
7343			return;
7344		}
7345
7346		isFunction = jQuery.isFunction( value );
7347
7348		return this.each(function( i ) {
7349			var val;
7350
7351			if ( this.nodeType !== 1 ) {
7352				return;
7353			}
7354
7355			if ( isFunction ) {
7356				val = value.call( this, i, jQuery( this ).val() );
7357			} else {
7358				val = value;
7359			}
7360
7361			// Treat null/undefined as ""; convert numbers to string
7362			if ( val == null ) {
7363				val = "";
7364
7365			} else if ( typeof val === "number" ) {
7366				val += "";
7367
7368			} else if ( jQuery.isArray( val ) ) {
7369				val = jQuery.map( val, function( value ) {
7370					return value == null ? "" : value + "";
7371				});
7372			}
7373
7374			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
7375
7376			// If set returns undefined, fall back to normal setting
7377			if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
7378				this.value = val;
7379			}
7380		});
7381	}
7382});
7383
7384jQuery.extend({
7385	valHooks: {
7386		option: {
7387			get: function( elem ) {
7388				var val = jQuery.find.attr( elem, "value" );
7389				return val != null ?
7390					val :
7391					// Support: IE10-11+
7392					// option.text throws exceptions (#14686, #14858)
7393					jQuery.trim( jQuery.text( elem ) );
7394			}
7395		},
7396		select: {
7397			get: function( elem ) {
7398				var value, option,
7399					options = elem.options,
7400					index = elem.selectedIndex,
7401					one = elem.type === "select-one" || index < 0,
7402					values = one ? null : [],
7403					max = one ? index + 1 : options.length,
7404					i = index < 0 ?
7405						max :
7406						one ? index : 0;
7407
7408				// Loop through all the selected options
7409				for ( ; i < max; i++ ) {
7410					option = options[ i ];
7411
7412					// IE6-9 doesn't update selected after form reset (#2551)
7413					if ( ( option.selected || i === index ) &&
7414							// Don't return options that are disabled or in a disabled optgroup
7415							( support.optDisabled ? !option.disabled : option.getAttribute( "disabled" ) === null ) &&
7416							( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
7417
7418						// Get the specific value for the option
7419						value = jQuery( option ).val();
7420
7421						// We don't need an array for one selects
7422						if ( one ) {
7423							return value;
7424						}
7425
7426						// Multi-Selects return an array
7427						values.push( value );
7428					}
7429				}
7430
7431				return values;
7432			},
7433
7434			set: function( elem, value ) {
7435				var optionSet, option,
7436					options = elem.options,
7437					values = jQuery.makeArray( value ),
7438					i = options.length;
7439
7440				while ( i-- ) {
7441					option = options[ i ];
7442					if ( (option.selected = jQuery.inArray( option.value, values ) >= 0) ) {
7443						optionSet = true;
7444					}
7445				}
7446
7447				// Force browsers to behave consistently when non-matching value is set
7448				if ( !optionSet ) {
7449					elem.selectedIndex = -1;
7450				}
7451				return values;
7452			}
7453		}
7454	}
7455});
7456
7457// Radios and checkboxes getter/setter
7458jQuery.each([ "radio", "checkbox" ], function() {
7459	jQuery.valHooks[ this ] = {
7460		set: function( elem, value ) {
7461			if ( jQuery.isArray( value ) ) {
7462				return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
7463			}
7464		}
7465	};
7466	if ( !support.checkOn ) {
7467		jQuery.valHooks[ this ].get = function( elem ) {
7468			return elem.getAttribute("value") === null ? "on" : elem.value;
7469		};
7470	}
7471});
7472
7473
7474
7475
7476// Return jQuery for attributes-only inclusion
7477
7478
7479jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
7480	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
7481	"change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
7482
7483	// Handle event binding
7484	jQuery.fn[ name ] = function( data, fn ) {
7485		return arguments.length > 0 ?
7486			this.on( name, null, data, fn ) :
7487			this.trigger( name );
7488	};
7489});
7490
7491jQuery.fn.extend({
7492	hover: function( fnOver, fnOut ) {
7493		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
7494	},
7495
7496	bind: function( types, data, fn ) {
7497		return this.on( types, null, data, fn );
7498	},
7499	unbind: function( types, fn ) {
7500		return this.off( types, null, fn );
7501	},
7502
7503	delegate: function( selector, types, data, fn ) {
7504		return this.on( types, selector, data, fn );
7505	},
7506	undelegate: function( selector, types, fn ) {
7507		// ( namespace ) or ( selector, types [, fn] )
7508		return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
7509	}
7510});
7511
7512
7513var nonce = jQuery.now();
7514
7515var rquery = (/\?/);
7516
7517
7518
7519// Support: Android 2.3
7520// Workaround failure to string-cast null input
7521jQuery.parseJSON = function( data ) {
7522	return JSON.parse( data + "" );
7523};
7524
7525
7526// Cross-browser xml parsing
7527jQuery.parseXML = function( data ) {
7528	var xml, tmp;
7529	if ( !data || typeof data !== "string" ) {
7530		return null;
7531	}
7532
7533	// Support: IE9
7534	try {
7535		tmp = new DOMParser();
7536		xml = tmp.parseFromString( data, "text/xml" );
7537	} catch ( e ) {
7538		xml = undefined;
7539	}
7540
7541	if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
7542		jQuery.error( "Invalid XML: " + data );
7543	}
7544	return xml;
7545};
7546
7547
7548var
7549	rhash = /#.*$/,
7550	rts = /([?&])_=[^&]*/,
7551	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
7552	// #7653, #8125, #8152: local protocol detection
7553	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
7554	rnoContent = /^(?:GET|HEAD)$/,
7555	rprotocol = /^\/\//,
7556	rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
7557
7558	/* Prefilters
7559	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
7560	 * 2) These are called:
7561	 *    - BEFORE asking for a transport
7562	 *    - AFTER param serialization (s.data is a string if s.processData is true)
7563	 * 3) key is the dataType
7564	 * 4) the catchall symbol "*" can be used
7565	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
7566	 */
7567	prefilters = {},
7568
7569	/* Transports bindings
7570	 * 1) key is the dataType
7571	 * 2) the catchall symbol "*" can be used
7572	 * 3) selection will start with transport dataType and THEN go to "*" if needed
7573	 */
7574	transports = {},
7575
7576	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
7577	allTypes = "*/".concat( "*" ),
7578
7579	// Document location
7580	ajaxLocation = window.location.href,
7581
7582	// Segment location into parts
7583	ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
7584
7585// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
7586function addToPrefiltersOrTransports( structure ) {
7587
7588	// dataTypeExpression is optional and defaults to "*"
7589	return function( dataTypeExpression, func ) {
7590
7591		if ( typeof dataTypeExpression !== "string" ) {
7592			func = dataTypeExpression;
7593			dataTypeExpression = "*";
7594		}
7595
7596		var dataType,
7597			i = 0,
7598			dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
7599
7600		if ( jQuery.isFunction( func ) ) {
7601			// For each dataType in the dataTypeExpression
7602			while ( (dataType = dataTypes[i++]) ) {
7603				// Prepend if requested
7604				if ( dataType[0] === "+" ) {
7605					dataType = dataType.slice( 1 ) || "*";
7606					(structure[ dataType ] = structure[ dataType ] || []).unshift( func );
7607
7608				// Otherwise append
7609				} else {
7610					(structure[ dataType ] = structure[ dataType ] || []).push( func );
7611				}
7612			}
7613		}
7614	};
7615}
7616
7617// Base inspection function for prefilters and transports
7618function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
7619
7620	var inspected = {},
7621		seekingTransport = ( structure === transports );
7622
7623	function inspect( dataType ) {
7624		var selected;
7625		inspected[ dataType ] = true;
7626		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
7627			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
7628			if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
7629				options.dataTypes.unshift( dataTypeOrTransport );
7630				inspect( dataTypeOrTransport );
7631				return false;
7632			} else if ( seekingTransport ) {
7633				return !( selected = dataTypeOrTransport );
7634			}
7635		});
7636		return selected;
7637	}
7638
7639	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
7640}
7641
7642// A special extend for ajax options
7643// that takes "flat" options (not to be deep extended)
7644// Fixes #9887
7645function ajaxExtend( target, src ) {
7646	var key, deep,
7647		flatOptions = jQuery.ajaxSettings.flatOptions || {};
7648
7649	for ( key in src ) {
7650		if ( src[ key ] !== undefined ) {
7651			( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
7652		}
7653	}
7654	if ( deep ) {
7655		jQuery.extend( true, target, deep );
7656	}
7657
7658	return target;
7659}
7660
7661/* Handles responses to an ajax request:
7662 * - finds the right dataType (mediates between content-type and expected dataType)
7663 * - returns the corresponding response
7664 */
7665function ajaxHandleResponses( s, jqXHR, responses ) {
7666
7667	var ct, type, finalDataType, firstDataType,
7668		contents = s.contents,
7669		dataTypes = s.dataTypes;
7670
7671	// Remove auto dataType and get content-type in the process
7672	while ( dataTypes[ 0 ] === "*" ) {
7673		dataTypes.shift();
7674		if ( ct === undefined ) {
7675			ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
7676		}
7677	}
7678
7679	// Check if we're dealing with a known content-type
7680	if ( ct ) {
7681		for ( type in contents ) {
7682			if ( contents[ type ] && contents[ type ].test( ct ) ) {
7683				dataTypes.unshift( type );
7684				break;
7685			}
7686		}
7687	}
7688
7689	// Check to see if we have a response for the expected dataType
7690	if ( dataTypes[ 0 ] in responses ) {
7691		finalDataType = dataTypes[ 0 ];
7692	} else {
7693		// Try convertible dataTypes
7694		for ( type in responses ) {
7695			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
7696				finalDataType = type;
7697				break;
7698			}
7699			if ( !firstDataType ) {
7700				firstDataType = type;
7701			}
7702		}
7703		// Or just use first one
7704		finalDataType = finalDataType || firstDataType;
7705	}
7706
7707	// If we found a dataType
7708	// We add the dataType to the list if needed
7709	// and return the corresponding response
7710	if ( finalDataType ) {
7711		if ( finalDataType !== dataTypes[ 0 ] ) {
7712			dataTypes.unshift( finalDataType );
7713		}
7714		return responses[ finalDataType ];
7715	}
7716}
7717
7718/* Chain conversions given the request and the original response
7719 * Also sets the responseXXX fields on the jqXHR instance
7720 */
7721function ajaxConvert( s, response, jqXHR, isSuccess ) {
7722	var conv2, current, conv, tmp, prev,
7723		converters = {},
7724		// Work with a copy of dataTypes in case we need to modify it for conversion
7725		dataTypes = s.dataTypes.slice();
7726
7727	// Create converters map with lowercased keys
7728	if ( dataTypes[ 1 ] ) {
7729		for ( conv in s.converters ) {
7730			converters[ conv.toLowerCase() ] = s.converters[ conv ];
7731		}
7732	}
7733
7734	current = dataTypes.shift();
7735
7736	// Convert to each sequential dataType
7737	while ( current ) {
7738
7739		if ( s.responseFields[ current ] ) {
7740			jqXHR[ s.responseFields[ current ] ] = response;
7741		}
7742
7743		// Apply the dataFilter if provided
7744		if ( !prev && isSuccess && s.dataFilter ) {
7745			response = s.dataFilter( response, s.dataType );
7746		}
7747
7748		prev = current;
7749		current = dataTypes.shift();
7750
7751		if ( current ) {
7752
7753		// There's only work to do if current dataType is non-auto
7754			if ( current === "*" ) {
7755
7756				current = prev;
7757
7758			// Convert response if prev dataType is non-auto and differs from current
7759			} else if ( prev !== "*" && prev !== current ) {
7760
7761				// Seek a direct converter
7762				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
7763
7764				// If none found, seek a pair
7765				if ( !conv ) {
7766					for ( conv2 in converters ) {
7767
7768						// If conv2 outputs current
7769						tmp = conv2.split( " " );
7770						if ( tmp[ 1 ] === current ) {
7771
7772							// If prev can be converted to accepted input
7773							conv = converters[ prev + " " + tmp[ 0 ] ] ||
7774								converters[ "* " + tmp[ 0 ] ];
7775							if ( conv ) {
7776								// Condense equivalence converters
7777								if ( conv === true ) {
7778									conv = converters[ conv2 ];
7779
7780								// Otherwise, insert the intermediate dataType
7781								} else if ( converters[ conv2 ] !== true ) {
7782									current = tmp[ 0 ];
7783									dataTypes.unshift( tmp[ 1 ] );
7784								}
7785								break;
7786							}
7787						}
7788					}
7789				}
7790
7791				// Apply converter (if not an equivalence)
7792				if ( conv !== true ) {
7793
7794					// Unless errors are allowed to bubble, catch and return them
7795					if ( conv && s[ "throws" ] ) {
7796						response = conv( response );
7797					} else {
7798						try {
7799							response = conv( response );
7800						} catch ( e ) {
7801							return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
7802						}
7803					}
7804				}
7805			}
7806		}
7807	}
7808
7809	return { state: "success", data: response };
7810}
7811
7812jQuery.extend({
7813
7814	// Counter for holding the number of active queries
7815	active: 0,
7816
7817	// Last-Modified header cache for next request
7818	lastModified: {},
7819	etag: {},
7820
7821	ajaxSettings: {
7822		url: ajaxLocation,
7823		type: "GET",
7824		isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
7825		global: true,
7826		processData: true,
7827		async: true,
7828		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
7829		/*
7830		timeout: 0,
7831		data: null,
7832		dataType: null,
7833		username: null,
7834		password: null,
7835		cache: null,
7836		throws: false,
7837		traditional: false,
7838		headers: {},
7839		*/
7840
7841		accepts: {
7842			"*": allTypes,
7843			text: "text/plain",
7844			html: "text/html",
7845			xml: "application/xml, text/xml",
7846			json: "application/json, text/javascript"
7847		},
7848
7849		contents: {
7850			xml: /xml/,
7851			html: /html/,
7852			json: /json/
7853		},
7854
7855		responseFields: {
7856			xml: "responseXML",
7857			text: "responseText",
7858			json: "responseJSON"
7859		},
7860
7861		// Data converters
7862		// Keys separate source (or catchall "*") and destination types with a single space
7863		converters: {
7864
7865			// Convert anything to text
7866			"* text": String,
7867
7868			// Text to html (true = no transformation)
7869			"text html": true,
7870
7871			// Evaluate text as a json expression
7872			"text json": jQuery.parseJSON,
7873
7874			// Parse text as xml
7875			"text xml": jQuery.parseXML
7876		},
7877
7878		// For options that shouldn't be deep extended:
7879		// you can add your own custom options here if
7880		// and when you create one that shouldn't be
7881		// deep extended (see ajaxExtend)
7882		flatOptions: {
7883			url: true,
7884			context: true
7885		}
7886	},
7887
7888	// Creates a full fledged settings object into target
7889	// with both ajaxSettings and settings fields.
7890	// If target is omitted, writes into ajaxSettings.
7891	ajaxSetup: function( target, settings ) {
7892		return settings ?
7893
7894			// Building a settings object
7895			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
7896
7897			// Extending ajaxSettings
7898			ajaxExtend( jQuery.ajaxSettings, target );
7899	},
7900
7901	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
7902	ajaxTransport: addToPrefiltersOrTransports( transports ),
7903
7904	// Main method
7905	ajax: function( url, options ) {
7906
7907		// If url is an object, simulate pre-1.5 signature
7908		if ( typeof url === "object" ) {
7909			options = url;
7910			url = undefined;
7911		}
7912
7913		// Force options to be an object
7914		options = options || {};
7915
7916		var transport,
7917			// URL without anti-cache param
7918			cacheURL,
7919			// Response headers
7920			responseHeadersString,
7921			responseHeaders,
7922			// timeout handle
7923			timeoutTimer,
7924			// Cross-domain detection vars
7925			parts,
7926			// To know if global events are to be dispatched
7927			fireGlobals,
7928			// Loop variable
7929			i,
7930			// Create the final options object
7931			s = jQuery.ajaxSetup( {}, options ),
7932			// Callbacks context
7933			callbackContext = s.context || s,
7934			// Context for global events is callbackContext if it is a DOM node or jQuery collection
7935			globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
7936				jQuery( callbackContext ) :
7937				jQuery.event,
7938			// Deferreds
7939			deferred = jQuery.Deferred(),
7940			completeDeferred = jQuery.Callbacks("once memory"),
7941			// Status-dependent callbacks
7942			statusCode = s.statusCode || {},
7943			// Headers (they are sent all at once)
7944			requestHeaders = {},
7945			requestHeadersNames = {},
7946			// The jqXHR state
7947			state = 0,
7948			// Default abort message
7949			strAbort = "canceled",
7950			// Fake xhr
7951			jqXHR = {
7952				readyState: 0,
7953
7954				// Builds headers hashtable if needed
7955				getResponseHeader: function( key ) {
7956					var match;
7957					if ( state === 2 ) {
7958						if ( !responseHeaders ) {
7959							responseHeaders = {};
7960							while ( (match = rheaders.exec( responseHeadersString )) ) {
7961								responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
7962							}
7963						}
7964						match = responseHeaders[ key.toLowerCase() ];
7965					}
7966					return match == null ? null : match;
7967				},
7968
7969				// Raw string
7970				getAllResponseHeaders: function() {
7971					return state === 2 ? responseHeadersString : null;
7972				},
7973
7974				// Caches the header
7975				setRequestHeader: function( name, value ) {
7976					var lname = name.toLowerCase();
7977					if ( !state ) {
7978						name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
7979						requestHeaders[ name ] = value;
7980					}
7981					return this;
7982				},
7983
7984				// Overrides response content-type header
7985				overrideMimeType: function( type ) {
7986					if ( !state ) {
7987						s.mimeType = type;
7988					}
7989					return this;
7990				},
7991
7992				// Status-dependent callbacks
7993				statusCode: function( map ) {
7994					var code;
7995					if ( map ) {
7996						if ( state < 2 ) {
7997							for ( code in map ) {
7998								// Lazy-add the new callback in a way that preserves old ones
7999								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
8000							}
8001						} else {
8002							// Execute the appropriate callbacks
8003							jqXHR.always( map[ jqXHR.status ] );
8004						}
8005					}
8006					return this;
8007				},
8008
8009				// Cancel the request
8010				abort: function( statusText ) {
8011					var finalText = statusText || strAbort;
8012					if ( transport ) {
8013						transport.abort( finalText );
8014					}
8015					done( 0, finalText );
8016					return this;
8017				}
8018			};
8019
8020		// Attach deferreds
8021		deferred.promise( jqXHR ).complete = completeDeferred.add;
8022		jqXHR.success = jqXHR.done;
8023		jqXHR.error = jqXHR.fail;
8024
8025		// Remove hash character (#7531: and string promotion)
8026		// Add protocol if not provided (prefilters might expect it)
8027		// Handle falsy url in the settings object (#10093: consistency with old signature)
8028		// We also use the url parameter if available
8029		s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" )
8030			.replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
8031
8032		// Alias method option to type as per ticket #12004
8033		s.type = options.method || options.type || s.method || s.type;
8034
8035		// Extract dataTypes list
8036		s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
8037
8038		// A cross-domain request is in order when we have a protocol:host:port mismatch
8039		if ( s.crossDomain == null ) {
8040			parts = rurl.exec( s.url.toLowerCase() );
8041			s.crossDomain = !!( parts &&
8042				( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
8043					( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
8044						( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
8045			);
8046		}
8047
8048		// Convert data if not already a string
8049		if ( s.data && s.processData && typeof s.data !== "string" ) {
8050			s.data = jQuery.param( s.data, s.traditional );
8051		}
8052
8053		// Apply prefilters
8054		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
8055
8056		// If request was aborted inside a prefilter, stop there
8057		if ( state === 2 ) {
8058			return jqXHR;
8059		}
8060
8061		// We can fire global events as of now if asked to
8062		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
8063		fireGlobals = jQuery.event && s.global;
8064
8065		// Watch for a new set of requests
8066		if ( fireGlobals && jQuery.active++ === 0 ) {
8067			jQuery.event.trigger("ajaxStart");
8068		}
8069
8070		// Uppercase the type
8071		s.type = s.type.toUpperCase();
8072
8073		// Determine if request has content
8074		s.hasContent = !rnoContent.test( s.type );
8075
8076		// Save the URL in case we're toying with the If-Modified-Since
8077		// and/or If-None-Match header later on
8078		cacheURL = s.url;
8079
8080		// More options handling for requests with no content
8081		if ( !s.hasContent ) {
8082
8083			// If data is available, append data to url
8084			if ( s.data ) {
8085				cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
8086				// #9682: remove data so that it's not used in an eventual retry
8087				delete s.data;
8088			}
8089
8090			// Add anti-cache in url if needed
8091			if ( s.cache === false ) {
8092				s.url = rts.test( cacheURL ) ?
8093
8094					// If there is already a '_' parameter, set its value
8095					cacheURL.replace( rts, "$1_=" + nonce++ ) :
8096
8097					// Otherwise add one to the end
8098					cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
8099			}
8100		}
8101
8102		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
8103		if ( s.ifModified ) {
8104			if ( jQuery.lastModified[ cacheURL ] ) {
8105				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
8106			}
8107			if ( jQuery.etag[ cacheURL ] ) {
8108				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
8109			}
8110		}
8111
8112		// Set the correct header, if data is being sent
8113		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
8114			jqXHR.setRequestHeader( "Content-Type", s.contentType );
8115		}
8116
8117		// Set the Accepts header for the server, depending on the dataType
8118		jqXHR.setRequestHeader(
8119			"Accept",
8120			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
8121				s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
8122				s.accepts[ "*" ]
8123		);
8124
8125		// Check for headers option
8126		for ( i in s.headers ) {
8127			jqXHR.setRequestHeader( i, s.headers[ i ] );
8128		}
8129
8130		// Allow custom headers/mimetypes and early abort
8131		if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
8132			// Abort if not done already and return
8133			return jqXHR.abort();
8134		}
8135
8136		// Aborting is no longer a cancellation
8137		strAbort = "abort";
8138
8139		// Install callbacks on deferreds
8140		for ( i in { success: 1, error: 1, complete: 1 } ) {
8141			jqXHR[ i ]( s[ i ] );
8142		}
8143
8144		// Get transport
8145		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
8146
8147		// If no transport, we auto-abort
8148		if ( !transport ) {
8149			done( -1, "No Transport" );
8150		} else {
8151			jqXHR.readyState = 1;
8152
8153			// Send global event
8154			if ( fireGlobals ) {
8155				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
8156			}
8157			// Timeout
8158			if ( s.async && s.timeout > 0 ) {
8159				timeoutTimer = setTimeout(function() {
8160					jqXHR.abort("timeout");
8161				}, s.timeout );
8162			}
8163
8164			try {
8165				state = 1;
8166				transport.send( requestHeaders, done );
8167			} catch ( e ) {
8168				// Propagate exception as error if not done
8169				if ( state < 2 ) {
8170					done( -1, e );
8171				// Simply rethrow otherwise
8172				} else {
8173					throw e;
8174				}
8175			}
8176		}
8177
8178		// Callback for when everything is done
8179		function done( status, nativeStatusText, responses, headers ) {
8180			var isSuccess, success, error, response, modified,
8181				statusText = nativeStatusText;
8182
8183			// Called once
8184			if ( state === 2 ) {
8185				return;
8186			}
8187
8188			// State is "done" now
8189			state = 2;
8190
8191			// Clear timeout if it exists
8192			if ( timeoutTimer ) {
8193				clearTimeout( timeoutTimer );
8194			}
8195
8196			// Dereference transport for early garbage collection
8197			// (no matter how long the jqXHR object will be used)
8198			transport = undefined;
8199
8200			// Cache response headers
8201			responseHeadersString = headers || "";
8202
8203			// Set readyState
8204			jqXHR.readyState = status > 0 ? 4 : 0;
8205
8206			// Determine if successful
8207			isSuccess = status >= 200 && status < 300 || status === 304;
8208
8209			// Get response data
8210			if ( responses ) {
8211				response = ajaxHandleResponses( s, jqXHR, responses );
8212			}
8213
8214			// Convert no matter what (that way responseXXX fields are always set)
8215			response = ajaxConvert( s, response, jqXHR, isSuccess );
8216
8217			// If successful, handle type chaining
8218			if ( isSuccess ) {
8219
8220				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
8221				if ( s.ifModified ) {
8222					modified = jqXHR.getResponseHeader("Last-Modified");
8223					if ( modified ) {
8224						jQuery.lastModified[ cacheURL ] = modified;
8225					}
8226					modified = jqXHR.getResponseHeader("etag");
8227					if ( modified ) {
8228						jQuery.etag[ cacheURL ] = modified;
8229					}
8230				}
8231
8232				// if no content
8233				if ( status === 204 || s.type === "HEAD" ) {
8234					statusText = "nocontent";
8235
8236				// if not modified
8237				} else if ( status === 304 ) {
8238					statusText = "notmodified";
8239
8240				// If we have data, let's convert it
8241				} else {
8242					statusText = response.state;
8243					success = response.data;
8244					error = response.error;
8245					isSuccess = !error;
8246				}
8247			} else {
8248				// Extract error from statusText and normalize for non-aborts
8249				error = statusText;
8250				if ( status || !statusText ) {
8251					statusText = "error";
8252					if ( status < 0 ) {
8253						status = 0;
8254					}
8255				}
8256			}
8257
8258			// Set data for the fake xhr object
8259			jqXHR.status = status;
8260			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
8261
8262			// Success/Error
8263			if ( isSuccess ) {
8264				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
8265			} else {
8266				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
8267			}
8268
8269			// Status-dependent callbacks
8270			jqXHR.statusCode( statusCode );
8271			statusCode = undefined;
8272
8273			if ( fireGlobals ) {
8274				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
8275					[ jqXHR, s, isSuccess ? success : error ] );
8276			}
8277
8278			// Complete
8279			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
8280
8281			if ( fireGlobals ) {
8282				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
8283				// Handle the global AJAX counter
8284				if ( !( --jQuery.active ) ) {
8285					jQuery.event.trigger("ajaxStop");
8286				}
8287			}
8288		}
8289
8290		return jqXHR;
8291	},
8292
8293	getJSON: function( url, data, callback ) {
8294		return jQuery.get( url, data, callback, "json" );
8295	},
8296
8297	getScript: function( url, callback ) {
8298		return jQuery.get( url, undefined, callback, "script" );
8299	}
8300});
8301
8302jQuery.each( [ "get", "post" ], function( i, method ) {
8303	jQuery[ method ] = function( url, data, callback, type ) {
8304		// Shift arguments if data argument was omitted
8305		if ( jQuery.isFunction( data ) ) {
8306			type = type || callback;
8307			callback = data;
8308			data = undefined;
8309		}
8310
8311		return jQuery.ajax({
8312			url: url,
8313			type: method,
8314			dataType: type,
8315			data: data,
8316			success: callback
8317		});
8318	};
8319});
8320
8321
8322jQuery._evalUrl = function( url ) {
8323	return jQuery.ajax({
8324		url: url,
8325		type: "GET",
8326		dataType: "script",
8327		async: false,
8328		global: false,
8329		"throws": true
8330	});
8331};
8332
8333
8334jQuery.fn.extend({
8335	wrapAll: function( html ) {
8336		var wrap;
8337
8338		if ( jQuery.isFunction( html ) ) {
8339			return this.each(function( i ) {
8340				jQuery( this ).wrapAll( html.call(this, i) );
8341			});
8342		}
8343
8344		if ( this[ 0 ] ) {
8345
8346			// The elements to wrap the target around
8347			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
8348
8349			if ( this[ 0 ].parentNode ) {
8350				wrap.insertBefore( this[ 0 ] );
8351			}
8352
8353			wrap.map(function() {
8354				var elem = this;
8355
8356				while ( elem.firstElementChild ) {
8357					elem = elem.firstElementChild;
8358				}
8359
8360				return elem;
8361			}).append( this );
8362		}
8363
8364		return this;
8365	},
8366
8367	wrapInner: function( html ) {
8368		if ( jQuery.isFunction( html ) ) {
8369			return this.each(function( i ) {
8370				jQuery( this ).wrapInner( html.call(this, i) );
8371			});
8372		}
8373
8374		return this.each(function() {
8375			var self = jQuery( this ),
8376				contents = self.contents();
8377
8378			if ( contents.length ) {
8379				contents.wrapAll( html );
8380
8381			} else {
8382				self.append( html );
8383			}
8384		});
8385	},
8386
8387	wrap: function( html ) {
8388		var isFunction = jQuery.isFunction( html );
8389
8390		return this.each(function( i ) {
8391			jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
8392		});
8393	},
8394
8395	unwrap: function() {
8396		return this.parent().each(function() {
8397			if ( !jQuery.nodeName( this, "body" ) ) {
8398				jQuery( this ).replaceWith( this.childNodes );
8399			}
8400		}).end();
8401	}
8402});
8403
8404
8405jQuery.expr.filters.hidden = function( elem ) {
8406	// Support: Opera <= 12.12
8407	// Opera reports offsetWidths and offsetHeights less than zero on some elements
8408	return elem.offsetWidth <= 0 && elem.offsetHeight <= 0;
8409};
8410jQuery.expr.filters.visible = function( elem ) {
8411	return !jQuery.expr.filters.hidden( elem );
8412};
8413
8414
8415
8416
8417var r20 = /%20/g,
8418	rbracket = /\[\]$/,
8419	rCRLF = /\r?\n/g,
8420	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
8421	rsubmittable = /^(?:input|select|textarea|keygen)/i;
8422
8423function buildParams( prefix, obj, traditional, add ) {
8424	var name;
8425
8426	if ( jQuery.isArray( obj ) ) {
8427		// Serialize array item.
8428		jQuery.each( obj, function( i, v ) {
8429			if ( traditional || rbracket.test( prefix ) ) {
8430				// Treat each array item as a scalar.
8431				add( prefix, v );
8432
8433			} else {
8434				// Item is non-scalar (array or object), encode its numeric index.
8435				buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
8436			}
8437		});
8438
8439	} else if ( !traditional && jQuery.type( obj ) === "object" ) {
8440		// Serialize object item.
8441		for ( name in obj ) {
8442			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
8443		}
8444
8445	} else {
8446		// Serialize scalar item.
8447		add( prefix, obj );
8448	}
8449}
8450
8451// Serialize an array of form elements or a set of
8452// key/values into a query string
8453jQuery.param = function( a, traditional ) {
8454	var prefix,
8455		s = [],
8456		add = function( key, value ) {
8457			// If value is a function, invoke it and return its value
vendor: 2,100 bytes, lines 8458-8529
8458			value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
8459			s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
8460		};
8461
8462	// Set traditional to true for jQuery <= 1.3.2 behavior.
8463	if ( traditional === undefined ) {
8464		traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
8465	}
8466
8467	// If an array was passed in, assume that it is an array of form elements.
8468	if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
8469		// Serialize the form elements
8470		jQuery.each( a, function() {
8471			add( this.name, this.value );
8472		});
8473
8474	} else {
8475		// If traditional, encode the "old" way (the way 1.3.2 or older
8476		// did it), otherwise encode params recursively.
8477		for ( prefix in a ) {
8478			buildParams( prefix, a[ prefix ], traditional, add );
8479		}
8480	}
8481
8482	// Return the resulting serialization
8483	return s.join( "&" ).replace( r20, "+" );
8484};
8485
8486jQuery.fn.extend({
8487	serialize: function() {
8488		return jQuery.param( this.serializeArray() );
8489	},
8490	serializeArray: function() {
8491		return this.map(function() {
8492			// Can add propHook for "elements" to filter or add form elements
8493			var elements = jQuery.prop( this, "elements" );
8494			return elements ? jQuery.makeArray( elements ) : this;
8495		})
8496		.filter(function() {
8497			var type = this.type;
8498
8499			// Use .is( ":disabled" ) so that fieldset[disabled] works
8500			return this.name && !jQuery( this ).is( ":disabled" ) &&
8501				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
8502				( this.checked || !rcheckableType.test( type ) );
8503		})
8504		.map(function( i, elem ) {
8505			var val = jQuery( this ).val();
8506
8507			return val == null ?
8508				null :
8509				jQuery.isArray( val ) ?
8510					jQuery.map( val, function( val ) {
8511						return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
8512					}) :
8513					{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
8514		}).get();
8515	}
8516});
8517
8518
8519jQuery.ajaxSettings.xhr = function() {
8520	try {
8521		return new XMLHttpRequest();
8522	} catch( e ) {}
8523};
8524
8525var xhrId = 0,
8526	xhrCallbacks = {},
8527	xhrSuccessStatus = {
8528		// file protocol always yields status code 0, assume 200
8529		0: 200,
vendor: 1,492 bytes, lines 8530-8578
8530		// Support: IE9
8531		// #1450: sometimes IE returns 1223 when it should be 204
8532		1223: 204
8533	},
8534	xhrSupported = jQuery.ajaxSettings.xhr();
8535
8536// Support: IE9
8537// Open requests must be manually aborted on unload (#5280)
8538// See https://support.microsoft.com/kb/2856746 for more info
8539if ( window.attachEvent ) {
8540	window.attachEvent( "onunload", function() {
8541		for ( var key in xhrCallbacks ) {
8542			xhrCallbacks[ key ]();
8543		}
8544	});
8545}
8546
8547support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
8548support.ajax = xhrSupported = !!xhrSupported;
8549
8550jQuery.ajaxTransport(function( options ) {
8551	var callback;
8552
8553	// Cross domain only allowed if supported through XMLHttpRequest
8554	if ( support.cors || xhrSupported && !options.crossDomain ) {
8555		return {
8556			send: function( headers, complete ) {
8557				var i,
8558					xhr = options.xhr(),
8559					id = ++xhrId;
8560
8561				xhr.open( options.type, options.url, options.async, options.username, options.password );
8562
8563				// Apply custom fields if provided
8564				if ( options.xhrFields ) {
8565					for ( i in options.xhrFields ) {
8566						xhr[ i ] = options.xhrFields[ i ];
8567					}
8568				}
8569
8570				// Override mime type if needed
8571				if ( options.mimeType && xhr.overrideMimeType ) {
8572					xhr.overrideMimeType( options.mimeType );
8573				}
8574
8575				// X-Requested-With header
8576				// For cross-domain requests, seeing as conditions for a preflight are
8577				// akin to a jigsaw puzzle, we simply never set it to be sure.
8578				// (it can always be set on a per-request basis or even using ajaxSetup)
vendor: 5,725 bytes, lines 8579-8805
8579				// For same-domain requests, won't change header if already provided.
8580				if ( !options.crossDomain && !headers["X-Requested-With"] ) {
8581					headers["X-Requested-With"] = "XMLHttpRequest";
8582				}
8583
8584				// Set headers
8585				for ( i in headers ) {
8586					xhr.setRequestHeader( i, headers[ i ] );
8587				}
8588
8589				// Callback
8590				callback = function( type ) {
8591					return function() {
8592						if ( callback ) {
8593							delete xhrCallbacks[ id ];
8594							callback = xhr.onload = xhr.onerror = null;
8595
8596							if ( type === "abort" ) {
8597								xhr.abort();
8598							} else if ( type === "error" ) {
8599								complete(
8600									// file: protocol always yields status 0; see #8605, #14207
8601									xhr.status,
8602									xhr.statusText
8603								);
8604							} else {
8605								complete(
8606									xhrSuccessStatus[ xhr.status ] || xhr.status,
8607									xhr.statusText,
8608									// Support: IE9
8609									// Accessing binary-data responseText throws an exception
8610									// (#11426)
8611									typeof xhr.responseText === "string" ? {
8612										text: xhr.responseText
8613									} : undefined,
8614									xhr.getAllResponseHeaders()
8615								);
8616							}
8617						}
8618					};
8619				};
8620
8621				// Listen to events
8622				xhr.onload = callback();
8623				xhr.onerror = callback("error");
8624
8625				// Create the abort callback
8626				callback = xhrCallbacks[ id ] = callback("abort");
8627
8628				try {
8629					// Do send the request (this may raise an exception)
8630					xhr.send( options.hasContent && options.data || null );
8631				} catch ( e ) {
8632					// #14683: Only rethrow if this hasn't been notified as an error yet
8633					if ( callback ) {
8634						throw e;
8635					}
8636				}
8637			},
8638
8639			abort: function() {
8640				if ( callback ) {
8641					callback();
8642				}
8643			}
8644		};
8645	}
8646});
8647
8648
8649
8650
8651// Install script dataType
8652jQuery.ajaxSetup({
8653	accepts: {
8654		script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
8655	},
8656	contents: {
8657		script: /(?:java|ecma)script/
8658	},
8659	converters: {
8660		"text script": function( text ) {
8661			jQuery.globalEval( text );
8662			return text;
8663		}
8664	}
8665});
8666
8667// Handle cache's special case and crossDomain
8668jQuery.ajaxPrefilter( "script", function( s ) {
8669	if ( s.cache === undefined ) {
8670		s.cache = false;
8671	}
8672	if ( s.crossDomain ) {
8673		s.type = "GET";
8674	}
8675});
8676
8677// Bind script tag hack transport
8678jQuery.ajaxTransport( "script", function( s ) {
8679	// This transport only deals with cross domain requests
8680	if ( s.crossDomain ) {
8681		var script, callback;
8682		return {
8683			send: function( _, complete ) {
8684				script = jQuery("<script>").prop({
8685					async: true,
8686					charset: s.scriptCharset,
8687					src: s.url
8688				}).on(
8689					"load error",
8690					callback = function( evt ) {
8691						script.remove();
8692						callback = null;
8693						if ( evt ) {
8694							complete( evt.type === "error" ? 404 : 200, evt.type );
8695						}
8696					}
8697				);
8698				document.head.appendChild( script[ 0 ] );
8699			},
8700			abort: function() {
8701				if ( callback ) {
8702					callback();
8703				}
8704			}
8705		};
8706	}
8707});
8708
8709
8710
8711
8712var oldCallbacks = [],
8713	rjsonp = /(=)\?(?=&|$)|\?\?/;
8714
8715// Default jsonp settings
8716jQuery.ajaxSetup({
8717	jsonp: "callback",
8718	jsonpCallback: function() {
8719		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
8720		this[ callback ] = true;
8721		return callback;
8722	}
8723});
8724
8725// Detect, normalize options and install callbacks for jsonp requests
8726jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
8727
8728	var callbackName, overwritten, responseContainer,
8729		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
8730			"url" :
8731			typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
8732		);
8733
8734	// Handle iff the expected data type is "jsonp" or we have a parameter to set
8735	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
8736
8737		// Get callback name, remembering preexisting value associated with it
8738		callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
8739			s.jsonpCallback() :
8740			s.jsonpCallback;
8741
8742		// Insert callback into url or form data
8743		if ( jsonProp ) {
8744			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
8745		} else if ( s.jsonp !== false ) {
8746			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
8747		}
8748
8749		// Use data converter to retrieve json after script execution
8750		s.converters["script json"] = function() {
8751			if ( !responseContainer ) {
8752				jQuery.error( callbackName + " was not called" );
8753			}
8754			return responseContainer[ 0 ];
8755		};
8756
8757		// force json dataType
8758		s.dataTypes[ 0 ] = "json";
8759
8760		// Install callback
8761		overwritten = window[ callbackName ];
8762		window[ callbackName ] = function() {
8763			responseContainer = arguments;
8764		};
8765
8766		// Clean-up function (fires after converters)
8767		jqXHR.always(function() {
8768			// Restore preexisting value
8769			window[ callbackName ] = overwritten;
8770
8771			// Save back as free
8772			if ( s[ callbackName ] ) {
8773				// make sure that re-using the options doesn't screw things around
8774				s.jsonpCallback = originalSettings.jsonpCallback;
8775
8776				// save the callback name for future use
8777				oldCallbacks.push( callbackName );
8778			}
8779
8780			// Call if it was a function and we have a response
8781			if ( responseContainer && jQuery.isFunction( overwritten ) ) {
8782				overwritten( responseContainer[ 0 ] );
8783			}
8784
8785			responseContainer = overwritten = undefined;
8786		});
8787
8788		// Delegate to script
8789		return "script";
8790	}
8791});
8792
8793
8794
8795
8796// data: string of html
8797// context (optional): If specified, the fragment will be created in this context, defaults to document
8798// keepScripts (optional): If true, will include scripts passed in the html string
8799jQuery.parseHTML = function( data, context, keepScripts ) {
8800	if ( !data || typeof data !== "string" ) {
8801		return null;
8802	}
8803	if ( typeof context === "boolean" ) {
8804		keepScripts = context;
8805		context = false;
vendor: 10,932 bytes, lines 8806-9211
8806	}
8807	context = context || document;
8808
8809	var parsed = rsingleTag.exec( data ),
8810		scripts = !keepScripts && [];
8811
8812	// Single tag
8813	if ( parsed ) {
8814		return [ context.createElement( parsed[1] ) ];
8815	}
8816
8817	parsed = jQuery.buildFragment( [ data ], context, scripts );
8818
8819	if ( scripts && scripts.length ) {
8820		jQuery( scripts ).remove();
8821	}
8822
8823	return jQuery.merge( [], parsed.childNodes );
8824};
8825
8826
8827// Keep a copy of the old load method
8828var _load = jQuery.fn.load;
8829
8830/**
8831 * Load a url into a page
8832 */
8833jQuery.fn.load = function( url, params, callback ) {
8834	if ( typeof url !== "string" && _load ) {
8835		return _load.apply( this, arguments );
8836	}
8837
8838	var selector, type, response,
8839		self = this,
8840		off = url.indexOf(" ");
8841
8842	if ( off >= 0 ) {
8843		selector = jQuery.trim( url.slice( off ) );
8844		url = url.slice( 0, off );
8845	}
8846
8847	// If it's a function
8848	if ( jQuery.isFunction( params ) ) {
8849
8850		// We assume that it's the callback
8851		callback = params;
8852		params = undefined;
8853
8854	// Otherwise, build a param string
8855	} else if ( params && typeof params === "object" ) {
8856		type = "POST";
8857	}
8858
8859	// If we have elements to modify, make the request
8860	if ( self.length > 0 ) {
8861		jQuery.ajax({
8862			url: url,
8863
8864			// if "type" variable is undefined, then "GET" method will be used
8865			type: type,
8866			dataType: "html",
8867			data: params
8868		}).done(function( responseText ) {
8869
8870			// Save response for use in complete callback
8871			response = arguments;
8872
8873			self.html( selector ?
8874
8875				// If a selector was specified, locate the right elements in a dummy div
8876				// Exclude scripts to avoid IE 'Permission Denied' errors
8877				jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
8878
8879				// Otherwise use the full result
8880				responseText );
8881
8882		}).complete( callback && function( jqXHR, status ) {
8883			self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
8884		});
8885	}
8886
8887	return this;
8888};
8889
8890
8891
8892
8893// Attach a bunch of functions for handling common AJAX events
8894jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) {
8895	jQuery.fn[ type ] = function( fn ) {
8896		return this.on( type, fn );
8897	};
8898});
8899
8900
8901
8902
8903jQuery.expr.filters.animated = function( elem ) {
8904	return jQuery.grep(jQuery.timers, function( fn ) {
8905		return elem === fn.elem;
8906	}).length;
8907};
8908
8909
8910
8911
8912var docElem = window.document.documentElement;
8913
8914/**
8915 * Gets a window from an element
8916 */
8917function getWindow( elem ) {
8918	return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
8919}
8920
8921jQuery.offset = {
8922	setOffset: function( elem, options, i ) {
8923		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
8924			position = jQuery.css( elem, "position" ),
8925			curElem = jQuery( elem ),
8926			props = {};
8927
8928		// Set position first, in-case top/left are set even on static elem
8929		if ( position === "static" ) {
8930			elem.style.position = "relative";
8931		}
8932
8933		curOffset = curElem.offset();
8934		curCSSTop = jQuery.css( elem, "top" );
8935		curCSSLeft = jQuery.css( elem, "left" );
8936		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
8937			( curCSSTop + curCSSLeft ).indexOf("auto") > -1;
8938
8939		// Need to be able to calculate position if either
8940		// top or left is auto and position is either absolute or fixed
8941		if ( calculatePosition ) {
8942			curPosition = curElem.position();
8943			curTop = curPosition.top;
8944			curLeft = curPosition.left;
8945
8946		} else {
8947			curTop = parseFloat( curCSSTop ) || 0;
8948			curLeft = parseFloat( curCSSLeft ) || 0;
8949		}
8950
8951		if ( jQuery.isFunction( options ) ) {
8952			options = options.call( elem, i, curOffset );
8953		}
8954
8955		if ( options.top != null ) {
8956			props.top = ( options.top - curOffset.top ) + curTop;
8957		}
8958		if ( options.left != null ) {
8959			props.left = ( options.left - curOffset.left ) + curLeft;
8960		}
8961
8962		if ( "using" in options ) {
8963			options.using.call( elem, props );
8964
8965		} else {
8966			curElem.css( props );
8967		}
8968	}
8969};
8970
8971jQuery.fn.extend({
8972	offset: function( options ) {
8973		if ( arguments.length ) {
8974			return options === undefined ?
8975				this :
8976				this.each(function( i ) {
8977					jQuery.offset.setOffset( this, options, i );
8978				});
8979		}
8980
8981		var docElem, win,
8982			elem = this[ 0 ],
8983			box = { top: 0, left: 0 },
8984			doc = elem && elem.ownerDocument;
8985
8986		if ( !doc ) {
8987			return;
8988		}
8989
8990		docElem = doc.documentElement;
8991
8992		// Make sure it's not a disconnected DOM node
8993		if ( !jQuery.contains( docElem, elem ) ) {
8994			return box;
8995		}
8996
8997		// Support: BlackBerry 5, iOS 3 (original iPhone)
8998		// If we don't have gBCR, just use 0,0 rather than error
8999		if ( typeof elem.getBoundingClientRect !== strundefined ) {
9000			box = elem.getBoundingClientRect();
9001		}
9002		win = getWindow( doc );
9003		return {
9004			top: box.top + win.pageYOffset - docElem.clientTop,
9005			left: box.left + win.pageXOffset - docElem.clientLeft
9006		};
9007	},
9008
9009	position: function() {
9010		if ( !this[ 0 ] ) {
9011			return;
9012		}
9013
9014		var offsetParent, offset,
9015			elem = this[ 0 ],
9016			parentOffset = { top: 0, left: 0 };
9017
9018		// Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent
9019		if ( jQuery.css( elem, "position" ) === "fixed" ) {
9020			// Assume getBoundingClientRect is there when computed position is fixed
9021			offset = elem.getBoundingClientRect();
9022
9023		} else {
9024			// Get *real* offsetParent
9025			offsetParent = this.offsetParent();
9026
9027			// Get correct offsets
9028			offset = this.offset();
9029			if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
9030				parentOffset = offsetParent.offset();
9031			}
9032
9033			// Add offsetParent borders
9034			parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
9035			parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
9036		}
9037
9038		// Subtract parent offsets and element margins
9039		return {
9040			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
9041			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
9042		};
9043	},
9044
9045	offsetParent: function() {
9046		return this.map(function() {
9047			var offsetParent = this.offsetParent || docElem;
9048
9049			while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) {
9050				offsetParent = offsetParent.offsetParent;
9051			}
9052
9053			return offsetParent || docElem;
9054		});
9055	}
9056});
9057
9058// Create scrollLeft and scrollTop methods
9059jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
9060	var top = "pageYOffset" === prop;
9061
9062	jQuery.fn[ method ] = function( val ) {
9063		return access( this, function( elem, method, val ) {
9064			var win = getWindow( elem );
9065
9066			if ( val === undefined ) {
9067				return win ? win[ prop ] : elem[ method ];
9068			}
9069
9070			if ( win ) {
9071				win.scrollTo(
9072					!top ? val : window.pageXOffset,
9073					top ? val : window.pageYOffset
9074				);
9075
9076			} else {
9077				elem[ method ] = val;
9078			}
9079		}, method, val, arguments.length, null );
9080	};
9081});
9082
9083// Support: Safari<7+, Chrome<37+
9084// Add the top/left cssHooks using jQuery.fn.position
9085// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
9086// Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280
9087// getComputedStyle returns percent when specified for top/left/bottom/right;
9088// rather than make the css module depend on the offset module, just check for it here
9089jQuery.each( [ "top", "left" ], function( i, prop ) {
9090	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
9091		function( elem, computed ) {
9092			if ( computed ) {
9093				computed = curCSS( elem, prop );
9094				// If curCSS returns percentage, fallback to offset
9095				return rnumnonpx.test( computed ) ?
9096					jQuery( elem ).position()[ prop ] + "px" :
9097					computed;
9098			}
9099		}
9100	);
9101});
9102
9103
9104// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
9105jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
9106	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
9107		// Margin is only for outerHeight, outerWidth
9108		jQuery.fn[ funcName ] = function( margin, value ) {
9109			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
9110				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
9111
9112			return access( this, function( elem, type, value ) {
9113				var doc;
9114
9115				if ( jQuery.isWindow( elem ) ) {
9116					// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
9117					// isn't a whole lot we can do. See pull request at this URL for discussion:
9118					// https://github.com/jquery/jquery/pull/764
9119					return elem.document.documentElement[ "client" + name ];
9120				}
9121
9122				// Get document width or height
9123				if ( elem.nodeType === 9 ) {
9124					doc = elem.documentElement;
9125
9126					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
9127					// whichever is greatest
9128					return Math.max(
9129						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
9130						elem.body[ "offset" + name ], doc[ "offset" + name ],
9131						doc[ "client" + name ]
9132					);
9133				}
9134
9135				return value === undefined ?
9136					// Get width or height on the element, requesting but not forcing parseFloat
9137					jQuery.css( elem, type, extra ) :
9138
9139					// Set width or height on the element
9140					jQuery.style( elem, type, value, extra );
9141			}, type, chainable ? margin : undefined, chainable, null );
9142		};
9143	});
9144});
9145
9146
9147// The number of elements contained in the matched element set
9148jQuery.fn.size = function() {
9149	return this.length;
9150};
9151
9152jQuery.fn.andSelf = jQuery.fn.addBack;
9153
9154
9155
9156
9157// Register as a named AMD module, since jQuery can be concatenated with other
9158// files that may use define, but not via a proper concatenation script that
9159// understands anonymous AMD modules. A named AMD is safest and most robust
9160// way to register. Lowercase jquery is used because AMD module names are
9161// derived from file names, and jQuery is normally delivered in a lowercase
9162// file name. Do this after creating the global so that if an AMD module wants
9163// to call noConflict to hide this version of jQuery, it will work.
9164
9165// Note that for maximum portability, libraries that are not jQuery should
9166// declare themselves as anonymous modules, and avoid setting a global if an
9167// AMD loader is present. jQuery is a special case. For more information, see
9168// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
9169
9170if ( typeof define === "function" && define.amd ) {
9171	define( "jquery", [], function() {
9172		return jQuery;
9173	});
9174}
9175
9176
9177
9178
9179var
9180	// Map over jQuery in case of overwrite
9181	_jQuery = window.jQuery,
9182
9183	// Map over the $ in case of overwrite
9184	_$ = window.$;
9185
9186jQuery.noConflict = function( deep ) {
9187	if ( window.$ === jQuery ) {
9188		window.$ = _$;
9189	}
9190
9191	if ( deep && window.jQuery === jQuery ) {
9192		window.jQuery = _jQuery;
9193	}
9194
9195	return jQuery;
9196};
9197
9198// Expose jQuery and $ identifiers, even in AMD
9199// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
9200// and CommonJS for browser emulators (#13566)
9201if ( typeof noGlobal === strundefined ) {
9202	window.jQuery = window.$ = jQuery;
9203}
9204
9205
9206
9207
9208return jQuery;
9209
9210}));
9211
vendor: 65,765 bytes, lines 9212-11452
9212/*!
9213 * Bootstrap v3.3.4 (http://getbootstrap.com)
9214 * Copyright 2011-2015 Twitter, Inc.
9215 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
9216 */
9217
9218if (typeof jQuery === 'undefined') {
9219  throw new Error('Bootstrap\'s JavaScript requires jQuery')
9220}
9221
9222+function ($) {
9223  'use strict';
9224  var version = $.fn.jquery.split(' ')[0].split('.')
9225  if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) {
9226    throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher')
9227  }
9228}(jQuery);
9229
9230/* ========================================================================
9231 * Bootstrap: transition.js v3.3.4
9232 * http://getbootstrap.com/javascript/#transitions
9233 * ========================================================================
9234 * Copyright 2011-2015 Twitter, Inc.
9235 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
9236 * ======================================================================== */
9237
9238
9239+function ($) {
9240  'use strict';
9241
9242  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
9243  // ============================================================
9244
9245  function transitionEnd() {
9246    var el = document.createElement('bootstrap')
9247
9248    var transEndEventNames = {
9249      WebkitTransition : 'webkitTransitionEnd',
9250      MozTransition    : 'transitionend',
9251      OTransition      : 'oTransitionEnd otransitionend',
9252      transition       : 'transitionend'
9253    }
9254
9255    for (var name in transEndEventNames) {
9256      if (el.style[name] !== undefined) {
9257        return { end: transEndEventNames[name] }
9258      }
9259    }
9260
9261    return false // explicit for ie8 (  ._.)
9262  }
9263
9264  // http://blog.alexmaccaw.com/css-transitions
9265  $.fn.emulateTransitionEnd = function (duration) {
9266    var called = false
9267    var $el = this
9268    $(this).one('bsTransitionEnd', function () { called = true })
9269    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
9270    setTimeout(callback, duration)
9271    return this
9272  }
9273
9274  $(function () {
9275    $.support.transition = transitionEnd()
9276
9277    if (!$.support.transition) return
9278
9279    $.event.special.bsTransitionEnd = {
9280      bindType: $.support.transition.end,
9281      delegateType: $.support.transition.end,
9282      handle: function (e) {
9283        if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
9284      }
9285    }
9286  })
9287
9288}(jQuery);
9289
9290/* ========================================================================
9291 * Bootstrap: alert.js v3.3.4
9292 * http://getbootstrap.com/javascript/#alerts
9293 * ========================================================================
9294 * Copyright 2011-2015 Twitter, Inc.
9295 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
9296 * ======================================================================== */
9297
9298
9299+function ($) {
9300  'use strict';
9301
9302  // ALERT CLASS DEFINITION
9303  // ======================
9304
9305  var dismiss = '[data-dismiss="alert"]'
9306  var Alert   = function (el) {
9307    $(el).on('click', dismiss, this.close)
9308  }
9309
9310  Alert.VERSION = '3.3.4'
9311
9312  Alert.TRANSITION_DURATION = 150
9313
9314  Alert.prototype.close = function (e) {
9315    var $this    = $(this)
9316    var selector = $this.attr('data-target')
9317
9318    if (!selector) {
9319      selector = $this.attr('href')
9320      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
9321    }
9322
9323    var $parent = $(selector)
9324
9325    if (e) e.preventDefault()
9326
9327    if (!$parent.length) {
9328      $parent = $this.closest('.alert')
9329    }
9330
9331    $parent.trigger(e = $.Event('close.bs.alert'))
9332
9333    if (e.isDefaultPrevented()) return
9334
9335    $parent.removeClass('in')
9336
9337    function removeElement() {
9338      // detach from parent, fire event then clean up data
9339      $parent.detach().trigger('closed.bs.alert').remove()
9340    }
9341
9342    $.support.transition && $parent.hasClass('fade') ?
9343      $parent
9344        .one('bsTransitionEnd', removeElement)
9345        .emulateTransitionEnd(Alert.TRANSITION_DURATION) :
9346      removeElement()
9347  }
9348
9349
9350  // ALERT PLUGIN DEFINITION
9351  // =======================
9352
9353  function Plugin(option) {
9354    return this.each(function () {
9355      var $this = $(this)
9356      var data  = $this.data('bs.alert')
9357
9358      if (!data) $this.data('bs.alert', (data = new Alert(this)))
9359      if (typeof option == 'string') data[option].call($this)
9360    })
9361  }
9362
9363  var old = $.fn.alert
9364
9365  $.fn.alert             = Plugin
9366  $.fn.alert.Constructor = Alert
9367
9368
9369  // ALERT NO CONFLICT
9370  // =================
9371
9372  $.fn.alert.noConflict = function () {
9373    $.fn.alert = old
9374    return this
9375  }
9376
9377
9378  // ALERT DATA-API
9379  // ==============
9380
9381  $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
9382
9383}(jQuery);
9384
9385/* ========================================================================
9386 * Bootstrap: button.js v3.3.4
9387 * http://getbootstrap.com/javascript/#buttons
9388 * ========================================================================
9389 * Copyright 2011-2015 Twitter, Inc.
9390 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
9391 * ======================================================================== */
9392
9393
9394+function ($) {
9395  'use strict';
9396
9397  // BUTTON PUBLIC CLASS DEFINITION
9398  // ==============================
9399
9400  var Button = function (element, options) {
9401    this.$element  = $(element)
9402    this.options   = $.extend({}, Button.DEFAULTS, options)
9403    this.isLoading = false
9404  }
9405
9406  Button.VERSION  = '3.3.4'
9407
9408  Button.DEFAULTS = {
9409    loadingText: 'loading...'
9410  }
9411
9412  Button.prototype.setState = function (state) {
9413    var d    = 'disabled'
9414    var $el  = this.$element
9415    var val  = $el.is('input') ? 'val' : 'html'
9416    var data = $el.data()
9417
9418    state = state + 'Text'
9419
9420    if (data.resetText == null) $el.data('resetText', $el[val]())
9421
9422    // push to event loop to allow forms to submit
9423    setTimeout($.proxy(function () {
9424      $el[val](data[state] == null ? this.options[state] : data[state])
9425
9426      if (state == 'loadingText') {
9427        this.isLoading = true
9428        $el.addClass(d).attr(d, d)
9429      } else if (this.isLoading) {
9430        this.isLoading = false
9431        $el.removeClass(d).removeAttr(d)
9432      }
9433    }, this), 0)
9434  }
9435
9436  Button.prototype.toggle = function () {
9437    var changed = true
9438    var $parent = this.$element.closest('[data-toggle="buttons"]')
9439
9440    if ($parent.length) {
9441      var $input = this.$element.find('input')
9442      if ($input.prop('type') == 'radio') {
9443        if ($input.prop('checked') && this.$element.hasClass('active')) changed = false
9444        else $parent.find('.active').removeClass('active')
9445      }
9446      if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')
9447    } else {
9448      this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
9449    }
9450
9451    if (changed) this.$element.toggleClass('active')
9452  }
9453
9454
9455  // BUTTON PLUGIN DEFINITION
9456  // ========================
9457
9458  function Plugin(option) {
9459    return this.each(function () {
9460      var $this   = $(this)
9461      var data    = $this.data('bs.button')
9462      var options = typeof option == 'object' && option
9463
9464      if (!data) $this.data('bs.button', (data = new Button(this, options)))
9465
9466      if (option == 'toggle') data.toggle()
9467      else if (option) data.setState(option)
9468    })
9469  }
9470
9471  var old = $.fn.button
9472
9473  $.fn.button             = Plugin
9474  $.fn.button.Constructor = Button
9475
9476
9477  // BUTTON NO CONFLICT
9478  // ==================
9479
9480  $.fn.button.noConflict = function () {
9481    $.fn.button = old
9482    return this
9483  }
9484
9485
9486  // BUTTON DATA-API
9487  // ===============
9488
9489  $(document)
9490    .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
9491      var $btn = $(e.target)
9492      if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
9493      Plugin.call($btn, 'toggle')
9494      e.preventDefault()
9495    })
9496    .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
9497      $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
9498    })
9499
9500}(jQuery);
9501
9502/* ========================================================================
9503 * Bootstrap: carousel.js v3.3.4
9504 * http://getbootstrap.com/javascript/#carousel
9505 * ========================================================================
9506 * Copyright 2011-2015 Twitter, Inc.
9507 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
9508 * ======================================================================== */
9509
9510
9511+function ($) {
9512  'use strict';
9513
9514  // CAROUSEL CLASS DEFINITION
9515  // =========================
9516
9517  var Carousel = function (element, options) {
9518    this.$element    = $(element)
9519    this.$indicators = this.$element.find('.carousel-indicators')
9520    this.options     = options
9521    this.paused      = null
9522    this.sliding     = null
9523    this.interval    = null
9524    this.$active     = null
9525    this.$items      = null
9526
9527    this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
9528
9529    this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
9530      .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
9531      .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
9532  }
9533
9534  Carousel.VERSION  = '3.3.4'
9535
9536  Carousel.TRANSITION_DURATION = 600
9537
9538  Carousel.DEFAULTS = {
9539    interval: 5000,
9540    pause: 'hover',
9541    wrap: true,
9542    keyboard: true
9543  }
9544
9545  Carousel.prototype.keydown = function (e) {
9546    if (/input|textarea/i.test(e.target.tagName)) return
9547    switch (e.which) {
9548      case 37: this.prev(); break
9549      case 39: this.next(); break
9550      default: return
9551    }
9552
9553    e.preventDefault()
9554  }
9555
9556  Carousel.prototype.cycle = function (e) {
9557    e || (this.paused = false)
9558
9559    this.interval && clearInterval(this.interval)
9560
9561    this.options.interval
9562      && !this.paused
9563      && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
9564
9565    return this
9566  }
9567
9568  Carousel.prototype.getItemIndex = function (item) {
9569    this.$items = item.parent().children('.item')
9570    return this.$items.index(item || this.$active)
9571  }
9572
9573  Carousel.prototype.getItemForDirection = function (direction, active) {
9574    var activeIndex = this.getItemIndex(active)
9575    var willWrap = (direction == 'prev' && activeIndex === 0)
9576                || (direction == 'next' && activeIndex == (this.$items.length - 1))
9577    if (willWrap && !this.options.wrap) return active
9578    var delta = direction == 'prev' ? -1 : 1
9579    var itemIndex = (activeIndex + delta) % this.$items.length
9580    return this.$items.eq(itemIndex)
9581  }
9582
9583  Carousel.prototype.to = function (pos) {
9584    var that        = this
9585    var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
9586
9587    if (pos > (this.$items.length - 1) || pos < 0) return
9588
9589    if (this.sliding)       return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
9590    if (activeIndex == pos) return this.pause().cycle()
9591
9592    return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
9593  }
9594
9595  Carousel.prototype.pause = function (e) {
9596    e || (this.paused = true)
9597
9598    if (this.$element.find('.next, .prev').length && $.support.transition) {
9599      this.$element.trigger($.support.transition.end)
9600      this.cycle(true)
9601    }
9602
9603    this.interval = clearInterval(this.interval)
9604
9605    return this
9606  }
9607
9608  Carousel.prototype.next = function () {
9609    if (this.sliding) return
9610    return this.slide('next')
9611  }
9612
9613  Carousel.prototype.prev = function () {
9614    if (this.sliding) return
9615    return this.slide('prev')
9616  }
9617
9618  Carousel.prototype.slide = function (type, next) {
9619    var $active   = this.$element.find('.item.active')
9620    var $next     = next || this.getItemForDirection(type, $active)
9621    var isCycling = this.interval
9622    var direction = type == 'next' ? 'left' : 'right'
9623    var that      = this
9624
9625    if ($next.hasClass('active')) return (this.sliding = false)
9626
9627    var relatedTarget = $next[0]
9628    var slideEvent = $.Event('slide.bs.carousel', {
9629      relatedTarget: relatedTarget,
9630      direction: direction
9631    })
9632    this.$element.trigger(slideEvent)
9633    if (slideEvent.isDefaultPrevented()) return
9634
9635    this.sliding = true
9636
9637    isCycling && this.pause()
9638
9639    if (this.$indicators.length) {
9640      this.$indicators.find('.active').removeClass('active')
9641      var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
9642      $nextIndicator && $nextIndicator.addClass('active')
9643    }
9644
9645    var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
9646    if ($.support.transition && this.$element.hasClass('slide')) {
9647      $next.addClass(type)
9648      $next[0].offsetWidth // force reflow
9649      $active.addClass(direction)
9650      $next.addClass(direction)
9651      $active
9652        .one('bsTransitionEnd', function () {
9653          $next.removeClass([type, direction].join(' ')).addClass('active')
9654          $active.removeClass(['active', direction].join(' '))
9655          that.sliding = false
9656          setTimeout(function () {
9657            that.$element.trigger(slidEvent)
9658          }, 0)
9659        })
9660        .emulateTransitionEnd(Carousel.TRANSITION_DURATION)
9661    } else {
9662      $active.removeClass('active')
9663      $next.addClass('active')
9664      this.sliding = false
9665      this.$element.trigger(slidEvent)
9666    }
9667
9668    isCycling && this.cycle()
9669
9670    return this
9671  }
9672
9673
9674  // CAROUSEL PLUGIN DEFINITION
9675  // ==========================
9676
9677  function Plugin(option) {
9678    return this.each(function () {
9679      var $this   = $(this)
9680      var data    = $this.data('bs.carousel')
9681      var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
9682      var action  = typeof option == 'string' ? option : options.slide
9683
9684      if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
9685      if (typeof option == 'number') data.to(option)
9686      else if (action) data[action]()
9687      else if (options.interval) data.pause().cycle()
9688    })
9689  }
9690
9691  var old = $.fn.carousel
9692
9693  $.fn.carousel             = Plugin
9694  $.fn.carousel.Constructor = Carousel
9695
9696
9697  // CAROUSEL NO CONFLICT
9698  // ====================
9699
9700  $.fn.carousel.noConflict = function () {
9701    $.fn.carousel = old
9702    return this
9703  }
9704
9705
9706  // CAROUSEL DATA-API
9707  // =================
9708
9709  var clickHandler = function (e) {
9710    var href
9711    var $this   = $(this)
9712    var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
9713    if (!$target.hasClass('carousel')) return
9714    var options = $.extend({}, $target.data(), $this.data())
9715    var slideIndex = $this.attr('data-slide-to')
9716    if (slideIndex) options.interval = false
9717
9718    Plugin.call($target, options)
9719
9720    if (slideIndex) {
9721      $target.data('bs.carousel').to(slideIndex)
9722    }
9723
9724    e.preventDefault()
9725  }
9726
9727  $(document)
9728    .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
9729    .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
9730
9731  $(window).on('load', function () {
9732    $('[data-ride="carousel"]').each(function () {
9733      var $carousel = $(this)
9734      Plugin.call($carousel, $carousel.data())
9735    })
9736  })
9737
9738}(jQuery);
9739
9740/* ========================================================================
9741 * Bootstrap: collapse.js v3.3.4
9742 * http://getbootstrap.com/javascript/#collapse
9743 * ========================================================================
9744 * Copyright 2011-2015 Twitter, Inc.
9745 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
9746 * ======================================================================== */
9747
9748
9749+function ($) {
9750  'use strict';
9751
9752  // COLLAPSE PUBLIC CLASS DEFINITION
9753  // ================================
9754
9755  var Collapse = function (element, options) {
9756    this.$element      = $(element)
9757    this.options       = $.extend({}, Collapse.DEFAULTS, options)
9758    this.$trigger      = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
9759                           '[data-toggle="collapse"][data-target="#' + element.id + '"]')
9760    this.transitioning = null
9761
9762    if (this.options.parent) {
9763      this.$parent = this.getParent()
9764    } else {
9765      this.addAriaAndCollapsedClass(this.$element, this.$trigger)
9766    }
9767
9768    if (this.options.toggle) this.toggle()
9769  }
9770
9771  Collapse.VERSION  = '3.3.4'
9772
9773  Collapse.TRANSITION_DURATION = 350
9774
9775  Collapse.DEFAULTS = {
9776    toggle: true
9777  }
9778
9779  Collapse.prototype.dimension = function () {
9780    var hasWidth = this.$element.hasClass('width')
9781    return hasWidth ? 'width' : 'height'
9782  }
9783
9784  Collapse.prototype.show = function () {
9785    if (this.transitioning || this.$element.hasClass('in')) return
9786
9787    var activesData
9788    var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
9789
9790    if (actives && actives.length) {
9791      activesData = actives.data('bs.collapse')
9792      if (activesData && activesData.transitioning) return
9793    }
9794
9795    var startEvent = $.Event('show.bs.collapse')
9796    this.$element.trigger(startEvent)
9797    if (startEvent.isDefaultPrevented()) return
9798
9799    if (actives && actives.length) {
9800      Plugin.call(actives, 'hide')
9801      activesData || actives.data('bs.collapse', null)
9802    }
9803
9804    var dimension = this.dimension()
9805
9806    this.$element
9807      .removeClass('collapse')
9808      .addClass('collapsing')[dimension](0)
9809      .attr('aria-expanded', true)
9810
9811    this.$trigger
9812      .removeClass('collapsed')
9813      .attr('aria-expanded', true)
9814
9815    this.transitioning = 1
9816
9817    var complete = function () {
9818      this.$element
9819        .removeClass('collapsing')
9820        .addClass('collapse in')[dimension]('')
9821      this.transitioning = 0
9822      this.$element
9823        .trigger('shown.bs.collapse')
9824    }
9825
9826    if (!$.support.transition) return complete.call(this)
9827
9828    var scrollSize = $.camelCase(['scroll', dimension].join('-'))
9829
9830    this.$element
9831      .one('bsTransitionEnd', $.proxy(complete, this))
9832      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
9833  }
9834
9835  Collapse.prototype.hide = function () {
9836    if (this.transitioning || !this.$element.hasClass('in')) return
9837
9838    var startEvent = $.Event('hide.bs.collapse')
9839    this.$element.trigger(startEvent)
9840    if (startEvent.isDefaultPrevented()) return
9841
9842    var dimension = this.dimension()
9843
9844    this.$element[dimension](this.$element[dimension]())[0].offsetHeight
9845
9846    this.$element
9847      .addClass('collapsing')
9848      .removeClass('collapse in')
9849      .attr('aria-expanded', false)
9850
9851    this.$trigger
9852      .addClass('collapsed')
9853      .attr('aria-expanded', false)
9854
9855    this.transitioning = 1
9856
9857    var complete = function () {
9858      this.transitioning = 0
9859      this.$element
9860        .removeClass('collapsing')
9861        .addClass('collapse')
9862        .trigger('hidden.bs.collapse')
9863    }
9864
9865    if (!$.support.transition) return complete.call(this)
9866
9867    this.$element
9868      [dimension](0)
9869      .one('bsTransitionEnd', $.proxy(complete, this))
9870      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
9871  }
9872
9873  Collapse.prototype.toggle = function () {
9874    this[this.$element.hasClass('in') ? 'hide' : 'show']()
9875  }
9876
9877  Collapse.prototype.getParent = function () {
9878    return $(this.options.parent)
9879      .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
9880      .each($.proxy(function (i, element) {
9881        var $element = $(element)
9882        this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
9883      }, this))
9884      .end()
9885  }
9886
9887  Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
9888    var isOpen = $element.hasClass('in')
9889
9890    $element.attr('aria-expanded', isOpen)
9891    $trigger
9892      .toggleClass('collapsed', !isOpen)
9893      .attr('aria-expanded', isOpen)
9894  }
9895
9896  function getTargetFromTrigger($trigger) {
9897    var href
9898    var target = $trigger.attr('data-target')
9899      || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
9900
9901    return $(target)
9902  }
9903
9904
9905  // COLLAPSE PLUGIN DEFINITION
9906  // ==========================
9907
9908  function Plugin(option) {
9909    return this.each(function () {
9910      var $this   = $(this)
9911      var data    = $this.data('bs.collapse')
9912      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
9913
9914      if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
9915      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
9916      if (typeof option == 'string') data[option]()
9917    })
9918  }
9919
9920  var old = $.fn.collapse
9921
9922  $.fn.collapse             = Plugin
9923  $.fn.collapse.Constructor = Collapse
9924
9925
9926  // COLLAPSE NO CONFLICT
9927  // ====================
9928
9929  $.fn.collapse.noConflict = function () {
9930    $.fn.collapse = old
9931    return this
9932  }
9933
9934
9935  // COLLAPSE DATA-API
9936  // =================
9937
9938  $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
9939    var $this   = $(this)
9940
9941    if (!$this.attr('data-target')) e.preventDefault()
9942
9943    var $target = getTargetFromTrigger($this)
9944    var data    = $target.data('bs.collapse')
9945    var option  = data ? 'toggle' : $this.data()
9946
9947    Plugin.call($target, option)
9948  })
9949
9950}(jQuery);
9951
9952/* ========================================================================
9953 * Bootstrap: dropdown.js v3.3.4
9954 * http://getbootstrap.com/javascript/#dropdowns
9955 * ========================================================================
9956 * Copyright 2011-2015 Twitter, Inc.
9957 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
9958 * ======================================================================== */
9959
9960
9961+function ($) {
9962  'use strict';
9963
9964  // DROPDOWN CLASS DEFINITION
9965  // =========================
9966
9967  var backdrop = '.dropdown-backdrop'
9968  var toggle   = '[data-toggle="dropdown"]'
9969  var Dropdown = function (element) {
9970    $(element).on('click.bs.dropdown', this.toggle)
9971  }
9972
9973  Dropdown.VERSION = '3.3.4'
9974
9975  Dropdown.prototype.toggle = function (e) {
9976    var $this = $(this)
9977
9978    if ($this.is('.disabled, :disabled')) return
9979
9980    var $parent  = getParent($this)
9981    var isActive = $parent.hasClass('open')
9982
9983    clearMenus()
9984
9985    if (!isActive) {
9986      if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
9987        // if mobile we use a backdrop because click events don't delegate
9988        $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
9989      }
9990
9991      var relatedTarget = { relatedTarget: this }
9992      $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
9993
9994      if (e.isDefaultPrevented()) return
9995
9996      $this
9997        .trigger('focus')
9998        .attr('aria-expanded', 'true')
9999
10000      $parent
10001        .toggleClass('open')
10002        .trigger('shown.bs.dropdown', relatedTarget)
10003    }
10004
10005    return false
10006  }
10007
10008  Dropdown.prototype.keydown = function (e) {
10009    if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
10010
10011    var $this = $(this)
10012
10013    e.preventDefault()
10014    e.stopPropagation()
10015
10016    if ($this.is('.disabled, :disabled')) return
10017
10018    var $parent  = getParent($this)
10019    var isActive = $parent.hasClass('open')
10020
10021    if ((!isActive && e.which != 27) || (isActive && e.which == 27)) {
10022      if (e.which == 27) $parent.find(toggle).trigger('focus')
10023      return $this.trigger('click')
10024    }
10025
10026    var desc = ' li:not(.disabled):visible a'
10027    var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc)
10028
10029    if (!$items.length) return
10030
10031    var index = $items.index(e.target)
10032
10033    if (e.which == 38 && index > 0)                 index--                        // up
10034    if (e.which == 40 && index < $items.length - 1) index++                        // down
10035    if (!~index)                                      index = 0
10036
10037    $items.eq(index).trigger('focus')
10038  }
10039
10040  function clearMenus(e) {
10041    if (e && e.which === 3) return
10042    $(backdrop).remove()
10043    $(toggle).each(function () {
10044      var $this         = $(this)
10045      var $parent       = getParent($this)
10046      var relatedTarget = { relatedTarget: this }
10047
10048      if (!$parent.hasClass('open')) return
10049
10050      $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
10051
10052      if (e.isDefaultPrevented()) return
10053
10054      $this.attr('aria-expanded', 'false')
10055      $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
10056    })
10057  }
10058
10059  function getParent($this) {
10060    var selector = $this.attr('data-target')
10061
10062    if (!selector) {
10063      selector = $this.attr('href')
10064      selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
10065    }
10066
10067    var $parent = selector && $(selector)
10068
10069    return $parent && $parent.length ? $parent : $this.parent()
10070  }
10071
10072
10073  // DROPDOWN PLUGIN DEFINITION
10074  // ==========================
10075
10076  function Plugin(option) {
10077    return this.each(function () {
10078      var $this = $(this)
10079      var data  = $this.data('bs.dropdown')
10080
10081      if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
10082      if (typeof option == 'string') data[option].call($this)
10083    })
10084  }
10085
10086  var old = $.fn.dropdown
10087
10088  $.fn.dropdown             = Plugin
10089  $.fn.dropdown.Constructor = Dropdown
10090
10091
10092  // DROPDOWN NO CONFLICT
10093  // ====================
10094
10095  $.fn.dropdown.noConflict = function () {
10096    $.fn.dropdown = old
10097    return this
10098  }
10099
10100
10101  // APPLY TO STANDARD DROPDOWN ELEMENTS
10102  // ===================================
10103
10104  $(document)
10105    .on('click.bs.dropdown.data-api', clearMenus)
10106    .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
10107    .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
10108    .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
10109    .on('keydown.bs.dropdown.data-api', '[role="menu"]', Dropdown.prototype.keydown)
10110    .on('keydown.bs.dropdown.data-api', '[role="listbox"]', Dropdown.prototype.keydown)
10111
10112}(jQuery);
10113
10114/* ========================================================================
10115 * Bootstrap: modal.js v3.3.4
10116 * http://getbootstrap.com/javascript/#modals
10117 * ========================================================================
10118 * Copyright 2011-2015 Twitter, Inc.
10119 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
10120 * ======================================================================== */
10121
10122
10123+function ($) {
10124  'use strict';
10125
10126  // MODAL CLASS DEFINITION
10127  // ======================
10128
10129  var Modal = function (element, options) {
10130    this.options             = options
10131    this.$body               = $(document.body)
10132    this.$element            = $(element)
10133    this.$dialog             = this.$element.find('.modal-dialog')
10134    this.$backdrop           = null
10135    this.isShown             = null
10136    this.originalBodyPad     = null
10137    this.scrollbarWidth      = 0
10138    this.ignoreBackdropClick = false
10139
10140    if (this.options.remote) {
10141      this.$element
10142        .find('.modal-content')
10143        .load(this.options.remote, $.proxy(function () {
10144          this.$element.trigger('loaded.bs.modal')
10145        }, this))
10146    }
10147  }
10148
10149  Modal.VERSION  = '3.3.4'
10150
10151  Modal.TRANSITION_DURATION = 300
10152  Modal.BACKDROP_TRANSITION_DURATION = 150
10153
10154  Modal.DEFAULTS = {
10155    backdrop: true,
10156    keyboard: true,
10157    show: true
10158  }
10159
10160  Modal.prototype.toggle = function (_relatedTarget) {
10161    return this.isShown ? this.hide() : this.show(_relatedTarget)
10162  }
10163
10164  Modal.prototype.show = function (_relatedTarget) {
10165    var that = this
10166    var e    = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
10167
10168    this.$element.trigger(e)
10169
10170    if (this.isShown || e.isDefaultPrevented()) return
10171
10172    this.isShown = true
10173
10174    this.checkScrollbar()
10175    this.setScrollbar()
10176    this.$body.addClass('modal-open')
10177
10178    this.escape()
10179    this.resize()
10180
10181    this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
10182
10183    this.$dialog.on('mousedown.dismiss.bs.modal', function () {
10184      that.$element.one('mouseup.dismiss.bs.modal', function (e) {
10185        if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
10186      })
10187    })
10188
10189    this.backdrop(function () {
10190      var transition = $.support.transition && that.$element.hasClass('fade')
10191
10192      if (!that.$element.parent().length) {
10193        that.$element.appendTo(that.$body) // don't move modals dom position
10194      }
10195
10196      that.$element
10197        .show()
10198        .scrollTop(0)
10199
10200      that.adjustDialog()
10201
10202      if (transition) {
10203        that.$element[0].offsetWidth // force reflow
10204      }
10205
10206      that.$element
10207        .addClass('in')
10208        .attr('aria-hidden', false)
10209
10210      that.enforceFocus()
10211
10212      var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
10213
10214      transition ?
10215        that.$dialog // wait for modal to slide in
10216          .one('bsTransitionEnd', function () {
10217            that.$element.trigger('focus').trigger(e)
10218          })
10219          .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
10220        that.$element.trigger('focus').trigger(e)
10221    })
10222  }
10223
10224  Modal.prototype.hide = function (e) {
10225    if (e) e.preventDefault()
10226
10227    e = $.Event('hide.bs.modal')
10228
10229    this.$element.trigger(e)
10230
10231    if (!this.isShown || e.isDefaultPrevented()) return
10232
10233    this.isShown = false
10234
10235    this.escape()
10236    this.resize()
10237
10238    $(document).off('focusin.bs.modal')
10239
10240    this.$element
10241      .removeClass('in')
10242      .attr('aria-hidden', true)
10243      .off('click.dismiss.bs.modal')
10244      .off('mouseup.dismiss.bs.modal')
10245
10246    this.$dialog.off('mousedown.dismiss.bs.modal')
10247
10248    $.support.transition && this.$element.hasClass('fade') ?
10249      this.$element
10250        .one('bsTransitionEnd', $.proxy(this.hideModal, this))
10251        .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
10252      this.hideModal()
10253  }
10254
10255  Modal.prototype.enforceFocus = function () {
10256    $(document)
10257      .off('focusin.bs.modal') // guard against infinite focus loop
10258      .on('focusin.bs.modal', $.proxy(function (e) {
10259        if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
10260          this.$element.trigger('focus')
10261        }
10262      }, this))
10263  }
10264
10265  Modal.prototype.escape = function () {
10266    if (this.isShown && this.options.keyboard) {
10267      this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
10268        e.which == 27 && this.hide()
10269      }, this))
10270    } else if (!this.isShown) {
10271      this.$element.off('keydown.dismiss.bs.modal')
10272    }
10273  }
10274
10275  Modal.prototype.resize = function () {
10276    if (this.isShown) {
10277      $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
10278    } else {
10279      $(window).off('resize.bs.modal')
10280    }
10281  }
10282
10283  Modal.prototype.hideModal = function () {
10284    var that = this
10285    this.$element.hide()
10286    this.backdrop(function () {
10287      that.$body.removeClass('modal-open')
10288      that.resetAdjustments()
10289      that.resetScrollbar()
10290      that.$element.trigger('hidden.bs.modal')
10291    })
10292  }
10293
10294  Modal.prototype.removeBackdrop = function () {
10295    this.$backdrop && this.$backdrop.remove()
10296    this.$backdrop = null
10297  }
10298
10299  Modal.prototype.backdrop = function (callback) {
10300    var that = this
10301    var animate = this.$element.hasClass('fade') ? 'fade' : ''
10302
10303    if (this.isShown && this.options.backdrop) {
10304      var doAnimate = $.support.transition && animate
10305
10306      this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
10307        .appendTo(this.$body)
10308
10309      this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
10310        if (this.ignoreBackdropClick) {
10311          this.ignoreBackdropClick = false
10312          return
10313        }
10314        if (e.target !== e.currentTarget) return
10315        this.options.backdrop == 'static'
10316          ? this.$element[0].focus()
10317          : this.hide()
10318      }, this))
10319
10320      if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
10321
10322      this.$backdrop.addClass('in')
10323
10324      if (!callback) return
10325
10326      doAnimate ?
10327        this.$backdrop
10328          .one('bsTransitionEnd', callback)
10329          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
10330        callback()
10331
10332    } else if (!this.isShown && this.$backdrop) {
10333      this.$backdrop.removeClass('in')
10334
10335      var callbackRemove = function () {
10336        that.removeBackdrop()
10337        callback && callback()
10338      }
10339      $.support.transition && this.$element.hasClass('fade') ?
10340        this.$backdrop
10341          .one('bsTransitionEnd', callbackRemove)
10342          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
10343        callbackRemove()
10344
10345    } else if (callback) {
10346      callback()
10347    }
10348  }
10349
10350  // these following methods are used to handle overflowing modals
10351
10352  Modal.prototype.handleUpdate = function () {
10353    this.adjustDialog()
10354  }
10355
10356  Modal.prototype.adjustDialog = function () {
10357    var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
10358
10359    this.$element.css({
10360      paddingLeft:  !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
10361      paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
10362    })
10363  }
10364
10365  Modal.prototype.resetAdjustments = function () {
10366    this.$element.css({
10367      paddingLeft: '',
10368      paddingRight: ''
10369    })
10370  }
10371
10372  Modal.prototype.checkScrollbar = function () {
10373    var fullWindowWidth = window.innerWidth
10374    if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
10375      var documentElementRect = document.documentElement.getBoundingClientRect()
10376      fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
10377    }
10378    this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
10379    this.scrollbarWidth = this.measureScrollbar()
10380  }
10381
10382  Modal.prototype.setScrollbar = function () {
10383    var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
10384    this.originalBodyPad = document.body.style.paddingRight || ''
10385    if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
10386  }
10387
10388  Modal.prototype.resetScrollbar = function () {
10389    this.$body.css('padding-right', this.originalBodyPad)
10390  }
10391
10392  Modal.prototype.measureScrollbar = function () { // thx walsh
10393    var scrollDiv = document.createElement('div')
10394    scrollDiv.className = 'modal-scrollbar-measure'
10395    this.$body.append(scrollDiv)
10396    var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
10397    this.$body[0].removeChild(scrollDiv)
10398    return scrollbarWidth
10399  }
10400
10401
10402  // MODAL PLUGIN DEFINITION
10403  // =======================
10404
10405  function Plugin(option, _relatedTarget) {
10406    return this.each(function () {
10407      var $this   = $(this)
10408      var data    = $this.data('bs.modal')
10409      var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
10410
10411      if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
10412      if (typeof option == 'string') data[option](_relatedTarget)
10413      else if (options.show) data.show(_relatedTarget)
10414    })
10415  }
10416
10417  var old = $.fn.modal
10418
10419  $.fn.modal             = Plugin
10420  $.fn.modal.Constructor = Modal
10421
10422
10423  // MODAL NO CONFLICT
10424  // =================
10425
10426  $.fn.modal.noConflict = function () {
10427    $.fn.modal = old
10428    return this
10429  }
10430
10431
10432  // MODAL DATA-API
10433  // ==============
10434
10435  $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
10436    var $this   = $(this)
10437    var href    = $this.attr('href')
10438    var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
10439    var option  = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
10440
10441    if ($this.is('a')) e.preventDefault()
10442
10443    $target.one('show.bs.modal', function (showEvent) {
10444      if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
10445      $target.one('hidden.bs.modal', function () {
10446        $this.is(':visible') && $this.trigger('focus')
10447      })
10448    })
10449    Plugin.call($target, option, this)
10450  })
10451
10452}(jQuery);
10453
10454/* ========================================================================
10455 * Bootstrap: tooltip.js v3.3.4
10456 * http://getbootstrap.com/javascript/#tooltip
10457 * Inspired by the original jQuery.tipsy by Jason Frame
10458 * ========================================================================
10459 * Copyright 2011-2015 Twitter, Inc.
10460 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
10461 * ======================================================================== */
10462
10463
10464+function ($) {
10465  'use strict';
10466
10467  // TOOLTIP PUBLIC CLASS DEFINITION
10468  // ===============================
10469
10470  var Tooltip = function (element, options) {
10471    this.type       = null
10472    this.options    = null
10473    this.enabled    = null
10474    this.timeout    = null
10475    this.hoverState = null
10476    this.$element   = null
10477
10478    this.init('tooltip', element, options)
10479  }
10480
10481  Tooltip.VERSION  = '3.3.4'
10482
10483  Tooltip.TRANSITION_DURATION = 150
10484
10485  Tooltip.DEFAULTS = {
10486    animation: true,
10487    placement: 'top',
10488    selector: false,
10489    template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
10490    trigger: 'hover focus',
10491    title: '',
10492    delay: 0,
10493    html: false,
10494    container: false,
10495    viewport: {
10496      selector: 'body',
10497      padding: 0
10498    }
10499  }
10500
10501  Tooltip.prototype.init = function (type, element, options) {
10502    this.enabled   = true
10503    this.type      = type
10504    this.$element  = $(element)
10505    this.options   = this.getOptions(options)
10506    this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)
10507
10508    if (this.$element[0] instanceof document.constructor && !this.options.selector) {
10509      throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
10510    }
10511
10512    var triggers = this.options.trigger.split(' ')
10513
10514    for (var i = triggers.length; i--;) {
10515      var trigger = triggers[i]
10516
10517      if (trigger == 'click') {
10518        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
10519      } else if (trigger != 'manual') {
10520        var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin'
10521        var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
10522
10523        this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
10524        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
10525      }
10526    }
10527
10528    this.options.selector ?
10529      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
10530      this.fixTitle()
10531  }
10532
10533  Tooltip.prototype.getDefaults = function () {
10534    return Tooltip.DEFAULTS
10535  }
10536
10537  Tooltip.prototype.getOptions = function (options) {
10538    options = $.extend({}, this.getDefaults(), this.$element.data(), options)
10539
10540    if (options.delay && typeof options.delay == 'number') {
10541      options.delay = {
10542        show: options.delay,
10543        hide: options.delay
10544      }
10545    }
10546
10547    return options
10548  }
10549
10550  Tooltip.prototype.getDelegateOptions = function () {
10551    var options  = {}
10552    var defaults = this.getDefaults()
10553
10554    this._options && $.each(this._options, function (key, value) {
10555      if (defaults[key] != value) options[key] = value
10556    })
10557
10558    return options
10559  }
10560
10561  Tooltip.prototype.enter = function (obj) {
10562    var self = obj instanceof this.constructor ?
10563      obj : $(obj.currentTarget).data('bs.' + this.type)
10564
10565    if (self && self.$tip && self.$tip.is(':visible')) {
10566      self.hoverState = 'in'
10567      return
10568    }
10569
10570    if (!self) {
10571      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
10572      $(obj.currentTarget).data('bs.' + this.type, self)
10573    }
10574
10575    clearTimeout(self.timeout)
10576
10577    self.hoverState = 'in'
10578
10579    if (!self.options.delay || !self.options.delay.show) return self.show()
10580
10581    self.timeout = setTimeout(function () {
10582      if (self.hoverState == 'in') self.show()
10583    }, self.options.delay.show)
10584  }
10585
10586  Tooltip.prototype.leave = function (obj) {
10587    var self = obj instanceof this.constructor ?
10588      obj : $(obj.currentTarget).data('bs.' + this.type)
10589
10590    if (!self) {
10591      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
10592      $(obj.currentTarget).data('bs.' + this.type, self)
10593    }
10594
10595    clearTimeout(self.timeout)
10596
10597    self.hoverState = 'out'
10598
10599    if (!self.options.delay || !self.options.delay.hide) return self.hide()
10600
10601    self.timeout = setTimeout(function () {
10602      if (self.hoverState == 'out') self.hide()
10603    }, self.options.delay.hide)
10604  }
10605
10606  Tooltip.prototype.show = function () {
10607    var e = $.Event('show.bs.' + this.type)
10608
10609    if (this.hasContent() && this.enabled) {
10610      this.$element.trigger(e)
10611
10612      var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
10613      if (e.isDefaultPrevented() || !inDom) return
10614      var that = this
10615
10616      var $tip = this.tip()
10617
10618      var tipId = this.getUID(this.type)
10619
10620      this.setContent()
10621      $tip.attr('id', tipId)
10622      this.$element.attr('aria-describedby', tipId)
10623
10624      if (this.options.animation) $tip.addClass('fade')
10625
10626      var placement = typeof this.options.placement == 'function' ?
10627        this.options.placement.call(this, $tip[0], this.$element[0]) :
10628        this.options.placement
10629
10630      var autoToken = /\s?auto?\s?/i
10631      var autoPlace = autoToken.test(placement)
10632      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
10633
10634      $tip
10635        .detach()
10636        .css({ top: 0, left: 0, display: 'block' })
10637        .addClass(placement)
10638        .data('bs.' + this.type, this)
10639
10640      this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
10641
10642      var pos          = this.getPosition()
10643      var actualWidth  = $tip[0].offsetWidth
10644      var actualHeight = $tip[0].offsetHeight
10645
10646      if (autoPlace) {
10647        var orgPlacement = placement
10648        var $container   = this.options.container ? $(this.options.container) : this.$element.parent()
10649        var containerDim = this.getPosition($container)
10650
10651        placement = placement == 'bottom' && pos.bottom + actualHeight > containerDim.bottom ? 'top'    :
10652                    placement == 'top'    && pos.top    - actualHeight < containerDim.top    ? 'bottom' :
10653                    placement == 'right'  && pos.right  + actualWidth  > containerDim.width  ? 'left'   :
10654                    placement == 'left'   && pos.left   - actualWidth  < containerDim.left   ? 'right'  :
10655                    placement
10656
10657        $tip
10658          .removeClass(orgPlacement)
10659          .addClass(placement)
10660      }
10661
10662      var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
10663
10664      this.applyPlacement(calculatedOffset, placement)
10665
10666      var complete = function () {
10667        var prevHoverState = that.hoverState
10668        that.$element.trigger('shown.bs.' + that.type)
10669        that.hoverState = null
10670
10671        if (prevHoverState == 'out') that.leave(that)
10672      }
10673
10674      $.support.transition && this.$tip.hasClass('fade') ?
10675        $tip
10676          .one('bsTransitionEnd', complete)
10677          .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
10678        complete()
10679    }
10680  }
10681
10682  Tooltip.prototype.applyPlacement = function (offset, placement) {
10683    var $tip   = this.tip()
10684    var width  = $tip[0].offsetWidth
10685    var height = $tip[0].offsetHeight
10686
10687    // manually read margins because getBoundingClientRect includes difference
10688    var marginTop = parseInt($tip.css('margin-top'), 10)
10689    var marginLeft = parseInt($tip.css('margin-left'), 10)
10690
10691    // we must check for NaN for ie 8/9
10692    if (isNaN(marginTop))  marginTop  = 0
10693    if (isNaN(marginLeft)) marginLeft = 0
10694
10695    offset.top  = offset.top  + marginTop
10696    offset.left = offset.left + marginLeft
10697
10698    // $.fn.offset doesn't round pixel values
10699    // so we use setOffset directly with our own function B-0
10700    $.offset.setOffset($tip[0], $.extend({
10701      using: function (props) {
10702        $tip.css({
10703          top: Math.round(props.top),
10704          left: Math.round(props.left)
10705        })
10706      }
10707    }, offset), 0)
10708
10709    $tip.addClass('in')
10710
10711    // check to see if placing tip in new offset caused the tip to resize itself
10712    var actualWidth  = $tip[0].offsetWidth
10713    var actualHeight = $tip[0].offsetHeight
10714
10715    if (placement == 'top' && actualHeight != height) {
10716      offset.top = offset.top + height - actualHeight
10717    }
10718
10719    var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
10720
10721    if (delta.left) offset.left += delta.left
10722    else offset.top += delta.top
10723
10724    var isVertical          = /top|bottom/.test(placement)
10725    var arrowDelta          = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
10726    var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
10727
10728    $tip.offset(offset)
10729    this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
10730  }
10731
10732  Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
10733    this.arrow()
10734      .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
10735      .css(isVertical ? 'top' : 'left', '')
10736  }
10737
10738  Tooltip.prototype.setContent = function () {
10739    var $tip  = this.tip()
10740    var title = this.getTitle()
10741
10742    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
10743    $tip.removeClass('fade in top bottom left right')
10744  }
10745
10746  Tooltip.prototype.hide = function (callback) {
10747    var that = this
10748    var $tip = $(this.$tip)
10749    var e    = $.Event('hide.bs.' + this.type)
10750
10751    function complete() {
10752      if (that.hoverState != 'in') $tip.detach()
10753      that.$element
10754        .removeAttr('aria-describedby')
10755        .trigger('hidden.bs.' + that.type)
10756      callback && callback()
10757    }
10758
10759    this.$element.trigger(e)
10760
10761    if (e.isDefaultPrevented()) return
10762
10763    $tip.removeClass('in')
10764
10765    $.support.transition && $tip.hasClass('fade') ?
10766      $tip
10767        .one('bsTransitionEnd', complete)
10768        .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
10769      complete()
10770
10771    this.hoverState = null
10772
10773    return this
10774  }
10775
10776  Tooltip.prototype.fixTitle = function () {
10777    var $e = this.$element
10778    if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') {
10779      $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
10780    }
10781  }
10782
10783  Tooltip.prototype.hasContent = function () {
10784    return this.getTitle()
10785  }
10786
10787  Tooltip.prototype.getPosition = function ($element) {
10788    $element   = $element || this.$element
10789
10790    var el     = $element[0]
10791    var isBody = el.tagName == 'BODY'
10792
10793    var elRect    = el.getBoundingClientRect()
10794    if (elRect.width == null) {
10795      // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
10796      elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
10797    }
10798    var elOffset  = isBody ? { top: 0, left: 0 } : $element.offset()
10799    var scroll    = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
10800    var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
10801
10802    return $.extend({}, elRect, scroll, outerDims, elOffset)
10803  }
10804
10805  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
10806    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2 } :
10807           placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
10808           placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
10809        /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
10810
10811  }
10812
10813  Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
10814    var delta = { top: 0, left: 0 }
10815    if (!this.$viewport) return delta
10816
10817    var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
10818    var viewportDimensions = this.getPosition(this.$viewport)
10819
10820    if (/right|left/.test(placement)) {
10821      var topEdgeOffset    = pos.top - viewportPadding - viewportDimensions.scroll
10822      var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
10823      if (topEdgeOffset < viewportDimensions.top) { // top overflow
10824        delta.top = viewportDimensions.top - topEdgeOffset
10825      } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
10826        delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
10827      }
10828    } else {
10829      var leftEdgeOffset  = pos.left - viewportPadding
10830      var rightEdgeOffset = pos.left + viewportPadding + actualWidth
10831      if (leftEdgeOffset < viewportDimensions.left) { // left overflow
10832        delta.left = viewportDimensions.left - leftEdgeOffset
10833      } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow
10834        delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
10835      }
10836    }
10837
10838    return delta
10839  }
10840
10841  Tooltip.prototype.getTitle = function () {
10842    var title
10843    var $e = this.$element
10844    var o  = this.options
10845
10846    title = $e.attr('data-original-title')
10847      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)
10848
10849    return title
10850  }
10851
10852  Tooltip.prototype.getUID = function (prefix) {
10853    do prefix += ~~(Math.random() * 1000000)
10854    while (document.getElementById(prefix))
10855    return prefix
10856  }
10857
10858  Tooltip.prototype.tip = function () {
10859    return (this.$tip = this.$tip || $(this.options.template))
10860  }
10861
10862  Tooltip.prototype.arrow = function () {
10863    return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
10864  }
10865
10866  Tooltip.prototype.enable = function () {
10867    this.enabled = true
10868  }
10869
10870  Tooltip.prototype.disable = function () {
10871    this.enabled = false
10872  }
10873
10874  Tooltip.prototype.toggleEnabled = function () {
10875    this.enabled = !this.enabled
10876  }
10877
10878  Tooltip.prototype.toggle = function (e) {
10879    var self = this
10880    if (e) {
10881      self = $(e.currentTarget).data('bs.' + this.type)
10882      if (!self) {
10883        self = new this.constructor(e.currentTarget, this.getDelegateOptions())
10884        $(e.currentTarget).data('bs.' + this.type, self)
10885      }
10886    }
10887
10888    self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
10889  }
10890
10891  Tooltip.prototype.destroy = function () {
10892    var that = this
10893    clearTimeout(this.timeout)
10894    this.hide(function () {
10895      that.$element.off('.' + that.type).removeData('bs.' + that.type)
10896    })
10897  }
10898
10899
10900  // TOOLTIP PLUGIN DEFINITION
10901  // =========================
10902
10903  function Plugin(option) {
10904    return this.each(function () {
10905      var $this   = $(this)
10906      var data    = $this.data('bs.tooltip')
10907      var options = typeof option == 'object' && option
10908
10909      if (!data && /destroy|hide/.test(option)) return
10910      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
10911      if (typeof option == 'string') data[option]()
10912    })
10913  }
10914
10915  var old = $.fn.tooltip
10916
10917  $.fn.tooltip             = Plugin
10918  $.fn.tooltip.Constructor = Tooltip
10919
10920
10921  // TOOLTIP NO CONFLICT
10922  // ===================
10923
10924  $.fn.tooltip.noConflict = function () {
10925    $.fn.tooltip = old
10926    return this
10927  }
10928
10929}(jQuery);
10930
10931/* ========================================================================
10932 * Bootstrap: popover.js v3.3.4
10933 * http://getbootstrap.com/javascript/#popovers
10934 * ========================================================================
10935 * Copyright 2011-2015 Twitter, Inc.
10936 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
10937 * ======================================================================== */
10938
10939
10940+function ($) {
10941  'use strict';
10942
10943  // POPOVER PUBLIC CLASS DEFINITION
10944  // ===============================
10945
10946  var Popover = function (element, options) {
10947    this.init('popover', element, options)
10948  }
10949
10950  if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
10951
10952  Popover.VERSION  = '3.3.4'
10953
10954  Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
10955    placement: 'right',
10956    trigger: 'click',
10957    content: '',
10958    template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
10959  })
10960
10961
10962  // NOTE: POPOVER EXTENDS tooltip.js
10963  // ================================
10964
10965  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
10966
10967  Popover.prototype.constructor = Popover
10968
10969  Popover.prototype.getDefaults = function () {
10970    return Popover.DEFAULTS
10971  }
10972
10973  Popover.prototype.setContent = function () {
10974    var $tip    = this.tip()
10975    var title   = this.getTitle()
10976    var content = this.getContent()
10977
10978    $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
10979    $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
10980      this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
10981    ](content)
10982
10983    $tip.removeClass('fade top bottom left right in')
10984
10985    // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
10986    // this manually by checking the contents.
10987    if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
10988  }
10989
10990  Popover.prototype.hasContent = function () {
10991    return this.getTitle() || this.getContent()
10992  }
10993
10994  Popover.prototype.getContent = function () {
10995    var $e = this.$element
10996    var o  = this.options
10997
10998    return $e.attr('data-content')
10999      || (typeof o.content == 'function' ?
11000            o.content.call($e[0]) :
11001            o.content)
11002  }
11003
11004  Popover.prototype.arrow = function () {
11005    return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
11006  }
11007
11008
11009  // POPOVER PLUGIN DEFINITION
11010  // =========================
11011
11012  function Plugin(option) {
11013    return this.each(function () {
11014      var $this   = $(this)
11015      var data    = $this.data('bs.popover')
11016      var options = typeof option == 'object' && option
11017
11018      if (!data && /destroy|hide/.test(option)) return
11019      if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
11020      if (typeof option == 'string') data[option]()
11021    })
11022  }
11023
11024  var old = $.fn.popover
11025
11026  $.fn.popover             = Plugin
11027  $.fn.popover.Constructor = Popover
11028
11029
11030  // POPOVER NO CONFLICT
11031  // ===================
11032
11033  $.fn.popover.noConflict = function () {
11034    $.fn.popover = old
11035    return this
11036  }
11037
11038}(jQuery);
11039
11040/* ========================================================================
11041 * Bootstrap: scrollspy.js v3.3.4
11042 * http://getbootstrap.com/javascript/#scrollspy
11043 * ========================================================================
11044 * Copyright 2011-2015 Twitter, Inc.
11045 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
11046 * ======================================================================== */
11047
11048
11049+function ($) {
11050  'use strict';
11051
11052  // SCROLLSPY CLASS DEFINITION
11053  // ==========================
11054
11055  function ScrollSpy(element, options) {
11056    this.$body          = $(document.body)
11057    this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
11058    this.options        = $.extend({}, ScrollSpy.DEFAULTS, options)
11059    this.selector       = (this.options.target || '') + ' .nav li > a'
11060    this.offsets        = []
11061    this.targets        = []
11062    this.activeTarget   = null
11063    this.scrollHeight   = 0
11064
11065    this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
11066    this.refresh()
11067    this.process()
11068  }
11069
11070  ScrollSpy.VERSION  = '3.3.4'
11071
11072  ScrollSpy.DEFAULTS = {
11073    offset: 10
11074  }
11075
11076  ScrollSpy.prototype.getScrollHeight = function () {
11077    return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
11078  }
11079
11080  ScrollSpy.prototype.refresh = function () {
11081    var that          = this
11082    var offsetMethod  = 'offset'
11083    var offsetBase    = 0
11084
11085    this.offsets      = []
11086    this.targets      = []
11087    this.scrollHeight = this.getScrollHeight()
11088
11089    if (!$.isWindow(this.$scrollElement[0])) {
11090      offsetMethod = 'position'
11091      offsetBase   = this.$scrollElement.scrollTop()
11092    }
11093
11094    this.$body
11095      .find(this.selector)
11096      .map(function () {
11097        var $el   = $(this)
11098        var href  = $el.data('target') || $el.attr('href')
11099        var $href = /^#./.test(href) && $(href)
11100
11101        return ($href
11102          && $href.length
11103          && $href.is(':visible')
11104          && [[$href[offsetMethod]().top + offsetBase, href]]) || null
11105      })
11106      .sort(function (a, b) { return a[0] - b[0] })
11107      .each(function () {
11108        that.offsets.push(this[0])
11109        that.targets.push(this[1])
11110      })
11111  }
11112
11113  ScrollSpy.prototype.process = function () {
11114    var scrollTop    = this.$scrollElement.scrollTop() + this.options.offset
11115    var scrollHeight = this.getScrollHeight()
11116    var maxScroll    = this.options.offset + scrollHeight - this.$scrollElement.height()
11117    var offsets      = this.offsets
11118    var targets      = this.targets
11119    var activeTarget = this.activeTarget
11120    var i
11121
11122    if (this.scrollHeight != scrollHeight) {
11123      this.refresh()
11124    }
11125
11126    if (scrollTop >= maxScroll) {
11127      return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
11128    }
11129
11130    if (activeTarget && scrollTop < offsets[0]) {
11131      this.activeTarget = null
11132      return this.clear()
11133    }
11134
11135    for (i = offsets.length; i--;) {
11136      activeTarget != targets[i]
11137        && scrollTop >= offsets[i]
11138        && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
11139        && this.activate(targets[i])
11140    }
11141  }
11142
11143  ScrollSpy.prototype.activate = function (target) {
11144    this.activeTarget = target
11145
11146    this.clear()
11147
11148    var selector = this.selector +
11149      '[data-target="' + target + '"],' +
11150      this.selector + '[href="' + target + '"]'
11151
11152    var active = $(selector)
11153      .parents('li')
11154      .addClass('active')
11155
11156    if (active.parent('.dropdown-menu').length) {
11157      active = active
11158        .closest('li.dropdown')
11159        .addClass('active')
11160    }
11161
11162    active.trigger('activate.bs.scrollspy')
11163  }
11164
11165  ScrollSpy.prototype.clear = function () {
11166    $(this.selector)
11167      .parentsUntil(this.options.target, '.active')
11168      .removeClass('active')
11169  }
11170
11171
11172  // SCROLLSPY PLUGIN DEFINITION
11173  // ===========================
11174
11175  function Plugin(option) {
11176    return this.each(function () {
11177      var $this   = $(this)
11178      var data    = $this.data('bs.scrollspy')
11179      var options = typeof option == 'object' && option
11180
11181      if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
11182      if (typeof option == 'string') data[option]()
11183    })
11184  }
11185
11186  var old = $.fn.scrollspy
11187
11188  $.fn.scrollspy             = Plugin
11189  $.fn.scrollspy.Constructor = ScrollSpy
11190
11191
11192  // SCROLLSPY NO CONFLICT
11193  // =====================
11194
11195  $.fn.scrollspy.noConflict = function () {
11196    $.fn.scrollspy = old
11197    return this
11198  }
11199
11200
11201  // SCROLLSPY DATA-API
11202  // ==================
11203
11204  $(window).on('load.bs.scrollspy.data-api', function () {
11205    $('[data-spy="scroll"]').each(function () {
11206      var $spy = $(this)
11207      Plugin.call($spy, $spy.data())
11208    })
11209  })
11210
11211}(jQuery);
11212
11213/* ========================================================================
11214 * Bootstrap: tab.js v3.3.4
11215 * http://getbootstrap.com/javascript/#tabs
11216 * ========================================================================
11217 * Copyright 2011-2015 Twitter, Inc.
11218 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
11219 * ======================================================================== */
11220
11221
11222+function ($) {
11223  'use strict';
11224
11225  // TAB CLASS DEFINITION
11226  // ====================
11227
11228  var Tab = function (element) {
11229    this.element = $(element)
11230  }
11231
11232  Tab.VERSION = '3.3.4'
11233
11234  Tab.TRANSITION_DURATION = 150
11235
11236  Tab.prototype.show = function () {
11237    var $this    = this.element
11238    var $ul      = $this.closest('ul:not(.dropdown-menu)')
11239    var selector = $this.data('target')
11240
11241    if (!selector) {
11242      selector = $this.attr('href')
11243      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
11244    }
11245
11246    if ($this.parent('li').hasClass('active')) return
11247
11248    var $previous = $ul.find('.active:last a')
11249    var hideEvent = $.Event('hide.bs.tab', {
11250      relatedTarget: $this[0]
11251    })
11252    var showEvent = $.Event('show.bs.tab', {
11253      relatedTarget: $previous[0]
11254    })
11255
11256    $previous.trigger(hideEvent)
11257    $this.trigger(showEvent)
11258
11259    if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
11260
11261    var $target = $(selector)
11262
11263    this.activate($this.closest('li'), $ul)
11264    this.activate($target, $target.parent(), function () {
11265      $previous.trigger({
11266        type: 'hidden.bs.tab',
11267        relatedTarget: $this[0]
11268      })
11269      $this.trigger({
11270        type: 'shown.bs.tab',
11271        relatedTarget: $previous[0]
11272      })
11273    })
11274  }
11275
11276  Tab.prototype.activate = function (element, container, callback) {
11277    var $active    = container.find('> .active')
11278    var transition = callback
11279      && $.support.transition
11280      && (($active.length && $active.hasClass('fade')) || !!container.find('> .fade').length)
11281
11282    function next() {
11283      $active
11284        .removeClass('active')
11285        .find('> .dropdown-menu > .active')
11286          .removeClass('active')
11287        .end()
11288        .find('[data-toggle="tab"]')
11289          .attr('aria-expanded', false)
11290
11291      element
11292        .addClass('active')
11293        .find('[data-toggle="tab"]')
11294          .attr('aria-expanded', true)
11295
11296      if (transition) {
11297        element[0].offsetWidth // reflow for transition
11298        element.addClass('in')
11299      } else {
11300        element.removeClass('fade')
11301      }
11302
11303      if (element.parent('.dropdown-menu').length) {
11304        element
11305          .closest('li.dropdown')
11306            .addClass('active')
11307          .end()
11308          .find('[data-toggle="tab"]')
11309            .attr('aria-expanded', true)
11310      }
11311
11312      callback && callback()
11313    }
11314
11315    $active.length && transition ?
11316      $active
11317        .one('bsTransitionEnd', next)
11318        .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
11319      next()
11320
11321    $active.removeClass('in')
11322  }
11323
11324
11325  // TAB PLUGIN DEFINITION
11326  // =====================
11327
11328  function Plugin(option) {
11329    return this.each(function () {
11330      var $this = $(this)
11331      var data  = $this.data('bs.tab')
11332
11333      if (!data) $this.data('bs.tab', (data = new Tab(this)))
11334      if (typeof option == 'string') data[option]()
11335    })
11336  }
11337
11338  var old = $.fn.tab
11339
11340  $.fn.tab             = Plugin
11341  $.fn.tab.Constructor = Tab
11342
11343
11344  // TAB NO CONFLICT
11345  // ===============
11346
11347  $.fn.tab.noConflict = function () {
11348    $.fn.tab = old
11349    return this
11350  }
11351
11352
11353  // TAB DATA-API
11354  // ============
11355
11356  var clickHandler = function (e) {
11357    e.preventDefault()
11358    Plugin.call($(this), 'show')
11359  }
11360
11361  $(document)
11362    .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
11363    .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
11364
11365}(jQuery);
11366
11367/* ========================================================================
11368 * Bootstrap: affix.js v3.3.4
11369 * http://getbootstrap.com/javascript/#affix
11370 * ========================================================================
11371 * Copyright 2011-2015 Twitter, Inc.
11372 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
11373 * ======================================================================== */
11374
11375
11376+function ($) {
11377  'use strict';
11378
11379  // AFFIX CLASS DEFINITION
11380  // ======================
11381
11382  var Affix = function (element, options) {
11383    this.options = $.extend({}, Affix.DEFAULTS, options)
11384
11385    this.$target = $(this.options.target)
11386      .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
11387      .on('click.bs.affix.data-api',  $.proxy(this.checkPositionWithEventLoop, this))
11388
11389    this.$element     = $(element)
11390    this.affixed      = null
11391    this.unpin        = null
11392    this.pinnedOffset = null
11393
11394    this.checkPosition()
11395  }
11396
11397  Affix.VERSION  = '3.3.4'
11398
11399  Affix.RESET    = 'affix affix-top affix-bottom'
11400
11401  Affix.DEFAULTS = {
11402    offset: 0,
11403    target: window
11404  }
11405
11406  Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
11407    var scrollTop    = this.$target.scrollTop()
11408    var position     = this.$element.offset()
11409    var targetHeight = this.$target.height()
11410
11411    if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
11412
11413    if (this.affixed == 'bottom') {
11414      if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
11415      return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
11416    }
11417
11418    var initializing   = this.affixed == null
11419    var colliderTop    = initializing ? scrollTop : position.top
11420    var colliderHeight = initializing ? targetHeight : height
11421
11422    if (offsetTop != null && scrollTop <= offsetTop) return 'top'
11423    if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
11424
11425    return false
11426  }
11427
11428  Affix.prototype.getPinnedOffset = function () {
11429    if (this.pinnedOffset) return this.pinnedOffset
11430    this.$element.removeClass(Affix.RESET).addClass('affix')
11431    var scrollTop = this.$target.scrollTop()
11432    var position  = this.$element.offset()
11433    return (this.pinnedOffset = position.top - scrollTop)
11434  }
11435
11436  Affix.prototype.checkPositionWithEventLoop = function () {
11437    setTimeout($.proxy(this.checkPosition, this), 1)
11438  }
11439
11440  Affix.prototype.checkPosition = function () {
11441    if (!this.$element.is(':visible')) return
11442
11443    var height       = this.$element.height()
11444    var offset       = this.options.offset
11445    var offsetTop    = offset.top
11446    var offsetBottom = offset.bottom
11447    var scrollHeight = $(document.body).height()
11448
11449    if (typeof offset != 'object')         offsetBottom = offsetTop = offset
11450    if (typeof offsetTop == 'function')    offsetTop    = offset.top(this.$element)
11451    if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
11452
vendor: 3,566 bytes, lines 11453-11588
11453    var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
11454
11455    if (this.affixed != affix) {
11456      if (this.unpin != null) this.$element.css('top', '')
11457
11458      var affixType = 'affix' + (affix ? '-' + affix : '')
11459      var e         = $.Event(affixType + '.bs.affix')
11460
11461      this.$element.trigger(e)
11462
11463      if (e.isDefaultPrevented()) return
11464
11465      this.affixed = affix
11466      this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
11467
11468      this.$element
11469        .removeClass(Affix.RESET)
11470        .addClass(affixType)
11471        .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
11472    }
11473
11474    if (affix == 'bottom') {
11475      this.$element.offset({
11476        top: scrollHeight - height - offsetBottom
11477      })
11478    }
11479  }
11480
11481
11482  // AFFIX PLUGIN DEFINITION
11483  // =======================
11484
11485  function Plugin(option) {
11486    return this.each(function () {
11487      var $this   = $(this)
11488      var data    = $this.data('bs.affix')
11489      var options = typeof option == 'object' && option
11490
11491      if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
11492      if (typeof option == 'string') data[option]()
11493    })
11494  }
11495
11496  var old = $.fn.affix
11497
11498  $.fn.affix             = Plugin
11499  $.fn.affix.Constructor = Affix
11500
11501
11502  // AFFIX NO CONFLICT
11503  // =================
11504
11505  $.fn.affix.noConflict = function () {
11506    $.fn.affix = old
11507    return this
11508  }
11509
11510
11511  // AFFIX DATA-API
11512  // ==============
11513
11514  $(window).on('load', function () {
11515    $('[data-spy="affix"]').each(function () {
11516      var $spy = $(this)
11517      var data = $spy.data()
11518
11519      data.offset = data.offset || {}
11520
11521      if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
11522      if (data.offsetTop    != null) data.offset.top    = data.offsetTop
11523
11524      Plugin.call($spy, data)
11525    })
11526  })
11527
11528}(jQuery);
11529
11530/*!
11531 * EventEmitter v4.2.11 - git.io/ee
11532 * Unlicense - http://unlicense.org/
11533 * Oliver Caldwell - http://oli.me.uk/
11534 * @preserve
11535 */
11536
11537;(function () {
11538    'use strict';
11539
11540    /**
11541     * Class for managing events.
11542     * Can be extended to provide event functionality in other classes.
11543     *
11544     * @class EventEmitter Manages event registering and emitting.
11545     */
11546    function EventEmitter() {}
11547
11548    // Shortcuts to improve speed and size
11549    var proto = EventEmitter.prototype;
11550    var exports = this;
11551    var originalGlobalValue = exports.EventEmitter;
11552
11553    /**
11554     * Finds the index of the listener for the event in its storage array.
11555     *
11556     * @param {Function[]} listeners Array of listeners to search through.
11557     * @param {Function} listener Method to look for.
11558     * @return {Number} Index of the specified listener, -1 if not found
11559     * @api private
11560     */
11561    function indexOfListener(listeners, listener) {
11562        var i = listeners.length;
11563        while (i--) {
11564            if (listeners[i].listener === listener) {
11565                return i;
11566            }
11567        }
11568
11569        return -1;
11570    }
11571
11572    /**
11573     * Alias a method while keeping the context correct, to allow for overwriting of target method.
11574     *
11575     * @param {String} name The name of the target method.
11576     * @return {Function} The aliased method
11577     * @api private
11578     */
11579    function alias(name) {
11580        return function aliasClosure() {
11581            return this[name].apply(this, arguments);
11582        };
11583    }
11584
11585    /**
11586     * Returns the listener array for the specified event.
11587     * Will initialise the event object and listener arrays if required.
11588     * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object c
vendor: 16,384 bytes, lines 11588-11995
11588ontaining bar and baz. But only if you have either defined them with defineEvent or added some listeners to them.
11589     * Each property in the object response is an array of listener functions.
11590     *
11591     * @param {String|RegExp} evt Name of the event to return the listeners from.
11592     * @return {Function[]|Object} All listener functions for the event.
11593     */
11594    proto.getListeners = function getListeners(evt) {
11595        var events = this._getEvents();
11596        var response;
11597        var key;
11598
11599        // Return a concatenated array of all matching events if
11600        // the selector is a regular expression.
11601        if (evt instanceof RegExp) {
11602            response = {};
11603            for (key in events) {
11604                if (events.hasOwnProperty(key) && evt.test(key)) {
11605                    response[key] = events[key];
11606                }
11607            }
11608        }
11609        else {
11610            response = events[evt] || (events[evt] = []);
11611        }
11612
11613        return response;
11614    };
11615
11616    /**
11617     * Takes a list of listener objects and flattens it into a list of listener functions.
11618     *
11619     * @param {Object[]} listeners Raw listener objects.
11620     * @return {Function[]} Just the listener functions.
11621     */
11622    proto.flattenListeners = function flattenListeners(listeners) {
11623        var flatListeners = [];
11624        var i;
11625
11626        for (i = 0; i < listeners.length; i += 1) {
11627            flatListeners.push(listeners[i].listener);
11628        }
11629
11630        return flatListeners;
11631    };
11632
11633    /**
11634     * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful.
11635     *
11636     * @param {String|RegExp} evt Name of the event to return the listeners from.
11637     * @return {Object} All listener functions for an event in an object.
11638     */
11639    proto.getListenersAsObject = function getListenersAsObject(evt) {
11640        var listeners = this.getListeners(evt);
11641        var response;
11642
11643        if (listeners instanceof Array) {
11644            response = {};
11645            response[evt] = listeners;
11646        }
11647
11648        return response || listeners;
11649    };
11650
11651    /**
11652     * Adds a listener function to the specified event.
11653     * The listener will not be added if it is a duplicate.
11654     * If the listener returns true then it will be removed after it is called.
11655     * If you pass a regular expression as the event name then the listener will be added to all events that match it.
11656     *
11657     * @param {String|RegExp} evt Name of the event to attach the listener to.
11658     * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
11659     * @return {Object} Current instance of EventEmitter for chaining.
11660     */
11661    proto.addListener = function addListener(evt, listener) {
11662        var listeners = this.getListenersAsObject(evt);
11663        var listenerIsWrapped = typeof listener === 'object';
11664        var key;
11665
11666        for (key in listeners) {
11667            if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) {
11668                listeners[key].push(listenerIsWrapped ? listener : {
11669                    listener: listener,
11670                    once: false
11671                });
11672            }
11673        }
11674
11675        return this;
11676    };
11677
11678    /**
11679     * Alias of addListener
11680     */
11681    proto.on = alias('addListener');
11682
11683    /**
11684     * Semi-alias of addListener. It will add a listener that will be
11685     * automatically removed after its first execution.
11686     *
11687     * @param {String|RegExp} evt Name of the event to attach the listener to.
11688     * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
11689     * @return {Object} Current instance of EventEmitter for chaining.
11690     */
11691    proto.addOnceListener = function addOnceListener(evt, listener) {
11692        return this.addListener(evt, {
11693            listener: listener,
11694            once: true
11695        });
11696    };
11697
11698    /**
11699     * Alias of addOnceListener.
11700     */
11701    proto.once = alias('addOnceListener');
11702
11703    /**
11704     * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad.
11705     * You need to tell it what event names should be matched by a regex.
11706     *
11707     * @param {String} evt Name of the event to create.
11708     * @return {Object} Current instance of EventEmitter for chaining.
11709     */
11710    proto.defineEvent = function defineEvent(evt) {
11711        this.getListeners(evt);
11712        return this;
11713    };
11714
11715    /**
11716     * Uses defineEvent to define multiple events.
11717     *
11718     * @param {String[]} evts An array of event names to define.
11719     * @return {Object} Current instance of EventEmitter for chaining.
11720     */
11721    proto.defineEvents = function defineEvents(evts) {
11722        for (var i = 0; i < evts.length; i += 1) {
11723            this.defineEvent(evts[i]);
11724        }
11725        return this;
11726    };
11727
11728    /**
11729     * Removes a listener function from the specified event.
11730     * When passed a regular expression as the event name, it will remove the listener from all events that match it.
11731     *
11732     * @param {String|RegExp} evt Name of the event to remove the listener from.
11733     * @param {Function} listener Method to remove from the event.
11734     * @return {Object} Current instance of EventEmitter for chaining.
11735     */
11736    proto.removeListener = function removeListener(evt, listener) {
11737        var listeners = this.getListenersAsObject(evt);
11738        var index;
11739        var key;
11740
11741        for (key in listeners) {
11742            if (listeners.hasOwnProperty(key)) {
11743                index = indexOfListener(listeners[key], listener);
11744
11745                if (index !== -1) {
11746                    listeners[key].splice(index, 1);
11747                }
11748            }
11749        }
11750
11751        return this;
11752    };
11753
11754    /**
11755     * Alias of removeListener
11756     */
11757    proto.off = alias('removeListener');
11758
11759    /**
11760     * Adds listeners in bulk using the manipulateListeners method.
11761     * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added.
11762     * You can also pass it a regular expression to add the array of listeners to all events that match it.
11763     * Yeah, this function does quite a bit. That's probably a bad thing.
11764     *
11765     * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once.
11766     * @param {Function[]} [listeners] An optional array of listener functions to add.
11767     * @return {Object} Current instance of EventEmitter for chaining.
11768     */
11769    proto.addListeners = function addListeners(evt, listeners) {
11770        // Pass through to manipulateListeners
11771        return this.manipulateListeners(false, evt, listeners);
11772    };
11773
11774    /**
11775     * Removes listeners in bulk using the manipulateListeners method.
11776     * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
11777     * You can also pass it an event name and an array of listeners to be removed.
11778     * You can also pass it a regular expression to remove the listeners from all events that match it.
11779     *
11780     * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once.
11781     * @param {Function[]} [listeners] An optional array of listener functions to remove.
11782     * @return {Object} Current instance of EventEmitter for chaining.
11783     */
11784    proto.removeListeners = function removeListeners(evt, listeners) {
11785        // Pass through to manipulateListeners
11786        return this.manipulateListeners(true, evt, listeners);
11787    };
11788
11789    /**
11790     * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level.
11791     * The first argument will determine if the listeners are removed (true) or added (false).
11792     * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
11793     * You can also pass it an event name and an array of listeners to be added/removed.
11794     * You can also pass it a regular expression to manipulate the listeners of all events that match it.
11795     *
11796     * @param {Boolean} remove True if you want to remove listeners, false if you want to add.
11797     * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once.
11798     * @param {Function[]} [listeners] An optional array of listener functions to add/remove.
11799     * @return {Object} Current instance of EventEmitter for chaining.
11800     */
11801    proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) {
11802        var i;
11803        var value;
11804        var single = remove ? this.removeListener : this.addListener;
11805        var multiple = remove ? this.removeListeners : this.addListeners;
11806
11807        // If evt is an object then pass each of its properties to this method
11808        if (typeof evt === 'object' && !(evt instanceof RegExp)) {
11809            for (i in evt) {
11810                if (evt.hasOwnProperty(i) && (value = evt[i])) {
11811                    // Pass the single listener straight through to the singular method
11812                    if (typeof value === 'function') {
11813                        single.call(this, i, value);
11814                    }
11815                    else {
11816                        // Otherwise pass back to the multiple function
11817                        multiple.call(this, i, value);
11818                    }
11819                }
11820            }
11821        }
11822        else {
11823            // So evt must be a string
11824            // And listeners must be an array of listeners
11825            // Loop over it and pass each one to the multiple method
11826            i = listeners.length;
11827            while (i--) {
11828                single.call(this, evt, listeners[i]);
11829            }
11830        }
11831
11832        return this;
11833    };
11834
11835    /**
11836     * Removes all listeners from a specified event.
11837     * If you do not specify an event then all listeners will be removed.
11838     * That means every event will be emptied.
11839     * You can also pass a regex to remove all events that match it.
11840     *
11841     * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.
11842     * @return {Object} Current instance of EventEmitter for chaining.
11843     */
11844    proto.removeEvent = function removeEvent(evt) {
11845        var type = typeof evt;
11846        var events = this._getEvents();
11847        var key;
11848
11849        // Remove different things depending on the state of evt
11850        if (type === 'string') {
11851            // Remove all listeners for the specified event
11852            delete events[evt];
11853        }
11854        else if (evt instanceof RegExp) {
11855            // Remove all events matching the regex.
11856            for (key in events) {
11857                if (events.hasOwnProperty(key) && evt.test(key)) {
11858                    delete events[key];
11859                }
11860            }
11861        }
11862        else {
11863            // Remove all listeners in all events
11864            delete this._events;
11865        }
11866
11867        return this;
11868    };
11869
11870    /**
11871     * Alias of removeEvent.
11872     *
11873     * Added to mirror the node API.
11874     */
11875    proto.removeAllListeners = alias('removeEvent');
11876
11877    /**
11878     * Emits an event of your choice.
11879     * When emitted, every listener attached to that event will be executed.
11880     * If you pass the optional argument array then those arguments will be passed to every listener upon execution.
11881     * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.
11882     * So they will not arrive within the array on the other side, they will be separate.
11883     * You can also pass a regular expression to emit to all events that match it.
11884     *
11885     * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
11886     * @param {Array} [args] Optional array of arguments to be passed to each listener.
11887     * @return {Object} Current instance of EventEmitter for chaining.
11888     */
11889    proto.emitEvent = function emitEvent(evt, args) {
11890        var listeners = this.getListenersAsObject(evt);
11891        var listener;
11892        var i;
11893        var key;
11894        var response;
11895
11896        for (key in listeners) {
11897            if (listeners.hasOwnProperty(key)) {
11898                i = listeners[key].length;
11899
11900                while (i--) {
11901                    // If the listener returns true then it shall be removed from the event
11902                    // The function is executed either with a basic call or an apply if there is an args array
11903                    listener = listeners[key][i];
11904
11905                    if (listener.once === true) {
11906                        this.removeListener(evt, listener.listener);
11907                    }
11908
11909                    response = listener.listener.apply(this, args || []);
11910
11911                    if (response === this._getOnceReturnValue()) {
11912                        this.removeListener(evt, listener.listener);
11913                    }
11914                }
11915            }
11916        }
11917
11918        return this;
11919    };
11920
11921    /**
11922     * Alias of emitEvent
11923     */
11924    proto.trigger = alias('emitEvent');
11925
11926    /**
11927     * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on.
11928     * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.
11929     *
11930     * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
11931     * @param {...*} Optional additional arguments to be passed to each listener.
11932     * @return {Object} Current instance of EventEmitter for chaining.
11933     */
11934    proto.emit = function emit(evt) {
11935        var args = Array.prototype.slice.call(arguments, 1);
11936        return this.emitEvent(evt, args);
11937    };
11938
11939    /**
11940     * Sets the current value to check against when executing listeners. If a
11941     * listeners return value matches the one set here then it will be removed
11942     * after execution. This value defaults to true.
11943     *
11944     * @param {*} value The new value to check for when executing listeners.
11945     * @return {Object} Current instance of EventEmitter for chaining.
11946     */
11947    proto.setOnceReturnValue = function setOnceReturnValue(value) {
11948        this._onceReturnValue = value;
11949        return this;
11950    };
11951
11952    /**
11953     * Fetches the current value to check against when executing listeners. If
11954     * the listeners return value matches this one then it should be removed
11955     * automatically. It will return true by default.
11956     *
11957     * @return {*|Boolean} The current value to check for or the default, true.
11958     * @api private
11959     */
11960    proto._getOnceReturnValue = function _getOnceReturnValue() {
11961        if (this.hasOwnProperty('_onceReturnValue')) {
11962            return this._onceReturnValue;
11963        }
11964        else {
11965            return true;
11966        }
11967    };
11968
11969    /**
11970     * Fetches the events object and creates one if required.
11971     *
11972     * @return {Object} The events storage object.
11973     * @api private
11974     */
11975    proto._getEvents = function _getEvents() {
11976        return this._events || (this._events = {});
11977    };
11978
11979    /**
11980     * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version.
11981     *
11982     * @return {Function} Non conflicting EventEmitter class.
11983     */
11984    EventEmitter.noConflict = function noConflict() {
11985        exports.EventEmitter = originalGlobalValue;
11986        return EventEmitter;
11987    };
11988
11989    // Expose the class either via AMD, CommonJS or the global object
11990    if (typeof define === 'function' && define.amd) {
11991        define(function () {
11992            return EventEmitter;
11993        });
11994    }
11995    else if (typeof 
11995module === 'object' && module.exports){
11996        module.exports = EventEmitter;
11997    }
11998    else {
11999        exports.EventEmitter = EventEmitter;
12000    }
12001}.call(this));
12002
12003/*!
12004 * eventie v1.0.6
12005 * event binding helper
12006 *   eventie.bind( elem, 'click', myFn )
12007 *   eventie.unbind( elem, 'click', myFn )
12008 * MIT license
12009 */
12010
12011/*jshint browser: true, undef: true, unused: true */
12012/*global define: false, module: false */
12013
12014( function( window ) {
12015
12016'use strict';
12017
12018var docElem = document.documentElement;
12019
12020var bind = function() {};
12021
12022function getIEEvent( obj ) {
12023  var event = window.event;
12024  // add event.target
12025  event.target = event.target || event.srcElement || obj;
12026  return event;
12027}
12028
12029if ( docElem.addEventListener ) {
12030  bind = function( obj, type, fn ) {
12031    obj.addEventListener( type, fn, false );
12032  };
12033} else if ( docElem.attachEvent ) {
12034  bind = function( obj, type, fn ) {
12035    obj[ type + fn ] = fn.handleEvent ?
12036      function() {
12037        var event = getIEEvent( obj );
12038        fn.handleEvent.call( fn, event );
12039      } :
12040      function() {
12041        var event = getIEEvent( obj );
12042        fn.call( obj, event );
12043      };
12044    obj.attachEvent( "on" + type, obj[ type + fn ] );
12045  };
12046}
12047
12048var unbind = function() {};
12049
12050if ( docElem.removeEventListener ) {
12051  unbind = function( obj, type, fn ) {
12052    obj.removeEventListener( type, fn, false );
12053  };
12054} else if ( docElem.detachEvent ) {
12055  unbind = function( obj, type, fn ) {
12056    obj.detachEvent( "on" + type, obj[ type + fn ] );
12057    try {
12058      delete obj[ type + fn ];
12059    } catch ( err ) {
12060      // can't delete window object properties
12061      obj[ type + fn ] = undefined;
12062    }
12063  };
12064}
12065
12066var eventie = {
12067  bind: bind,
12068  unbind: unbind
12069};
12070
12071// ----- module definition ----- //
12072
12073if ( typeof define === 'function' && define.amd ) {
12074  // AMD
12075  define( eventie );
12076} else if ( typeof exports === 'object' ) {
12077  // CommonJS
12078  module.exports = eventie;
12079} else {
12080  // browser global
12081  window.eventie = eventie;
12082}
12083
12084})( window );
12085
12086/*!
12087 * imagesLoaded v3.0.4
12088 * JavaScript is all like "You images are done yet or what?"
12089 */
12090
12091( function( window ) {
12092
12093'use strict';
12094
12095var $ = window.jQuery;
12096var console = window.console;
12097var hasConsole = typeof console !== 'undefined';
12098
12099// -------------------------- helpers -------------------------- //
12100
12101// extend objects
12102function extend( a, b ) {
12103  for ( var prop in b ) {
12104    a[ prop ] = b[ prop ];
12105  }
12106  return a;
12107}
12108
12109var objToString = Object.prototype.toString;
12110function isArray( obj ) {
12111  return objToString.call( obj ) === '[object Array]';
12112}
12113
12114// turn element or nodeList into an array
12115function makeArray( obj ) {
12116  var ary = [];
12117  if ( isArray( obj ) ) {
12118    // use object if already an array
12119    ary = obj;
12120  } else if ( typeof obj.length === 'number' ) {
12121    // convert nodeList to array
12122    for ( var i=0, len = obj.length; i < len; i++ ) {
12123      ary.push( obj[i] );
12124    }
12125  } else {
12126    // array of single index
12127    ary.push( obj );
12128  }
12129  return ary;
12130}
12131
12132// --------------------------  -------------------------- //
12133
12134function defineImagesLoaded( EventEmitter, eventie ) {
12135
12136  /**
12137   * @param {Array, Element, NodeList, String} elem
12138   * @param {Object or Function} options - if function, use as callback
12139   * @param {Function} onAlways - callback function
12140   */
12141  function ImagesLoaded( elem, options, onAlways ) {
12142    // coerce ImagesLoaded() without new, to be new ImagesLoaded()
12143    if ( !( this instanceof ImagesLoaded ) ) {
12144      return new ImagesLoaded( elem, options );
12145    }
12146    // use elem as selector string
12147    if ( typeof elem === 'string' ) {
12148      elem = document.querySelectorAll( elem );
12149    }
12150
12151    this.elements = makeArray( elem );
12152    this.options = extend( {}, this.options );
12153
12154    if ( typeof options === 'function' ) {
12155      onAlways = options;
12156    } else {
12157      extend( this.options, options );
12158    }
12159
12160    if ( onAlways ) {
12161      this.on( 'always', onAlways );
12162    }
12163
12164    this.getImages();
12165
12166    if ( $ ) {
12167      // add jQuery Deferred object
12168      this.jqDeferred = new $.Deferred();
12169    }
12170
12171    // HACK check async to allow time to bind listeners
12172    var _this = this;
12173    setTimeout( function() {
12174      _this.check();
12175    });
12176  }
12177
12178  ImagesLoaded.prototype = new EventEmitter();
12179
12180  ImagesLoaded.prototype.options = {};
12181
12182  ImagesLoaded.prototype.getImages = function() {
12183    this.images = [];
12184
12185    // filter & find items if we have an item selector
12186    for ( var i=0, len = this.elements.length; i < len; i++ ) {
12187      var elem = this.elements[i];
12188      // filter siblings
12189      if ( elem.nodeName === 'IMG' ) {
12190        this.addImage( elem );
12191      }
12192      // find children
12193      var childElems = elem.querySelectorAll('img');
12194      // concat childElems to filterFound array
12195      for ( var j=0, jLen = childElems.length; j < jLen; j++ ) {
12196        var img = childElems[j];
12197        this.addImage( img );
12198      }
12199    }
12200  };
12201
12202  /**
12203   * @param {Image} img
12204   */
12205  ImagesLoaded.prototype.addImage = function( img ) {
12206    var loadingImage = new LoadingImage( img );
12207    this.images.push( loadingImage );
12208  };
12209
12210  ImagesLoaded.prototype.check = function() {
12211    var _this = this;
12212    var checkedCount = 0;
12213    var length = this.images.length;
12214    this.hasAnyBroken = false;
12215    // complete if no images
12216    if ( !length ) {
12217      this.complete();
12218      return;
12219    }
12220
12221    function onConfirm( image, message ) {
12222      if ( _this.options.debug && hasConsole ) {
12223        console.log( 'confirm', image, message );
12224      }
12225
12226      _this.progress( image );
12227      checkedCount++;
12228      if ( checkedCount === length ) {
12229        _this.complete();
12230      }
12231      return true; // bind once
12232    }
12233
12234    for ( var i=0; i < length; i++ ) {
12235      var loadingImage = this.images[i];
12236      loadingImage.on( 'confirm', onConfirm );
12237      loadingImage.check();
12238    }
12239  };
12240
12241  ImagesLoaded.prototype.progress = function( image ) {
12242    this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;
12243    // HACK - Chrome triggers event before object properties have changed. #83
12244    var _this = this;
12245    setTimeout( function() {
12246      _this.emit( 'progress', _this, image );
12247      if ( _this.jqDeferred ) {
12248        _this.jqDeferred.notify( _this, image );
12249      }
12250    });
12251  };
12252
12253  ImagesLoaded.prototype.complete = function() {
12254    var eventName = this.hasAnyBroken ? 'fail' : 'done';
12255    this.isComplete = true;
12256    var _this = this;
12257    // HACK - another setTimeout so that confirm happens after progress
12258    setTimeout( function() {
12259      _this.emit( eventName, _this );
12260      _this.emit( 'always', _this );
12261      if ( _this.jqDeferred ) {
12262        var jqMethod = _this.hasAnyBroken ? 'reject' : 'resolve';
12263        _this.jqDeferred[ jqMethod ]( _this );
12264      }
12265    });
12266  };
12267
12268  // -------------------------- jquery -------------------------- //
12269
12270  if ( $ ) {
12271    $.fn.imagesLoaded = function( options, callback ) {
12272      var instance = new ImagesLoaded( this, options, callback );
12273      return instance.jqDeferred.promise( $(this) );
12274    };
12275  }
12276
12277
12278  // --------------------------  -------------------------- //
12279
12280  var cache = {};
12281
12282  function LoadingImage( img ) {
12283    this.img = img;
12284  }
12285
12286  LoadingImage.prototype = new EventEmitter();
12287
12288  LoadingImage.prototype.check = function() {
12289    // first check cached any previous images that have same src
12290    var cached = cache[ this.img.src ];
12291    if ( cached ) {
12292      this.useCached( cached );
12293      return;
12294    }
12295    // add this to cache
12296    cache[ this.img.src ] = this;
12297
12298    // If complete is true and browser supports natural sizes,
12299    // try to check for image status manually.
12300    if ( this.img.complete && this.img.naturalWidth !== undefined ) {
12301      // report based on naturalWidth
12302      this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
12303      return;
12304    }
12305
12306    // If none of the checks above matched, simulate loading on detached element.
12307    var proxyImage = this.proxyImage = new Image();
12308    eventie.bind( proxyImage, 'load', this );
12309    eventie.bind( proxyImage, 'error', this );
12310    proxyImage.src = this.img.src;
12311  };
12312
12313  LoadingImage.prototype.useCached = function( cached ) {
12314    if ( cached.isConfirmed ) {
12315      this.confirm( cached.isLoaded, 'cached was confirmed' );
12316    } else {
12317      var _this = this;
12318      cached.on( 'confirm', function( image ) {
12319        _this.confirm( image.isLoaded, 'cache emitted confirmed' );
12320        return true; // bind once
12321      });
12322    }
12323  };
12324
12325  LoadingImage.prototype.confirm = function( isLoaded, message ) {
12326    this.isConfirmed = true;
12327    this.isLoaded = isLoaded;
12328    this.emit( 'confirm', this, message );
12329  };
12330
12331  // trigger specified handler for event type
12332  LoadingImage.prototype.handleEvent = function( event ) {
12333    var method = 'on' + event.type;
12334    if ( this[ method ] ) {
12335      this[ method ]( event );
12336    }
12337  };
12338
12339  LoadingImage.prototype.onload = function() {
12340    this.confirm( true, 'onload' );
12341    this.unbindProxyEvents();
12342  };
12343
12344  LoadingImage.prototype.onerror = function() {
12345    this.confirm( false, 'onerror' );
12346    this.unbindProxyEvents();
12347  };
12348
12349  LoadingImage.prototype.unbindProxyEvents = function() {
12350    eventie.unbind( this.proxyImage, 'load', this );
12351    eventie.unbind( this.proxyImage, 'error', this );
12352  };
12353
12354  // -----  ----- //
12355
12356  return ImagesLoaded;
12357}
12358
12359// -------------------------- transport -------------------------- //
12360
12361if ( typeof define === 'function' && define.amd ) {
12362  // AMD
12363  define( [
12364      'eventEmitter/EventEmitter',
12365      'eventie/eventie'
12366    ],
12367    defineImagesLoaded );
12368} else {
12369  // browser global
12370  window.imagesLoaded = defineImagesLoaded(
12371    window.EventEmitter,
12372    window.eventie
12373  );
12374}
12375
12376})( window );
12377
12378/*!
12379 * jQuery Breakpoint plugin v4.6.4
12380 * http://github.com/lesjames/breakpoint
12381 *
12382 * MIT License
12383 */
12384
12385(function (factory) {
12386
12387    if (typeof define === 'function' && define.amd) {
12388
12389        // AMD. Register as an anonymous module.
12390        define(['jquery', 'imagesloaded', 'eventEmitter/EventEmitter'], factory);
12391
12392    } else {
12393
12394        // Browser globals
12395        factory(window.jQuery, window.imagesLoaded, window.EventEmitter);
12396
12397    }
12398
12399}(function ($, imagesLoaded, EventEmitter) {
12400
12401    // breakpoint functions
12402    // ==========================================================================
12403
12404    // some craxy regex to deal with how browsers pass the JSON through CSS
12405    function removeQuotes(string) {
12406        if (typeof string === 'string' || string instanceof String) {
12407            string = string.replace(/^['"]+|\s+|\\|(;\s?})+|['"]$/g, '');
12408        }
12409        return string;
12410    }
12411
12412    // get the breakpoint labels from the body's css generated content
12413    function getBreakpoint() {
12414
12415        var style = null;
12416
12417        // modern browser can read the label
12418        if (window.getComputedStyle && window.getComputedStyle(document.body, '::before')) {
12419
12420            // grab json from css generated content
12421            style = window.getComputedStyle(document.body, '::before');
12422            style = style.content;
12423
12424        } else {
12425
12426            // older browsers need some help
12427            var getComputedFallback = function(el) {
12428                this.el = el;
12429                this.getPropertyValue = function(prop) {
12430                    var re = /(\-([a-z]){1})/g;
12431                    if (re.test(prop)) {
12432                        prop = prop.replace(re, function () {
12433                            return arguments[2].toUpperCase();
12434                        });
12435                    }
12436                    return el.currentStyle[prop] ? el.currentStyle[prop] : null;
12437                };
12438                return this;
12439            };
12440
12441            // fallback label is added as a font-family to the head, thanks Jeremy Keith
12442            style = getComputedFallback(document.getElementsByTagName('head')[0]);
12443            style = style.getPropertyValue('font-family');
12444
12445        }
12446
12447        // parse that sucka and return it
12448        return JSON.parse(removeQuotes(style));
12449
12450    }
12451
12452    // finds the source of an image by matching breakpoint label to image data attr
12453    function findSource($image, set) {
12454
12455        // try the current breakpoint first
12456        var src = $image.attr('data-' + set.options.prefix + set.breakpoint.current),
12457            i = set.breakpoint.position - 1;
12458
12459        // if no match is found walk backwards through the
12460        // labels array until a matching data attr is found
12461        if (src === undefined) {
12462            for (i; i >= 0; i = i - 1) {
12463                src = $image.attr('data-' + set.options.prefix + set.breakpoint.all[i]);
12464                if (src !== undefined) {
12465                    break;
12466                }
12467            }
12468        }
12469
12470        return src;
12471    }
12472
12473    function setSource($image, set) {
12474        var src = findSource($image, set);
12475        if (src) {
12476            // cached images don't fire load sometimes, so we reset src
12477            $image.attr('src', 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==');
12478            $image.attr('src', src);
12479
12480        }
12481        return $image;
12482    }
12483
12484    // callback and deferred execution
12485    function breakpointComplete(set) {
12486
12487        // this requires imagesLoaded and that requires querySelector
12488        if (imagesLoaded && document.querySelectorAll && set.images.length > 0) {
12489
12490            var load = imagesLoaded(set.images);
12491
12492            load.on('done', function ( instance ) {
12493                set.dfd.resolve( set.breakpoint, instance );
12494                if ( $.isFunction( set.callback ) ) {
12495                    set.callback.call( null, set.breakpoint, instance );
12496                }
12497            });
12498
12499            load.on('fail', function ( instance ) {
12500                set.dfd.reject( set.breakpoint, instance );
12501            });
12502
12503            load.on('progress', function( instance, image ) {
12504                set.dfd.notify( set.breakpoint, instance, image );
12505            });
12506
12507        } else {
12508
12509            // no images here or imagesLoaded isn't loaded,
12510            // just send back the breakpoint info
12511            set.dfd.resolve( set.breakpoint );
12512            if ( $.isFunction( set.callback ) ) {
12513                set.callback.call( null, set.breakpoint );
12514            }
12515
12516        }
12517
12518    }
12519
12520
12521    // Breakpoint Constructor
12522    // ==========================================================================
12523
12524    function BreakpointImages( images ) {
12525
12526        // keep a reference to this
12527        var _this = this;
12528
12529        // store the selected images
12530        this.images = images;
12531
12532        // create callback and deferred
12533        this.callback = null;
12534        this.dfd = $.Deferred();
12535
12536        // breakpoint default options
12537        this.options = {
12538            prefix: '',
12539            debug: false
12540        };
12541
12542        // check to see if the breakpoint has changed
12543        this.checkBreakpoint = function () {
12544
12545            // grab the latest breakpoint so we can see it if updated
12546            var latestBreakpoint = getBreakpoint();
12547
12548            // if the breakpoint is set and it matches the previous value bail out
12549            if (_this.breakpoint && _this.breakpoint.current === latestBreakpoint.current) {
12550                return;
12551            }
12552
12553            // breakpoint is new so save it
12554            _this.breakpoint = latestBreakpoint;
12555            _this.processImages();
12556        };
12557
12558        // process the images with the current breakpoint
12559        this.processImages = function () {
12560
12561            if (_this.images.length > 0) {
12562                _this.images.each(function () {
12563                    setSource( $(this), _this );
12564                });
12565            }
12566            breakpointComplete(_this);
12567        };
12568
12569        // init event listener
12570        this.on('breakpoint.init', function () {
12571
12572            _this.checkBreakpoint();
12573
12574            // return true removes this listener
12575            return true;
12576
12577        });
12578
12579        // window resize listener
12580        this.on('breakpoint.update', _this.checkBreakpoint);
12581
12582        // for removing the resize listener
12583        this.removeEvent = function () {
12584            _this.off('breakpoint.update', _this.checkBreakpoint);
12585        };
12586
12587    }
12588
12589    // add event methods
12590    BreakpointImages.prototype = new EventEmitter();
12591
12592
12593    // define the plugin
12594    // ==========================================================================
12595
12596    $.fn.breakpoint = function (options, callback) {
12597
12598        var $images = [];
12599
12600        if (this[0] !== document) {
12601            // reduce selection to only images
12602            $images = this.find('img').add( this.filter('img') );
12603        }
12604
12605        // create an instance and pass it selected images
12606        var breakpointImages = new BreakpointImages( $images );
12607
12608        // if callback passed as only argument
12609        if ( $.isFunction( options ) ) {
12610            callback = options;
12611            options = {};
12612        }
12613
12614        // store options and callback on instance
12615        breakpointImages.options = $.extend({}, breakpointImages.options, options);
12616        breakpointImages.callback = callback;
12617
12618
12619        // event bindings
12620        // ==========================================================================
12621
12622        // get things started
12623        $(document).ready(function () {
12624            breakpointImages.trigger('breakpoint.init');
12625        });
12626
12627        // reevaluate breakpoint when window resizes
12628        $(window).on('resize.breakpoint', function () {
12629            breakpointImages.trigger('breakpoint.update');
12630        });
12631
12632        // remove listeners on unload
12633        $(window).on('unload.breakpoint', function () {
12634            $(window).off('.breakpoint');
12635            breakpointImages.removeEvent();
12636        });
12637
12638        if (breakpointImages.options.debug) {
12639
12640            // if debug return functions for testing
12641            return {
12642                breakpointImages: breakpointImages,
12643                removeQuotes: removeQuotes,
12644                getBreakpoint: getBreakpoint,
12645                findSource: findSource,
12646                setSource: setSource
12647            };
12648
12649        } else {
12650
12651            // return the deferred and attach it to the instance
12652            return breakpointImages.dfd.promise( breakpointImages );
12653
12654        }
12655
12656    };
12657
12658}));
12659/*!
12660 * classie v1.0.1
12661 * class helper functions
12662 * from bonzo https://github.com/ded/bonzo
12663 * MIT license
12664 * 
12665 * classie.has( elem, 'my-class' ) -> true/false
12666 * classie.add( elem, 'my-new-class' )
12667 * classie.remove( elem, 'my-unwanted-class' )
12668 * classie.toggle( elem, 'my-class' )
12669 */
12670
12671/*jshint browser: true, strict: true, undef: true, unused: true */
12672/*global define: false, module: false */
12673
12674( function( window ) {
12675
12676'use strict';
12677
12678// class helper functions from bonzo https://github.com/ded/bonzo
12679
12680function classReg( className ) {
12681  return new RegExp("(^|\\s+)" + className + "(\\s+|$)");
12682}
12683
12684// classList support for class management
12685// altho to be fair, the api sucks because it won't accept multiple classes at once
12686var hasClass, addClass, removeClass;
12687
12688if ( 'classList' in document.documentElement ) {
12689  hasClass = function( elem, c ) {
12690    return elem.classList.contains( c );
12691  };
12692  addClass = function( elem, c ) {
12693    elem.classList.add( c );
12694  };
12695  removeClass = function( elem, c ) {
12696    elem.classList.remove( c );
12697  };
12698}
12699else {
12700  hasClass = function( elem, c ) {
12701    return classReg( c ).test( elem.className );
12702  };
12703  addClass = function( elem, c ) {
12704    if ( !hasClass( elem, c ) ) {
12705      elem.className = elem.className + ' ' + c;
12706    }
12707  };
12708  removeClass = function( elem, c ) {
12709    elem.className = elem.className.replace( classReg( c ), ' ' );
12710  };
12711}
12712
12713function toggleClass( elem, c ) {
12714  var fn = hasClass( elem, c ) ? removeClass : addClass;
12715  fn( elem, c );
12716}
12717
12718var classie = {
12719  // full names
12720  hasClass: hasClass,
12721  addClass: addClass,
12722  removeClass: removeClass,
12723  toggleClass: toggleClass,
12724  // short names
12725  has: hasClass,
12726  add: addClass,
12727  remove: removeClass,
12728  toggle: toggleClass
12729};
12730
12731// transport
12732if ( typeof define === 'function' && define.amd ) {
12733  // AMD
12734  define( classie );
12735} else if ( typeof exports === 'object' ) {
12736  // CommonJS
12737  module.exports = classie;
12738} else {
12739  // browser global
12740  window.classie = classie;
12741}
12742
12743})( window );
12744
12745/*!
12746 * Modernizr v2.6.3
12747 * www.modernizr.com
12748 *
12749 * Copyright (c) Faruk Ates, Paul Irish, Alex Sexton
12750 * Available under the BSD and MIT licenses: www.modernizr.com/license/
12751 */
12752
12753/*
12754 * Modernizr tests which native CSS3 and HTML5 features are available in
12755 * the current UA and makes the results available to you in two ways:
12756 * as properties on a global Modernizr object, and as classes on the
12757 * <html> element. This information allows you to progressively enhance
12758 * your pages with a granular level of control over the experience.
12759 *
12760 * Modernizr has an optional (not included) conditional resource loader
12761 * called Modernizr.load(), based on Yepnope.js (yepnopejs.com).
12762 * To get a build that includes Modernizr.load(), as well as choosing
12763 * which tests to include, go to www.modernizr.com/download/
12764 *
12765 * Authors        Faruk Ates, Paul Irish, Alex Sexton
12766 * Contributors   Ryan Seddon, Ben Alman
12767 */
12768
12769window.Modernizr = (function( window, document, undefined ) {
12770
12771    var version = '2.6.3',
12772
12773    Modernizr = {},
12774
12775    /*>>cssclasses*/
12776    // option for enabling the HTML classes to be added
12777    enableClasses = true,
12778    /*>>cssclasses*/
12779
12780    docElement = document.documentElement,
12781
12782    /**
12783     * Create our "modernizr" element that we do most feature tests on.
12784     */
12785    mod = 'modernizr',
12786    modElem = document.createElement(mod),
12787    mStyle = modElem.style,
12788
12789    /**
12790     * Create the input element for various Web Forms feature tests.
12791     */
12792    inputElem /*>>inputelem*/ = document.createElement('input') /*>>inputelem*/ ,
12793
12794    /*>>smile*/
12795    smile = ':)',
12796    /*>>smile*/
12797
12798    toString = {}.toString,
12799
12800    // TODO :: make the prefixes more granular
12801    /*>>prefixes*/
12802    // List of property values to set for css tests. See ticket #21
12803    prefixes = ' -webkit- -moz- -o- -ms- '.split(' '),
12804    /*>>prefixes*/
12805
12806    /*>>domprefixes*/
12807    // Following spec is to expose vendor-specific style properties as:
12808    //   elem.style.WebkitBorderRadius
12809    // and the following would be incorrect:
12810    //   elem.style.webkitBorderRadius
12811
12812    // Webkit ghosts their properties in lowercase but Opera & Moz do not.
12813    // Microsoft uses a lowercase `ms` instead of the correct `Ms` in IE8+
12814    //   erik.eae.net/archives/2008/03/10/21.48.10/
12815
12816    // More here: github.com/Modernizr/Modernizr/issues/issue/21
12817    omPrefixes = 'Webkit Moz O ms',
12818
12819    cssomPrefixes = omPrefixes.split(' '),
12820
12821    domPrefixes = omPrefixes.toLowerCase().split(' '),
12822    /*>>domprefixes*/
12823
12824    /*>>ns*/
12825    ns = {'svg': 'http://www.w3.org/2000/svg'},
12826    /*>>ns*/
12827
12828    tests = {},
12829    inputs = {},
12830    attrs = {},
12831
12832    classes = [],
12833
12834    slice = classes.slice,
12835
12836    featureName, // used in testing loop
12837
12838
12839    /*>>
vendor: 2,981 bytes, lines 12839-12903
12839teststyles*/
12840    // Inject element with style element and some CSS rules
12841    injectElementWithStyles = function( rule, callback, nodes, testnames ) {
12842
12843      var style, ret, node, docOverflow,
12844          div = document.createElement('div'),
12845          // After page load injecting a fake body doesn't work so check if body exists
12846          body = document.body,
12847          // IE6 and 7 won't return offsetWidth or offsetHeight unless it's in the body element, so we fake it.
12848          fakeBody = body || document.createElement('body');
12849
12850      if ( parseInt(nodes, 10) ) {
12851          // In order not to give false positives we create a node for each test
12852          // This also allows the method to scale for unspecified uses
12853          while ( nodes-- ) {
12854              node = document.createElement('div');
12855              node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
12856              div.appendChild(node);
12857          }
12858      }
12859
12860      // <style> elements in IE6-9 are considered 'NoScope' elements and therefore will be removed
12861      // when injected with innerHTML. To get around this you need to prepend the 'NoScope' element
12862      // with a 'scoped' element, in our case the soft-hyphen entity as it won't mess with our measurements.
12863      // msdn.microsoft.com/en-us/library/ms533897%28VS.85%29.aspx
12864      // Documents served as xml will throw if using &shy; so use xml friendly encoded version. See issue #277
12865      style = ['&#173;','<style id="s', mod, '">', rule, '</style>'].join('');
12866      div.id = mod;
12867      // IE6 will false positive on some tests due to the style element inside the test div somehow interfering offsetHeight, so insert it into body or fakebody.
12868      // Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270
12869      (body ? div : fakeBody).innerHTML += style;
12870      fakeBody.appendChild(div);
12871      if ( !body ) {
12872          //avoid crashing IE8, if background image is used
12873          fakeBody.style.background = '';
12874          //Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible
12875          fakeBody.style.overflow = 'hidden';
12876          docOverflow = docElement.style.overflow;
12877          docElement.style.overflow = 'hidden';
12878          docElement.appendChild(fakeBody);
12879      }
12880
12881      ret = callback(div, rule);
12882      // If this is done after page load we don't want to remove the body so check if body exists
12883      if ( !body ) {
12884          fakeBody.parentNode.removeChild(fakeBody);
12885          docElement.style.overflow = docOverflow;
12886      } else {
12887          div.parentNode.removeChild(div);
12888      }
12889
12890      return !!ret;
12891
12892    },
12893    /*>>teststyles*/
12894
12895    /*>>mq*/
12896    // adapted from matchMedia polyfill
12897    // by Scott Jehl and Paul Irish
12898    // gist.github.com/786768
12899    testMediaQuery = function( mq ) {
12900
12901      var matchMedia = window.matchMedia || window.msMatchMedia;
12902      if ( matchMedia ) {
12903        return matchMedia(mq).matches
vendor: 14,824 bytes, lines 12903-13352
12903;
12904      }
12905
12906      var bool;
12907
12908      injectElementWithStyles('@media ' + mq + ' { #' + mod + ' { position: absolute; } }', function( node ) {
12909        bool = (window.getComputedStyle ?
12910                  getComputedStyle(node, null) :
12911                  node.currentStyle)['position'] == 'absolute';
12912      });
12913
12914      return bool;
12915
12916     },
12917     /*>>mq*/
12918
12919
12920    /*>>hasevent*/
12921    //
12922    // isEventSupported determines if a given element supports the given event
12923    // kangax.github.com/iseventsupported/
12924    //
12925    // The following results are known incorrects:
12926    //   Modernizr.hasEvent("webkitTransitionEnd", elem) // false negative
12927    //   Modernizr.hasEvent("textInput") // in Webkit. github.com/Modernizr/Modernizr/issues/333
12928    //   ...
12929    isEventSupported = (function() {
12930
12931      var TAGNAMES = {
12932        'select': 'input', 'change': 'input',
12933        'submit': 'form', 'reset': 'form',
12934        'error': 'img', 'load': 'img', 'abort': 'img'
12935      };
12936
12937      function isEventSupported( eventName, element ) {
12938
12939        element = element || document.createElement(TAGNAMES[eventName] || 'div');
12940        eventName = 'on' + eventName;
12941
12942        // When using `setAttribute`, IE skips "unload", WebKit skips "unload" and "resize", whereas `in` "catches" those
12943        var isSupported = eventName in element;
12944
12945        if ( !isSupported ) {
12946          // If it has no `setAttribute` (i.e. doesn't implement Node interface), try generic element
12947          if ( !element.setAttribute ) {
12948            element = document.createElement('div');
12949          }
12950          if ( element.setAttribute && element.removeAttribute ) {
12951            element.setAttribute(eventName, '');
12952            isSupported = is(element[eventName], 'function');
12953
12954            // If property was created, "remove it" (by setting value to `undefined`)
12955            if ( !is(element[eventName], 'undefined') ) {
12956              element[eventName] = undefined;
12957            }
12958            element.removeAttribute(eventName);
12959          }
12960        }
12961
12962        element = null;
12963        return isSupported;
12964      }
12965      return isEventSupported;
12966    })(),
12967    /*>>hasevent*/
12968
12969    // TODO :: Add flag for hasownprop ? didn't last time
12970
12971    // hasOwnProperty shim by kangax needed for Safari 2.0 support
12972    _hasOwnProperty = ({}).hasOwnProperty, hasOwnProp;
12973
12974    if ( !is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined') ) {
12975      hasOwnProp = function (object, property) {
12976        return _hasOwnProperty.call(object, property);
12977      };
12978    }
12979    else {
12980      hasOwnProp = function (object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */
12981        return ((property in object) && is(object.constructor.prototype[property], 'undefined'));
12982      };
12983    }
12984
12985    // Adapted from ES5-shim https://github.com/kriskowal/es5-shim/blob/master/es5-shim.js
12986    // es5.github.com/#x15.3.4.5
12987
12988    if (!Function.prototype.bind) {
12989      Function.prototype.bind = function bind(that) {
12990
12991        var target = this;
12992
12993        if (typeof target != "function") {
12994            throw new TypeError();
12995        }
12996
12997        var args = slice.call(arguments, 1),
12998            bound = function () {
12999
13000            if (this instanceof bound) {
13001
13002              var F = function(){};
13003              F.prototype = target.prototype;
13004              var self = new F();
13005
13006              var result = target.apply(
13007                  self,
13008                  args.concat(slice.call(arguments))
13009              );
13010              if (Object(result) === result) {
13011                  return result;
13012              }
13013              return self;
13014
13015            } else {
13016
13017              return target.apply(
13018                  that,
13019                  args.concat(slice.call(arguments))
13020              );
13021
13022            }
13023
13024        };
13025
13026        return bound;
13027      };
13028    }
13029
13030    /**
13031     * setCss applies given styles to the Modernizr DOM node.
13032     */
13033    function setCss( str ) {
13034        mStyle.cssText = str;
13035    }
13036
13037    /**
13038     * setCssAll extrapolates all vendor-specific css strings.
13039     */
13040    function setCssAll( str1, str2 ) {
13041        return setCss(prefixes.join(str1 + ';') + ( str2 || '' ));
13042    }
13043
13044    /**
13045     * is returns a boolean for if typeof obj is exactly type.
13046     */
13047    function is( obj, type ) {
13048        return typeof obj === type;
13049    }
13050
13051    /**
13052     * contains returns a boolean for if substr is found within str.
13053     */
13054    function contains( str, substr ) {
13055        return !!~('' + str).indexOf(substr);
13056    }
13057
13058    /*>>testprop*/
13059
13060    // testProps is a generic CSS / DOM property test.
13061
13062    // In testing support for a given CSS property, it's legit to test:
13063    //    `elem.style[styleName] !== undefined`
13064    // If the property is supported it will return an empty string,
13065    // if unsupported it will return undefined.
13066
13067    // We'll take advantage of this quick test and skip setting a style
13068    // on our modernizr element, but instead just testing undefined vs
13069    // empty string.
13070
13071    // Because the testing of the CSS property names (with "-", as
13072    // opposed to the camelCase DOM properties) is non-portable and
13073    // non-standard but works in WebKit and IE (but not Gecko or Opera),
13074    // we explicitly reject properties with dashes so that authors
13075    // developing in WebKit or IE first don't end up with
13076    // browser-specific content by accident.
13077
13078    function testProps( props, prefixed ) {
13079        for ( var i in props ) {
13080            var prop = props[i];
13081            if ( !contains(prop, "-") && mStyle[prop] !== undefined ) {
13082                return prefixed == 'pfx' ? prop : true;
13083            }
13084        }
13085        return false;
13086    }
13087    /*>>testprop*/
13088
13089    // TODO :: add testDOMProps
13090    /**
13091     * testDOMProps is a generic DOM property test; if a browser supports
13092     *   a certain property, it won't return undefined for it.
13093     */
13094    function testDOMProps( props, obj, elem ) {
13095        for ( var i in props ) {
13096            var item = obj[props[i]];
13097            if ( item !== undefined) {
13098
13099                // return the property name as a string
13100                if (elem === false) return props[i];
13101
13102                // let's bind a function
13103                if (is(item, 'function')){
13104                  // default to autobind unless override
13105                  return item.bind(elem || obj);
13106                }
13107
13108                // return the unbound function or obj or value
13109                return item;
13110            }
13111        }
13112        return false;
13113    }
13114
13115    /*>>testallprops*/
13116    /**
13117     * testPropsAll tests a list of DOM properties we want to check against.
13118     *   We specify literally ALL possible (known and/or likely) properties on
13119     *   the element including the non-vendor prefixed one, for forward-
13120     *   compatibility.
13121     */
13122    function testPropsAll( prop, prefixed, elem ) {
13123
13124        var ucProp  = prop.charAt(0).toUpperCase() + prop.slice(1),
13125            props   = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');
13126
13127        // did they call .prefixed('boxSizing') or are we just testing a prop?
13128        if(is(prefixed, "string") || is(prefixed, "undefined")) {
13129          return testProps(props, prefixed);
13130
13131        // otherwise, they called .prefixed('requestAnimationFrame', window[, elem])
13132        } else {
13133          props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
13134          return testDOMProps(props, prefixed, elem);
13135        }
13136    }
13137    /*>>testallprops*/
13138
13139
13140    /**
13141     * Tests
13142     * -----
13143     */
13144
13145    // The *new* flexbox
13146    // dev.w3.org/csswg/css3-flexbox
13147
13148    tests['flexbox'] = function() {
13149      return testPropsAll('flexWrap');
13150    };
13151
13152    // The *old* flexbox
13153    // www.w3.org/TR/2009/WD-css3-flexbox-20090723/
13154
13155    tests['flexboxlegacy'] = function() {
13156        return testPropsAll('boxDirection');
13157    };
13158
13159    // On the S60 and BB Storm, getContext exists, but always returns undefined
13160    // so we actually have to call getContext() to verify
13161    // github.com/Modernizr/Modernizr/issues/issue/97/
13162
13163    tests['canvas'] = function() {
13164        var elem = document.createElement('canvas');
13165        return !!(elem.getContext && elem.getContext('2d'));
13166    };
13167
13168    tests['canvastext'] = function() {
13169        return !!(Modernizr['canvas'] && is(document.createElement('canvas').getContext('2d').fillText, 'function'));
13170    };
13171
13172    // webk.it/70117 is tracking a legit WebGL feature detect proposal
13173
13174    // We do a soft detect which may false positive in order to avoid
13175    // an expensive context creation: bugzil.la/732441
13176
13177    tests['webgl'] = function() {
13178        return !!window.WebGLRenderingContext;
13179    };
13180
13181    /*
13182     * The Modernizr.touch test only indicates if the browser supports
13183     *    touch events, which does not necessarily reflect a touchscreen
13184     *    device, as evidenced by tablets running Windows 7 or, alas,
13185     *    the Palm Pre / WebOS (touch) phones.
13186     *
13187     * Additionally, Chrome (desktop) used to lie about its support on this,
13188     *    but that has since been rectified: crbug.com/36415
13189     *
13190     * We also test for Firefox 4 Multitouch Support.
13191     *
13192     * For more info, see: modernizr.github.com/Modernizr/touch.html
13193     */
13194
13195    tests['touch'] = function() {
13196        var bool;
13197
13198        if(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
13199          bool = true;
13200        } else {
13201          injectElementWithStyles(['@media (',prefixes.join('touch-enabled),('),mod,')','{#modernizr{top:9px;position:absolute}}'].join(''), function( node ) {
13202            bool = node.offsetTop === 9;
13203          });
13204        }
13205
13206        return bool;
13207    };
13208
13209
13210    // geolocation is often considered a trivial feature detect...
13211    // Turns out, it's quite tricky to get right:
13212    //
13213    // Using !!navigator.geolocation does two things we don't want. It:
13214    //   1. Leaks memory in IE9: github.com/Modernizr/Modernizr/issues/513
13215    //   2. Disables page caching in WebKit: webk.it/43956
13216    //
13217    // Meanwhile, in Firefox < 8, an about:config setting could expose
13218    // a false positive that would throw an exception: bugzil.la/688158
13219
13220    tests['geolocation'] = function() {
13221        return 'geolocation' in navigator;
13222    };
13223
13224
13225    tests['postmessage'] = function() {
13226      return !!window.postMessage;
13227    };
13228
13229
13230    // Chrome incognito mode used to throw an exception when using openDatabase
13231    // It doesn't anymore.
13232    tests['websqldatabase'] = function() {
13233      return !!window.openDatabase;
13234    };
13235
13236    // Vendors had inconsistent prefixing with the experimental Indexed DB:
13237    // - Webkit's implementation is accessible through webkitIndexedDB
13238    // - Firefox shipped moz_indexedDB before FF4b9, but since then has been mozIndexedDB
13239    // For speed, we don't test the legacy (and beta-only) indexedDB
13240    tests['indexedDB'] = function() {
13241      return !!testPropsAll("indexedDB", window);
13242    };
13243
13244    // documentMode logic from YUI to filter out IE8 Compat Mode
13245    //   which false positives.
13246    tests['hashchange'] = function() {
13247      return isEventSupported('hashchange', window) && (document.documentMode === undefined || document.documentMode > 7);
13248    };
13249
13250    // Per 1.6:
13251    // This used to be Modernizr.historymanagement but the longer
13252    // name has been deprecated in favor of a shorter and property-matching one.
13253    // The old API is still available in 1.6, but as of 2.0 will throw a warning,
13254    // and in the first release thereafter disappear entirely.
13255    tests['history'] = function() {
13256      return !!(window.history && history.pushState);
13257    };
13258
13259    tests['draganddrop'] = function() {
13260        var div = document.createElement('div');
13261        return ('draggable' in div) || ('ondragstart' in div && 'ondrop' in div);
13262    };
13263
13264    // FF3.6 was EOL'ed on 4/24/12, but the ESR version of FF10
13265    // will be supported until FF19 (2/12/13), at which time, ESR becomes FF17.
13266    // FF10 still uses prefixes, so check for it until then.
13267    // for more ESR info, see: mozilla.org/en-US/firefox/organizations/faq/
13268    tests['websockets'] = function() {
13269        return 'WebSocket' in window || 'MozWebSocket' in window;
13270    };
13271
13272
13273    // css-tricks.com/rgba-browser-support/
13274    tests['rgba'] = function() {
13275        // Set an rgba() color and check the returned value
13276
13277        setCss('background-color:rgba(150,255,150,.5)');
13278
13279        return contains(mStyle.backgroundColor, 'rgba');
13280    };
13281
13282    tests['hsla'] = function() {
13283        // Same as rgba(), in fact, browsers re-map hsla() to rgba() internally,
13284        //   except IE9 who retains it as hsla
13285
13286        setCss('background-color:hsla(120,40%,100%,.5)');
13287
13288        return contains(mStyle.backgroundColor, 'rgba') || contains(mStyle.backgroundColor, 'hsla');
13289    };
13290
13291    tests['multiplebgs'] = function() {
13292        // Setting multiple images AND a color on the background shorthand property
13293        //  and then querying the style.background property value for the number of
13294        //  occurrences of "url(" is a reliable method for detecting ACTUAL support for this!
13295
13296        setCss('background:url(https://),url(https://),red url(https://)');
13297
13298        // If the UA supports multiple backgrounds, there should be three occurrences
13299        //   of the string "url(" in the return value for elemStyle.background
13300
13301        return (/(url\s*\(.*?){3}/).test(mStyle.background);
13302    };
13303
13304
13305
13306    // this will false positive in Opera Mini
13307    //   github.com/Modernizr/Modernizr/issues/396
13308
13309    tests['backgroundsize'] = function() {
13310        return testPropsAll('backgroundSize');
13311    };
13312
13313    tests['borderimage'] = function() {
13314        return testPropsAll('borderImage');
13315    };
13316
13317
13318    // Super comprehensive table about all the unique implementations of
13319    // border-radius: muddledramblings.com/table-of-css3-border-radius-compliance
13320
13321    tests['borderradius'] = function() {
13322        return testPropsAll('borderRadius');
13323    };
13324
13325    // WebOS unfortunately false positives on this test.
13326    tests['boxshadow'] = function() {
13327        return testPropsAll('boxShadow');
13328    };
13329
13330    // FF3.0 will false positive on this test
13331    tests['textshadow'] = function() {
13332        return document.createElement('div').style.textShadow === '';
13333    };
13334
13335
13336    tests['opacity'] = function() {
13337        // Browsers that actually have CSS Opacity implemented have done so
13338        //  according to spec, which means their return values are within the
13339        //  range of [0.0,1.0] - including the leading zero.
13340
13341        setCssAll('opacity:.55');
13342
13343        // The non-literal . in this regex is intentional:
13344        //   German Chrome returns this value as 0,55
13345        // github.com/Modernizr/Modernizr/issues/#issue/59/comment/516632
13346        return (/^0.55$/).test(mStyle.opacity);
13347    };
13348
13349
13350    // Note, Android < 4 will pass this test, but can only animate
13351    //   a single property at a time
13352    //   
13352daneden.me/2011/12/putting-up-with-androids-bullshit/
vendor: 15,361 bytes, lines 13352-13751
13352
13353    tests['cssanimations'] = function() {
13354        return testPropsAll('animationName');
13355    };
13356
13357
13358    tests['csscolumns'] = function() {
13359        return testPropsAll('columnCount');
13360    };
13361
13362
13363    tests['cssgradients'] = function() {
13364        /**
13365         * For CSS Gradients syntax, please see:
13366         * webkit.org/blog/175/introducing-css-gradients/
13367         * developer.mozilla.org/en/CSS/-moz-linear-gradient
13368         * developer.mozilla.org/en/CSS/-moz-radial-gradient
13369         * dev.w3.org/csswg/css3-images/#gradients-
13370         */
13371
13372        var str1 = 'background-image:',
13373            str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));',
13374            str3 = 'linear-gradient(left top,#9f9, white);';
13375
13376        setCss(
13377             // legacy webkit syntax (FIXME: remove when syntax not in use anymore)
13378              (str1 + '-webkit- '.split(' ').join(str2 + str1) +
13379             // standard syntax             // trailing 'background-image:'
13380              prefixes.join(str3 + str1)).slice(0, -str1.length)
13381        );
13382
13383        return contains(mStyle.backgroundImage, 'gradient');
13384    };
13385
13386
13387    tests['cssreflections'] = function() {
13388        return testPropsAll('boxReflect');
13389    };
13390
13391
13392    tests['csstransforms'] = function() {
13393        return !!testPropsAll('transform');
13394    };
13395
13396
13397    tests['csstransforms3d'] = function() {
13398
13399        var ret = !!testPropsAll('perspective');
13400
13401        // Webkit's 3D transforms are passed off to the browser's own graphics renderer.
13402        //   It works fine in Safari on Leopard and Snow Leopard, but not in Chrome in
13403        //   some conditions. As a result, Webkit typically recognizes the syntax but
13404        //   will sometimes throw a false positive, thus we must do a more thorough check:
13405        if ( ret && 'webkitPerspective' in docElement.style ) {
13406
13407          // Webkit allows this media query to succeed only if the feature is enabled.
13408          // `@media (transform-3d),(-webkit-transform-3d){ ... }`
13409          injectElementWithStyles('@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}', function( node, rule ) {
13410            ret = node.offsetLeft === 9 && node.offsetHeight === 3;
13411          });
13412        }
13413        return ret;
13414    };
13415
13416
13417    tests['csstransitions'] = function() {
13418        return testPropsAll('transition');
13419    };
13420
13421
13422    /*>>fontface*/
13423    // @font-face detection routine by Diego Perini
13424    // javascript.nwbox.com/CSSSupport/
13425
13426    // false positives:
13427    //   WebOS github.com/Modernizr/Modernizr/issues/342
13428    //   WP7   github.com/Modernizr/Modernizr/issues/538
13429    tests['fontface'] = function() {
13430        var bool;
13431
13432        injectElementWithStyles('@font-face {font-family:"font";src:url("https://")}', function( node, rule ) {
13433          var style = document.getElementById('smodernizr'),
13434              sheet = style.sheet || style.styleSheet,
13435              cssText = sheet ? (sheet.cssRules && sheet.cssRules[0] ? sheet.cssRules[0].cssText : sheet.cssText || '') : '';
13436
13437          bool = /src/i.test(cssText) && cssText.indexOf(rule.split(' ')[0]) === 0;
13438        });
13439
13440        return bool;
13441    };
13442    /*>>fontface*/
13443
13444    // CSS generated content detection
13445    tests['generatedcontent'] = function() {
13446        var bool;
13447
13448        injectElementWithStyles(['#',mod,'{font:0/0 a}#',mod,':after{content:"',smile,'";visibility:hidden;font:3px/1 a}'].join(''), function( node ) {
13449          bool = node.offsetHeight >= 3;
13450        });
13451
13452        return bool;
13453    };
13454
13455
13456
13457    // These tests evaluate support of the video/audio elements, as well as
13458    // testing what types of content they support.
13459    //
13460    // We're using the Boolean constructor here, so that we can extend the value
13461    // e.g.  Modernizr.video     // true
13462    //       Modernizr.video.ogg // 'probably'
13463    //
13464    // Codec values from : github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845
13465    //                     thx to NielsLeenheer and zcorpan
13466
13467    // Note: in some older browsers, "no" was a return value instead of empty string.
13468    //   It was live in FF3.5.0 and 3.5.1, but fixed in 3.5.2
13469    //   It was also live in Safari 4.0.0 - 4.0.4, but fixed in 4.0.5
13470
13471    tests['video'] = function() {
13472        var elem = document.createElement('video'),
13473            bool = false;
13474
13475        // IE9 Running on Windows Server SKU can cause an exception to be thrown, bug #224
13476        try {
13477            if ( bool = !!elem.canPlayType ) {
13478                bool      = new Boolean(bool);
13479                bool.ogg  = elem.canPlayType('video/ogg; codecs="theora"')      .replace(/^no$/,'');
13480
13481                // Without QuickTime, this value will be `undefined`. github.com/Modernizr/Modernizr/issues/546
13482                bool.h264 = elem.canPlayType('video/mp4; codecs="avc1.42E01E"') .replace(/^no$/,'');
13483
13484                bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,'');
13485            }
13486
13487        } catch(e) { }
13488
13489        return bool;
13490    };
13491
13492    tests['audio'] = function() {
13493        var elem = document.createElement('audio'),
13494            bool = false;
13495
13496        try {
13497            if ( bool = !!elem.canPlayType ) {
13498                bool      = new Boolean(bool);
13499                bool.ogg  = elem.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,'');
13500                bool.mp3  = elem.canPlayType('audio/mpeg;')               .replace(/^no$/,'');
13501
13502                // Mimetypes accepted:
13503                //   developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements
13504                //   bit.ly/iphoneoscodecs
13505                bool.wav  = elem.canPlayType('audio/wav; codecs="1"')     .replace(/^no$/,'');
13506                bool.m4a  = ( elem.canPlayType('audio/x-m4a;')            ||
13507                              elem.canPlayType('audio/aac;'))             .replace(/^no$/,'');
13508            }
13509        } catch(e) { }
13510
13511        return bool;
13512    };
13513
13514
13515    // In FF4, if disabled, window.localStorage should === null.
13516
13517    // Normally, we could not test that directly and need to do a
13518    //   `('localStorage' in window) && ` test first because otherwise Firefox will
13519    //   throw bugzil.la/365772 if cookies are disabled
13520
13521    // Also in iOS5 Private Browsing mode, attempting to use localStorage.setItem
13522    // will throw the exception:
13523    //   QUOTA_EXCEEDED_ERRROR DOM Exception 22.
13524    // Peculiarly, getItem and removeItem calls do not throw.
13525
13526    // Because we are forced to try/catch this, we'll go aggressive.
13527
13528    // Just FWIW: IE8 Compat mode supports these features completely:
13529    //   www.quirksmode.org/dom/html5.html
13530    // But IE8 doesn't support either with local files
13531
13532    tests['localstorage'] = function() {
13533        try {
13534            localStorage.setItem(mod, mod);
13535            localStorage.removeItem(mod);
13536            return true;
13537        } catch(e) {
13538            return false;
13539        }
13540    };
13541
13542    tests['sessionstorage'] = function() {
13543        try {
13544            sessionStorage.setItem(mod, mod);
13545            sessionStorage.removeItem(mod);
13546            return true;
13547        } catch(e) {
13548            return false;
13549        }
13550    };
13551
13552
13553    tests['webworkers'] = function() {
13554        return !!window.Worker;
13555    };
13556
13557
13558    tests['applicationcache'] = function() {
13559        return !!window.applicationCache;
13560    };
13561
13562
13563    // Thanks to Erik Dahlstrom
13564    tests['svg'] = function() {
13565        return !!document.createElementNS && !!document.createElementNS(ns.svg, 'svg').createSVGRect;
13566    };
13567
13568    // specifically for SVG inline in HTML, not within XHTML
13569    // test page: paulirish.com/demo/inline-svg
13570    tests['inlinesvg'] = function() {
13571      var div = document.createElement('div');
13572      div.innerHTML = '<svg/>';
13573      return (div.firstChild && div.firstChild.namespaceURI) == ns.svg;
13574    };
13575
13576    // SVG SMIL animation
13577    tests['smil'] = function() {
13578        return !!document.createElementNS && /SVGAnimate/.test(toString.call(document.createElementNS(ns.svg, 'animate')));
13579    };
13580
13581    // This test is only for clip paths in SVG proper, not clip paths on HTML content
13582    // demo: srufaculty.sru.edu/david.dailey/svg/newstuff/clipPath4.svg
13583
13584    // However read the comments to dig into applying SVG clippaths to HTML content here:
13585    //   github.com/Modernizr/Modernizr/issues/213#issuecomment-1149491
13586    tests['svgclippaths'] = function() {
13587        return !!document.createElementNS && /SVGClipPath/.test(toString.call(document.createElementNS(ns.svg, 'clipPath')));
13588    };
13589
13590    /*>>webforms*/
13591    // input features and input types go directly onto the ret object, bypassing the tests loop.
13592    // Hold this guy to execute in a moment.
13593    function webforms() {
13594        /*>>input*/
13595        // Run through HTML5's new input attributes to see if the UA understands any.
13596        // We're using f which is the <input> element created early on
13597        // Mike Taylr has created a comprehensive resource for testing these attributes
13598        //   when applied to all input types:
13599        //   miketaylr.com/code/input-type-attr.html
13600        // spec: www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
13601
13602        // Only input placeholder is tested while textarea's placeholder is not.
13603        // Currently Safari 4 and Opera 11 have support only for the input placeholder
13604        // Both tests are available in feature-detects/forms-placeholder.js
13605        Modernizr['input'] = (function( props ) {
13606            for ( var i = 0, len = props.length; i < len; i++ ) {
13607                attrs[ props[i] ] = !!(props[i] in inputElem);
13608            }
13609            if (attrs.list){
13610              // safari false positive's on datalist: webk.it/74252
13611              // see also github.com/Modernizr/Modernizr/issues/146
13612              attrs.list = !!(document.createElement('datalist') && window.HTMLDataListElement);
13613            }
13614            return attrs;
13615        })('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' '));
13616        /*>>input*/
13617
13618        /*>>inputtypes*/
13619        // Run through HTML5's new input types to see if the UA understands any.
13620        //   This is put behind the tests runloop because it doesn't return a
13621        //   true/false like all the other tests; instead, it returns an object
13622        //   containing each input type with its corresponding true/false value
13623
13624        // Big thanks to @miketaylr for the html5 forms expertise. miketaylr.com/
13625        Modernizr['inputtypes'] = (function(props) {
13626
13627            for ( var i = 0, bool, inputElemType, defaultView, len = props.length; i < len; i++ ) {
13628
13629                inputElem.setAttribute('type', inputElemType = props[i]);
13630                bool = inputElem.type !== 'text';
13631
13632                // We first check to see if the type we give it sticks..
13633                // If the type does, we feed it a textual value, which shouldn't be valid.
13634                // If the value doesn't stick, we know there's input sanitization which infers a custom UI
13635                if ( bool ) {
13636
13637                    inputElem.value         = smile;
13638                    inputElem.style.cssText = 'position:absolute;visibility:hidden;';
13639
13640                    if ( /^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined ) {
13641
13642                      docElement.appendChild(inputElem);
13643                      defaultView = document.defaultView;
13644
13645                      // Safari 2-4 allows the smiley as a value, despite making a slider
13646                      bool =  defaultView.getComputedStyle &&
13647                              defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' &&
13648                              // Mobile android web browser has false positive, so must
13649                              // check the height to see if the widget is actually there.
13650                              (inputElem.offsetHeight !== 0);
13651
13652                      docElement.removeChild(inputElem);
13653
13654                    } else if ( /^(search|tel)$/.test(inputElemType) ){
13655                      // Spec doesn't define any special parsing or detectable UI
13656                      //   behaviors so we pass these through as true
13657
13658                      // Interestingly, opera fails the earlier test, so it doesn't
13659                      //  even make it here.
13660
13661                    } else if ( /^(url|email)$/.test(inputElemType) ) {
13662                      // Real url and email support comes with prebaked validation.
13663                      bool = inputElem.checkValidity && inputElem.checkValidity() === false;
13664
13665                    } else {
13666                      // If the upgraded input compontent rejects the :) text, we got a winner
13667                      bool = inputElem.value != smile;
13668                    }
13669                }
13670
13671                inputs[ props[i] ] = !!bool;
13672            }
13673            return inputs;
13674        })('search tel url email datetime date month week time datetime-local number range color'.split(' '));
13675        /*>>inputtypes*/
13676    }
13677    /*>>webforms*/
13678
13679
13680    // End of test definitions
13681    // -----------------------
13682
13683
13684
13685    // Run through all tests and detect their support in the current UA.
13686    // todo: hypothetically we could be doing an array of tests and use a basic loop here.
13687    for ( var feature in tests ) {
13688        if ( hasOwnProp(tests, feature) ) {
13689            // run the test, throw the return value into the Modernizr,
13690            //   then based on that boolean, define an appropriate className
13691            //   and push it into an array of classes we'll join later.
13692            featureName  = feature.toLowerCase();
13693            Modernizr[featureName] = tests[feature]();
13694
13695            classes.push((Modernizr[featureName] ? '' : 'no-') + featureName);
13696        }
13697    }
13698
13699    /*>>webforms*/
13700    // input tests need to run.
13701    Modernizr.input || webforms();
13702    /*>>webforms*/
13703
13704
13705    /**
13706     * addTest allows the user to define their own feature tests
13707     * the result will be added onto the Modernizr object,
13708     * as well as an appropriate className set on the html element
13709     *
13710     * @param feature - String naming the feature
13711     * @param test - Function returning true if feature is supported, false if not
13712     */
13713     Modernizr.addTest = function ( feature, test ) {
13714       if ( typeof feature == 'object' ) {
13715         for ( var key in feature ) {
13716           if ( hasOwnProp( feature, key ) ) {
13717             Modernizr.addTest( key, feature[ key ] );
13718           }
13719         }
13720       } else {
13721
13722         feature = feature.toLowerCase();
13723
13724         if ( Modernizr[feature] !== undefined ) {
13725           // we're going to quit if you're trying to overwrite an existing test
13726           // if we were to allow it, we'd do this:
13727           //   var re = new RegExp("\\b(no-)?" + feature + "\\b");
13728           //   docElement.className = docElement.className.replace( re, '' );
13729           // but, no rly, stuff 'em.
13730           return Modernizr;
13731         }
13732
13733         test = typeof test == 'function' ? test() : test;
13734
13735         if (typeof enableClasses !== "undefined" && enableClasses) {
13736           docElement.className += ' ' + (test ? '' : 'no-') + feature;
13737         }
13738         Modernizr[feature] = test;
13739
13740       }
13741
13742       return Modernizr; // allow chaining.
13743     };
13744
13745
13746    // Reset modElem.cssText to nothing to reduce memory footprint.
13747    setCss('');
13748    modElem = inputElem = null;
13749
13750    /*>>shiv*/
13751    /*
vendor: 2,672 bytes, lines 13751-13820
13751! HTML5 Shiv v3.6.1 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed */
13752    ;(function(window, document) {
13753    /*jshint evil:true */
13754      /** Preset options */
13755      var options = window.html5 || {};
13756
13757      /** Used to skip problem elements */
13758      var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
13759
13760      /** Not all elements can be cloned in IE **/
13761      var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
13762
13763      /** Detect whether the browser supports default html5 styles */
13764      var supportsHtml5Styles;
13765
13766      /** Name of the expando, to work with multiple documents or to re-shiv one document */
13767      var expando = '_html5shiv';
13768
13769      /** The id for the the documents expando */
13770      var expanID = 0;
13771
13772      /** Cached data for each document */
13773      var expandoData = {};
13774
13775      /** Detect whether the browser supports unknown elements */
13776      var supportsUnknownElements;
13777
13778      (function() {
13779        try {
13780            var a = document.createElement('a');
13781            a.innerHTML = '<xyz></xyz>';
13782            //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
13783            supportsHtml5Styles = ('hidden' in a);
13784
13785            supportsUnknownElements = a.childNodes.length == 1 || (function() {
13786              // assign a false positive if unable to shiv
13787              (document.createElement)('a');
13788              var frag = document.createDocumentFragment();
13789              return (
13790                typeof frag.cloneNode == 'undefined' ||
13791                typeof frag.createDocumentFragment == 'undefined' ||
13792                typeof frag.createElement == 'undefined'
13793              );
13794            }());
13795        } catch(e) {
13796          supportsHtml5Styles = true;
13797          supportsUnknownElements = true;
13798        }
13799
13800      }());
13801
13802      /*--------------------------------------------------------------------------*/
13803
13804      /**
13805       * Creates a style sheet with the given CSS text and adds it to the document.
13806       * @private
13807       * @param {Document} ownerDocument The document.
13808       * @param {String} cssText The CSS text.
13809       * @returns {StyleSheet} The style element.
13810       */
13811      function addStyleSheet(ownerDocument, cssText) {
13812        var p = ownerDocument.createElement('p'),
13813            parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
13814
13815        p.innerHTML = 'x<style>' + cssText + '</style>';
13816        return parent.insertBefore(p.lastChild, parent.firstChild);
13817      }
13818
13819      /**
13820       * Returns the value of `html5.elements` as an array.
vendor: 5,012 bytes, lines 13821-13960
13821       * @private
13822       * @returns {Array} An array of shived element node names.
13823       */
13824      function getElements() {
13825        var elements = html5.elements;
13826        return typeof elements == 'string' ? elements.split(' ') : elements;
13827      }
13828
13829        /**
13830       * Returns the data associated to the given document
13831       * @private
13832       * @param {Document} ownerDocument The document.
13833       * @returns {Object} An object of data.
13834       */
13835      function getExpandoData(ownerDocument) {
13836        var data = expandoData[ownerDocument[expando]];
13837        if (!data) {
13838            data = {};
13839            expanID++;
13840            ownerDocument[expando] = expanID;
13841            expandoData[expanID] = data;
13842        }
13843        return data;
13844      }
13845
13846      /**
13847       * returns a shived element for the given nodeName and document
13848       * @memberOf html5
13849       * @param {String} nodeName name of the element
13850       * @param {Document} ownerDocument The context document.
13851       * @returns {Object} The shived element.
13852       */
13853      function createElement(nodeName, ownerDocument, data){
13854        if (!ownerDocument) {
13855            ownerDocument = document;
13856        }
13857        if(supportsUnknownElements){
13858            return ownerDocument.createElement(nodeName);
13859        }
13860        if (!data) {
13861            data = getExpandoData(ownerDocument);
13862        }
13863        var node;
13864
13865        if (data.cache[nodeName]) {
13866            node = data.cache[nodeName].cloneNode();
13867        } else if (saveClones.test(nodeName)) {
13868            node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
13869        } else {
13870            node = data.createElem(nodeName);
13871        }
13872
13873        // Avoid adding some elements to fragments in IE < 9 because
13874        // * Attributes like `name` or `type` cannot be set/changed once an element
13875        //   is inserted into a document/fragment
13876        // * Link elements with `src` attributes that are inaccessible, as with
13877        //   a 403 response, will cause the tab/window to crash
13878        // * Script elements appended to fragments will execute when their `src`
13879        //   or `text` property is set
13880        return node.canHaveChildren && !reSkip.test(nodeName) ? data.frag.appendChild(node) : node;
13881      }
13882
13883      /**
13884       * returns a shived DocumentFragment for the given document
13885       * @memberOf html5
13886       * @param {Document} ownerDocument The context document.
13887       * @returns {Object} The shived DocumentFragment.
13888       */
13889      function createDocumentFragment(ownerDocument, data){
13890        if (!ownerDocument) {
13891            ownerDocument = document;
13892        }
13893        if(supportsUnknownElements){
13894            return ownerDocument.createDocumentFragment();
13895        }
13896        data = data || getExpandoData(ownerDocument);
13897        var clone = data.frag.cloneNode(),
13898            i = 0,
13899            elems = getElements(),
13900            l = elems.length;
13901        for(;i<l;i++){
13902            clone.createElement(elems[i]);
13903        }
13904        return clone;
13905      }
13906
13907      /**
13908       * Shivs the `createElement` and `createDocumentFragment` methods of the document.
13909       * @private
13910       * @param {Document|DocumentFragment} ownerDocument The document.
13911       * @param {Object} data of the document.
13912       */
13913      function shivMethods(ownerDocument, data) {
13914        if (!data.cache) {
13915            data.cache = {};
13916            data.createElem = ownerDocument.createElement;
13917            data.createFrag = ownerDocument.createDocumentFragment;
13918            data.frag = data.createFrag();
13919        }
13920
13921
13922        ownerDocument.createElement = function(nodeName) {
13923          //abort shiv
13924          if (!html5.shivMethods) {
13925              return data.createElem(nodeName);
13926          }
13927          return createElement(nodeName, ownerDocument, data);
13928        };
13929
13930        ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
13931          'var n=f.cloneNode(),c=n.createElement;' +
13932          'h.shivMethods&&(' +
13933            // unroll the `createElement` calls
13934            getElements().join().replace(/\w+/g, function(nodeName) {
13935              data.createElem(nodeName);
13936              data.frag.createElement(nodeName);
13937              return 'c("' + nodeName + '")';
13938            }) +
13939          ');return n}'
13940        )(html5, data.frag);
13941      }
13942
13943      /*--------------------------------------------------------------------------*/
13944
13945      /**
13946       * Shivs the given document.
13947       * @memberOf html5
13948       * @param {Document} ownerDocument The document to shiv.
13949       * @returns {Document} The shived document.
13950       */
13951      function shivDocument(ownerDocument) {
13952        if (!ownerDocument) {
13953            ownerDocument = document;
13954        }
13955        var data = getExpandoData(ownerDocument);
13956
13957        if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
13958          data.hasCSS = !!addStyleSheet(ownerDocument,
13959            // corrects block display not defined in IE6/7/8/9
13960            'article,aside,figcaption,figure,footer,header,hgroup,nav,section{dis
13960play:block}' +
13961            // adds styling not present in IE6/7/8/9
13962            'mark{background:#FF0;color:#000}'
13963          );
13964        }
13965        if (!supportsUnknownElements) {
13966          shivMethods(ownerDocument, data);
13967        }
13968        return ownerDocument;
13969      }
13970
13971      /*--------------------------------------------------------------------------*/
13972
13973      /**
13974       * The `html5` object is exposed so that more elements can be shived and
13975       * existing shiving can be detected on iframes.
13976       * @type Object
13977       * @example
13978       *
13979       * // options can be changed before the script is included
13980       * html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
13981       */
13982      var html5 = {
13983
13984        /**
13985         * An array or space separated string of node names of the elements to shiv.
13986         * @memberOf html5
13987         * @type Array|String
13988         */
13989        'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video',
13990
13991        /**
13992         * A flag to indicate that the HTML5 style sheet should be inserted.
13993         * @memberOf html5
13994         * @type Boolean
13995         */
13996        'shivCSS': (options.shivCSS !== false),
13997
13998        /**
13999         * Is equal to true if a browser supports creating unknown/HTML5 elements
14000         * @memberOf html5
14001         * @type boolean
14002         */
14003        'supportsUnknownElements': supportsUnknownElements,
14004
14005        /**
14006         * A flag to indicate that the document's `createElement` and `createDocumentFragment`
14007         * methods should be overwritten.
14008         * @memberOf html5
14009         * @type Boolean
14010         */
14011        'shivMethods': (options.shivMethods !== false),
14012
14013        /**
14014         * A string to describe the type of `html5` object ("default" or "default print").
14015         * @memberOf html5
14016         * @type String
14017         */
14018        'type': 'default',
14019
14020        // shivs the document according to the specified `html5` object options
14021        'shivDocument': shivDocument,
14022
14023        //creates a shived element
14024        createElement: createElement,
14025
14026        //creates a shived documentFragment
14027        createDocumentFragment: createDocumentFragment
14028      };
14029
14030      /*--------------------------------------------------------------------------*/
14031
14032      // expose html5
14033      window.html5 = html5;
14034
14035      // shiv the document
14036      shivDocument(document);
14037
14038    }(this, document));
14039    /*>>shiv*/
14040
14041    // Assign private properties to the return object with prefix
14042    Modernizr._version      = version;
14043
14044    // expose these for the plugin API. Look in the source for how to join() them against your input
14045    /*>>prefixes*/
14046    Modernizr._prefixes     = prefixes;
14047    /*>>prefixes*/
14048    /*>>domprefixes*/
14049    Modernizr._domPrefixes  = domPrefixes;
14050    Modernizr._cssomPrefixes  = cssomPrefixes;
14051    /*>>domprefixes*/
14052
14053    /*>>mq*/
14054    // Modernizr.mq tests a given media query, live against the current state of the window
14055    // A few important notes:
14056    //   * If a browser does not support media queries at all (eg. oldIE) the mq() will always return false
14057    //   * A max-width or orientation query will be evaluated against the current state, which may change later.
14058    //   * You must specify values. Eg. If you are testing support for the min-width media query use:
14059    //       Modernizr.mq('(min-width:0)')
14060    // usage:
14061    // Modernizr.mq('only screen and (max-width:768)')
14062    Modernizr.mq            = testMediaQuery;
14063    /*>>mq*/
14064
14065    /*>>hasevent*/
14066    // Modernizr.hasEvent() detects support for a given event, with an optional element to test on
14067    // Modernizr.hasEvent('gesturestart', elem)
14068    Modernizr.hasEvent      = isEventSupported;
14069    /*>>hasevent*/
14070
14071    /*>>testprop*/
14072    // Modernizr.testProp() investigates whether a given style property is recognized
14073    // Note that the property names must be provided in the camelCase variant.
14074    // Modernizr.testProp('pointerEvents')
14075    Modernizr.testProp      = function(prop){
14076        return testProps([prop]);
14077    };
14078    /*>>testprop*/
14079
14080    /*>>testallprops*/
14081    // Modernizr.testAllProps() investigates whether a given style property,
14082    //   or any of its vendor-prefixed variants, is recognized
14083    // Note that the property names must be provided in the camelCase variant.
14084    // Modernizr.testAllProps('boxSizing')
14085    Modernizr.testAllProps  = testPropsAll;
14086    /*>>testallprops*/
14087
14088
14089    /*>>teststyles*/
14090    // Modernizr.testStyles() allows you to add custom styles to the document and test an element afterwards
14091    // Modernizr.testStyles('#modernizr { position:absolute }', function(elem, rule){ ... })
14092    Modernizr.testStyles    = injectElementWithStyles;
14093    /*>>teststyles*/
14094
14095
14096    /*>>prefixed*/
14097    // Modernizr.prefixed() returns the prefixed or nonprefixed property name variant of your input
14098    // Modernizr.prefixed('boxSizing') // 'MozBoxSizing'
14099
14100    // Properties must be passed as dom-style camelcase, rather than `box-sizing` hypentated style.
14101    // Return values will also be the camelCase variant, if you need to translate that to hypenated style use:
14102    //
14103    //     str.replace(/([A-Z])/g, function(str,m1){ return '-' + m1.toLowerCase(); }).replace(/^ms-/,'-ms-');
14104
14105    // If you're trying to ascertain which transition end event to bind to, you might do something like...
14106    //
14107    //     var transEndEventNames = {
14108    //       'WebkitTransition' : 'webkitTransitionEnd',
14109    //       'MozTransition'    : 'transitionend',
14110    //       'OTransition'      : 'oTransitionEnd',
14111    //       'msTransition'     : 'MSTransitionEnd',
14112    //       'transition'       : 'transitionend'
14113    //     },
14114    //     transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];
14115
14116    Modernizr.prefixed      = function(prop, obj, elem){
14117      if(!obj) {
14118        return testPropsAll(prop, 'pfx');
14119      } else {
14120        // Testing DOM property e.g. Modernizr.prefixed('requestAnimationFrame', window) // 'mozRequestAnimationFrame'
14121        return testPropsAll(prop, obj, elem);
14122      }
14123    };
14124    /*>>prefixed*/
14125
14126
14127    /*>>cssclasses*/
14128    // Remove "no-js" class from <html> element, if it exists:
14129    docElement.className = docElement.className.replace(/(^|\s)no-js(\s|$)/, '$1$2') +
14130
14131                            // Add the new classes to the <html> element.
14132                            (enableClasses ? ' js ' + classes.join(' ') : '');
14133    /*>>cssclasses*/
14134
14135    return Modernizr;
14136
14137})(this, this.document);
14138
14139/*
14140     _ _      _       _
14141 ___| (_) ___| | __  (_)___
14142/ __| | |/ __| |/ /  | / __|
14143\__ \ | | (__|   < _ | \__ \
14144|___/_|_|\___|_|\_(_)/ |___/
14145                   |__/
14146
14147 Version: 1.6.0
14148  Author: Ken Wheeler
14149 Website: http://kenwheeler.github.io
14150    Docs: http://kenwheeler.github.io/slick
14151    Repo: http://github.com/kenwheeler/slick
14152  Issues: http://github.com/kenwheeler/slick/issues
14153
14154 */
14155/* global window, document, define, jQuery, setInterval, clearInterval */
14156(function(factory) {
14157    'use strict';
14158    if (typeof define === 'function' && define.amd) {
14159        define(['jquery'], factory);
14160    } else if (typeof exports !== 'undefined') {
14161        module.exports = factory(require('jquery'));
14162    } else {
14163        factory(jQuery);
14164    }
14165
14166}(function($) {
14167    'use strict';
14168    var Slick = window.Slick || {};
14169
14170    Slick = (function() {
14171
14172        var instanceUid = 0;
14173
14174        function Slick(element, settings) {
14175
14176            var _ = this, dataSettings;
14177
14178            _.defaults = {
14179                accessibility: true,
14180                adaptiveHeight: false,
14181                appendArrows: $(element),
14182                appendDots: $(element),
14183                arrows: true,
14184                asNavFor: null,
14185                prevArrow: '<button type="button" data-role="none" class="slick-prev" aria-label="Previous" tabindex="0" role="button">Previous</button>',
14186                nextArrow: '<button type="button" data-role="none" class="slick-next" aria-label="Next" tabindex="0" role="button">Next</button>',
14187                autoplay: false,
14188                autoplaySpeed: 3000,
14189                centerMode: false,
14190                centerPadding: '50px',
14191                cssEase: 'ease',
14192                customPaging: function(slider, i) {
14193                    return $('<button type="button" data-role="none" role="button" tabindex="0" />').text(i + 1);
14194                },
14195                dots: false,
14196                dotsClass: 'slick-dots',
14197                draggable: true,
14198                easing: 'linear',
14199                edgeFriction: 0.35,
14200                fade: false,
14201                focusOnSelect: false,
14202                infinite: true,
14203                initialSlide: 0,
14204                lazyLoad: 'ondemand',
14205                mobileFirst: false,
14206                pauseOnHover: true,
14207                pauseOnFocus: true,
14208                pauseOnDotsHover: false,
14209                respondTo: 'window',
14210                responsive: null,
14211                rows: 1,
14212                rtl: false,
14213                slide: '',
14214                slidesPerRow: 1,
14215                slidesToShow: 1,
14216                slidesToScroll: 1,
14217                speed: 500,
14218                swipe: true,
14219                swipeToSlide: false,
14220                touchMove: true,
14221                touchThreshold: 5,
14222                useCSS: true,
14223                useTransform: true,
14224                variableWidth: false,
14225                vertical: false,
14226                verticalSwiping: false,
14227                waitForAnimate: true,
14228                zIndex: 1000
14229            };
14230
14231            _.initials = {
14232                animating: false,
14233                dragging: false,
14234                autoPlayTimer: null,
14235                currentDirection: 0,
14236                currentLeft: null,
14237                currentSlide: 0,
14238                direction: 1,
14239                $dots: null,
14240                listWidth: null,
14241                listHeight: null,
14242                loadIndex: 0,
14243                $nextArrow: null,
14244                $prevArrow: null,
14245                slideCount: null,
14246                slideWidth: null,
14247                $slideTrack: null,
14248                $slides: null,
14249                sliding: false,
14250                slideOffset: 0,
14251                swipeLeft: null
vendor: 11,177 bytes, lines 14251-14634
14251,
14252                $list: null,
14253                touchObject: {},
14254                transformsEnabled: false,
14255                unslicked: false
14256            };
14257
14258            $.extend(_, _.initials);
14259
14260            _.activeBreakpoint = null;
14261            _.animType = null;
14262            _.animProp = null;
14263            _.breakpoints = [];
14264            _.breakpointSettings = [];
14265            _.cssTransitions = false;
14266            _.focussed = false;
14267            _.interrupted = false;
14268            _.hidden = 'hidden';
14269            _.paused = true;
14270            _.positionProp = null;
14271            _.respondTo = null;
14272            _.rowCount = 1;
14273            _.shouldClick = true;
14274            _.$slider = $(element);
14275            _.$slidesCache = null;
14276            _.transformType = null;
14277            _.transitionType = null;
14278            _.visibilityChange = 'visibilitychange';
14279            _.windowWidth = 0;
14280            _.windowTimer = null;
14281
14282            dataSettings = $(element).data('slick') || {};
14283
14284            _.options = $.extend({}, _.defaults, settings, dataSettings);
14285
14286            _.currentSlide = _.options.initialSlide;
14287
14288            _.originalSettings = _.options;
14289
14290            if (typeof document.mozHidden !== 'undefined') {
14291                _.hidden = 'mozHidden';
14292                _.visibilityChange = 'mozvisibilitychange';
14293            } else if (typeof document.webkitHidden !== 'undefined') {
14294                _.hidden = 'webkitHidden';
14295                _.visibilityChange = 'webkitvisibilitychange';
14296            }
14297
14298            _.autoPlay = $.proxy(_.autoPlay, _);
14299            _.autoPlayClear = $.proxy(_.autoPlayClear, _);
14300            _.autoPlayIterator = $.proxy(_.autoPlayIterator, _);
14301            _.changeSlide = $.proxy(_.changeSlide, _);
14302            _.clickHandler = $.proxy(_.clickHandler, _);
14303            _.selectHandler = $.proxy(_.selectHandler, _);
14304            _.setPosition = $.proxy(_.setPosition, _);
14305            _.swipeHandler = $.proxy(_.swipeHandler, _);
14306            _.dragHandler = $.proxy(_.dragHandler, _);
14307            _.keyHandler = $.proxy(_.keyHandler, _);
14308
14309            _.instanceUid = instanceUid++;
14310
14311            // A simple way to check for HTML strings
14312            // Strict HTML recognition (must start with <)
14313            // Extracted from jQuery v1.11 source
14314            _.htmlExpr = /^(?:\s*(<[\w\W]+>)[^>]*)$/;
14315
14316
14317            _.registerBreakpoints();
14318            _.init(true);
14319
14320        }
14321
14322        return Slick;
14323
14324    }());
14325
14326    Slick.prototype.activateADA = function() {
14327        var _ = this;
14328
14329        _.$slideTrack.find('.slick-active').attr({
14330            'aria-hidden': 'false'
14331        }).find('a, input, button, select').attr({
14332            'tabindex': '0'
14333        });
14334
14335    };
14336
14337    Slick.prototype.addSlide = Slick.prototype.slickAdd = function(markup, index, addBefore) {
14338
14339        var _ = this;
14340
14341        if (typeof(index) === 'boolean') {
14342            addBefore = index;
14343            index = null;
14344        } else if (index < 0 || (index >= _.slideCount)) {
14345            return false;
14346        }
14347
14348        _.unload();
14349
14350        if (typeof(index) === 'number') {
14351            if (index === 0 && _.$slides.length === 0) {
14352                $(markup).appendTo(_.$slideTrack);
14353            } else if (addBefore) {
14354                $(markup).insertBefore(_.$slides.eq(index));
14355            } else {
14356                $(markup).insertAfter(_.$slides.eq(index));
14357            }
14358        } else {
14359            if (addBefore === true) {
14360                $(markup).prependTo(_.$slideTrack);
14361            } else {
14362                $(markup).appendTo(_.$slideTrack);
14363            }
14364        }
14365
14366        _.$slides = _.$slideTrack.children(this.options.slide);
14367
14368        _.$slideTrack.children(this.options.slide).detach();
14369
14370        _.$slideTrack.append(_.$slides);
14371
14372        _.$slides.each(function(index, element) {
14373            $(element).attr('data-slick-index', index);
14374        });
14375
14376        _.$slidesCache = _.$slides;
14377
14378        _.reinit();
14379
14380    };
14381
14382    Slick.prototype.animateHeight = function() {
14383        var _ = this;
14384        if (_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) {
14385            var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true);
14386            _.$list.animate({
14387                height: targetHeight
14388            }, _.options.speed);
14389        }
14390    };
14391
14392    Slick.prototype.animateSlide = function(targetLeft, callback) {
14393
14394        var animProps = {},
14395            _ = this;
14396
14397        _.animateHeight();
14398
14399        if (_.options.rtl === true && _.options.vertical === false) {
14400            targetLeft = -targetLeft;
14401        }
14402        if (_.transformsEnabled === false) {
14403            if (_.options.vertical === false) {
14404                _.$slideTrack.animate({
14405                    left: targetLeft
14406                }, _.options.speed, _.options.easing, callback);
14407            } else {
14408                _.$slideTrack.animate({
14409                    top: targetLeft
14410                }, _.options.speed, _.options.easing, callback);
14411            }
14412
14413        } else {
14414
14415            if (_.cssTransitions === false) {
14416                if (_.options.rtl === true) {
14417                    _.currentLeft = -(_.currentLeft);
14418                }
14419                $({
14420                    animStart: _.currentLeft
14421                }).animate({
14422                    animStart: targetLeft
14423                }, {
14424                    duration: _.options.speed,
14425                    easing: _.options.easing,
14426                    step: function(now) {
14427                        now = Math.ceil(now);
14428                        if (_.options.vertical === false) {
14429                            animProps[_.animType] = 'translate(' +
14430                                now + 'px, 0px)';
14431                            _.$slideTrack.css(animProps);
14432                        } else {
14433                            animProps[_.animType] = 'translate(0px,' +
14434                                now + 'px)';
14435                            _.$slideTrack.css(animProps);
14436                        }
14437                    },
14438                    complete: function() {
14439                        if (callback) {
14440                            callback.call();
14441                        }
14442                    }
14443                });
14444
14445            } else {
14446
14447                _.applyTransition();
14448                targetLeft = Math.ceil(targetLeft);
14449
14450                if (_.options.vertical === false) {
14451                    animProps[_.animType] = 'translate3d(' + targetLeft + 'px, 0px, 0px)';
14452                } else {
14453                    animProps[_.animType] = 'translate3d(0px,' + targetLeft + 'px, 0px)';
14454                }
14455                _.$slideTrack.css(animProps);
14456
14457                if (callback) {
14458                    setTimeout(function() {
14459
14460                        _.disableTransition();
14461
14462                        callback.call();
14463                    }, _.options.speed);
14464                }
14465
14466            }
14467
14468        }
14469
14470    };
14471
14472    Slick.prototype.getNavTarget = function() {
14473
14474        var _ = this,
14475            asNavFor = _.options.asNavFor;
14476
14477        if ( asNavFor && asNavFor !== null ) {
14478            asNavFor = $(asNavFor).not(_.$slider);
14479        }
14480
14481        return asNavFor;
14482
14483    };
14484
14485    Slick.prototype.asNavFor = function(index) {
14486
14487        var _ = this,
14488            asNavFor = _.getNavTarget();
14489
14490        if ( asNavFor !== null && typeof asNavFor === 'object' ) {
14491            asNavFor.each(function() {
14492                var target = $(this).slick('getSlick');
14493                if(!target.unslicked) {
14494                    target.slideHandler(index, true);
14495                }
14496            });
14497        }
14498
14499    };
14500
14501    Slick.prototype.applyTransition = function(slide) {
14502
14503        var _ = this,
14504            transition = {};
14505
14506        if (_.options.fade === false) {
14507            transition[_.transitionType] = _.transformType + ' ' + _.options.speed + 'ms ' + _.options.cssEase;
14508        } else {
14509            transition[_.transitionType] = 'opacity ' + _.options.speed + 'ms ' + _.options.cssEase;
14510        }
14511
14512        if (_.options.fade === false) {
14513            _.$slideTrack.css(transition);
14514        } else {
14515            _.$slides.eq(slide).css(transition);
14516        }
14517
14518    };
14519
14520    Slick.prototype.autoPlay = function() {
14521
14522        var _ = this;
14523
14524        _.autoPlayClear();
14525
14526        if ( _.slideCount > _.options.slidesToShow ) {
14527            _.autoPlayTimer = setInterval( _.autoPlayIterator, _.options.autoplaySpeed );
14528        }
14529
14530    };
14531
14532    Slick.prototype.autoPlayClear = function() {
14533
14534        var _ = this;
14535
14536        if (_.autoPlayTimer) {
14537            clearInterval(_.autoPlayTimer);
14538        }
14539
14540    };
14541
14542    Slick.prototype.autoPlayIterator = function() {
14543
14544        var _ = this,
14545            slideTo = _.currentSlide + _.options.slidesToScroll;
14546
14547        if ( !_.paused && !_.interrupted && !_.focussed ) {
14548
14549            if ( _.options.infinite === false ) {
14550
14551                if ( _.direction === 1 && ( _.currentSlide + 1 ) === ( _.slideCount - 1 )) {
14552                    _.direction = 0;
14553                }
14554
14555                else if ( _.direction === 0 ) {
14556
14557                    slideTo = _.currentSlide - _.options.slidesToScroll;
14558
14559                    if ( _.currentSlide - 1 === 0 ) {
14560                        _.direction = 1;
14561                    }
14562
14563                }
14564
14565            }
14566
14567            _.slideHandler( slideTo );
14568
14569        }
14570
14571    };
14572
14573    Slick.prototype.buildArrows = function() {
14574
14575        var _ = this;
14576
14577        if (_.options.arrows === true ) {
14578
14579            _.$prevArrow = $(_.options.prevArrow).addClass('slick-arrow');
14580            _.$nextArrow = $(_.options.nextArrow).addClass('slick-arrow');
14581
14582            if( _.slideCount > _.options.slidesToShow ) {
14583
14584                _.$prevArrow.removeClass('slick-hidden').removeAttr('aria-hidden tabindex');
14585                _.$nextArrow.removeClass('slick-hidden').removeAttr('aria-hidden tabindex');
14586
14587                if (_.htmlExpr.test(_.options.prevArrow)) {
14588                    _.$prevArrow.prependTo(_.options.appendArrows);
14589                }
14590
14591                if (_.htmlExpr.test(_.options.nextArrow)) {
14592                    _.$nextArrow.appendTo(_.options.appendArrows);
14593                }
14594
14595                if (_.options.infinite !== true) {
14596                    _.$prevArrow
14597                        .addClass('slick-disabled')
14598                        .attr('aria-disabled', 'true');
14599                }
14600
14601            } else {
14602
14603                _.$prevArrow.add( _.$nextArrow )
14604
14605                    .addClass('slick-hidden')
14606                    .attr({
14607                        'aria-disabled': 'true',
14608                        'tabindex': '-1'
14609                    });
14610
14611            }
14612
14613        }
14614
14615    };
14616
14617    Slick.prototype.buildDots = function() {
14618
14619        var _ = this,
14620            i, dot;
14621
14622        if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
14623
14624            _.$slider.addClass('slick-dotted');
14625
14626            dot = $('<ul />').addClass(_.options.dotsClass);
14627
14628            for (i = 0; i <= _.getDotCount(); i += 1) {
14629                dot.append($('<li />').append(_.options.customPaging.call(this, _, i)));
14630            }
14631
14632            _.$dots = dot.appendTo(_.options.appendDots);
14633
14634            _.$dots.find('li').first().addClass('slick-active')
vendor: 18,779 bytes, lines 14634-15243
14634.attr('aria-hidden', 'false');
14635
14636        }
14637
14638    };
14639
14640    Slick.prototype.buildOut = function() {
14641
14642        var _ = this;
14643
14644        _.$slides =
14645            _.$slider
14646                .children( _.options.slide + ':not(.slick-cloned)')
14647                .addClass('slick-slide');
14648
14649        _.slideCount = _.$slides.length;
14650
14651        _.$slides.each(function(index, element) {
14652            $(element)
14653                .attr('data-slick-index', index)
14654                .data('originalStyling', $(element).attr('style') || '');
14655        });
14656
14657        _.$slider.addClass('slick-slider');
14658
14659        _.$slideTrack = (_.slideCount === 0) ?
14660            $('<div class="slick-track"/>').appendTo(_.$slider) :
14661            _.$slides.wrapAll('<div class="slick-track"/>').parent();
14662
14663        _.$list = _.$slideTrack.wrap(
14664            '<div aria-live="polite" class="slick-list"/>').parent();
14665        _.$slideTrack.css('opacity', 0);
14666
14667        if (_.options.centerMode === true || _.options.swipeToSlide === true) {
14668            _.options.slidesToScroll = 1;
14669        }
14670
14671        $('img[data-lazy]', _.$slider).not('[src]').addClass('slick-loading');
14672
14673        _.setupInfinite();
14674
14675        _.buildArrows();
14676
14677        _.buildDots();
14678
14679        _.updateDots();
14680
14681
14682        _.setSlideClasses(typeof _.currentSlide === 'number' ? _.currentSlide : 0);
14683
14684        if (_.options.draggable === true) {
14685            _.$list.addClass('draggable');
14686        }
14687
14688    };
14689
14690    Slick.prototype.buildRows = function() {
14691
14692        var _ = this, a, b, c, newSlides, numOfSlides, originalSlides,slidesPerSection;
14693
14694        newSlides = document.createDocumentFragment();
14695        originalSlides = _.$slider.children();
14696
14697        if(_.options.rows > 1) {
14698
14699            slidesPerSection = _.options.slidesPerRow * _.options.rows;
14700            numOfSlides = Math.ceil(
14701                originalSlides.length / slidesPerSection
14702            );
14703
14704            for(a = 0; a < numOfSlides; a++){
14705                var slide = document.createElement('div');
14706                for(b = 0; b < _.options.rows; b++) {
14707                    var row = document.createElement('div');
14708                    for(c = 0; c < _.options.slidesPerRow; c++) {
14709                        var target = (a * slidesPerSection + ((b * _.options.slidesPerRow) + c));
14710                        if (originalSlides.get(target)) {
14711                            row.appendChild(originalSlides.get(target));
14712                        }
14713                    }
14714                    slide.appendChild(row);
14715                }
14716                newSlides.appendChild(slide);
14717            }
14718
14719            _.$slider.empty().append(newSlides);
14720            _.$slider.children().children().children()
14721                .css({
14722                    'width':(100 / _.options.slidesPerRow) + '%',
14723                    'display': 'inline-block'
14724                });
14725
14726        }
14727
14728    };
14729
14730    Slick.prototype.checkResponsive = function(initial, forceUpdate) {
14731
14732        var _ = this,
14733            breakpoint, targetBreakpoint, respondToWidth, triggerBreakpoint = false;
14734        var sliderWidth = _.$slider.width();
14735        var windowWidth = window.innerWidth || $(window).width();
14736
14737        if (_.respondTo === 'window') {
14738            respondToWidth = windowWidth;
14739        } else if (_.respondTo === 'slider') {
14740            respondToWidth = sliderWidth;
14741        } else if (_.respondTo === 'min') {
14742            respondToWidth = Math.min(windowWidth, sliderWidth);
14743        }
14744
14745        if ( _.options.responsive &&
14746            _.options.responsive.length &&
14747            _.options.responsive !== null) {
14748
14749            targetBreakpoint = null;
14750
14751            for (breakpoint in _.breakpoints) {
14752                if (_.breakpoints.hasOwnProperty(breakpoint)) {
14753                    if (_.originalSettings.mobileFirst === false) {
14754                        if (respondToWidth < _.breakpoints[breakpoint]) {
14755                            targetBreakpoint = _.breakpoints[breakpoint];
14756                        }
14757                    } else {
14758                        if (respondToWidth > _.breakpoints[breakpoint]) {
14759                            targetBreakpoint = _.breakpoints[breakpoint];
14760                        }
14761                    }
14762                }
14763            }
14764
14765            if (targetBreakpoint !== null) {
14766                if (_.activeBreakpoint !== null) {
14767                    if (targetBreakpoint !== _.activeBreakpoint || forceUpdate) {
14768                        _.activeBreakpoint =
14769                            targetBreakpoint;
14770                        if (_.breakpointSettings[targetBreakpoint] === 'unslick') {
14771                            _.unslick(targetBreakpoint);
14772                        } else {
14773                            _.options = $.extend({}, _.originalSettings,
14774                                _.breakpointSettings[
14775                                    targetBreakpoint]);
14776                            if (initial === true) {
14777                                _.currentSlide = _.options.initialSlide;
14778                            }
14779                            _.refresh(initial);
14780                        }
14781                        triggerBreakpoint = targetBreakpoint;
14782                    }
14783                } else {
14784                    _.activeBreakpoint = targetBreakpoint;
14785                    if (_.breakpointSettings[targetBreakpoint] === 'unslick') {
14786                        _.unslick(targetBreakpoint);
14787                    } else {
14788                        _.options = $.extend({}, _.originalSettings,
14789                            _.breakpointSettings[
14790                                targetBreakpoint]);
14791                        if (initial === true) {
14792                            _.currentSlide = _.options.initialSlide;
14793                        }
14794                        _.refresh(initial);
14795                    }
14796                    triggerBreakpoint = targetBreakpoint;
14797                }
14798            } else {
14799                if (_.activeBreakpoint !== null) {
14800                    _.activeBreakpoint = null;
14801                    _.options = _.originalSettings;
14802                    if (initial === true) {
14803                        _.currentSlide = _.options.initialSlide;
14804                    }
14805                    _.refresh(initial);
14806                    triggerBreakpoint = targetBreakpoint;
14807                }
14808            }
14809
14810            // only trigger breakpoints during an actual break. not on initialize.
14811            if( !initial && triggerBreakpoint !== false ) {
14812                _.$slider.trigger('breakpoint', [_, triggerBreakpoint]);
14813            }
14814        }
14815
14816    };
14817
14818    Slick.prototype.changeSlide = function(event, dontAnimate) {
14819
14820        var _ = this,
14821            $target = $(event.currentTarget),
14822            indexOffset, slideOffset, unevenOffset;
14823
14824        // If target is a link, prevent default action.
14825        if($target.is('a')) {
14826            event.preventDefault();
14827        }
14828
14829        // If target is not the <li> element (ie: a child), find the <li>.
14830        if(!$target.is('li')) {
14831            $target = $target.closest('li');
14832        }
14833
14834        unevenOffset = (_.slideCount % _.options.slidesToScroll !== 0);
14835        indexOffset = unevenOffset ? 0 : (_.slideCount - _.currentSlide) % _.options.slidesToScroll;
14836
14837        switch (event.data.message) {
14838
14839            case 'previous':
14840                slideOffset = indexOffset === 0 ? _.options.slidesToScroll : _.options.slidesToShow - indexOffset;
14841                if (_.slideCount > _.options.slidesToShow) {
14842                    _.slideHandler(_.currentSlide - slideOffset, false, dontAnimate);
14843                }
14844                break;
14845
14846            case 'next':
14847                slideOffset = indexOffset === 0 ? _.options.slidesToScroll : indexOffset;
14848                if (_.slideCount > _.options.slidesToShow) {
14849                    _.slideHandler(_.currentSlide + slideOffset, false, dontAnimate);
14850                }
14851                break;
14852
14853            case 'index':
14854                var index = event.data.index === 0 ? 0 :
14855                    event.data.index || $target.index() * _.options.slidesToScroll;
14856
14857                _.slideHandler(_.checkNavigable(index), false, dontAnimate);
14858                $target.children().trigger('focus');
14859                break;
14860
14861            default:
14862                return;
14863        }
14864
14865    };
14866
14867    Slick.prototype.checkNavigable = function(index) {
14868
14869        var _ = this,
14870            navigables, prevNavigable;
14871
14872        navigables = _.getNavigableIndexes();
14873        prevNavigable = 0;
14874        if (index > navigables[navigables.length - 1]) {
14875            index = navigables[navigables.length - 1];
14876        } else {
14877            for (var n in navigables) {
14878                if (index < navigables[n]) {
14879                    index = prevNavigable;
14880                    break;
14881                }
14882                prevNavigable = navigables[n];
14883            }
14884        }
14885
14886        return index;
14887    };
14888
14889    Slick.prototype.cleanUpEvents = function() {
14890
14891        var _ = this;
14892
14893        if (_.options.dots && _.$dots !== null) {
14894
14895            $('li', _.$dots)
14896                .off('click.slick', _.changeSlide)
14897                .off('mouseenter.slick', $.proxy(_.interrupt, _, true))
14898                .off('mouseleave.slick', $.proxy(_.interrupt, _, false));
14899
14900        }
14901
14902        _.$slider.off('focus.slick blur.slick');
14903
14904        if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
14905            _.$prevArrow && _.$prevArrow.off('click.slick', _.changeSlide);
14906            _.$nextArrow && _.$nextArrow.off('click.slick', _.changeSlide);
14907        }
14908
14909        _.$list.off('touchstart.slick mousedown.slick', _.swipeHandler);
14910        _.$list.off('touchmove.slick mousemove.slick', _.swipeHandler);
14911        _.$list.off('touchend.slick mouseup.slick', _.swipeHandler);
14912        _.$list.off('touchcancel.slick mouseleave.slick', _.swipeHandler);
14913
14914        _.$list.off('click.slick', _.clickHandler);
14915
14916        $(document).off(_.visibilityChange, _.visibility);
14917
14918        _.cleanUpSlideEvents();
14919
14920        if (_.options.accessibility === true) {
14921            _.$list.off('keydown.slick', _.keyHandler);
14922        }
14923
14924        if (_.options.focusOnSelect === true) {
14925            $(_.$slideTrack).children().off('click.slick', _.selectHandler);
14926        }
14927
14928        $(window).off('orientationchange.slick.slick-' + _.instanceUid, _.orientationChange);
14929
14930        $(window).off('resize.slick.slick-' + _.instanceUid, _.resize);
14931
14932        $('[draggable!=true]', _.$slideTrack).off('dragstart', _.preventDefault);
14933
14934        $(window).off('load.slick.slick-' + _.instanceUid, _.setPosition);
14935        $(document).off('ready.slick.slick-' + _.instanceUid, _.setPosition);
14936
14937    };
14938
14939    Slick.prototype.cleanUpSlideEvents = function() {
14940
14941        var _ = this;
14942
14943        _.$list.off('mouseenter.slick', $.proxy(_.interrupt, _, true));
14944        _.$list.off('mouseleave.slick', $.proxy(_.interrupt, _, false));
14945
14946    };
14947
14948    Slick.prototype.cleanUpRows = function() {
14949
14950        var _ = this, originalSlides;
14951
14952        if(_.options.rows > 1) {
14953            originalSlides = _.$slides.children().children();
14954            originalSlides.removeAttr('style');
14955            _.$slider.empty().append(originalSlides);
14956        }
14957
14958    };
14959
14960    Slick.prototype.clickHandler = function(event) {
14961
14962        var _ = this;
14963
14964        if (_.shouldClick === false) {
14965            event.stopImmediatePropagation();
14966            event.stopPropagation();
14967            event.preventDefault();
14968        }
14969
14970    };
14971
14972    Slick.prototype.destroy = function(refresh) {
14973
14974        var _ = this;
14975
14976        _.autoPlayClear();
14977
14978        _.touchObject = {};
14979
14980        _.cleanUpEvents();
14981
14982        $('.slick-cloned', _.$slider).detach();
14983
14984        if (_.$dots) {
14985            _.$dots.remove();
14986        }
14987
14988
14989        if ( _.$prevArrow && _.$prevArrow.length ) {
14990
14991            _.$prevArrow
14992                .removeClass('slick-disabled slick-arrow slick-hidden')
14993                .removeAttr('aria-hidden aria-disabled tabindex')
14994                .css('display','');
14995
14996            if ( _.htmlExpr.test( _.options.prevArrow )) {
14997                _.$prevArrow.remove();
14998            }
14999        }
15000
15001        if ( _.$nextArrow && _.$nextArrow.length ) {
15002
15003            _.$nextArrow
15004                .removeClass('slick-disabled slick-arrow slick-hidden')
15005                .removeAttr('aria-hidden aria-disabled tabindex')
15006                .css('display','');
15007
15008            if ( _.htmlExpr.test( _.options.nextArrow )) {
15009                _.$nextArrow.remove();
15010            }
15011
15012        }
15013
15014
15015        if (_.$slides) {
15016
15017            _.$slides
15018                .removeClass('slick-slide slick-active slick-center slick-visible slick-current')
15019                .removeAttr('aria-hidden')
15020                .removeAttr('data-slick-index')
15021                .each(function(){
15022                    $(this).attr('style', $(this).data('originalStyling'));
15023                });
15024
15025            _.$slideTrack.children(this.options.slide).detach();
15026
15027            _.$slideTrack.detach();
15028
15029            _.$list.detach();
15030
15031            _.$slider.append(_.$slides);
15032        }
15033
15034        _.cleanUpRows();
15035
15036        _.$slider.removeClass('slick-slider');
15037        _.$slider.removeClass('slick-initialized');
15038        _.$slider.removeClass('slick-dotted');
15039
15040        _.unslicked = true;
15041
15042        if(!refresh) {
15043            _.$slider.trigger('destroy', [_]);
15044        }
15045
15046    };
15047
15048    Slick.prototype.disableTransition = function(slide) {
15049
15050        var _ = this,
15051            transition = {};
15052
15053        transition[_.transitionType] = '';
15054
15055        if (_.options.fade === false) {
15056            _.$slideTrack.css(transition);
15057        } else {
15058            _.$slides.eq(slide).css(transition);
15059        }
15060
15061    };
15062
15063    Slick.prototype.fadeSlide = function(slideIndex, callback) {
15064
15065        var _ = this;
15066
15067        if (_.cssTransitions === false) {
15068
15069            _.$slides.eq(slideIndex).css({
15070                zIndex: _.options.zIndex
15071            });
15072
15073            _.$slides.eq(slideIndex).animate({
15074                opacity: 1
15075            }, _.options.speed, _.options.easing, callback);
15076
15077        } else {
15078
15079            _.applyTransition(slideIndex);
15080
15081            _.$slides.eq(slideIndex).css({
15082                opacity: 1,
15083                zIndex: _.options.zIndex
15084            });
15085
15086            if (callback) {
15087                setTimeout(function() {
15088
15089                    _.disableTransition(slideIndex);
15090
15091                    callback.call();
15092                }, _.options.speed);
15093            }
15094
15095        }
15096
15097    };
15098
15099    Slick.prototype.fadeSlideOut = function(slideIndex) {
15100
15101        var _ = this;
15102
15103        if (_.cssTransitions === false) {
15104
15105            _.$slides.eq(slideIndex).animate({
15106                opacity: 0,
15107                zIndex: _.options.zIndex - 2
15108            }, _.options.speed, _.options.easing);
15109
15110        } else {
15111
15112            _.applyTransition(slideIndex);
15113
15114            _.$slides.eq(slideIndex).css({
15115                opacity: 0,
15116                zIndex: _.options.zIndex - 2
15117            });
15118
15119        }
15120
15121    };
15122
15123    Slick.prototype.filterSlides = Slick.prototype.slickFilter = function(filter) {
15124
15125        var _ = this;
15126
15127        if (filter !== null) {
15128
15129            _.$slidesCache = _.$slides;
15130
15131            _.unload();
15132
15133            _.$slideTrack.children(this.options.slide).detach();
15134
15135            _.$slidesCache.filter(filter).appendTo(_.$slideTrack);
15136
15137            _.reinit();
15138
15139        }
15140
15141    };
15142
15143    Slick.prototype.focusHandler = function() {
15144
15145        var _ = this;
15146
15147        _.$slider
15148            .off('focus.slick blur.slick')
15149            .on('focus.slick blur.slick',
15150                '*:not(.slick-arrow)', function(event) {
15151
15152            event.stopImmediatePropagation();
15153            var $sf = $(this);
15154
15155            setTimeout(function() {
15156
15157                if( _.options.pauseOnFocus ) {
15158                    _.focussed = $sf.is(':focus');
15159                    _.autoPlay();
15160                }
15161
15162            }, 0);
15163
15164        });
15165    };
15166
15167    Slick.prototype.getCurrent = Slick.prototype.slickCurrentSlide = function() {
15168
15169        var _ = this;
15170        return _.currentSlide;
15171
15172    };
15173
15174    Slick.prototype.getDotCount = function() {
15175
15176        var _ = this;
15177
15178        var breakPoint = 0;
15179        var counter = 0;
15180        var pagerQty = 0;
15181
15182        if (_.options.infinite === true) {
15183            while (breakPoint < _.slideCount) {
15184                ++pagerQty;
15185                breakPoint = counter + _.options.slidesToScroll;
15186                counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
15187            }
15188        } else if (_.options.centerMode === true) {
15189            pagerQty = _.slideCount;
15190        } else if(!_.options.asNavFor) {
15191            pagerQty = 1 + Math.ceil((_.slideCount - _.options.slidesToShow) / _.options.slidesToScroll);
15192        }else {
15193            while (breakPoint < _.slideCount) {
15194                ++pagerQty;
15195                breakPoint = counter + _.options.slidesToScroll;
15196                counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
15197            }
15198        }
15199
15200        return pagerQty - 1;
15201
15202    };
15203
15204    Slick.prototype.getLeft = function(slideIndex) {
15205
15206        var _ = this,
15207            targetLeft,
15208            verticalHeight,
15209            verticalOffset = 0,
15210            targetSlide;
15211
15212        _.slideOffset = 0;
15213        verticalHeight = _.$slides.first().outerHeight(true);
15214
15215        if (_.options.infinite === true) {
15216            if (_.slideCount > _.options.slidesToShow) {
15217                _.slideOffset = (_.slideWidth * _.options.slidesToShow) * -1;
15218                verticalOffset = (verticalHeight * _.options.slidesToShow) * -1;
15219            }
15220            if (_.slideCount % _.options.slidesToScroll !== 0) {
15221                if (slideIndex + _.options.slidesToScroll > _.slideCount && _.slideCount > _.options.slidesToShow) {
15222                    if (slideIndex > _.slideCount) {
15223                        _.slideOffset = ((_.options.slidesToShow - (slideIndex - _.slideCount)) * _.slideWidth) * -1;
15224                        verticalOffset = ((_.options.slidesToShow - (slideIndex - _.slideCount)) * verticalHeight) * -1;
15225                    } else {
15226                        _.slideOffset = ((_.slideCount % _.options.slidesToScroll) * _.slideWidth) * -1;
15227                        verticalOffset = ((_.slideCount % _.options.slidesToScroll) * verticalHeight) * -1;
15228                    }
15229                }
15230            }
15231        } else {
15232            if (slideIndex + _.options.slidesToShow > _.slideCount) {
15233                _.slideOffset = ((slideIndex + _.options.slidesToShow) - _.slideCount) * _.slideWidth;
15234                verticalOffset = ((slideIndex + _.options.slidesToShow) - _.slideCount) * verticalHeight;
15235            }
15236        }
15237
15238        if (_.slideCount <= _.options.slidesToShow) {
15239            _.slideOffset = 0;
15240            verticalOffset = 0;
15241        }
15242
15243       
vendor: 5,167 bytes, lines 15243-15416
15243 if (_.options.centerMode === true && _.options.infinite === true) {
15244            _.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2) - _.slideWidth;
15245        } else if (_.options.centerMode === true) {
15246            _.slideOffset = 0;
15247            _.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2);
15248        }
15249
15250        if (_.options.vertical === false) {
15251            targetLeft = ((slideIndex * _.slideWidth) * -1) + _.slideOffset;
15252        } else {
15253            targetLeft = ((slideIndex * verticalHeight) * -1) + verticalOffset;
15254        }
15255
15256        if (_.options.variableWidth === true) {
15257
15258            if (_.slideCount <= _.options.slidesToShow || _.options.infinite === false) {
15259                targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex);
15260            } else {
15261                targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow);
15262            }
15263
15264            if (_.options.rtl === true) {
15265                if (targetSlide[0]) {
15266                    targetLeft = (_.$slideTrack.width() - targetSlide[0].offsetLeft - targetSlide.width()) * -1;
15267                } else {
15268                    targetLeft =  0;
15269                }
15270            } else {
15271                targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0;
15272            }
15273
15274            if (_.options.centerMode === true) {
15275                if (_.slideCount <= _.options.slidesToShow || _.options.infinite === false) {
15276                    targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex);
15277                } else {
15278                    targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow + 1);
15279                }
15280
15281                if (_.options.rtl === true) {
15282                    if (targetSlide[0]) {
15283                        targetLeft = (_.$slideTrack.width() - targetSlide[0].offsetLeft - targetSlide.width()) * -1;
15284                    } else {
15285                        targetLeft =  0;
15286                    }
15287                } else {
15288                    targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0;
15289                }
15290
15291                targetLeft += (_.$list.width() - targetSlide.outerWidth()) / 2;
15292            }
15293        }
15294
15295        return targetLeft;
15296
15297    };
15298
15299    Slick.prototype.getOption = Slick.prototype.slickGetOption = function(option) {
15300
15301        var _ = this;
15302
15303        return _.options[option];
15304
15305    };
15306
15307    Slick.prototype.getNavigableIndexes = function() {
15308
15309        var _ = this,
15310            breakPoint = 0,
15311            counter = 0,
15312            indexes = [],
15313            max;
15314
15315        if (_.options.infinite === false) {
15316            max = _.slideCount;
15317        } else {
15318            breakPoint = _.options.slidesToScroll * -1;
15319            counter = _.options.slidesToScroll * -1;
15320            max = _.slideCount * 2;
15321        }
15322
15323        while (breakPoint < max) {
15324            indexes.push(breakPoint);
15325            breakPoint = counter + _.options.slidesToScroll;
15326            counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
15327        }
15328
15329        return indexes;
15330
15331    };
15332
15333    Slick.prototype.getSlick = function() {
15334
15335        return this;
15336
15337    };
15338
15339    Slick.prototype.getSlideCount = function() {
15340
15341        var _ = this,
15342            slidesTraversed, swipedSlide, centerOffset;
15343
15344        centerOffset = _.options.centerMode === true ? _.slideWidth * Math.floor(_.options.slidesToShow / 2) : 0;
15345
15346        if (_.options.swipeToSlide === true) {
15347            _.$slideTrack.find('.slick-slide').each(function(index, slide) {
15348                if (slide.offsetLeft - centerOffset + ($(slide).outerWidth() / 2) > (_.swipeLeft * -1)) {
15349                    swipedSlide = slide;
15350                    return false;
15351                }
15352            });
15353
15354            slidesTraversed = Math.abs($(swipedSlide).attr('data-slick-index') - _.currentSlide) || 1;
15355
15356            return slidesTraversed;
15357
15358        } else {
15359            return _.options.slidesToScroll;
15360        }
15361
15362    };
15363
15364    Slick.prototype.goTo = Slick.prototype.slickGoTo = function(slide, dontAnimate) {
15365
15366        var _ = this;
15367
15368        _.changeSlide({
15369            data: {
15370                message: 'index',
15371                index: parseInt(slide)
15372            }
15373        }, dontAnimate);
15374
15375    };
15376
15377    Slick.prototype.init = function(creation) {
15378
15379        var _ = this;
15380
15381        if (!$(_.$slider).hasClass('slick-initialized')) {
15382
15383            $(_.$slider).addClass('slick-initialized');
15384
15385            _.buildRows();
15386            _.buildOut();
15387            _.setProps();
15388            _.startLoad();
15389            _.loadSlider();
15390            _.initializeEvents();
15391            _.updateArrows();
15392            _.updateDots();
15393            _.checkResponsive(true);
15394            _.focusHandler();
15395
15396        }
15397
15398        if (creation) {
15399            _.$slider.trigger('init', [_]);
15400        }
15401
15402        if (_.options.accessibility === true) {
15403            _.initADA();
15404        }
15405
15406        if ( _.options.autoplay ) {
15407
15408            _.paused = false;
15409            _.autoPlay();
15410
15411        }
15412
15413    };
15414
15415    Slick.prototype.initADA = function() {
15416        var _ = this
15416;
15417        _.$slides.add(_.$slideTrack.find('.slick-cloned')).attr({
15418            'aria-hidden': 'true',
15419            'tabindex': '-1'
15420        }).find('a, input, button, select').attr({
15421            'tabindex': '-1'
15422        });
15423
15424        _.$slideTrack.attr('role', 'listbox');
15425
15426        _.$slides.not(_.$slideTrack.find('.slick-cloned')).each(function(i) {
15427            $(this).attr({
15428                'role': 'option',
15429                'aria-describedby': 'slick-slide' + _.instanceUid + i + ''
15430            });
15431        });
15432
15433        if (_.$dots !== null) {
15434            _.$dots.attr('role', 'tablist').find('li').each(function(i) {
15435                $(this).attr({
15436                    'role': 'presentation',
15437                    'aria-selected': 'false',
15438                    'aria-controls': 'navigation' + _.instanceUid + i + '',
15439                    'id': 'slick-slide' + _.instanceUid + i + ''
15440                });
15441            })
15442                .first().attr('aria-selected', 'true').end()
15443                .find('button').attr('role', 'button').end()
15444                .closest('div').attr('role', 'toolbar');
15445        }
15446        _.activateADA();
15447
15448    };
15449
15450    Slick.prototype.initArrowEvents = function() {
15451
15452        var _ = this;
15453
15454        if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
15455            _.$prevArrow
15456               .off('click.slick')
15457               .on('click.slick', {
15458                    message: 'previous'
15459               }, _.changeSlide);
15460            _.$nextArrow
15461               .off('click.slick')
15462               .on('click.slick', {
15463                    message: 'next'
15464               }, _.changeSlide);
15465        }
15466
15467    };
15468
15469    Slick.prototype.initDotEvents = function() {
15470
15471        var _ = this;
15472
15473        if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
15474            $('li', _.$dots).on('click.slick', {
15475                message: 'index'
15476            }, _.changeSlide);
15477        }
15478
15479        if ( _.options.dots === true && _.options.pauseOnDotsHover === true ) {
15480
15481            $('li', _.$dots)
15482                .on('mouseenter.slick', $.proxy(_.interrupt, _, true))
15483                .on('mouseleave.slick', $.proxy(_.interrupt, _, false));
15484
15485        }
15486
15487    };
15488
15489    Slick.prototype.initSlideEvents = function() {
15490
15491        var _ = this;
15492
15493        if ( _.options.pauseOnHover ) {
15494
15495            _.$list.on('mouseenter.slick', $.proxy(_.interrupt, _, true));
15496            _.$list.on('mouseleave.slick', $.proxy(_.interrupt, _, false));
15497
15498        }
15499
15500    };
15501
15502    Slick.prototype.initializeEvents = function() {
15503
15504        var _ = this;
15505
15506        _.initArrowEvents();
15507
15508        _.initDotEvents();
15509        _.initSlideEvents();
15510
15511        _.$list.on('touchstart.slick mousedown.slick', {
15512            action: 'start'
15513        }, _.swipeHandler);
15514        _.$list.on('touchmove.slick mousemove.slick', {
15515            action: 'move'
15516        }, _.swipeHandler);
15517        _.$list.on('touchend.slick mouseup.slick', {
15518            action: 'end'
15519        }, _.swipeHandler);
vendor: 10,240 bytes, lines 15520-15897
15520        _.$list.on('touchcancel.slick mouseleave.slick', {
15521            action: 'end'
15522        }, _.swipeHandler);
15523
15524        _.$list.on('click.slick', _.clickHandler);
15525
15526        $(document).on(_.visibilityChange, $.proxy(_.visibility, _));
15527
15528        if (_.options.accessibility === true) {
15529            _.$list.on('keydown.slick', _.keyHandler);
15530        }
15531
15532        if (_.options.focusOnSelect === true) {
15533            $(_.$slideTrack).children().on('click.slick', _.selectHandler);
15534        }
15535
15536        $(window).on('orientationchange.slick.slick-' + _.instanceUid, $.proxy(_.orientationChange, _));
15537
15538        $(window).on('resize.slick.slick-' + _.instanceUid, $.proxy(_.resize, _));
15539
15540        $('[draggable!=true]', _.$slideTrack).on('dragstart', _.preventDefault);
15541
15542        $(window).on('load.slick.slick-' + _.instanceUid, _.setPosition);
15543        $(document).on('ready.slick.slick-' + _.instanceUid, _.setPosition);
15544
15545    };
15546
15547    Slick.prototype.initUI = function() {
15548
15549        var _ = this;
15550
15551        if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
15552
15553            _.$prevArrow.show();
15554            _.$nextArrow.show();
15555
15556        }
15557
15558        if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
15559
15560            _.$dots.show();
15561
15562        }
15563
15564    };
15565
15566    Slick.prototype.keyHandler = function(event) {
15567
15568        var _ = this;
15569         //Dont slide if the cursor is inside the form fields and arrow keys are pressed
15570        if(!event.target.tagName.match('TEXTAREA|INPUT|SELECT')) {
15571            if (event.keyCode === 37 && _.options.accessibility === true) {
15572                _.changeSlide({
15573                    data: {
15574                        message: _.options.rtl === true ? 'next' :  'previous'
15575                    }
15576                });
15577            } else if (event.keyCode === 39 && _.options.accessibility === true) {
15578                _.changeSlide({
15579                    data: {
15580                        message: _.options.rtl === true ? 'previous' : 'next'
15581                    }
15582                });
15583            }
15584        }
15585
15586    };
15587
15588    Slick.prototype.lazyLoad = function() {
15589
15590        var _ = this,
15591            loadRange, cloneRange, rangeStart, rangeEnd;
15592
15593        function loadImages(imagesScope) {
15594
15595            $('img[data-lazy]', imagesScope).each(function() {
15596
15597                var image = $(this),
15598                    imageSource = $(this).attr('data-lazy'),
15599                    imageToLoad = document.createElement('img');
15600
15601                imageToLoad.onload = function() {
15602
15603                    image
15604                        .animate({ opacity: 0 }, 100, function() {
15605                            image
15606                                .attr('src', imageSource)
15607                                .animate({ opacity: 1 }, 200, function() {
15608                                    image
15609                                        .removeAttr('data-lazy')
15610                                        .removeClass('slick-loading');
15611                                });
15612                            _.$slider.trigger('lazyLoaded', [_, image, imageSource]);
15613                        });
15614
15615                };
15616
15617                imageToLoad.onerror = function() {
15618
15619                    image
15620                        .removeAttr( 'data-lazy' )
15621                        .removeClass( 'slick-loading' )
15622                        .addClass( 'slick-lazyload-error' );
15623
15624                    _.$slider.trigger('lazyLoadError', [ _, image, imageSource ]);
15625
15626                };
15627
15628                imageToLoad.src = imageSource;
15629
15630            });
15631
15632        }
15633
15634        if (_.options.centerMode === true) {
15635            if (_.options.infinite === true) {
15636                rangeStart = _.currentSlide + (_.options.slidesToShow / 2 + 1);
15637                rangeEnd = rangeStart + _.options.slidesToShow + 2;
15638            } else {
15639                rangeStart = Math.max(0, _.currentSlide - (_.options.slidesToShow / 2 + 1));
15640                rangeEnd = 2 + (_.options.slidesToShow / 2 + 1) + _.currentSlide;
15641            }
15642        } else {
15643            rangeStart = _.options.infinite ? _.options.slidesToShow + _.currentSlide : _.currentSlide;
15644            rangeEnd = Math.ceil(rangeStart + _.options.slidesToShow);
15645            if (_.options.fade === true) {
15646                if (rangeStart > 0) rangeStart--;
15647                if (rangeEnd <= _.slideCount) rangeEnd++;
15648            }
15649        }
15650
15651        loadRange = _.$slider.find('.slick-slide').slice(rangeStart, rangeEnd);
15652        loadImages(loadRange);
15653
15654        if (_.slideCount <= _.options.slidesToShow) {
15655            cloneRange = _.$slider.find('.slick-slide');
15656            loadImages(cloneRange);
15657        } else
15658        if (_.currentSlide >= _.slideCount - _.options.slidesToShow) {
15659            cloneRange = _.$slider.find('.slick-cloned').slice(0, _.options.slidesToShow);
15660            loadImages(cloneRange);
15661        } else if (_.currentSlide === 0) {
15662            cloneRange = _.$slider.find('.slick-cloned').slice(_.options.slidesToShow * -1);
15663            loadImages(cloneRange);
15664        }
15665
15666    };
15667
15668    Slick.prototype.loadSlider = function() {
15669
15670        var _ = this;
15671
15672        _.setPosition();
15673
15674        _.$slideTrack.css({
15675            opacity: 1
15676        });
15677
15678        _.$slider.removeClass('slick-loading');
15679
15680        _.initUI();
15681
15682        if (_.options.lazyLoad === 'progressive') {
15683            _.progressiveLazyLoad();
15684        }
15685
15686    };
15687
15688    Slick.prototype.next = Slick.prototype.slickNext = function() {
15689
15690        var _ = this;
15691
15692        _.changeSlide({
15693            data: {
15694                message: 'next'
15695            }
15696        });
15697
15698    };
15699
15700    Slick.prototype.orientationChange = function() {
15701
15702        var _ = this;
15703
15704        _.checkResponsive();
15705        _.setPosition();
15706
15707    };
15708
15709    Slick.prototype.pause = Slick.prototype.slickPause = function() {
15710
15711        var _ = this;
15712
15713        _.autoPlayClear();
15714        _.paused = true;
15715
15716    };
15717
15718    Slick.prototype.play = Slick.prototype.slickPlay = function() {
15719
15720        var _ = this;
15721
15722        _.autoPlay();
15723        _.options.autoplay = true;
15724        _.paused = false;
15725        _.focussed = false;
15726        _.interrupted = false;
15727
15728    };
15729
15730    Slick.prototype.postSlide = function(index) {
15731
15732        var _ = this;
15733
15734        if( !_.unslicked ) {
15735
15736            _.$slider.trigger('afterChange', [_, index]);
15737
15738            _.animating = false;
15739
15740            _.setPosition();
15741
15742            _.swipeLeft = null;
15743
15744            if ( _.options.autoplay ) {
15745                _.autoPlay();
15746            }
15747
15748            if (_.options.accessibility === true) {
15749                _.initADA();
15750            }
15751
15752        }
15753
15754    };
15755
15756    Slick.prototype.prev = Slick.prototype.slickPrev = function() {
15757
15758        var _ = this;
15759
15760        _.changeSlide({
15761            data: {
15762                message: 'previous'
15763            }
15764        });
15765
15766    };
15767
15768    Slick.prototype.preventDefault = function(event) {
15769
15770        event.preventDefault();
15771
15772    };
15773
15774    Slick.prototype.progressiveLazyLoad = function( tryCount ) {
15775
15776        tryCount = tryCount || 1;
15777
15778        var _ = this,
15779            $imgsToLoad = $( 'img[data-lazy]', _.$slider ),
15780            image,
15781            imageSource,
15782            imageToLoad;
15783
15784        if ( $imgsToLoad.length ) {
15785
15786            image = $imgsToLoad.first();
15787            imageSource = image.attr('data-lazy');
15788            imageToLoad = document.createElement('img');
15789
15790            imageToLoad.onload = function() {
15791
15792                image
15793                    .attr( 'src', imageSource )
15794                    .removeAttr('data-lazy')
15795                    .removeClass('slick-loading');
15796
15797                if ( _.options.adaptiveHeight === true ) {
15798                    _.setPosition();
15799                }
15800
15801                _.$slider.trigger('lazyLoaded', [ _, image, imageSource ]);
15802                _.progressiveLazyLoad();
15803
15804            };
15805
15806            imageToLoad.onerror = function() {
15807
15808                if ( tryCount < 3 ) {
15809
15810                    /**
15811                     * try to load the image 3 times,
15812                     * leave a slight delay so we don't get
15813                     * servers blocking the request.
15814                     */
15815                    setTimeout( function() {
15816                        _.progressiveLazyLoad( tryCount + 1 );
15817                    }, 500 );
15818
15819                } else {
15820
15821                    image
15822                        .removeAttr( 'data-lazy' )
15823                        .removeClass( 'slick-loading' )
15824                        .addClass( 'slick-lazyload-error' );
15825
15826                    _.$slider.trigger('lazyLoadError', [ _, image, imageSource ]);
15827
15828                    _.progressiveLazyLoad();
15829
15830                }
15831
15832            };
15833
15834            imageToLoad.src = imageSource;
15835
15836        } else {
15837
15838            _.$slider.trigger('allImagesLoaded', [ _ ]);
15839
15840        }
15841
15842    };
15843
15844    Slick.prototype.refresh = function( initializing ) {
15845
15846        var _ = this, currentSlide, lastVisibleIndex;
15847
15848        lastVisibleIndex = _.slideCount - _.options.slidesToShow;
15849
15850        // in non-infinite sliders, we don't want to go past the
15851        // last visible index.
15852        if( !_.options.infinite && ( _.currentSlide > lastVisibleIndex )) {
15853            _.currentSlide = lastVisibleIndex;
15854        }
15855
15856        // if less slides than to show, go to start.
15857        if ( _.slideCount <= _.options.slidesToShow ) {
15858            _.currentSlide = 0;
15859
15860        }
15861
15862        currentSlide = _.currentSlide;
15863
15864        _.destroy(true);
15865
15866        $.extend(_, _.initials, { currentSlide: currentSlide });
15867
15868        _.init();
15869
15870        if( !initializing ) {
15871
15872            _.changeSlide({
15873                data: {
15874                    message: 'index',
15875                    index: currentSlide
15876                }
15877            }, false);
15878
15879        }
15880
15881    };
15882
15883    Slick.prototype.registerBreakpoints = function() {
15884
15885        var _ = this, breakpoint, currentBreakpoint, l,
15886            responsiveSettings = _.options.responsive || null;
15887
15888        if ( $.type(responsiveSettings) === 'array' && responsiveSettings.length ) {
15889
15890            _.respondTo = _.options.respondTo || 'window';
15891
15892            for ( breakpoint in responsiveSettings ) {
15893
15894                l = _.breakpoints.length-1;
15895                currentBreakpoint = responsiveSettings[breakpoint].breakpoint;
15896
15897                if (responsiveSettings.hasOwnProperty(breakpoint)) {
vendor: 12,466 bytes, lines 15897-16330
15897
15898
15899                    // loop through the breakpoints and cut out any existing
15900                    // ones with the same breakpoint number, we don't want dupes.
15901                    while( l >= 0 ) {
15902                        if( _.breakpoints[l] && _.breakpoints[l] === currentBreakpoint ) {
15903                            _.breakpoints.splice(l,1);
15904                        }
15905                        l--;
15906                    }
15907
15908                    _.breakpoints.push(currentBreakpoint);
15909                    _.breakpointSettings[currentBreakpoint] = responsiveSettings[breakpoint].settings;
15910
15911                }
15912
15913            }
15914
15915            _.breakpoints.sort(function(a, b) {
15916                return ( _.options.mobileFirst ) ? a-b : b-a;
15917            });
15918
15919        }
15920
15921    };
15922
15923    Slick.prototype.reinit = function() {
15924
15925        var _ = this;
15926
15927        _.$slides =
15928            _.$slideTrack
15929                .children(_.options.slide)
15930                .addClass('slick-slide');
15931
15932        _.slideCount = _.$slides.length;
15933
15934        if (_.currentSlide >= _.slideCount && _.currentSlide !== 0) {
15935            _.currentSlide = _.currentSlide - _.options.slidesToScroll;
15936        }
15937
15938        if (_.slideCount <= _.options.slidesToShow) {
15939            _.currentSlide = 0;
15940        }
15941
15942        _.registerBreakpoints();
15943
15944        _.setProps();
15945        _.setupInfinite();
15946        _.buildArrows();
15947        _.updateArrows();
15948        _.initArrowEvents();
15949        _.buildDots();
15950        _.updateDots();
15951        _.initDotEvents();
15952        _.cleanUpSlideEvents();
15953        _.initSlideEvents();
15954
15955        _.checkResponsive(false, true);
15956
15957        if (_.options.focusOnSelect === true) {
15958            $(_.$slideTrack).children().on('click.slick', _.selectHandler);
15959        }
15960
15961        _.setSlideClasses(typeof _.currentSlide === 'number' ? _.currentSlide : 0);
15962
15963        _.setPosition();
15964        _.focusHandler();
15965
15966        _.paused = !_.options.autoplay;
15967        _.autoPlay();
15968
15969        _.$slider.trigger('reInit', [_]);
15970
15971    };
15972
15973    Slick.prototype.resize = function() {
15974
15975        var _ = this;
15976
15977        if ($(window).width() !== _.windowWidth) {
15978            clearTimeout(_.windowDelay);
15979            _.windowDelay = window.setTimeout(function() {
15980                _.windowWidth = $(window).width();
15981                _.checkResponsive();
15982                if( !_.unslicked ) { _.setPosition(); }
15983            }, 50);
15984        }
15985    };
15986
15987    Slick.prototype.removeSlide = Slick.prototype.slickRemove = function(index, removeBefore, removeAll) {
15988
15989        var _ = this;
15990
15991        if (typeof(index) === 'boolean') {
15992            removeBefore = index;
15993            index = removeBefore === true ? 0 : _.slideCount - 1;
15994        } else {
15995            index = removeBefore === true ? --index : index;
15996        }
15997
15998        if (_.slideCount < 1 || index < 0 || index > _.slideCount - 1) {
15999            return false;
16000        }
16001
16002        _.unload();
16003
16004        if (removeAll === true) {
16005            _.$slideTrack.children().remove();
16006        } else {
16007            _.$slideTrack.children(this.options.slide).eq(index).remove();
16008        }
16009
16010        _.$slides = _.$slideTrack.children(this.options.slide);
16011
16012        _.$slideTrack.children(this.options.slide).detach();
16013
16014        _.$slideTrack.append(_.$slides);
16015
16016        _.$slidesCache = _.$slides;
16017
16018        _.reinit();
16019
16020    };
16021
16022    Slick.prototype.setCSS = function(position) {
16023
16024        var _ = this,
16025            positionProps = {},
16026            x, y;
16027
16028        if (_.options.rtl === true) {
16029            position = -position;
16030        }
16031        x = _.positionProp == 'left' ? Math.ceil(position) + 'px' : '0px';
16032        y = _.positionProp == 'top' ? Math.ceil(position) + 'px' : '0px';
16033
16034        positionProps[_.positionProp] = position;
16035
16036        if (_.transformsEnabled === false) {
16037            _.$slideTrack.css(positionProps);
16038        } else {
16039            positionProps = {};
16040            if (_.cssTransitions === false) {
16041                positionProps[_.animType] = 'translate(' + x + ', ' + y + ')';
16042                _.$slideTrack.css(positionProps);
16043            } else {
16044                positionProps[_.animType] = 'translate3d(' + x + ', ' + y + ', 0px)';
16045                _.$slideTrack.css(positionProps);
16046            }
16047        }
16048
16049    };
16050
16051    Slick.prototype.setDimensions = function() {
16052
16053        var _ = this;
16054
16055        if (_.options.vertical === false) {
16056            if (_.options.centerMode === true) {
16057                _.$list.css({
16058                    padding: ('0px ' + _.options.centerPadding)
16059                });
16060            }
16061        } else {
16062            _.$list.height(_.$slides.first().outerHeight(true) * _.options.slidesToShow);
16063            if (_.options.centerMode === true) {
16064                _.$list.css({
16065                    padding: (_.options.centerPadding + ' 0px')
16066                });
16067            }
16068        }
16069
16070        _.listWidth = _.$list.width();
16071        _.listHeight = _.$list.height();
16072
16073
16074        if (_.options.vertical === false && _.options.variableWidth === false) {
16075            _.slideWidth = Math.ceil(_.listWidth / _.options.slidesToShow);
16076            _.$slideTrack.width(Math.ceil((_.slideWidth * _.$slideTrack.children('.slick-slide').length)));
16077
16078        } else if (_.options.variableWidth === true) {
16079            _.$slideTrack.width(5000 * _.slideCount);
16080        } else {
16081            _.slideWidth = Math.ceil(_.listWidth);
16082            _.$slideTrack.height(Math.ceil((_.$slides.first().outerHeight(true) * _.$slideTrack.children('.slick-slide').length)));
16083        }
16084
16085        var offset = _.$slides.first().outerWidth(true) - _.$slides.first().width();
16086        if (_.options.variableWidth === false) _.$slideTrack.children('.slick-slide').width(_.slideWidth - offset);
16087
16088    };
16089
16090    Slick.prototype.setFade = function() {
16091
16092        var _ = this,
16093            targetLeft;
16094
16095        _.$slides.each(function(index, element) {
16096            targetLeft = (_.slideWidth * index) * -1;
16097            if (_.options.rtl === true) {
16098                $(element).css({
16099                    position: 'relative',
16100                    right: targetLeft,
16101                    top: 0,
16102                    zIndex: _.options.zIndex - 2,
16103                    opacity: 0
16104                });
16105            } else {
16106                $(element).css({
16107                    position: 'relative',
16108                    left: targetLeft,
16109                    top: 0,
16110                    zIndex: _.options.zIndex - 2,
16111                    opacity: 0
16112                });
16113            }
16114        });
16115
16116        _.$slides.eq(_.currentSlide).css({
16117            zIndex: _.options.zIndex - 1,
16118            opacity: 1
16119        });
16120
16121    };
16122
16123    Slick.prototype.setHeight = function() {
16124
16125        var _ = this;
16126
16127        if (_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) {
16128            var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true);
16129            _.$list.css('height', targetHeight);
16130        }
16131
16132    };
16133
16134    Slick.prototype.setOption =
16135    Slick.prototype.slickSetOption = function() {
16136
16137        /**
16138         * accepts arguments in format of:
16139         *
16140         *  - for changing a single option's value:
16141         *     .slick("setOption", option, value, refresh )
16142         *
16143         *  - for changing a set of responsive options:
16144         *     .slick("setOption", 'responsive', [{}, ...], refresh )
16145         *
16146         *  - for updating multiple values at once (not responsive)
16147         *     .slick("setOption", { 'option': value, ... }, refresh )
16148         */
16149
16150        var _ = this, l, item, option, value, refresh = false, type;
16151
16152        if( $.type( arguments[0] ) === 'object' ) {
16153
16154            option =  arguments[0];
16155            refresh = arguments[1];
16156            type = 'multiple';
16157
16158        } else if ( $.type( arguments[0] ) === 'string' ) {
16159
16160            option =  arguments[0];
16161            value = arguments[1];
16162            refresh = arguments[2];
16163
16164            if ( arguments[0] === 'responsive' && $.type( arguments[1] ) === 'array' ) {
16165
16166                type = 'responsive';
16167
16168            } else if ( typeof arguments[1] !== 'undefined' ) {
16169
16170                type = 'single';
16171
16172            }
16173
16174        }
16175
16176        if ( type === 'single' ) {
16177
16178            _.options[option] = value;
16179
16180
16181        } else if ( type === 'multiple' ) {
16182
16183            $.each( option , function( opt, val ) {
16184
16185                _.options[opt] = val;
16186
16187            });
16188
16189
16190        } else if ( type === 'responsive' ) {
16191
16192            for ( item in value ) {
16193
16194                if( $.type( _.options.responsive ) !== 'array' ) {
16195
16196                    _.options.responsive = [ value[item] ];
16197
16198                } else {
16199
16200                    l = _.options.responsive.length-1;
16201
16202                    // loop through the responsive object and splice out duplicates.
16203                    while( l >= 0 ) {
16204
16205                        if( _.options.responsive[l].breakpoint === value[item].breakpoint ) {
16206
16207                            _.options.responsive.splice(l,1);
16208
16209                        }
16210
16211                        l--;
16212
16213                    }
16214
16215                    _.options.responsive.push( value[item] );
16216
16217                }
16218
16219            }
16220
16221        }
16222
16223        if ( refresh ) {
16224
16225            _.unload();
16226            _.reinit();
16227
16228        }
16229
16230    };
16231
16232    Slick.prototype.setPosition = function() {
16233
16234        var _ = this;
16235
16236        _.setDimensions();
16237
16238        _.setHeight();
16239
16240        if (_.options.fade === false) {
16241            _.setCSS(_.getLeft(_.currentSlide));
16242        } else {
16243            _.setFade();
16244        }
16245
16246        _.$slider.trigger('setPosition', [_]);
16247
16248    };
16249
16250    Slick.prototype.setProps = function() {
16251
16252        var _ = this,
16253            bodyStyle = document.body.style;
16254
16255        _.positionProp = _.options.vertical === true ? 'top' : 'left';
16256
16257        if (_.positionProp === 'top') {
16258            _.$slider.addClass('slick-vertical');
16259        } else {
16260            _.$slider.removeClass('slick-vertical');
16261        }
16262
16263        if (bodyStyle.WebkitTransition !== undefined ||
16264            bodyStyle.MozTransition !== undefined ||
16265            bodyStyle.msTransition !== undefined) {
16266            if (_.options.useCSS === true) {
16267                _.cssTransitions = true;
16268            }
16269        }
16270
16271        if ( _.options.fade ) {
16272            if ( typeof _.options.zIndex === 'number' ) {
16273                if( _.options.zIndex < 3 ) {
16274                    _.options.zIndex = 3;
16275                }
16276            } else {
16277                _.options.zIndex = _.defaults.zIndex;
16278            }
16279        }
16280
16281        if (bodyStyle.OTransform !== undefined) {
16282            _.animType = 'OTransform';
16283            _.transformType = '-o-transform';
16284            _.transitionType = 'OTransition';
16285            if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false;
16286        }
16287        if (bodyStyle.MozTransform !== undefined) {
16288            _.animType = 'MozTransform';
16289            _.transformType = '-moz-transform';
16290            _.transitionType = 'MozTransition';
16291            if (bodyStyle.perspectiveProperty === undefined && bodyStyle.MozPerspective === undefined) _.animType = false;
16292        }
16293        if (bodyStyle.webkitTransform !== undefined) {
16294            _.animType = 'webkitTransform';
16295            _.transformType = '-webkit-transform';
16296            _.transitionType = 'webkitTransition';
16297            if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false;
16298        }
16299        if (bodyStyle.msTransform !== undefined) {
16300            _.animType = 'msTransform';
16301            _.transformType = '-ms-transform';
16302            _.transitionType = 'msTransition';
16303            if (bodyStyle.msTransform === undefined) _.animType = false;
16304        }
16305        if (bodyStyle.transform !== undefined && _.animType !== false) {
16306            _.animType = 'transform';
16307            _.transformType = 'transform';
16308            _.transitionType = 'transition';
16309        }
16310        _.transformsEnabled = _.options.useTransform && (_.animType !== null && _.animType !== false);
16311    };
16312
16313
16314    Slick.prototype.setSlideClasses = function(index) {
16315
16316        var _ = this,
16317            centerOffset, allSlides, indexOffset, remainder;
16318
16319        allSlides = _.$slider
16320            .find('.slick-slide')
16321            .removeClass('slick-active slick-center slick-current')
16322            .attr('aria-hidden', 'true');
16323
16324        _.$slides
16325            .eq(index)
16326            .addClass('slick-current');
16327
16328        if (_.options.centerMode === true) {
16329
16330            
vendor: 19,730 bytes, lines 16330-17030
16330centerOffset = Math.floor(_.options.slidesToShow / 2);
16331
16332            if (_.options.infinite === true) {
16333
16334                if (index >= centerOffset && index <= (_.slideCount - 1) - centerOffset) {
16335
16336                    _.$slides
16337                        .slice(index - centerOffset, index + centerOffset + 1)
16338                        .addClass('slick-active')
16339                        .attr('aria-hidden', 'false');
16340
16341                } else {
16342
16343                    indexOffset = _.options.slidesToShow + index;
16344                    allSlides
16345                        .slice(indexOffset - centerOffset + 1, indexOffset + centerOffset + 2)
16346                        .addClass('slick-active')
16347                        .attr('aria-hidden', 'false');
16348
16349                }
16350
16351                if (index === 0) {
16352
16353                    allSlides
16354                        .eq(allSlides.length - 1 - _.options.slidesToShow)
16355                        .addClass('slick-center');
16356
16357                } else if (index === _.slideCount - 1) {
16358
16359                    allSlides
16360                        .eq(_.options.slidesToShow)
16361                        .addClass('slick-center');
16362
16363                }
16364
16365            }
16366
16367            _.$slides
16368                .eq(index)
16369                .addClass('slick-center');
16370
16371        } else {
16372
16373            if (index >= 0 && index <= (_.slideCount - _.options.slidesToShow)) {
16374
16375                _.$slides
16376                    .slice(index, index + _.options.slidesToShow)
16377                    .addClass('slick-active')
16378                    .attr('aria-hidden', 'false');
16379
16380            } else if (allSlides.length <= _.options.slidesToShow) {
16381
16382                allSlides
16383                    .addClass('slick-active')
16384                    .attr('aria-hidden', 'false');
16385
16386            } else {
16387
16388                remainder = _.slideCount % _.options.slidesToShow;
16389                indexOffset = _.options.infinite === true ? _.options.slidesToShow + index : index;
16390
16391                if (_.options.slidesToShow == _.options.slidesToScroll && (_.slideCount - index) < _.options.slidesToShow) {
16392
16393                    allSlides
16394                        .slice(indexOffset - (_.options.slidesToShow - remainder), indexOffset + remainder)
16395                        .addClass('slick-active')
16396                        .attr('aria-hidden', 'false');
16397
16398                } else {
16399
16400                    allSlides
16401                        .slice(indexOffset, indexOffset + _.options.slidesToShow)
16402                        .addClass('slick-active')
16403                        .attr('aria-hidden', 'false');
16404
16405                }
16406
16407            }
16408
16409        }
16410
16411        if (_.options.lazyLoad === 'ondemand') {
16412            _.lazyLoad();
16413        }
16414
16415    };
16416
16417    Slick.prototype.setupInfinite = function() {
16418
16419        var _ = this,
16420            i, slideIndex, infiniteCount;
16421
16422        if (_.options.fade === true) {
16423            _.options.centerMode = false;
16424        }
16425
16426        if (_.options.infinite === true && _.options.fade === false) {
16427
16428            slideIndex = null;
16429
16430            if (_.slideCount > _.options.slidesToShow) {
16431
16432                if (_.options.centerMode === true) {
16433                    infiniteCount = _.options.slidesToShow + 1;
16434                } else {
16435                    infiniteCount = _.options.slidesToShow;
16436                }
16437
16438                for (i = _.slideCount; i > (_.slideCount -
16439                        infiniteCount); i -= 1) {
16440                    slideIndex = i - 1;
16441                    $(_.$slides[slideIndex]).clone(true).attr('id', '')
16442                        .attr('data-slick-index', slideIndex - _.slideCount)
16443                        .prependTo(_.$slideTrack).addClass('slick-cloned');
16444                }
16445                for (i = 0; i < infiniteCount; i += 1) {
16446                    slideIndex = i;
16447                    $(_.$slides[slideIndex]).clone(true).attr('id', '')
16448                        .attr('data-slick-index', slideIndex + _.slideCount)
16449                        .appendTo(_.$slideTrack).addClass('slick-cloned');
16450                }
16451                _.$slideTrack.find('.slick-cloned').find('[id]').each(function() {
16452                    $(this).attr('id', '');
16453                });
16454
16455            }
16456
16457        }
16458
16459    };
16460
16461    Slick.prototype.interrupt = function( toggle ) {
16462
16463        var _ = this;
16464
16465        if( !toggle ) {
16466            _.autoPlay();
16467        }
16468        _.interrupted = toggle;
16469
16470    };
16471
16472    Slick.prototype.selectHandler = function(event) {
16473
16474        var _ = this;
16475
16476        var targetElement =
16477            $(event.target).is('.slick-slide') ?
16478                $(event.target) :
16479                $(event.target).parents('.slick-slide');
16480
16481        var index = parseInt(targetElement.attr('data-slick-index'));
16482
16483        if (!index) index = 0;
16484
16485        if (_.slideCount <= _.options.slidesToShow) {
16486
16487            _.setSlideClasses(index);
16488            _.asNavFor(index);
16489            return;
16490
16491        }
16492
16493        _.slideHandler(index);
16494
16495    };
16496
16497    Slick.prototype.slideHandler = function(index, sync, dontAnimate) {
16498
16499        var targetSlide, animSlide, oldSlide, slideLeft, targetLeft = null,
16500            _ = this, navTarget;
16501
16502        sync = sync || false;
16503
16504        if (_.animating === true && _.options.waitForAnimate === true) {
16505            return;
16506        }
16507
16508        if (_.options.fade === true && _.currentSlide === index) {
16509            return;
16510        }
16511
16512        if (_.slideCount <= _.options.slidesToShow) {
16513            return;
16514        }
16515
16516        if (sync === false) {
16517            _.asNavFor(index);
16518        }
16519
16520        targetSlide = index;
16521        targetLeft = _.getLeft(targetSlide);
16522        slideLeft = _.getLeft(_.currentSlide);
16523
16524        _.currentLeft = _.swipeLeft === null ? slideLeft : _.swipeLeft;
16525
16526        if (_.options.infinite === false && _.options.centerMode === false && (index < 0 || index > _.getDotCount() * _.options.slidesToScroll)) {
16527            if (_.options.fade === false) {
16528                targetSlide = _.currentSlide;
16529                if (dontAnimate !== true) {
16530                    _.animateSlide(slideLeft, function() {
16531                        _.postSlide(targetSlide);
16532                    });
16533                } else {
16534                    _.postSlide(targetSlide);
16535                }
16536            }
16537            return;
16538        } else if (_.options.infinite === false && _.options.centerMode === true && (index < 0 || index > (_.slideCount - _.options.slidesToScroll))) {
16539            if (_.options.fade === false) {
16540                targetSlide = _.currentSlide;
16541                if (dontAnimate !== true) {
16542                    _.animateSlide(slideLeft, function() {
16543                        _.postSlide(targetSlide);
16544                    });
16545                } else {
16546                    _.postSlide(targetSlide);
16547                }
16548            }
16549            return;
16550        }
16551
16552        if ( _.options.autoplay ) {
16553            clearInterval(_.autoPlayTimer);
16554        }
16555
16556        if (targetSlide < 0) {
16557            if (_.slideCount % _.options.slidesToScroll !== 0) {
16558                animSlide = _.slideCount - (_.slideCount % _.options.slidesToScroll);
16559            } else {
16560                animSlide = _.slideCount + targetSlide;
16561            }
16562        } else if (targetSlide >= _.slideCount) {
16563            if (_.slideCount % _.options.slidesToScroll !== 0) {
16564                animSlide = 0;
16565            } else {
16566                animSlide = targetSlide - _.slideCount;
16567            }
16568        } else {
16569            animSlide = targetSlide;
16570        }
16571
16572        _.animating = true;
16573
16574        _.$slider.trigger('beforeChange', [_, _.currentSlide, animSlide]);
16575
16576        oldSlide = _.currentSlide;
16577        _.currentSlide = animSlide;
16578
16579        _.setSlideClasses(_.currentSlide);
16580
16581        if ( _.options.asNavFor ) {
16582
16583            navTarget = _.getNavTarget();
16584            navTarget = navTarget.slick('getSlick');
16585
16586            if ( navTarget.slideCount <= navTarget.options.slidesToShow ) {
16587                navTarget.setSlideClasses(_.currentSlide);
16588            }
16589
16590        }
16591
16592        _.updateDots();
16593        _.updateArrows();
16594
16595        if (_.options.fade === true) {
16596            if (dontAnimate !== true) {
16597
16598                _.fadeSlideOut(oldSlide);
16599
16600                _.fadeSlide(animSlide, function() {
16601                    _.postSlide(animSlide);
16602                });
16603
16604            } else {
16605                _.postSlide(animSlide);
16606            }
16607            _.animateHeight();
16608            return;
16609        }
16610
16611        if (dontAnimate !== true) {
16612            _.animateSlide(targetLeft, function() {
16613                _.postSlide(animSlide);
16614            });
16615        } else {
16616            _.postSlide(animSlide);
16617        }
16618
16619    };
16620
16621    Slick.prototype.startLoad = function() {
16622
16623        var _ = this;
16624
16625        if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
16626
16627            _.$prevArrow.hide();
16628            _.$nextArrow.hide();
16629
16630        }
16631
16632        if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
16633
16634            _.$dots.hide();
16635
16636        }
16637
16638        _.$slider.addClass('slick-loading');
16639
16640    };
16641
16642    Slick.prototype.swipeDirection = function() {
16643
16644        var xDist, yDist, r, swipeAngle, _ = this;
16645
16646        xDist = _.touchObject.startX - _.touchObject.curX;
16647        yDist = _.touchObject.startY - _.touchObject.curY;
16648        r = Math.atan2(yDist, xDist);
16649
16650        swipeAngle = Math.round(r * 180 / Math.PI);
16651        if (swipeAngle < 0) {
16652            swipeAngle = 360 - Math.abs(swipeAngle);
16653        }
16654
16655        if ((swipeAngle <= 45) && (swipeAngle >= 0)) {
16656            return (_.options.rtl === false ? 'left' : 'right');
16657        }
16658        if ((swipeAngle <= 360) && (swipeAngle >= 315)) {
16659            return (_.options.rtl === false ? 'left' : 'right');
16660        }
16661        if ((swipeAngle >= 135) && (swipeAngle <= 225)) {
16662            return (_.options.rtl === false ? 'right' : 'left');
16663        }
16664        if (_.options.verticalSwiping === true) {
16665            if ((swipeAngle >= 35) && (swipeAngle <= 135)) {
16666                return 'down';
16667            } else {
16668                return 'up';
16669            }
16670        }
16671
16672        return 'vertical';
16673
16674    };
16675
16676    Slick.prototype.swipeEnd = function(event) {
16677
16678        var _ = this,
16679            slideCount,
16680            direction;
16681
16682        _.dragging = false;
16683        _.interrupted = false;
16684        _.shouldClick = ( _.touchObject.swipeLength > 10 ) ? false : true;
16685
16686        if ( _.touchObject.curX === undefined ) {
16687            return false;
16688        }
16689
16690        if ( _.touchObject.edgeHit === true ) {
16691            _.$slider.trigger('edge', [_, _.swipeDirection() ]);
16692        }
16693
16694        if ( _.touchObject.swipeLength >= _.touchObject.minSwipe ) {
16695
16696            direction = _.swipeDirection();
16697
16698            switch ( direction ) {
16699
16700                case 'left':
16701                case 'down':
16702
16703                    slideCount =
16704                        _.options.swipeToSlide ?
16705                            _.checkNavigable( _.currentSlide + _.getSlideCount() ) :
16706                            _.currentSlide + _.getSlideCount();
16707
16708                    _.currentDirection = 0;
16709
16710                    break;
16711
16712                case 'right':
16713                case 'up':
16714
16715                    slideCount =
16716                        _.options.swipeToSlide ?
16717                            _.checkNavigable( _.currentSlide - _.getSlideCount() ) :
16718                            _.currentSlide - _.getSlideCount();
16719
16720                    _.currentDirection = 1;
16721
16722                    break;
16723
16724                default:
16725
16726
16727            }
16728
16729            if( direction != 'vertical' ) {
16730
16731                _.slideHandler( slideCount );
16732                _.touchObject = {};
16733                _.$slider.trigger('swipe', [_, direction ]);
16734
16735            }
16736
16737        } else {
16738
16739            if ( _.touchObject.startX !== _.touchObject.curX ) {
16740
16741                _.slideHandler( _.currentSlide );
16742                _.touchObject = {};
16743
16744            }
16745
16746        }
16747
16748    };
16749
16750    Slick.prototype.swipeHandler = function(event) {
16751
16752        var _ = this;
16753
16754        if ((_.options.swipe === false) || ('ontouchend' in document && _.options.swipe === false)) {
16755            return;
16756        } else if (_.options.draggable === false && event.type.indexOf('mouse') !== -1) {
16757            return;
16758        }
16759
16760        _.touchObject.fingerCount = event.originalEvent && event.originalEvent.touches !== undefined ?
16761            event.originalEvent.touches.length : 1;
16762
16763        _.touchObject.minSwipe = _.listWidth / _.options
16764            .touchThreshold;
16765
16766        if (_.options.verticalSwiping === true) {
16767            _.touchObject.minSwipe = _.listHeight / _.options
16768                .touchThreshold;
16769        }
16770
16771        switch (event.data.action) {
16772
16773            case 'start':
16774                _.swipeStart(event);
16775                break;
16776
16777            case 'move':
16778                _.swipeMove(event);
16779                break;
16780
16781            case 'end':
16782                _.swipeEnd(event);
16783                break;
16784
16785        }
16786
16787    };
16788
16789    Slick.prototype.swipeMove = function(event) {
16790
16791        var _ = this,
16792            edgeWasHit = false,
16793            curLeft, swipeDirection, swipeLength, positionOffset, touches;
16794
16795        touches = event.originalEvent !== undefined ? event.originalEvent.touches : null;
16796
16797        if (!_.dragging || touches && touches.length !== 1) {
16798            return false;
16799        }
16800
16801        curLeft = _.getLeft(_.currentSlide);
16802
16803        _.touchObject.curX = touches !== undefined ? touches[0].pageX : event.clientX;
16804        _.touchObject.curY = touches !== undefined ? touches[0].pageY : event.clientY;
16805
16806        _.touchObject.swipeLength = Math.round(Math.sqrt(
16807            Math.pow(_.touchObject.curX - _.touchObject.startX, 2)));
16808
16809        if (_.options.verticalSwiping === true) {
16810            _.touchObject.swipeLength = Math.round(Math.sqrt(
16811                Math.pow(_.touchObject.curY - _.touchObject.startY, 2)));
16812        }
16813
16814        swipeDirection = _.swipeDirection();
16815
16816        if (swipeDirection === 'vertical') {
16817            return;
16818        }
16819
16820        if (event.originalEvent !== undefined && _.touchObject.swipeLength > 4) {
16821            event.preventDefault();
16822        }
16823
16824        positionOffset = (_.options.rtl === false ? 1 : -1) * (_.touchObject.curX > _.touchObject.startX ? 1 : -1);
16825        if (_.options.verticalSwiping === true) {
16826            positionOffset = _.touchObject.curY > _.touchObject.startY ? 1 : -1;
16827        }
16828
16829
16830        swipeLength = _.touchObject.swipeLength;
16831
16832        _.touchObject.edgeHit = false;
16833
16834        if (_.options.infinite === false) {
16835            if ((_.currentSlide === 0 && swipeDirection === 'right') || (_.currentSlide >= _.getDotCount() && swipeDirection === 'left')) {
16836                swipeLength = _.touchObject.swipeLength * _.options.edgeFriction;
16837                _.touchObject.edgeHit = true;
16838            }
16839        }
16840
16841        if (_.options.vertical === false) {
16842            _.swipeLeft = curLeft + swipeLength * positionOffset;
16843        } else {
16844            _.swipeLeft = curLeft + (swipeLength * (_.$list.height() / _.listWidth)) * positionOffset;
16845        }
16846        if (_.options.verticalSwiping === true) {
16847            _.swipeLeft = curLeft + swipeLength * positionOffset;
16848        }
16849
16850        if (_.options.fade === true || _.options.touchMove === false) {
16851            return false;
16852        }
16853
16854        if (_.animating === true) {
16855            _.swipeLeft = null;
16856            return false;
16857        }
16858
16859        _.setCSS(_.swipeLeft);
16860
16861    };
16862
16863    Slick.prototype.swipeStart = function(event) {
16864
16865        var _ = this,
16866            touches;
16867
16868        _.interrupted = true;
16869
16870        if (_.touchObject.fingerCount !== 1 || _.slideCount <= _.options.slidesToShow) {
16871            _.touchObject = {};
16872            return false;
16873        }
16874
16875        if (event.originalEvent !== undefined && event.originalEvent.touches !== undefined) {
16876            touches = event.originalEvent.touches[0];
16877        }
16878
16879        _.touchObject.startX = _.touchObject.curX = touches !== undefined ? touches.pageX : event.clientX;
16880        _.touchObject.startY = _.touchObject.curY = touches !== undefined ? touches.pageY : event.clientY;
16881
16882        _.dragging = true;
16883
16884    };
16885
16886    Slick.prototype.unfilterSlides = Slick.prototype.slickUnfilter = function() {
16887
16888        var _ = this;
16889
16890        if (_.$slidesCache !== null) {
16891
16892            _.unload();
16893
16894            _.$slideTrack.children(this.options.slide).detach();
16895
16896            _.$slidesCache.appendTo(_.$slideTrack);
16897
16898            _.reinit();
16899
16900        }
16901
16902    };
16903
16904    Slick.prototype.unload = function() {
16905
16906        var _ = this;
16907
16908        $('.slick-cloned', _.$slider).remove();
16909
16910        if (_.$dots) {
16911            _.$dots.remove();
16912        }
16913
16914        if (_.$prevArrow && _.htmlExpr.test(_.options.prevArrow)) {
16915            _.$prevArrow.remove();
16916        }
16917
16918        if (_.$nextArrow && _.htmlExpr.test(_.options.nextArrow)) {
16919            _.$nextArrow.remove();
16920        }
16921
16922        _.$slides
16923            .removeClass('slick-slide slick-active slick-visible slick-current')
16924            .attr('aria-hidden', 'true')
16925            .css('width', '');
16926
16927    };
16928
16929    Slick.prototype.unslick = function(fromBreakpoint) {
16930
16931        var _ = this;
16932        _.$slider.trigger('unslick', [_, fromBreakpoint]);
16933        _.destroy();
16934
16935    };
16936
16937    Slick.prototype.updateArrows = function() {
16938
16939        var _ = this,
16940            centerOffset;
16941
16942        centerOffset = Math.floor(_.options.slidesToShow / 2);
16943
16944        if ( _.options.arrows === true &&
16945            _.slideCount > _.options.slidesToShow &&
16946            !_.options.infinite ) {
16947
16948            _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
16949            _.$nextArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
16950
16951            if (_.currentSlide === 0) {
16952
16953                _.$prevArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
16954                _.$nextArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
16955
16956            } else if (_.currentSlide >= _.slideCount - _.options.slidesToShow && _.options.centerMode === false) {
16957
16958                _.$nextArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
16959                _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
16960
16961            } else if (_.currentSlide >= _.slideCount - 1 && _.options.centerMode === true) {
16962
16963                _.$nextArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
16964                _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
16965
16966            }
16967
16968        }
16969
16970    };
16971
16972    Slick.prototype.updateDots = function() {
16973
16974        var _ = this;
16975
16976        if (_.$dots !== null) {
16977
16978            _.$dots
16979                .find('li')
16980                .removeClass('slick-active')
16981                .attr('aria-hidden', 'true');
16982
16983            _.$dots
16984                .find('li')
16985                .eq(Math.floor(_.currentSlide / _.options.slidesToScroll))
16986                .addClass('slick-active')
16987                .attr('aria-hidden', 'false');
16988
16989        }
16990
16991    };
16992
16993    Slick.prototype.visibility = function() {
16994
16995        var _ = this;
16996
16997        if ( _.options.autoplay ) {
16998
16999            if ( document[_.hidden] ) {
17000
17001                _.interrupted = true;
17002
17003            } else {
17004
17005                _.interrupted = false;
17006
17007            }
17008
17009        }
17010
17011    };
17012
17013    $.fn.slick = function() {
17014        var _ = this,
17015            opt = arguments[0],
17016            args = Array.prototype.slice.call(arguments, 1),
17017            l = _.length,
17018            i,
17019            ret;
17020        for (i = 0; i < l; i++) {
17021            if (typeof opt == 'object' || typeof opt == 'undefined')
17022                _[i].slick = new Slick(_[i], opt);
17023            else
17024                ret = _[i].slick[opt].apply(_[i].slick, args);
17025            if (typeof ret != 'undefined') return ret;
17026        }
17027        return _;
17028    };
17029
17030}));

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